AGENTS.md
packages/omo-senpi/AGENTS.mdAGENTS.md
Quality
89/100
Scores the file, not the repository.Length
2,150 words
8 headings · 2 code blocksRepository
67k
— · pushed 0 days agoLast changed
today
First indexed 2 days ago.1# omo-senpi23Native Senpi TypeScript extension adapter for oh-my-openagent.45This package is adapter-only. It may depend on harness-neutral core packages plus the Senpi-coupled `@oh-my-opencode/senpi-task` engine, but those packages must not import Senpi, Pi packages, or this adapter through their harness-neutral entrypoints. The Senpi runtime boundary stays here.67## Anatomy89| Path | Purpose |10|------|---------|11| `package.json` | Private workspace package `@oh-my-opencode/omo-senpi`; exports the adapter, extension, and local installer entrypoints. |12| `src/extension/` | Senpi ExtensionAPI composition layer. It validates the required API surface, registers global and per-component disable flags, and wires components defensively. |13| `src/components/` | Ten live components: `config-startup`, `ultrawork`, `start-work-continuation`, `ulw-loop`, `fallback-architect`, `comment-checker`, `telemetry`, `lsp`, `task`, and `config-watch`, plus the `config-resolution` loader helper. |14| `src/install/` | Local Senpi installer and uninstaller helpers. They add or remove the absolute plugin path in `SENPI_CODING_AGENT_DIR` or `~/.senpi/agent` settings. |15| `scripts/qa/` | Live Senpi QA drivers, continuation probe, and mock provider used by task 13 validation. |16| `skills/` | Native Senpi skills authored directly against the Senpi tool surface (not ported from Codex or the shared pool); currently `hyperplan`, `init-deep`, `ultrawork`, `ulw-loop`, and `ulw-research`. `sync-skills.mjs` ships them verbatim. |17| `plugin/` | The single Pi package `@code-yeongyu/omo-senpi`. It contains generated `extensions/omo.js`, generated skills, package metadata, and plugin-local build scripts. |1819The v1 install surface is local-path only. Install the built Pi package from `packages/omo-senpi/plugin`; do not document npm, git, or marketplace distribution for this adapter until that exists in code.2021## Components2223- `config-startup`: runs the shared lock+journal migration engine (`runSenpiStartupMigration`, both legacy groups: `2026-07-opencode-config-unification` for `oh-my-*` files and `2026-07-codex-config-jsonc` for `~/.omo/config.jsonc`) before Senpi reads its unified configuration, then loads the profile-selected `[senpi]` view through `config-resolution` (`loadSenpiOmoConfig`: `loadOmoConfig` with `harness: "senpi"` plus `resolveModelReferences` catalog expansion). Migration results and config diagnostics surface once on the first `session_start` via the host notification UI (falling back to the logger).2425- `ultrawork`: injects the Senpi ultrawork directive on matching input as a hidden custom message (`pi.sendMessage({customType: 'omo-ultrawork:directive', content: DIRECTIVE, display: false})` followed by `{action: 'continue'}`), backed by `src/components/ultrawork/generated-directive.ts`. On the idle path the user's typed text is never modified; senpi converts the custom message into `role: 'user'` conversation context, so the directive reaches the model but is not rendered in the TUI. A prompt QUEUED mid-stream (the input event carries `streamingBehavior`) instead gets the directive appended inside that one message: senpi drains steering and follow-up queues one message at a time by default and answers each drained message, so a separate hidden message would burn its own turn before the user's ask arrived. Appending rather than prepending is what keeps `/skill:` expansion working on that path. All guards are preserved: the `/(?:ultrawork|ulw(?!-))/i` trigger, the `omo-senpi-ultrawork-disabled` flag, skipping `source === 'extension'` inputs, skipping `ulw-` skill names (`ulw-plan`, `ulw-loop`, `ulw-research`), and skipping inputs that already carry a matched `<ultrawork-mode>`...`</ultrawork-mode>` tag pair (a lone open-tag mention still arms). For `/skill:` commands on the idle path there is no prepend/append distinction because text is not rewritten: `/skill:ultrawork` passes through untouched (expansion already inlines the directive), a trigger that appears only in the skill NAME does not arm, and senpi's native skill expansion can no longer be disturbed by the hook. The directive is authored senpi-native at `skills/ultrawork/SKILL.md` and ships verbatim; `plugin/scripts/embed-directive.mjs` embeds its body into `src/components/ultrawork/generated-directive.ts` and fails the build when non-senpi harness tokens (multi_agent, update_plan, codex, ...) appear in the source.26- `start-work-continuation`: reads `.omo/boulder.json` on `agent_end` (the Senpi analog of Codex's Stop hook) and injects a continuation directive when the current session owns an active or paused Prometheus work plan. It uses `senpi:<session_id>` state produced by the `start-work` skill, suppresses repeats by a `work_id:updated_at:completed/total` signature, and caps consecutive continuations at 8 (reset on user input). It registers before `ulw-loop` so active boulder work takes precedence over ulw-loop continuation.27- `ulw-loop`: detects active `omo ulw-loop` state and injects continuation guidance when the cwd has an incomplete run. It explicitly defers to `start-work-continuation` when boulder state is continuable for the same session.28- `fallback-architect`: when senpi's retry-fallback controller moves the session off `claude-fable-5` because the model refused or the provider rejected the request under Anthropic's Usage Policy, it injects one hidden `omo-fallback-architect:directive` message telling the weaker active model to decompose the problem and consult `task(category: "architect")` with self-contained per-part queries. Detection uses only the extension surface: `message_end` supplies the refusal signal and `model_select` with `source: "fallback"` supplies the switch, with the refusal predicate in `detection.ts` mirroring senpi `isClassifierRefusal` (`packages/ai/src/utils/stop-details.ts`) including its stop-reason-first ordering. It fires only when `loadOmoConfig` reports an enabled `architect` category, and a compact reminder then rides on each later user prompt until fable 5 is active again. The reminder is ALWAYS a hidden custom message (`display: false`) and the typed text is never rewritten: on the mid-stream path senpi steers a custom message into the running turn (`sendCustomMessage` -> `agent.steer`), so hiding it costs no extra assistant turn for queued prompts either — the old transform-append leaked the reminder into the user's own bubble in the TUI. Arming also emits one user-VISIBLE `omo-fallback-architect:notice` custom message (`display: true`, structured `details: { from, to }`) framing the switch as an upgrade (the fallback model drives execution while Fable-5-grade reasoning stays reachable through the architect lane); `notice.ts` owns the copy plus a registered TUI message renderer, and the stable customType + details ride senpi's session/event stream so GUI surfaces (omo-desktop-app) can render the same event later without senpi core changes. Gated by `omo-senpi-fallback-architect-disabled`.29- `comment-checker`: runs the shared comment-checker flow after write-like tool results when a resolver finds the binary.30- `telemetry`: sends the anonymous once-per-UTC-day `omo_senpi_daily_active` event, with product-specific opt-outs.31- `lsp`: registers direct LSP tools and optional post-edit diagnostics through the packaged shared LSP daemon runtime. The Senpi adapter owns only descriptors, schemas, renderers, path extraction, and project-config migration warnings.32- `task`: loads the unified `omo.jsonc` view at register (via `config-resolution`), composes the task engine over `@oh-my-opencode/senpi-task`, and registers the 4 task tools (`task`, `task_send`, `task_cancel`, `task_output`) plus the 6 lead-only team tools (`team_create`, `team_delete`, `task_create`, `task_get`, `task_list`, `task_update`).33 The engine overlays four builtin curated read-only subagents (`explore`, `librarian`, `metis`, `momus`) under the omo.json `agents` record, so any session can delegate via `task(subagent_type: "<name>")` with zero configuration; omo.json `agents.<name>` replaces individual builtin fields field-level while unset fields keep the builtin, and `disable: true` hides one from the task tool description and spawn resolution even when a request supplies an explicit model. Curated agents are pinned to in-process execution (their `execution_mode` override is ignored) and are rejected as team members because process-mode member spawns drop the persona prompt and tool policy. The component also wires the plan-gated agent tier: `components/task/skill-invocation-tracker.ts` records three per-session channels - invocations from `read` tool results on `*/skills/<name>/SKILL.md` and raw `/skill:<name>` inputs; USER requests from raw user input naming ulw-plan (after stripping injected `<ultrawork-mode>`/`<system-reminder>` blocks); and plan artifacts from successful read/write/edit on `.omo/plans/*.md` paths at any root (worktrees included) or apply_patch bodies touching one (state is dropped on `session_shutdown`; `load_skills` on a spawn arms the child and is deliberately not a parent-session record) - and `createTaskTool` receives it as `resolveSkillInvocations`, so `metis`/`momus` spawn only when the user explicitly requested `ulw-plan`, a plan artifact exists, and `start-work` was never invoked (the classification and verdict live in senpi-task `agents/invocation-guard.ts`). Their nine-name tool surface replaces Senpi's general `bash` with a structured read-only GitHub/HTTPS broker and excludes direct edit/write plus mutating LSP tools. Team sends are durable file-only writes. The adapter owns one 1-second lead poller per team led by the current session; process members load the scoped member extension with only `task_send` and receive lead mail steered into the resident member's running turn. It wires the ordered session-start recovery chain (process reattach, member/lead reservation reclaim, failed-notification retry, owned-lead poll), transition suspension, shutdown teardown, a completion-message renderer, the `/tasks` and `/task-kill` slash commands, and the status-UI footer. Gated by the `--no-omo-task` flag and skipped when required ExtensionAPI capabilities are missing.34- `config-watch`: registers the resolved user and project `.omo` configuration chain with Senpi's optional `config-watch` event protocol. Its dry-run validation rejects new config diagnostics before the host reloads the extension; it safely skips with a warning on older Senpi APIs without the optional events capability. The user config directory is `~/.omo`; when it does not yet exist, its only parent is `$HOME`. Whenever the senpi agent dir sits under `$HOME` — including the default `~/.senpi/agent` — the bare-`$HOME` creation target is dropped by the protected-path filter below, so `userConfigCreationDiscovery` reports `reload_required` and later user-scope creation is discovered on the next session start. With `SENPI_CODING_AGENT_DIR` pointed outside `$HOME` the target survives and creation stays watched. Either way the flag is derived from the surviving targets rather than from directory existence, so it never claims a watch the host never received. Targets that cover the senpi agent dir's protected paths (`auth.json`, `sessions/`, `logs/` under `SENPI_CODING_AGENT_DIR`, default `~/.senpi/agent`) are filtered out of the resolution because the host rejects them deterministically — practically this drops the bare-`$HOME` ancestor target, so a NEW `.omo` created directly in the `$HOME` root is discovered only on the next session start. Rejections are never re-registered synchronously (the host rejects on the REGISTER stack, so a sync re-emit recurses until stack overflow): the refresh is deferred via `setTimeout(0)` and capped at 3 retries per registration-payload fingerprint, resetting when the payload changes.3536`packages/omo-opencode` is a separate build that still uses its prior task/team names; cross-edition parity is a deliberate follow-up outside this adapter.3738### Deprecated config keys3940Legacy `codegraph.*` keys in user `omo.json` are tolerated-ignored: the schema lives in shared `@oh-my-opencode/omo-config-core` (which other editions still consume), but omo-senpi no longer registers a codegraph component or reads those keys. Users with stale `codegraph.*` entries experience no error — the keys are silently ignored by the senpi adapter. This tolerant-ignore behavior is covered by `src/components/config-startup/index.test.ts`.4142Rules are intentionally not a Senpi component. Senpi has builtin rules, so this adapter must not add a `rules` component just to mirror Codex or OpenCode.4344### Dependencies4546The adapter depends on `@oh-my-opencode/senpi-task` (task engine + tool factories), `@oh-my-opencode/omo-config-core` (`loadOmoConfig` + `resolveModelReferences` + the migration engine), `@oh-my-opencode/omo-opencode/config-migration` (dependency-clean legacy discovery + transform consumed by `config-startup`), `@oh-my-opencode/delegate-core`, `@oh-my-opencode/team-core`, `@oh-my-opencode/boulder-state` (Boulder work-plan state for `start-work-continuation`), `@oh-my-opencode/comment-checker-core`, `@oh-my-opencode/telemetry-core`, `@oh-my-opencode/prompts-core`, `@oh-my-opencode/lsp-core`, `@code-yeongyu/lsp-daemon`, and `@oh-my-opencode/utils`, with `@code-yeongyu/senpi` as an optional peer (`package.json`).4748## Build And Packaging4950Build outputs under `plugin/extensions/` and `plugin/skills/` are generated. Do not hand-edit them.5152- `node packages/omo-senpi/plugin/scripts/build-extension.mjs` builds `plugin/extensions/omo.js`.53- `node packages/omo-senpi/plugin/scripts/build-extension.mjs --check` verifies the generated extension is current.54- `node packages/omo-senpi/plugin/scripts/sync-skills.mjs` syncs Senpi-ready skills into `plugin/skills/` from three pools: component-owned native sources shipped verbatim (`ulw-loop`), native `skills/` sources shipped verbatim (`hyperplan`, `init-deep`, `ultrawork`, `ulw-research`; `init-deep` is a senpi-local override whose `nativeSkillNames` entry shadows the shared-pool copy so the shared file stays untouched for omo-codex), and the repo `shared-skills` pool (start-work gets a `codex:`->`senpi:` overlay; ulw-plan gets a senpi overlay adding a momus-only review override plus architect/ultrabrain advisory consultation lanes; shared skills get a Senpi tool-compatibility banner).55- `node packages/omo-senpi/plugin/scripts/embed-directive.mjs --check` verifies the generated ultrawork directive is current.56- `bun run test:senpi` runs the package gate: build the shared daemon, stage the plugin artifacts, typecheck, then `bun test packages/omo-senpi`.5758Peer-external build rule: the extension build must externalize the Senpi peer/import family so shared core packages stay harness-neutral and Senpi resolves those peers from the installed Senpi runtime. Keep `SENPI_LOADER_ALIASES` in `plugin/scripts/build-extension.mjs` aligned with `src/bundle-purity.test.ts`, including `@code-yeongyu/senpi`, `@earendil-works/pi-*`, and `@mariozechner/pi-*` imports. The current build also externalizes the TypeBox aliases required by Senpi's loader and Node builtins.5960## QA6162For adapter code changes, run the narrowest relevant unit tests plus the Senpi package gate:6364```sh65tsgo --noEmit -p packages/omo-senpi/tsconfig.json66bun run test:senpi67```6869Task live QA scripts:7071```sh72node packages/omo-senpi/scripts/qa/drive.mjs --self-test73node packages/omo-senpi/scripts/qa/drive.mjs74node packages/omo-senpi/scripts/qa/probe-continuation.mjs75SENPI_BIN="$(command -v senpi)" node packages/omo-senpi/scripts/qa/task-e2e.mjs76SENPI_BIN="$(command -v senpi)" node packages/omo-senpi/scripts/qa/team-e2e.mjs77node packages/omo-senpi/scripts/qa/task-rpc-e2e.mjs --self-test78```7980`drive.mjs` and the task/team live drivers create isolated Senpi agent directories and ignore caller `SENPI_CODING_AGENT_DIR`. If the Senpi binary is unavailable, the live drivers report `SKIP` or `FAIL` in final JSON instead of touching the real `~/.senpi/agent`.8182Task-component QA in this package: `packages/omo-senpi/scripts/qa/task-13.test.ts` exercises the task engine wiring, `task-e2e.mjs` covers single and batch task lifecycles, `team-e2e.mjs` covers injection-driven delivery, shutdown-via-`task_send`, stale-reservation reclaim, member-liveness events, and kill/restart exactly-once recovery, and `task-rpc-e2e.mjs --self-test` pins the RPC driver scripts. The `@oh-my-opencode/senpi-task` unit + chaos suites (`bun test packages/senpi-task`) cover the state machine, runners, and completion invariants. The task engine's own standalone manual drivers live under `packages/senpi-task/scripts/` (see [`packages/senpi-task/AGENTS.md`](../senpi-task/AGENTS.md)).8384## Evidence Rules8586Live Senpi QA evidence goes under `.omo/evidence/omo-senpi-adapter/`, one subdirectory per change or task. Record:8788- what command or manual action was run;89- what behavior it was meant to prove;90- the observed result, including final JSON from the QA driver when present;91- isolation proof, especially the sandbox `SENPI_CODING_AGENT_DIR` and whether the real Senpi agent dir stayed untouched;92- omitted or redacted material, especially raw logs that could contain secrets.9394Do not claim live Senpi QA from unit tests alone. `bun run test:senpi` is the package gate; the scripts in `scripts/qa/` are the real harness proof.95
Also in code-yeongyu/oh-my-openagent
Diff this repo’s formatsOne repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| code-yeongyu/oh-my-openagentpackages/omo-opencode/src/features/claude-code-agent-loader/AGENTS.md · 67k | AGENTS.md | archdeploymentagent-behaviour | 62/100 | 2 days ago | |
| code-yeongyu/oh-my-openagentpackages/omo-opencode/src/features/claude-code-mcp-loader/AGENTS.md · 67k | AGENTS.md | lint-formatarchsecuritydeployment+1 | 66/100 | 2 days ago | |
| code-yeongyu/oh-my-openagentpackages/omo-opencode/src/tools/background-task/AGENTS.md · 67k | AGENTS.md | arch | 70/100 | 2 days ago | |
| code-yeongyu/oh-my-openagentscript/AGENTS.md · 67k | AGENTS.md | buildtestarchdeployment | 80/100 | 2 days ago | |
| code-yeongyu/oh-my-openagentpackages/omo-opencode/src/features/claude-code-plugin-loader/AGENTS.md · 67k | AGENTS.md | archdeploymentagent-behaviour | 70/100 | 2 days ago | |
| code-yeongyu/oh-my-openagent.agents/AGENTS.md · 67k | AGENTS.md | stylearchtesting-strategydatabase | 64/100 | 2 days ago | |
| code-yeongyu/oh-my-openagent.opencode/AGENTS.md · 67k | AGENTS.md | stylearchdo-not | 71/100 | 2 days ago | |
| code-yeongyu/oh-my-openagentAGENTS.md · 67k | AGENTS.md | setupbuildtestlint-format+11 | 84/100 | 2 days ago | |
| code-yeongyu/oh-my-openagentassets/AGENTS.md · 67k | AGENTS.md | buildteststylearch | 88/100 | 2 days ago | |
| code-yeongyu/oh-my-openagentbin/AGENTS.md · 67k | AGENTS.md | teststylearch | 64/100 | 2 days ago | |
| code-yeongyu/oh-my-openagentpackages/AGENTS.md · 67k | AGENTS.md | buildtestlint-formatstyle+3 | 83/100 | 2 days ago | |
| code-yeongyu/oh-my-openagentpackages/agents-md-core/AGENTS.md · 67k | AGENTS.md | archdependenciesapi | 48/100 | 2 days ago | |
| code-yeongyu/oh-my-openagentpackages/boulder-state/AGENTS.md · 67k | AGENTS.md | archapi | 48/100 | 2 days ago | |
| code-yeongyu/oh-my-openagentpackages/claude-code-compat-core/AGENTS.md · 67k | AGENTS.md | archagent-behaviour | 56/100 | 2 days ago | |
| code-yeongyu/oh-my-openagentpackages/comment-checker-core/AGENTS.md · 67k | AGENTS.md | archdependenciesapi | 48/100 | 2 days ago | |
| code-yeongyu/oh-my-openagentpackages/delegate-core/AGENTS.md · 67k | AGENTS.md | stylearchdependenciesapi | 60/100 | 2 days ago | |
| code-yeongyu/oh-my-openagentpackages/git-bash-mcp/AGENTS.md · 67k | AGENTS.md | buildtestlint-formatarch+1 | 82/100 | 2 days ago | |
| code-yeongyu/oh-my-openagentpackages/hashline-core/AGENTS.md · 67k | AGENTS.md | archtypesdependenciesapi | 48/100 | 2 days ago | |
| code-yeongyu/oh-my-openagentpackages/lsp-core/AGENTS.md · 67k | AGENTS.md | archmonorepo | 43/100 | 2 days ago | |
| code-yeongyu/oh-my-openagentpackages/lsp-daemon/AGENTS.md · 67k | AGENTS.md | buildtestlint-formatarch+1 | 89/100 | today |
Diff against packages/omo-opencode/src/features/claude-code-agent-loader/AGENTS.md Diff against packages/omo-opencode/src/features/claude-code-mcp-loader/AGENTS.md Diff against packages/omo-opencode/src/tools/background-task/AGENTS.md Diff against script/AGENTS.md Diff against packages/omo-opencode/src/features/claude-code-plugin-loader/AGENTS.md Diff against .agents/AGENTS.md Diff against .opencode/AGENTS.md Diff against AGENTS.md Diff against assets/AGENTS.md Diff against bin/AGENTS.md Diff against packages/AGENTS.md Diff against packages/agents-md-core/AGENTS.md Diff against packages/boulder-state/AGENTS.md Diff against packages/claude-code-compat-core/AGENTS.md Diff against packages/comment-checker-core/AGENTS.md Diff against packages/delegate-core/AGENTS.md Diff against packages/git-bash-mcp/AGENTS.md Diff against packages/hashline-core/AGENTS.md Diff against packages/lsp-core/AGENTS.md Diff against packages/lsp-daemon/AGENTS.md
Similar configs
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| aaif-goose/gooseAGENTS.md · 52k | AGENTS.md | setupbuildtestlint-format+6 | 100/100 | 3 days ago | |
| TryGhost/Ghoste2e/AGENTS.md · 55k | AGENTS.md | setupteststylearch+2 | 100/100 | 3 days ago | |
| duckduckgo/content-scope-scriptsspecial-pages/AGENTS.md · 70 | AGENTS.md | buildteststylearch+3 | 100/100 | 3 days ago | |
| n8n-io/n8npackages/@n8n/agents/AGENTS.md · 199k | AGENTS.md | buildteststylearch+3 | 100/100 | 3 days ago | |
| mui/material-uiAGENTS.md · 99k | AGENTS.md | setupbuildtestlint-format+9 | 100/100 | 3 days ago | |
| SkeneTechnologies/skene-cookbookAGENTS.md · 51 | AGENTS.md | setupbuildtestlint-format+7 | 100/100 | 2 days ago | |
| trick77/agents-md-syncAGENTS.md · 2 | AGENTS.md | setupbuildteststyle+5 | 100/100 | 3 days ago | |
| code-yeongyu/oh-my-openagentpackages/web/AGENTS.md · 67k | AGENTS.md | setupbuildtestlint-format+6 | 100/100 | 2 days ago |
