Skip to content

feat(omp): run LifeOS hooks in omp via Claude-Code hook contract bridge - #1945

Open
Faizalj wants to merge 3 commits into
danielmiessler:mainfrom
Faizalj:feat/omp-hooks-bridge
Open

feat(omp): run LifeOS hooks in omp via Claude-Code hook contract bridge#1945
Faizalj wants to merge 3 commits into
danielmiessler:mainfrom
Faizalj:feat/omp-hooks-bridge

Conversation

@Faizalj

@Faizalj Faizalj commented Aug 22, 2026

Copy link
Copy Markdown

What

Adds OmpHooksBridge.ts — an omp (Oh My Pi) extension that shims the Claude Code hook contract (JSON on stdin/stdout, registry from ${LIFEOS_DIR}/settings.json) onto the omp event bus, so LifeOS hooks run in non-Claude-Code harnesses. This serves LifeOS's stated harness-agnostic goal ("designed to run wherever your AI does").

Event mapping

omp event Claude Code event Effect
session_start SessionStart startup maintenance hooks
turn_start UserPromptSubmit prompt-side hooks
tool_call PreToolUse deny → block; ask → UI confirm (fail-closed headless)
tool_result PostToolUse result hooks (isError → PostToolUseFailure)
turn_end Stop per-turn stop hooks
session_shutdown SessionEnd end-of-session maintenance

additionalContext returned by hooks is queued and injected as a system message before the next LLM call via omp's context event — the equivalent of Claude Code's implicit injection.

Testing evidence

Headless run (omp -p --auto-approve "run: echo bridge-test", DeepSeek v4 flash via Ollama), audit log:

  • 76 hooks loaded from the live registry; all six event classes executed: SessionStart 5 · UserPromptSubmit 24 · PreToolUse 2 · PostToolUse 4 · Stop 16 · SessionEnd 6
  • PreToolUse enforcement verified (ContextReduction + PreToolGuard fire before bash)
  • EventLogger hook wrote a real entry to LifeOS tool-activity.jsonl from inside the omp session (observability pipeline live)
  • context_inject fired (118 chars) — delta blocks reach the LLM
  • Zero hook crashes; per-hook 30s timeout; failures logged, never fatal

Full log excerpt in LifeOS/install/LIFEOS/DOCUMENTATION/OmpHooksBridge.md.

Known limitations

  • transcript_path empty — transcript-parsing hooks degrade gracefully
  • UserPromptSubmit gets a placeholder prompt (input event not yet wired)
  • Sequential hook execution adds ~1–2s/turn for heavy prompt-side hooks

Adds OmpHooksBridge.ts, an omp extension that shims the Claude Code hook
contract (JSON stdin/stdout, settings.json registry) onto the omp event bus:
session_start→SessionStart, turn_start→UserPromptSubmit, tool_call→PreToolUse
(deny/ask enforcement), tool_result→PostToolUse(Failure), turn_end→Stop,
session_shutdown→SessionEnd. additionalContext is injected as a system
message before the next LLM call. Verified end-to-end headless: 76 hooks
across all six event classes, EventLogger writes tool-activity.jsonl from
inside omp, zero hook crashes. Doc: OmpHooksBridge.md.
VoiceCompletion.hook.ts requires a Claude transcript; omp has none. The
bridge now extracts the final 🗣️ closer from the session log at turn_end
and speaks it through Pulse /notify (ElevenLabs). Same semantics as Claude
Code: no voice line means silence. Env: OMP_VOICE=0 disables, OMP_VOICE_ID
overrides the voice. Verified headless: voice sent, HTTP 200, ~4s.
- extract the 🗣️ closer from the message that just completed the turn,
  not the newest session JSONL — with parallel sessions the global scan
  picked the wrong session's line (or none) and voice silently died
- accept both '🗣️ <ZEN>:' and '🗣️ ZEN:' — angle-bracket-only matching
  dropped every closer written without brackets, so sessions spoke nothing
- drop the now-unused statSync import; doc: voice path is turn-scoped
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant