@lyupro/codex-bridge 0.5.1 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/CHANGELOG.md +420 -252
  2. package/README.md +21 -4
  3. package/bin/codex-bridge.mjs +4 -0
  4. package/cli/doctor.mjs +399 -293
  5. package/cli/frontmatter.mjs +137 -0
  6. package/cli/hook.mjs +2 -2
  7. package/cli/install-record.mjs +2 -2
  8. package/cli/install.mjs +14 -2
  9. package/cli/manifest.mjs +23 -22
  10. package/cli/permissions.mjs +2 -2
  11. package/cli/projects.mjs +3 -3
  12. package/cli/prune-plan.mjs +2 -2
  13. package/cli/prune.mjs +1 -1
  14. package/cli/read.mjs +2 -2
  15. package/cli/rules-owners.mjs +2 -2
  16. package/cli/run-lookup.mjs +3 -3
  17. package/cli/runs-inventory.mjs +3 -3
  18. package/cli/settings-merge.mjs +56 -11
  19. package/cli/stop.mjs +5 -5
  20. package/cli/unlock.mjs +7 -7
  21. package/package.json +2 -2
  22. package/scripts/check-file-size.mjs +1 -1
  23. package/scripts/run-tests.mjs +30 -1
  24. package/scripts/suite-count.mjs +65 -0
  25. package/src/agents/codex-build.md +265 -231
  26. package/src/agents/codex-review.md +219 -184
  27. package/src/agents/codex-scout.md +232 -200
  28. package/src/{hooks → home/hooks}/guard-tries.mjs +1 -1
  29. package/src/{hooks → home/hooks}/live-runs.mjs +43 -3
  30. package/src/home/hooks/order-gate.mjs +135 -0
  31. package/src/{hooks → home/hooks}/prune-guard.mjs +2 -2
  32. package/src/{hooks → home/hooks}/reply-guard.mjs +117 -97
  33. package/src/home/hooks/reply-parser.mjs +27 -0
  34. package/src/home/hooks/reply-verdicts.mjs +174 -0
  35. package/src/home/hooks/shell-write-intent.mjs +120 -0
  36. package/src/{hooks → home/hooks}/stop-guard.mjs +3 -3
  37. package/src/home/hooks/worktree-lock.mjs +109 -0
  38. package/src/home/hooks/worktree-witness.mjs +113 -0
  39. package/src/home/lib/dispatcher-order.mjs +36 -0
  40. package/src/{heartbeat.mjs → home/lib/heartbeat.mjs} +4 -1
  41. package/src/{hook-definitions.mjs → home/lib/hook-definitions.mjs} +11 -2
  42. package/src/home/lib/host-refusal.mjs +20 -0
  43. package/src/{json-file.mjs → home/lib/json-file.mjs} +4 -4
  44. package/src/{meta → home/lib/meta}/paths.mjs +20 -1
  45. package/src/{meta → home/lib/meta}/reply.mjs +1 -1
  46. package/src/{meta → home/lib/meta}/verdict.mjs +1 -1
  47. package/src/{no-self-execution.mjs → home/lib/no-self-execution.mjs} +7 -2
  48. package/src/{required-inputs.mjs → home/lib/required-inputs.mjs} +56 -5
  49. package/src/{retention.mjs → home/lib/retention.mjs} +1 -1
  50. package/src/{run-codex.mjs → home/lib/run-codex.mjs} +39 -11
  51. package/src/{run-config.mjs → home/lib/run-config.mjs} +2 -2
  52. package/src/{runner → home/lib/runner}/args.mjs +86 -10
  53. package/src/{runner → home/lib/runner}/attach.mjs +58 -9
  54. package/src/{runner → home/lib/runner}/codex-cmd.mjs +398 -392
  55. package/src/{runner → home/lib/runner}/launcher.mjs +33 -21
  56. package/src/home/lib/runner/order-owner.mjs +28 -0
  57. package/src/{runner → home/lib/runner}/run-env.mjs +1 -1
  58. package/src/home/lib/runner/sandbox-flags.mjs +27 -0
  59. package/src/home/lib/runner/task-file.mjs +92 -0
  60. package/src/home/lib/runner/task-input.mjs +26 -0
  61. package/src/{runner → home/lib/runner}/worker.mjs +1 -1
  62. package/src/home/lib/shell-unsafe.mjs +26 -0
  63. package/src/{write-meta.mjs → home/lib/write-meta.mjs} +12 -1
  64. package/src/hooks/order-gate.mjs +0 -73
  65. package/src/hooks/worktree-lock.mjs +0 -77
  66. /package/src/{run-config.json → home/config.json} +0 -0
  67. /package/src/{conventions.md → home/conventions.md} +0 -0
  68. /package/src/{cli-names.mjs → home/lib/cli-names.mjs} +0 -0
  69. /package/src/{meta → home/lib/meta}/chain.mjs +0 -0
  70. /package/src/{meta → home/lib/meta}/deadline.mjs +0 -0
  71. /package/src/{meta → home/lib/meta}/environment.mjs +0 -0
  72. /package/src/{meta → home/lib/meta}/events.mjs +0 -0
  73. /package/src/{meta → home/lib/meta}/outcome.mjs +0 -0
  74. /package/src/{meta → home/lib/meta}/pre-start.mjs +0 -0
  75. /package/src/{meta → home/lib/meta}/reason.mjs +0 -0
  76. /package/src/{meta → home/lib/meta}/run-state.mjs +0 -0
  77. /package/src/{meta → home/lib/meta}/startup.mjs +0 -0
  78. /package/src/{meta → home/lib/meta}/transport.mjs +0 -0
  79. /package/src/{process-identity.mjs → home/lib/process-identity.mjs} +0 -0
  80. /package/src/{runner → home/lib/runner}/continuation.mjs +0 -0
  81. /package/src/{runner → home/lib/runner}/conventions.mjs +0 -0
  82. /package/src/{runner → home/lib/runner}/git-state.mjs +0 -0
  83. /package/src/{runner → home/lib/runner}/project-dir.mjs +0 -0
  84. /package/src/{runner → home/lib/runner}/prompts.mjs +0 -0
  85. /package/src/{runner → home/lib/runner}/run-context.mjs +0 -0
  86. /package/src/{runner → home/lib/runner}/runs-root.mjs +0 -0
  87. /package/src/{runner → home/lib/runner}/schemas.mjs +0 -0
  88. /package/src/{runner → home/lib/runner}/scope-check.mjs +0 -0
  89. /package/src/{stop-contract.mjs → home/lib/stop-contract.mjs} +0 -0
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # codex-bridge
2
2
 
