context-brake 0.0.0-stage → 1.1.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 +351 -2
- package/dist/assets/runtime/antigravity-cli-hook.mjs +19219 -0
- package/dist/assets/runtime/claude-code-hook.mjs +19400 -0
- package/dist/assets/runtime/claude-code-mod.mjs +18685 -0
- package/dist/assets/runtime/claude-code-statusline.mjs +18781 -0
- package/dist/assets/runtime/codex-cli-hook.mjs +19347 -0
- package/dist/assets/runtime/context-brake-runtime.mjs +6 -0
- package/dist/assets/runtime/cursor-hook.mjs +19229 -0
- package/dist/assets/runtime/github-copilot-cli-hook.mjs +19234 -0
- package/dist/assets/runtime/omp-extension.js +19284 -0
- package/dist/assets/runtime/omp-restart.js +18795 -0
- package/dist/assets/runtime/opencode-plugin.js +19247 -0
- package/dist/assets/runtime/pi-extension.js +19278 -0
- package/dist/assets/runtime/pi-restart.js +18790 -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 +25 -0
- package/dist/src/cli/assistant/assistant-questions.d.ts +3 -0
- package/dist/src/cli/assistant/assistant-questions.js +27 -0
- package/dist/src/cli/assistant/assistant-session.d.ts +5 -0
- package/dist/src/cli/assistant/assistant-session.js +27 -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/invocation-facts.d.ts +5 -0
- package/dist/src/cli/assistant/invocation-facts.js +6 -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 +11 -0
- package/dist/src/cli/assistant/questions-misc.js +26 -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-skill.d.ts +21 -0
- package/dist/src/cli/assistant/questions-skill.js +45 -0
- package/dist/src/cli/assistant/questions-snapshot.d.ts +11 -0
- package/dist/src/cli/assistant/questions-snapshot.js +59 -0
- package/dist/src/cli/assistant/questions-trigger.d.ts +6 -0
- package/dist/src/cli/assistant/questions-trigger.js +56 -0
- package/dist/src/cli/assistant/skill-options.d.ts +20 -0
- package/dist/src/cli/assistant/skill-options.js +40 -0
- package/dist/src/cli/assistant/snapshot-specs.d.ts +10 -0
- package/dist/src/cli/assistant/snapshot-specs.js +32 -0
- package/dist/src/cli/assistant/summary-rows.d.ts +5 -0
- package/dist/src/cli/assistant/summary-rows.js +47 -0
- package/dist/src/cli/assistant/summary.d.ts +3 -0
- package/dist/src/cli/assistant/summary.js +25 -0
- package/dist/src/cli/assistant/types.d.ts +52 -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 +57 -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 +71 -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 +16 -0
- package/dist/src/cli/init-option-rules.js +45 -0
- package/dist/src/cli/main.d.ts +3 -0
- package/dist/src/cli/main.js +62 -0
- package/dist/src/cli/output/card.d.ts +8 -0
- package/dist/src/cli/output/card.js +30 -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 +18 -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/install-rows.d.ts +6 -0
- package/dist/src/cli/output/install-rows.js +31 -0
- package/dist/src/cli/output/install-text.d.ts +4 -0
- package/dist/src/cli/output/install-text.js +26 -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/style.d.ts +22 -0
- package/dist/src/cli/output/style.js +27 -0
- package/dist/src/cli/output/text.d.ts +4 -0
- package/dist/src/cli/output/text.js +41 -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 +50 -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 +82 -0
- package/dist/src/core/contracts/configuration.js +44 -0
- package/dist/src/core/contracts/context-reading.d.ts +16 -0
- package/dist/src/core/contracts/context-reading.js +20 -0
- package/dist/src/core/contracts/context-window-report.d.ts +23 -0
- package/dist/src/core/contracts/context-window-report.js +10 -0
- package/dist/src/core/contracts/diagnostics.d.ts +567 -0
- package/dist/src/core/contracts/diagnostics.js +36 -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 +85 -0
- package/dist/src/core/contracts/manifest.js +26 -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 +52 -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/skill-catalog.d.ts +11 -0
- package/dist/src/core/contracts/skill-catalog.js +1 -0
- package/dist/src/core/contracts/skill-invocation.d.ts +3 -0
- package/dist/src/core/contracts/skill-invocation.js +1 -0
- package/dist/src/core/contracts/skill-name.d.ts +5 -0
- package/dist/src/core/contracts/skill-name.js +31 -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 +62 -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 +13 -0
- package/dist/src/core/services/doctor-report-extras.js +40 -0
- package/dist/src/core/services/doctor-service.d.ts +26 -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 +10 -0
- package/dist/src/core/services/injection-policy.js +5 -0
- package/dist/src/core/services/installation-adapters.d.ts +22 -0
- package/dist/src/core/services/installation-adapters.js +30 -0
- package/dist/src/core/services/installation-builder.d.ts +24 -0
- package/dist/src/core/services/installation-builder.js +67 -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 +12 -0
- package/dist/src/core/services/manifest-change.js +17 -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/skill-candidates.d.ts +16 -0
- package/dist/src/core/services/skill-candidates.js +14 -0
- package/dist/src/core/services/skill-invocation.d.ts +4 -0
- package/dist/src/core/services/skill-invocation.js +12 -0
- package/dist/src/core/services/skill-ranking.d.ts +7 -0
- package/dist/src/core/services/skill-ranking.js +25 -0
- package/dist/src/core/services/snapshot-merge.d.ts +23 -0
- package/dist/src/core/services/snapshot-merge.js +32 -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/trigger-text.d.ts +5 -0
- package/dist/src/core/services/trigger-text.js +4 -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 +17 -0
- package/dist/src/core/services/zone-guidance.js +38 -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 +52 -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/antigravity-cli/skill-folders.d.ts +1 -0
- package/dist/src/infrastructure/harnesses/antigravity-cli/skill-folders.js +1 -0
- package/dist/src/infrastructure/harnesses/antigravity-cli/skill-invocation.d.ts +2 -0
- package/dist/src/infrastructure/harnesses/antigravity-cli/skill-invocation.js +2 -0
- package/dist/src/infrastructure/harnesses/claude-code/adapter.d.ts +14 -0
- package/dist/src/infrastructure/harnesses/claude-code/adapter.js +86 -0
- package/dist/src/infrastructure/harnesses/claude-code/auto-restart-diagnostics.d.ts +10 -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 +11 -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/context-readings-scan.d.ts +2 -0
- package/dist/src/infrastructure/harnesses/claude-code/context-readings-scan.js +21 -0
- package/dist/src/infrastructure/harnesses/claude-code/context-source.d.ts +10 -0
- package/dist/src/infrastructure/harnesses/claude-code/context-source.js +16 -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/context-reading.d.ts +2 -0
- package/dist/src/infrastructure/harnesses/claude-code/mod/context-reading.js +67 -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 +65 -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 +5 -0
- package/dist/src/infrastructure/harnesses/claude-code/mod/mod-log.js +37 -0
- package/dist/src/infrastructure/harnesses/claude-code/mod/register.d.ts +2 -0
- package/dist/src/infrastructure/harnesses/claude-code/mod/register.js +28 -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/mod-reading.d.ts +6 -0
- package/dist/src/infrastructure/harnesses/claude-code/mod-reading.js +37 -0
- package/dist/src/infrastructure/harnesses/claude-code/planner.d.ts +8 -0
- package/dist/src/infrastructure/harnesses/claude-code/planner.js +72 -0
- package/dist/src/infrastructure/harnesses/claude-code/project-root.d.ts +2 -0
- package/dist/src/infrastructure/harnesses/claude-code/project-root.js +5 -0
- package/dist/src/infrastructure/harnesses/claude-code/runtime.d.ts +10 -0
- package/dist/src/infrastructure/harnesses/claude-code/runtime.js +87 -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/skill-folders.d.ts +1 -0
- package/dist/src/infrastructure/harnesses/claude-code/skill-folders.js +1 -0
- package/dist/src/infrastructure/harnesses/claude-code/skill-invocation.d.ts +2 -0
- package/dist/src/infrastructure/harnesses/claude-code/skill-invocation.js +2 -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 +63 -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-migration.d.ts +3 -0
- package/dist/src/infrastructure/harnesses/claude-code/statusline-migration.js +23 -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 +5 -0
- package/dist/src/infrastructure/harnesses/claude-code/statusline-planner.js +85 -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/claude-code/user-settings.d.ts +2 -0
- package/dist/src/infrastructure/harnesses/claude-code/user-settings.js +11 -0
- package/dist/src/infrastructure/harnesses/codex-cli/adapter.d.ts +14 -0
- package/dist/src/infrastructure/harnesses/codex-cli/adapter.js +91 -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 +86 -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/codex-cli/skill-folders.d.ts +1 -0
- package/dist/src/infrastructure/harnesses/codex-cli/skill-folders.js +1 -0
- package/dist/src/infrastructure/harnesses/codex-cli/skill-invocation.d.ts +2 -0
- package/dist/src/infrastructure/harnesses/codex-cli/skill-invocation.js +2 -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/config-origin.d.ts +10 -0
- package/dist/src/infrastructure/harnesses/common/config-origin.js +52 -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 +71 -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 +50 -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/cursor/skill-folders.d.ts +1 -0
- package/dist/src/infrastructure/harnesses/cursor/skill-folders.js +1 -0
- package/dist/src/infrastructure/harnesses/cursor/skill-invocation.d.ts +2 -0
- package/dist/src/infrastructure/harnesses/cursor/skill-invocation.js +2 -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 +68 -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/github-copilot-cli/skill-folders.d.ts +1 -0
- package/dist/src/infrastructure/harnesses/github-copilot-cli/skill-folders.js +1 -0
- package/dist/src/infrastructure/harnesses/github-copilot-cli/skill-invocation.d.ts +2 -0
- package/dist/src/infrastructure/harnesses/github-copilot-cli/skill-invocation.js +2 -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 +70 -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/oh-my-pi/skill-folders.d.ts +1 -0
- package/dist/src/infrastructure/harnesses/oh-my-pi/skill-folders.js +1 -0
- package/dist/src/infrastructure/harnesses/oh-my-pi/skill-invocation.d.ts +2 -0
- package/dist/src/infrastructure/harnesses/oh-my-pi/skill-invocation.js +2 -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 +52 -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/opencode/skill-folders.d.ts +1 -0
- package/dist/src/infrastructure/harnesses/opencode/skill-folders.js +1 -0
- package/dist/src/infrastructure/harnesses/opencode/skill-invocation.d.ts +2 -0
- package/dist/src/infrastructure/harnesses/opencode/skill-invocation.js +2 -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 +68 -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/pi/skill-folders.d.ts +1 -0
- package/dist/src/infrastructure/harnesses/pi/skill-folders.js +1 -0
- package/dist/src/infrastructure/harnesses/pi/skill-invocation.d.ts +2 -0
- package/dist/src/infrastructure/harnesses/pi/skill-invocation.js +2 -0
- package/dist/src/infrastructure/harnesses/registry.d.ts +6 -0
- package/dist/src/infrastructure/harnesses/registry.js +94 -0
- package/dist/src/infrastructure/harnesses/skill-folders.d.ts +3 -0
- package/dist/src/infrastructure/harnesses/skill-folders.js +21 -0
- package/dist/src/infrastructure/harnesses/skill-invocations.d.ts +4 -0
- package/dist/src/infrastructure/harnesses/skill-invocations.js +21 -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 +46 -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/skills/frontmatter.d.ts +5 -0
- package/dist/src/infrastructure/skills/frontmatter.js +25 -0
- package/dist/src/infrastructure/skills/skill-catalog-reader.d.ts +4 -0
- package/dist/src/infrastructure/skills/skill-catalog-reader.js +78 -0
- package/dist/src/infrastructure/skills/skill-catalog.d.ts +2 -0
- package/dist/src/infrastructure/skills/skill-catalog.js +5 -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 +11 -0
- package/dist/src/infrastructure/storage/change-applier.js +81 -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 +53 -0
- package/dist/src/infrastructure/storage/json-node-removal.d.ts +2 -0
- package/dist/src/infrastructure/storage/json-node-removal.js +70 -0
- package/dist/src/infrastructure/storage/json-span-utils.d.ts +24 -0
- package/dist/src/infrastructure/storage/json-span-utils.js +57 -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 +151 -0
- package/package.json +65 -4
- package/schemas/context-brake.config.schema.json +182 -0
- package/schemas/doctor-report.schema.json +646 -0
- package/schemas/install-report.schema.json +458 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { open, rm, stat } from 'node:fs/promises';
|
|
2
|
+
import { isMissingFileError } from '../runtime/runtime-paths.js';
|
|
3
|
+
const STALE_CLAIM_LOCK_MS = 30_000;
|
|
4
|
+
export async function createExclusive(path) {
|
|
5
|
+
try {
|
|
6
|
+
await (await open(path, 'wx')).close();
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
catch (error) {
|
|
10
|
+
if (error.code === 'EEXIST')
|
|
11
|
+
return false;
|
|
12
|
+
throw error;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export async function acquireClaimLock(lock, clock) {
|
|
16
|
+
if (await createExclusive(lock))
|
|
17
|
+
return true;
|
|
18
|
+
if (!(await isStale(lock, clock)))
|
|
19
|
+
return false;
|
|
20
|
+
await rm(lock, { force: true });
|
|
21
|
+
return createExclusive(lock);
|
|
22
|
+
}
|
|
23
|
+
async function isStale(lock, clock) {
|
|
24
|
+
try {
|
|
25
|
+
return clock.now().getTime() - (await stat(lock)).mtimeMs > STALE_CLAIM_LOCK_MS;
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
if (isMissingFileError(error))
|
|
29
|
+
return true;
|
|
30
|
+
throw error;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { InvalidJsonDocumentError, validateJsonDocument, parseAndValidateJson } from './json-validator.js';
|
|
2
|
+
export declare function setJsonProperty(text: string, path: readonly (string | number)[], value: unknown): string;
|
|
3
|
+
export declare function appendJsonArrayItem(text: string, path: readonly (string | number)[], value: unknown): string;
|
|
4
|
+
export declare function removeJsonProperty(text: string, path: readonly (string | number)[]): string;
|
|
5
|
+
export declare function removeJsonArrayItem(text: string, path: readonly (string | number)[], predicate: (item: unknown) => boolean): string;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { findNodeAtLocation, getNodeValue } from 'jsonc-parser';
|
|
2
|
+
import { parseAndValidateJson } from './json-validator.js';
|
|
3
|
+
import { detectEol, detectIndent, formatJsonValue, insertArrayItem, insertObjectEntry } from './json-span-utils.js';
|
|
4
|
+
import { removeNodeSpan } from './json-node-removal.js';
|
|
5
|
+
export { InvalidJsonDocumentError, validateJsonDocument, parseAndValidateJson } from './json-validator.js';
|
|
6
|
+
export function setJsonProperty(text, path, value) {
|
|
7
|
+
const root = parseAndValidateJson(text);
|
|
8
|
+
const indent = detectIndent(text);
|
|
9
|
+
const eol = detectEol(text);
|
|
10
|
+
const format = text.includes('\n') ? indent : '';
|
|
11
|
+
const existingNode = findNodeAtLocation(root, path);
|
|
12
|
+
if (existingNode) {
|
|
13
|
+
const formatted = formatJsonValue(value, { indent: format, eol, depth: path.length });
|
|
14
|
+
return `${text.slice(0, existingNode.offset)}${formatted}${text.slice(existingNode.offset + existingNode.length)}`;
|
|
15
|
+
}
|
|
16
|
+
const parentPath = path.slice(0, -1);
|
|
17
|
+
const key = String(path[path.length - 1]);
|
|
18
|
+
const parentNode = parentPath.length === 0 ? root : findNodeAtLocation(root, parentPath);
|
|
19
|
+
if (!parentNode) {
|
|
20
|
+
return setJsonProperty(text, parentPath, { [key]: value });
|
|
21
|
+
}
|
|
22
|
+
const formattedVal = formatJsonValue(value, { indent: format, eol, depth: path.length });
|
|
23
|
+
return insertObjectEntry(text, parentNode, { key, formattedVal, indent: format, depth: path.length });
|
|
24
|
+
}
|
|
25
|
+
export function appendJsonArrayItem(text, path, value) {
|
|
26
|
+
const root = parseAndValidateJson(text);
|
|
27
|
+
const arrayNode = findNodeAtLocation(root, path);
|
|
28
|
+
if (!arrayNode) {
|
|
29
|
+
return setJsonProperty(text, path, [value]);
|
|
30
|
+
}
|
|
31
|
+
const indent = detectIndent(text);
|
|
32
|
+
const eol = detectEol(text);
|
|
33
|
+
const format = text.includes('\n') ? indent : '';
|
|
34
|
+
const formattedVal = formatJsonValue(value, { indent: format, eol, depth: path.length + 1 });
|
|
35
|
+
return insertArrayItem(text, arrayNode, { formattedVal, indent: format, depth: path.length + 1 });
|
|
36
|
+
}
|
|
37
|
+
export function removeJsonProperty(text, path) {
|
|
38
|
+
const root = parseAndValidateJson(text);
|
|
39
|
+
const node = findNodeAtLocation(root, path);
|
|
40
|
+
if (!node || !node.parent || node.parent.type !== 'property')
|
|
41
|
+
return text;
|
|
42
|
+
return removeNodeSpan(text, node.parent);
|
|
43
|
+
}
|
|
44
|
+
export function removeJsonArrayItem(text, path, predicate) {
|
|
45
|
+
const root = parseAndValidateJson(text);
|
|
46
|
+
const arrayNode = findNodeAtLocation(root, path);
|
|
47
|
+
if (!arrayNode || !arrayNode.children)
|
|
48
|
+
return text;
|
|
49
|
+
const target = arrayNode.children.find((child) => predicate(getNodeValue(child)));
|
|
50
|
+
if (!target)
|
|
51
|
+
return text;
|
|
52
|
+
return removeNodeSpan(text, target);
|
|
53
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { findLineEndAfter, findSeparatorComma } from './json-span-utils.js';
|
|
2
|
+
function siblingContext(node) {
|
|
3
|
+
const list = node.parent?.children;
|
|
4
|
+
return list ? { list, index: list.indexOf(node) } : undefined;
|
|
5
|
+
}
|
|
6
|
+
function commaAfterPrevious(text, node) {
|
|
7
|
+
const context = siblingContext(node);
|
|
8
|
+
if (!context || context.index <= 0)
|
|
9
|
+
return -1;
|
|
10
|
+
const previous = context.list[context.index - 1];
|
|
11
|
+
return findSeparatorComma(text, previous.offset + previous.length, node.offset);
|
|
12
|
+
}
|
|
13
|
+
function commaBeforeNext(text, node) {
|
|
14
|
+
const context = siblingContext(node);
|
|
15
|
+
const next = context?.list[context.index + 1];
|
|
16
|
+
return next ? findSeparatorComma(text, node.offset + node.length, next.offset) : -1;
|
|
17
|
+
}
|
|
18
|
+
function isLastChild(node) {
|
|
19
|
+
const context = siblingContext(node);
|
|
20
|
+
return context === undefined || context.index === context.list.length - 1;
|
|
21
|
+
}
|
|
22
|
+
function isOnlyNodeOnLine(text, span) {
|
|
23
|
+
const leading = text.slice(span.lineStart, span.start);
|
|
24
|
+
return /^\s*$/.test(leading) && /^[ \t]*,?[ \t]*\r?\n?$/.test(text.slice(span.end, span.lineEnd));
|
|
25
|
+
}
|
|
26
|
+
function removeLastNode(text, node, span) {
|
|
27
|
+
const ownLine = isOnlyNodeOnLine(text, span);
|
|
28
|
+
const after = text.slice(ownLine ? span.lineEnd : span.end);
|
|
29
|
+
const comma = !ownLine || isLastChild(node) ? commaAfterPrevious(text, node) : -1;
|
|
30
|
+
const cut = ownLine ? span.lineStart : span.start;
|
|
31
|
+
if (comma === -1)
|
|
32
|
+
return `${text.slice(0, cut)}${after}`;
|
|
33
|
+
return `${text.slice(0, comma)}${text.slice(comma + 1, cut)}${after}`;
|
|
34
|
+
}
|
|
35
|
+
function removeBeforeComma(text, node, span) {
|
|
36
|
+
const before = text.slice(0, span.start);
|
|
37
|
+
const leadingComma = before.match(/,\s*$/);
|
|
38
|
+
if (leadingComma?.index !== undefined)
|
|
39
|
+
return `${before.slice(0, leadingComma.index)}${text.slice(span.end)}`;
|
|
40
|
+
const comma = commaBeforeNext(text, node);
|
|
41
|
+
if (comma === -1)
|
|
42
|
+
return `${before}${text.slice(span.end)}`;
|
|
43
|
+
return `${before}${text.slice(span.end, comma)}${text.slice(comma + 1)}`;
|
|
44
|
+
}
|
|
45
|
+
function emptyContainer(text, node) {
|
|
46
|
+
const container = node.parent;
|
|
47
|
+
if (container?.children?.length !== 1)
|
|
48
|
+
return undefined;
|
|
49
|
+
const open = container.offset + 1;
|
|
50
|
+
const close = container.offset + container.length - 1;
|
|
51
|
+
const rest = `${text.slice(open, node.offset)}${text.slice(node.offset + node.length, close)}`;
|
|
52
|
+
return /^\s*$/.test(rest) ? `${text.slice(0, open)}${text.slice(close)}` : undefined;
|
|
53
|
+
}
|
|
54
|
+
export function removeNodeSpan(text, node) {
|
|
55
|
+
const emptied = emptyContainer(text, node);
|
|
56
|
+
if (emptied !== undefined)
|
|
57
|
+
return emptied;
|
|
58
|
+
const start = node.offset;
|
|
59
|
+
const end = start + node.length;
|
|
60
|
+
const lineStart = text.lastIndexOf('\n', start) + 1;
|
|
61
|
+
const span = { start, end, lineStart, lineEnd: findLineEndAfter(text, end) };
|
|
62
|
+
if (isOnlyNodeOnLine(text, span))
|
|
63
|
+
return removeLastNode(text, node, span);
|
|
64
|
+
const trailingComma = text.slice(end).match(/^\s*,/);
|
|
65
|
+
if (trailingComma)
|
|
66
|
+
return `${text.slice(0, start)}${text.slice(end + trailingComma[0].length)}`;
|
|
67
|
+
if (isLastChild(node))
|
|
68
|
+
return removeLastNode(text, node, span);
|
|
69
|
+
return removeBeforeComma(text, node, span);
|
|
70
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Node } from 'jsonc-parser';
|
|
2
|
+
export type FormatOptions = {
|
|
3
|
+
indent: string;
|
|
4
|
+
eol: string;
|
|
5
|
+
depth: number;
|
|
6
|
+
};
|
|
7
|
+
export type InsertEntryOptions = {
|
|
8
|
+
key: string;
|
|
9
|
+
formattedVal: string;
|
|
10
|
+
indent: string;
|
|
11
|
+
depth: number;
|
|
12
|
+
};
|
|
13
|
+
export type InsertItemOptions = {
|
|
14
|
+
formattedVal: string;
|
|
15
|
+
indent: string;
|
|
16
|
+
depth: number;
|
|
17
|
+
};
|
|
18
|
+
export declare function detectEol(text: string): string;
|
|
19
|
+
export declare function detectIndent(text: string): string;
|
|
20
|
+
export declare function findLineEndAfter(text: string, offset: number): number;
|
|
21
|
+
export declare function formatJsonValue(value: unknown, opts: FormatOptions): string;
|
|
22
|
+
export declare function findSeparatorComma(text: string, from: number, to: number): number;
|
|
23
|
+
export declare function insertObjectEntry(text: string, parentNode: Node, opts: InsertEntryOptions): string;
|
|
24
|
+
export declare function insertArrayItem(text: string, arrayNode: Node, opts: InsertItemOptions): string;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export function detectEol(text) {
|
|
2
|
+
return text.includes('\r\n') ? '\r\n' : '\n';
|
|
3
|
+
}
|
|
4
|
+
export function detectIndent(text) {
|
|
5
|
+
const match = text.match(/\n([ \t]+)[^\s]/);
|
|
6
|
+
return match?.[1] ?? '';
|
|
7
|
+
}
|
|
8
|
+
export function findLineEndAfter(text, offset) {
|
|
9
|
+
const newline = text.indexOf('\n', offset);
|
|
10
|
+
return newline === -1 ? text.length : newline + 1;
|
|
11
|
+
}
|
|
12
|
+
export function formatJsonValue(value, opts) {
|
|
13
|
+
const raw = JSON.stringify(value, null, opts.indent);
|
|
14
|
+
if (!raw.includes('\n'))
|
|
15
|
+
return raw;
|
|
16
|
+
const prefix = opts.indent.repeat(opts.depth);
|
|
17
|
+
return raw.split('\n').map((line, idx) => (idx === 0 ? line : `${prefix}${line}`)).join(opts.eol);
|
|
18
|
+
}
|
|
19
|
+
export function findSeparatorComma(text, from, to) {
|
|
20
|
+
let index = from;
|
|
21
|
+
while (index < to) {
|
|
22
|
+
if (text.startsWith('//', index))
|
|
23
|
+
index = findLineEndAfter(text, index + 2);
|
|
24
|
+
else if (text.startsWith('/*', index)) {
|
|
25
|
+
const close = text.indexOf('*/', index + 2);
|
|
26
|
+
index = close === -1 ? to : close + 2;
|
|
27
|
+
}
|
|
28
|
+
else if (text[index] === ',')
|
|
29
|
+
return index;
|
|
30
|
+
else
|
|
31
|
+
index += 1;
|
|
32
|
+
}
|
|
33
|
+
return -1;
|
|
34
|
+
}
|
|
35
|
+
function insertIntoContainer(text, container, opts) {
|
|
36
|
+
const compact = !text.includes('\n');
|
|
37
|
+
if (!container.children || container.children.length === 0) {
|
|
38
|
+
const pos = container.offset + 1;
|
|
39
|
+
const inner = compact ? opts.item : `${detectEol(text)}${opts.indent.repeat(opts.depth)}${opts.item}${detectEol(text)}${opts.indent.repeat(opts.depth - 1)}`;
|
|
40
|
+
return `${text.slice(0, pos)}${inner}${text.slice(pos)}`;
|
|
41
|
+
}
|
|
42
|
+
const last = container.children[container.children.length - 1];
|
|
43
|
+
const lastEnd = last.offset + last.length;
|
|
44
|
+
const closePos = container.offset + container.length - 1;
|
|
45
|
+
const gap = text.slice(lastEnd, closePos);
|
|
46
|
+
const closing = gap.match(/\s*$/)?.[0] ?? '';
|
|
47
|
+
const trivia = gap.slice(0, gap.length - closing.length);
|
|
48
|
+
const comma = findSeparatorComma(text, lastEnd, closePos) === -1 ? ',' : '';
|
|
49
|
+
const separator = compact ? '' : `${detectEol(text)}${opts.indent.repeat(opts.depth)}`;
|
|
50
|
+
return `${text.slice(0, lastEnd)}${comma}${trivia}${separator}${opts.item}${closing}${text.slice(closePos)}`;
|
|
51
|
+
}
|
|
52
|
+
export function insertObjectEntry(text, parentNode, opts) {
|
|
53
|
+
return insertIntoContainer(text, parentNode, { item: `${JSON.stringify(opts.key)}: ${opts.formattedVal}`, indent: opts.indent, depth: opts.depth });
|
|
54
|
+
}
|
|
55
|
+
export function insertArrayItem(text, arrayNode, opts) {
|
|
56
|
+
return insertIntoContainer(text, arrayNode, { item: opts.formattedVal, indent: opts.indent, depth: opts.depth });
|
|
57
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type Node } from 'jsonc-parser';
|
|
2
|
+
export declare class InvalidJsonDocumentError extends Error {
|
|
3
|
+
readonly issue: string;
|
|
4
|
+
readonly filePath?: string | undefined;
|
|
5
|
+
constructor(issue: string, filePath?: string | undefined);
|
|
6
|
+
}
|
|
7
|
+
export declare function findDuplicateKeys(node: Node): string[];
|
|
8
|
+
export declare function validateJsonDocument(text: string): {
|
|
9
|
+
valid: boolean;
|
|
10
|
+
errors: string[];
|
|
11
|
+
duplicateKeys: string[];
|
|
12
|
+
};
|
|
13
|
+
export declare function parseAndValidateJson(text: string, filePath?: string): Node;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { parseTree, printParseErrorCode } from 'jsonc-parser';
|
|
2
|
+
export class InvalidJsonDocumentError extends Error {
|
|
3
|
+
issue;
|
|
4
|
+
filePath;
|
|
5
|
+
constructor(issue, filePath) {
|
|
6
|
+
super(filePath ? `Invalid JSON document in ${filePath}: ${issue}` : `Invalid JSON document: ${issue}`);
|
|
7
|
+
this.issue = issue;
|
|
8
|
+
this.filePath = filePath;
|
|
9
|
+
this.name = 'InvalidJsonDocumentError';
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export function findDuplicateKeys(node) {
|
|
13
|
+
const duplicates = [];
|
|
14
|
+
function walk(current) {
|
|
15
|
+
if (current.type === 'object' && current.children) {
|
|
16
|
+
const seen = new Set();
|
|
17
|
+
for (const prop of current.children) {
|
|
18
|
+
if (prop.type === 'property' && prop.children?.[0]) {
|
|
19
|
+
const key = String(prop.children[0].value);
|
|
20
|
+
if (seen.has(key)) {
|
|
21
|
+
duplicates.push(key);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
seen.add(key);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (current.children) {
|
|
30
|
+
for (const child of current.children) {
|
|
31
|
+
walk(child);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
walk(node);
|
|
36
|
+
return duplicates;
|
|
37
|
+
}
|
|
38
|
+
export function validateJsonDocument(text) {
|
|
39
|
+
const parseErrors = [];
|
|
40
|
+
const root = parseTree(text, parseErrors, { disallowComments: false });
|
|
41
|
+
const errorMessages = parseErrors.map((err) => `${printParseErrorCode(err.error)} at offset ${err.offset}`);
|
|
42
|
+
if (!root) {
|
|
43
|
+
const emptyErr = errorMessages.length > 0 ? errorMessages : ['Empty or invalid JSON document'];
|
|
44
|
+
return { valid: false, errors: emptyErr, duplicateKeys: [] };
|
|
45
|
+
}
|
|
46
|
+
const duplicates = findDuplicateKeys(root);
|
|
47
|
+
const isValid = parseErrors.length === 0 && duplicates.length === 0;
|
|
48
|
+
return { valid: isValid, errors: errorMessages, duplicateKeys: duplicates };
|
|
49
|
+
}
|
|
50
|
+
export function parseAndValidateJson(text, filePath) {
|
|
51
|
+
const result = validateJsonDocument(text);
|
|
52
|
+
if (!result.valid) {
|
|
53
|
+
const detail = result.duplicateKeys.length > 0 ? `Duplicate key: ${result.duplicateKeys.join(', ')}` : result.errors.join('; ');
|
|
54
|
+
throw new InvalidJsonDocumentError(detail, filePath);
|
|
55
|
+
}
|
|
56
|
+
const root = parseTree(text, [], { disallowComments: false });
|
|
57
|
+
if (!root) {
|
|
58
|
+
throw new InvalidJsonDocumentError('Root node not found', filePath);
|
|
59
|
+
}
|
|
60
|
+
return root;
|
|
61
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type InstallationManifest, type ManifestStore } from '../../core/contracts/manifest.js';
|
|
2
|
+
import type { FileSnapshot, PlannedChange } from '../../core/contracts/changes.js';
|
|
3
|
+
export declare class NodeManifestStore implements ManifestStore {
|
|
4
|
+
readonly projectRoot: string;
|
|
5
|
+
readonly manifestPath: string;
|
|
6
|
+
constructor(projectRoot: string);
|
|
7
|
+
load(): Promise<InstallationManifest | null>;
|
|
8
|
+
planSave(manifest: InstallationManifest, previous: InstallationManifest | null, snapshot?: FileSnapshot | null | undefined): PlannedChange;
|
|
9
|
+
save(manifest: InstallationManifest): Promise<void>;
|
|
10
|
+
delete(): Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { installationManifestSchema, MANIFEST_RELATIVE_PATH } from '../../core/contracts/manifest.js';
|
|
4
|
+
import { normalizeSeparators } from './path-boundary.js';
|
|
5
|
+
import { deleteFileIfExists, writeFileAtomically } from './atomic-writer.js';
|
|
6
|
+
export class NodeManifestStore {
|
|
7
|
+
projectRoot;
|
|
8
|
+
manifestPath;
|
|
9
|
+
constructor(projectRoot) {
|
|
10
|
+
this.projectRoot = projectRoot;
|
|
11
|
+
this.manifestPath = resolve(projectRoot, MANIFEST_RELATIVE_PATH);
|
|
12
|
+
}
|
|
13
|
+
async load() {
|
|
14
|
+
try {
|
|
15
|
+
const content = await readFile(this.manifestPath, 'utf8');
|
|
16
|
+
const parsed = JSON.parse(content);
|
|
17
|
+
return installationManifestSchema.parse(parsed);
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
if (err.code === 'ENOENT')
|
|
21
|
+
return null;
|
|
22
|
+
throw err;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
planSave(manifest, previous, snapshot) {
|
|
26
|
+
const formatted = `${JSON.stringify(manifest, null, 2)}\n`;
|
|
27
|
+
const realPath = snapshot?.realPath ?? normalizeSeparators(this.manifestPath);
|
|
28
|
+
return {
|
|
29
|
+
path: MANIFEST_RELATIVE_PATH,
|
|
30
|
+
realPath,
|
|
31
|
+
kind: previous ? 'update' : 'create',
|
|
32
|
+
owner: 'manifest',
|
|
33
|
+
content: formatted,
|
|
34
|
+
preview: { summary: 'Record installation manifest with managed assets and entries' },
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
async save(manifest) {
|
|
38
|
+
const validated = installationManifestSchema.parse(manifest);
|
|
39
|
+
const formatted = `${JSON.stringify(validated, null, 2)}\n`;
|
|
40
|
+
await writeFileAtomically(this.manifestPath, formatted);
|
|
41
|
+
}
|
|
42
|
+
async delete() {
|
|
43
|
+
await deleteFileIfExists(this.manifestPath);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { FileSnapshot } from '../../core/contracts/changes.js';
|
|
2
|
+
export declare function computeSha256(content: string): Promise<string>;
|
|
3
|
+
export declare function snapshotFile(projectRoot: string, relativePath: string): Promise<FileSnapshot>;
|
|
4
|
+
export declare function snapshotFiles(projectRoot: string, relativePaths: readonly string[]): Promise<FileSnapshot[]>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { lstat, readFile, stat } from 'node:fs/promises';
|
|
3
|
+
import { resolve } from 'node:path';
|
|
4
|
+
import { assertWithinRepository, computeFileIdentity } from './path-boundary.js';
|
|
5
|
+
export async function computeSha256(content) {
|
|
6
|
+
return createHash('sha256').update(content).digest('hex');
|
|
7
|
+
}
|
|
8
|
+
export async function snapshotFile(projectRoot, relativePath) {
|
|
9
|
+
const canonical = await assertWithinRepository(projectRoot, relativePath);
|
|
10
|
+
const fullPath = resolve(projectRoot, relativePath);
|
|
11
|
+
const linkStat = await lstat(fullPath).catch(() => null);
|
|
12
|
+
if (!linkStat) {
|
|
13
|
+
const identity = computeFileIdentity(canonical);
|
|
14
|
+
return { path: relativePath, realPath: canonical, exists: false, content: null, sha256: null, isSymlink: false, fileIdentity: identity };
|
|
15
|
+
}
|
|
16
|
+
const isSymlink = linkStat.isSymbolicLink();
|
|
17
|
+
const targetStat = await stat(fullPath).catch(() => null);
|
|
18
|
+
if (!targetStat || !targetStat.isFile()) {
|
|
19
|
+
const identity = computeFileIdentity(canonical, targetStat?.dev, targetStat?.ino);
|
|
20
|
+
return { path: relativePath, realPath: canonical, exists: targetStat !== null, content: null, sha256: null, isSymlink, fileIdentity: identity };
|
|
21
|
+
}
|
|
22
|
+
const content = await readFile(canonical, 'utf8');
|
|
23
|
+
const sha256 = await computeSha256(content);
|
|
24
|
+
const identity = computeFileIdentity(canonical, targetStat.dev, targetStat.ino);
|
|
25
|
+
return { path: relativePath, realPath: canonical, exists: true, content, sha256, isSymlink, fileIdentity: identity };
|
|
26
|
+
}
|
|
27
|
+
export async function snapshotFiles(projectRoot, relativePaths) {
|
|
28
|
+
const results = [];
|
|
29
|
+
for (const relativePath of relativePaths) {
|
|
30
|
+
results.push(await snapshotFile(projectRoot, relativePath));
|
|
31
|
+
}
|
|
32
|
+
return results;
|
|
33
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type HandoffStore } from '../../core/contracts/handoff.js';
|
|
2
|
+
import type { ClaimDeadline } from '../../core/contracts/hook-phase.js';
|
|
3
|
+
import type { Clock } from '../../core/contracts/session-ledger.js';
|
|
4
|
+
export declare class NodeHandoffStore implements HandoffStore {
|
|
5
|
+
private readonly projectRoot;
|
|
6
|
+
private readonly clock;
|
|
7
|
+
constructor(projectRoot: string, clock: Clock);
|
|
8
|
+
pendingSince(): Promise<number | null>;
|
|
9
|
+
claim(deadline?: ClaimDeadline): Promise<string | null>;
|
|
10
|
+
private claimLocked;
|
|
11
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { constants } from 'node:fs';
|
|
2
|
+
import { copyFile, mkdir, readdir, rename, rm, stat } from 'node:fs/promises';
|
|
3
|
+
import { basename, join } from 'node:path';
|
|
4
|
+
import { HANDOFF_ARCHIVE_LIMIT, HANDOFF_ARCHIVE_RELATIVE_DIR, HANDOFF_RELATIVE_PATH } from '../../core/contracts/handoff.js';
|
|
5
|
+
import { isMissingFileError } from '../runtime/runtime-paths.js';
|
|
6
|
+
import { acquireClaimLock, createExclusive } from './handoff-claim-lock.js';
|
|
7
|
+
const ARCHIVE_EXTENSION = '.md';
|
|
8
|
+
const CLAIM_LOCK_NAME = '.claim.lock';
|
|
9
|
+
const OPEN_DEADLINE = { isExpired: () => false, commit: () => true };
|
|
10
|
+
export class NodeHandoffStore {
|
|
11
|
+
projectRoot;
|
|
12
|
+
clock;
|
|
13
|
+
constructor(projectRoot, clock) {
|
|
14
|
+
this.projectRoot = projectRoot;
|
|
15
|
+
this.clock = clock;
|
|
16
|
+
}
|
|
17
|
+
async pendingSince() {
|
|
18
|
+
try {
|
|
19
|
+
return (await stat(join(this.projectRoot, HANDOFF_RELATIVE_PATH))).mtimeMs;
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
if (isMissingFileError(error))
|
|
23
|
+
return null;
|
|
24
|
+
throw error;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async claim(deadline = OPEN_DEADLINE) {
|
|
28
|
+
if ((await this.pendingSince()) === null)
|
|
29
|
+
return null;
|
|
30
|
+
const archive = join(this.projectRoot, HANDOFF_ARCHIVE_RELATIVE_DIR);
|
|
31
|
+
await mkdir(archive, { recursive: true });
|
|
32
|
+
const lock = join(archive, CLAIM_LOCK_NAME);
|
|
33
|
+
if (!(await acquireClaimLock(lock, this.clock)))
|
|
34
|
+
return null;
|
|
35
|
+
return this.claimLocked(archive, deadline).finally(() => rm(lock, { force: true }));
|
|
36
|
+
}
|
|
37
|
+
async claimLocked(archive, deadline) {
|
|
38
|
+
if ((await this.pendingSince()) === null || deadline.isExpired())
|
|
39
|
+
return null;
|
|
40
|
+
const name = await reserveName(archive, this.clock.now().toISOString().replace(/[-:]/g, ''));
|
|
41
|
+
const pending = join(this.projectRoot, HANDOFF_RELATIVE_PATH);
|
|
42
|
+
const archived = join(archive, name);
|
|
43
|
+
if (!(await moveInto(pending, archived)))
|
|
44
|
+
return null;
|
|
45
|
+
if (!deadline.commit()) {
|
|
46
|
+
await restoreHandoff(archived, pending);
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
await pruneOrRestore(archive, archived, pending);
|
|
50
|
+
return `${HANDOFF_ARCHIVE_RELATIVE_DIR}/${name}`;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async function pruneOrRestore(archive, archived, pending) {
|
|
54
|
+
try {
|
|
55
|
+
await pruneArchive(archive, basename(archived));
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
await restoreHandoff(archived, pending);
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async function reserveName(archive, stamp) {
|
|
63
|
+
for (let suffix = 0;; suffix += 1) {
|
|
64
|
+
const name = suffix === 0 ? `${stamp}${ARCHIVE_EXTENSION}` : `${stamp}-${suffix}${ARCHIVE_EXTENSION}`;
|
|
65
|
+
if (await createExclusive(join(archive, name)))
|
|
66
|
+
return name;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async function moveInto(source, reserved) {
|
|
70
|
+
try {
|
|
71
|
+
await rename(source, reserved);
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
await rm(reserved, { force: true });
|
|
76
|
+
if (isMissingFileError(error))
|
|
77
|
+
return false;
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async function restoreHandoff(archived, pending) {
|
|
82
|
+
try {
|
|
83
|
+
await copyFile(archived, pending, constants.COPYFILE_EXCL);
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
if (error.code === 'EEXIST')
|
|
87
|
+
return;
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
await rm(archived, { force: true });
|
|
91
|
+
}
|
|
92
|
+
async function pruneArchive(archive, delivered) {
|
|
93
|
+
const names = (await readdir(archive)).filter((name) => name.endsWith(ARCHIVE_EXTENSION) && name !== delivered).sort();
|
|
94
|
+
const excess = names.slice(0, Math.max(0, names.length - (HANDOFF_ARCHIVE_LIMIT - 1)));
|
|
95
|
+
await Promise.all(excess.map((name) => rm(join(archive, name), { force: true })));
|
|
96
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare class PackageMetadataError extends Error {
|
|
2
|
+
readonly issue: string;
|
|
3
|
+
constructor(issue: string);
|
|
4
|
+
}
|
|
5
|
+
export declare function packageJsonCandidates(baseDir: string): string[];
|
|
6
|
+
export declare function readPackageVersionFrom(baseDir: string): Promise<string>;
|
|
7
|
+
export declare function readPackageVersion(): Promise<string>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { dirname, resolve } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import semver from 'semver';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
const currentDir = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const PACKAGE_NAME = 'context-brake';
|
|
8
|
+
const packageJsonSchema = z.object({
|
|
9
|
+
name: z.string(),
|
|
10
|
+
version: z.string(),
|
|
11
|
+
}).passthrough();
|
|
12
|
+
export class PackageMetadataError extends Error {
|
|
13
|
+
issue;
|
|
14
|
+
constructor(issue) {
|
|
15
|
+
super(`Unable to read ${PACKAGE_NAME} package metadata: ${issue}`);
|
|
16
|
+
this.issue = issue;
|
|
17
|
+
this.name = 'PackageMetadataError';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export function packageJsonCandidates(baseDir) {
|
|
21
|
+
return [
|
|
22
|
+
resolve(baseDir, '../../../../package.json'),
|
|
23
|
+
resolve(baseDir, '../../../package.json'),
|
|
24
|
+
];
|
|
25
|
+
}
|
|
26
|
+
async function readCandidate(candidate) {
|
|
27
|
+
const raw = await readFile(candidate, 'utf8');
|
|
28
|
+
return JSON.parse(raw);
|
|
29
|
+
}
|
|
30
|
+
async function loadPackageJson(baseDir) {
|
|
31
|
+
const candidates = packageJsonCandidates(baseDir);
|
|
32
|
+
for (const candidate of candidates) {
|
|
33
|
+
try {
|
|
34
|
+
return await readCandidate(candidate);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
throw new PackageMetadataError(`no package.json found among candidate paths: ${candidates.join(', ')}`);
|
|
41
|
+
}
|
|
42
|
+
export async function readPackageVersionFrom(baseDir) {
|
|
43
|
+
const raw = await loadPackageJson(baseDir);
|
|
44
|
+
const parsed = packageJsonSchema.safeParse(raw);
|
|
45
|
+
if (!parsed.success) {
|
|
46
|
+
throw new PackageMetadataError(`package.json does not match the expected shape: ${parsed.error.message}`);
|
|
47
|
+
}
|
|
48
|
+
if (parsed.data.name !== PACKAGE_NAME) {
|
|
49
|
+
throw new PackageMetadataError(`package.json 'name' is '${parsed.data.name}', expected '${PACKAGE_NAME}'`);
|
|
50
|
+
}
|
|
51
|
+
if (!semver.valid(parsed.data.version)) {
|
|
52
|
+
throw new PackageMetadataError(`package.json 'version' is not valid semver: '${parsed.data.version}'`);
|
|
53
|
+
}
|
|
54
|
+
return parsed.data.version;
|
|
55
|
+
}
|
|
56
|
+
export function readPackageVersion() {
|
|
57
|
+
return readPackageVersionFrom(currentDir);
|
|
58
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare class RepositoryBoundaryError extends Error {
|
|
2
|
+
readonly targetPath: string;
|
|
3
|
+
readonly projectRoot: string;
|
|
4
|
+
constructor(targetPath: string, projectRoot: string);
|
|
5
|
+
}
|
|
6
|
+
export declare function normalizeSeparators(filePath: string): string;
|
|
7
|
+
export declare function arePathsEqual(pathA: string, pathB: string): boolean;
|
|
8
|
+
export declare function resolveCanonicalPath(baseDir: string, targetPath: string): Promise<string>;
|
|
9
|
+
export declare function isWithinRepository(projectRoot: string, targetPath: string): Promise<boolean>;
|
|
10
|
+
export declare function assertWithinRepository(projectRoot: string, targetPath: string): Promise<string>;
|
|
11
|
+
export declare function computeFileIdentity(canonicalPath: string, dev?: number, ino?: number): string;
|