oh-my-codex 0.20.3 → 0.20.5
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.
- package/Cargo.lock +35 -18
- package/Cargo.toml +1 -1
- package/README.md +2 -2
- package/crates/omx-runtime/Cargo.toml +3 -0
- package/crates/omx-runtime/src/main.rs +390 -0
- package/crates/omx-runtime/tests/execution.rs +264 -0
- package/dist/adapt/__tests__/herdr-target.test.d.ts +2 -0
- package/dist/adapt/__tests__/herdr-target.test.d.ts.map +1 -0
- package/dist/adapt/__tests__/herdr-target.test.js +72 -0
- package/dist/adapt/__tests__/herdr-target.test.js.map +1 -0
- package/dist/adapt/contracts.d.ts +1 -1
- package/dist/adapt/contracts.d.ts.map +1 -1
- package/dist/adapt/contracts.js +1 -1
- package/dist/adapt/contracts.js.map +1 -1
- package/dist/adapt/herdr/__tests__/authority.test.d.ts +2 -0
- package/dist/adapt/herdr/__tests__/authority.test.d.ts.map +1 -0
- package/dist/adapt/herdr/__tests__/authority.test.js +49 -0
- package/dist/adapt/herdr/__tests__/authority.test.js.map +1 -0
- package/dist/adapt/herdr/__tests__/bridge.test.d.ts +2 -0
- package/dist/adapt/herdr/__tests__/bridge.test.d.ts.map +1 -0
- package/dist/adapt/herdr/__tests__/bridge.test.js +176 -0
- package/dist/adapt/herdr/__tests__/bridge.test.js.map +1 -0
- package/dist/adapt/herdr/__tests__/sanitize.test.d.ts +2 -0
- package/dist/adapt/herdr/__tests__/sanitize.test.d.ts.map +1 -0
- package/dist/adapt/herdr/__tests__/sanitize.test.js +45 -0
- package/dist/adapt/herdr/__tests__/sanitize.test.js.map +1 -0
- package/dist/adapt/herdr/__tests__/semantic.test.d.ts +2 -0
- package/dist/adapt/herdr/__tests__/semantic.test.d.ts.map +1 -0
- package/dist/adapt/herdr/__tests__/semantic.test.js +130 -0
- package/dist/adapt/herdr/__tests__/semantic.test.js.map +1 -0
- package/dist/adapt/herdr/__tests__/seq-store.test.d.ts +2 -0
- package/dist/adapt/herdr/__tests__/seq-store.test.d.ts.map +1 -0
- package/dist/adapt/herdr/__tests__/seq-store.test.js +54 -0
- package/dist/adapt/herdr/__tests__/seq-store.test.js.map +1 -0
- package/dist/adapt/herdr/__tests__/socket-live.test.d.ts +2 -0
- package/dist/adapt/herdr/__tests__/socket-live.test.d.ts.map +1 -0
- package/dist/adapt/herdr/__tests__/socket-live.test.js +104 -0
- package/dist/adapt/herdr/__tests__/socket-live.test.js.map +1 -0
- package/dist/adapt/herdr/__tests__/team-map.test.d.ts +2 -0
- package/dist/adapt/herdr/__tests__/team-map.test.d.ts.map +1 -0
- package/dist/adapt/herdr/__tests__/team-map.test.js +46 -0
- package/dist/adapt/herdr/__tests__/team-map.test.js.map +1 -0
- package/dist/adapt/herdr/__tests__/transport.test.d.ts +2 -0
- package/dist/adapt/herdr/__tests__/transport.test.d.ts.map +1 -0
- package/dist/adapt/herdr/__tests__/transport.test.js +160 -0
- package/dist/adapt/herdr/__tests__/transport.test.js.map +1 -0
- package/dist/adapt/herdr/__tests__/wiring.test.d.ts +2 -0
- package/dist/adapt/herdr/__tests__/wiring.test.d.ts.map +1 -0
- package/dist/adapt/herdr/__tests__/wiring.test.js +118 -0
- package/dist/adapt/herdr/__tests__/wiring.test.js.map +1 -0
- package/dist/adapt/herdr/authority.d.ts +34 -0
- package/dist/adapt/herdr/authority.d.ts.map +1 -0
- package/dist/adapt/herdr/authority.js +71 -0
- package/dist/adapt/herdr/authority.js.map +1 -0
- package/dist/adapt/herdr/bridge.d.ts +84 -0
- package/dist/adapt/herdr/bridge.d.ts.map +1 -0
- package/dist/adapt/herdr/bridge.js +222 -0
- package/dist/adapt/herdr/bridge.js.map +1 -0
- package/dist/adapt/herdr/sanitize.d.ts +20 -0
- package/dist/adapt/herdr/sanitize.d.ts.map +1 -0
- package/dist/adapt/herdr/sanitize.js +70 -0
- package/dist/adapt/herdr/sanitize.js.map +1 -0
- package/dist/adapt/herdr/semantic.d.ts +67 -0
- package/dist/adapt/herdr/semantic.d.ts.map +1 -0
- package/dist/adapt/herdr/semantic.js +170 -0
- package/dist/adapt/herdr/semantic.js.map +1 -0
- package/dist/adapt/herdr/seq-store.d.ts +32 -0
- package/dist/adapt/herdr/seq-store.d.ts.map +1 -0
- package/dist/adapt/herdr/seq-store.js +126 -0
- package/dist/adapt/herdr/seq-store.js.map +1 -0
- package/dist/adapt/herdr/team-map.d.ts +30 -0
- package/dist/adapt/herdr/team-map.d.ts.map +1 -0
- package/dist/adapt/herdr/team-map.js +37 -0
- package/dist/adapt/herdr/team-map.js.map +1 -0
- package/dist/adapt/herdr/transport.d.ts +115 -0
- package/dist/adapt/herdr/transport.d.ts.map +1 -0
- package/dist/adapt/herdr/transport.js +260 -0
- package/dist/adapt/herdr/transport.js.map +1 -0
- package/dist/adapt/herdr/wiring.d.ts +24 -0
- package/dist/adapt/herdr/wiring.d.ts.map +1 -0
- package/dist/adapt/herdr/wiring.js +62 -0
- package/dist/adapt/herdr/wiring.js.map +1 -0
- package/dist/adapt/herdr.d.ts +19 -0
- package/dist/adapt/herdr.d.ts.map +1 -0
- package/dist/adapt/herdr.js +115 -0
- package/dist/adapt/herdr.js.map +1 -0
- package/dist/adapt/index.d.ts +4 -0
- package/dist/adapt/index.d.ts.map +1 -1
- package/dist/adapt/index.js +48 -0
- package/dist/adapt/index.js.map +1 -1
- package/dist/adapt/registry.d.ts.map +1 -1
- package/dist/adapt/registry.js +11 -0
- package/dist/adapt/registry.js.map +1 -1
- package/dist/auth/__tests__/hotswap.test.js +60 -1
- package/dist/auth/__tests__/hotswap.test.js.map +1 -1
- package/dist/auth/__tests__/storage.test.js +33 -1
- package/dist/auth/__tests__/storage.test.js.map +1 -1
- package/dist/auth/hotswap.d.ts +16 -2
- package/dist/auth/hotswap.d.ts.map +1 -1
- package/dist/auth/hotswap.js +22 -7
- package/dist/auth/hotswap.js.map +1 -1
- package/dist/auth/storage.js +1 -1
- package/dist/auth/storage.js.map +1 -1
- package/dist/autopilot/__tests__/ralplan-gate.test.js +86 -1333
- package/dist/autopilot/__tests__/ralplan-gate.test.js.map +1 -1
- package/dist/autopilot/ralplan-gate.d.ts.map +1 -1
- package/dist/autopilot/ralplan-gate.js +7 -6
- package/dist/autopilot/ralplan-gate.js.map +1 -1
- package/dist/cli/__tests__/agents-init.test.js +4 -23
- package/dist/cli/__tests__/agents-init.test.js.map +1 -1
- package/dist/cli/__tests__/api.test.js +61 -24
- package/dist/cli/__tests__/api.test.js.map +1 -1
- package/dist/cli/__tests__/auth.test.js +3 -1
- package/dist/cli/__tests__/auth.test.js.map +1 -1
- package/dist/cli/__tests__/codex-feature-probe.test.js +66 -1
- package/dist/cli/__tests__/codex-feature-probe.test.js.map +1 -1
- package/dist/cli/__tests__/codex-plugin-layout.test.js +70 -2
- package/dist/cli/__tests__/codex-plugin-layout.test.js.map +1 -1
- package/dist/cli/__tests__/detached-leader-teardown.test.d.ts +2 -0
- package/dist/cli/__tests__/detached-leader-teardown.test.d.ts.map +1 -0
- package/dist/cli/__tests__/detached-leader-teardown.test.js +473 -0
- package/dist/cli/__tests__/detached-leader-teardown.test.js.map +1 -0
- package/dist/cli/__tests__/doctor-process-identity-readiness.test.d.ts +2 -0
- package/dist/cli/__tests__/doctor-process-identity-readiness.test.d.ts.map +1 -0
- package/dist/cli/__tests__/doctor-process-identity-readiness.test.js +103 -0
- package/dist/cli/__tests__/doctor-process-identity-readiness.test.js.map +1 -0
- package/dist/cli/__tests__/doctor-state-root-binding.test.d.ts +2 -0
- package/dist/cli/__tests__/doctor-state-root-binding.test.d.ts.map +1 -0
- package/dist/cli/__tests__/doctor-state-root-binding.test.js +139 -0
- package/dist/cli/__tests__/doctor-state-root-binding.test.js.map +1 -0
- package/dist/cli/__tests__/doctor-warning-copy.test.js +35 -3
- package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
- package/dist/cli/__tests__/exec.test.js +75 -0
- package/dist/cli/__tests__/exec.test.js.map +1 -1
- package/dist/cli/__tests__/index.test.js +621 -460
- package/dist/cli/__tests__/index.test.js.map +1 -1
- package/dist/cli/__tests__/launch-fallback.test.js +1020 -143
- package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
- package/dist/cli/__tests__/mcp-parity.test.js +4 -3
- package/dist/cli/__tests__/mcp-parity.test.js.map +1 -1
- package/dist/cli/__tests__/native-assets.test.js +398 -16
- package/dist/cli/__tests__/native-assets.test.js.map +1 -1
- package/dist/cli/__tests__/native-hook-claim-journal.test.js +53 -5
- package/dist/cli/__tests__/native-hook-claim-journal.test.js.map +1 -1
- package/dist/cli/__tests__/ralph.test.js +2 -2
- package/dist/cli/__tests__/ralph.test.js.map +1 -1
- package/dist/cli/__tests__/ralplan-bootstrap-3181.test.js +57 -57
- package/dist/cli/__tests__/ralplan-bootstrap-3181.test.js.map +1 -1
- package/dist/cli/__tests__/ralplan-child-binding-3212.test.d.ts +2 -0
- package/dist/cli/__tests__/ralplan-child-binding-3212.test.d.ts.map +1 -0
- package/dist/cli/__tests__/ralplan-child-binding-3212.test.js +56 -0
- package/dist/cli/__tests__/ralplan-child-binding-3212.test.js.map +1 -0
- package/dist/cli/__tests__/ralplan.test.js +84 -12
- package/dist/cli/__tests__/ralplan.test.js.map +1 -1
- package/dist/cli/__tests__/session-scoped-runtime.test.js +1118 -43
- package/dist/cli/__tests__/session-scoped-runtime.test.js.map +1 -1
- package/dist/cli/__tests__/setup-agents-overwrite.test.js +8 -55
- package/dist/cli/__tests__/setup-agents-overwrite.test.js.map +1 -1
- package/dist/cli/__tests__/setup-install-mode.test.js +183 -4
- package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -1
- package/dist/cli/__tests__/sparkshell-cli.test.js +93 -41
- package/dist/cli/__tests__/sparkshell-cli.test.js.map +1 -1
- package/dist/cli/__tests__/team.test.js +45 -1
- package/dist/cli/__tests__/team.test.js.map +1 -1
- package/dist/cli/__tests__/ultragoal.test.js +117 -2
- package/dist/cli/__tests__/ultragoal.test.js.map +1 -1
- package/dist/cli/__tests__/uninstall.test.js +50 -5
- package/dist/cli/__tests__/uninstall.test.js.map +1 -1
- package/dist/cli/__tests__/update.test.js +669 -177
- package/dist/cli/__tests__/update.test.js.map +1 -1
- package/dist/cli/__tests__/windows-popup-loop-contract.test.js +32 -2
- package/dist/cli/__tests__/windows-popup-loop-contract.test.js.map +1 -1
- package/dist/cli/api.d.ts.map +1 -1
- package/dist/cli/api.js +9 -10
- package/dist/cli/api.js.map +1 -1
- package/dist/cli/codex-feature-probe.d.ts +16 -0
- package/dist/cli/codex-feature-probe.d.ts.map +1 -1
- package/dist/cli/codex-feature-probe.js +44 -0
- package/dist/cli/codex-feature-probe.js.map +1 -1
- package/dist/cli/codex-home.d.ts.map +1 -1
- package/dist/cli/codex-home.js +7 -4
- package/dist/cli/codex-home.js.map +1 -1
- package/dist/cli/doctor.d.ts +17 -0
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +277 -3
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/index.d.ts +231 -12
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2298 -735
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/native-assets.d.ts +25 -0
- package/dist/cli/native-assets.d.ts.map +1 -1
- package/dist/cli/native-assets.js +448 -51
- package/dist/cli/native-assets.js.map +1 -1
- package/dist/cli/native-hook-claim-journal.d.ts +8 -4
- package/dist/cli/native-hook-claim-journal.d.ts.map +1 -1
- package/dist/cli/native-hook-claim-journal.js +30 -8
- package/dist/cli/native-hook-claim-journal.js.map +1 -1
- package/dist/cli/package-manager-ownership.d.ts +63 -0
- package/dist/cli/package-manager-ownership.d.ts.map +1 -0
- package/dist/cli/package-manager-ownership.js +323 -0
- package/dist/cli/package-manager-ownership.js.map +1 -0
- package/dist/cli/ralph.js +2 -2
- package/dist/cli/ralph.js.map +1 -1
- package/dist/cli/ralplan.d.ts +4 -2
- package/dist/cli/ralplan.d.ts.map +1 -1
- package/dist/cli/ralplan.js +76 -34
- package/dist/cli/ralplan.js.map +1 -1
- package/dist/cli/setup-preferences.d.ts +15 -0
- package/dist/cli/setup-preferences.d.ts.map +1 -1
- package/dist/cli/setup-preferences.js +27 -1
- package/dist/cli/setup-preferences.js.map +1 -1
- package/dist/cli/setup.d.ts +3 -0
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +55 -32
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/sparkshell.d.ts.map +1 -1
- package/dist/cli/sparkshell.js +52 -9
- package/dist/cli/sparkshell.js.map +1 -1
- package/dist/cli/ultragoal.d.ts.map +1 -1
- package/dist/cli/ultragoal.js +2 -2
- package/dist/cli/ultragoal.js.map +1 -1
- package/dist/cli/uninstall.d.ts.map +1 -1
- package/dist/cli/uninstall.js +27 -28
- package/dist/cli/uninstall.js.map +1 -1
- package/dist/cli/update-worker.d.ts +2 -0
- package/dist/cli/update-worker.d.ts.map +1 -0
- package/dist/cli/update-worker.js +142 -0
- package/dist/cli/update-worker.js.map +1 -0
- package/dist/cli/update.d.ts +14 -22
- package/dist/cli/update.d.ts.map +1 -1
- package/dist/cli/update.js +192 -241
- package/dist/cli/update.js.map +1 -1
- package/dist/config/__tests__/generator-idempotent.test.js +173 -29
- package/dist/config/__tests__/generator-idempotent.test.js.map +1 -1
- package/dist/config/__tests__/generator-notify.test.js +3 -1
- package/dist/config/__tests__/generator-notify.test.js.map +1 -1
- package/dist/config/generator.d.ts +25 -3
- package/dist/config/generator.d.ts.map +1 -1
- package/dist/config/generator.js +113 -35
- package/dist/config/generator.js.map +1 -1
- package/dist/goal-workflows/__tests__/codex-goal-snapshot.test.js +25 -0
- package/dist/goal-workflows/__tests__/codex-goal-snapshot.test.js.map +1 -1
- package/dist/goal-workflows/codex-goal-snapshot.d.ts +1 -1
- package/dist/goal-workflows/codex-goal-snapshot.d.ts.map +1 -1
- package/dist/goal-workflows/codex-goal-snapshot.js +2 -0
- package/dist/goal-workflows/codex-goal-snapshot.js.map +1 -1
- package/dist/hooks/__tests__/agents-overlay.test.js +3 -1
- package/dist/hooks/__tests__/agents-overlay.test.js.map +1 -1
- package/dist/hooks/__tests__/autopilot-skill-contract.test.js +27 -4
- package/dist/hooks/__tests__/autopilot-skill-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/issue-3293-autopilot-handoff.test.d.ts +2 -0
- package/dist/hooks/__tests__/issue-3293-autopilot-handoff.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/issue-3293-autopilot-handoff.test.js +172 -0
- package/dist/hooks/__tests__/issue-3293-autopilot-handoff.test.js.map +1 -0
- package/dist/hooks/__tests__/keyword-detector.test.js +172 -33
- package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js +173 -11
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js +1 -0
- package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +65 -17
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js +27 -0
- package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js +10 -118
- package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-regression-205.test.js +7 -0
- package/dist/hooks/__tests__/notify-hook-regression-205.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js +2 -2
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +4 -1
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.js +2 -1
- package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +1 -0
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +1 -1
- package/dist/hooks/__tests__/prompt-guidance-contract.test.js +9 -0
- package/dist/hooks/__tests__/prompt-guidance-contract.test.js.map +1 -1
- package/dist/hooks/__tests__/session.test.js +2976 -557
- package/dist/hooks/__tests__/session.test.js.map +1 -1
- package/dist/hooks/agents-overlay.js +1 -1
- package/dist/hooks/agents-overlay.js.map +1 -1
- package/dist/hooks/extensibility/__tests__/dispatcher.test.js +108 -2
- package/dist/hooks/extensibility/__tests__/dispatcher.test.js.map +1 -1
- package/dist/hooks/extensibility/__tests__/sdk.test.js +151 -1
- package/dist/hooks/extensibility/__tests__/sdk.test.js.map +1 -1
- package/dist/hooks/extensibility/dispatcher.d.ts.map +1 -1
- package/dist/hooks/extensibility/dispatcher.js +20 -3
- package/dist/hooks/extensibility/dispatcher.js.map +1 -1
- package/dist/hooks/extensibility/plugin-runner.js +1 -0
- package/dist/hooks/extensibility/plugin-runner.js.map +1 -1
- package/dist/hooks/extensibility/runtime.d.ts.map +1 -1
- package/dist/hooks/extensibility/runtime.js.map +1 -1
- package/dist/hooks/extensibility/sdk/paths.d.ts +1 -1
- package/dist/hooks/extensibility/sdk/paths.d.ts.map +1 -1
- package/dist/hooks/extensibility/sdk/paths.js +2 -2
- package/dist/hooks/extensibility/sdk/paths.js.map +1 -1
- package/dist/hooks/extensibility/sdk/runtime-state.d.ts +1 -1
- package/dist/hooks/extensibility/sdk/runtime-state.d.ts.map +1 -1
- package/dist/hooks/extensibility/sdk/runtime-state.js +55 -15
- package/dist/hooks/extensibility/sdk/runtime-state.js.map +1 -1
- package/dist/hooks/extensibility/sdk.d.ts +1 -0
- package/dist/hooks/extensibility/sdk.d.ts.map +1 -1
- package/dist/hooks/extensibility/sdk.js +1 -1
- package/dist/hooks/extensibility/sdk.js.map +1 -1
- package/dist/hooks/extensibility/types.d.ts +7 -0
- package/dist/hooks/extensibility/types.d.ts.map +1 -1
- package/dist/hooks/keyword-detector.d.ts +10 -3
- package/dist/hooks/keyword-detector.d.ts.map +1 -1
- package/dist/hooks/keyword-detector.js +116 -20
- package/dist/hooks/keyword-detector.js.map +1 -1
- package/dist/hooks/session.d.ts +180 -14
- package/dist/hooks/session.d.ts.map +1 -1
- package/dist/hooks/session.js +1402 -281
- package/dist/hooks/session.js.map +1 -1
- package/dist/hud/__tests__/hud-tmux-injection.test.js +6 -6
- package/dist/hud/__tests__/hud-tmux-injection.test.js.map +1 -1
- package/dist/hud/__tests__/index.test.js +26 -16
- package/dist/hud/__tests__/index.test.js.map +1 -1
- package/dist/hud/__tests__/reconcile.test.js +83 -78
- package/dist/hud/__tests__/reconcile.test.js.map +1 -1
- package/dist/hud/__tests__/state.test.js +36 -31
- package/dist/hud/__tests__/state.test.js.map +1 -1
- package/dist/hud/__tests__/tmux.test.js +155 -198
- package/dist/hud/__tests__/tmux.test.js.map +1 -1
- package/dist/hud/tmux.d.ts +42 -4
- package/dist/hud/tmux.d.ts.map +1 -1
- package/dist/hud/tmux.js +1017 -139
- package/dist/hud/tmux.js.map +1 -1
- package/dist/leader/__tests__/contract.test.js +71 -34
- package/dist/leader/__tests__/contract.test.js.map +1 -1
- package/dist/leader/contract.d.ts +1 -6
- package/dist/leader/contract.d.ts.map +1 -1
- package/dist/leader/contract.js +25 -24
- package/dist/leader/contract.js.map +1 -1
- package/dist/mcp/__tests__/hermes-bridge.test.js +17 -0
- package/dist/mcp/__tests__/hermes-bridge.test.js.map +1 -1
- package/dist/mcp/__tests__/server-lifecycle.test.js +4 -4
- package/dist/mcp/__tests__/state-paths.test.js +735 -4
- package/dist/mcp/__tests__/state-paths.test.js.map +1 -1
- package/dist/mcp/__tests__/state-server.test.js +1 -1
- package/dist/mcp/__tests__/state-server.test.js.map +1 -1
- package/dist/mcp/__tests__/trace-server.test.js +2 -2
- package/dist/mcp/__tests__/trace-server.test.js.map +1 -1
- package/dist/mcp/hermes-bridge.d.ts.map +1 -1
- package/dist/mcp/hermes-bridge.js +2 -2
- package/dist/mcp/hermes-bridge.js.map +1 -1
- package/dist/mcp/state-paths.d.ts +78 -4
- package/dist/mcp/state-paths.d.ts.map +1 -1
- package/dist/mcp/state-paths.js +543 -40
- package/dist/mcp/state-paths.js.map +1 -1
- package/dist/mcp/state-server.d.ts +4 -4
- package/dist/mcp/state-server.d.ts.map +1 -1
- package/dist/modes/__tests__/base-autopilot-gates.test.js +36 -7
- package/dist/modes/__tests__/base-autopilot-gates.test.js.map +1 -1
- package/dist/modes/__tests__/base-multi-state-compat.test.js +1 -1
- package/dist/modes/__tests__/base-multi-state-compat.test.js.map +1 -1
- package/dist/modes/__tests__/base-session-scope.test.js +17 -8
- package/dist/modes/__tests__/base-session-scope.test.js.map +1 -1
- package/dist/modes/base.d.ts +5 -5
- package/dist/modes/base.d.ts.map +1 -1
- package/dist/modes/base.js +76 -21
- package/dist/modes/base.js.map +1 -1
- package/dist/native-assets/archive.d.ts +17 -0
- package/dist/native-assets/archive.d.ts.map +1 -0
- package/dist/native-assets/archive.js +238 -0
- package/dist/native-assets/archive.js.map +1 -0
- package/dist/native-assets/policy.d.ts +42 -0
- package/dist/native-assets/policy.d.ts.map +1 -0
- package/dist/native-assets/policy.js +155 -0
- package/dist/native-assets/policy.js.map +1 -0
- package/dist/pipeline/__tests__/orchestrator.test.js +162 -40
- package/dist/pipeline/__tests__/orchestrator.test.js.map +1 -1
- package/dist/pipeline/__tests__/stages.test.js +66 -149
- package/dist/pipeline/__tests__/stages.test.js.map +1 -1
- package/dist/pipeline/orchestrator.d.ts.map +1 -1
- package/dist/pipeline/orchestrator.js +124 -18
- package/dist/pipeline/orchestrator.js.map +1 -1
- package/dist/pipeline/stages/ralplan.d.ts.map +1 -1
- package/dist/pipeline/stages/ralplan.js +36 -8
- package/dist/pipeline/stages/ralplan.js.map +1 -1
- package/dist/ralplan/__tests__/consensus-gate.test.js +70 -1437
- package/dist/ralplan/__tests__/consensus-gate.test.js.map +1 -1
- package/dist/ralplan/__tests__/documented-leader-preflight.test.js +328 -39
- package/dist/ralplan/__tests__/documented-leader-preflight.test.js.map +1 -1
- package/dist/ralplan/__tests__/runtime.test.js +82 -102
- package/dist/ralplan/__tests__/runtime.test.js.map +1 -1
- package/dist/ralplan/consensus-gate.d.ts +9 -1
- package/dist/ralplan/consensus-gate.d.ts.map +1 -1
- package/dist/ralplan/consensus-gate.js +40 -304
- package/dist/ralplan/consensus-gate.js.map +1 -1
- package/dist/ralplan/documented-leader-preflight.d.ts +15 -8
- package/dist/ralplan/documented-leader-preflight.d.ts.map +1 -1
- package/dist/ralplan/documented-leader-preflight.js +356 -54
- package/dist/ralplan/documented-leader-preflight.js.map +1 -1
- package/dist/ralplan/runtime.d.ts +1 -1
- package/dist/ralplan/runtime.d.ts.map +1 -1
- package/dist/ralplan/runtime.js +68 -173
- package/dist/ralplan/runtime.js.map +1 -1
- package/dist/runtime/run-state.d.ts +5 -1
- package/dist/runtime/run-state.d.ts.map +1 -1
- package/dist/runtime/run-state.js +15 -8
- package/dist/runtime/run-state.js.map +1 -1
- package/dist/scripts/__tests__/codex-native-hook.test.js +14071 -8859
- package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
- package/dist/scripts/__tests__/issue-3293-callsite-parity.test.d.ts +2 -0
- package/dist/scripts/__tests__/issue-3293-callsite-parity.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/issue-3293-callsite-parity.test.js +225 -0
- package/dist/scripts/__tests__/issue-3293-callsite-parity.test.js.map +1 -0
- package/dist/scripts/__tests__/issue-3293-cancel-transaction.test.d.ts +2 -0
- package/dist/scripts/__tests__/issue-3293-cancel-transaction.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/issue-3293-cancel-transaction.test.js +188 -0
- package/dist/scripts/__tests__/issue-3293-cancel-transaction.test.js.map +1 -0
- package/dist/scripts/__tests__/issue-3293-hook-owned-cancel.test.d.ts +2 -0
- package/dist/scripts/__tests__/issue-3293-hook-owned-cancel.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/issue-3293-hook-owned-cancel.test.js +259 -0
- package/dist/scripts/__tests__/issue-3293-hook-owned-cancel.test.js.map +1 -0
- package/dist/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.d.ts +2 -0
- package/dist/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.js +491 -0
- package/dist/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.js.map +1 -0
- package/dist/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.d.ts +2 -0
- package/dist/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.js +708 -0
- package/dist/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.js.map +1 -0
- package/dist/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.d.ts +2 -0
- package/dist/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.js +208 -0
- package/dist/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.js.map +1 -0
- package/dist/scripts/__tests__/notify-state-io.test.js +26 -0
- package/dist/scripts/__tests__/notify-state-io.test.js.map +1 -1
- package/dist/scripts/__tests__/notify-tmux-injection.test.js +23 -1
- package/dist/scripts/__tests__/notify-tmux-injection.test.js.map +1 -1
- package/dist/scripts/__tests__/postinstall.test.js +19 -1
- package/dist/scripts/__tests__/postinstall.test.js.map +1 -1
- package/dist/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.js +25 -8
- package/dist/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.js.map +1 -1
- package/dist/scripts/__tests__/role-intent-durable-recovery-3181.test.js +60 -25
- package/dist/scripts/__tests__/role-intent-durable-recovery-3181.test.js.map +1 -1
- package/dist/scripts/__tests__/smoke-packed-install.test.js +155 -16
- package/dist/scripts/__tests__/smoke-packed-install.test.js.map +1 -1
- package/dist/scripts/__tests__/verify-native-release-assets.test.d.ts +2 -0
- package/dist/scripts/__tests__/verify-native-release-assets.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/verify-native-release-assets.test.js +235 -0
- package/dist/scripts/__tests__/verify-native-release-assets.test.js.map +1 -0
- package/dist/scripts/codex-native-hook.d.ts +50 -1
- package/dist/scripts/codex-native-hook.d.ts.map +1 -1
- package/dist/scripts/codex-native-hook.js +3559 -451
- package/dist/scripts/codex-native-hook.js.map +1 -1
- package/dist/scripts/codex-native-pre-post.d.ts +9 -0
- package/dist/scripts/codex-native-pre-post.d.ts.map +1 -1
- package/dist/scripts/codex-native-pre-post.js +35 -12
- package/dist/scripts/codex-native-pre-post.js.map +1 -1
- package/dist/scripts/generate-native-release-manifest.js +80 -51
- package/dist/scripts/generate-native-release-manifest.js.map +1 -1
- package/dist/scripts/notify-fallback-watcher.js +28 -39
- package/dist/scripts/notify-fallback-watcher.js.map +1 -1
- package/dist/scripts/notify-hook/state-io.d.ts.map +1 -1
- package/dist/scripts/notify-hook/state-io.js +5 -0
- package/dist/scripts/notify-hook/state-io.js.map +1 -1
- package/dist/scripts/notify-hook/team-leader-nudge.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-leader-nudge.js +32 -3
- package/dist/scripts/notify-hook/team-leader-nudge.js.map +1 -1
- package/dist/scripts/notify-hook/team-worker-stop.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-worker-stop.js +23 -3
- package/dist/scripts/notify-hook/team-worker-stop.js.map +1 -1
- package/dist/scripts/notify-hook/team-worker.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-worker.js +45 -5
- package/dist/scripts/notify-hook/team-worker.js.map +1 -1
- package/dist/scripts/notify-hook/tmux-injection.d.ts +1 -0
- package/dist/scripts/notify-hook/tmux-injection.d.ts.map +1 -1
- package/dist/scripts/notify-hook/tmux-injection.js +4 -1
- package/dist/scripts/notify-hook/tmux-injection.js.map +1 -1
- package/dist/scripts/notify-hook.js +78 -82
- package/dist/scripts/notify-hook.js.map +1 -1
- package/dist/scripts/postinstall-advisory.d.ts +14 -0
- package/dist/scripts/postinstall-advisory.d.ts.map +1 -0
- package/dist/scripts/postinstall-advisory.js +49 -0
- package/dist/scripts/postinstall-advisory.js.map +1 -0
- package/dist/scripts/postinstall.d.ts +1 -1
- package/dist/scripts/postinstall.d.ts.map +1 -1
- package/dist/scripts/postinstall.js +1 -1
- package/dist/scripts/postinstall.js.map +1 -1
- package/dist/scripts/smoke-packed-install.d.ts +32 -1
- package/dist/scripts/smoke-packed-install.d.ts.map +1 -1
- package/dist/scripts/smoke-packed-install.js +413 -60
- package/dist/scripts/smoke-packed-install.js.map +1 -1
- package/dist/scripts/sync-plugin-mirror.d.ts.map +1 -1
- package/dist/scripts/sync-plugin-mirror.js +16 -1
- package/dist/scripts/sync-plugin-mirror.js.map +1 -1
- package/dist/scripts/verify-native-release-assets.js +37 -23
- package/dist/scripts/verify-native-release-assets.js.map +1 -1
- package/dist/state/__tests__/mode-state-context.test.js +12 -5
- package/dist/state/__tests__/mode-state-context.test.js.map +1 -1
- package/dist/state/__tests__/operations.test.js +460 -850
- package/dist/state/__tests__/operations.test.js.map +1 -1
- package/dist/state/__tests__/skill-active.test.js +400 -2
- package/dist/state/__tests__/skill-active.test.js.map +1 -1
- package/dist/state/mode-state-context.d.ts +3 -0
- package/dist/state/mode-state-context.d.ts.map +1 -1
- package/dist/state/mode-state-context.js +27 -13
- package/dist/state/mode-state-context.js.map +1 -1
- package/dist/state/operations.d.ts +3 -0
- package/dist/state/operations.d.ts.map +1 -1
- package/dist/state/operations.js +144 -40
- package/dist/state/operations.js.map +1 -1
- package/dist/state/skill-active.d.ts +18 -1
- package/dist/state/skill-active.d.ts.map +1 -1
- package/dist/state/skill-active.js +420 -23
- package/dist/state/skill-active.js.map +1 -1
- package/dist/state/workflow-transition-reconcile.d.ts +3 -0
- package/dist/state/workflow-transition-reconcile.d.ts.map +1 -1
- package/dist/state/workflow-transition-reconcile.js +10 -4
- package/dist/state/workflow-transition-reconcile.js.map +1 -1
- package/dist/state/workflow-transition.d.ts.map +1 -1
- package/dist/state/workflow-transition.js +3 -1
- package/dist/state/workflow-transition.js.map +1 -1
- package/dist/subagents/__tests__/leader-bootstrap-3181.test.js +27 -0
- package/dist/subagents/__tests__/leader-bootstrap-3181.test.js.map +1 -1
- package/dist/subagents/__tests__/tracker.test.js +837 -1048
- package/dist/subagents/__tests__/tracker.test.js.map +1 -1
- package/dist/subagents/tracker.d.ts +64 -60
- package/dist/subagents/tracker.d.ts.map +1 -1
- package/dist/subagents/tracker.js +809 -358
- package/dist/subagents/tracker.js.map +1 -1
- package/dist/team/__tests__/delivery-e2e-smoke.test.js +6 -7
- package/dist/team/__tests__/delivery-e2e-smoke.test.js.map +1 -1
- package/dist/team/__tests__/mcp-comm.test.js +104 -3
- package/dist/team/__tests__/mcp-comm.test.js.map +1 -1
- package/dist/team/__tests__/notice-ledger.test.d.ts +2 -0
- package/dist/team/__tests__/notice-ledger.test.d.ts.map +1 -0
- package/dist/team/__tests__/notice-ledger.test.js +131 -0
- package/dist/team/__tests__/notice-ledger.test.js.map +1 -0
- package/dist/team/__tests__/pane-teardown-residue-e2e.test.d.ts +2 -0
- package/dist/team/__tests__/pane-teardown-residue-e2e.test.d.ts.map +1 -0
- package/dist/team/__tests__/pane-teardown-residue-e2e.test.js +410 -0
- package/dist/team/__tests__/pane-teardown-residue-e2e.test.js.map +1 -0
- package/dist/team/__tests__/phase-controller.test.js +20 -0
- package/dist/team/__tests__/phase-controller.test.js.map +1 -1
- package/dist/team/__tests__/runtime.test.js +725 -59
- package/dist/team/__tests__/runtime.test.js.map +1 -1
- package/dist/team/__tests__/scaling.test.js +222 -237
- package/dist/team/__tests__/scaling.test.js.map +1 -1
- package/dist/team/__tests__/state-root.test.js +117 -2
- package/dist/team/__tests__/state-root.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.test.js +887 -92
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/__tests__/tmux-source-authority-realtmux.test.d.ts +2 -0
- package/dist/team/__tests__/tmux-source-authority-realtmux.test.d.ts.map +1 -0
- package/dist/team/__tests__/tmux-source-authority-realtmux.test.js +149 -0
- package/dist/team/__tests__/tmux-source-authority-realtmux.test.js.map +1 -0
- package/dist/team/__tests__/tmux-test-fixture.d.ts +69 -0
- package/dist/team/__tests__/tmux-test-fixture.d.ts.map +1 -1
- package/dist/team/__tests__/tmux-test-fixture.js +242 -15
- package/dist/team/__tests__/tmux-test-fixture.js.map +1 -1
- package/dist/team/__tests__/tmux-test-fixture.test.js +177 -1
- package/dist/team/__tests__/tmux-test-fixture.test.js.map +1 -1
- package/dist/team/__tests__/worker-runtime-identity.test.js +45 -72
- package/dist/team/__tests__/worker-runtime-identity.test.js.map +1 -1
- package/dist/team/notice-ledger.d.ts +54 -0
- package/dist/team/notice-ledger.d.ts.map +1 -0
- package/dist/team/notice-ledger.js +259 -0
- package/dist/team/notice-ledger.js.map +1 -0
- package/dist/team/phase-controller.d.ts.map +1 -1
- package/dist/team/phase-controller.js +2 -0
- package/dist/team/phase-controller.js.map +1 -1
- package/dist/team/runtime.d.ts +3 -1
- package/dist/team/runtime.d.ts.map +1 -1
- package/dist/team/runtime.js +314 -142
- package/dist/team/runtime.js.map +1 -1
- package/dist/team/scaling.d.ts.map +1 -1
- package/dist/team/scaling.js +161 -91
- package/dist/team/scaling.js.map +1 -1
- package/dist/team/state/monitor.d.ts +10 -0
- package/dist/team/state/monitor.d.ts.map +1 -1
- package/dist/team/state/monitor.js +13 -0
- package/dist/team/state/monitor.js.map +1 -1
- package/dist/team/state/types.d.ts +15 -0
- package/dist/team/state/types.d.ts.map +1 -1
- package/dist/team/state/types.js.map +1 -1
- package/dist/team/state-root.d.ts +12 -0
- package/dist/team/state-root.d.ts.map +1 -1
- package/dist/team/state-root.js +177 -0
- package/dist/team/state-root.js.map +1 -1
- package/dist/team/state.d.ts +18 -0
- package/dist/team/state.d.ts.map +1 -1
- package/dist/team/state.js +36 -0
- package/dist/team/state.js.map +1 -1
- package/dist/team/tmux-session.d.ts +40 -4
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +513 -166
- package/dist/team/tmux-session.js.map +1 -1
- package/dist/ultragoal/__tests__/artifacts.test.js +950 -2
- package/dist/ultragoal/__tests__/artifacts.test.js.map +1 -1
- package/dist/ultragoal/__tests__/docs-contract.test.js +1 -0
- package/dist/ultragoal/__tests__/docs-contract.test.js.map +1 -1
- package/dist/ultragoal/artifacts.d.ts +35 -1
- package/dist/ultragoal/artifacts.d.ts.map +1 -1
- package/dist/ultragoal/artifacts.js +232 -46
- package/dist/ultragoal/artifacts.js.map +1 -1
- package/dist/utils/__tests__/file-durability.test.js +58 -1
- package/dist/utils/__tests__/file-durability.test.js.map +1 -1
- package/dist/utils/__tests__/paths.test.js +21 -1
- package/dist/utils/__tests__/paths.test.js.map +1 -1
- package/dist/utils/file-durability.d.ts +10 -0
- package/dist/utils/file-durability.d.ts.map +1 -1
- package/dist/utils/file-durability.js +34 -4
- package/dist/utils/file-durability.js.map +1 -1
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +14 -6
- package/dist/utils/paths.js.map +1 -1
- package/dist/verification/__tests__/ci-rust-gates.test.js +49 -4
- package/dist/verification/__tests__/ci-rust-gates.test.js.map +1 -1
- package/dist/verification/__tests__/explore-harness-release-workflow.test.js +60 -0
- package/dist/verification/__tests__/explore-harness-release-workflow.test.js.map +1 -1
- package/dist/verification/__tests__/native-release-manifest.test.js +157 -4
- package/dist/verification/__tests__/native-release-manifest.test.js.map +1 -1
- package/package.json +13 -5
- package/plugins/oh-my-codex/.codex-plugin/plugin.json +1 -1
- package/plugins/oh-my-codex/hooks/codex-native-hook.mjs +81 -17
- package/plugins/oh-my-codex/skills/autopilot/SKILL.md +13 -5
- package/plugins/oh-my-codex/skills/cancel/SKILL.md +30 -85
- package/plugins/oh-my-codex/skills/ralph/SKILL.md +5 -5
- package/plugins/oh-my-codex/skills/ralplan/SKILL.md +15 -17
- package/plugins/oh-my-codex/skills/ultragoal/SKILL.md +3 -2
- package/skills/autopilot/SKILL.md +13 -5
- package/skills/cancel/SKILL.md +30 -85
- package/skills/ralph/SKILL.md +5 -5
- package/skills/ralplan/SKILL.md +15 -17
- package/skills/ultragoal/SKILL.md +3 -2
- package/src/scripts/__tests__/codex-native-hook.test.ts +6091 -540
- package/src/scripts/__tests__/issue-3293-callsite-parity.test.ts +187 -0
- package/src/scripts/__tests__/issue-3293-cancel-transaction.test.ts +189 -0
- package/src/scripts/__tests__/issue-3293-hook-owned-cancel.test.ts +187 -0
- package/src/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.ts +591 -0
- package/src/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.ts +701 -0
- package/src/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.ts +211 -0
- package/src/scripts/__tests__/notify-state-io.test.ts +29 -0
- package/src/scripts/__tests__/notify-tmux-injection.test.ts +26 -1
- package/src/scripts/__tests__/postinstall.test.ts +23 -1
- package/src/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.ts +27 -8
- package/src/scripts/__tests__/role-intent-durable-recovery-3181.test.ts +61 -27
- package/src/scripts/__tests__/smoke-packed-install.test.ts +209 -18
- package/src/scripts/__tests__/verify-native-release-assets.test.ts +240 -0
- package/src/scripts/codex-native-hook.ts +3638 -475
- package/src/scripts/codex-native-pre-post.ts +43 -12
- package/src/scripts/generate-native-release-manifest.ts +83 -79
- package/src/scripts/notify-fallback-watcher.ts +38 -38
- package/src/scripts/notify-hook/state-io.ts +11 -0
- package/src/scripts/notify-hook/team-leader-nudge.ts +32 -4
- package/src/scripts/notify-hook/team-worker-stop.ts +23 -4
- package/src/scripts/notify-hook/team-worker.ts +43 -5
- package/src/scripts/notify-hook/tmux-injection.ts +5 -1
- package/src/scripts/notify-hook.ts +83 -82
- package/src/scripts/postinstall-advisory.ts +67 -0
- package/src/scripts/postinstall.ts +1 -1
- package/src/scripts/smoke-packed-install.ts +446 -59
- package/src/scripts/sync-plugin-mirror.ts +17 -1
- package/src/scripts/verify-native-release-assets.ts +39 -31
- package/templates/AGENTS.md +1 -0
|
@@ -7,6 +7,7 @@ import { delimiter, join } from 'node:path';
|
|
|
7
7
|
import { PassThrough } from 'node:stream';
|
|
8
8
|
import { test } from 'node:test';
|
|
9
9
|
import {
|
|
10
|
+
assertPackedLaunchCwdPreserved,
|
|
10
11
|
assertInstalledPluginSurface,
|
|
11
12
|
assertInstalledReasoningDeclarationContract,
|
|
12
13
|
assertInstalledReasoningRuntimeContract,
|
|
@@ -14,9 +15,11 @@ import {
|
|
|
14
15
|
assertInstalledRootReasoningRejection,
|
|
15
16
|
assertInstalledTeamSkillContract,
|
|
16
17
|
assertPackedInstallFileMetadata,
|
|
18
|
+
assertPackedRegressionWorkflowState,
|
|
17
19
|
buildNativeHookSmokePayload,
|
|
18
20
|
ensureRepoDependencies,
|
|
19
21
|
hasUsableNodeModules,
|
|
22
|
+
buildPackedProbeEnv,
|
|
20
23
|
buildPackedRegressionEnvironment,
|
|
21
24
|
CODEX_APP_SERVER_TIMEOUTS,
|
|
22
25
|
CodexAppServer,
|
|
@@ -41,9 +44,13 @@ import {
|
|
|
41
44
|
parseNpmPackJsonOutput,
|
|
42
45
|
parseCodexHooksListResult,
|
|
43
46
|
probeCodexVersion,
|
|
47
|
+
parseArgs,
|
|
44
48
|
resolveGitCommonDir,
|
|
45
49
|
resolveReusableNodeModulesSource,
|
|
50
|
+
replacePathKeyCaseInsensitive,
|
|
51
|
+
resolvePackedSmokeRuntimeBinary,
|
|
46
52
|
validateHookStdout,
|
|
53
|
+
shouldPackedRegressionStopBlock,
|
|
47
54
|
assertCodexBatchWriteResult,
|
|
48
55
|
assertGeneratedTrustMatchesCodex,
|
|
49
56
|
managedCodexHooksByEvent,
|
|
@@ -65,6 +72,126 @@ function createFakeCodexAppServer(
|
|
|
65
72
|
}
|
|
66
73
|
|
|
67
74
|
|
|
75
|
+
test('packed smoke resolves and validates the platform-aware repo runtime', async () => {
|
|
76
|
+
const root = await mkdtemp(join(tmpdir(), 'omx-packed-runtime-'));
|
|
77
|
+
try {
|
|
78
|
+
const debugDir = join(root, 'target', 'debug');
|
|
79
|
+
await mkdir(debugDir, { recursive: true });
|
|
80
|
+
const runtimePath = join(debugDir, 'omx-runtime');
|
|
81
|
+
await writeFile(runtimePath, '#!/bin/sh\nexit 0\n');
|
|
82
|
+
await chmod(runtimePath, 0o755);
|
|
83
|
+
assert.equal(resolvePackedSmokeRuntimeBinary(root, { platform: 'linux' }), runtimePath);
|
|
84
|
+
|
|
85
|
+
const windowsRuntimePath = join(debugDir, 'omx-runtime.exe');
|
|
86
|
+
await writeFile(windowsRuntimePath, 'windows executable fixture');
|
|
87
|
+
assert.equal(resolvePackedSmokeRuntimeBinary(root, { platform: 'win32' }), windowsRuntimePath);
|
|
88
|
+
assert.throws(
|
|
89
|
+
() => resolvePackedSmokeRuntimeBinary(root, { platform: 'linux', candidate: 'relative/omx-runtime' }),
|
|
90
|
+
/must be absolute/,
|
|
91
|
+
);
|
|
92
|
+
assert.equal(
|
|
93
|
+
resolvePackedSmokeRuntimeBinary(root, { platform: 'linux', candidate: runtimePath }),
|
|
94
|
+
runtimePath,
|
|
95
|
+
);
|
|
96
|
+
assert.throws(
|
|
97
|
+
() => resolvePackedSmokeRuntimeBinary(join(root, 'missing'), { platform: 'linux' }),
|
|
98
|
+
/run "npm run build:runtime"/,
|
|
99
|
+
);
|
|
100
|
+
const nonExecutablePath = join(root, 'non-executable-runtime');
|
|
101
|
+
await writeFile(nonExecutablePath, 'not executable');
|
|
102
|
+
await chmod(nonExecutablePath, 0o644);
|
|
103
|
+
assert.throws(
|
|
104
|
+
() => resolvePackedSmokeRuntimeBinary(root, { platform: 'linux', candidate: nonExecutablePath }),
|
|
105
|
+
/executable regular file/,
|
|
106
|
+
);
|
|
107
|
+
} finally {
|
|
108
|
+
await rm(root, { recursive: true, force: true });
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test('packed probe env strips ambient runtime and supports default, absent, and explicit provisioning', async () => {
|
|
113
|
+
const root = await mkdtemp(join(tmpdir(), 'omx-packed-probe-env-'));
|
|
114
|
+
try {
|
|
115
|
+
const debugDir = join(root, 'target', 'debug');
|
|
116
|
+
await mkdir(debugDir, { recursive: true });
|
|
117
|
+
const runtimePath = join(debugDir, 'omx-runtime');
|
|
118
|
+
await writeFile(runtimePath, '#!/bin/sh\nexit 0\n');
|
|
119
|
+
await chmod(runtimePath, 0o755);
|
|
120
|
+
|
|
121
|
+
const defaultEnv = buildPackedProbeEnv(
|
|
122
|
+
{ OMX_RUNTIME_BINARY: '/tmp/ambient-decoy' },
|
|
123
|
+
{ repoRoot: root },
|
|
124
|
+
);
|
|
125
|
+
assert.equal(defaultEnv.OMX_RUNTIME_BINARY, runtimePath);
|
|
126
|
+
const absentEnv = buildPackedProbeEnv({}, { runtimeBinary: null });
|
|
127
|
+
assert.equal(Object.hasOwn(absentEnv, 'OMX_RUNTIME_BINARY'), false);
|
|
128
|
+
const explicitEnv = buildPackedProbeEnv({}, { runtimeBinary: runtimePath });
|
|
129
|
+
assert.equal(explicitEnv.OMX_RUNTIME_BINARY, runtimePath);
|
|
130
|
+
assert.throws(
|
|
131
|
+
() => buildPackedProbeEnv({}, { runtimeBinary: 'relative/omx-runtime' }),
|
|
132
|
+
/must be absolute/,
|
|
133
|
+
);
|
|
134
|
+
} finally {
|
|
135
|
+
await rm(root, { recursive: true, force: true });
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test('packed fail-closed PATH replacement removes a win32-shaped decoy runtime and every casing variant', async () => {
|
|
140
|
+
const root = await mkdtemp(join(tmpdir(), 'omx-packed-path-isolation-'));
|
|
141
|
+
try {
|
|
142
|
+
const decoyDir = join(root, 'decoy');
|
|
143
|
+
const isolatedDir = join(root, 'isolated');
|
|
144
|
+
await mkdir(decoyDir);
|
|
145
|
+
await mkdir(isolatedDir);
|
|
146
|
+
const decoyRuntime = join(decoyDir, 'omx-runtime.exe');
|
|
147
|
+
await writeFile(decoyRuntime, 'decoy');
|
|
148
|
+
await access(decoyRuntime);
|
|
149
|
+
|
|
150
|
+
const env = replacePathKeyCaseInsensitive(
|
|
151
|
+
{ Path: decoyDir, PATH: join(root, 'other'), KEEP: '1' },
|
|
152
|
+
isolatedDir,
|
|
153
|
+
);
|
|
154
|
+
const pathKeys = Object.keys(env).filter((key) => key.toUpperCase() === 'PATH');
|
|
155
|
+
assert.deepEqual(pathKeys, ['Path']);
|
|
156
|
+
assert.equal(env.Path, isolatedDir);
|
|
157
|
+
assert.equal(env.Path.split(delimiter).includes(decoyDir), false);
|
|
158
|
+
assert.equal(env.KEEP, '1');
|
|
159
|
+
} finally {
|
|
160
|
+
await rm(root, { recursive: true, force: true });
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
test('packed fail-closed PATH replacement creates a single POSIX key when absent', () => {
|
|
165
|
+
const env = replacePathKeyCaseInsensitive({ KEEP: '1' }, '/isolated');
|
|
166
|
+
assert.deepEqual(env, { KEEP: '1', PATH: '/isolated' });
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
test('packed launch cwd assertion accepts filesystem aliases and rejects distinct directories', async () => {
|
|
170
|
+
if (process.platform === 'win32') return;
|
|
171
|
+
const root = await mkdtemp(join(tmpdir(), 'omx-packed-cwd-'));
|
|
172
|
+
try {
|
|
173
|
+
const realDir = join(root, 'real');
|
|
174
|
+
const otherDir = join(root, 'other');
|
|
175
|
+
const aliasDir = join(root, 'alias');
|
|
176
|
+
await mkdir(realDir);
|
|
177
|
+
await mkdir(otherDir);
|
|
178
|
+
await symlink(realDir, aliasDir);
|
|
179
|
+
assert.doesNotThrow(() => assertPackedLaunchCwdPreserved(realDir, aliasDir, 'cwd mismatch'));
|
|
180
|
+
assert.throws(
|
|
181
|
+
() => assertPackedLaunchCwdPreserved(realDir, otherDir, 'cwd mismatch'),
|
|
182
|
+
/cwd mismatch: expected .* received /,
|
|
183
|
+
);
|
|
184
|
+
} finally {
|
|
185
|
+
await rm(root, { recursive: true, force: true });
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
test('packed smoke arguments expose a probe-only mode and reject unknown flags', () => {
|
|
190
|
+
assert.deepEqual(parseArgs([]), { failClosedProbe: false });
|
|
191
|
+
assert.deepEqual(parseArgs(['--fail-closed-probe']), { failClosedProbe: true });
|
|
192
|
+
assert.throws(() => parseArgs(['--unknown']), /Unknown argument/);
|
|
193
|
+
});
|
|
194
|
+
|
|
68
195
|
test('packed install smoke retains narrow boot commands and adds the isolated lifecycle separately', () => {
|
|
69
196
|
assert.deepEqual(PACKED_INSTALL_SMOKE_CORE_COMMANDS, [
|
|
70
197
|
['--help'],
|
|
@@ -98,20 +225,33 @@ test('packed 0.144.5 fixture is sanitized, pointer-free, and kept separate from
|
|
|
98
225
|
assert.equal(PACKED_CODEX_01445_NO_POINTER_NO_TRACKER_FIXTURE.session_id.includes('-'), true);
|
|
99
226
|
});
|
|
100
227
|
|
|
101
|
-
test('
|
|
102
|
-
const
|
|
228
|
+
test('source parser regression keeps collaboration results authoritative over unrelated child prose', () => {
|
|
229
|
+
const successfulResponse = JSON.stringify({
|
|
103
230
|
success: true,
|
|
104
231
|
status: 'completed',
|
|
105
|
-
|
|
232
|
+
agents: [{ agent_name: '/root', agent_status: 'running' }],
|
|
233
|
+
output: 'Child succeeded; an optional adapter was unavailable, unsupported, and not found.',
|
|
106
234
|
});
|
|
107
235
|
for (const toolName of [
|
|
108
236
|
'collaboration.spawn_agent',
|
|
109
237
|
'collaboration.list_agents',
|
|
238
|
+
'collaborationlist_agents',
|
|
110
239
|
'collaboration.followup_task',
|
|
111
240
|
'collaboration.wait_agent',
|
|
112
241
|
]) {
|
|
113
|
-
assert.equal(parseNativeSubagentResultDisposition(toolName,
|
|
242
|
+
assert.equal(parseNativeSubagentResultDisposition(toolName, successfulResponse).kind, 'success', toolName);
|
|
114
243
|
}
|
|
244
|
+
|
|
245
|
+
const nestedLifecycleOnly = JSON.stringify({
|
|
246
|
+
agents: [
|
|
247
|
+
{ agent_name: '/root', agent_status: 'running' },
|
|
248
|
+
{
|
|
249
|
+
agent_name: '/root/reviewer',
|
|
250
|
+
agent_status: { completed: 'Optional adapter is unavailable and unsupported.' },
|
|
251
|
+
},
|
|
252
|
+
],
|
|
253
|
+
});
|
|
254
|
+
assert.equal(parseNativeSubagentResultDisposition('collaborationlist_agents', nestedLifecycleOnly).kind, 'unknown');
|
|
115
255
|
});
|
|
116
256
|
|
|
117
257
|
test('packed lifecycle keeps the pinned newline-delimited Codex app-server envelopes literal', () => {
|
|
@@ -714,24 +854,40 @@ test('packed lifecycle fails before probing the 33rd unique PATH candidate', asy
|
|
|
714
854
|
if (process.platform === 'win32') return;
|
|
715
855
|
const root = await mkdtemp(join(tmpdir(), 'omx-codex-candidate-budget-'));
|
|
716
856
|
const candidateDirs = Array.from({ length: 33 }, (_value, index) => join(root, `candidate-${index}`));
|
|
717
|
-
|
|
857
|
+
// Duplicate the first PATH entry twice to demonstrate that PATH de-duplication
|
|
858
|
+
// (by resolved candidate path) does not consume extra candidate-budget slots,
|
|
859
|
+
// while still preserving first-occurrence probing order.
|
|
860
|
+
const pathValue = [candidateDirs[0], candidateDirs[0], ...candidateDirs].join(delimiter);
|
|
861
|
+
const spawnedExecutables: string[] = [];
|
|
862
|
+
const spawnSyncImpl = ((command: string) => {
|
|
863
|
+
spawnedExecutables.push(command);
|
|
864
|
+
return { status: 1, stdout: '', stderr: '', error: undefined };
|
|
865
|
+
}) as never;
|
|
718
866
|
try {
|
|
719
867
|
await Promise.all(candidateDirs.map((dir) => mkdir(dir, { recursive: true })));
|
|
720
|
-
await Promise.all(candidateDirs.map(async (dir
|
|
868
|
+
await Promise.all(candidateDirs.map(async (dir) => {
|
|
721
869
|
const executable = join(dir, 'codex');
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
: '#!/bin/sh\nexit 1\n',
|
|
727
|
-
);
|
|
870
|
+
// These candidates are never actually executed: spawnSyncImpl is a
|
|
871
|
+
// deterministic seam that returns an immediate nonzero result without
|
|
872
|
+
// starting a real shell process. Only filesystem presence is real.
|
|
873
|
+
await writeFile(executable, '#!/bin/sh\nexit 1\n');
|
|
728
874
|
await chmod(executable, 0o755);
|
|
729
875
|
}));
|
|
730
876
|
assert.throws(
|
|
731
|
-
() => probeCodexVersion(root, { PATH:
|
|
877
|
+
() => probeCodexVersion(root, { PATH: pathValue }, { spawnSyncImpl }),
|
|
732
878
|
/32-candidate PATH budget/,
|
|
733
879
|
);
|
|
734
|
-
|
|
880
|
+
assert.equal(spawnedExecutables.length, 32, 'must probe exactly 32 unique candidates before the budget error');
|
|
881
|
+
assert.deepEqual(
|
|
882
|
+
spawnedExecutables,
|
|
883
|
+
candidateDirs.slice(0, 32).map((dir) => join(dir, 'codex')),
|
|
884
|
+
'must probe unique candidates in PATH order, with the duplicated first entry counted only once',
|
|
885
|
+
);
|
|
886
|
+
const thirtyThirdExecutable = join(candidateDirs[32], 'codex');
|
|
887
|
+
assert.ok(
|
|
888
|
+
!spawnedExecutables.includes(thirtyThirdExecutable),
|
|
889
|
+
'the 33rd unique candidate must never be spawned',
|
|
890
|
+
);
|
|
735
891
|
} finally {
|
|
736
892
|
await rm(root, { recursive: true, force: true });
|
|
737
893
|
}
|
|
@@ -990,13 +1146,13 @@ test('packed install smoke covers directive activation and terminal false-activa
|
|
|
990
1146
|
{ name: 'doc-preserves-earlier', prompt: 'Use autopilot mode; "note"; use $ralplan is the workflow command.', expectedSkill: 'autopilot', expectedStopBlock: true },
|
|
991
1147
|
{ name: 'doc-colon-followup', prompt: 'use $ralplan is the workflow command: use $autopilot build it', expectedSkill: 'autopilot', expectedStopBlock: true },
|
|
992
1148
|
{ name: 'table-followup', prompt: 'Mode | Meaning\n--- | ---\nmanual | documentation\n$ralplan plan it', expectedSkill: 'ralplan', expectedStopBlock: true },
|
|
993
|
-
{ name: 'neg-advance-reopen', prompt: 'Do not run $ralplan but advance to $ultragoal', expectedSkill: 'ultragoal', expectedStopBlock: false },
|
|
994
|
-
{ name: 'neg-jump-reopen', prompt: 'Do not run $ralplan but jump straight to $ultragoal', expectedSkill: 'ultragoal', expectedStopBlock: false },
|
|
1149
|
+
{ name: 'neg-advance-reopen', prompt: 'Do not run $ralplan but advance to $ultragoal', expectedSkill: 'ultragoal', expectedStopBlock: false, insideTmux: true },
|
|
1150
|
+
{ name: 'neg-jump-reopen', prompt: 'Do not run $ralplan but jump straight to $ultragoal', expectedSkill: 'ultragoal', expectedStopBlock: false, insideTmux: true },
|
|
995
1151
|
{ name: 'reference-plain-title', prompt: '[docs]: /target "title\nplain text"\n$ralplan plan it', expectedSkill: 'ralplan', expectedStopBlock: true },
|
|
996
1152
|
{ name: 'reference-plain-destination', prompt: '[docs]: ./target\n$ralplan plan it', expectedSkill: 'ralplan', expectedStopBlock: true },
|
|
997
1153
|
{ name: 'directive-use-the', prompt: 'Do not run $ralplan; use the $autopilot build it', expectedSkill: 'autopilot', expectedStopBlock: true },
|
|
998
1154
|
{ name: 'directive-continue-after-quote', prompt: '"quoted"\ncontinue with $ralplan', expectedSkill: 'ralplan', expectedStopBlock: true },
|
|
999
|
-
{ name: 'doc-advance-followup', prompt: 'use $ralplan is the workflow command; advance to $ultragoal', expectedSkill: 'ultragoal', expectedStopBlock: false },
|
|
1155
|
+
{ name: 'doc-advance-followup', prompt: 'use $ralplan is the workflow command; advance to $ultragoal', expectedSkill: 'ultragoal', expectedStopBlock: false, insideTmux: true },
|
|
1000
1156
|
{ name: 'directive-run-code-review', prompt: 'run $code-review', expectedSkill: 'code-review', expectedStopBlock: false },
|
|
1001
1157
|
{ name: 'directive-documentation', prompt: 'use $ralplan is the consensus-planning command', expectedSkill: null, expectedStopBlock: false },
|
|
1002
1158
|
{ name: 'nested-bounded-child-unbounded-parent', prompt: '"`x`\n$ralplan plan it', expectedSkill: null, expectedStopBlock: false },
|
|
@@ -1028,13 +1184,39 @@ test('packed install smoke covers directive activation and terminal false-activa
|
|
|
1028
1184
|
{ name: 'percent-suffix', prompt: '$ralplan%docs', expectedSkill: null, expectedStopBlock: false },
|
|
1029
1185
|
{ name: 'fullwidth-percent-suffix', prompt: '$ralplan%docs', expectedSkill: null, expectedStopBlock: false },
|
|
1030
1186
|
{ name: 'g1a-ordered-multi-skill', prompt: '$ralplan, $autopilot; $team', expectedSkill: 'ralplan', expectedStopBlock: true, expectedDeferredSkills: ['autopilot', 'team'], expectedActiveSkills: ['ralplan'], insideTmux: true },
|
|
1031
|
-
{ name: 'g1c-duplicate-alias', prompt: '$autopilot $oh-my-codex:autopilot build it', expectedSkill: 'autopilot', expectedStopBlock: true, expectedDeferredSkills: [], expectedActiveSkills: [
|
|
1187
|
+
{ name: 'g1c-duplicate-alias', prompt: '$autopilot $oh-my-codex:autopilot build it', expectedSkill: 'autopilot', expectedStopBlock: true, expectedDeferredSkills: [], expectedActiveSkills: [] },
|
|
1032
1188
|
{ name: 'b3-longer-valid-fence', prompt: '```text\n$autopilot build it\n````\n$ralplan plan it', expectedSkill: 'ralplan', expectedStopBlock: true },
|
|
1033
1189
|
{ name: 'b4-shorter-invalid-fence', prompt: '````text\n$autopilot build it\n```\n$ralplan plan it', expectedSkill: null, expectedStopBlock: false },
|
|
1034
1190
|
{ name: 'b5-different-marker-invalid-fence', prompt: '```text\n$autopilot build it\n~~~\n$ralplan plan it', expectedSkill: null, expectedStopBlock: false },
|
|
1035
1191
|
]);
|
|
1036
1192
|
});
|
|
1037
1193
|
|
|
1194
|
+
test('packed regression workflow expectations distinguish active activation from receipt-unavailable Autopilot termination', () => {
|
|
1195
|
+
assert.doesNotThrow(() => assertPackedRegressionWorkflowState(
|
|
1196
|
+
{ name: 'active-ralplan', expectedSkill: 'ralplan' },
|
|
1197
|
+
{ active: true, skill: 'ralplan' },
|
|
1198
|
+
));
|
|
1199
|
+
assert.doesNotThrow(() => assertPackedRegressionWorkflowState(
|
|
1200
|
+
{ name: 'failed-autopilot', expectedSkill: 'autopilot' },
|
|
1201
|
+
{
|
|
1202
|
+
active: false,
|
|
1203
|
+
skill: 'autopilot',
|
|
1204
|
+
phase: 'failed',
|
|
1205
|
+
error: 'documented_host_consensus_receipt_unavailable',
|
|
1206
|
+
active_skills: [],
|
|
1207
|
+
},
|
|
1208
|
+
));
|
|
1209
|
+
assert.throws(() => assertPackedRegressionWorkflowState(
|
|
1210
|
+
{ name: 'stale-active-autopilot', expectedSkill: 'autopilot' },
|
|
1211
|
+
{ active: true, skill: 'autopilot', phase: 'running', active_skills: [{ skill: 'autopilot' }] },
|
|
1212
|
+
), /persisted unexpected workflow state/);
|
|
1213
|
+
});
|
|
1214
|
+
|
|
1215
|
+
test('packed regression Stop expectations release terminal receipt-unavailable Autopilot state', () => {
|
|
1216
|
+
assert.equal(shouldPackedRegressionStopBlock({ expectedSkill: 'ralplan', expectedStopBlock: true }), true);
|
|
1217
|
+
assert.equal(shouldPackedRegressionStopBlock({ expectedSkill: 'autopilot', expectedStopBlock: true }), false);
|
|
1218
|
+
});
|
|
1219
|
+
|
|
1038
1220
|
test('packed regression environment clears inherited Team routing state', () => {
|
|
1039
1221
|
const environment = buildPackedRegressionEnvironment(
|
|
1040
1222
|
{ name: 'poisoned-team-case', insideTmux: true },
|
|
@@ -1265,6 +1447,14 @@ test('packed install helpers freeze installed runtime and declaration reasoning
|
|
|
1265
1447
|
);
|
|
1266
1448
|
});
|
|
1267
1449
|
|
|
1450
|
+
test('packed install removes same-user native-anchor authentication', async () => {
|
|
1451
|
+
const hookSource = await readFile(join(process.cwd(), 'src/scripts/codex-native-hook.ts'), 'utf8');
|
|
1452
|
+
const cliSource = await readFile(join(process.cwd(), 'src/cli/index.ts'), 'utf8');
|
|
1453
|
+
assert.doesNotMatch(hookSource, /isVerifiedPluginLauncherClaim|classifyNativeTranscriptProvenance|signNativeLeaderAttestation|native-anchor-auth/);
|
|
1454
|
+
assert.match(hookSource, /unsupported_documented_leader_proof/);
|
|
1455
|
+
assert.match(cliSource, /execWithOverlay[\s\S]+OMX_CODEX_LAUNCH_ID[\s\S]+buildHudRuntimeEnv\(\{ sessionId/);
|
|
1456
|
+
});
|
|
1457
|
+
|
|
1268
1458
|
test('packed install contract requires canonical/plugin Team skill parity and text', async () => {
|
|
1269
1459
|
const canonical = await readFile(join(process.cwd(), 'skills/team/SKILL.md'));
|
|
1270
1460
|
const pluginMirror = await readFile(join(process.cwd(), 'plugins/oh-my-codex/skills/team/SKILL.md'));
|
|
@@ -1325,6 +1515,7 @@ test('packed install plugin assertions enforce the packaged plugin contract', as
|
|
|
1325
1515
|
"import { spawn } from 'node:child_process';",
|
|
1326
1516
|
"import { join } from 'node:path';",
|
|
1327
1517
|
"const OMX_PLUGIN_HOOK_LAUNCHER_CONTRACT_MARKER = 'omx-plugin-hook-launcher:v1';",
|
|
1518
|
+
"const OMX_PLUGIN_HOOK_ROUTING_ONLY_MARKER = 'omx-plugin-hook-routing-only:v1';",
|
|
1328
1519
|
"const hookDir = new URL('.', import.meta.url).pathname;",
|
|
1329
1520
|
'function readPinnedLauncher() {',
|
|
1330
1521
|
" const launcherPath = join(hookDir, 'omx-command.json');",
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
|
|
5
|
+
import { tmpdir } from 'node:os';
|
|
6
|
+
import { join } from 'node:path';
|
|
7
|
+
import { PassThrough } from 'node:stream';
|
|
8
|
+
import { gzipSync } from 'node:zlib';
|
|
9
|
+
import { describe, it } from 'node:test';
|
|
10
|
+
import { compress as xzCompress } from '@napi-rs/lzma/xz';
|
|
11
|
+
import * as tar from 'tar-stream';
|
|
12
|
+
import * as yazl from 'yazl';
|
|
13
|
+
import { fileURLToPath } from 'node:url';
|
|
14
|
+
|
|
15
|
+
function sha256(value: Buffer): string {
|
|
16
|
+
return createHash('sha256').update(value).digest('hex');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function verify(manifest: string, artifacts: string) {
|
|
20
|
+
return spawnSync(process.execPath, [fileURLToPath(new URL('../verify-native-release-assets.js', import.meta.url)), '--manifest', manifest, '--artifacts-dir', artifacts], { encoding: 'utf-8' });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async function collect(stream: NodeJS.ReadableStream): Promise<Buffer> {
|
|
24
|
+
const output: Buffer[] = [];
|
|
25
|
+
for await (const chunk of stream) output.push(Buffer.from(chunk));
|
|
26
|
+
return Buffer.concat(output);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function tarArchive(entries: Array<{ name: string; data?: Buffer; type?: tar.Headers['type']; linkname?: string }>, format: 'tar.gz' | 'tar.xz'): Promise<Buffer> {
|
|
30
|
+
const archive = tar.pack();
|
|
31
|
+
for (const item of entries) {
|
|
32
|
+
const header: tar.Headers = { name: item.name, type: item.type ?? 'file', size: item.data?.length ?? 0, linkname: item.linkname };
|
|
33
|
+
if ((item.type ?? 'file') === 'file') archive.entry(header, item.data ?? Buffer.alloc(0));
|
|
34
|
+
else archive.entry(header);
|
|
35
|
+
}
|
|
36
|
+
archive.finalize();
|
|
37
|
+
const raw = await collect(archive);
|
|
38
|
+
return format === 'tar.gz' ? gzipSync(raw) : xzCompress(raw);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async function zipArchive(entries: Array<{ name: string; data?: Buffer }>): Promise<Buffer> {
|
|
42
|
+
const archive = new yazl.ZipFile();
|
|
43
|
+
for (const item of entries) {
|
|
44
|
+
if (item.name.endsWith('/')) archive.addEmptyDirectory(item.name);
|
|
45
|
+
else archive.addBuffer(item.data ?? Buffer.alloc(0), item.name);
|
|
46
|
+
}
|
|
47
|
+
archive.end();
|
|
48
|
+
return collect(archive.outputStream);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function crc32(value: Buffer): number {
|
|
52
|
+
let crc = 0xffffffff;
|
|
53
|
+
for (const byte of value) {
|
|
54
|
+
crc ^= byte;
|
|
55
|
+
for (let bit = 0; bit < 8; bit += 1) crc = (crc >>> 1) ^ (-(crc & 1) & 0xedb88320);
|
|
56
|
+
}
|
|
57
|
+
return (crc ^ 0xffffffff) >>> 0;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function rawZip(name: string, mode: number, dosAttributes = 0, data = Buffer.alloc(0)): Buffer {
|
|
61
|
+
const fileName = Buffer.from(name);
|
|
62
|
+
const crc = crc32(data);
|
|
63
|
+
const local = Buffer.alloc(30);
|
|
64
|
+
local.writeUInt32LE(0x04034b50, 0);
|
|
65
|
+
local.writeUInt16LE(20, 4);
|
|
66
|
+
local.writeUInt32LE(crc, 14);
|
|
67
|
+
local.writeUInt32LE(data.length, 18);
|
|
68
|
+
local.writeUInt32LE(data.length, 22);
|
|
69
|
+
local.writeUInt16LE(fileName.length, 26);
|
|
70
|
+
|
|
71
|
+
const central = Buffer.alloc(46);
|
|
72
|
+
central.writeUInt32LE(0x02014b50, 0);
|
|
73
|
+
central.writeUInt16LE((3 << 8) | 20, 4);
|
|
74
|
+
central.writeUInt16LE(20, 6);
|
|
75
|
+
central.writeUInt32LE(crc, 16);
|
|
76
|
+
central.writeUInt32LE(data.length, 20);
|
|
77
|
+
central.writeUInt32LE(data.length, 24);
|
|
78
|
+
central.writeUInt16LE(fileName.length, 28);
|
|
79
|
+
central.writeUInt32LE((((mode & 0xffff) << 16) | dosAttributes) >>> 0, 38);
|
|
80
|
+
|
|
81
|
+
const directoryOffset = local.length + fileName.length + data.length;
|
|
82
|
+
const end = Buffer.alloc(22);
|
|
83
|
+
end.writeUInt32LE(0x06054b50, 0);
|
|
84
|
+
end.writeUInt16LE(1, 8);
|
|
85
|
+
end.writeUInt16LE(1, 10);
|
|
86
|
+
end.writeUInt32LE(central.length + fileName.length, 12);
|
|
87
|
+
end.writeUInt32LE(directoryOffset, 16);
|
|
88
|
+
return Buffer.concat([local, fileName, data, central, fileName, end]);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function manifestFor(archive: string, content: Buffer, overrides: Record<string, unknown> = {}) {
|
|
92
|
+
return {
|
|
93
|
+
manifest_version: 1,
|
|
94
|
+
version: '0.8.15',
|
|
95
|
+
tag: 'v0.8.15',
|
|
96
|
+
assets: [{
|
|
97
|
+
product: 'omx-api', version: '0.8.15', platform: 'linux', arch: 'x64', target: 'x86_64-unknown-linux-musl', libc: 'musl',
|
|
98
|
+
archive, binary: 'omx-api', binary_path: 'omx-api', sha256: sha256(content), size: content.length,
|
|
99
|
+
download_url: `https://example.invalid/${archive}`,
|
|
100
|
+
...overrides,
|
|
101
|
+
}],
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async function verifyArchive(root: string, archive: string, content: Buffer, overrides: Record<string, unknown> = {}, manifestOverrides: Record<string, unknown> = {}) {
|
|
106
|
+
await writeFile(join(root, archive), content);
|
|
107
|
+
const manifest = join(root, `${archive}.manifest.json`);
|
|
108
|
+
await writeFile(manifest, JSON.stringify({ ...manifestFor(archive, content, overrides), ...manifestOverrides }));
|
|
109
|
+
return verify(manifest, root);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
describe('verify-native-release-assets', () => {
|
|
113
|
+
it('accepts tar.gz, tar.xz, and zip archives with one wrapped regular binary', async () => {
|
|
114
|
+
const wd = await mkdtemp(join(tmpdir(), 'omx-verify-native-release-'));
|
|
115
|
+
try {
|
|
116
|
+
for (const format of ['tar.gz', 'tar.xz', 'zip'] as const) {
|
|
117
|
+
const artifacts = join(wd, format.replace('.', '-'));
|
|
118
|
+
await mkdir(artifacts, { recursive: true });
|
|
119
|
+
const archive = `omx-api-x86_64-unknown-linux-musl.${format}`;
|
|
120
|
+
const content = format === 'zip'
|
|
121
|
+
? await zipArchive([{ name: 'wrapper/', data: Buffer.alloc(0) }, { name: 'wrapper/omx-api', data: Buffer.from('x') }])
|
|
122
|
+
: await tarArchive([{ name: 'wrapper/', type: 'directory' }, { name: 'wrapper/omx-api', data: Buffer.from('x') }], format);
|
|
123
|
+
assert.equal((await verifyArchive(artifacts, archive, content)).status, 0, format);
|
|
124
|
+
}
|
|
125
|
+
} finally {
|
|
126
|
+
await rm(wd, { recursive: true, force: true });
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it('accepts full-release siblings with logical Windows binary names and executable paths', async () => {
|
|
131
|
+
const wd = await mkdtemp(join(tmpdir(), 'omx-verify-native-release-full-'));
|
|
132
|
+
try {
|
|
133
|
+
const apiArchive = 'omx-api-x86_64-pc-windows-msvc.zip';
|
|
134
|
+
const runtimeArchive = 'omx-runtime-x86_64-pc-windows-msvc.zip';
|
|
135
|
+
const apiBytes = await zipArchive([{ name: 'omx-api.exe', data: Buffer.from('api') }]);
|
|
136
|
+
const runtimeBytes = await zipArchive([{ name: 'omx-runtime.exe', data: Buffer.from('runtime') }]);
|
|
137
|
+
await writeFile(join(wd, apiArchive), apiBytes);
|
|
138
|
+
await writeFile(join(wd, runtimeArchive), runtimeBytes);
|
|
139
|
+
const asset = (product: string, archive: string, binaryPath: string, content: Buffer) => ({
|
|
140
|
+
product,
|
|
141
|
+
version: '0.20.3',
|
|
142
|
+
platform: 'win32',
|
|
143
|
+
arch: 'x64',
|
|
144
|
+
target: 'x86_64-pc-windows-msvc',
|
|
145
|
+
archive,
|
|
146
|
+
binary: product,
|
|
147
|
+
binary_path: binaryPath,
|
|
148
|
+
sha256: sha256(content),
|
|
149
|
+
size: content.length,
|
|
150
|
+
download_url: `https://example.invalid/${archive}`,
|
|
151
|
+
});
|
|
152
|
+
const manifestPath = join(wd, 'native-release-manifest.json');
|
|
153
|
+
await writeFile(manifestPath, JSON.stringify({
|
|
154
|
+
manifest_version: 1,
|
|
155
|
+
version: '0.20.3',
|
|
156
|
+
tag: 'v0.20.3',
|
|
157
|
+
assets: [
|
|
158
|
+
asset('omx-api', apiArchive, 'omx-api.exe', apiBytes),
|
|
159
|
+
asset('omx-runtime', runtimeArchive, 'omx-runtime.exe', runtimeBytes),
|
|
160
|
+
],
|
|
161
|
+
}));
|
|
162
|
+
const result = verify(manifestPath, wd);
|
|
163
|
+
assert.equal(result.status, 0, result.stderr || result.stdout);
|
|
164
|
+
} finally {
|
|
165
|
+
await rm(wd, { recursive: true, force: true });
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it('rejects unsafe unrelated paths and links before selecting a binary', async () => {
|
|
170
|
+
const wd = await mkdtemp(join(tmpdir(), 'omx-verify-native-release-unsafe-'));
|
|
171
|
+
try {
|
|
172
|
+
for (const [index, unsafe] of ['../escape', '/absolute', 'C:/drive', 'dir\\backslash'].entries()) {
|
|
173
|
+
const archive = `unsafe-${index}.tar.gz`;
|
|
174
|
+
const content = await tarArchive([{ name: 'omx-api', data: Buffer.from('x') }, { name: unsafe, data: Buffer.from('x') }], 'tar.gz');
|
|
175
|
+
assert.notEqual((await verifyArchive(wd, archive, content)).status, 0, unsafe);
|
|
176
|
+
}
|
|
177
|
+
const linked = await tarArchive([{ name: 'omx-api', data: Buffer.from('x') }, { name: 'link', type: 'symlink', linkname: 'omx-api' }], 'tar.gz');
|
|
178
|
+
assert.notEqual((await verifyArchive(wd, 'linked.tar.gz', linked)).status, 0);
|
|
179
|
+
} finally {
|
|
180
|
+
await rm(wd, { recursive: true, force: true });
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it('rejects ZIP entries with contradictory Unix types and directory markers', async () => {
|
|
185
|
+
const wd = await mkdtemp(join(tmpdir(), 'omx-verify-native-release-zip-types-'));
|
|
186
|
+
try {
|
|
187
|
+
const malformed = [
|
|
188
|
+
rawZip('regular/', 0o100644),
|
|
189
|
+
rawZip('regular', 0o100644, 0x10),
|
|
190
|
+
rawZip('directory', 0o040755),
|
|
191
|
+
];
|
|
192
|
+
for (const [index, content] of malformed.entries()) {
|
|
193
|
+
assert.notEqual((await verifyArchive(wd, `zip-types-${index}.zip`, content)).status, 0);
|
|
194
|
+
}
|
|
195
|
+
} finally {
|
|
196
|
+
await rm(wd, { recursive: true, force: true });
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it('rejects ambiguous, colliding, and zero-byte selected members', async () => {
|
|
201
|
+
const wd = await mkdtemp(join(tmpdir(), 'omx-verify-native-release-selection-'));
|
|
202
|
+
try {
|
|
203
|
+
const cases = [
|
|
204
|
+
await tarArchive([{ name: 'one/omx-api', data: Buffer.from('x') }, { name: 'two/omx-api', data: Buffer.from('x') }], 'tar.gz'),
|
|
205
|
+
await tarArchive([{ name: 'omx-api', data: Buffer.from('x') }, { name: 'omx-api/config', data: Buffer.from('x') }], 'tar.gz'),
|
|
206
|
+
await tarArchive([{ name: 'omx-api', data: Buffer.alloc(0) }], 'tar.gz'),
|
|
207
|
+
];
|
|
208
|
+
for (const [index, content] of cases.entries()) {
|
|
209
|
+
assert.notEqual((await verifyArchive(wd, `selection-${index}.tar.gz`, content)).status, 0);
|
|
210
|
+
}
|
|
211
|
+
} finally {
|
|
212
|
+
await rm(wd, { recursive: true, force: true });
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
it('enforces manifest version, target, libc, and basename coherence', async () => {
|
|
217
|
+
const wd = await mkdtemp(join(tmpdir(), 'omx-verify-native-release-manifest-'));
|
|
218
|
+
try {
|
|
219
|
+
const content = await tarArchive([{ name: 'omx-api', data: Buffer.from('x') }], 'tar.gz');
|
|
220
|
+
const invalid = [
|
|
221
|
+
[{}, { manifest_version: undefined }],
|
|
222
|
+
[{}, { version: 'v0.8.15', tag: 'vv0.8.15' }],
|
|
223
|
+
[{}, { tag: 'v0.8.16' }],
|
|
224
|
+
[{ platform: 'darwin', arch: 'x64', target: 'x86_64-apple-darwin', libc: 'musl' }, {}],
|
|
225
|
+
[{ product: 'omx-unknown' }, {}],
|
|
226
|
+
[{ binary: 'omx-api.exe' }, {}],
|
|
227
|
+
[{ binary_path: '../omx-api' }, {}],
|
|
228
|
+
[{ archive: 'nested/omx-api-x86_64-unknown-linux-musl.tar.gz' }, {}],
|
|
229
|
+
[{ archive: 'omx-api-x86_64-unknown-linux-musl.tar.bz2' }, {}],
|
|
230
|
+
[{ archive: 'omx-api-x86_64-unknown-linux-gnu.tar.gz' }, {}],
|
|
231
|
+
[{ archive: 'omx-api-aarch64-unknown-linux-musl.tar.gz' }, {}],
|
|
232
|
+
] as const;
|
|
233
|
+
for (const [index, [assetOverrides, documentOverrides]] of invalid.entries()) {
|
|
234
|
+
assert.notEqual((await verifyArchive(wd, `manifest-${index}.tar.gz`, content, assetOverrides, documentOverrides)).status, 0);
|
|
235
|
+
}
|
|
236
|
+
} finally {
|
|
237
|
+
await rm(wd, { recursive: true, force: true });
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
});
|