peaks-loop 4.0.0-beta.9 → 4.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +572 -234
- package/README-en.md +67 -30
- package/README.md +67 -30
- package/agents/karpathy-reviewer.md +33 -0
- package/bin/peaks.js +0 -0
- package/dist/cli/cli-helpers.d.ts +31 -6
- package/dist/cli/cli-helpers.js +48 -25
- package/dist/cli/commands/_register.d.ts +3 -0
- package/dist/cli/commands/_register.js +139 -0
- package/dist/cli/commands/_super.d.ts +10 -0
- package/dist/cli/commands/_super.js +97 -0
- package/dist/cli/commands/adapter-commands-s2a.js +1 -1
- package/dist/cli/commands/asset-commands.js +33 -16
- package/dist/cli/commands/audit-commands.js +2 -2
- package/dist/cli/commands/autonomous-swarm-commands.d.ts +12 -0
- package/dist/cli/commands/autonomous-swarm-commands.js +120 -0
- package/dist/cli/commands/bee-commands.js +1 -1
- package/dist/cli/commands/capability-commands.js +1 -1
- package/dist/cli/commands/capability-worker-config-sc-commands.js +0 -2
- package/dist/cli/commands/changeset-commands.d.ts +13 -0
- package/dist/cli/commands/changeset-commands.js +46 -0
- package/dist/cli/commands/code-commands.d.ts +11 -1
- package/dist/cli/commands/code-commands.js +19 -699
- package/dist/cli/commands/code-job-shape-commands.d.ts +9 -0
- package/dist/cli/commands/code-job-shape-commands.js +164 -0
- package/dist/cli/commands/code-mode-gate-commands.d.ts +9 -0
- package/dist/cli/commands/code-mode-gate-commands.js +223 -0
- package/dist/cli/commands/code-review-commands.js +2 -2
- package/dist/cli/commands/code-run-command.d.ts +12 -0
- package/dist/cli/commands/code-run-command.js +68 -0
- package/dist/cli/commands/code-runtime-commands.d.ts +11 -0
- package/dist/cli/commands/code-runtime-commands.js +391 -0
- package/dist/cli/commands/codegraph-commands.js +1 -1
- package/dist/cli/commands/compact-command.js +53 -1
- package/dist/cli/commands/complexity-commands.js +1 -1
- package/dist/cli/commands/config-commands.js +4 -75
- package/dist/cli/commands/container-commands.d.ts +28 -0
- package/dist/cli/commands/container-commands.js +221 -0
- package/dist/cli/commands/context-commands.js +3 -2
- package/dist/cli/commands/core/artifacts-command.js +1 -1
- package/dist/cli/commands/core/binding-commands.js +1 -1
- package/dist/cli/commands/core/doctor-command.js +63 -3
- package/dist/cli/commands/core/memory-command.js +1 -1
- package/dist/cli/commands/core/profile-command.js +1 -1
- package/dist/cli/commands/core/proxy-command.js +1 -1
- package/dist/cli/commands/core/session-command.js +9 -7
- package/dist/cli/commands/core/skill-command.js +7 -4
- package/dist/cli/commands/core/standards-command.js +1 -1
- package/dist/cli/commands/cron-commands.d.ts +57 -0
- package/dist/cli/commands/cron-commands.js +257 -0
- package/dist/cli/commands/cron-scheduler-commands.d.ts +47 -0
- package/dist/cli/commands/cron-scheduler-commands.js +284 -0
- package/dist/cli/commands/dashboard-commands.d.ts +4 -0
- package/dist/cli/commands/dashboard-commands.js +10 -0
- package/dist/cli/commands/dashboard-long-run.d.ts +25 -0
- package/dist/cli/commands/dashboard-long-run.js +122 -0
- package/dist/cli/commands/dashboard-summary.d.ts +12 -0
- package/dist/cli/commands/dashboard-summary.js +58 -0
- package/dist/cli/commands/dispatch-commands.d.ts +0 -7
- package/dist/cli/commands/dispatch-commands.js +372 -8
- package/dist/cli/commands/dispatch-from-dag.js +4 -1
- package/dist/cli/commands/doc-commands.js +1 -1
- package/dist/cli/commands/ecc-commands.d.ts +30 -0
- package/dist/cli/commands/ecc-commands.js +119 -0
- package/dist/cli/commands/evolution-commands.js +1 -1
- package/dist/cli/commands/feedback-commands.js +1 -1
- package/dist/cli/commands/final-review-commands.js +1 -1
- package/dist/cli/commands/fixture-commands.js +1 -1
- package/dist/cli/commands/fork-commands.js +1 -1
- package/dist/cli/commands/gate-commands.js +128 -6
- package/dist/cli/commands/governance-classify-contract-commands.d.ts +21 -0
- package/dist/cli/commands/governance-classify-contract-commands.js +273 -0
- package/dist/cli/commands/heartbeat-commands.js +76 -5
- package/dist/cli/commands/heartbeat-watch-command.d.ts +31 -0
- package/dist/cli/commands/heartbeat-watch-command.js +146 -0
- package/dist/cli/commands/hook-handle.js +1 -1
- package/dist/cli/commands/hooks-commands.js +126 -10
- package/dist/cli/commands/ide-commands.js +1 -1
- package/dist/cli/commands/impact-commands.js +1 -1
- package/dist/cli/commands/job-commands.js +34 -1
- package/dist/cli/commands/lease-metrics-commands.d.ts +67 -0
- package/dist/cli/commands/lease-metrics-commands.js +231 -0
- package/dist/cli/commands/lease-stats-commands.d.ts +65 -0
- package/dist/cli/commands/lease-stats-commands.js +107 -0
- package/dist/cli/commands/legacy-commands.js +1 -1
- package/dist/cli/commands/log-commands.js +1 -1
- package/dist/cli/commands/loop-commands.js +1 -1
- package/dist/cli/commands/loop-eval-commands.js +1 -1
- package/dist/cli/commands/memory-commands.js +1 -1
- package/dist/cli/commands/migrate-1-4-1-command.js +1 -1
- package/dist/cli/commands/migrate-v2-10-to-v2-11-command.js +1 -1
- package/dist/cli/commands/mut-commands.d.ts +1 -1
- package/dist/cli/commands/mut-commands.js +1 -5
- package/dist/cli/commands/observability-commands.js +1 -1
- package/dist/cli/commands/openspec-commands.js +65 -4
- package/dist/cli/commands/perf-audit-commands.js +3 -3
- package/dist/cli/commands/perf-commands.js +1 -1
- package/dist/cli/commands/polyrepo-commands.js +1 -1
- package/dist/cli/commands/prd-blocks-commands.js +1 -1
- package/dist/cli/commands/prd-commands.js +4 -2
- package/dist/cli/commands/preferences-commands.js +23 -3
- package/dist/cli/commands/project-commands.js +1 -1
- package/dist/cli/commands/qa-business-review-commands.js +1 -1
- package/dist/cli/commands/qa-commands.d.ts +1 -1
- package/dist/cli/commands/qa-commands.js +39 -3
- package/dist/cli/commands/release-commands.d.ts +15 -0
- package/dist/cli/commands/release-commands.js +113 -21
- package/dist/cli/commands/request-commands.js +1 -1
- package/dist/cli/commands/retrospective-commands.js +1 -1
- package/dist/cli/commands/reviewer-commands.js +1 -1
- package/dist/cli/commands/role-commands.js +1 -1
- package/dist/cli/commands/runtime-commands-helpers.d.ts +7 -0
- package/dist/cli/commands/runtime-commands-helpers.js +24 -0
- package/dist/cli/commands/runtime-commands.js +1 -2
- package/dist/cli/commands/sc-commands.js +4 -2
- package/dist/cli/commands/scan-commands.js +1 -1
- package/dist/cli/commands/security-audit-commands.js +3 -3
- package/dist/cli/commands/sediment-commands.js +10 -1
- package/dist/cli/commands/session-24h-mode.d.ts +26 -0
- package/dist/cli/commands/session-24h-mode.js +196 -0
- package/dist/cli/commands/share-commands.d.ts +19 -0
- package/dist/cli/commands/share-commands.js +121 -2
- package/dist/cli/commands/skill-conformance-commands.js +1 -1
- package/dist/cli/commands/skill-loop-engineering-readiness-commands.js +1 -1
- package/dist/cli/commands/skill-search-commands.js +4 -1
- package/dist/cli/commands/slice-commands.js +1 -1
- package/dist/cli/commands/slice-integrate-commands.js +1 -1
- package/dist/cli/commands/slice-review-commands.js +1 -1
- package/dist/cli/commands/smoke-commands.js +1 -1
- package/dist/cli/commands/sop-commands.js +1 -1
- package/dist/cli/commands/spill-demo-command.d.ts +7 -0
- package/dist/cli/commands/spill-demo-command.js +29 -0
- package/dist/cli/commands/statusline-commands.d.ts +12 -0
- package/dist/cli/commands/statusline-commands.js +79 -17
- package/dist/cli/commands/sub-agent-commands.js +2 -1
- package/dist/cli/commands/sub-agent-shared.d.ts +10 -0
- package/dist/cli/commands/sub-agent-shared.js +24 -1
- package/dist/cli/commands/swarm-commands.d.ts +13 -0
- package/dist/cli/commands/swarm-commands.js +77 -0
- package/dist/cli/commands/tech-commands.d.ts +64 -0
- package/dist/cli/commands/tech-commands.js +195 -0
- package/dist/cli/commands/understand-commands.js +1 -1
- package/dist/cli/commands/upgrade-commands.d.ts +2 -0
- package/dist/cli/commands/upgrade-commands.js +40 -5
- package/dist/cli/commands/user-touchpoint-commands.js +1 -1
- package/dist/cli/commands/verdict-aggregate-command.js +1 -1
- package/dist/cli/commands/vm-commands.d.ts +31 -0
- package/dist/cli/commands/vm-commands.js +274 -0
- package/dist/cli/commands/workflow-commands.js +24 -1
- package/dist/cli/commands/workflow-plan-commands.js +1 -1
- package/dist/cli/commands/workspace/init-command.js +1 -1
- package/dist/cli/commands/workspace/migrate-command.js +1 -1
- package/dist/cli/commands/workspace/reconcile-command.js +1 -1
- package/dist/cli/commands/worktree-auth-commands.d.ts +29 -0
- package/dist/cli/commands/worktree-auth-commands.js +652 -0
- package/dist/cli/index.js +58 -13
- package/dist/cli/program.d.ts +2 -2
- package/dist/cli/program.js +86 -281
- package/dist/services/24h-mode/decider.d.ts +103 -0
- package/dist/services/24h-mode/decider.js +144 -0
- package/dist/services/24h-mode/index.d.ts +12 -0
- package/dist/services/24h-mode/index.js +12 -0
- package/dist/services/24h-mode/state.d.ts +48 -0
- package/dist/services/24h-mode/state.js +51 -0
- package/dist/services/24h-mode/store.d.ts +27 -0
- package/dist/services/24h-mode/store.js +119 -0
- package/dist/services/artifacts/artifact-prerequisites.js +1 -1
- package/dist/services/artifacts/request-artifact-service.js +1 -1
- package/dist/services/artifacts/workspace-service.js +1 -1
- package/dist/services/audit/enforcers/lint-bee-runtime-contract.d.ts +25 -0
- package/dist/services/audit/enforcers/lint-bee-runtime-contract.js +91 -0
- package/dist/services/audit/enforcers/lint-peaks-code-runtime.d.ts +16 -0
- package/dist/services/audit/enforcers/lint-peaks-code-runtime.js +31 -0
- package/dist/services/audit/enforcers/lint-peaks-skill-runtime.d.ts +23 -0
- package/dist/services/audit/enforcers/lint-peaks-skill-runtime.js +59 -0
- package/dist/services/audit/enforcers/lint-peaks-ui-sc-txt-runtime.d.ts +28 -0
- package/dist/services/audit/enforcers/lint-peaks-ui-sc-txt-runtime.js +86 -0
- package/dist/services/audit/enforcers/lint-prd-artifact-handoff.d.ts +16 -0
- package/dist/services/audit/enforcers/lint-prd-artifact-handoff.js +41 -0
- package/dist/services/audit/enforcers/lint-prd-source-snapshot.d.ts +27 -0
- package/dist/services/audit/enforcers/lint-prd-source-snapshot.js +47 -0
- package/dist/services/audit/enforcers/lint-qa-gateguard-and-runtime.d.ts +19 -0
- package/dist/services/audit/enforcers/lint-qa-gateguard-and-runtime.js +47 -0
- package/dist/services/audit/enforcers/lint-rd-handoff-coverage.d.ts +18 -0
- package/dist/services/audit/enforcers/lint-rd-handoff-coverage.js +70 -0
- package/dist/services/audit/enforcers/lint-skill-presence-mandatory.d.ts +25 -0
- package/dist/services/audit/enforcers/lint-skill-presence-mandatory.js +53 -0
- package/dist/services/audit/red-line-catalog-p2-a.d.ts +0 -6
- package/dist/services/audit/red-line-catalog-p2-a.js +230 -1
- package/dist/services/audit/static-service.d.ts +32 -25
- package/dist/services/audit/static-service.js +30 -109
- package/dist/services/audit-independent/index.d.ts +2 -0
- package/dist/services/audit-independent/index.js +2 -0
- package/dist/services/autonomous-swarm/autonomous-swarm-service.d.ts +127 -0
- package/dist/services/autonomous-swarm/autonomous-swarm-service.js +446 -0
- package/dist/services/changeset/changeset-check-service.d.ts +22 -0
- package/dist/services/changeset/changeset-check-service.js +47 -0
- package/dist/services/code/auto-compact-modes.d.ts +30 -0
- package/dist/services/code/auto-compact-modes.js +38 -0
- package/dist/services/code/auto-compact-orchestrator.d.ts +43 -5
- package/dist/services/code/auto-compact-orchestrator.js +101 -21
- package/dist/services/code/dag-orchestrator.d.ts +30 -1
- package/dist/services/code/dag-orchestrator.js +106 -1
- package/dist/services/code/status-line-renderer.d.ts +2 -0
- package/dist/services/code/status-line-renderer.js +21 -3
- package/dist/services/code-review/ocr-service.d.ts +1 -1
- package/dist/services/code-review/ocr-service.js +6 -3
- package/dist/services/compact-history/compact-history-service.d.ts +41 -0
- package/dist/services/compact-history/compact-history-service.js +62 -0
- package/dist/services/compact-statusline/compact-statusline-service.d.ts +16 -0
- package/dist/services/compact-statusline/compact-statusline-service.js +83 -0
- package/dist/services/config/config-service.d.ts +1 -12
- package/dist/services/config/config-service.js +3 -72
- package/dist/services/config/config-types.d.ts +2 -4
- package/dist/services/config/config-types.js +1 -1
- package/dist/services/container/container-lease.d.ts +67 -0
- package/dist/services/container/container-lease.js +135 -0
- package/dist/services/context/auto-compact-dispatcher.d.ts +40 -5
- package/dist/services/context/auto-compact-dispatcher.js +32 -102
- package/dist/services/context/auto-compact-reader.js +1 -1
- package/dist/services/context/auto-compact-types.d.ts +27 -2
- package/dist/services/context/auto-compact-types.js +8 -1
- package/dist/services/context/build-dispatch-system-prompt.d.ts +75 -0
- package/dist/services/context/build-dispatch-system-prompt.js +117 -0
- package/dist/services/context/collector.d.ts +2 -2
- package/dist/services/context/context-builder.d.ts +4 -4
- package/dist/services/context/context-schema.d.ts +48 -48
- package/dist/services/context/ide-detect.d.ts +4 -0
- package/dist/services/context/ide-detect.js +24 -0
- package/dist/services/context/main-session-monitor.d.ts +1 -4
- package/dist/services/context/main-session-monitor.js +1 -24
- package/dist/services/context/memory-index-reader.d.ts +8 -0
- package/dist/services/context/memory-index-reader.js +57 -0
- package/dist/services/context/memory-lru-cache.d.ts +12 -0
- package/dist/services/context/memory-lru-cache.js +60 -0
- package/dist/services/context/memory-preflight-config.d.ts +19 -0
- package/dist/services/context/memory-preflight-config.js +25 -0
- package/dist/services/context/memory-preflight-service.d.ts +19 -0
- package/dist/services/context/memory-preflight-service.js +120 -0
- package/dist/services/context/spillover-store.d.ts +23 -0
- package/dist/services/context/spillover-store.js +155 -0
- package/dist/services/context/spillover-types.d.ts +18 -0
- package/dist/services/context/spillover-types.js +1 -0
- package/dist/services/crystallization/crystallization-service.d.ts +22 -5
- package/dist/services/crystallization/crystallization-service.js +8 -14
- package/dist/services/crystallization/crystallization-types.d.ts +6 -6
- package/dist/services/crystallization/evidence-brief-builder.d.ts +1 -1
- package/dist/services/crystallization/index.d.ts +13 -0
- package/dist/services/crystallization/index.js +13 -0
- package/dist/services/dashboard/project-dashboard-service.js +2 -2
- package/dist/services/dispatch/await-batch.d.ts +70 -0
- package/dist/services/dispatch/await-batch.js +272 -0
- package/dist/services/dispatch/batch-counter.js +1 -1
- package/dist/services/dispatch/dispatch-record-writer.d.ts +126 -4
- package/dist/services/dispatch/dispatch-record-writer.js +239 -9
- package/dist/services/dispatch/slice-dag.d.ts +46 -0
- package/dist/services/dispatch/slice-dag.js +6 -0
- package/dist/services/dispatch/stage-enum.d.ts +27 -0
- package/dist/services/dispatch/stage-enum.js +48 -0
- package/dist/services/dispatch/startup-timeout.d.ts +86 -0
- package/dist/services/dispatch/startup-timeout.js +97 -0
- package/dist/services/dispatch/sub-agent-dispatcher.js +40 -89
- package/dist/services/dispatch/test-tool-detection.d.ts +25 -1
- package/dist/services/dispatch/test-tool-detection.js +80 -0
- package/dist/services/doctor/doctor-service/checks/check-id-schema.d.ts +18 -0
- package/dist/services/doctor/doctor-service/checks/check-id-schema.js +64 -0
- package/dist/services/doctor/doctor-service/checks/codegraph-capability.d.ts +14 -0
- package/dist/services/doctor/doctor-service/checks/codegraph-capability.js +69 -0
- package/dist/services/doctor/doctor-service/checks/dist-source-version.d.ts +32 -0
- package/dist/services/doctor/doctor-service/checks/dist-source-version.js +110 -0
- package/dist/services/doctor/doctor-service/checks/gateguard-conflict.d.ts +24 -0
- package/dist/services/doctor/doctor-service/checks/gateguard-conflict.js +164 -0
- package/dist/services/doctor/doctor-service/checks/l3-memory-health.d.ts +16 -0
- package/dist/services/doctor/doctor-service/checks/l3-memory-health.js +57 -0
- package/dist/services/doctor/doctor-service/checks/l3-orphan-sessions.d.ts +19 -0
- package/dist/services/doctor/doctor-service/checks/l3-orphan-sessions.js +66 -0
- package/dist/services/doctor/doctor-service/checks/schema-validity.d.ts +10 -0
- package/dist/services/doctor/doctor-service/checks/schema-validity.js +33 -0
- package/dist/services/doctor/doctor-service/checks/skill-apply-note.d.ts +20 -0
- package/dist/services/doctor/doctor-service/checks/skill-apply-note.js +85 -0
- package/dist/services/doctor/doctor-service/checks/skill-existence.d.ts +13 -0
- package/dist/services/doctor/doctor-service/checks/skill-existence.js +30 -0
- package/dist/services/doctor/doctor-service/checks/skill-name-match.d.ts +10 -0
- package/dist/services/doctor/doctor-service/checks/skill-name-match.js +25 -0
- package/dist/services/doctor/doctor-service/checks/skill-parse.d.ts +10 -0
- package/dist/services/doctor/doctor-service/checks/skill-parse.js +19 -0
- package/dist/services/doctor/doctor-service/checks/skill-presence.d.ts +21 -0
- package/dist/services/doctor/doctor-service/checks/skill-presence.js +75 -0
- package/dist/services/doctor/doctor-service/checks/skill-runbook.d.ts +14 -0
- package/dist/services/doctor/doctor-service/checks/skill-runbook.js +47 -0
- package/dist/services/doctor/doctor-service/checks/statusline-install.d.ts +14 -0
- package/dist/services/doctor/doctor-service/checks/statusline-install.js +32 -0
- package/dist/services/doctor/doctor-service/checks/statusline-runtime.d.ts +13 -0
- package/dist/services/doctor/doctor-service/checks/statusline-runtime.js +30 -0
- package/dist/services/doctor/doctor-service/checks/user-config.d.ts +11 -0
- package/dist/services/doctor/doctor-service/checks/user-config.js +27 -0
- package/dist/services/doctor/doctor-service/checks/workspace-init.d.ts +16 -0
- package/dist/services/doctor/doctor-service/checks/workspace-init.js +34 -0
- package/dist/services/doctor/doctor-service/checks/workspace-layout.d.ts +33 -0
- package/dist/services/doctor/doctor-service/checks/workspace-layout.js +180 -0
- package/dist/services/doctor/doctor-service/index.d.ts +48 -0
- package/dist/services/doctor/doctor-service/index.js +254 -0
- package/dist/services/doctor/doctor-service/plugin-registry.d.ts +41 -0
- package/dist/services/doctor/doctor-service/plugin-registry.js +77 -0
- package/dist/services/doctor/doctor-service/report/final-summary.d.ts +20 -0
- package/dist/services/doctor/doctor-service/report/final-summary.js +29 -0
- package/dist/services/doctor/doctor-service/types.d.ts +245 -0
- package/dist/services/doctor/doctor-service/types.js +15 -0
- package/dist/services/doctor/doctor-service.d.ts +15 -146
- package/dist/services/doctor/doctor-service.js +22 -926
- package/dist/services/doctor/index.d.ts +22 -0
- package/dist/services/doctor/index.js +22 -0
- package/dist/services/env/shell-probe.d.ts +71 -0
- package/dist/services/env/shell-probe.js +161 -0
- package/dist/services/evolution/evolution-types.d.ts +39 -39
- package/dist/services/final-review/final-review-service.d.ts +11 -1
- package/dist/services/final-review/index.d.ts +2 -0
- package/dist/services/final-review/index.js +1 -0
- package/dist/services/hooks/auto-compact-hook-install.d.ts +4 -5
- package/dist/services/hooks/auto-compact-hook-install.js +4 -5
- package/dist/services/hooks/worktree-authorization-gate.d.ts +205 -0
- package/dist/services/hooks/worktree-authorization-gate.js +492 -0
- package/dist/services/ide/adapters/claude-code-adapter.js +2 -2
- package/dist/services/ide/adapters/qoder-adapter.d.ts +25 -0
- package/dist/services/ide/adapters/qoder-adapter.js +57 -0
- package/dist/services/ide/adapters/tongyi-lingma-adapter.d.ts +16 -0
- package/dist/services/ide/adapters/tongyi-lingma-adapter.js +45 -0
- package/dist/services/ide/ide-registry.js +6 -0
- package/dist/services/ide/ide-types.d.ts +1 -1
- package/dist/services/job/job-types.d.ts +56 -56
- package/dist/services/job-snapshot/index.d.ts +8 -0
- package/dist/services/job-snapshot/index.js +7 -0
- package/dist/services/{job/job-resource-snapshot.d.ts → job-snapshot/snapshot.d.ts} +1 -1
- package/dist/services/job-snapshot/types.d.ts +7 -0
- package/dist/services/job-snapshot/types.js +1 -0
- package/dist/services/karpathy-cost/karpathy-cost-check-service.d.ts +67 -0
- package/dist/services/karpathy-cost/karpathy-cost-check-service.js +108 -0
- package/dist/services/log/retention.d.ts +16 -0
- package/dist/services/log/retention.js +17 -0
- package/dist/services/loop/loop-bee-relation-types.d.ts +6 -6
- package/dist/services/loop/loop-release-types.d.ts +24 -24
- package/dist/services/loop/monotonic-runner.d.ts +17 -11
- package/dist/services/loop/monotonic-runner.js +118 -79
- package/dist/services/memory/project-memory-service/index/kind-dispatch.d.ts +8 -0
- package/dist/services/memory/project-memory-service/index/kind-dispatch.js +253 -0
- package/dist/services/memory/project-memory-service/index/ranking.d.ts +6 -0
- package/dist/services/memory/project-memory-service/index/ranking.js +171 -0
- package/dist/services/memory/project-memory-service/index/search.d.ts +34 -0
- package/dist/services/memory/project-memory-service/index/search.js +194 -0
- package/dist/services/memory/project-memory-service/index.d.ts +9 -0
- package/dist/services/memory/project-memory-service/index.js +24 -0
- package/dist/services/memory/project-memory-service/parsers/frontmatter.d.ts +9 -0
- package/dist/services/memory/project-memory-service/parsers/frontmatter.js +106 -0
- package/dist/services/memory/project-memory-service/parsers/markdown-pure.d.ts +7 -0
- package/dist/services/memory/project-memory-service/parsers/markdown-pure.js +96 -0
- package/dist/services/memory/project-memory-service/store/atomic-write.d.ts +5 -0
- package/dist/services/memory/project-memory-service/store/atomic-write.js +56 -0
- package/dist/services/memory/project-memory-service/store/paths.d.ts +8 -0
- package/dist/services/memory/project-memory-service/store/paths.js +116 -0
- package/dist/services/memory/project-memory-service/types.d.ts +128 -0
- package/dist/services/memory/project-memory-service/types.js +9 -0
- package/dist/services/memory/project-memory-service.d.ts +1 -167
- package/dist/services/memory/project-memory-service.js +19 -816
- package/dist/services/migrate-skill-name/schema.d.ts +2 -2
- package/dist/services/observability/aggregation.d.ts +27 -0
- package/dist/services/observability/aggregation.js +72 -0
- package/dist/services/observability/observability-service.d.ts +73 -7
- package/dist/services/observability/observability-service.js +87 -1
- package/dist/services/openspec/artifact-boundary.d.ts +138 -0
- package/dist/services/openspec/artifact-boundary.js +150 -0
- package/dist/services/openspec/coverage-evidence-reader.d.ts +191 -0
- package/dist/services/openspec/coverage-evidence-reader.js +386 -0
- package/dist/services/openspec/openspec-archive-service.d.ts +70 -0
- package/dist/services/openspec/openspec-archive-service.js +320 -8
- package/dist/services/openspec/openspec-bridge-service.js +1 -1
- package/dist/services/openspec/openspec-init-service.js +1 -1
- package/dist/services/openspec/openspec-propose-from-doctor-service.js +1 -1
- package/dist/services/openspec/openspec-render-service.js +7 -4
- package/dist/services/openspec/openspec-scan-service.js +1 -1
- package/dist/services/openspec/openspec-validate-service.js +5 -4
- package/dist/services/preferences/preferences-service.js +10 -0
- package/dist/services/preferences/preferences-types.d.ts +13 -0
- package/dist/services/preferences/preferences-types.js +11 -0
- package/dist/services/qa/screenshot-archive-service.d.ts +51 -0
- package/dist/services/qa/screenshot-archive-service.js +134 -0
- package/dist/services/rd/rd-service.js +10 -11
- package/dist/services/rd/types.d.ts +32 -32
- package/dist/services/rd-swarm/rd-swarm-service.d.ts +60 -0
- package/dist/services/rd-swarm/rd-swarm-service.js +93 -0
- package/dist/services/recommendations/capability-seed-items.js +0 -1
- package/dist/services/recommendations/capability-seed-mappings.js +0 -1
- package/dist/services/recommendations/capability-seed-sources.js +0 -1
- package/dist/services/release/version-precheck-service.d.ts +51 -0
- package/dist/services/release/version-precheck-service.js +257 -0
- package/dist/services/scan/acceptance-coverage-service.js +1 -1
- package/dist/services/scan/archetype-service.js +1 -1
- package/dist/services/scan/existing-system-service.js +1 -1
- package/dist/services/scan/libraries-service.js +1 -1
- package/dist/services/sediment/json-schema.d.ts +40 -40
- package/dist/services/share/bundle-types.d.ts +12 -12
- package/dist/services/share/run-state-contract.d.ts +2 -2
- package/dist/services/skill/skill-search-service.d.ts +12 -7
- package/dist/services/skill/skill-search-service.js +8 -4
- package/dist/services/skillhub/migrations/001-initial.sql +71 -0
- package/dist/services/skillhub/migrations/002-loop-release.sql +32 -0
- package/dist/services/skillhub/migrations/003-loop-bee-relation.sql +35 -0
- package/dist/services/skillhub/migrations/004-loop-bee-extension.sql +65 -0
- package/dist/services/skillhub/migrations/005-evolution-evaluation.sql +81 -0
- package/dist/services/skillhub/migrations/006-crystallization-event.sql +92 -0
- package/dist/services/skills/hooks-settings-service.d.ts +75 -0
- package/dist/services/skills/hooks-settings-service.js +230 -2
- package/dist/services/skills/skill-registry.d.ts +1 -0
- package/dist/services/skills/skill-registry.js +6 -4
- package/dist/services/skills/skill-runbook-service.js +1 -1
- package/dist/services/slice/slice-check-service.js +1 -1
- package/dist/services/standards/main-session-monitor-ban-hook.d.ts +14 -0
- package/dist/services/standards/main-session-monitor-ban-hook.js +19 -0
- package/dist/services/standards/missing-standards-detector.d.ts +25 -0
- package/dist/services/standards/missing-standards-detector.js +43 -12
- package/dist/services/tech/tech-change-id-service.d.ts +82 -0
- package/dist/services/tech/tech-change-id-service.js +117 -0
- package/dist/services/understand/understand-hybrid-service.js +1 -1
- package/dist/services/understand/understand-scan-service.js +2 -2
- package/dist/services/upgrade/upgrade-service.js +4 -3
- package/dist/services/verdict/envelopes.d.ts +2 -2
- package/dist/services/verdict/envelopes.js +2 -2
- package/dist/services/verdict/verdict-aggregator.d.ts +3 -3
- package/dist/services/vm/vm-lease.d.ts +40 -0
- package/dist/services/vm/vm-lease.js +137 -0
- package/dist/services/workflow/autonomous-resume-writer.js +1 -1
- package/dist/services/workflow/pipeline-verify-gate-support.d.ts +47 -0
- package/dist/services/workflow/pipeline-verify-gate-support.js +194 -0
- package/dist/services/workflow/pipeline-verify-service.d.ts +17 -81
- package/dist/services/workflow/pipeline-verify-service.js +42 -218
- package/dist/services/workflow/pipeline-verify-types.d.ts +90 -0
- package/dist/services/workflow/pipeline-verify-types.js +10 -0
- package/dist/services/workflow/plan-reader.d.ts +1 -1
- package/dist/services/workflow/plan-reader.js +1 -1
- package/dist/services/workflow/plan-refresher.d.ts +1 -1
- package/dist/services/workflow/plan-refresher.js +1 -1
- package/dist/services/workflow/plan-trigger-detector.d.ts +1 -1
- package/dist/services/workflow/plan-trigger-detector.js +1 -1
- package/dist/services/workflow/workflow-autonomous-resume-helpers.d.ts +1 -1
- package/dist/services/workflow/workflow-autonomous-service.d.ts +2 -98
- package/dist/services/workflow/workflow-autonomous-types.d.ts +114 -0
- package/dist/services/workflow/workflow-autonomous-types.js +21 -0
- package/dist/services/workflow/workflow-router-service.js +18 -16
- package/dist/services/workflow/workflow-spec-lint.d.ts +13 -0
- package/dist/services/workflow/workflow-spec-lint.js +75 -0
- package/dist/services/workflow/workflow-spec-types.d.ts +100 -0
- package/dist/services/workflow/workflow-spec-types.js +13 -0
- package/dist/services/workflow/workflow-spec-yaml.d.ts +17 -0
- package/dist/services/workflow/workflow-spec-yaml.js +88 -0
- package/dist/services/workflow/workflow-spec.d.ts +11 -91
- package/dist/services/workflow/workflow-spec.js +16 -145
- package/dist/services/workspace/migrate-service.js +1 -1
- package/dist/services/workspace/workspace-service.js +1 -1
- package/dist/services/worktree/worktree-lease.d.ts +170 -0
- package/dist/services/worktree/worktree-lease.js +242 -0
- package/package.json +91 -51
- package/scripts/clean-dist.mjs +31 -1
- package/scripts/copy-templates.mjs +16 -0
- package/scripts/sync-version.mjs +53 -2
- package/skills/bee/peaks-perf-audit/SKILL.md +17 -0
- package/skills/bee/peaks-prd/SKILL.md +16 -0
- package/skills/bee/peaks-prd/test-prompts.json +12 -0
- package/skills/bee/peaks-qa/SKILL.md +16 -1
- package/skills/bee/peaks-qa/references/qa-sub-agent-dispatch.md +22 -0
- package/skills/bee/peaks-qa/test-prompts.json +12 -0
- package/skills/bee/peaks-rd/SKILL.md +29 -20
- package/skills/bee/peaks-rd/references/rd-sub-agent-dispatch.md +39 -0
- package/skills/bee/peaks-rd/test-prompts.json +12 -0
- package/skills/bee/peaks-reviewer/SKILL.md +17 -0
- package/skills/bee/peaks-sc/SKILL.md +16 -0
- package/skills/bee/peaks-security-audit/SKILL.md +17 -0
- package/skills/bee/peaks-txt/SKILL.md +16 -0
- package/skills/bee/peaks-txt/test-prompts.json +12 -0
- package/skills/bee/peaks-ui/SKILL.md +49 -43
- package/skills/bee/peaks-ui/test-prompts.json +12 -0
- package/skills/peaks-code/SKILL.md +54 -109
- package/skills/peaks-code/references/boundaries.md +15 -1
- package/skills/peaks-code/references/cron-scheduler-deployment.md +313 -0
- package/skills/peaks-code/references/external-skill-invocation.md +27 -0
- package/skills/peaks-code/references/lease-dashboard.html +224 -0
- package/skills/peaks-code/references/lease-stats.sample.json +26 -0
- package/skills/peaks-code/references/peaks-worktree-l2-enforcers.md +208 -0
- package/skills/peaks-code/references/periodic-checkpoint.md +4 -4
- package/skills/peaks-code/references/runbook.md +63 -1
- package/skills/peaks-code/references/startup-sequence.md +110 -0
- package/skills/peaks-code/references/step-0-8-gate.md +1 -1
- package/skills/peaks-code/references/sub-agent-dispatch.md +92 -1
- package/skills/peaks-code/references/worktree-governance.md +123 -0
- package/skills/peaks-code/test-prompts.json +12 -0
- package/skills/peaks-doctor/SKILL.md +1 -1
- package/skills/peaks-ide/SKILL.md +1 -1
- package/skills/peaks-solo/SKILL.md +21 -0
- package/skills/peaks-solo/references/triage-decision-table.md +6 -0
- package/skills/peaks-sop/test-prompts.json +17 -0
- package/dist/cli/commands/agent-commands.d.ts +0 -20
- package/dist/cli/commands/agent-commands.js +0 -48
- package/dist/cli/commands/classify-classify-commands.d.ts +0 -19
- package/dist/cli/commands/classify-classify-commands.js +0 -151
- package/dist/cli/commands/contract-commands.d.ts +0 -26
- package/dist/cli/commands/contract-commands.js +0 -114
- package/dist/cli/commands/session-auto-compact-hook-command.d.ts +0 -37
- package/dist/cli/commands/session-auto-compact-hook-command.js +0 -127
- package/dist/cli/commands/worker-commands.d.ts +0 -3
- package/dist/cli/commands/worker-commands.js +0 -52
- package/dist/services/agent/ecc-agent-service.d.ts +0 -47
- package/dist/services/agent/ecc-agent-service.js +0 -143
- package/dist/services/config/provider-service.d.ts +0 -48
- package/dist/services/config/provider-service.js +0 -143
- package/dist/services/context/dispatch-context-guard.d.ts +0 -27
- package/dist/services/context/dispatch-context-guard.js +0 -192
- package/dist/services/context/shared-channel.d.ts +0 -93
- package/dist/services/context/shared-channel.js +0 -308
- package/dist/services/filesystem/file-lock.d.ts +0 -11
- package/dist/services/filesystem/file-lock.js +0 -152
- package/dist/services/mut/assert-scanner.d.ts +0 -6
- package/dist/services/mut/assert-scanner.js +0 -116
- package/dist/services/mut/index.d.ts +0 -8
- package/dist/services/mut/index.js +0 -7
- package/dist/services/mut/mut-runner.d.ts +0 -39
- package/dist/services/mut/mut-runner.js +0 -29
- package/dist/services/mut/production-stryker.d.ts +0 -2
- package/dist/services/mut/production-stryker.js +0 -75
- package/dist/services/mut/report-builder.d.ts +0 -11
- package/dist/services/mut/report-builder.js +0 -110
- package/dist/services/mut/report-loader.d.ts +0 -31
- package/dist/services/mut/report-loader.js +0 -78
- package/dist/services/mut/thresholds.d.ts +0 -21
- package/dist/services/mut/thresholds.js +0 -22
- package/dist/services/mut/types.d.ts +0 -336
- package/dist/services/mut/types.js +0 -59
- package/dist/services/providers/minimax-provider-service.d.ts +0 -24
- package/dist/services/providers/minimax-provider-service.js +0 -143
- package/dist/services/providers/minimax-worker-service.d.ts +0 -21
- package/dist/services/providers/minimax-worker-service.js +0 -83
- package/dist/shared/fs.d.ts +0 -4
- package/dist/shared/fs.js +0 -26
- package/dist/shared/paths.d.ts +0 -6
- package/dist/shared/paths.js +0 -50
- package/dist/shared/result.d.ts +0 -22
- package/dist/shared/result.js +0 -46
- package/dist/shared/version.d.ts +0 -1
- package/dist/shared/version.js +0 -1
- package/examples/video-demo/README.md +0 -142
- package/examples/video-demo/out/en-closing-960.png +0 -0
- package/examples/video-demo/out/zh-closing-960.png +0 -0
- package/examples/video-demo/preview/peaks-loop-demo-en.mp4 +0 -0
- package/examples/video-demo/preview/peaks-loop-demo.mp4 +0 -0
- /package/dist/services/{job/job-resource-snapshot.js → job-snapshot/snapshot.js} +0 -0
|
@@ -19,8 +19,16 @@
|
|
|
19
19
|
* pair. Anything more elaborate (e.g. conditionals on outputs) belongs
|
|
20
20
|
* in a future minor.
|
|
21
21
|
*
|
|
22
|
-
* File budget: ≤
|
|
22
|
+
* File budget: ≤ 400 lines (rid-006 split). This file now holds the
|
|
23
|
+
* parser + private constants + private build helpers; types live in
|
|
24
|
+
* `workflow-spec-types.ts`; YAML field helpers live in
|
|
25
|
+
* `workflow-spec-yaml.ts`; lint lives in `workflow-spec-lint.ts`.
|
|
26
|
+
* The re-export shim at the bottom preserves the original public
|
|
27
|
+
* surface so external callers (`workflow-loader.ts`,
|
|
28
|
+
* `loop-eval-commands.ts`, `evaluator-dispatcher.ts`) compile
|
|
29
|
+
* unchanged.
|
|
23
30
|
*/
|
|
31
|
+
import { arrayField, leadingSpaces, numberField, objectField, parseScalar, stringArrayField, stringField } from './workflow-spec-yaml.js';
|
|
24
32
|
const VALID_EVALUATORS = new Set([
|
|
25
33
|
'karpathy',
|
|
26
34
|
'code-review',
|
|
@@ -285,147 +293,10 @@ function buildEvaluator(raw) {
|
|
|
285
293
|
...(threshold !== undefined ? { threshold } : {})
|
|
286
294
|
};
|
|
287
295
|
}
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
if (seen.has(phase.id))
|
|
296
|
-
errors.push(`duplicate phase id "${phase.id}"`);
|
|
297
|
-
seen.add(phase.id);
|
|
298
|
-
}
|
|
299
|
-
// Gate references in phases must exist in the gates list (or be a known
|
|
300
|
-
// built-in like "Gate B3").
|
|
301
|
-
const gateIds = new Set(spec.gates.map((g) => g.id));
|
|
302
|
-
for (const phase of spec.phases) {
|
|
303
|
-
for (const gateRef of phase.gates) {
|
|
304
|
-
if (!gateIds.has(gateRef) && !gateRef.startsWith('Gate ')) {
|
|
305
|
-
warnings.push(`phase "${phase.id}" references unknown gate "${gateRef}" (not in gates[] and not a built-in "Gate …" label)`);
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
// Evaluator gates must match a gate id when present.
|
|
310
|
-
for (const ev of spec.evaluators) {
|
|
311
|
-
if (ev.gate !== undefined && !gateIds.has(ev.gate) && !ev.gate.startsWith('Gate ')) {
|
|
312
|
-
warnings.push(`evaluator "${ev.type}" references unknown gate "${ev.gate}"`);
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
// dependsOn references must resolve.
|
|
316
|
-
const phaseIds = new Set(spec.phases.map((p) => p.id));
|
|
317
|
-
for (const phase of spec.phases) {
|
|
318
|
-
if (phase.dependsOn !== undefined) {
|
|
319
|
-
for (const dep of phase.dependsOn) {
|
|
320
|
-
if (!phaseIds.has(dep))
|
|
321
|
-
errors.push(`phase "${phase.id}" depends on missing phase "${dep}"`);
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
// Parallel groups must contain ≥2 phases.
|
|
326
|
-
const groupCounts = new Map();
|
|
327
|
-
for (const phase of spec.phases) {
|
|
328
|
-
if (phase.parallelGroup !== undefined) {
|
|
329
|
-
groupCounts.set(phase.parallelGroup, (groupCounts.get(phase.parallelGroup) ?? 0) + 1);
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
for (const [group, count] of groupCounts) {
|
|
333
|
-
if (count < 2)
|
|
334
|
-
warnings.push(`parallelGroup "${group}" has only ${count} phase(s); parallelism requires ≥2`);
|
|
335
|
-
}
|
|
336
|
-
// Budget sanity.
|
|
337
|
-
if (spec.budget.cycles !== undefined && spec.budget.cycles < 1) {
|
|
338
|
-
errors.push(`budget.cycles must be ≥1 when set (got ${spec.budget.cycles})`);
|
|
339
|
-
}
|
|
340
|
-
if (spec.budget.tokens !== undefined && spec.budget.tokens < 1) {
|
|
341
|
-
errors.push(`budget.tokens must be ≥1 when set (got ${spec.budget.tokens})`);
|
|
342
|
-
}
|
|
343
|
-
if (spec.budget.wallSeconds !== undefined && spec.budget.wallSeconds < 1) {
|
|
344
|
-
errors.push(`budget.wallSeconds must be ≥1 when set (got ${spec.budget.wallSeconds})`);
|
|
345
|
-
}
|
|
346
|
-
return {
|
|
347
|
-
ok: errors.length === 0,
|
|
348
|
-
errors,
|
|
349
|
-
warnings,
|
|
350
|
-
normalizedSpec: spec
|
|
351
|
-
};
|
|
352
|
-
}
|
|
353
|
-
// ─── yaml helper primitives ─────────────────────────────────────────────
|
|
354
|
-
function leadingSpaces(line) {
|
|
355
|
-
let n = 0;
|
|
356
|
-
for (const ch of line) {
|
|
357
|
-
if (ch === ' ')
|
|
358
|
-
n++;
|
|
359
|
-
else
|
|
360
|
-
break;
|
|
361
|
-
}
|
|
362
|
-
return n;
|
|
363
|
-
}
|
|
364
|
-
function parseScalar(raw) {
|
|
365
|
-
if (raw === '')
|
|
366
|
-
return '';
|
|
367
|
-
if (raw === 'true')
|
|
368
|
-
return true;
|
|
369
|
-
if (raw === 'false')
|
|
370
|
-
return false;
|
|
371
|
-
if (raw === 'null' || raw === '~')
|
|
372
|
-
return null;
|
|
373
|
-
// Inline array form `[a, b, c]`
|
|
374
|
-
if (raw.startsWith('[') && raw.endsWith(']')) {
|
|
375
|
-
const inner = raw.slice(1, -1).trim();
|
|
376
|
-
if (inner === '')
|
|
377
|
-
return [];
|
|
378
|
-
return inner.split(',').map((s) => parseScalar(s.trim()));
|
|
379
|
-
}
|
|
380
|
-
// Strip optional surrounding quotes.
|
|
381
|
-
if ((raw.startsWith('"') && raw.endsWith('"')) || (raw.startsWith("'") && raw.endsWith("'"))) {
|
|
382
|
-
return raw.slice(1, -1);
|
|
383
|
-
}
|
|
384
|
-
// Number?
|
|
385
|
-
if (/^-?\d+$/.test(raw))
|
|
386
|
-
return parseInt(raw, 10);
|
|
387
|
-
if (/^-?\d+\.\d+$/.test(raw))
|
|
388
|
-
return parseFloat(raw);
|
|
389
|
-
return raw;
|
|
390
|
-
}
|
|
391
|
-
function stringField(obj, key, fallback) {
|
|
392
|
-
const v = obj[key];
|
|
393
|
-
if (typeof v === 'string')
|
|
394
|
-
return v;
|
|
395
|
-
if (fallback !== undefined)
|
|
396
|
-
return fallback;
|
|
397
|
-
throw new Error(`workflow yaml: missing required string field "${key}"`);
|
|
398
|
-
}
|
|
399
|
-
function numberField(obj, key, fallback) {
|
|
400
|
-
const v = obj[key];
|
|
401
|
-
if (typeof v === 'number' && Number.isFinite(v))
|
|
402
|
-
return v;
|
|
403
|
-
if (fallback !== undefined)
|
|
404
|
-
return fallback;
|
|
405
|
-
throw new Error(`workflow yaml: missing required number field "${key}"`);
|
|
406
|
-
}
|
|
407
|
-
function arrayField(obj, key) {
|
|
408
|
-
const v = obj[key];
|
|
409
|
-
if (v === undefined)
|
|
410
|
-
return [];
|
|
411
|
-
if (!Array.isArray(v))
|
|
412
|
-
throw new Error(`workflow yaml: field "${key}" must be an array`);
|
|
413
|
-
return v;
|
|
414
|
-
}
|
|
415
|
-
function objectField(obj, key) {
|
|
416
|
-
const v = obj[key];
|
|
417
|
-
if (v === undefined)
|
|
418
|
-
return {};
|
|
419
|
-
if (v === null || typeof v !== 'object' || Array.isArray(v)) {
|
|
420
|
-
throw new Error(`workflow yaml: field "${key}" must be an object`);
|
|
421
|
-
}
|
|
422
|
-
return v;
|
|
423
|
-
}
|
|
424
|
-
function stringArrayField(obj, key) {
|
|
425
|
-
const v = obj[key];
|
|
426
|
-
if (v === undefined)
|
|
427
|
-
return [];
|
|
428
|
-
if (!Array.isArray(v))
|
|
429
|
-
throw new Error(`workflow yaml: field "${key}" must be an array of strings`);
|
|
430
|
-
return v.map((s) => String(s));
|
|
431
|
-
}
|
|
296
|
+
// ─── verbatim re-export shim (rid-006) ────────────────────────────────────
|
|
297
|
+
// External callers (`workflow-loader.ts`, `loop-eval-commands.ts`,
|
|
298
|
+
// `evaluator-dispatcher.ts`) import the public types and the lint
|
|
299
|
+
// function from this module. Re-export them under their original names
|
|
300
|
+
// so the call sites compile unchanged. The lint function moved to
|
|
301
|
+
// `workflow-spec-lint.ts`; the types moved to `workflow-spec-types.ts`.
|
|
302
|
+
export { lintWorkflowSpec } from './workflow-spec-lint.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { execFileSync } from 'node:child_process';
|
|
2
2
|
import { mkdir, readFile, readdir, rename, rm } from 'node:fs/promises';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
|
-
import { isDirectory, pathExists } from '
|
|
4
|
+
import { isDirectory, pathExists } from 'peaks-loop-shared/fs';
|
|
5
5
|
import { isPathInsideArtifactRoot } from '../../shared/path-safety.js';
|
|
6
6
|
const ROLE_DIRS = new Set(['prd', 'ui', 'rd', 'qa', 'sc', 'system']);
|
|
7
7
|
/** Top-level dirs in `.peaks/` that are NEVER legacy session dirs
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { mkdir } from 'node:fs/promises';
|
|
2
2
|
import { existsSync, lstatSync, readdirSync } from 'node:fs';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
|
-
import { isDirectory } from '
|
|
4
|
+
import { isDirectory } from 'peaks-loop-shared/fs';
|
|
5
5
|
import { getSessionId, setCurrentSessionBinding, setSessionMeta } from '../session/session-manager.js';
|
|
6
6
|
/**
|
|
7
7
|
* Slice 2026-06-29-change-id-root-removal: list the immediate children of
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* worktree-lease — pure-function lease store for `peaks worktree spawn`.
|
|
3
|
+
*
|
|
4
|
+
* Slice 2026-07-29-worktree-l2-extended Part 1. This is the Layer 2
|
|
5
|
+
* governance complement to Layer 3 (`permissions.deny` for the superpowers
|
|
6
|
+
* chain) and Layer 1 (sub-agent dispatch prompt refusal). Together the
|
|
7
|
+
* three layers close the superpowers-chain jailbreak that previously
|
|
8
|
+
* bypassed peaks-loop's worktree posture.
|
|
9
|
+
*
|
|
10
|
+
* The store is a pure function module: every helper takes the lease
|
|
11
|
+
* directory path as an argument and returns structured data. Atomic
|
|
12
|
+
* filesystem writes happen at the call site (CLI command), keeping the
|
|
13
|
+
* helpers trivially testable. The CLI surface lives in
|
|
14
|
+
* `src/cli/commands/worktree-spawn-commands.ts`.
|
|
15
|
+
*
|
|
16
|
+
* Why a separate lease (vs reusing `peaks worktree auth grant`):
|
|
17
|
+
* - `auth grant` is a single-shot, short-lived token file consulted by
|
|
18
|
+
* the PreToolUse hook BEFORE `git worktree add` runs. It answers
|
|
19
|
+
* "is the LLM allowed to do this right now?"
|
|
20
|
+
* - `lease` is a long-lived lifecycle object that owns the worktree
|
|
21
|
+
* path, branch, expiry, and consumption log. It answers
|
|
22
|
+
* "what worktrees does this session own, and which are still alive?"
|
|
23
|
+
* The two coexist: `spawn` writes a lease; the lease's existence
|
|
24
|
+
* implicitly authorizes worktree operations on its path (the hook
|
|
25
|
+
* integration is Part 2 of this slice).
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* Per-role default TTL. Sub-agent dispatch duration varies by role:
|
|
29
|
+
* - rd (long planning + impl) → 30 min
|
|
30
|
+
* - qa (test design + browser validation) → 15 min
|
|
31
|
+
* - ui (high-fidelity prototype iteration) → 1 h
|
|
32
|
+
* - txt (handoff capsule, no worktree expected) → n/a (no worktree)
|
|
33
|
+
* - general-purpose / unknown → 30 min (rd-like)
|
|
34
|
+
*
|
|
35
|
+
* Users MAY override with `--ttl <duration>` (e.g. `--ttl 4h`).
|
|
36
|
+
*/
|
|
37
|
+
export declare const DEFAULT_TTL_BY_ROLE: Readonly<Record<string, number>>;
|
|
38
|
+
export declare const DEFAULT_TTL_MS: number | undefined;
|
|
39
|
+
export type WorktreeLeaseStatus = 'active' | 'released' | 'expired' | 'gc';
|
|
40
|
+
export interface WorktreeLease {
|
|
41
|
+
/** Random 16-hex lease id; emitted to the operator as the lease handle. */
|
|
42
|
+
readonly leaseId: string;
|
|
43
|
+
/** The peaks request id (rid) that the lease was spawned for. */
|
|
44
|
+
readonly rid: string;
|
|
45
|
+
/** Sub-agent role (rd | qa | ui | sc | prd | general-purpose | ...). */
|
|
46
|
+
readonly role: string;
|
|
47
|
+
/** Absolute worktree path on disk (under .peaks/_runtime/<sid>/worktrees/<leaseId>/). */
|
|
48
|
+
readonly path: string;
|
|
49
|
+
/** Branch name (one of the worktree's --branch / -b args). */
|
|
50
|
+
readonly branch: string;
|
|
51
|
+
/** Unix epoch ms when the lease was created. */
|
|
52
|
+
readonly createdAt: number;
|
|
53
|
+
/** Unix epoch ms when the lease expires. */
|
|
54
|
+
readonly expiresAt: number;
|
|
55
|
+
/** Operator-supplied purpose text (audit log). */
|
|
56
|
+
readonly purpose: string;
|
|
57
|
+
/** Lifecycle status; updated by `releaseLease` / `markExpired`. */
|
|
58
|
+
readonly status: WorktreeLeaseStatus;
|
|
59
|
+
/** Sub-agent batch / dispatch ids that have consumed this lease. */
|
|
60
|
+
readonly consumedBySubAgents: ReadonlyArray<string>;
|
|
61
|
+
}
|
|
62
|
+
/** Subset of WorktreeLease that the CLI writes on creation. Status starts at 'active'. */
|
|
63
|
+
export type WorktreeLeaseDraft = Omit<WorktreeLease, 'status' | 'consumedBySubAgents'>;
|
|
64
|
+
/**
|
|
65
|
+
* Compose a deterministic lease path under the per-session runtime dir.
|
|
66
|
+
* The function is pure: same inputs → same output. The caller passes
|
|
67
|
+
* `<sessionId>` (NOT a bare `<sid>` per the 2.7.1 single-scope-axis rule).
|
|
68
|
+
*
|
|
69
|
+
* Path layout:
|
|
70
|
+
* .peaks/_runtime/<sessionId>/worktree-leases/<leaseId>.json
|
|
71
|
+
*
|
|
72
|
+
* The `worktree-leases/` directory is gitignored per the .peaks/_runtime/
|
|
73
|
+
* rule (committed in .gitignore for all runtime artifacts).
|
|
74
|
+
*/
|
|
75
|
+
export declare function leaseStoreDir(sessionRuntimeDir: string): string;
|
|
76
|
+
export declare function leaseFilePath(sessionRuntimeDir: string, leaseId: string): string;
|
|
77
|
+
/**
|
|
78
|
+
* Compose the absolute worktree path (the `git worktree add <path>` target).
|
|
79
|
+
* Sits adjacent to the lease file under the same runtime dir.
|
|
80
|
+
*/
|
|
81
|
+
export declare function worktreePath(sessionRuntimeDir: string, leaseId: string): string;
|
|
82
|
+
/**
|
|
83
|
+
* Generate a 16-hex lease id (8 random bytes, hex-encoded). The id is
|
|
84
|
+
* unique enough for the per-session scope; collisions across sessions
|
|
85
|
+
* are irrelevant because each session has its own lease directory.
|
|
86
|
+
*/
|
|
87
|
+
export declare function generateLeaseId(): string;
|
|
88
|
+
/**
|
|
89
|
+
* Compute the TTL ms for a role, falling back to DEFAULT_TTL_MS for
|
|
90
|
+
* unknown roles. The CLI overrides with `--ttl <ms>` when the user
|
|
91
|
+
* passes a positive value.
|
|
92
|
+
*/
|
|
93
|
+
export declare function ttlForRole(role: string): number;
|
|
94
|
+
/**
|
|
95
|
+
* Pure: produce a fresh `WorktreeLease` from a draft + status.
|
|
96
|
+
* `status` defaults to `'active'`; `consumedBySubAgents` defaults to [].
|
|
97
|
+
* Used by the CLI's atomicWriteJson call.
|
|
98
|
+
*/
|
|
99
|
+
export declare function finalizeLease(draft: WorktreeLeaseDraft): WorktreeLease;
|
|
100
|
+
/** Pure: lease status transitions to 'released'. Returns a new lease. */
|
|
101
|
+
export declare function markReleased(lease: WorktreeLease): WorktreeLease;
|
|
102
|
+
/** Pure: lease status transitions to 'expired'. Returns a new lease. */
|
|
103
|
+
export declare function markExpired(lease: WorktreeLease): WorktreeLease;
|
|
104
|
+
/** Pure: lease status transitions to 'gc'. Returns a new lease. */
|
|
105
|
+
export declare function markGc(lease: WorktreeLease): WorktreeLease;
|
|
106
|
+
/** Pure: append a sub-agent batch / dispatch id to the consumption log. Returns a new lease. */
|
|
107
|
+
export declare function recordConsumption(lease: WorktreeLease, subAgentId: string): WorktreeLease;
|
|
108
|
+
/**
|
|
109
|
+
* Pure: is the lease still active (status === 'active' AND not past expiry).
|
|
110
|
+
* Expired leases are NOT auto-released; the gc CLI is the only path that
|
|
111
|
+
* transitions them to 'gc'. Until then, the on-disk state stays 'active'
|
|
112
|
+
* but `isLeaseActive` returns false so consumers skip the lease.
|
|
113
|
+
*/
|
|
114
|
+
export declare function isLeaseActive(lease: WorktreeLease, now?: number): boolean;
|
|
115
|
+
/**
|
|
116
|
+
* Pure: read every lease file under the session's lease store dir.
|
|
117
|
+
* Returns leases in the order returned by `fs.readdir` (no sort).
|
|
118
|
+
* Malformed files are surfaced as `{ file, error }` records so the caller
|
|
119
|
+
* (the `list` CLI) can warn without aborting the whole list. Missing
|
|
120
|
+
* directory is not an error — it returns an empty leases array.
|
|
121
|
+
*/
|
|
122
|
+
export interface LeaseReadError {
|
|
123
|
+
readonly file: string;
|
|
124
|
+
readonly error: string;
|
|
125
|
+
}
|
|
126
|
+
export type LeaseListResult = {
|
|
127
|
+
readonly kind: 'ok';
|
|
128
|
+
readonly leases: ReadonlyArray<WorktreeLease>;
|
|
129
|
+
readonly errors: ReadonlyArray<LeaseReadError>;
|
|
130
|
+
} | {
|
|
131
|
+
readonly kind: 'store-missing';
|
|
132
|
+
readonly storeDir: string;
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* List every lease file under the session's lease store dir.
|
|
136
|
+
*
|
|
137
|
+
* Pure with respect to its inputs: it does NOT sort or filter, and it
|
|
138
|
+
* does NOT mark anything expired. Callers (the `list` CLI) apply their
|
|
139
|
+
* own sort/filter and run `markExpired` lazily.
|
|
140
|
+
*/
|
|
141
|
+
export declare function listLeasesSync(storeDir: string, fs: {
|
|
142
|
+
readdir: (path: string) => ReadonlyArray<string>;
|
|
143
|
+
readFile: (path: string) => string;
|
|
144
|
+
existsSync: (path: string) => boolean;
|
|
145
|
+
}): LeaseListResult;
|
|
146
|
+
/**
|
|
147
|
+
* Pure: a lease is eligible for `gc` if its status is one of {released,
|
|
148
|
+
* expired} AND its worktree path is no longer attached to git (`git
|
|
149
|
+
* worktree list` would not include it). The CLI re-checks with git and
|
|
150
|
+
* uses this helper as a coarse pre-filter.
|
|
151
|
+
*/
|
|
152
|
+
export declare function isLeaseGcEligible(lease: WorktreeLease, now?: number): boolean;
|
|
153
|
+
/**
|
|
154
|
+
* Pure: derive a new lease from an existing one with an extended
|
|
155
|
+
* `expiresAt`. Other fields are preserved. The CLI writes the new lease
|
|
156
|
+
* atomically. Used by `peaks worktree renew --lease-id <id> --ttl <ms>`.
|
|
157
|
+
*/
|
|
158
|
+
export declare function renewLease(lease: WorktreeLease, newExpiresAt: number): WorktreeLease;
|
|
159
|
+
/**
|
|
160
|
+
* Pure: serialize a lease to JSON with stable field order (deterministic
|
|
161
|
+
* output for diff-friendly audit logs). The CLI passes the result to
|
|
162
|
+
* `atomicWriteJson`. The function does NOT mutate the input.
|
|
163
|
+
*/
|
|
164
|
+
export declare function serializeLease(lease: WorktreeLease): string;
|
|
165
|
+
/**
|
|
166
|
+
* Pure: deserialize a lease from JSON. Throws on malformed input — the
|
|
167
|
+
* CLI catches and returns a `LEASE_FILE_INVALID` envelope (mirroring the
|
|
168
|
+
* `peaks worktree auth` FILE_INVALID convention).
|
|
169
|
+
*/
|
|
170
|
+
export declare function deserializeLease(raw: string): WorktreeLease;
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* worktree-lease — pure-function lease store for `peaks worktree spawn`.
|
|
3
|
+
*
|
|
4
|
+
* Slice 2026-07-29-worktree-l2-extended Part 1. This is the Layer 2
|
|
5
|
+
* governance complement to Layer 3 (`permissions.deny` for the superpowers
|
|
6
|
+
* chain) and Layer 1 (sub-agent dispatch prompt refusal). Together the
|
|
7
|
+
* three layers close the superpowers-chain jailbreak that previously
|
|
8
|
+
* bypassed peaks-loop's worktree posture.
|
|
9
|
+
*
|
|
10
|
+
* The store is a pure function module: every helper takes the lease
|
|
11
|
+
* directory path as an argument and returns structured data. Atomic
|
|
12
|
+
* filesystem writes happen at the call site (CLI command), keeping the
|
|
13
|
+
* helpers trivially testable. The CLI surface lives in
|
|
14
|
+
* `src/cli/commands/worktree-spawn-commands.ts`.
|
|
15
|
+
*
|
|
16
|
+
* Why a separate lease (vs reusing `peaks worktree auth grant`):
|
|
17
|
+
* - `auth grant` is a single-shot, short-lived token file consulted by
|
|
18
|
+
* the PreToolUse hook BEFORE `git worktree add` runs. It answers
|
|
19
|
+
* "is the LLM allowed to do this right now?"
|
|
20
|
+
* - `lease` is a long-lived lifecycle object that owns the worktree
|
|
21
|
+
* path, branch, expiry, and consumption log. It answers
|
|
22
|
+
* "what worktrees does this session own, and which are still alive?"
|
|
23
|
+
* The two coexist: `spawn` writes a lease; the lease's existence
|
|
24
|
+
* implicitly authorizes worktree operations on its path (the hook
|
|
25
|
+
* integration is Part 2 of this slice).
|
|
26
|
+
*/
|
|
27
|
+
import { randomBytes } from 'node:crypto';
|
|
28
|
+
import { posix as path } from 'node:path';
|
|
29
|
+
/**
|
|
30
|
+
* Per-role default TTL. Sub-agent dispatch duration varies by role:
|
|
31
|
+
* - rd (long planning + impl) → 30 min
|
|
32
|
+
* - qa (test design + browser validation) → 15 min
|
|
33
|
+
* - ui (high-fidelity prototype iteration) → 1 h
|
|
34
|
+
* - txt (handoff capsule, no worktree expected) → n/a (no worktree)
|
|
35
|
+
* - general-purpose / unknown → 30 min (rd-like)
|
|
36
|
+
*
|
|
37
|
+
* Users MAY override with `--ttl <duration>` (e.g. `--ttl 4h`).
|
|
38
|
+
*/
|
|
39
|
+
export const DEFAULT_TTL_BY_ROLE = Object.freeze({
|
|
40
|
+
rd: 30 * 60 * 1_000,
|
|
41
|
+
qa: 15 * 60 * 1_000,
|
|
42
|
+
ui: 60 * 60 * 1_000,
|
|
43
|
+
sc: 30 * 60 * 1_000,
|
|
44
|
+
prd: 15 * 60 * 1_000,
|
|
45
|
+
general: 30 * 60 * 1_000
|
|
46
|
+
});
|
|
47
|
+
export const DEFAULT_TTL_MS = DEFAULT_TTL_BY_ROLE.rd;
|
|
48
|
+
/**
|
|
49
|
+
* Compose a deterministic lease path under the per-session runtime dir.
|
|
50
|
+
* The function is pure: same inputs → same output. The caller passes
|
|
51
|
+
* `<sessionId>` (NOT a bare `<sid>` per the 2.7.1 single-scope-axis rule).
|
|
52
|
+
*
|
|
53
|
+
* Path layout:
|
|
54
|
+
* .peaks/_runtime/<sessionId>/worktree-leases/<leaseId>.json
|
|
55
|
+
*
|
|
56
|
+
* The `worktree-leases/` directory is gitignored per the .peaks/_runtime/
|
|
57
|
+
* rule (committed in .gitignore for all runtime artifacts).
|
|
58
|
+
*/
|
|
59
|
+
export function leaseStoreDir(sessionRuntimeDir) {
|
|
60
|
+
return joinPath(sessionRuntimeDir, 'worktree-leases');
|
|
61
|
+
}
|
|
62
|
+
export function leaseFilePath(sessionRuntimeDir, leaseId) {
|
|
63
|
+
return joinPath(leaseStoreDir(sessionRuntimeDir), `${leaseId}.json`);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Compose the absolute worktree path (the `git worktree add <path>` target).
|
|
67
|
+
* Sits adjacent to the lease file under the same runtime dir.
|
|
68
|
+
*/
|
|
69
|
+
export function worktreePath(sessionRuntimeDir, leaseId) {
|
|
70
|
+
return joinPath(sessionRuntimeDir, 'worktrees', leaseId);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Generate a 16-hex lease id (8 random bytes, hex-encoded). The id is
|
|
74
|
+
* unique enough for the per-session scope; collisions across sessions
|
|
75
|
+
* are irrelevant because each session has its own lease directory.
|
|
76
|
+
*/
|
|
77
|
+
export function generateLeaseId() {
|
|
78
|
+
return randomBytes(8).toString('hex');
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Compute the TTL ms for a role, falling back to DEFAULT_TTL_MS for
|
|
82
|
+
* unknown roles. The CLI overrides with `--ttl <ms>` when the user
|
|
83
|
+
* passes a positive value.
|
|
84
|
+
*/
|
|
85
|
+
export function ttlForRole(role) {
|
|
86
|
+
const normalized = role.toLowerCase();
|
|
87
|
+
const candidate = DEFAULT_TTL_BY_ROLE[normalized];
|
|
88
|
+
const fallback = DEFAULT_TTL_BY_ROLE['rd'] ?? 30 * 60 * 1_000;
|
|
89
|
+
return candidate ?? fallback;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Pure: produce a fresh `WorktreeLease` from a draft + status.
|
|
93
|
+
* `status` defaults to `'active'`; `consumedBySubAgents` defaults to [].
|
|
94
|
+
* Used by the CLI's atomicWriteJson call.
|
|
95
|
+
*/
|
|
96
|
+
export function finalizeLease(draft) {
|
|
97
|
+
return {
|
|
98
|
+
...draft,
|
|
99
|
+
status: 'active',
|
|
100
|
+
consumedBySubAgents: []
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/** Pure: lease status transitions to 'released'. Returns a new lease. */
|
|
104
|
+
export function markReleased(lease) {
|
|
105
|
+
return { ...lease, status: 'released' };
|
|
106
|
+
}
|
|
107
|
+
/** Pure: lease status transitions to 'expired'. Returns a new lease. */
|
|
108
|
+
export function markExpired(lease) {
|
|
109
|
+
return { ...lease, status: 'expired' };
|
|
110
|
+
}
|
|
111
|
+
/** Pure: lease status transitions to 'gc'. Returns a new lease. */
|
|
112
|
+
export function markGc(lease) {
|
|
113
|
+
return { ...lease, status: 'gc' };
|
|
114
|
+
}
|
|
115
|
+
/** Pure: append a sub-agent batch / dispatch id to the consumption log. Returns a new lease. */
|
|
116
|
+
export function recordConsumption(lease, subAgentId) {
|
|
117
|
+
if (lease.consumedBySubAgents.includes(subAgentId))
|
|
118
|
+
return lease;
|
|
119
|
+
return { ...lease, consumedBySubAgents: [...lease.consumedBySubAgents, subAgentId] };
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Pure: is the lease still active (status === 'active' AND not past expiry).
|
|
123
|
+
* Expired leases are NOT auto-released; the gc CLI is the only path that
|
|
124
|
+
* transitions them to 'gc'. Until then, the on-disk state stays 'active'
|
|
125
|
+
* but `isLeaseActive` returns false so consumers skip the lease.
|
|
126
|
+
*/
|
|
127
|
+
export function isLeaseActive(lease, now = Date.now()) {
|
|
128
|
+
return lease.status === 'active' && lease.expiresAt > now;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* List every lease file under the session's lease store dir.
|
|
132
|
+
*
|
|
133
|
+
* Pure with respect to its inputs: it does NOT sort or filter, and it
|
|
134
|
+
* does NOT mark anything expired. Callers (the `list` CLI) apply their
|
|
135
|
+
* own sort/filter and run `markExpired` lazily.
|
|
136
|
+
*/
|
|
137
|
+
export function listLeasesSync(storeDir, fs) {
|
|
138
|
+
if (!fs.existsSync(storeDir)) {
|
|
139
|
+
return { kind: 'store-missing', storeDir };
|
|
140
|
+
}
|
|
141
|
+
const files = fs.readdir(storeDir).filter((f) => f.endsWith('.json'));
|
|
142
|
+
const leases = [];
|
|
143
|
+
const errors = [];
|
|
144
|
+
for (const f of files) {
|
|
145
|
+
const file = `${storeDir.replace(/[\\/]+$/, '')}/${f}`;
|
|
146
|
+
try {
|
|
147
|
+
leases.push(deserializeLease(fs.readFile(file)));
|
|
148
|
+
}
|
|
149
|
+
catch (err) {
|
|
150
|
+
errors.push({ file, error: err instanceof Error ? err.message : String(err) });
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return { kind: 'ok', leases, errors };
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Pure: a lease is eligible for `gc` if its status is one of {released,
|
|
157
|
+
* expired} AND its worktree path is no longer attached to git (`git
|
|
158
|
+
* worktree list` would not include it). The CLI re-checks with git and
|
|
159
|
+
* uses this helper as a coarse pre-filter.
|
|
160
|
+
*/
|
|
161
|
+
export function isLeaseGcEligible(lease, now = Date.now()) {
|
|
162
|
+
if (lease.status === 'gc')
|
|
163
|
+
return false;
|
|
164
|
+
if (lease.status === 'released')
|
|
165
|
+
return true;
|
|
166
|
+
// status === 'active' but past expiry → treat as expired candidate
|
|
167
|
+
return lease.expiresAt <= now;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Pure: derive a new lease from an existing one with an extended
|
|
171
|
+
* `expiresAt`. Other fields are preserved. The CLI writes the new lease
|
|
172
|
+
* atomically. Used by `peaks worktree renew --lease-id <id> --ttl <ms>`.
|
|
173
|
+
*/
|
|
174
|
+
export function renewLease(lease, newExpiresAt) {
|
|
175
|
+
return { ...lease, expiresAt: newExpiresAt, status: 'active' };
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Pure: serialize a lease to JSON with stable field order (deterministic
|
|
179
|
+
* output for diff-friendly audit logs). The CLI passes the result to
|
|
180
|
+
* `atomicWriteJson`. The function does NOT mutate the input.
|
|
181
|
+
*/
|
|
182
|
+
export function serializeLease(lease) {
|
|
183
|
+
return JSON.stringify(lease, null, 2) + '\n';
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Pure: deserialize a lease from JSON. Throws on malformed input — the
|
|
187
|
+
* CLI catches and returns a `LEASE_FILE_INVALID` envelope (mirroring the
|
|
188
|
+
* `peaks worktree auth` FILE_INVALID convention).
|
|
189
|
+
*/
|
|
190
|
+
export function deserializeLease(raw) {
|
|
191
|
+
const parsed = JSON.parse(raw);
|
|
192
|
+
if (typeof parsed !== 'object' || parsed === null) {
|
|
193
|
+
throw new Error('lease file must contain a JSON object');
|
|
194
|
+
}
|
|
195
|
+
const obj = parsed;
|
|
196
|
+
if (typeof obj.leaseId !== 'string')
|
|
197
|
+
throw new Error('leaseId missing');
|
|
198
|
+
if (typeof obj.rid !== 'string')
|
|
199
|
+
throw new Error('rid missing');
|
|
200
|
+
if (typeof obj.role !== 'string')
|
|
201
|
+
throw new Error('role missing');
|
|
202
|
+
if (typeof obj.path !== 'string')
|
|
203
|
+
throw new Error('path missing');
|
|
204
|
+
if (typeof obj.branch !== 'string')
|
|
205
|
+
throw new Error('branch missing');
|
|
206
|
+
if (typeof obj.createdAt !== 'number')
|
|
207
|
+
throw new Error('createdAt missing');
|
|
208
|
+
if (typeof obj.expiresAt !== 'number')
|
|
209
|
+
throw new Error('expiresAt missing');
|
|
210
|
+
if (typeof obj.purpose !== 'string')
|
|
211
|
+
throw new Error('purpose missing');
|
|
212
|
+
if (typeof obj.status !== 'string')
|
|
213
|
+
throw new Error('status missing');
|
|
214
|
+
if (!Array.isArray(obj.consumedBySubAgents))
|
|
215
|
+
throw new Error('consumedBySubAgents missing');
|
|
216
|
+
return {
|
|
217
|
+
leaseId: obj.leaseId,
|
|
218
|
+
rid: obj.rid,
|
|
219
|
+
role: obj.role,
|
|
220
|
+
path: obj.path,
|
|
221
|
+
branch: obj.branch,
|
|
222
|
+
createdAt: obj.createdAt,
|
|
223
|
+
expiresAt: obj.expiresAt,
|
|
224
|
+
purpose: obj.purpose,
|
|
225
|
+
status: obj.status,
|
|
226
|
+
consumedBySubAgents: obj.consumedBySubAgents
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
/** Internal: normalize a path segment to forward slashes (Windows
|
|
230
|
+
* callers pass `C:\Users\...`; posix.join sees the backslash and
|
|
231
|
+
* silently mangles). Then posix-join. The CLI uses the same module
|
|
232
|
+
* so reads + writes always agree. */
|
|
233
|
+
function joinPath(...segments) {
|
|
234
|
+
if (segments.length === 0)
|
|
235
|
+
return '';
|
|
236
|
+
const normalized = segments.map((s) => s.replace(/\\/g, '/'));
|
|
237
|
+
let acc = normalized[0];
|
|
238
|
+
for (let i = 1; i < normalized.length; i++) {
|
|
239
|
+
acc = path.join(acc, normalized[i]);
|
|
240
|
+
}
|
|
241
|
+
return acc;
|
|
242
|
+
}
|