context-brake 0.0.0-stage → 1.0.0
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/LICENSE +21 -0
- package/README.md +361 -2
- package/dist/assets/runtime/antigravity-cli-hook.mjs +19174 -0
- package/dist/assets/runtime/claude-code-hook.mjs +19302 -0
- package/dist/assets/runtime/claude-code-mod.mjs +18579 -0
- package/dist/assets/runtime/claude-code-statusline.mjs +18749 -0
- package/dist/assets/runtime/codex-cli-hook.mjs +19299 -0
- package/dist/assets/runtime/context-brake-runtime.mjs +6 -0
- package/dist/assets/runtime/cursor-hook.mjs +19181 -0
- package/dist/assets/runtime/github-copilot-cli-hook.mjs +19186 -0
- package/dist/assets/runtime/omp-extension.js +19237 -0
- package/dist/assets/runtime/omp-restart.js +18763 -0
- package/dist/assets/runtime/opencode-plugin.js +19200 -0
- package/dist/assets/runtime/pi-extension.js +19228 -0
- package/dist/assets/runtime/pi-restart.js +18758 -0
- package/dist/src/cli/argument-parser.d.ts +20 -0
- package/dist/src/cli/argument-parser.js +45 -0
- package/dist/src/cli/argument-validator.d.ts +8 -0
- package/dist/src/cli/argument-validator.js +24 -0
- package/dist/src/cli/assistant/ask.d.ts +10 -0
- package/dist/src/cli/assistant/ask.js +36 -0
- package/dist/src/cli/assistant/assistant-context.d.ts +9 -0
- package/dist/src/cli/assistant/assistant-context.js +18 -0
- package/dist/src/cli/assistant/assistant-questions.d.ts +3 -0
- package/dist/src/cli/assistant/assistant-questions.js +26 -0
- package/dist/src/cli/assistant/assistant-session.d.ts +5 -0
- package/dist/src/cli/assistant/assistant-session.js +25 -0
- package/dist/src/cli/assistant/clack-prompt-port.d.ts +14 -0
- package/dist/src/cli/assistant/clack-prompt-port.js +47 -0
- package/dist/src/cli/assistant/equivalent-command.d.ts +1 -0
- package/dist/src/cli/assistant/equivalent-command.js +16 -0
- package/dist/src/cli/assistant/prompt-factory.d.ts +3 -0
- package/dist/src/cli/assistant/prompt-factory.js +16 -0
- package/dist/src/cli/assistant/prompt-port.d.ts +14 -0
- package/dist/src/cli/assistant/prompt-port.js +28 -0
- package/dist/src/cli/assistant/questions-gitignore.d.ts +7 -0
- package/dist/src/cli/assistant/questions-gitignore.js +14 -0
- package/dist/src/cli/assistant/questions-harness.d.ts +9 -0
- package/dist/src/cli/assistant/questions-harness.js +52 -0
- package/dist/src/cli/assistant/questions-misc.d.ts +10 -0
- package/dist/src/cli/assistant/questions-misc.js +25 -0
- package/dist/src/cli/assistant/questions-restart.d.ts +15 -0
- package/dist/src/cli/assistant/questions-restart.js +51 -0
- package/dist/src/cli/assistant/questions-snapshot.d.ts +9 -0
- package/dist/src/cli/assistant/questions-snapshot.js +64 -0
- package/dist/src/cli/assistant/snapshot-specs.d.ts +4 -0
- package/dist/src/cli/assistant/snapshot-specs.js +22 -0
- package/dist/src/cli/assistant/summary.d.ts +2 -0
- package/dist/src/cli/assistant/summary.js +34 -0
- package/dist/src/cli/assistant/types.d.ts +37 -0
- package/dist/src/cli/assistant/types.js +1 -0
- package/dist/src/cli/assistant/ui-prompt.d.ts +29 -0
- package/dist/src/cli/assistant/ui-prompt.js +1 -0
- package/dist/src/cli/commands/doctor.d.ts +3 -0
- package/dist/src/cli/commands/doctor.js +56 -0
- package/dist/src/cli/commands/init.d.ts +4 -0
- package/dist/src/cli/commands/init.js +26 -0
- package/dist/src/cli/commands/remove.d.ts +3 -0
- package/dist/src/cli/commands/remove.js +62 -0
- package/dist/src/cli/composition-root.d.ts +3 -0
- package/dist/src/cli/composition-root.js +62 -0
- package/dist/src/cli/confirmation.d.ts +6 -0
- package/dist/src/cli/confirmation.js +22 -0
- package/dist/src/cli/detection-collector.d.ts +14 -0
- package/dist/src/cli/detection-collector.js +31 -0
- package/dist/src/cli/exit-codes.d.ts +8 -0
- package/dist/src/cli/exit-codes.js +8 -0
- package/dist/src/cli/gitignore-findings.d.ts +3 -0
- package/dist/src/cli/gitignore-findings.js +11 -0
- package/dist/src/cli/handoff-findings.d.ts +5 -0
- package/dist/src/cli/handoff-findings.js +15 -0
- package/dist/src/cli/init-arguments.d.ts +25 -0
- package/dist/src/cli/init-arguments.js +70 -0
- package/dist/src/cli/init-config-state.d.ts +14 -0
- package/dist/src/cli/init-config-state.js +19 -0
- package/dist/src/cli/init-config-updates.d.ts +13 -0
- package/dist/src/cli/init-config-updates.js +35 -0
- package/dist/src/cli/init-flow.d.ts +14 -0
- package/dist/src/cli/init-flow.js +72 -0
- package/dist/src/cli/init-option-rules.d.ts +11 -0
- package/dist/src/cli/init-option-rules.js +29 -0
- package/dist/src/cli/main.d.ts +3 -0
- package/dist/src/cli/main.js +62 -0
- package/dist/src/cli/output/detection-text.d.ts +2 -0
- package/dist/src/cli/output/detection-text.js +3 -0
- package/dist/src/cli/output/doctor-mode-text.d.ts +2 -0
- package/dist/src/cli/output/doctor-mode-text.js +12 -0
- package/dist/src/cli/output/doctor-sessions-text.d.ts +2 -0
- package/dist/src/cli/output/doctor-sessions-text.js +12 -0
- package/dist/src/cli/output/json.d.ts +1 -0
- package/dist/src/cli/output/json.js +3 -0
- package/dist/src/cli/output/text.d.ts +5 -0
- package/dist/src/cli/output/text.js +68 -0
- package/dist/src/cli/snapshot-helper.d.ts +3 -0
- package/dist/src/cli/snapshot-helper.js +25 -0
- package/dist/src/cli/terminal.d.ts +9 -0
- package/dist/src/cli/terminal.js +18 -0
- package/dist/src/core/contracts/adapter.d.ts +49 -0
- package/dist/src/core/contracts/adapter.js +1 -0
- package/dist/src/core/contracts/auto-restart.d.ts +10 -0
- package/dist/src/core/contracts/auto-restart.js +10 -0
- package/dist/src/core/contracts/changes.d.ts +219 -0
- package/dist/src/core/contracts/changes.js +13 -0
- package/dist/src/core/contracts/configuration.d.ts +81 -0
- package/dist/src/core/contracts/configuration.js +52 -0
- package/dist/src/core/contracts/context-window-report.d.ts +16 -0
- package/dist/src/core/contracts/context-window-report.js +8 -0
- package/dist/src/core/contracts/diagnostics.d.ts +546 -0
- package/dist/src/core/contracts/diagnostics.js +35 -0
- package/dist/src/core/contracts/handoff.d.ts +10 -0
- package/dist/src/core/contracts/handoff.js +3 -0
- package/dist/src/core/contracts/harness.d.ts +73 -0
- package/dist/src/core/contracts/harness.js +23 -0
- package/dist/src/core/contracts/hook-phase.d.ts +12 -0
- package/dist/src/core/contracts/hook-phase.js +1 -0
- package/dist/src/core/contracts/manifest.d.ts +69 -0
- package/dist/src/core/contracts/manifest.js +20 -0
- package/dist/src/core/contracts/processes.d.ts +24 -0
- package/dist/src/core/contracts/processes.js +1 -0
- package/dist/src/core/contracts/restart-host.d.ts +32 -0
- package/dist/src/core/contracts/restart-host.js +3 -0
- package/dist/src/core/contracts/restart-log.d.ts +52 -0
- package/dist/src/core/contracts/restart-log.js +15 -0
- package/dist/src/core/contracts/runtime.d.ts +50 -0
- package/dist/src/core/contracts/runtime.js +1 -0
- package/dist/src/core/contracts/session-ledger.d.ts +144 -0
- package/dist/src/core/contracts/session-ledger.js +38 -0
- package/dist/src/core/contracts/statusline-line.d.ts +20 -0
- package/dist/src/core/contracts/statusline-line.js +13 -0
- package/dist/src/core/contracts/zones.d.ts +18 -0
- package/dist/src/core/contracts/zones.js +4 -0
- package/dist/src/core/services/active-sessions.d.ts +17 -0
- package/dist/src/core/services/active-sessions.js +35 -0
- package/dist/src/core/services/asset-currency.d.ts +17 -0
- package/dist/src/core/services/asset-currency.js +72 -0
- package/dist/src/core/services/auto-restart-merge.d.ts +26 -0
- package/dist/src/core/services/auto-restart-merge.js +30 -0
- package/dist/src/core/services/auto-restart-notices.d.ts +6 -0
- package/dist/src/core/services/auto-restart-notices.js +27 -0
- package/dist/src/core/services/auto-restart-policy.d.ts +26 -0
- package/dist/src/core/services/auto-restart-policy.js +23 -0
- package/dist/src/core/services/brake-engine.d.ts +24 -0
- package/dist/src/core/services/brake-engine.js +61 -0
- package/dist/src/core/services/change-plan-service.d.ts +11 -0
- package/dist/src/core/services/change-plan-service.js +60 -0
- package/dist/src/core/services/config-legacy-checks.d.ts +6 -0
- package/dist/src/core/services/config-legacy-checks.js +28 -0
- package/dist/src/core/services/debug-mode-merge.d.ts +25 -0
- package/dist/src/core/services/debug-mode-merge.js +21 -0
- package/dist/src/core/services/detection-service.d.ts +6 -0
- package/dist/src/core/services/detection-service.js +54 -0
- package/dist/src/core/services/doctor-checks.d.ts +6 -0
- package/dist/src/core/services/doctor-checks.js +24 -0
- package/dist/src/core/services/doctor-report-extras.d.ts +11 -0
- package/dist/src/core/services/doctor-report-extras.js +23 -0
- package/dist/src/core/services/doctor-service.d.ts +24 -0
- package/dist/src/core/services/doctor-service.js +82 -0
- package/dist/src/core/services/failure-policy.d.ts +38 -0
- package/dist/src/core/services/failure-policy.js +63 -0
- package/dist/src/core/services/gitignore-block.d.ts +10 -0
- package/dist/src/core/services/gitignore-block.js +61 -0
- package/dist/src/core/services/gitignore-merge.d.ts +23 -0
- package/dist/src/core/services/gitignore-merge.js +21 -0
- package/dist/src/core/services/gitignore-plan.d.ts +34 -0
- package/dist/src/core/services/gitignore-plan.js +65 -0
- package/dist/src/core/services/harness-exclusion.d.ts +14 -0
- package/dist/src/core/services/harness-exclusion.js +19 -0
- package/dist/src/core/services/harness-removal.d.ts +23 -0
- package/dist/src/core/services/harness-removal.js +34 -0
- package/dist/src/core/services/injection-policy.d.ts +9 -0
- package/dist/src/core/services/injection-policy.js +5 -0
- package/dist/src/core/services/installation-adapters.d.ts +21 -0
- package/dist/src/core/services/installation-adapters.js +28 -0
- package/dist/src/core/services/installation-builder.d.ts +24 -0
- package/dist/src/core/services/installation-builder.js +66 -0
- package/dist/src/core/services/installation-findings.d.ts +5 -0
- package/dist/src/core/services/installation-findings.js +19 -0
- package/dist/src/core/services/installation-service.d.ts +36 -0
- package/dist/src/core/services/installation-service.js +50 -0
- package/dist/src/core/services/manifest-change.d.ts +11 -0
- package/dist/src/core/services/manifest-change.js +16 -0
- package/dist/src/core/services/no-harness-finding.d.ts +3 -0
- package/dist/src/core/services/no-harness-finding.js +9 -0
- package/dist/src/core/services/removal-helper.d.ts +10 -0
- package/dist/src/core/services/removal-helper.js +48 -0
- package/dist/src/core/services/removal-service.d.ts +19 -0
- package/dist/src/core/services/removal-service.js +45 -0
- package/dist/src/core/services/report-service.d.ts +30 -0
- package/dist/src/core/services/report-service.js +71 -0
- package/dist/src/core/services/reset-notice.d.ts +3 -0
- package/dist/src/core/services/reset-notice.js +8 -0
- package/dist/src/core/services/restart-doctor-findings.d.ts +10 -0
- package/dist/src/core/services/restart-doctor-findings.js +24 -0
- package/dist/src/core/services/restart-flow.d.ts +13 -0
- package/dist/src/core/services/restart-flow.js +50 -0
- package/dist/src/core/services/restart-guards.d.ts +6 -0
- package/dist/src/core/services/restart-guards.js +25 -0
- package/dist/src/core/services/restart-install-extras.d.ts +27 -0
- package/dist/src/core/services/restart-install-extras.js +39 -0
- package/dist/src/core/services/restart-mode.d.ts +4 -0
- package/dist/src/core/services/restart-mode.js +6 -0
- package/dist/src/core/services/runtime-error-checks.d.ts +11 -0
- package/dist/src/core/services/runtime-error-checks.js +20 -0
- package/dist/src/core/services/session-counters.d.ts +15 -0
- package/dist/src/core/services/session-counters.js +33 -0
- package/dist/src/core/services/session-reset-handler.d.ts +18 -0
- package/dist/src/core/services/session-reset-handler.js +24 -0
- package/dist/src/core/services/session-zone.d.ts +30 -0
- package/dist/src/core/services/session-zone.js +25 -0
- package/dist/src/core/services/snapshot-merge.d.ts +22 -0
- package/dist/src/core/services/snapshot-merge.js +25 -0
- package/dist/src/core/services/statusline-summary.d.ts +10 -0
- package/dist/src/core/services/statusline-summary.js +13 -0
- package/dist/src/core/services/support-service.d.ts +2 -0
- package/dist/src/core/services/support-service.js +57 -0
- package/dist/src/core/services/telemetry-block.d.ts +14 -0
- package/dist/src/core/services/telemetry-block.js +17 -0
- package/dist/src/core/services/usage-resolver.d.ts +20 -0
- package/dist/src/core/services/usage-resolver.js +23 -0
- package/dist/src/core/services/version-service.d.ts +14 -0
- package/dist/src/core/services/version-service.js +45 -0
- package/dist/src/core/services/window-trust.d.ts +2 -0
- package/dist/src/core/services/window-trust.js +3 -0
- package/dist/src/core/services/zone-classifier.d.ts +11 -0
- package/dist/src/core/services/zone-classifier.js +24 -0
- package/dist/src/core/services/zone-guidance.d.ts +6 -0
- package/dist/src/core/services/zone-guidance.js +32 -0
- package/dist/src/core/validation/configuration-sanitizer.d.ts +10 -0
- package/dist/src/core/validation/configuration-sanitizer.js +31 -0
- package/dist/src/core/validation/configuration-validator.d.ts +18 -0
- package/dist/src/core/validation/configuration-validator.js +45 -0
- package/dist/src/infrastructure/diagnostics/in-process-sampler.d.ts +18 -0
- package/dist/src/infrastructure/diagnostics/in-process-sampler.js +63 -0
- package/dist/src/infrastructure/diagnostics/overhead-measurer.d.ts +12 -0
- package/dist/src/infrastructure/diagnostics/overhead-measurer.js +77 -0
- package/dist/src/infrastructure/diagnostics/p95.d.ts +1 -0
- package/dist/src/infrastructure/diagnostics/p95.js +9 -0
- package/dist/src/infrastructure/diagnostics/process-sampler.d.ts +7 -0
- package/dist/src/infrastructure/diagnostics/process-sampler.js +69 -0
- package/dist/src/infrastructure/diagnostics/sample-failure.d.ts +10 -0
- package/dist/src/infrastructure/diagnostics/sample-failure.js +19 -0
- package/dist/src/infrastructure/git/git-context.d.ts +3 -0
- package/dist/src/infrastructure/git/git-context.js +25 -0
- package/dist/src/infrastructure/harnesses/antigravity-cli/adapter.d.ts +14 -0
- package/dist/src/infrastructure/harnesses/antigravity-cli/adapter.js +84 -0
- package/dist/src/infrastructure/harnesses/antigravity-cli/capabilities.d.ts +2 -0
- package/dist/src/infrastructure/harnesses/antigravity-cli/capabilities.js +6 -0
- package/dist/src/infrastructure/harnesses/antigravity-cli/detector.d.ts +4 -0
- package/dist/src/infrastructure/harnesses/antigravity-cli/detector.js +56 -0
- package/dist/src/infrastructure/harnesses/antigravity-cli/planner.d.ts +7 -0
- package/dist/src/infrastructure/harnesses/antigravity-cli/planner.js +62 -0
- package/dist/src/infrastructure/harnesses/antigravity-cli/runtime.d.ts +9 -0
- package/dist/src/infrastructure/harnesses/antigravity-cli/runtime.js +51 -0
- package/dist/src/infrastructure/harnesses/antigravity-cli/schemas.d.ts +31 -0
- package/dist/src/infrastructure/harnesses/antigravity-cli/schemas.js +19 -0
- package/dist/src/infrastructure/harnesses/claude-code/adapter.d.ts +14 -0
- package/dist/src/infrastructure/harnesses/claude-code/adapter.js +84 -0
- package/dist/src/infrastructure/harnesses/claude-code/auto-restart-diagnostics.d.ts +9 -0
- package/dist/src/infrastructure/harnesses/claude-code/auto-restart-diagnostics.js +60 -0
- package/dist/src/infrastructure/harnesses/claude-code/auto-restart-files.d.ts +12 -0
- package/dist/src/infrastructure/harnesses/claude-code/auto-restart-files.js +24 -0
- package/dist/src/infrastructure/harnesses/claude-code/auto-restart-ownership.d.ts +5 -0
- package/dist/src/infrastructure/harnesses/claude-code/auto-restart-ownership.js +41 -0
- package/dist/src/infrastructure/harnesses/claude-code/auto-restart-planner.d.ts +7 -0
- package/dist/src/infrastructure/harnesses/claude-code/auto-restart-planner.js +81 -0
- package/dist/src/infrastructure/harnesses/claude-code/auto-restart-settings.d.ts +4 -0
- package/dist/src/infrastructure/harnesses/claude-code/auto-restart-settings.js +29 -0
- package/dist/src/infrastructure/harnesses/claude-code/capabilities.d.ts +2 -0
- package/dist/src/infrastructure/harnesses/claude-code/capabilities.js +6 -0
- package/dist/src/infrastructure/harnesses/claude-code/claude-hooks-config.d.ts +1 -0
- package/dist/src/infrastructure/harnesses/claude-code/claude-hooks-config.js +25 -0
- package/dist/src/infrastructure/harnesses/claude-code/claude-merger.d.ts +14 -0
- package/dist/src/infrastructure/harnesses/claude-code/claude-merger.js +44 -0
- package/dist/src/infrastructure/harnesses/claude-code/detector.d.ts +6 -0
- package/dist/src/infrastructure/harnesses/claude-code/detector.js +14 -0
- package/dist/src/infrastructure/harnesses/claude-code/mod/hooks.d.ts +6 -0
- package/dist/src/infrastructure/harnesses/claude-code/mod/hooks.js +43 -0
- package/dist/src/infrastructure/harnesses/claude-code/mod/host.d.ts +56 -0
- package/dist/src/infrastructure/harnesses/claude-code/mod/host.js +1 -0
- package/dist/src/infrastructure/harnesses/claude-code/mod/mod-config.d.ts +8 -0
- package/dist/src/infrastructure/harnesses/claude-code/mod/mod-config.js +31 -0
- package/dist/src/infrastructure/harnesses/claude-code/mod/mod-guards.d.ts +3 -0
- package/dist/src/infrastructure/harnesses/claude-code/mod/mod-guards.js +13 -0
- package/dist/src/infrastructure/harnesses/claude-code/mod/mod-info.d.ts +4 -0
- package/dist/src/infrastructure/harnesses/claude-code/mod/mod-info.js +5 -0
- package/dist/src/infrastructure/harnesses/claude-code/mod/mod-log.d.ts +4 -0
- package/dist/src/infrastructure/harnesses/claude-code/mod/mod-log.js +34 -0
- package/dist/src/infrastructure/harnesses/claude-code/mod/register.d.ts +2 -0
- package/dist/src/infrastructure/harnesses/claude-code/mod/register.js +23 -0
- package/dist/src/infrastructure/harnesses/claude-code/mod/restart-facts.d.ts +3 -0
- package/dist/src/infrastructure/harnesses/claude-code/mod/restart-facts.js +12 -0
- package/dist/src/infrastructure/harnesses/claude-code/mod/restart-flow.d.ts +4 -0
- package/dist/src/infrastructure/harnesses/claude-code/mod/restart-flow.js +22 -0
- package/dist/src/infrastructure/harnesses/claude-code/mod/restart-host.d.ts +7 -0
- package/dist/src/infrastructure/harnesses/claude-code/mod/restart-host.js +35 -0
- package/dist/src/infrastructure/harnesses/claude-code/mod/turn-state.d.ts +7 -0
- package/dist/src/infrastructure/harnesses/claude-code/mod/turn-state.js +12 -0
- package/dist/src/infrastructure/harnesses/claude-code/planner.d.ts +7 -0
- package/dist/src/infrastructure/harnesses/claude-code/planner.js +72 -0
- package/dist/src/infrastructure/harnesses/claude-code/runtime.d.ts +10 -0
- package/dist/src/infrastructure/harnesses/claude-code/runtime.js +82 -0
- package/dist/src/infrastructure/harnesses/claude-code/schemas.d.ts +42 -0
- package/dist/src/infrastructure/harnesses/claude-code/schemas.js +30 -0
- package/dist/src/infrastructure/harnesses/claude-code/statusline-bridge.d.ts +12 -0
- package/dist/src/infrastructure/harnesses/claude-code/statusline-bridge.js +78 -0
- package/dist/src/infrastructure/harnesses/claude-code/statusline-context-window.d.ts +5 -0
- package/dist/src/infrastructure/harnesses/claude-code/statusline-context-window.js +50 -0
- package/dist/src/infrastructure/harnesses/claude-code/statusline-default.d.ts +6 -0
- package/dist/src/infrastructure/harnesses/claude-code/statusline-default.js +38 -0
- package/dist/src/infrastructure/harnesses/claude-code/statusline-diagnostics.d.ts +3 -0
- package/dist/src/infrastructure/harnesses/claude-code/statusline-diagnostics.js +70 -0
- package/dist/src/infrastructure/harnesses/claude-code/statusline-output.d.ts +9 -0
- package/dist/src/infrastructure/harnesses/claude-code/statusline-output.js +15 -0
- package/dist/src/infrastructure/harnesses/claude-code/statusline-payload.d.ts +7 -0
- package/dist/src/infrastructure/harnesses/claude-code/statusline-payload.js +36 -0
- package/dist/src/infrastructure/harnesses/claude-code/statusline-planner.d.ts +4 -0
- package/dist/src/infrastructure/harnesses/claude-code/statusline-planner.js +82 -0
- package/dist/src/infrastructure/harnesses/claude-code/statusline-previous.d.ts +17 -0
- package/dist/src/infrastructure/harnesses/claude-code/statusline-previous.js +41 -0
- package/dist/src/infrastructure/harnesses/claude-code/statusline-restore.d.ts +9 -0
- package/dist/src/infrastructure/harnesses/claude-code/statusline-restore.js +31 -0
- package/dist/src/infrastructure/harnesses/claude-code/statusline-settings.d.ts +33 -0
- package/dist/src/infrastructure/harnesses/claude-code/statusline-settings.js +63 -0
- package/dist/src/infrastructure/harnesses/claude-code/statusline-shell.d.ts +13 -0
- package/dist/src/infrastructure/harnesses/claude-code/statusline-shell.js +28 -0
- package/dist/src/infrastructure/harnesses/claude-code/statusline-state.d.ts +21 -0
- package/dist/src/infrastructure/harnesses/claude-code/statusline-state.js +29 -0
- package/dist/src/infrastructure/harnesses/claude-code/transcript-usage.d.ts +6 -0
- package/dist/src/infrastructure/harnesses/claude-code/transcript-usage.js +24 -0
- package/dist/src/infrastructure/harnesses/codex-cli/adapter.d.ts +14 -0
- package/dist/src/infrastructure/harnesses/codex-cli/adapter.js +90 -0
- package/dist/src/infrastructure/harnesses/codex-cli/capabilities.d.ts +2 -0
- package/dist/src/infrastructure/harnesses/codex-cli/capabilities.js +6 -0
- package/dist/src/infrastructure/harnesses/codex-cli/detector.d.ts +6 -0
- package/dist/src/infrastructure/harnesses/codex-cli/detector.js +13 -0
- package/dist/src/infrastructure/harnesses/codex-cli/planner.d.ts +7 -0
- package/dist/src/infrastructure/harnesses/codex-cli/planner.js +75 -0
- package/dist/src/infrastructure/harnesses/codex-cli/rollout-usage.d.ts +6 -0
- package/dist/src/infrastructure/harnesses/codex-cli/rollout-usage.js +27 -0
- package/dist/src/infrastructure/harnesses/codex-cli/runtime.d.ts +10 -0
- package/dist/src/infrastructure/harnesses/codex-cli/runtime.js +85 -0
- package/dist/src/infrastructure/harnesses/codex-cli/schemas.d.ts +47 -0
- package/dist/src/infrastructure/harnesses/codex-cli/schemas.js +25 -0
- package/dist/src/infrastructure/harnesses/common/antigravity-hooks-updater.d.ts +4 -0
- package/dist/src/infrastructure/harnesses/common/antigravity-hooks-updater.js +57 -0
- package/dist/src/infrastructure/harnesses/common/change-target.d.ts +1 -0
- package/dist/src/infrastructure/harnesses/common/change-target.js +40 -0
- package/dist/src/infrastructure/harnesses/common/codex-hooks-updater.d.ts +13 -0
- package/dist/src/infrastructure/harnesses/common/codex-hooks-updater.js +79 -0
- package/dist/src/infrastructure/harnesses/common/cursor-hooks-updater.d.ts +3 -0
- package/dist/src/infrastructure/harnesses/common/cursor-hooks-updater.js +63 -0
- package/dist/src/infrastructure/harnesses/common/diagnostic-helpers.d.ts +7 -0
- package/dist/src/infrastructure/harnesses/common/diagnostic-helpers.js +60 -0
- package/dist/src/infrastructure/harnesses/common/hook-event-cleanup.d.ts +3 -0
- package/dist/src/infrastructure/harnesses/common/hook-event-cleanup.js +50 -0
- package/dist/src/infrastructure/harnesses/common/in-process-restart-log.d.ts +9 -0
- package/dist/src/infrastructure/harnesses/common/in-process-restart-log.js +36 -0
- package/dist/src/infrastructure/harnesses/common/in-process-restart-state.d.ts +11 -0
- package/dist/src/infrastructure/harnesses/common/in-process-restart-state.js +50 -0
- package/dist/src/infrastructure/harnesses/common/in-process-restart-support.d.ts +13 -0
- package/dist/src/infrastructure/harnesses/common/in-process-restart-support.js +15 -0
- package/dist/src/infrastructure/harnesses/common/in-process-support.d.ts +18 -0
- package/dist/src/infrastructure/harnesses/common/in-process-support.js +40 -0
- package/dist/src/infrastructure/harnesses/common/jsonl-tail-reader.d.ts +6 -0
- package/dist/src/infrastructure/harnesses/common/jsonl-tail-reader.js +76 -0
- package/dist/src/infrastructure/harnesses/common/path-helpers.d.ts +6 -0
- package/dist/src/infrastructure/harnesses/common/path-helpers.js +51 -0
- package/dist/src/infrastructure/harnesses/common/removal-config-validator.d.ts +2 -0
- package/dist/src/infrastructure/harnesses/common/removal-config-validator.js +14 -0
- package/dist/src/infrastructure/harnesses/common/restart-asset-plan.d.ts +12 -0
- package/dist/src/infrastructure/harnesses/common/restart-asset-plan.js +37 -0
- package/dist/src/infrastructure/harnesses/common/restart-diagnostics.d.ts +12 -0
- package/dist/src/infrastructure/harnesses/common/restart-diagnostics.js +49 -0
- package/dist/src/infrastructure/harnesses/common/runtime-assets.d.ts +1 -0
- package/dist/src/infrastructure/harnesses/common/runtime-assets.js +23 -0
- package/dist/src/infrastructure/harnesses/common/runtime-support.d.ts +8 -0
- package/dist/src/infrastructure/harnesses/common/runtime-support.js +44 -0
- package/dist/src/infrastructure/harnesses/common/version-probes.d.ts +3 -0
- package/dist/src/infrastructure/harnesses/common/version-probes.js +21 -0
- package/dist/src/infrastructure/harnesses/cursor/adapter.d.ts +14 -0
- package/dist/src/infrastructure/harnesses/cursor/adapter.js +70 -0
- package/dist/src/infrastructure/harnesses/cursor/capabilities.d.ts +2 -0
- package/dist/src/infrastructure/harnesses/cursor/capabilities.js +6 -0
- package/dist/src/infrastructure/harnesses/cursor/detector.d.ts +6 -0
- package/dist/src/infrastructure/harnesses/cursor/detector.js +13 -0
- package/dist/src/infrastructure/harnesses/cursor/planner.d.ts +7 -0
- package/dist/src/infrastructure/harnesses/cursor/planner.js +66 -0
- package/dist/src/infrastructure/harnesses/cursor/runtime.d.ts +9 -0
- package/dist/src/infrastructure/harnesses/cursor/runtime.js +49 -0
- package/dist/src/infrastructure/harnesses/cursor/schemas.d.ts +39 -0
- package/dist/src/infrastructure/harnesses/cursor/schemas.js +23 -0
- package/dist/src/infrastructure/harnesses/github-copilot-cli/adapter.d.ts +14 -0
- package/dist/src/infrastructure/harnesses/github-copilot-cli/adapter.js +69 -0
- package/dist/src/infrastructure/harnesses/github-copilot-cli/capabilities.d.ts +2 -0
- package/dist/src/infrastructure/harnesses/github-copilot-cli/capabilities.js +6 -0
- package/dist/src/infrastructure/harnesses/github-copilot-cli/detector.d.ts +6 -0
- package/dist/src/infrastructure/harnesses/github-copilot-cli/detector.js +15 -0
- package/dist/src/infrastructure/harnesses/github-copilot-cli/planner.d.ts +7 -0
- package/dist/src/infrastructure/harnesses/github-copilot-cli/planner.js +66 -0
- package/dist/src/infrastructure/harnesses/github-copilot-cli/runtime.d.ts +9 -0
- package/dist/src/infrastructure/harnesses/github-copilot-cli/runtime.js +67 -0
- package/dist/src/infrastructure/harnesses/github-copilot-cli/schemas.d.ts +35 -0
- package/dist/src/infrastructure/harnesses/github-copilot-cli/schemas.js +21 -0
- package/dist/src/infrastructure/harnesses/oh-my-pi/adapter.d.ts +14 -0
- package/dist/src/infrastructure/harnesses/oh-my-pi/adapter.js +64 -0
- package/dist/src/infrastructure/harnesses/oh-my-pi/capabilities.d.ts +2 -0
- package/dist/src/infrastructure/harnesses/oh-my-pi/capabilities.js +6 -0
- package/dist/src/infrastructure/harnesses/oh-my-pi/detector.d.ts +6 -0
- package/dist/src/infrastructure/harnesses/oh-my-pi/detector.js +13 -0
- package/dist/src/infrastructure/harnesses/oh-my-pi/events.d.ts +8 -0
- package/dist/src/infrastructure/harnesses/oh-my-pi/events.js +65 -0
- package/dist/src/infrastructure/harnesses/oh-my-pi/planner.d.ts +7 -0
- package/dist/src/infrastructure/harnesses/oh-my-pi/planner.js +32 -0
- package/dist/src/infrastructure/harnesses/oh-my-pi/restart.d.ts +28 -0
- package/dist/src/infrastructure/harnesses/oh-my-pi/restart.js +79 -0
- package/dist/src/infrastructure/harnesses/oh-my-pi/runtime.d.ts +17 -0
- package/dist/src/infrastructure/harnesses/oh-my-pi/runtime.js +69 -0
- package/dist/src/infrastructure/harnesses/oh-my-pi/schemas.d.ts +50 -0
- package/dist/src/infrastructure/harnesses/oh-my-pi/schemas.js +17 -0
- package/dist/src/infrastructure/harnesses/opencode/adapter.d.ts +14 -0
- package/dist/src/infrastructure/harnesses/opencode/adapter.js +64 -0
- package/dist/src/infrastructure/harnesses/opencode/capabilities.d.ts +2 -0
- package/dist/src/infrastructure/harnesses/opencode/capabilities.js +6 -0
- package/dist/src/infrastructure/harnesses/opencode/detector.d.ts +6 -0
- package/dist/src/infrastructure/harnesses/opencode/detector.js +16 -0
- package/dist/src/infrastructure/harnesses/opencode/events.d.ts +8 -0
- package/dist/src/infrastructure/harnesses/opencode/events.js +36 -0
- package/dist/src/infrastructure/harnesses/opencode/planner.d.ts +6 -0
- package/dist/src/infrastructure/harnesses/opencode/planner.js +23 -0
- package/dist/src/infrastructure/harnesses/opencode/runtime.d.ts +20 -0
- package/dist/src/infrastructure/harnesses/opencode/runtime.js +51 -0
- package/dist/src/infrastructure/harnesses/opencode/schemas.d.ts +51 -0
- package/dist/src/infrastructure/harnesses/opencode/schemas.js +32 -0
- package/dist/src/infrastructure/harnesses/pi/adapter.d.ts +14 -0
- package/dist/src/infrastructure/harnesses/pi/adapter.js +64 -0
- package/dist/src/infrastructure/harnesses/pi/capabilities.d.ts +2 -0
- package/dist/src/infrastructure/harnesses/pi/capabilities.js +6 -0
- package/dist/src/infrastructure/harnesses/pi/detector.d.ts +6 -0
- package/dist/src/infrastructure/harnesses/pi/detector.js +10 -0
- package/dist/src/infrastructure/harnesses/pi/events.d.ts +8 -0
- package/dist/src/infrastructure/harnesses/pi/events.js +65 -0
- package/dist/src/infrastructure/harnesses/pi/planner.d.ts +7 -0
- package/dist/src/infrastructure/harnesses/pi/planner.js +32 -0
- package/dist/src/infrastructure/harnesses/pi/restart.d.ts +33 -0
- package/dist/src/infrastructure/harnesses/pi/restart.js +69 -0
- package/dist/src/infrastructure/harnesses/pi/runtime.d.ts +17 -0
- package/dist/src/infrastructure/harnesses/pi/runtime.js +67 -0
- package/dist/src/infrastructure/harnesses/pi/schemas.d.ts +50 -0
- package/dist/src/infrastructure/harnesses/pi/schemas.js +17 -0
- package/dist/src/infrastructure/harnesses/registry.d.ts +6 -0
- package/dist/src/infrastructure/harnesses/registry.js +94 -0
- package/dist/src/infrastructure/process/node-process-runner.d.ts +8 -0
- package/dist/src/infrastructure/process/node-process-runner.js +66 -0
- package/dist/src/infrastructure/process/process-tree.d.ts +2 -0
- package/dist/src/infrastructure/process/process-tree.js +28 -0
- package/dist/src/infrastructure/runtime/hook-deadline.d.ts +26 -0
- package/dist/src/infrastructure/runtime/hook-deadline.js +55 -0
- package/dist/src/infrastructure/runtime/hook-failure.d.ts +14 -0
- package/dist/src/infrastructure/runtime/hook-failure.js +22 -0
- package/dist/src/infrastructure/runtime/in-process-host.d.ts +16 -0
- package/dist/src/infrastructure/runtime/in-process-host.js +75 -0
- package/dist/src/infrastructure/runtime/node-runtime-logs.d.ts +8 -0
- package/dist/src/infrastructure/runtime/node-runtime-logs.js +21 -0
- package/dist/src/infrastructure/runtime/node-session-ledger.d.ts +17 -0
- package/dist/src/infrastructure/runtime/node-session-ledger.js +68 -0
- package/dist/src/infrastructure/runtime/process-hook-host.d.ts +25 -0
- package/dist/src/infrastructure/runtime/process-hook-host.js +79 -0
- package/dist/src/infrastructure/runtime/runtime-composition.d.ts +29 -0
- package/dist/src/infrastructure/runtime/runtime-composition.js +41 -0
- package/dist/src/infrastructure/runtime/runtime-paths.d.ts +12 -0
- package/dist/src/infrastructure/runtime/runtime-paths.js +45 -0
- package/dist/src/infrastructure/runtime/runtime-state-reader.d.ts +9 -0
- package/dist/src/infrastructure/runtime/runtime-state-reader.js +82 -0
- package/dist/src/infrastructure/storage/atomic-writer.d.ts +2 -0
- package/dist/src/infrastructure/storage/atomic-writer.js +35 -0
- package/dist/src/infrastructure/storage/change-applier.d.ts +10 -0
- package/dist/src/infrastructure/storage/change-applier.js +80 -0
- package/dist/src/infrastructure/storage/directory-pruner.d.ts +8 -0
- package/dist/src/infrastructure/storage/directory-pruner.js +76 -0
- package/dist/src/infrastructure/storage/handoff-claim-lock.d.ts +3 -0
- package/dist/src/infrastructure/storage/handoff-claim-lock.js +32 -0
- package/dist/src/infrastructure/storage/json-document-editor.d.ts +5 -0
- package/dist/src/infrastructure/storage/json-document-editor.js +52 -0
- package/dist/src/infrastructure/storage/json-span-utils.d.ts +24 -0
- package/dist/src/infrastructure/storage/json-span-utils.js +104 -0
- package/dist/src/infrastructure/storage/json-validator.d.ts +13 -0
- package/dist/src/infrastructure/storage/json-validator.js +61 -0
- package/dist/src/infrastructure/storage/manifest-store.d.ts +11 -0
- package/dist/src/infrastructure/storage/manifest-store.js +45 -0
- package/dist/src/infrastructure/storage/node-file-system.d.ts +4 -0
- package/dist/src/infrastructure/storage/node-file-system.js +33 -0
- package/dist/src/infrastructure/storage/node-handoff-store.d.ts +11 -0
- package/dist/src/infrastructure/storage/node-handoff-store.js +96 -0
- package/dist/src/infrastructure/storage/package-metadata.d.ts +7 -0
- package/dist/src/infrastructure/storage/package-metadata.js +58 -0
- package/dist/src/infrastructure/storage/path-boundary.d.ts +11 -0
- package/dist/src/infrastructure/storage/path-boundary.js +73 -0
- package/dist/src/infrastructure/storage/project-config-store.d.ts +9 -0
- package/dist/src/infrastructure/storage/project-config-store.js +24 -0
- package/dist/src/infrastructure/storage/runtime-state-files.d.ts +12 -0
- package/dist/src/infrastructure/storage/runtime-state-files.js +22 -0
- package/docs/telemetry-block.md +149 -0
- package/package.json +65 -4
- package/schemas/context-brake.config.schema.json +177 -0
- package/schemas/doctor-report.schema.json +595 -0
- package/schemas/install-report.schema.json +458 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import process from 'node:process';
|
|
3
|
+
function killWindowsTree(child) {
|
|
4
|
+
return new Promise((resolve) => {
|
|
5
|
+
if (!child.pid) {
|
|
6
|
+
resolve();
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
execFile('taskkill', ['/pid', String(child.pid), '/t', '/f'], { windowsHide: true }, () => resolve());
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
function killPosixTree(child) {
|
|
13
|
+
if (!child.pid) {
|
|
14
|
+
child.kill('SIGKILL');
|
|
15
|
+
return Promise.resolve();
|
|
16
|
+
}
|
|
17
|
+
try {
|
|
18
|
+
process.kill(-child.pid, 'SIGKILL');
|
|
19
|
+
}
|
|
20
|
+
catch (cause) {
|
|
21
|
+
if (!child.kill('SIGKILL'))
|
|
22
|
+
return Promise.reject(new Error('Unable to stop timed-out process tree.', { cause }));
|
|
23
|
+
}
|
|
24
|
+
return Promise.resolve();
|
|
25
|
+
}
|
|
26
|
+
export function killProcessTree(child) {
|
|
27
|
+
return process.platform === 'win32' ? killWindowsTree(child) : killPosixTree(child);
|
|
28
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { HookPhase, PhaseTiming } from '../../core/contracts/hook-phase.js';
|
|
2
|
+
import type { RuntimeEvent } from '../../core/contracts/runtime.js';
|
|
3
|
+
export declare const SESSION_START_DEADLINE_MILLISECONDS = 5000;
|
|
4
|
+
export type DeadlineLimits = {
|
|
5
|
+
readonly event: number;
|
|
6
|
+
readonly sessionStart: number;
|
|
7
|
+
};
|
|
8
|
+
export declare const DEFAULT_DEADLINE_LIMITS: DeadlineLimits;
|
|
9
|
+
export declare class HookDeadline {
|
|
10
|
+
private readonly now;
|
|
11
|
+
private phase;
|
|
12
|
+
private expiredAtLeastOnce;
|
|
13
|
+
private timer;
|
|
14
|
+
private rejectExpired;
|
|
15
|
+
private readonly startedAt;
|
|
16
|
+
private readonly expired;
|
|
17
|
+
constructor(milliseconds: number, initialPhase: HookPhase, now?: () => number);
|
|
18
|
+
readonly mark: (phase: HookPhase) => void;
|
|
19
|
+
readonly isExpired: () => boolean;
|
|
20
|
+
readonly commit: () => boolean;
|
|
21
|
+
extendTo(milliseconds: number): void;
|
|
22
|
+
run<T>(work: Promise<T>): Promise<T>;
|
|
23
|
+
private schedule;
|
|
24
|
+
}
|
|
25
|
+
export declare function deadlineFor(event: RuntimeEvent | null, limits: DeadlineLimits): number;
|
|
26
|
+
export declare function deadlineTiming(error: unknown): PhaseTiming | undefined;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { performance } from 'node:perf_hooks';
|
|
2
|
+
import { DeadlineExceededError, INTERNAL_DEADLINE_MILLISECONDS } from '../../core/services/failure-policy.js';
|
|
3
|
+
export const SESSION_START_DEADLINE_MILLISECONDS = 5000;
|
|
4
|
+
export const DEFAULT_DEADLINE_LIMITS = { event: INTERNAL_DEADLINE_MILLISECONDS, sessionStart: SESSION_START_DEADLINE_MILLISECONDS };
|
|
5
|
+
export class HookDeadline {
|
|
6
|
+
now;
|
|
7
|
+
phase;
|
|
8
|
+
expiredAtLeastOnce = false;
|
|
9
|
+
timer;
|
|
10
|
+
rejectExpired = () => undefined;
|
|
11
|
+
startedAt;
|
|
12
|
+
expired;
|
|
13
|
+
constructor(milliseconds, initialPhase, now = () => performance.now()) {
|
|
14
|
+
this.now = now;
|
|
15
|
+
this.phase = initialPhase;
|
|
16
|
+
this.startedAt = now();
|
|
17
|
+
this.expired = new Promise((_, reject) => { this.rejectExpired = reject; });
|
|
18
|
+
this.expired.catch(() => undefined);
|
|
19
|
+
this.schedule(milliseconds);
|
|
20
|
+
}
|
|
21
|
+
mark = (phase) => { this.phase = phase; };
|
|
22
|
+
isExpired = () => this.expiredAtLeastOnce;
|
|
23
|
+
commit = () => {
|
|
24
|
+
if (this.expiredAtLeastOnce)
|
|
25
|
+
return false;
|
|
26
|
+
clearTimeout(this.timer);
|
|
27
|
+
this.timer = undefined;
|
|
28
|
+
return true;
|
|
29
|
+
};
|
|
30
|
+
extendTo(milliseconds) {
|
|
31
|
+
if (this.timer === undefined)
|
|
32
|
+
return;
|
|
33
|
+
clearTimeout(this.timer);
|
|
34
|
+
this.schedule(milliseconds);
|
|
35
|
+
}
|
|
36
|
+
async run(work) {
|
|
37
|
+
try {
|
|
38
|
+
return await Promise.race([work, this.expired]);
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
clearTimeout(this.timer);
|
|
42
|
+
this.timer = undefined;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
schedule(milliseconds) {
|
|
46
|
+
const remaining = Math.max(0, milliseconds - (this.now() - this.startedAt));
|
|
47
|
+
this.timer = setTimeout(() => { this.expiredAtLeastOnce = true; this.rejectExpired(new DeadlineExceededError(this.phase, Math.round(this.now() - this.startedAt))); }, remaining);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export function deadlineFor(event, limits) {
|
|
51
|
+
return event?.kind === 'session_reset' ? limits.sessionStart : limits.event;
|
|
52
|
+
}
|
|
53
|
+
export function deadlineTiming(error) {
|
|
54
|
+
return error instanceof DeadlineExceededError ? { phase: error.phase, elapsedMs: error.elapsedMs } : undefined;
|
|
55
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ContextBrakeConfig } from '../../core/contracts/configuration.js';
|
|
2
|
+
import type { RuntimeDecision, RuntimeDescriptor, RuntimeEvent } from '../../core/contracts/runtime.js';
|
|
3
|
+
export type HookState = {
|
|
4
|
+
event: RuntimeEvent | null;
|
|
5
|
+
projectRoot: string | null;
|
|
6
|
+
config: ContextBrakeConfig | null;
|
|
7
|
+
};
|
|
8
|
+
export type HookFailure = {
|
|
9
|
+
readonly descriptor: RuntimeDescriptor;
|
|
10
|
+
readonly state: HookState;
|
|
11
|
+
readonly error: unknown;
|
|
12
|
+
readonly eventName: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function failureDecision(input: HookFailure): Promise<RuntimeDecision>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { failureDetail, failureErrorCode, recordRuntimeFailure, resolveFailure } from '../../core/services/failure-policy.js';
|
|
2
|
+
import { deadlineTiming } from './hook-deadline.js';
|
|
3
|
+
import { createRuntimePorts, systemClock } from './runtime-composition.js';
|
|
4
|
+
const NEUTRAL = { kind: 'neutral' };
|
|
5
|
+
export async function failureDecision(input) {
|
|
6
|
+
if (input.state.projectRoot === null)
|
|
7
|
+
return NEUTRAL;
|
|
8
|
+
const ports = createRuntimePorts({ projectRoot: input.state.projectRoot, config: input.state.config, clock: systemClock });
|
|
9
|
+
const code = failureErrorCode(input.error);
|
|
10
|
+
const detail = failureDetail(input.error);
|
|
11
|
+
const timing = deadlineTiming(input.error);
|
|
12
|
+
if (input.state.event === null) {
|
|
13
|
+
await recordRuntimeFailure(ports.errors, { harness: input.descriptor.harness, event: input.eventName, code, detail, ...timing });
|
|
14
|
+
return NEUTRAL;
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
return await resolveFailure({ event: input.state.event, code, detail, timing, config: input.state.config, descriptor: input.descriptor, ledger: ports.ledger, errors: ports.errors });
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return NEUTRAL;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ContextBrakeConfig } from '../../core/contracts/configuration.js';
|
|
2
|
+
import type { RuntimeDecision, RuntimeDescriptor, RuntimeEvent } from '../../core/contracts/runtime.js';
|
|
3
|
+
import type { Clock } from '../../core/contracts/session-ledger.js';
|
|
4
|
+
import type { RuntimeInput } from '../../core/services/brake-engine.js';
|
|
5
|
+
import { type DeadlineLimits } from './hook-deadline.js';
|
|
6
|
+
export type InProcessRuntimeInput = {
|
|
7
|
+
readonly projectRoot: string;
|
|
8
|
+
readonly descriptor: RuntimeDescriptor;
|
|
9
|
+
readonly config: ContextBrakeConfig;
|
|
10
|
+
readonly clock?: Clock | undefined;
|
|
11
|
+
readonly deadlines?: DeadlineLimits | undefined;
|
|
12
|
+
};
|
|
13
|
+
export type InProcessRuntime = {
|
|
14
|
+
readonly handle: (event: RuntimeEvent, input?: RuntimeInput) => Promise<RuntimeDecision>;
|
|
15
|
+
};
|
|
16
|
+
export declare function createInProcessRuntime(input: InProcessRuntimeInput): InProcessRuntime;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { failureDetail, failureErrorCode, resolveFailure } from '../../core/services/failure-policy.js';
|
|
2
|
+
import { deadlineFor, deadlineTiming, DEFAULT_DEADLINE_LIMITS, HookDeadline } from './hook-deadline.js';
|
|
3
|
+
import { NodeSessionLedger } from './node-session-ledger.js';
|
|
4
|
+
import { composeRuntime, systemClock } from './runtime-composition.js';
|
|
5
|
+
import { sessionLedgerHash } from './runtime-paths.js';
|
|
6
|
+
export function createInProcessRuntime(input) {
|
|
7
|
+
const clock = input.clock ?? systemClock;
|
|
8
|
+
const ledger = new CachedSessionLedger(new NodeSessionLedger(input.projectRoot, clock), clock);
|
|
9
|
+
const services = composeRuntime({ projectRoot: input.projectRoot, descriptor: input.descriptor, config: input.config, clock, ledger });
|
|
10
|
+
return {
|
|
11
|
+
async handle(event, engineInput) {
|
|
12
|
+
try {
|
|
13
|
+
if (event.kind === 'session_reset')
|
|
14
|
+
ledger.invalidate(event.session);
|
|
15
|
+
const deadline = new HookDeadline(deadlineFor(event, input.deadlines ?? DEFAULT_DEADLINE_LIMITS), 'engine');
|
|
16
|
+
return await deadline.run(services.engine.handle(event, { ...engineInput, onPhase: deadline.mark, deadline }));
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
return handleFailure({ event, error, config: input.config, descriptor: input.descriptor, services, ledger });
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
async function handleFailure(input) {
|
|
25
|
+
try {
|
|
26
|
+
return await resolveFailure({ event: input.event, code: failureErrorCode(input.error), detail: failureDetail(input.error), timing: deadlineTiming(input.error), config: input.config, descriptor: input.descriptor, ledger: input.ledger, errors: input.services.errors });
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return { kind: 'neutral' };
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
class CachedSessionLedger {
|
|
33
|
+
inner;
|
|
34
|
+
clock;
|
|
35
|
+
cache = new Map();
|
|
36
|
+
constructor(inner, clock) {
|
|
37
|
+
this.inner = inner;
|
|
38
|
+
this.clock = clock;
|
|
39
|
+
}
|
|
40
|
+
async readLines(key) {
|
|
41
|
+
const cached = this.cache.get(entryKey(key));
|
|
42
|
+
if (cached !== undefined)
|
|
43
|
+
return cached;
|
|
44
|
+
const lines = [...await this.inner.readLines(key)];
|
|
45
|
+
this.cache.set(entryKey(key), lines);
|
|
46
|
+
return lines;
|
|
47
|
+
}
|
|
48
|
+
async appendSessionLine(key) {
|
|
49
|
+
await this.inner.appendSessionLine(key);
|
|
50
|
+
this.cache.get(entryKey(key))?.push({ v: 1, type: 'session', at: this.clock.now().toISOString(), harness: key.harness, sessionId: key.sessionId, agentId: key.agentId });
|
|
51
|
+
}
|
|
52
|
+
async appendToolLine(key, input) {
|
|
53
|
+
await this.inner.appendToolLine(key, input);
|
|
54
|
+
this.cache.get(entryKey(key))?.push({ v: 1, type: 'tool', at: this.clock.now().toISOString(), ...input });
|
|
55
|
+
}
|
|
56
|
+
async appendResetLine(key, reason) {
|
|
57
|
+
await this.inner.appendResetLine(key, reason);
|
|
58
|
+
this.cache.get(entryKey(key))?.push({ v: 1, type: 'reset', at: this.clock.now().toISOString(), reason });
|
|
59
|
+
}
|
|
60
|
+
async appendStatuslineLine(key, input) {
|
|
61
|
+
await this.inner.appendStatuslineLine(key, input);
|
|
62
|
+
this.cache.get(entryKey(key))?.push({ v: 1, type: 'statusline', at: this.clock.now().toISOString(), ...input });
|
|
63
|
+
}
|
|
64
|
+
async pruneStaleSessions() {
|
|
65
|
+
const pruned = await this.inner.pruneStaleSessions();
|
|
66
|
+
this.cache.clear();
|
|
67
|
+
return pruned;
|
|
68
|
+
}
|
|
69
|
+
invalidate(key) {
|
|
70
|
+
this.cache.delete(entryKey(key));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function entryKey(key) {
|
|
74
|
+
return `${key.harness}\0${sessionLedgerHash(key)}`;
|
|
75
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { HarnessId } from '../../core/contracts/harness.js';
|
|
2
|
+
import type { Clock, ErrorRecordInput, RuntimeErrorLog } from '../../core/contracts/session-ledger.js';
|
|
3
|
+
export declare class NodeRuntimeErrorLog implements RuntimeErrorLog {
|
|
4
|
+
readonly projectRoot: string;
|
|
5
|
+
readonly clock: Clock;
|
|
6
|
+
constructor(projectRoot: string, clock: Clock);
|
|
7
|
+
append(harness: HarnessId, input: ErrorRecordInput): Promise<void>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { appendFile } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { errorLineSchema } from '../../core/contracts/session-ledger.js';
|
|
4
|
+
import { ensureRuntimeDirectory, runtimeDirectory } from './runtime-paths.js';
|
|
5
|
+
const ERRORS_FILE_NAME = 'errors.jsonl';
|
|
6
|
+
export class NodeRuntimeErrorLog {
|
|
7
|
+
projectRoot;
|
|
8
|
+
clock;
|
|
9
|
+
constructor(projectRoot, clock) {
|
|
10
|
+
this.projectRoot = projectRoot;
|
|
11
|
+
this.clock = clock;
|
|
12
|
+
}
|
|
13
|
+
async append(harness, input) {
|
|
14
|
+
const line = errorLineSchema.parse({ v: 1, at: this.clock.now().toISOString(), harness, ...input });
|
|
15
|
+
await appendRuntimeLine(this.projectRoot, ERRORS_FILE_NAME, line);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
async function appendRuntimeLine(projectRoot, fileName, line) {
|
|
19
|
+
await ensureRuntimeDirectory(projectRoot);
|
|
20
|
+
await appendFile(join(runtimeDirectory(projectRoot), fileName), `${JSON.stringify(line)}\n`, 'utf8');
|
|
21
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { SessionKey } from '../../core/contracts/runtime.js';
|
|
2
|
+
import type { Clock, LedgerLine, ResetReason, SessionLedger, ToolLineInput } from '../../core/contracts/session-ledger.js';
|
|
3
|
+
import { type StatuslineLineInput } from '../../core/contracts/statusline-line.js';
|
|
4
|
+
export declare class NodeSessionLedger implements SessionLedger {
|
|
5
|
+
readonly projectRoot: string;
|
|
6
|
+
readonly clock: Clock;
|
|
7
|
+
constructor(projectRoot: string, clock: Clock);
|
|
8
|
+
readLines(key: SessionKey): Promise<readonly LedgerLine[]>;
|
|
9
|
+
appendSessionLine(key: SessionKey): Promise<void>;
|
|
10
|
+
appendToolLine(key: SessionKey, input: ToolLineInput): Promise<void>;
|
|
11
|
+
appendResetLine(key: SessionKey, reason: ResetReason): Promise<void>;
|
|
12
|
+
appendStatuslineLine(key: SessionKey, input: StatuslineLineInput): Promise<void>;
|
|
13
|
+
pruneStaleSessions(): Promise<number>;
|
|
14
|
+
private prune;
|
|
15
|
+
private append;
|
|
16
|
+
private timestamp;
|
|
17
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { appendFile, readFile, stat, unlink } from 'node:fs/promises';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { parseLedgerLines, resetLineSchema, sessionLineSchema, toolLineSchema, SESSION_RETENTION_DAYS } from '../../core/contracts/session-ledger.js';
|
|
4
|
+
import { statuslineLineSchema } from '../../core/contracts/statusline-line.js';
|
|
5
|
+
import { listRuntimeStateFiles } from '../storage/runtime-state-files.js';
|
|
6
|
+
import { ensureSessionDirectory, isMissingFileError, LEDGER_FILE_EXTENSION, sessionLedgerPath, SESSIONS_RELATIVE_PREFIX } from './runtime-paths.js';
|
|
7
|
+
const MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
8
|
+
export class NodeSessionLedger {
|
|
9
|
+
projectRoot;
|
|
10
|
+
clock;
|
|
11
|
+
constructor(projectRoot, clock) {
|
|
12
|
+
this.projectRoot = projectRoot;
|
|
13
|
+
this.clock = clock;
|
|
14
|
+
}
|
|
15
|
+
async readLines(key) {
|
|
16
|
+
const content = await readFile(sessionLedgerPath(this.projectRoot, key), 'utf8').catch((error) => {
|
|
17
|
+
if (isMissingFileError(error))
|
|
18
|
+
return '';
|
|
19
|
+
throw error;
|
|
20
|
+
});
|
|
21
|
+
return parseLedgerLines(content);
|
|
22
|
+
}
|
|
23
|
+
async appendSessionLine(key) {
|
|
24
|
+
await this.append(key, sessionLineSchema.parse({ v: 1, type: 'session', at: this.timestamp(), harness: key.harness, sessionId: key.sessionId, agentId: key.agentId }));
|
|
25
|
+
}
|
|
26
|
+
async appendToolLine(key, input) {
|
|
27
|
+
await this.append(key, toolLineSchema.parse({ v: 1, type: 'tool', at: this.timestamp(), ...input }));
|
|
28
|
+
}
|
|
29
|
+
async appendResetLine(key, reason) {
|
|
30
|
+
await this.append(key, resetLineSchema.parse({ v: 1, type: 'reset', at: this.timestamp(), reason }));
|
|
31
|
+
}
|
|
32
|
+
async appendStatuslineLine(key, input) {
|
|
33
|
+
await this.append(key, statuslineLineSchema.parse({ v: 1, type: 'statusline', at: this.timestamp(), ...input }));
|
|
34
|
+
}
|
|
35
|
+
async pruneStaleSessions() {
|
|
36
|
+
const cutoff = this.clock.now().getTime() - SESSION_RETENTION_DAYS * MILLISECONDS_PER_DAY;
|
|
37
|
+
const files = await listRuntimeStateFiles(this.projectRoot);
|
|
38
|
+
let pruned = 0;
|
|
39
|
+
for (const file of files) {
|
|
40
|
+
if (!file.startsWith(SESSIONS_RELATIVE_PREFIX) || !file.endsWith(LEDGER_FILE_EXTENSION))
|
|
41
|
+
continue;
|
|
42
|
+
if (await this.prune(resolve(this.projectRoot, file), cutoff))
|
|
43
|
+
pruned += 1;
|
|
44
|
+
}
|
|
45
|
+
return pruned;
|
|
46
|
+
}
|
|
47
|
+
async prune(filePath, cutoffMilliseconds) {
|
|
48
|
+
const stats = await stat(filePath).catch((error) => {
|
|
49
|
+
if (isMissingFileError(error))
|
|
50
|
+
return null;
|
|
51
|
+
throw error;
|
|
52
|
+
});
|
|
53
|
+
if (stats === null || stats.mtime.getTime() >= cutoffMilliseconds)
|
|
54
|
+
return false;
|
|
55
|
+
await unlink(filePath).catch((error) => {
|
|
56
|
+
if (!isMissingFileError(error))
|
|
57
|
+
throw error;
|
|
58
|
+
});
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
async append(key, line) {
|
|
62
|
+
await ensureSessionDirectory(this.projectRoot, key);
|
|
63
|
+
await appendFile(sessionLedgerPath(this.projectRoot, key), `${JSON.stringify(line)}\n`, 'utf8');
|
|
64
|
+
}
|
|
65
|
+
timestamp() {
|
|
66
|
+
return this.clock.now().toISOString();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { RuntimeDecision, RuntimeDescriptor, RuntimeEvent } from '../../core/contracts/runtime.js';
|
|
2
|
+
import type { RuntimeInput } from '../../core/services/brake-engine.js';
|
|
3
|
+
import { type RuntimePorts } from './runtime-composition.js';
|
|
4
|
+
export declare const MAXIMUM_STDIN_BYTES: number;
|
|
5
|
+
export type ProcessHarnessAdapter = {
|
|
6
|
+
readonly descriptor: RuntimeDescriptor;
|
|
7
|
+
readonly mapEvent: (eventName: string, payload: unknown) => RuntimeEvent | null;
|
|
8
|
+
readonly mapInput: (eventName: string, payload: unknown, errors: RuntimePorts['errors']) => RuntimeInput | Promise<RuntimeInput>;
|
|
9
|
+
readonly renderDecision: (decision: RuntimeDecision, eventName: string) => string | null;
|
|
10
|
+
readonly resolveProjectRoot: (input: {
|
|
11
|
+
readonly eventName: string;
|
|
12
|
+
readonly payload: unknown;
|
|
13
|
+
}) => Promise<string>;
|
|
14
|
+
};
|
|
15
|
+
export type ProcessHookContext = {
|
|
16
|
+
readonly argv: readonly string[];
|
|
17
|
+
readonly readStdin: () => Promise<string>;
|
|
18
|
+
readonly writeStdout: (text: string) => void;
|
|
19
|
+
readonly writeStderr: (text: string) => void;
|
|
20
|
+
readonly deadlineMilliseconds: number;
|
|
21
|
+
readonly sessionStartDeadlineMilliseconds?: number | undefined;
|
|
22
|
+
};
|
|
23
|
+
export declare const defaultProcessHookContext: ProcessHookContext;
|
|
24
|
+
export declare function readStdinUpTo(stream: NodeJS.ReadableStream, maximumBytes: number): Promise<string>;
|
|
25
|
+
export declare function runProcessHook(adapter: ProcessHarnessAdapter, context?: ProcessHookContext): Promise<number>;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { failureErrorCode, INTERNAL_DEADLINE_MILLISECONDS } from '../../core/services/failure-policy.js';
|
|
2
|
+
import { deadlineFor, HookDeadline, SESSION_START_DEADLINE_MILLISECONDS } from './hook-deadline.js';
|
|
3
|
+
import { failureDecision } from './hook-failure.js';
|
|
4
|
+
import { composeRuntime, loadRuntimeConfiguration, systemClock } from './runtime-composition.js';
|
|
5
|
+
export const MAXIMUM_STDIN_BYTES = 16 * 1024 * 1024;
|
|
6
|
+
const NEUTRAL = { kind: 'neutral' };
|
|
7
|
+
export const defaultProcessHookContext = {
|
|
8
|
+
argv: process.argv,
|
|
9
|
+
readStdin: () => readStdinUpTo(process.stdin, MAXIMUM_STDIN_BYTES),
|
|
10
|
+
writeStdout: (text) => { process.stdout.write(text); },
|
|
11
|
+
writeStderr: (text) => { process.stderr.write(text); },
|
|
12
|
+
deadlineMilliseconds: INTERNAL_DEADLINE_MILLISECONDS,
|
|
13
|
+
sessionStartDeadlineMilliseconds: SESSION_START_DEADLINE_MILLISECONDS,
|
|
14
|
+
};
|
|
15
|
+
export function readStdinUpTo(stream, maximumBytes) {
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
const chunks = [];
|
|
18
|
+
let size = 0;
|
|
19
|
+
stream.on('data', (chunk) => {
|
|
20
|
+
const remaining = maximumBytes - size;
|
|
21
|
+
if (remaining <= 0)
|
|
22
|
+
return;
|
|
23
|
+
chunks.push(remaining >= chunk.length ? chunk : chunk.subarray(0, remaining));
|
|
24
|
+
size += chunk.length;
|
|
25
|
+
});
|
|
26
|
+
stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
|
|
27
|
+
stream.on('error', (error) => reject(error));
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
export async function runProcessHook(adapter, context = defaultProcessHookContext) {
|
|
31
|
+
const eventName = context.argv[2] ?? '';
|
|
32
|
+
const state = { event: null, projectRoot: null, config: null };
|
|
33
|
+
const deadline = new HookDeadline(context.deadlineMilliseconds, 'project_root');
|
|
34
|
+
const limits = { event: context.deadlineMilliseconds, sessionStart: context.sessionStartDeadlineMilliseconds ?? SESSION_START_DEADLINE_MILLISECONDS };
|
|
35
|
+
try {
|
|
36
|
+
const decision = await deadline.run(dispatchHook({ adapter, context, eventName, state, deadline, limits }));
|
|
37
|
+
writeDecision({ adapter, context, decision, eventName });
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
const decision = await failureDecision({ descriptor: adapter.descriptor, state, error, eventName });
|
|
41
|
+
writeDecision({ adapter, context, decision, eventName });
|
|
42
|
+
context.writeStderr(`ContextBrake: ${failureErrorCode(error)}\n`);
|
|
43
|
+
}
|
|
44
|
+
return 0;
|
|
45
|
+
}
|
|
46
|
+
async function dispatchHook(input) {
|
|
47
|
+
const { deadline } = input;
|
|
48
|
+
const projectRoot = await input.adapter.resolveProjectRoot({ eventName: input.eventName, payload: null });
|
|
49
|
+
input.state.projectRoot = projectRoot;
|
|
50
|
+
deadline.mark('stdin');
|
|
51
|
+
const payload = parsePayload(await input.context.readStdin());
|
|
52
|
+
deadline.mark('event');
|
|
53
|
+
const event = input.adapter.mapEvent(input.eventName, payload);
|
|
54
|
+
input.state.event = event;
|
|
55
|
+
deadline.extendTo(deadlineFor(event, input.limits));
|
|
56
|
+
deadline.mark('config');
|
|
57
|
+
const config = await loadRuntimeConfiguration(projectRoot);
|
|
58
|
+
input.state.config = config;
|
|
59
|
+
if (event === null)
|
|
60
|
+
return NEUTRAL;
|
|
61
|
+
const services = composeRuntime({ projectRoot, descriptor: input.adapter.descriptor, config, clock: systemClock });
|
|
62
|
+
deadline.mark('input');
|
|
63
|
+
const engineInput = await input.adapter.mapInput(input.eventName, payload, services.errors);
|
|
64
|
+
deadline.mark('engine');
|
|
65
|
+
return services.engine.handle(event, { ...engineInput, onPhase: deadline.mark, deadline });
|
|
66
|
+
}
|
|
67
|
+
function writeDecision(input) {
|
|
68
|
+
const text = input.adapter.renderDecision(input.decision, input.eventName);
|
|
69
|
+
if (text !== null && text !== '')
|
|
70
|
+
input.context.writeStdout(text);
|
|
71
|
+
}
|
|
72
|
+
function parsePayload(raw) {
|
|
73
|
+
try {
|
|
74
|
+
return JSON.parse(raw);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type ContextBrakeConfig } from '../../core/contracts/configuration.js';
|
|
2
|
+
import type { HarnessId } from '../../core/contracts/harness.js';
|
|
3
|
+
import type { RuntimeDescriptor } from '../../core/contracts/runtime.js';
|
|
4
|
+
import type { Clock, RuntimeErrorLog, SessionLedger } from '../../core/contracts/session-ledger.js';
|
|
5
|
+
import { type BrakeEngine } from '../../core/services/brake-engine.js';
|
|
6
|
+
export declare const CONFIG_RELATIVE_PATH = "context-brake.config.json";
|
|
7
|
+
export declare const systemClock: Clock;
|
|
8
|
+
export type RuntimePorts = {
|
|
9
|
+
readonly ledger: SessionLedger;
|
|
10
|
+
readonly errors: RuntimeErrorLog;
|
|
11
|
+
};
|
|
12
|
+
export type RuntimeServices = RuntimePorts & {
|
|
13
|
+
readonly engine: BrakeEngine;
|
|
14
|
+
readonly config: ContextBrakeConfig;
|
|
15
|
+
};
|
|
16
|
+
export type RuntimePortsInput = {
|
|
17
|
+
readonly projectRoot: string;
|
|
18
|
+
readonly config: ContextBrakeConfig | null;
|
|
19
|
+
readonly clock: Clock;
|
|
20
|
+
readonly ledger?: SessionLedger | undefined;
|
|
21
|
+
readonly harness?: HarnessId;
|
|
22
|
+
};
|
|
23
|
+
export type RuntimeCompositionInput = RuntimePortsInput & {
|
|
24
|
+
readonly descriptor: RuntimeDescriptor;
|
|
25
|
+
readonly config: ContextBrakeConfig;
|
|
26
|
+
};
|
|
27
|
+
export declare function loadRuntimeConfiguration(projectRoot: string): Promise<ContextBrakeConfig>;
|
|
28
|
+
export declare function createRuntimePorts(input: RuntimePortsInput): RuntimePorts;
|
|
29
|
+
export declare function composeRuntime(input: RuntimeCompositionInput): RuntimeServices;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { DEFAULT_CONFIG } from '../../core/contracts/configuration.js';
|
|
4
|
+
import { createBrakeEngine } from '../../core/services/brake-engine.js';
|
|
5
|
+
import { invalidSyntaxError, parseConfiguration } from '../../core/validation/configuration-validator.js';
|
|
6
|
+
import { NodeHandoffStore } from '../storage/node-handoff-store.js';
|
|
7
|
+
import { NodeRuntimeErrorLog } from './node-runtime-logs.js';
|
|
8
|
+
import { NodeSessionLedger } from './node-session-ledger.js';
|
|
9
|
+
import { isMissingFileError } from './runtime-paths.js';
|
|
10
|
+
export const CONFIG_RELATIVE_PATH = 'context-brake.config.json';
|
|
11
|
+
export const systemClock = { now: () => new Date() };
|
|
12
|
+
export async function loadRuntimeConfiguration(projectRoot) {
|
|
13
|
+
const filePath = resolve(projectRoot, CONFIG_RELATIVE_PATH);
|
|
14
|
+
const content = await readFile(filePath, 'utf8').catch((error) => {
|
|
15
|
+
if (isMissingFileError(error))
|
|
16
|
+
return null;
|
|
17
|
+
throw error;
|
|
18
|
+
});
|
|
19
|
+
if (content === null)
|
|
20
|
+
return DEFAULT_CONFIG;
|
|
21
|
+
let value;
|
|
22
|
+
try {
|
|
23
|
+
value = JSON.parse(content);
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
throw invalidSyntaxError(filePath, content, error);
|
|
27
|
+
}
|
|
28
|
+
return parseConfiguration(value, filePath);
|
|
29
|
+
}
|
|
30
|
+
export function createRuntimePorts(input) {
|
|
31
|
+
return {
|
|
32
|
+
ledger: input.ledger ?? new NodeSessionLedger(input.projectRoot, input.clock),
|
|
33
|
+
errors: new NodeRuntimeErrorLog(input.projectRoot, input.clock),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export function composeRuntime(input) {
|
|
37
|
+
const ports = createRuntimePorts({ ...input, harness: input.descriptor.harness });
|
|
38
|
+
const handoff = new NodeHandoffStore(input.projectRoot, input.clock);
|
|
39
|
+
const engine = createBrakeEngine({ descriptor: input.descriptor, config: input.config, ledger: ports.ledger, errors: ports.errors, handoff });
|
|
40
|
+
return { ...ports, engine, config: input.config };
|
|
41
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SessionKey } from '../../core/contracts/runtime.js';
|
|
2
|
+
export declare const RUNTIME_GITIGNORE_CONTENT = "*\n";
|
|
3
|
+
export declare const SESSIONS_DIR_NAME = "sessions";
|
|
4
|
+
export declare const LEDGER_FILE_EXTENSION = ".jsonl";
|
|
5
|
+
export declare const SESSIONS_RELATIVE_PREFIX: string;
|
|
6
|
+
export declare function runtimeDirectory(projectRoot: string): string;
|
|
7
|
+
export declare function sessionsDirectory(projectRoot: string, harness: SessionKey['harness']): string;
|
|
8
|
+
export declare function sessionLedgerHash(key: SessionKey): string;
|
|
9
|
+
export declare function sessionLedgerPath(projectRoot: string, key: SessionKey): string;
|
|
10
|
+
export declare function ensureRuntimeDirectory(projectRoot: string): Promise<void>;
|
|
11
|
+
export declare function ensureSessionDirectory(projectRoot: string, key: SessionKey): Promise<void>;
|
|
12
|
+
export declare function isMissingFileError(error: unknown): boolean;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { join, resolve } from 'node:path';
|
|
4
|
+
import { RUNTIME_STATE_RELATIVE_DIR } from '../storage/runtime-state-files.js';
|
|
5
|
+
export const RUNTIME_GITIGNORE_CONTENT = '*\n';
|
|
6
|
+
export const SESSIONS_DIR_NAME = 'sessions';
|
|
7
|
+
export const LEDGER_FILE_EXTENSION = '.jsonl';
|
|
8
|
+
export const SESSIONS_RELATIVE_PREFIX = `${RUNTIME_STATE_RELATIVE_DIR}/${SESSIONS_DIR_NAME}/`;
|
|
9
|
+
const HASH_LENGTH = 32;
|
|
10
|
+
export function runtimeDirectory(projectRoot) {
|
|
11
|
+
return resolve(projectRoot, RUNTIME_STATE_RELATIVE_DIR);
|
|
12
|
+
}
|
|
13
|
+
export function sessionsDirectory(projectRoot, harness) {
|
|
14
|
+
return join(runtimeDirectory(projectRoot), SESSIONS_DIR_NAME, harness);
|
|
15
|
+
}
|
|
16
|
+
export function sessionLedgerHash(key) {
|
|
17
|
+
return createHash('sha256').update(`${key.sessionId}\0${key.agentId ?? ''}`).digest('hex').slice(0, HASH_LENGTH);
|
|
18
|
+
}
|
|
19
|
+
export function sessionLedgerPath(projectRoot, key) {
|
|
20
|
+
return join(sessionsDirectory(projectRoot, key.harness), `${sessionLedgerHash(key)}${LEDGER_FILE_EXTENSION}`);
|
|
21
|
+
}
|
|
22
|
+
export async function ensureRuntimeDirectory(projectRoot) {
|
|
23
|
+
const directory = runtimeDirectory(projectRoot);
|
|
24
|
+
await mkdir(join(directory, SESSIONS_DIR_NAME), { recursive: true });
|
|
25
|
+
await writeGitignoreIfMissing(join(directory, '.gitignore'));
|
|
26
|
+
}
|
|
27
|
+
export async function ensureSessionDirectory(projectRoot, key) {
|
|
28
|
+
await ensureRuntimeDirectory(projectRoot);
|
|
29
|
+
await mkdir(sessionsDirectory(projectRoot, key.harness), { recursive: true });
|
|
30
|
+
}
|
|
31
|
+
export function isMissingFileError(error) {
|
|
32
|
+
return error.code === 'ENOENT';
|
|
33
|
+
}
|
|
34
|
+
async function writeGitignoreIfMissing(filePath) {
|
|
35
|
+
try {
|
|
36
|
+
await writeFile(filePath, RUNTIME_GITIGNORE_CONTENT, { flag: 'wx' });
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
if (!isAlreadyCreated(error))
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function isAlreadyCreated(error) {
|
|
44
|
+
return error.code === 'EEXIST';
|
|
45
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Clock } from '../../core/contracts/session-ledger.js';
|
|
2
|
+
import { type RuntimeStateReading } from '../../core/services/runtime-error-checks.js';
|
|
3
|
+
export declare class NodeRuntimeStateReader {
|
|
4
|
+
readonly projectRoot: string;
|
|
5
|
+
readonly clock: Clock;
|
|
6
|
+
constructor(projectRoot: string, clock: Clock);
|
|
7
|
+
read(): Promise<RuntimeStateReading | null>;
|
|
8
|
+
private readLedgers;
|
|
9
|
+
}
|