fix(providers): register omo in the runtime lists the type system cannot see - #43
Merged
Conversation
…not see Adding omo to the unions in #39 left three runtime lookups untouched, so the provider typechecked and shipped while behaving wrongly at every layer. - omo read gjc's transcripts. The agent home came from `provider === 'omp' ? '.omp' : '.gjc'`, and a ternary routes a new union member into its else branch without a type error. 632 gjc sessions were indexed as omo, and none of omo's own five transcripts were ever read. - omo never appeared in the sidebar. Two `Array.includes` allowlists in useExternalCliSessions filtered it out after the backend reported it. - omo replies never refreshed. Its transcript root was missing from PROVIDER_WATCH_PATHS, so the initial scan found sessions that no watcher ever updated. The root and title lookups are now exhaustive Records, which makes the next provider a compile error instead of a silent fallthrough. The remaining allowlists (external spawn, completion identity, event-driven notifications, notification label) get omo wherever omp already appears. Also swaps the placeholder logo for the official `oh-my-openagent/.github/assets/omo-icon-light.svg`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The message-author chain ends in `: t('messageTypes.claude')`, so omo fell
through to the Claude label the same way its transcript root fell through to
gjc. Follows the gjc/omp pattern of an i18n key with a defaultValue, so no
locale file changes are needed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… display Four defects found by running omo through ChatMux end to end. - omo could not continue a session. `--resume` means different things in the two CLIs: Oh My Pi resumes the given id, omo takes no value and opens an interactive picker, which under `--print` with no stdin exits 13 without running the turn. Measured across valid id, wrong cwd, and `--resume=<id>`; all exit non-zero. omo's equivalent is `--session-id`, verified to resume an existing id and create a missing one. - Ordinary CLI logging surfaced as chat errors. Both CLIs write config notices and hook status to stderr on runs that exit 0, and every line was forwarded as an error message. stderr is now buffered and reported only when the process actually fails. - Assistant avatars were gjc-only. `transcriptView` existed solely to hide the author row for every live provider except gjc; the prop is removed, so all providers show their icon and name. omo also fell through the author chain to the Claude label. - The omo logo rendered small. The official asset sits at ~63% of its canvas, so the viewBox is cropped to the mark's measured bounds. omo's send runtime stays unregistered in spawnFns: sending to a session that is already live in a tmux pane would start a second headless process on the same transcript. Filed separately. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
devswha
added a commit
that referenced
this pull request
Aug 13, 2026
…sions (#46) extractExternalResumeSessionId matched only the pi-derived --resume|-r form for omo, but omo's canonical continuation flag is --session-id (its --resume takes no value and opens a picker) -- the same fact #43 established for the headless runtime in server/pi-cli.ts. A tmux pane started with `omo --session-id <id>` therefore never linked back to its transcript session. omo now tries --session-id first and keeps the --resume fallback; omp is unchanged and never accepts --session-id.
devswha
added a commit
that referenced
this pull request
Aug 13, 2026
… omo runtime (#47) chat.send routed every message to spawnFns[provider] without checking whether the target transcript is currently owned by a live tmux pane, so a second headless CLI resumed the same session id: two processes interleaved one JSONL and the live agent never saw the message (#44, observed on omo). - New live-spawn-guard service: before starting a run, chat.send resolves the fresh external-CLI roster and refuses with SESSION_LIVE_IN_TMUX when a pane of the same provider owns the exact provider session id. Fail-open on unavailable discovery evidence: a false block would break the core chat path, a false allow merely restores pre-guard behavior. - Guarded providers are the six headless-resume CLIs (claude, codex, cursor, opencode, omp, omo). gjc is exempt: its live sessions are reached through the SDK connect lane, which attaches instead of forking. - With the guard in place, spawnOmo/abortOmoSession are registered, closing the omo send gap left by #43. The pi runtime abort-handle capture and the chat.abort failure branch now include omo alongside gjc/omp. Verified end to end on this host: a real omo pane started with --session-id <id> in tmux blocks the spawn with the owning session name, an unrelated id and the same id under omp pass, and killing the pane releases the guard. Closes #44
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #39. Adding omo to the type unions was not enough: three runtime lookups were left behind, so the provider typechecked, passed 917 tests, went green in CI, and behaved wrongly at every layer.
What was broken
1. omo read gjc's transcripts.
A ternary routes a new union member into its else branch with no type error. Result: 632 gjc sessions indexed as omo, and none of omo's own 5 transcripts ever read.
2. omo never appeared in the sidebar. Two
Array.includesallowlists inuseExternalCliSessionsdropped it after the backend had correctly reported"kind":"omo".3. omo replies never refreshed. Its transcript root was missing from
PROVIDER_WATCH_PATHS, so the startup scan indexed sessions that no watcher ever updated — sends worked, responses never appeared.Fix
Root and title lookups become exhaustive
Record<PiTranscriptProvider, …>, so the next provider is a compile error rather than a silent fallthrough. The remaining allowlists get omo wherever omp already appears: external spawn (supportedClis), completion identity, event-driven notifications, and the notification label map (omo showed as "Assistant").Also replaces the placeholder logo with the official
oh-my-openagent/.github/assets/omo-icon-light.svg.Regression lock
pi-transcript-roots.test.tsasserts each pi provider resolves to its own~/.<provider>/agentand that no two share a root. Verified by mutation: pointing omo back at.gjcfails the test.Verification
After the fix, against real data:
The 632 mis-attributed rows were purged and the scan markers cleared. Full gate green: typecheck, lint, identity, server, client.
Note for reviewers
All three defects share one shape — correct types, wrong runtime list. The compiler enumerated the 12 exhaustive Records that needed omo and caught none of these, because
Array.includesand? :are invisible to it. Worth remembering when the next provider lands.