feat: add Codex + Copilot CLI harness backends#24
Open
nhuelstng wants to merge 21 commits into
Open
Conversation
Local worktrees created during investigation/feature work should not be tracked.
- Add codex and copilot Harness descriptors to harnessRegistry() - Add SessionListCodex and SessionListCopilot enum values - Add listCodex() and listCopilot() best-effort session listing - Codex: reads ~/.codex/sessions/ (path undocumented, best-effort) - Copilot: reads ~/.copilot/session-store.db via sqlite3 CLI (schema-gated) - Thread codexRoot + copilotDB through list() for testability - Copilot alias is 'co' (not 'gh-copilot' — exec is standalone 'copilot') - Codex alias is 'cx' - Both have ServerLaunch: nil (serve runs inner as-is) - TDD: tests written first, verified RED, then implemented to GREEN
- Render() takes activate-response JSON + skillsDir, returns markdown - Handles skill states: ready, pending-credentials, broken - Handles global-skill target_path warning (finding #10) - TDD: tests written first, verified RED, then implemented to GREEN Skipped: omac manifest subcommand, bridge migration (finding #16 — split into separate change to avoid scope creep risk to working harnesses).
- .codex/hooks/omac-bridge.sh: SessionStart hook, activates + emits manifest - .codex/hooks.json: registers bridge for SessionStart (startup|resume|clear|compact) - No Stop/deactivate handler (finding #1: codex Stop is turn-scoped, not session-scoped) - Uses hookSpecificOutput.additionalContext (same nesting as Claude Code) - Uses git-root-relative path for portability (finding #8) - Bridge test: verifies script exists, runs, is inert when omac absent
- .copilot/hooks/omac-bridge.sh: SessionStart + SessionEnd hook - .copilot/hooks/omac.json: user-level registration (finding #8: not .github/hooks/) - Registers with PascalCase event names (finding #3: snake_case payload) - Uses hookSpecificOutput.additionalContext (finding #2: VS Code-compatible) - Copilot has SessionEnd (unlike codex) → deactivate on session end - Uses git-root-relative path for portability (finding #8) - Bridge test: verifies script exists, runs, is inert when omac absent
- Codex: no Stop/deactivate (turn-scoped, finding #1) - Copilot: user-level hooks not .github/hooks/ (finding #8) - Copilot: PascalCase events, hookSpecificOutput nesting (findings #2,#3) - Copilot alias 'co' not 'gh-copilot' (finding #13) - sqlite3 CLI not modernc.org/sqlite (finding #6) - list() signature matches actual code (finding #7) - Manifest migration deferred to separate change (finding #16) - File impact table updated to match actual implementation
… check, env overrides)
…it codes, ConfigHome, XDG, cross-package)
…v overrides) - omac manifest subcommand wrapping manifest.Render() for debugging - Pre-flight binary check (exec.LookPath) in runLaunch + runServe - Harness binary status section in omac doctor (advisory) - HomeEnv field + ConfigHome() method on Harness for all 4 harnesses - Session path resolvers honor *_HOME env overrides via ConfigHome() - GlobalSkillsDir() + GlobalBridgeDir() use ConfigHome()
There was a problem hiding this comment.
Pull request overview
This PR expands omac’s harness ecosystem by adding Codex CLI and GitHub Copilot CLI as first-class harness backends, plus follow-on CLI/config improvements (manifest rendering command, inner-binary preflight checks, and *_HOME config-home overrides) and associated docs/bridge assets.
Changes:
- Add
codex/copilotharness descriptors, session-list kinds, and session listing implementations. - Extract a shared skills-manifest renderer (
internal/manifest.Render) and expose it viaomac manifest. - Add preflight inner-harness binary checks (start/serve) and advisory harness-binary reporting in
omac doctor, plus docs/specs/bridge hook assets.
Reviewed changes
Copilot reviewed 29 out of 30 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Documents new harness tokens/aliases and updates usage examples and harness tables. |
| openspec/changes/support-codex-copilot-harnesses/tasks.md | Adds/records implementation task tracking for codex+copilot and related follow-ons. |
| openspec/changes/support-codex-copilot-harnesses/proposal.md | Adds an OpenSpec proposal describing codex+copilot harness support. |
| internal/session/session.go | Adds Codex/Copilot session store discovery and listing dispatch. |
| internal/session/session_test.go | Extends session-listing tests to cover new harnesses and missing-store behavior. |
| internal/sandboxprofile/resolve.go | Allows default sandbox filesystem access to ~/.codex and ~/.copilot. |
| internal/manifest/manifest.go | Introduces a harness-agnostic manifest renderer for activate-response JSON. |
| internal/manifest/manifest_test.go | Adds unit tests for manifest rendering across skill states. |
| internal/config/harness.go | Registers codex/copilot harnesses; adds HomeEnv + ConfigHome() and wires global dirs through it. |
| internal/config/harness_test.go | Adds tests for codex/copilot descriptors and *_HOME overrides. |
| internal/cli/start.go | Adds shared checkInnerBinary and wires it into omac start launch flow. |
| internal/cli/serve.go | Wires inner-binary preflight check into omac serve. |
| internal/cli/manifest_cmd.go | Adds omac manifest subcommand for rendering manifest text from activate JSON. |
| internal/cli/manifest_cmd_test.go | Adds tests for omac manifest (stdin/file/invalid/misuse cases). |
| internal/cli/doctor.go | Adds an “Inner harnesses” section reporting binary presence on PATH. |
| internal/cli/cli.go | Registers the new manifest subcommand and updates usage text. |
| internal/cli/binary_check_test.go | Adds unit tests for checkInnerBinary and doctor output coverage. |
| internal/builtinskills/assets/omac-write-a-skill/references/creating-a-skill.md | Updates bundled guidance doc to mention codex/copilot harness directories and bridges. |
| docs/superpowers/specs/2026-06-29-deferred-items-design.md | Adds a design/spec for the “deferred items” (manifest cmd, binary checks, env overrides). |
| docs/superpowers/specs/2026-06-29-codex-copilot-backends-design.md | Adds a detailed design spec for codex/copilot harness support. |
| docs/superpowers/plans/2026-06-29-deferred-items.md | Adds an implementation plan for deferred items (now implemented in this PR). |
| docs/superpowers/plans/2026-06-29-codex-copilot-backends.md | Adds an implementation plan for remaining codex/copilot work. |
| CREATING_A_SKILL.md | Updates public skill authoring doc for codex/copilot directories and bridges. |
| .gitignore | Ignores local /.worktrees/ directory. |
| .copilot/hooks/omac.json | Adds Copilot hook registration JSON (SessionStart/SessionEnd). |
| .copilot/hooks/omac-bridge.sh | Adds Copilot bridge hook script (activate/deactivate + manifest injection). |
| .copilot/hooks/bridge_test.go | Adds a Go test intended to sanity-check the Copilot bridge script. |
| .codex/hooks/omac-bridge.sh | Adds Codex bridge hook script (activate + manifest injection; no deactivate). |
| .codex/hooks/bridge_test.go | Adds a Go test intended to sanity-check the Codex bridge script. |
| .codex/hooks.json | Adds Codex hook registration JSON (SessionStart only). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| `~/.claude/projects/<encoded-cwd>/<id>.jsonl` (where `<encoded-cwd>` is the | ||
| folder path with non-alphanumerics replaced by `-`, the way Claude Code names | ||
| it). Titles come from the session's `aiTitle`, and a file's embedded `cwd` | ||
| it), Codex via `codex session list`, Copilot via `copilot session list`. |
Comment on lines
+98
to
+102
| Deferred to separate change: | ||
| - `omac manifest` subcommand + migration of existing bridges to call it | ||
| - README.md harness list + CREATING_A_SKILL.md skills-dirs updates | ||
| - `COPILOT_HOME` env override support | ||
| - Pre-flight binary check (`exec.LookPath`) |
| - [x] 6.1 Create `openspec/changes/support-codex-copilot-harnesses/proposal.md` | ||
| - [x] 6.2 Create `openspec/changes/support-codex-copilot-harnesses/tasks.md` | ||
|
|
||
| ## 7. Deferred to separate change |
| # Deferred Items: Manifest Subcommand, Binary Check, Env Overrides | ||
|
|
||
| **Date:** 2026-06-29 | ||
| **Status:** Design approved, pending implementation |
Comment on lines
+483
to
+484
| sortNewestFirst(sessions) | ||
| return sessions |
Comment on lines
+1
to
+5
| package bridge | ||
|
|
||
| import ( | ||
| "encoding/json" | ||
| "os/exec" |
Comment on lines
+1
to
+5
| package bridge | ||
|
|
||
| import ( | ||
| "encoding/json" | ||
| "os/exec" |
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.
Summary
Add Codex CLI (
codex) and GitHub Copilot CLI (copilot) as supported harness backends in omac, following the same declarative pattern used for OpenCode and Claude Code. Brings the total to four supported agentic coders.Changes
Go implementation (TDD):
internal/config/harness.go— codex + copilotHarnessdescriptors,SessionListCodex/SessionListCopilotenum valuesinternal/session/session.go—listCodex()(reads~/.codex/sessions/),listCopilot()(reads~/.copilot/session-store.dbvia sqlite3 CLI)internal/manifest/manifest.go— sharedRender()function extracted (handles ready/pending-credentials/broken states + global target_path warning)internal/sandboxprofile/resolve.go—~/.codex+~/.copilotadded to default filesystem allow-listBridge scripts:
.codex/hooks/omac-bridge.sh+.codex/hooks.json— SessionStart only (Stop is turn-scoped, no deactivation; relies on TTL reaper).copilot/hooks/omac-bridge.sh+.copilot/hooks/omac.json— SessionStart + SessionEnd, user-level hooksDocs:
README.md— harness tables, bridge mechanisms, quickstart, continue/resume examples, sandbox profileCREATING_A_SKILL.md— skills dirs, discovery section, sidecar section for all 4 harnessesdocs/superpowers/openspec/changes/support-codex-copilot-harnesses/Key decisions
Stopevent is turn-scoped, not session-scoped. Relies on TTL reaper.SessionStart/SessionEnd) for snake_case payload compatibility.copilot/hooks/omac.json(not repo-level.github/hooks/)co(exec is standalonecopilotbinary, notgh-copilot)Test plan
go build ./...passesgo test ./...passes (all packages green)TestBundleGuideMatchesRepoRoot— bundled guide synced with repo rootDeferred to separate change
omac manifestsubcommand + migration of existing bridgesCOPILOT_HOMEenv override supportexec.LookPath)