3
- **Delegate implementation, reconnaissance and review from Claude Code to Codex — five host guards, zero runtime dependencies, zero build steps.**
3
+ **Delegate implementation, reconnaissance and review from Claude Code to Codex — six host guards, zero runtime dependencies, zero build steps.**
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/@lyupro/codex-bridge)](https://www.npmjs.com/package/@lyupro/codex-bridge)
6
6
  [![Node.js](https://img.shields.io/node/v/@lyupro/codex-bridge)](https://www.npmjs.com/package/@lyupro/codex-bridge)
@@ -22,6 +22,10 @@ codexb install # the short name, same command
22
22
 
23
23
  Two other entry points reach the same command: `npx @lyupro/codex-bridge install` for a one-off run without a global install, and `node bin/codex-bridge.mjs install` from a clone. Every command below works through all three.
24
24
 
25
+ Shipped agents invoke delegated runs through `codex-bridge run`. This is a permission contract,
26
+ not a style choice: the stable package command lets host permission rules match the invocation
27
+ without exposing an installation-specific absolute path and prompting on every delegation.
28
+
25
29
  Use `--scope project` to install the Claude Code-facing files under `<repo>/.claude`; the default user scope uses `~/.claude`.
26
30
 
27
31
  Installation has two roots:
@@ -29,6 +33,10 @@ Installation has two roots:
29
33
  - `~/.lyupro/.codex-bridge/` contains package runtime files, guards, configuration, conventions, and the installation record.
30
34
  - The selected Claude Code root (`~/.claude/` or `<repo>/.claude/`) contains the three agents, two slash commands, merged hook registrations in `settings.json`, and run artifacts under `codex-runs/`.
31
35
 
36
+ The repository's `src/home/` directory is the literal image copied into the branded root: its
37
+ `hooks/`, `lib/`, `config.json`, and `conventions.md` paths are the host paths without remapping.
38
+ Only npm's `package.json` is copied into that root from outside the image.
39
+
32
40
  Before every `settings.json` write, the existing file is backed up. Existing settings and foreign hooks are preserved. `--dry-run` prints the plan without writing.
33
41
 
34
42
  If a global install and a clone coexist, you have two package copies. `codex-bridge update`, `codexb update`, and the clone entry point copy files from whichever copy launched the command; using the wrong one can replace a newer host installation with older files.
@@ -47,12 +55,12 @@ If a global install and a clone coexist, you have two package copies. `codex-bri
47
55
  - **Invalid work is rejected before quota is spent.** Scope, order, retry, branch, and continuation checks run before a run folder is created.
48
56
  - **Verdicts come from artifacts.** CLI events, git state, and the declared report decide the result, not model claims about itself.
49
57
  - **Identical retries attach safely.** Repeating the same command joins the active run instead of starting another one.
50
- - **5 host guards enforce the boundary.** `reply-guard`, `order-gate`, `worktree-lock`, `prune-guard`, and `stop-guard` cover replies, orders, edits, deletion, and stopping.
58
+ - **6 host guards enforce the boundary.** `reply-guard`, `order-gate`, `worktree-lock`, `prune-guard`, and `stop-guard` cover replies, orders, edits, deletion, and stopping; `worktree-witness` stands behind the lock and names a write that reached the tree anyway.
51
59
  - **Installation is identifiable and reversible.** Writes to `settings.json` are merged and backed up; uninstall removes recorded package files only.
52
60
  - **Every run leaves an audit folder.** The verbatim task, scope, before/after git state, events, report, verdict, and reason remain together.
53
61
  - **Zero runtime dependencies and zero build steps.** The package is plain `.mjs` on the Node.js standard library.
54
62
 
55
- The current suite contains **604 automated tests: 603 passing and 1 skipped**.
63
+ The current suite contains **757 automated tests: 756 passing and 1 skipped**.
56
64
 
57
65
  ## Verify
58
66
 
@@ -81,7 +89,15 @@ Output on a healthy host (trimmed):
81
89
  [ok] liveRuns: 0 runs working right now
82
90
  ```
83
91
 
84
- `doctor` reports the selected host, package source, installed files and guards, Codex availability, retention policy, permissions, live runs, and the current repository's run folder.
92
+ `doctor` reports the selected host, package source, installed files and guards, Codex availability, retention policy, permissions, live runs, and the current repository's run folder. The `agents` line is a read, not a file count: each installed definition is parsed and its `name` checked against the dispatcher it claims to be, because a definition the host cannot read is a dispatcher that does not exist while every other line still says `[ok]`. Content that drifts from the packaged definition is a failure, not a warning: `doctor` exits 1 and names `codex-bridge update --force`, because a host running someone else's agent files may be calling the runner in a form no permission rule matches.
93
+
94
+ If a session answers `Agent type 'codex-build' not found`, a run can still be started without the dispatcher — the agent is a wrapper that types one command:
95
+
96
+ ```bash
97
+ codex-bridge run --agent codex-build --repo <repository> --order-id <id> --scope <globs> --task-file <absolute path>
98
+ ```
99
+
100
+ The trade-off is explicit: `order-gate` and `reply-guard` sit on the dispatcher call, so a direct run is unguarded and its result is judged by the worktree and the suite.
85
101
 
86
102
  ## Update
87
103
 
@@ -111,6 +127,7 @@ Transport files from runs at least **30 days** old are pruned automatically when
111
127
  | `permissions [add\|remove] [--scope user\|project] [--host <path>]` | Inspect or manage optional shell rules. |
112
128
  | `uninstall [--scope user\|project] [--host <path>] [--dry-run]` | Remove recorded package files while preserving run artifacts. |
113
129
  | `doctor [--scope user\|project] [--host <path>]` | Diagnose the selected host and Codex connection. |
130
+ | `run <runner options> --task-file <abs path>` | Start or attach to a delegated run through the permission-stable package command. The task file carries the statement, the scout questions and the verification command; its path must be absolute. Piping the statement on stdin is the alternative channel, and the two cannot be combined. |
114
131
  | `projects [<name>] [--json]` | List projects or runs in the run store. |
115
132
  | `prune <project> [<run>] [--purge] [--older-than <age>] [-f] [--json]` | Plan or perform operator-confirmed cleanup. |
116
133
  | `unlock [<project>\|--all]` | Close records whose runner is gone. |
@@ -7,6 +7,7 @@ import { resolveHost } from '../cli/hosts.mjs';
7
7
  import { install } from '../cli/install.mjs';
8
8
  import { projects } from '../cli/projects.mjs';
9
9
  import { read } from '../cli/read.mjs';
10
+ import { runCodexCommand } from '../src/home/lib/run-codex.mjs';
10
11
  import { packageInfo } from '../cli/manifest.mjs';
11
12
  import { permissions } from '../cli/permissions.mjs';
12
13
  import { prune } from '../cli/prune.mjs';
@@ -23,6 +24,7 @@ Usage:
23
24
  codex-bridge permissions [add|remove] [--scope user|project] [--host <path>]
24
25
  codex-bridge uninstall [--scope user|project] [--host <path>] [--dry-run]
25
26
  codex-bridge doctor [--scope user|project] [--host <path>]
27
+ codex-bridge run <runner options> --task-file <path>
26
28
  codex-bridge projects [<name>] [--json]
27
29
  codex-bridge prune <project> [<run>] [--purge] [--older-than <age>] [-f] [--json]
28
30
  codex-bridge prune --all-projects [--older-than <age>] [-f] [--json]
@@ -40,6 +42,7 @@ Commands:
40
42
  permissions Show, add, or remove optional shell permission rules
41
43
  uninstall Remove installed files while preserving run artifacts
42
44
  doctor Diagnose the selected Claude Code host
45
+ run Start or attach to a delegated Codex run
43
46
  projects List projects or runs from the run store
44
47
  prune Remove archived transport, or purge selected run folders
45
48
  unlock Close running records whose runner is gone
@@ -84,6 +87,7 @@ export async function main(argv, io = console) {
84
87
  io.log((await packageInfo()).version);
85
88
  return 0;
86
89
  }
90
+ if (command === 'run') return runCodexCommand(rest);
87
91
  if (command === 'doctor') {
88
92
  const host = resolveHost(commandOptions(command, rest));
89
93
  const result = await diagnose({ host });