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
|
@@ -48,5 +48,30 @@ export declare function resolveCachedNativeBinaryCandidatePaths(product: NativeP
|
|
|
48
48
|
export declare function resolveNativeReleaseAssetCandidates(manifest: NativeReleaseManifest, product: NativeProduct, version: string, platform: NodeJS.Platform, arch: string, options?: NativeBinaryCandidateOptions): NativeReleaseAsset[];
|
|
49
49
|
export declare function isRepositoryCheckout(packageRoot?: string): boolean;
|
|
50
50
|
export declare function loadNativeReleaseManifest(packageRoot?: string, version?: string, env?: NodeJS.ProcessEnv): Promise<NativeReleaseManifest>;
|
|
51
|
+
export type ManagedNativeBinaryState = 'verified' | 'missing' | 'publication-in-progress' | 'binary-unsafe' | 'binary-empty' | 'orphan-checksum' | 'checksum-unsafe' | 'checksum-malformed' | 'checksum-mismatch' | 'legacy-unverified' | 'cache-descendant-unsafe' | 'inspection-race' | 'publication-lock-timeout' | 'cleanup-failed';
|
|
52
|
+
export interface NativeCacheLockDiagnostic {
|
|
53
|
+
path: string;
|
|
54
|
+
classification: 'valid-owner-record' | 'metadata-malformed' | 'lock-unsafe' | 'inspection-race' | 'metadata-unavailable';
|
|
55
|
+
owner?: {
|
|
56
|
+
pid: number;
|
|
57
|
+
hostname: string;
|
|
58
|
+
started_at: string;
|
|
59
|
+
binary_path: string;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
export interface ManagedNativeBinaryInspection {
|
|
63
|
+
state: ManagedNativeBinaryState;
|
|
64
|
+
/** Present only when opened-handle verification authorizes this exact binary. */
|
|
65
|
+
path?: string;
|
|
66
|
+
lock?: NativeCacheLockDiagnostic;
|
|
67
|
+
}
|
|
68
|
+
interface NativeAssetsTestHooks {
|
|
69
|
+
beforeCreateParent?(path: string): Promise<void>;
|
|
70
|
+
}
|
|
71
|
+
/** Test-only seam for deterministic cache-parent creation races. */
|
|
72
|
+
export declare function setNativeAssetsTestHooksForTests(hooks: NativeAssetsTestHooks | undefined): () => void;
|
|
73
|
+
/** Inspects the exact B/S/L protocol. Only `verified` has a path. */
|
|
74
|
+
export declare function inspectManagedNativeBinary(binaryPath: string, env?: NodeJS.ProcessEnv): Promise<ManagedNativeBinaryInspection>;
|
|
51
75
|
export declare function hydrateNativeBinary(product: NativeProduct, options?: HydrateNativeBinaryOptions): Promise<string | undefined>;
|
|
76
|
+
export {};
|
|
52
77
|
//# sourceMappingURL=native-assets.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native-assets.d.ts","sourceRoot":"","sources":["../../src/cli/native-assets.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"native-assets.d.ts","sourceRoot":"","sources":["../../src/cli/native-assets.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,aAAa,GAAG,qBAAqB,GAAG,gBAAgB,GAAG,SAAS,CAAC;AACjF,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC;AAE1C,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,aAAa,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,kBAAkB,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,0BAA0B;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,4BAA4B;IAC3C,mBAAmB,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;CAC7C;AAED,MAAM,WAAW,uCAAuC;IACtD,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,eAAe,CAAC,EAAE,UAAU,CAAC;CAC9B;AAMD,eAAO,MAAM,eAAe,oBAAoB,CAAC;AACjD,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AACvD,eAAO,MAAM,WAAW,gBAAgB,CAAC;AAWzC,wBAAsB,iBAAiB,CAAC,WAAW,SAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAIvF;AAWD,wBAAsB,2BAA2B,CAC/C,WAAW,SAAmB,EAC9B,OAAO,CAAC,EAAE,MAAM,EAChB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAAC,MAAM,CAAC,CAQjB;AAED,wBAAsB,wBAAwB,CAC5C,WAAW,SAAmB,EAC9B,OAAO,CAAC,EAAE,MAAM,EAChB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAAC,MAAM,CAAC,CAKjB;AAED,wBAAgB,sBAAsB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAOnF;AAED,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,MAAM,CAAC,QAA2B,EAC5C,IAAI,GAAE,MAAqB,EAC3B,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,IAAI,CAAC,EAAE,UAAU,GAChB,MAAM,CAIR;AAaD,wBAAgB,gCAAgC,CAC9C,OAAO,GAAE,uCAA4C,GACpD,UAAU,EAAE,CAKd;AA2BD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,IAAI,CAAC,kBAAkB,EAAE,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAC,GAAG,UAAU,GAAG,SAAS,CAM3H;AAED,wBAAgB,uCAAuC,CACrD,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,MAAM,CAAC,QAA2B,EAC5C,IAAI,GAAE,MAAqB,EAC3B,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,OAAO,GAAE,4BAAiC,GACzC,MAAM,EAAE,CASV;AAED,wBAAgB,mCAAmC,CACjD,QAAQ,EAAE,qBAAqB,EAC/B,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,CAAC,QAAQ,EACzB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,4BAAiC,GACzC,kBAAkB,EAAE,CAiBtB;AAED,wBAAgB,oBAAoB,CAAC,WAAW,SAAmB,GAAG,OAAO,CAE5E;AAED,wBAAsB,yBAAyB,CAC7C,WAAW,SAAmB,EAC9B,OAAO,CAAC,EAAE,MAAM,EAChB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAAC,qBAAqB,CAAC,CAUhC;AAsCD,MAAM,MAAM,wBAAwB,GAChC,UAAU,GACV,SAAS,GACT,yBAAyB,GACzB,eAAe,GACf,cAAc,GACd,iBAAiB,GACjB,iBAAiB,GACjB,oBAAoB,GACpB,mBAAmB,GACnB,mBAAmB,GACnB,yBAAyB,GACzB,iBAAiB,GACjB,0BAA0B,GAC1B,gBAAgB,CAAC;AAErB,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,oBAAoB,GAAG,oBAAoB,GAAG,aAAa,GAAG,iBAAiB,GAAG,sBAAsB,CAAC;IACzH,KAAK,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;CACpF;AAED,MAAM,WAAW,6BAA6B;IAC5C,KAAK,EAAE,wBAAwB,CAAC;IAChC,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,yBAAyB,CAAC;CAClC;AAYD,UAAU,qBAAqB;IAC7B,kBAAkB,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClD;AAID,oEAAoE;AACpE,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,qBAAqB,GAAG,SAAS,GAAG,MAAM,IAAI,CAIrG;AAgLD,qEAAqE;AACrE,wBAAsB,0BAA0B,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAAC,6BAA6B,CAAC,CA4CjJ;AA6HD,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,aAAa,EACtB,OAAO,GAAE,0BAA+B,GACvC,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA4E7B"}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
|
-
import {
|
|
3
|
-
import { copyFile, mkdir, mkdtemp, readFile,
|
|
4
|
-
import { homedir, tmpdir } from 'node:os';
|
|
5
|
-
import { dirname,
|
|
2
|
+
import { constants, createWriteStream, existsSync, readdirSync } from 'node:fs';
|
|
3
|
+
import { chmod, copyFile, lstat, mkdir, mkdtemp, open, readFile, realpath, rename, rm, stat, unlink } from 'node:fs/promises';
|
|
4
|
+
import { homedir, hostname, tmpdir } from 'node:os';
|
|
5
|
+
import { dirname, join, relative, resolve, sep } from 'node:path';
|
|
6
6
|
import { pipeline } from 'node:stream/promises';
|
|
7
7
|
import { Readable } from 'node:stream';
|
|
8
8
|
import { spawnPlatformCommandSync } from '../utils/platform-command.js';
|
|
9
9
|
import { getPackageRoot } from '../utils/package.js';
|
|
10
|
+
import { validateNativeReleaseManifest } from '../native-assets/policy.js';
|
|
11
|
+
import { inspectNativeArchive, selectNativeArchiveBinary, writeSelectedNativeArchiveMember } from '../native-assets/archive.js';
|
|
10
12
|
const NATIVE_AUTO_FETCH_ENV = 'OMX_NATIVE_AUTO_FETCH';
|
|
11
13
|
const NATIVE_MANIFEST_URL_ENV = 'OMX_NATIVE_MANIFEST_URL';
|
|
12
14
|
const NATIVE_RELEASE_BASE_URL_ENV = 'OMX_NATIVE_RELEASE_BASE_URL';
|
|
@@ -162,7 +164,11 @@ export async function loadNativeReleaseManifest(packageRoot = getPackageRoot(),
|
|
|
162
164
|
if (!response.ok) {
|
|
163
165
|
throw new Error(`[native-assets] failed to fetch native release manifest (${response.status} ${response.statusText}) from ${url}`);
|
|
164
166
|
}
|
|
165
|
-
|
|
167
|
+
const manifest = await response.json();
|
|
168
|
+
validateNativeReleaseManifest(manifest);
|
|
169
|
+
if (version && manifest.version !== version)
|
|
170
|
+
throw new Error(`[native-assets] manifest version mismatch: expected ${version}, received ${manifest.version}`);
|
|
171
|
+
return manifest;
|
|
166
172
|
}
|
|
167
173
|
function isUnavailableManifestError(error) {
|
|
168
174
|
if (!(error instanceof Error))
|
|
@@ -189,46 +195,439 @@ async function sha256ForFile(path) {
|
|
|
189
195
|
hash.update(await readFile(path));
|
|
190
196
|
return hash.digest('hex');
|
|
191
197
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
198
|
+
const SIDECAR_SUFFIX = '.sha256';
|
|
199
|
+
const LOCK_SUFFIX = '.hydrate.lock';
|
|
200
|
+
const LOCK_WAIT_MS = 10_000;
|
|
201
|
+
const LOCK_RETRY_MS = 100;
|
|
202
|
+
const NATIVE_LOCK_WAIT_MS_ENV = 'OMX_NATIVE_LOCK_WAIT_MS';
|
|
203
|
+
const SHA256_LINE = /^[0-9a-f]{64}\n$/;
|
|
204
|
+
function sidecarPath(binaryPath) { return `${binaryPath}${SIDECAR_SUFFIX}`; }
|
|
205
|
+
function lockPath(binaryPath) { return `${binaryPath}${LOCK_SUFFIX}`; }
|
|
206
|
+
function sameFile(left, right) { return left.dev === right.dev && left.ino === right.ino && left.size === right.size; }
|
|
207
|
+
function errno(error) { return error.code; }
|
|
208
|
+
function uuid() { return crypto.randomUUID(); }
|
|
209
|
+
function absent(error) { return errno(error) === 'ENOENT'; }
|
|
210
|
+
let nativeAssetsTestHooks;
|
|
211
|
+
/** Test-only seam for deterministic cache-parent creation races. */
|
|
212
|
+
export function setNativeAssetsTestHooksForTests(hooks) {
|
|
213
|
+
const previousHooks = nativeAssetsTestHooks;
|
|
214
|
+
nativeAssetsTestHooks = hooks;
|
|
215
|
+
return () => { nativeAssetsTestHooks = previousHooks; };
|
|
216
|
+
}
|
|
217
|
+
function lockWaitMs(env) {
|
|
218
|
+
const configured = env[NATIVE_LOCK_WAIT_MS_ENV]?.trim();
|
|
219
|
+
if (!configured)
|
|
220
|
+
return LOCK_WAIT_MS;
|
|
221
|
+
const value = Number(configured);
|
|
222
|
+
return Number.isFinite(value) && value >= 0 ? value : LOCK_WAIT_MS;
|
|
223
|
+
}
|
|
224
|
+
function lockRecord(token, binaryPath) {
|
|
225
|
+
return `${JSON.stringify({
|
|
226
|
+
version: 1,
|
|
227
|
+
token,
|
|
228
|
+
pid: process.pid,
|
|
229
|
+
hostname: hostname(),
|
|
230
|
+
started_at: new Date().toISOString(),
|
|
231
|
+
binary_path: binaryPath,
|
|
232
|
+
})}\n`;
|
|
233
|
+
}
|
|
234
|
+
function canonicalDescendantPath(path, configuredRoot, canonicalRoot) {
|
|
235
|
+
const resolvedPath = resolve(path);
|
|
236
|
+
const canonicalRelative = relative(canonicalRoot, resolvedPath);
|
|
237
|
+
if (canonicalRelative && canonicalRelative !== '..' && !canonicalRelative.startsWith(`..${sep}`))
|
|
238
|
+
return resolvedPath;
|
|
239
|
+
const rel = relative(resolve(configuredRoot), resolvedPath);
|
|
240
|
+
if (!rel || rel === '..' || rel.startsWith(`..${sep}`))
|
|
241
|
+
throw new Error('[native-assets] cache path escapes configured root');
|
|
242
|
+
return join(canonicalRoot, rel);
|
|
243
|
+
}
|
|
244
|
+
async function canonicalCacheRoot(root, create) {
|
|
245
|
+
try {
|
|
246
|
+
if (create)
|
|
247
|
+
await mkdir(root, { recursive: true, mode: 0o700 });
|
|
248
|
+
const entry = await lstat(root);
|
|
249
|
+
if (!entry.isDirectory() && !entry.isSymbolicLink())
|
|
250
|
+
throw new Error('unsafe root');
|
|
251
|
+
return await realpath(root); // The configured root itself is intentionally allowed to be a symlink.
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
if (!create && absent(error))
|
|
255
|
+
return undefined;
|
|
256
|
+
throw error;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
async function validateDescendant(path, canonicalRoot, createParents) {
|
|
260
|
+
const candidate = resolve(path);
|
|
261
|
+
const rel = relative(canonicalRoot, candidate);
|
|
262
|
+
if (!rel || rel === '..' || rel.startsWith(`..${sep}`) || resolve(canonicalRoot, rel) !== candidate) {
|
|
263
|
+
throw new Error('[native-assets] cache path escapes configured root');
|
|
264
|
+
}
|
|
265
|
+
const parts = rel.split(sep).filter(Boolean);
|
|
266
|
+
let current = canonicalRoot;
|
|
267
|
+
for (const [index, part] of parts.entries()) {
|
|
268
|
+
current = join(current, part);
|
|
269
|
+
const isLeaf = index === parts.length - 1;
|
|
270
|
+
try {
|
|
271
|
+
const entry = await lstat(current);
|
|
272
|
+
if (!isLeaf && (entry.isSymbolicLink() || !entry.isDirectory()))
|
|
273
|
+
throw new Error(`[native-assets] cache descendant is unsafe: ${current}`);
|
|
201
274
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
throw new Error(`[native-assets] failed to extract archive ${archivePath}: ${(result.stderr || result.error?.message || '').trim()}`);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
async function findExtractedBinaryPath(rootDir, binaryPath) {
|
|
210
|
-
const normalizedNeedle = binaryPath.replaceAll('\\', '/');
|
|
211
|
-
const exactCandidate = join(rootDir, binaryPath);
|
|
212
|
-
if (existsSync(exactCandidate))
|
|
213
|
-
return exactCandidate;
|
|
214
|
-
const pending = [rootDir];
|
|
215
|
-
while (pending.length > 0) {
|
|
216
|
-
const current = pending.pop();
|
|
217
|
-
const entries = await readdir(current, { withFileTypes: true });
|
|
218
|
-
for (const entry of entries) {
|
|
219
|
-
const fullPath = join(current, entry.name);
|
|
220
|
-
if (entry.isDirectory()) {
|
|
221
|
-
pending.push(fullPath);
|
|
275
|
+
catch (error) {
|
|
276
|
+
if (!absent(error))
|
|
277
|
+
throw error;
|
|
278
|
+
if (!createParents || isLeaf)
|
|
222
279
|
continue;
|
|
280
|
+
await nativeAssetsTestHooks?.beforeCreateParent?.(current);
|
|
281
|
+
try {
|
|
282
|
+
await mkdir(current, { mode: 0o700 });
|
|
223
283
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
284
|
+
catch (error) {
|
|
285
|
+
if (errno(error) !== 'EEXIST')
|
|
286
|
+
throw error;
|
|
227
287
|
}
|
|
288
|
+
const created = await lstat(current);
|
|
289
|
+
if (!created.isDirectory() || created.isSymbolicLink())
|
|
290
|
+
throw new Error(`[native-assets] cache descendant is unsafe: ${current}`);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
try {
|
|
294
|
+
const parent = await realpath(dirname(path));
|
|
295
|
+
if (parent !== canonicalRoot && !parent.startsWith(`${canonicalRoot}${sep}`))
|
|
296
|
+
throw new Error('[native-assets] cache path escapes configured root');
|
|
297
|
+
}
|
|
298
|
+
catch (error) {
|
|
299
|
+
if (!absent(error))
|
|
300
|
+
throw error;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
async function reInspectPath(path, identity, requireNonEmpty) {
|
|
304
|
+
try {
|
|
305
|
+
const current = await lstat(path);
|
|
306
|
+
if (current.isSymbolicLink() || !current.isFile() || current.nlink !== 1
|
|
307
|
+
|| (requireNonEmpty && current.size <= 0)
|
|
308
|
+
|| !sameFile(identity, { dev: current.dev, ino: current.ino, size: current.size })) {
|
|
309
|
+
throw new Error('inspection race');
|
|
228
310
|
}
|
|
229
311
|
}
|
|
312
|
+
catch (error) {
|
|
313
|
+
if (absent(error))
|
|
314
|
+
throw new Error('inspection race');
|
|
315
|
+
throw error;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
async function readOpenedFile(path, requireNonEmpty, hash, maxBytes) {
|
|
319
|
+
const before = await lstat(path);
|
|
320
|
+
if (before.isSymbolicLink() || !before.isFile() || before.nlink !== 1)
|
|
321
|
+
throw new Error('unsafe file');
|
|
322
|
+
if (requireNonEmpty && before.size <= 0)
|
|
323
|
+
throw new Error('empty file');
|
|
324
|
+
if (maxBytes !== undefined && before.size > maxBytes)
|
|
325
|
+
throw new Error('file too large');
|
|
326
|
+
const handle = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
327
|
+
try {
|
|
328
|
+
const opened = await handle.stat();
|
|
329
|
+
const identity = { dev: opened.dev, ino: opened.ino, size: opened.size };
|
|
330
|
+
if (!opened.isFile() || opened.nlink !== 1 || (requireNonEmpty && opened.size <= 0)
|
|
331
|
+
|| (maxBytes !== undefined && opened.size > maxBytes)
|
|
332
|
+
|| !sameFile({ dev: before.dev, ino: before.ino, size: before.size }, identity))
|
|
333
|
+
throw new Error('inspection race');
|
|
334
|
+
const chunks = [];
|
|
335
|
+
const digest = hash ? createHash('sha256') : undefined;
|
|
336
|
+
const buffer = Buffer.alloc(Math.min(64 * 1024, maxBytes ?? 64 * 1024));
|
|
337
|
+
let position = 0;
|
|
338
|
+
while (position < opened.size) {
|
|
339
|
+
const { bytesRead } = await handle.read(buffer, 0, Math.min(buffer.length, opened.size - position), position);
|
|
340
|
+
if (bytesRead === 0)
|
|
341
|
+
throw new Error('inspection race');
|
|
342
|
+
const bytes = buffer.subarray(0, bytesRead);
|
|
343
|
+
digest?.update(bytes);
|
|
344
|
+
if (!hash)
|
|
345
|
+
chunks.push(Buffer.from(bytes));
|
|
346
|
+
position += bytesRead;
|
|
347
|
+
}
|
|
348
|
+
const after = await handle.stat();
|
|
349
|
+
if (!sameFile(identity, { dev: after.dev, ino: after.ino, size: after.size }) || after.nlink !== 1)
|
|
350
|
+
throw new Error('inspection race');
|
|
351
|
+
await reInspectPath(path, identity, requireNonEmpty);
|
|
352
|
+
return { ...identity, digest: digest?.digest('hex'), text: hash ? undefined : Buffer.concat(chunks).toString('utf8') };
|
|
353
|
+
}
|
|
354
|
+
finally {
|
|
355
|
+
await handle.close();
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
const MAX_SIDECAR_BYTES = 65;
|
|
359
|
+
const MAX_LOCK_RECORD_BYTES = 1024;
|
|
360
|
+
function validLockRecord(record, text, binaryPath) {
|
|
361
|
+
if (record.version !== 1 || typeof record.token !== 'string'
|
|
362
|
+
|| !/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(record.token)
|
|
363
|
+
|| typeof record.pid !== 'number' || !Number.isSafeInteger(record.pid) || record.pid <= 0
|
|
364
|
+
|| typeof record.hostname !== 'string' || !record.hostname.trim()
|
|
365
|
+
|| typeof record.started_at !== 'string' || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/.test(record.started_at)
|
|
366
|
+
|| !Number.isFinite(Date.parse(record.started_at))
|
|
367
|
+
|| typeof record.binary_path !== 'string' || !record.binary_path.trim() || record.binary_path !== binaryPath)
|
|
368
|
+
return false;
|
|
369
|
+
return text === `${JSON.stringify(record)}\n`;
|
|
370
|
+
}
|
|
371
|
+
function sanitizeLockDiagnosticField(value) {
|
|
372
|
+
return value.replace(/[\r\n\t\0]/g, ' ').replace(/[^\x20-\x7e]/g, '?').slice(0, 512);
|
|
373
|
+
}
|
|
374
|
+
async function inspectLock(path, binaryPath) {
|
|
375
|
+
try {
|
|
376
|
+
const file = await readOpenedFile(path, false, false, MAX_LOCK_RECORD_BYTES);
|
|
377
|
+
const text = file.text || '';
|
|
378
|
+
const parsed = JSON.parse(text);
|
|
379
|
+
const record = {
|
|
380
|
+
version: parsed.version,
|
|
381
|
+
token: parsed.token,
|
|
382
|
+
pid: parsed.pid,
|
|
383
|
+
hostname: parsed.hostname,
|
|
384
|
+
started_at: parsed.started_at,
|
|
385
|
+
binary_path: parsed.binary_path,
|
|
386
|
+
};
|
|
387
|
+
if (!validLockRecord(record, text, binaryPath))
|
|
388
|
+
return { path, classification: 'metadata-malformed' };
|
|
389
|
+
return {
|
|
390
|
+
path,
|
|
391
|
+
classification: 'valid-owner-record',
|
|
392
|
+
owner: {
|
|
393
|
+
pid: record.pid,
|
|
394
|
+
hostname: sanitizeLockDiagnosticField(record.hostname),
|
|
395
|
+
started_at: record.started_at,
|
|
396
|
+
binary_path: sanitizeLockDiagnosticField(record.binary_path),
|
|
397
|
+
},
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
catch (error) {
|
|
401
|
+
if (absent(error))
|
|
402
|
+
return undefined;
|
|
403
|
+
const message = error instanceof Error ? error.message : '';
|
|
404
|
+
return { path, classification: message.includes('race') ? 'inspection-race' : message.includes('unsafe') ? 'lock-unsafe' : error instanceof SyntaxError || message.includes('too large') ? 'metadata-malformed' : 'metadata-unavailable' };
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
/** Inspects the exact B/S/L protocol. Only `verified` has a path. */
|
|
408
|
+
export async function inspectManagedNativeBinary(binaryPath, env = process.env) {
|
|
409
|
+
const configuredRoot = resolveNativeCacheRoot(env);
|
|
410
|
+
let root;
|
|
411
|
+
let effectiveBinaryPath;
|
|
412
|
+
try {
|
|
413
|
+
root = await canonicalCacheRoot(configuredRoot, false);
|
|
414
|
+
if (!root)
|
|
415
|
+
return { state: 'missing' };
|
|
416
|
+
effectiveBinaryPath = canonicalDescendantPath(binaryPath, configuredRoot, root);
|
|
417
|
+
await validateDescendant(effectiveBinaryPath, root, false);
|
|
418
|
+
await validateDescendant(sidecarPath(effectiveBinaryPath), root, false);
|
|
419
|
+
await validateDescendant(lockPath(effectiveBinaryPath), root, false);
|
|
420
|
+
}
|
|
421
|
+
catch (error) {
|
|
422
|
+
return { state: error instanceof Error && error.message.includes('race') ? 'inspection-race' : 'cache-descendant-unsafe' };
|
|
423
|
+
}
|
|
424
|
+
const lockDiagnostic = await inspectLock(lockPath(effectiveBinaryPath), effectiveBinaryPath);
|
|
425
|
+
try {
|
|
426
|
+
await validateDescendant(effectiveBinaryPath, root, false);
|
|
427
|
+
await validateDescendant(sidecarPath(effectiveBinaryPath), root, false);
|
|
428
|
+
await validateDescendant(lockPath(effectiveBinaryPath), root, false);
|
|
429
|
+
}
|
|
430
|
+
catch {
|
|
431
|
+
return { state: 'inspection-race' };
|
|
432
|
+
}
|
|
433
|
+
let binary;
|
|
434
|
+
try {
|
|
435
|
+
binary = await readOpenedFile(effectiveBinaryPath, true, true);
|
|
436
|
+
}
|
|
437
|
+
catch (error) {
|
|
438
|
+
if (!absent(error)) {
|
|
439
|
+
const message = error instanceof Error ? error.message : '';
|
|
440
|
+
return { state: message.includes('empty') ? 'binary-empty' : message.includes('race') ? 'inspection-race' : 'binary-unsafe', lock: lockDiagnostic };
|
|
441
|
+
}
|
|
442
|
+
try {
|
|
443
|
+
await lstat(sidecarPath(effectiveBinaryPath));
|
|
444
|
+
return { state: 'orphan-checksum', lock: lockDiagnostic };
|
|
445
|
+
}
|
|
446
|
+
catch (sidecarError) {
|
|
447
|
+
if (!absent(sidecarError))
|
|
448
|
+
return { state: 'inspection-race', lock: lockDiagnostic };
|
|
449
|
+
return { state: lockDiagnostic ? 'publication-in-progress' : 'missing', lock: lockDiagnostic };
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
try {
|
|
453
|
+
await validateDescendant(effectiveBinaryPath, root, false);
|
|
454
|
+
}
|
|
455
|
+
catch {
|
|
456
|
+
return { state: 'inspection-race', lock: lockDiagnostic };
|
|
457
|
+
}
|
|
458
|
+
let sidecar;
|
|
459
|
+
try {
|
|
460
|
+
sidecar = await readOpenedFile(sidecarPath(effectiveBinaryPath), true, false, MAX_SIDECAR_BYTES);
|
|
461
|
+
}
|
|
462
|
+
catch (error) {
|
|
463
|
+
if (absent(error))
|
|
464
|
+
return { state: lockDiagnostic ? 'publication-in-progress' : 'legacy-unverified', lock: lockDiagnostic };
|
|
465
|
+
return { state: error instanceof Error && error.message.includes('too large') ? 'checksum-malformed' : 'checksum-unsafe', lock: lockDiagnostic };
|
|
466
|
+
}
|
|
467
|
+
try {
|
|
468
|
+
await validateDescendant(sidecarPath(effectiveBinaryPath), root, false);
|
|
469
|
+
}
|
|
470
|
+
catch {
|
|
471
|
+
return { state: 'inspection-race', lock: lockDiagnostic };
|
|
472
|
+
}
|
|
473
|
+
if (sidecar.size !== MAX_SIDECAR_BYTES || !SHA256_LINE.test(sidecar.text || ''))
|
|
474
|
+
return { state: 'checksum-malformed', lock: lockDiagnostic };
|
|
475
|
+
if (sidecar.text.slice(0, 64) !== binary.digest)
|
|
476
|
+
return { state: 'checksum-mismatch', lock: lockDiagnostic };
|
|
477
|
+
return { state: 'verified', path: effectiveBinaryPath, lock: lockDiagnostic };
|
|
478
|
+
}
|
|
479
|
+
async function acquireCacheLock(binaryPath, env) {
|
|
480
|
+
const path = lockPath(binaryPath);
|
|
481
|
+
const started = performance.now();
|
|
482
|
+
const deadline = started + lockWaitMs(env);
|
|
483
|
+
for (;;) {
|
|
484
|
+
const token = uuid();
|
|
485
|
+
const record = lockRecord(token, binaryPath);
|
|
486
|
+
const recordBytes = Buffer.from(record, 'utf8');
|
|
487
|
+
try {
|
|
488
|
+
const handle = await open(path, constants.O_RDWR | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o600);
|
|
489
|
+
try {
|
|
490
|
+
const { bytesWritten } = await handle.write(recordBytes, 0, recordBytes.length, 0);
|
|
491
|
+
if (bytesWritten !== recordBytes.length)
|
|
492
|
+
throw new Error('[native-assets] incomplete lock write');
|
|
493
|
+
const readback = Buffer.alloc(recordBytes.length);
|
|
494
|
+
const { bytesRead } = await handle.read(readback, 0, readback.length, 0);
|
|
495
|
+
if (bytesRead !== readback.length || !readback.equals(recordBytes))
|
|
496
|
+
throw new Error('[native-assets] lock readback mismatch');
|
|
497
|
+
const identity = await handle.stat();
|
|
498
|
+
const fileIdentity = { dev: identity.dev, ino: identity.ino, size: identity.size };
|
|
499
|
+
if (!identity.isFile() || identity.nlink !== 1)
|
|
500
|
+
throw new Error('[native-assets] unsafe publication lock');
|
|
501
|
+
await reInspectPath(path, fileIdentity, true);
|
|
502
|
+
return { path, token, record, identity: fileIdentity };
|
|
503
|
+
}
|
|
504
|
+
finally {
|
|
505
|
+
await handle.close();
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
catch (error) {
|
|
509
|
+
if (errno(error) !== 'EEXIST')
|
|
510
|
+
throw error;
|
|
511
|
+
if (performance.now() >= deadline) {
|
|
512
|
+
const diagnostic = await inspectLock(path, binaryPath) ?? { path, classification: 'metadata-unavailable' };
|
|
513
|
+
const owner = diagnostic.owner ? ` owner=${JSON.stringify(diagnostic.owner)}` : '';
|
|
514
|
+
throw new Error(`[native-assets] publication-lock-timeout: ${path}; elapsed=${Math.round(performance.now() - started)}ms deadline=${lockWaitMs(env)}ms; ${diagnostic.classification}${owner}. Confirm no OMX hydration process is active for this cache key, remove only this named lock manually, then retry.`);
|
|
515
|
+
}
|
|
516
|
+
await new Promise((done) => setTimeout(done, LOCK_RETRY_MS));
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
async function releaseCacheLock(lock) {
|
|
521
|
+
try {
|
|
522
|
+
const reopened = await readOpenedFile(lock.path, false, false);
|
|
523
|
+
if (!sameFile(lock.identity, reopened) || reopened.text !== lock.record)
|
|
524
|
+
return { state: 'cleanup-failed' };
|
|
525
|
+
const current = await lstat(lock.path);
|
|
526
|
+
if (!sameFile(lock.identity, { dev: current.dev, ino: current.ino, size: current.size }) || !current.isFile() || current.nlink !== 1)
|
|
527
|
+
return { state: 'cleanup-failed' };
|
|
528
|
+
await unlink(lock.path);
|
|
529
|
+
}
|
|
530
|
+
catch (error) {
|
|
531
|
+
return absent(error) ? undefined : { state: 'cleanup-failed' };
|
|
532
|
+
}
|
|
230
533
|
return undefined;
|
|
231
534
|
}
|
|
535
|
+
async function quarantineInvalid(path) {
|
|
536
|
+
try {
|
|
537
|
+
await lstat(path);
|
|
538
|
+
await rename(path, `${path}.quarantine.${uuid()}`);
|
|
539
|
+
}
|
|
540
|
+
catch (error) {
|
|
541
|
+
if (!absent(error))
|
|
542
|
+
throw error;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
async function publishManagedNativeBinary(source, destination, platform, env) {
|
|
546
|
+
const configuredRoot = resolveNativeCacheRoot(env);
|
|
547
|
+
const root = await canonicalCacheRoot(configuredRoot, true);
|
|
548
|
+
if (!root)
|
|
549
|
+
throw new Error('[native-assets] unable to create cache root');
|
|
550
|
+
destination = canonicalDescendantPath(destination, configuredRoot, root);
|
|
551
|
+
await validateDescendant(destination, root, true);
|
|
552
|
+
const lock = await acquireCacheLock(destination, env);
|
|
553
|
+
const attempt = uuid();
|
|
554
|
+
const tempBinary = join(dirname(destination), `.${attempt}.tmp.bin`);
|
|
555
|
+
const tempSidecar = join(dirname(destination), `.${attempt}.tmp.sha256`);
|
|
556
|
+
const revalidatePublicationPaths = async () => {
|
|
557
|
+
await validateDescendant(destination, root, false);
|
|
558
|
+
await validateDescendant(sidecarPath(destination), root, false);
|
|
559
|
+
await validateDescendant(lock.path, root, false);
|
|
560
|
+
await validateDescendant(tempBinary, root, false);
|
|
561
|
+
await validateDescendant(tempSidecar, root, false);
|
|
562
|
+
};
|
|
563
|
+
let primaryError;
|
|
564
|
+
try {
|
|
565
|
+
await revalidatePublicationPaths();
|
|
566
|
+
const existing = await inspectManagedNativeBinary(destination, env);
|
|
567
|
+
if (existing.state === 'verified')
|
|
568
|
+
return existing.path;
|
|
569
|
+
await copyFile(source, tempBinary, constants.COPYFILE_EXCL);
|
|
570
|
+
await revalidatePublicationPaths();
|
|
571
|
+
if (platform !== 'win32')
|
|
572
|
+
await chmod(tempBinary, 0o755);
|
|
573
|
+
const binary = await readOpenedFile(tempBinary, true, true);
|
|
574
|
+
const sidecar = `${binary.digest}\n`;
|
|
575
|
+
const handle = await open(tempSidecar, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o600);
|
|
576
|
+
try {
|
|
577
|
+
await handle.writeFile(sidecar, 'utf8');
|
|
578
|
+
}
|
|
579
|
+
finally {
|
|
580
|
+
await handle.close();
|
|
581
|
+
}
|
|
582
|
+
if ((await readOpenedFile(tempSidecar, true, false, MAX_SIDECAR_BYTES)).text !== sidecar)
|
|
583
|
+
throw new Error('[native-assets] temporary checksum verification failed');
|
|
584
|
+
await revalidatePublicationPaths();
|
|
585
|
+
await quarantineInvalid(destination);
|
|
586
|
+
await revalidatePublicationPaths();
|
|
587
|
+
await quarantineInvalid(sidecarPath(destination));
|
|
588
|
+
await revalidatePublicationPaths();
|
|
589
|
+
await rename(tempBinary, destination);
|
|
590
|
+
await revalidatePublicationPaths();
|
|
591
|
+
await rename(tempSidecar, sidecarPath(destination));
|
|
592
|
+
await revalidatePublicationPaths();
|
|
593
|
+
const final = await inspectManagedNativeBinary(destination, env);
|
|
594
|
+
await revalidatePublicationPaths();
|
|
595
|
+
if (final.state !== 'verified')
|
|
596
|
+
throw new Error(`[native-assets] cache publication verification failed: ${final.state}`);
|
|
597
|
+
return final.path;
|
|
598
|
+
}
|
|
599
|
+
catch (error) {
|
|
600
|
+
primaryError = error;
|
|
601
|
+
throw error;
|
|
602
|
+
}
|
|
603
|
+
finally {
|
|
604
|
+
const cleanupFailures = [];
|
|
605
|
+
try {
|
|
606
|
+
await revalidatePublicationPaths();
|
|
607
|
+
}
|
|
608
|
+
catch (error) {
|
|
609
|
+
cleanupFailures.push(`revalidate publication paths: ${error instanceof Error ? error.message : String(error)}`);
|
|
610
|
+
}
|
|
611
|
+
for (const temporary of [tempBinary, tempSidecar]) {
|
|
612
|
+
try {
|
|
613
|
+
await rm(temporary, { force: true });
|
|
614
|
+
}
|
|
615
|
+
catch (error) {
|
|
616
|
+
cleanupFailures.push(`remove ${temporary}: ${error instanceof Error ? error.message : String(error)}`);
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
const lockCleanup = await releaseCacheLock(lock);
|
|
620
|
+
if (lockCleanup)
|
|
621
|
+
cleanupFailures.push(`${lockCleanup.state}: publication lock was retained`);
|
|
622
|
+
if (cleanupFailures.length > 0) {
|
|
623
|
+
const evidence = `[native-assets] cleanup evidence: ${cleanupFailures.join('; ')}`;
|
|
624
|
+
if (primaryError instanceof Error)
|
|
625
|
+
primaryError.message += `\n${evidence}`;
|
|
626
|
+
else
|
|
627
|
+
throw new Error(evidence);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
}
|
|
232
631
|
export async function hydrateNativeBinary(product, options = {}) {
|
|
233
632
|
const { packageRoot = getPackageRoot(), env = process.env, platform = process.platform, arch = process.arch, } = options;
|
|
234
633
|
if (env[NATIVE_AUTO_FETCH_ENV]?.trim() === '0')
|
|
@@ -239,8 +638,9 @@ export async function hydrateNativeBinary(product, options = {}) {
|
|
|
239
638
|
return undefined;
|
|
240
639
|
const version = await getPackageVersion(packageRoot);
|
|
241
640
|
for (const cachedBinaryPath of resolveCachedNativeBinaryCandidatePaths(product, version, platform, arch, env)) {
|
|
242
|
-
|
|
243
|
-
|
|
641
|
+
const inspected = await inspectManagedNativeBinary(cachedBinaryPath, env);
|
|
642
|
+
if (inspected.state === 'verified')
|
|
643
|
+
return inspected.path;
|
|
244
644
|
}
|
|
245
645
|
let manifest;
|
|
246
646
|
try {
|
|
@@ -257,7 +657,7 @@ export async function hydrateNativeBinary(product, options = {}) {
|
|
|
257
657
|
if (assets.length === 0)
|
|
258
658
|
return undefined;
|
|
259
659
|
const tempRoot = await mkdtemp(join(tmpdir(), `${product}-${platform}-${arch}-`));
|
|
260
|
-
const
|
|
660
|
+
const extractedBinaryPath = join(tempRoot, 'native-binary');
|
|
261
661
|
try {
|
|
262
662
|
for (let index = 0; index < assets.length; index += 1) {
|
|
263
663
|
const asset = assets[index];
|
|
@@ -273,21 +673,18 @@ export async function hydrateNativeBinary(product, options = {}) {
|
|
|
273
673
|
if (digest !== asset.sha256) {
|
|
274
674
|
throw new Error(`[native-assets] checksum mismatch for ${asset.archive}`);
|
|
275
675
|
}
|
|
276
|
-
await
|
|
277
|
-
const
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
if (platform !== 'win32')
|
|
284
|
-
chmodSync(cachedBinaryPath, 0o755);
|
|
285
|
-
return cachedBinaryPath;
|
|
676
|
+
const archiveEntries = await inspectNativeArchive(archivePath);
|
|
677
|
+
const archiveBinary = selectNativeArchiveBinary(archiveEntries, asset.binary_path);
|
|
678
|
+
await writeSelectedNativeArchiveMember(archivePath, archiveBinary.path, extractedBinaryPath);
|
|
679
|
+
const published = await publishManagedNativeBinary(extractedBinaryPath, cachedBinaryPath, platform, env);
|
|
680
|
+
if (published)
|
|
681
|
+
return published;
|
|
682
|
+
throw new Error(`[native-assets] cache publication verification failed for ${cachedBinaryPath}`);
|
|
286
683
|
}
|
|
287
684
|
catch (error) {
|
|
288
685
|
if (index < assets.length - 1 && isUnavailableArchiveError(error)) {
|
|
289
686
|
await rm(archivePath, { force: true });
|
|
290
|
-
await rm(
|
|
687
|
+
await rm(extractedBinaryPath, { force: true });
|
|
291
688
|
continue;
|
|
292
689
|
}
|
|
293
690
|
throw error;
|