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
|
@@ -14,20 +14,18 @@
|
|
|
14
14
|
* v2.11.0 Group F (Tier 9) — D5 / D7 additions:
|
|
15
15
|
* - `peaks code should-pause --step <step> --mode <mode>` (D5)
|
|
16
16
|
* - `peaks code post-compact-detect --project <path>` (D7)
|
|
17
|
+
*
|
|
18
|
+
* rid-024: 7 sub-commands extracted into 3 sibling files:
|
|
19
|
+
* - code-mode-gate-commands.ts (plan + should-pause)
|
|
20
|
+
* - code-job-shape-commands.ts (detect-job + read-job-shape)
|
|
21
|
+
* - code-runtime-commands.ts (post-compact-detect + auto-compact + context-now + gate-step-08 + emit-handoff)
|
|
22
|
+
* This file keeps the public API: types, buildCodePlan, runCodeFast,
|
|
23
|
+
* registerCodeCommands (now a thin orchestrator).
|
|
17
24
|
*/
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import { emitObservabilityEvent } from '../../services/observability/observability-service.js';
|
|
23
|
-
import { findProjectRoot } from '../../services/config/config-safety.js';
|
|
24
|
-
import { GATED_STEPS, isHardFloorCategory, isCodeMode, isCommitBoundaryAction, shouldPauseAtGate, formatAutoProceedLogLine } from '../../services/code/mode-gate.js';
|
|
25
|
-
import { getSkillPresence, checkStalePresence } from '../../services/skills/skill-presence-service.js';
|
|
26
|
-
import { detectPostCompactResume, formatPostCompactResumeLogLine } from '../../services/code/post-compact-detector.js';
|
|
27
|
-
import { runAutoCompact } from '../../services/code/auto-compact-orchestrator.js';
|
|
28
|
-
import { readJobShapeDecision, writeJobShapeDecision, JobShapeDecisionError, JOB_SHAPE_NOT_DECIDED, JOB_SHAPE_ALREADY_DECIDED } from '../../services/code/job-shape-decision.js';
|
|
29
|
-
import { evaluateStep08, STEP_08_BACKUP_REGEX } from '../../services/code/step-08-gate.js';
|
|
30
|
-
import { evaluateEmitHandoff, JOB_NOT_INITIALIZED, JOB_REMAINING_BLOCKED } from '../../services/code/emit-handoff.js';
|
|
25
|
+
import { registerCodeRunCommand } from './code-run-command.js';
|
|
26
|
+
import { registerCodeModeGateCommands } from './code-mode-gate-commands.js';
|
|
27
|
+
import { registerCodeJobShapeCommands } from './code-job-shape-commands.js';
|
|
28
|
+
import { registerCodeRuntimeCommands } from './code-runtime-commands.js';
|
|
31
29
|
const STEP_ORDER = [
|
|
32
30
|
'load-memory',
|
|
33
31
|
'standards-preflight',
|
|
@@ -105,694 +103,16 @@ export async function runCodeFast(opts) {
|
|
|
105
103
|
* LLM-side orchestration is driven by the SKILL.md (LLM-side), so this
|
|
106
104
|
* CLI command is a thin surface that builds the plan and emits a JSON
|
|
107
105
|
* envelope for downstream tooling.
|
|
106
|
+
*
|
|
107
|
+
* rid-024: this function is now a thin orchestrator that delegates to 3
|
|
108
|
+
* sibling register functions + the rid-020b run register.
|
|
108
109
|
*/
|
|
109
110
|
export function registerCodeCommands(program, io) {
|
|
110
111
|
const code = program
|
|
111
|
-
.command('code')
|
|
112
|
+
.command('code', { hidden: true })
|
|
112
113
|
.description('peaks-code LLM-side workflow planner (slice 2 fast mode)');
|
|
113
|
-
code
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
.option('--fast', 'fast mode: skip memory full-load, standards preflight, and QA repair loop', false)
|
|
118
|
-
.option('--json', 'emit JSON envelope')
|
|
119
|
-
.action((sessionId, opts) => {
|
|
120
|
-
const plan = buildCodePlan({ sessionId, fast: opts.fast === true });
|
|
121
|
-
if (opts.json === true) {
|
|
122
|
-
process.stdout.write(JSON.stringify({ ok: true, data: plan }) + '\n');
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
process.stdout.write(`change-id: ${plan.sessionId}\n`);
|
|
126
|
-
for (const step of plan.steps) {
|
|
127
|
-
const flag = step.skipped ? 'SKIP' : 'RUN ';
|
|
128
|
-
const repair = step.id === 'qa-cycle' ? ` repair=${step.repairLoop === true ? 'on' : 'off'}` : '';
|
|
129
|
-
process.stdout.write(` [${flag}] ${step.id}${repair}\n`);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
addJsonOption(code
|
|
134
|
-
.command('should-pause')
|
|
135
|
-
.description('v2.11.0 D5: ask the mode-gate whether the LLM should pause for an AskUserQuestion at a given step. ' +
|
|
136
|
-
'full-auto / swarm auto-proceed (recommended = chosen); assisted / strict pause. ' +
|
|
137
|
-
'The 3 hard-floor categories always pause regardless of mode. ' +
|
|
138
|
-
'v2.15.0 slice 002 AC-2: when --step step-1-mode-select AND the recorded skill presence is stale ' +
|
|
139
|
-
'(outer-session-mismatch / no-presence), the gate returns shouldPause: true with reason "stale-presence" ' +
|
|
140
|
-
'even if the user passed --mode full-auto. The re-ask is mandatory — sticky-mode from a previous ' +
|
|
141
|
-
'session is NOT authoritative.')
|
|
142
|
-
.requiredOption('--step <step>', `one of: ${GATED_STEPS.join(', ')}`)
|
|
143
|
-
// v2.18.4 slice 002-fix-first-run-step-gates (Bug 2):
|
|
144
|
-
// `--mode` is now OPTIONAL. Step 1's SEMANTIC is "ask the user
|
|
145
|
-
// what mode to use" — requiring --mode to ask mode is a
|
|
146
|
-
// chicken-and-egg. When --mode is omitted, default to
|
|
147
|
-
// 'full-auto' so the gate can still evaluate; the gate's hard-
|
|
148
|
-
// pause on `step-1-mode-select` (mode-selection-itself) will
|
|
149
|
-
// pause regardless, and the LLM-side caller can present
|
|
150
|
-
// AskUserQuestion without first knowing the mode.
|
|
151
|
-
.option('--mode <mode>', 'one of: full-auto, assisted, swarm, strict. Defaults to full-auto when omitted (Step 1 chicken-and-egg fix).')
|
|
152
|
-
.option('--hard-floor <category>', 'optional hard-floor override (irreversible-external-side-effect | authentication-credential | multi-day-investment | commit-boundary-side-effect)')
|
|
153
|
-
.option('--recommended <option>', 'recommended option label to log when auto-proceeding', 'recommended-option')
|
|
154
|
-
.option('--project <path>', 'v2.15.0 slice 002 AC-2: project root for presence:check-stale. Default: cwd. Pass only when step=step-1-mode-select.')
|
|
155
|
-
.option('--ignore-stale-presence', 'v2.15.0 slice 002 AC-2: skip the stale-presence check (test seam). Default false.')
|
|
156
|
-
.option('--commit-boundary-action <id>', 'v2.15.0 slice 002 AC-4 CLI seam (slice 002 repair): when the LLM is about to run a commit-boundary action (git push / tag / npm publish / global install), pass the action id here to force the hard-floor pause. Valid: git-push | git-tag | npm-publish | npm-install-global | peaks-global-install. Default: omitted (no override).')).action((opts) => {
|
|
157
|
-
try {
|
|
158
|
-
// v2.18.4 slice 002-fix-first-run-step-gates (Bug 2):
|
|
159
|
-
// --mode is optional. Default to 'full-auto' when omitted
|
|
160
|
-
// so step-1-mode-select can run without forcing the caller
|
|
161
|
-
// to know the mode up front. The gate's hard-pause on
|
|
162
|
-
// step-1-mode-select will still pause regardless.
|
|
163
|
-
const mode = opts.mode ?? 'full-auto';
|
|
164
|
-
if (!isCodeMode(mode)) {
|
|
165
|
-
printResult(io, fail('code.should-pause', 'INVALID_MODE', `mode must be one of full-auto, assisted, swarm, strict (got "${mode}")`, { provided: mode }, ['Pass --mode full-auto | assisted | swarm | strict']), opts.json);
|
|
166
|
-
process.exitCode = 1;
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
if (!GATED_STEPS.includes(opts.step)) {
|
|
170
|
-
printResult(io, fail('code.should-pause', 'INVALID_STEP', `step must be one of the 14 GATED_STEPS (got "${opts.step}")`, { provided: opts.step, allowed: [...GATED_STEPS] }, ['Pass --step <one of the 14 GATED_STEPS>']), opts.json);
|
|
171
|
-
process.exitCode = 1;
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
const hardFloor = opts.hardFloor;
|
|
175
|
-
if (hardFloor !== undefined && !isHardFloorCategory(hardFloor)) {
|
|
176
|
-
printResult(io, fail('code.should-pause', 'INVALID_HARD_FLOOR', `hard-floor must be one of: irreversible-external-side-effect | authentication-credential | multi-day-investment | commit-boundary-side-effect (got "${hardFloor}")`, { provided: hardFloor }, ['Omit --hard-floor or pass a valid category']), opts.json);
|
|
177
|
-
process.exitCode = 1;
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
// v2.15.0 slice 002 repair (QA blocker): validate the
|
|
181
|
-
// --commit-boundary-action flag at the CLI boundary. The
|
|
182
|
-
// service-layer `shouldPauseAtGate` accepts a boolean
|
|
183
|
-
// `commitBoundaryAction: true`; this flag tells the CLI to
|
|
184
|
-
// pass it through. An unknown action id is rejected here
|
|
185
|
-
// (not silently ignored) so typos fail loud.
|
|
186
|
-
const commitBoundaryActionId = opts.commitBoundaryAction;
|
|
187
|
-
if (commitBoundaryActionId !== undefined && !isCommitBoundaryAction(commitBoundaryActionId)) {
|
|
188
|
-
printResult(io, fail('code.should-pause', 'INVALID_COMMIT_BOUNDARY_ACTION', `--commit-boundary-action must be one of: git-push | git-tag | npm-publish | npm-install-global | peaks-global-install (got "${commitBoundaryActionId}")`, { provided: commitBoundaryActionId }, ['Omit --commit-boundary-action or pass a valid action id']), opts.json);
|
|
189
|
-
process.exitCode = 1;
|
|
190
|
-
return;
|
|
191
|
-
}
|
|
192
|
-
const step = opts.step;
|
|
193
|
-
// Slice 002 (v2.15.0) AC-2: when the caller is asking about
|
|
194
|
-
// Step 1 AND the recorded presence is stale, OVERRIDE the
|
|
195
|
-
// gate decision to PAUSE with reason='stale-presence'. The
|
|
196
|
-
// hard-pause on step-1-mode-select (defect #1 fix from
|
|
197
|
-
// 2026-06-28-code-mode-bypass-fix) is already in effect, so
|
|
198
|
-
// this only adds the structured `stale` reason + an
|
|
199
|
-
// envelope-level `stalePresence` field so downstream tooling
|
|
200
|
-
// (statusline, sub-agent dispatch) can act on it.
|
|
201
|
-
let stalePresence = null;
|
|
202
|
-
if (opts.step === 'step-1-mode-select' && opts.ignoreStalePresence !== true) {
|
|
203
|
-
const projectRoot = opts.project ?? findProjectRoot(process.cwd()) ?? process.cwd();
|
|
204
|
-
stalePresence = checkStalePresence({ projectRootOverride: projectRoot });
|
|
205
|
-
}
|
|
206
|
-
if (stalePresence !== null && stalePresence.stale) {
|
|
207
|
-
// Build the envelope manually so we can attach the extra
|
|
208
|
-
// structured fields (stalePresence, logLine) and emit a
|
|
209
|
-
// dedicated observability event tagged with reason='stale-presence'.
|
|
210
|
-
const sid = readActiveSid(opts.project ?? findProjectRoot(process.cwd()) ?? process.cwd()) ?? '';
|
|
211
|
-
if (sid.length > 0) {
|
|
212
|
-
emitObservabilityEvent({
|
|
213
|
-
schemaVersion: 1,
|
|
214
|
-
ts: new Date().toISOString(),
|
|
215
|
-
sessionId: sid,
|
|
216
|
-
category: 'mode-gate',
|
|
217
|
-
detail: {
|
|
218
|
-
mode: mode,
|
|
219
|
-
step,
|
|
220
|
-
shouldPause: true,
|
|
221
|
-
reason: 'stale-presence',
|
|
222
|
-
staleReason: stalePresence.reason,
|
|
223
|
-
recordedOuterSessionId: stalePresence.recordedOuterSessionId,
|
|
224
|
-
currentOuterSessionId: stalePresence.currentOuterSessionId
|
|
225
|
-
}
|
|
226
|
-
}, { projectRoot: opts.project ?? process.cwd() });
|
|
227
|
-
}
|
|
228
|
-
printResult(io, ok('code.should-pause', {
|
|
229
|
-
shouldPause: true,
|
|
230
|
-
reason: `stale-presence — re-ask Step 1 (${stalePresence.reason}; recorded outer session id does not match current)`,
|
|
231
|
-
gateKind: 'mode-selection-itself',
|
|
232
|
-
logLine: `auto-pause (${mode}, stale-presence:${stalePresence.reason}): ${step} → re-ask`,
|
|
233
|
-
stalePresence: {
|
|
234
|
-
stale: true,
|
|
235
|
-
reason: stalePresence.reason,
|
|
236
|
-
recordedOuterSessionId: stalePresence.recordedOuterSessionId,
|
|
237
|
-
currentOuterSessionId: stalePresence.currentOuterSessionId
|
|
238
|
-
}
|
|
239
|
-
}, [], [
|
|
240
|
-
`Recorded outer session id "${stalePresence.recordedOuterSessionId ?? '?'}" does not match current outer session id "${stalePresence.currentOuterSessionId ?? '?'}".`,
|
|
241
|
-
`peaks-code Step 1 must AskUserQuestion to confirm the mode for THIS session (slice 002 AC-2).`
|
|
242
|
-
]), opts.json);
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
const decision = shouldPauseAtGate({
|
|
246
|
-
mode: mode,
|
|
247
|
-
step,
|
|
248
|
-
hardFloorCategory: hardFloor,
|
|
249
|
-
// v2.15.0 slice 002 repair (QA blocker): translate the CLI
|
|
250
|
-
// --commit-boundary-action flag into the service-layer
|
|
251
|
-
// boolean. The CLI accepts the action id (e.g. "git-push")
|
|
252
|
-
// for ergonomic machine consumption; the service layer only
|
|
253
|
-
// cares that *some* commit-boundary action triggered the
|
|
254
|
-
// override. The actual action id is echoed in the JSON
|
|
255
|
-
// envelope below.
|
|
256
|
-
commitBoundaryAction: commitBoundaryActionId !== undefined
|
|
257
|
-
});
|
|
258
|
-
// Slice C of v2.11.1 — observability hook #4/7. Fire-and-forget
|
|
259
|
-
// per PRD Q4 (full-auto must never fail-loud). projectRoot
|
|
260
|
-
// resolution mirrors observability-commands.ts (findProjectRoot
|
|
261
|
-
// → cwd fallback).
|
|
262
|
-
const projectRoot = findProjectRoot(process.cwd()) ?? process.cwd();
|
|
263
|
-
const sid = readActiveSid(projectRoot) ?? '';
|
|
264
|
-
if (sid.length > 0) {
|
|
265
|
-
emitObservabilityEvent({
|
|
266
|
-
schemaVersion: 1,
|
|
267
|
-
ts: new Date().toISOString(),
|
|
268
|
-
sessionId: sid,
|
|
269
|
-
category: 'mode-gate',
|
|
270
|
-
detail: {
|
|
271
|
-
mode: mode,
|
|
272
|
-
step,
|
|
273
|
-
shouldPause: decision.shouldPause,
|
|
274
|
-
reason: decision.reason,
|
|
275
|
-
...(decision.hardFloorCategory !== undefined ? { hardFloorCategory: decision.hardFloorCategory } : {})
|
|
276
|
-
}
|
|
277
|
-
}, { projectRoot });
|
|
278
|
-
}
|
|
279
|
-
const logLine = formatAutoProceedLogLine({
|
|
280
|
-
mode: mode,
|
|
281
|
-
step,
|
|
282
|
-
recommendedOption: opts.recommended ?? 'recommended-option',
|
|
283
|
-
hardFloorCategory: hardFloor
|
|
284
|
-
});
|
|
285
|
-
printResult(io,
|
|
286
|
-
// v2.15.0 slice 002 repair: include the commit-boundary
|
|
287
|
-
// action id in the envelope (when provided) so the LLM-side
|
|
288
|
-
// caller can echo which boundary was checked. Null when no
|
|
289
|
-
// --commit-boundary-action flag was passed.
|
|
290
|
-
ok('code.should-pause', {
|
|
291
|
-
...decision,
|
|
292
|
-
logLine,
|
|
293
|
-
...(commitBoundaryActionId !== undefined ? { commitBoundaryAction: commitBoundaryActionId } : {})
|
|
294
|
-
}, [], [
|
|
295
|
-
decision.shouldPause
|
|
296
|
-
? `Mode ${mode} + step ${opts.step} → PAUSE for AskUserQuestion${commitBoundaryActionId !== undefined ? ` (commit-boundary: ${commitBoundaryActionId})` : ''}`
|
|
297
|
-
: `Mode ${mode} + step ${opts.step} → AUTO-PROCEED with recommended option`
|
|
298
|
-
]), opts.json);
|
|
299
|
-
}
|
|
300
|
-
catch (err) {
|
|
301
|
-
printResult(io, fail('code.should-pause', 'SHOULD_PAUSE_FAILED', getErrorMessage(err), null, ['Re-run with --json for envelope shape']), opts.json);
|
|
302
|
-
process.exitCode = 1;
|
|
303
|
-
}
|
|
304
|
-
});
|
|
305
|
-
addJsonOption(code
|
|
306
|
-
.command('post-compact-detect')
|
|
307
|
-
.description('v2.11.0 D7: detect whether the current invocation is a same-day post-compact resume. ' +
|
|
308
|
-
'Auto-resumes (no AskUserQuestion) when the most-recent checkpoint is from today, has a mode field, ' +
|
|
309
|
-
'and the active skill is peaks-code. Falls through to the normal Step 0.7 flow otherwise.')
|
|
310
|
-
.requiredOption('--project <path>', 'target project root')
|
|
311
|
-
.option('--session-id <sid>', 'override session id (default: read from active presence)')
|
|
312
|
-
.option('--active-skill <skill>', 'override active skill (test seam; default: read from presence)')).action(async (opts) => {
|
|
313
|
-
try {
|
|
314
|
-
const sessionId = opts.sessionId ?? readActiveSid(opts.project);
|
|
315
|
-
if (sessionId === null) {
|
|
316
|
-
printResult(io, fail('code.post-compact-detect', 'NO_ACTIVE_SESSION', 'no active session id; pass --session-id or set presence via `peaks skill presence:set peaks-code`', null, ['Re-run with --session-id <sid>']), opts.json);
|
|
317
|
-
process.exitCode = 1;
|
|
318
|
-
return;
|
|
319
|
-
}
|
|
320
|
-
const probe = await detectPostCompactResume({
|
|
321
|
-
sessionId,
|
|
322
|
-
projectRoot: opts.project,
|
|
323
|
-
activeSkill: opts.activeSkill
|
|
324
|
-
});
|
|
325
|
-
const logLine = formatPostCompactResumeLogLine(probe);
|
|
326
|
-
printResult(io, ok('code.post-compact-detect', { ...probe, logLine }, [...probe.warnings], [
|
|
327
|
-
probe.shouldAutoResume
|
|
328
|
-
? `Post-compact match → auto-resume mode=${probe.mode ?? '?'} checkpoint=${probe.checkpointPath ?? '?'}`
|
|
329
|
-
: `No auto-resume: ${probe.reason}`
|
|
330
|
-
]), opts.json);
|
|
331
|
-
}
|
|
332
|
-
catch (err) {
|
|
333
|
-
printResult(io, fail('code.post-compact-detect', 'POST_COMPACT_DETECT_FAILED', getErrorMessage(err), null, ['Verify the project path and try again']), opts.json);
|
|
334
|
-
process.exitCode = 1;
|
|
335
|
-
}
|
|
336
|
-
});
|
|
337
|
-
addJsonOption(code
|
|
338
|
-
.command('auto-compact')
|
|
339
|
-
.description('v2.13.0 AC-4: zero-human-intervention auto-compact. Probes current ' +
|
|
340
|
-
'context-fill % via the active IDE adapter; ≥ 0.85 writes a pre-compact ' +
|
|
341
|
-
'checkpoint + convergence plan + auto-decisions log; ≥ 0.95 forces ' +
|
|
342
|
-
'synchronous IDE-side compact. The LLM / runner keeps working with ' +
|
|
343
|
-
'context < 95% without human intervention. pair with `peaks context ' +
|
|
344
|
-
'now` (AC-1) which feeds the ratio into this command.')
|
|
345
|
-
.requiredOption('--project <path>', 'target project root')
|
|
346
|
-
.option('--session-id <sid>', 'override session id (default: read from active presence)')
|
|
347
|
-
.option('--in-flight-batch', 'defer if a sub-agent batch is in flight (D6.e)')
|
|
348
|
-
.option('--force', 'force compact at any ratio (test seam)')
|
|
349
|
-
.option('--bypass-red-line', 'skip the 95% red-line gate (test seam; never true in production)')).action(async (opts) => {
|
|
350
|
-
try {
|
|
351
|
-
const result = await runAutoCompact({
|
|
352
|
-
projectRoot: opts.project,
|
|
353
|
-
sessionId: opts.sessionId ?? readActiveSid(opts.project) ?? undefined,
|
|
354
|
-
inFlightBatch: opts.inFlightBatch === true
|
|
355
|
-
? { hasInFlightBatch: true }
|
|
356
|
-
: undefined,
|
|
357
|
-
force: opts.force === true,
|
|
358
|
-
bypassRedLine: opts.bypassRedLine === true
|
|
359
|
-
});
|
|
360
|
-
const code = result.code;
|
|
361
|
-
const exitOk = result.ok || code === 'AUTO_COMPACT_SKIP' || code === 'AUTO_COMPACT_WAIT';
|
|
362
|
-
// Adapt AutoCompactResult → ResultEnvelope so printResult's
|
|
363
|
-
// generic accepts it. The orchestrator envelope carries
|
|
364
|
-
// `data` on success-path and `nextActions` on the error
|
|
365
|
-
// path; surface both directly to the user.
|
|
366
|
-
const data = 'data' in result ? result.data : null;
|
|
367
|
-
const nextActions = 'nextActions' in result ? result.nextActions : [];
|
|
368
|
-
const envelope = result.ok
|
|
369
|
-
? ok(`code.auto-compact`, data ?? {}, [], [result.message, ...nextActions])
|
|
370
|
-
: fail(`code.auto-compact`, code, result.message, data, [...nextActions]);
|
|
371
|
-
printResult(io, envelope, opts.json);
|
|
372
|
-
if (!exitOk)
|
|
373
|
-
process.exitCode = 1;
|
|
374
|
-
}
|
|
375
|
-
catch (err) {
|
|
376
|
-
printResult(io, fail('code.auto-compact', 'AUTO_COMPACT_FAILED', getErrorMessage(err), null, [
|
|
377
|
-
'Verify the project path + session id and try again'
|
|
378
|
-
]), opts.json);
|
|
379
|
-
process.exitCode = 1;
|
|
380
|
-
}
|
|
381
|
-
});
|
|
382
|
-
addJsonOption(code
|
|
383
|
-
.command('context-now')
|
|
384
|
-
.description('v2.13.0 AC-1: read the active IDE adapter\'s context-fill % ' +
|
|
385
|
-
'without requiring the LLM to pass --prompt-size <bytes> manually. ' +
|
|
386
|
-
'Adapter-driven (no hard-coded IDE names): Claude Code is the MVP ' +
|
|
387
|
-
'implementation; trae / codex / cursor / qoder / tongyi-lingma / ' +
|
|
388
|
-
'hermes / openclaw register their own env-var via IdeAdapter.compact. ' +
|
|
389
|
-
'v3.1.2: when --enforce-job-mode is set OR job-shape.json says isJob=true, ' +
|
|
390
|
-
'≥0.85 emits action=auto-compact-now (MANDATORY, not advisory) and ' +
|
|
391
|
-
'≥0.95 emits action=red-line (forced hook fires next turn).')
|
|
392
|
-
.requiredOption('--project <path>', 'target project root')
|
|
393
|
-
.option('--session-id <sid>', 'override session id (default: read from active presence)')
|
|
394
|
-
.option('--enforce-job-mode', 'v3.1.2: treat ≥0.85 as MANDATORY auto-compact (not advisory). Auto-enabled when job-shape.json says isJob=true.')).action(async (opts) => {
|
|
395
|
-
try {
|
|
396
|
-
const { readContextPercent } = await import('../../services/context/auto-compact-reader.js');
|
|
397
|
-
// v3.1.2: detect Job mode from job-shape.json when --enforce-job-mode
|
|
398
|
-
// is not explicitly passed. The LLM is the source of truth for
|
|
399
|
-
// whether the request is Job-shaped; the recorded decision is.
|
|
400
|
-
let isJobMode = opts.enforceJobMode === true;
|
|
401
|
-
if (!isJobMode) {
|
|
402
|
-
try {
|
|
403
|
-
const sessionIdForDecision = opts.sessionId ?? readActiveSid(opts.project);
|
|
404
|
-
if (sessionIdForDecision !== null) {
|
|
405
|
-
const record = readJobShapeDecision(opts.project, sessionIdForDecision);
|
|
406
|
-
if (record.decision.isJob)
|
|
407
|
-
isJobMode = true;
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
catch (err) {
|
|
411
|
-
if (!(err instanceof JobShapeDecisionError))
|
|
412
|
-
throw err;
|
|
413
|
-
// missing/malformed decision file is fine — fall back to advisory.
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
const probe = readContextPercent({
|
|
417
|
-
projectRoot: opts.project,
|
|
418
|
-
sessionId: opts.sessionId ?? readActiveSid(opts.project) ?? 'unknown',
|
|
419
|
-
env: process.env
|
|
420
|
-
});
|
|
421
|
-
const ratioPct = (probe.ratio * 100).toFixed(1);
|
|
422
|
-
let action = 'ok';
|
|
423
|
-
let next = null;
|
|
424
|
-
if (probe.ratio >= 0.95) {
|
|
425
|
-
action = isJobMode ? 'red-line' : 'red-line';
|
|
426
|
-
next = 'peaks session auto-compact-hook';
|
|
427
|
-
}
|
|
428
|
-
else if (probe.ratio >= 0.85) {
|
|
429
|
-
if (isJobMode) {
|
|
430
|
-
action = 'auto-compact-now';
|
|
431
|
-
next = 'peaks session auto-compact --execute';
|
|
432
|
-
}
|
|
433
|
-
else {
|
|
434
|
-
action = 'soft-warn';
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
else if (probe.ratio >= 0.5) {
|
|
438
|
-
action = 'soft-warn';
|
|
439
|
-
}
|
|
440
|
-
const verdict = action === 'red-line' ? 'red-line'
|
|
441
|
-
: action === 'auto-compact-now' ? 'pre-compact'
|
|
442
|
-
: action === 'soft-warn' ? 'soft-warn'
|
|
443
|
-
: 'ok';
|
|
444
|
-
const jobModeNotice = isJobMode
|
|
445
|
-
? 'Job mode enforced: ≥0.85 is MANDATORY auto-compact (v3.1.2).'
|
|
446
|
-
: 'Advisory mode (single-rid): ≥0.85 is recommended, not mandatory.';
|
|
447
|
-
printResult(io, ok('code.context-now', {
|
|
448
|
-
ratio: probe.ratio,
|
|
449
|
-
ratioPct: `${ratioPct}%`,
|
|
450
|
-
verdict,
|
|
451
|
-
action,
|
|
452
|
-
next,
|
|
453
|
-
jobMode: isJobMode,
|
|
454
|
-
source: probe.source,
|
|
455
|
-
ide: probe.ide,
|
|
456
|
-
capacityBytes: probe.capacityBytes,
|
|
457
|
-
rawBytes: probe.rawBytes ?? null,
|
|
458
|
-
capturedAt: probe.capturedAt
|
|
459
|
-
}, [], [
|
|
460
|
-
action === 'red-line'
|
|
461
|
-
? `RED LINE: ≥ 95%. Next: \`${next}\` (PreToolUse hook fires next turn).`
|
|
462
|
-
: action === 'auto-compact-now'
|
|
463
|
-
? `Job-mode MANDATORY auto-compact. Code MUST call \`${next}\` WITHOUT confirmation.`
|
|
464
|
-
: action === 'soft-warn'
|
|
465
|
-
? isJobMode
|
|
466
|
-
? `Job mode soft-warn (50–85%). Continue working; the next \`peaks context now\` will re-check.`
|
|
467
|
-
: `Soft warn (50–85%). Continue working; the next \`peaks context now\` will re-check.`
|
|
468
|
-
: `Below 50%. No action required.`,
|
|
469
|
-
jobModeNotice
|
|
470
|
-
]), true);
|
|
471
|
-
}
|
|
472
|
-
catch (err) {
|
|
473
|
-
printResult(io, fail('code.context-now', 'CONTEXT_NOW_FAILED', getErrorMessage(err), null, [
|
|
474
|
-
'Verify the project path and try again'
|
|
475
|
-
]), opts.json);
|
|
476
|
-
process.exitCode = 1;
|
|
477
|
-
}
|
|
478
|
-
});
|
|
479
|
-
// v3.1.1 Step 0.8 — Job-shape decision recorder.
|
|
480
|
-
// The CLI is a *recorder*, not a judge. The LLM supplies the verdict
|
|
481
|
-
// (--is-job, --rationale, --suggested-job-id, --suggested-strategy,
|
|
482
|
-
// --confidence); the CLI validates the shape, stamps `decidedAt`
|
|
483
|
-
// server-side, and writes to `.peaks/_runtime/<sessionId>/job-shape.json`.
|
|
484
|
-
addJsonOption(code
|
|
485
|
-
.command('detect-job')
|
|
486
|
-
.description('v3.1.1 Step 0.8: record the LLM\'s Job-shape judgement. CLI is a recorder, NOT a detector. ' +
|
|
487
|
-
'Pass --is-job true|false, --rationale <text>, --suggested-job-id <slug>. ' +
|
|
488
|
-
'Downstream steps call `peaks code read-job-shape` and refuse to proceed if missing.')
|
|
489
|
-
.requiredOption('--is-job <bool>', 'true | false (the LLM\'s semantic verdict)')
|
|
490
|
-
.requiredOption('--rationale <text>', '1-3 sentences the LLM writes explaining the call')
|
|
491
|
-
.requiredOption('--suggested-job-id <jid>', 'LLM-chosen stable id, slug-safe (/^[a-z0-9][a-z0-9-]{2,40}$/)')
|
|
492
|
-
.option('--suggested-strategy <single|rotating>', 'single | rotating', 'single')
|
|
493
|
-
.option('--confidence <high|medium|low>', 'high | medium | low', 'medium')
|
|
494
|
-
.option('--force', 'overwrite an existing decision file')
|
|
495
|
-
.option('--session-id <sid>', 'override session id (default: read from active presence)')
|
|
496
|
-
.option('--project <path>', 'target project root (default: findProjectRoot(cwd))')
|
|
497
|
-
.option('--prompt <text>', 'override the prompt hashed into promptHash (default: read last-prompt.txt if present, else empty)')).action(async (opts) => {
|
|
498
|
-
try {
|
|
499
|
-
if (opts.isJob !== 'true' && opts.isJob !== 'false') {
|
|
500
|
-
printResult(io, fail('code.detect-job', 'INVALID_FLAG', `--is-job must be true | false (got "${opts.isJob}")`, { provided: opts.isJob }, ['Pass --is-job true or --is-job false']), opts.json);
|
|
501
|
-
process.exitCode = 1;
|
|
502
|
-
return;
|
|
503
|
-
}
|
|
504
|
-
if (opts.suggestedStrategy !== 'single' && opts.suggestedStrategy !== 'rotating') {
|
|
505
|
-
printResult(io, fail('code.detect-job', 'INVALID_FLAG', `--suggested-strategy must be single | rotating (got "${opts.suggestedStrategy}")`, { provided: opts.suggestedStrategy }, ['Pass --suggested-strategy single or --suggested-strategy rotating']), opts.json);
|
|
506
|
-
process.exitCode = 1;
|
|
507
|
-
return;
|
|
508
|
-
}
|
|
509
|
-
if (opts.confidence !== 'high' && opts.confidence !== 'medium' && opts.confidence !== 'low') {
|
|
510
|
-
printResult(io, fail('code.detect-job', 'INVALID_FLAG', `--confidence must be high | medium | low (got "${opts.confidence}")`, { provided: opts.confidence }, ['Pass --confidence high | medium | low']), opts.json);
|
|
511
|
-
process.exitCode = 1;
|
|
512
|
-
return;
|
|
513
|
-
}
|
|
514
|
-
const jidRe = /^[a-z0-9][a-z0-9-]{2,40}$/;
|
|
515
|
-
if (!jidRe.test(opts.suggestedJobId)) {
|
|
516
|
-
printResult(io, fail('code.detect-job', 'INVALID_FLAG', `--suggested-job-id must match /^[a-z0-9][a-z0-9-]{2,40}$/ (got "${opts.suggestedJobId}")`, { provided: opts.suggestedJobId }, ['Pass a slug-safe id (lowercase, digits, dashes; 3-41 chars)']), opts.json);
|
|
517
|
-
process.exitCode = 1;
|
|
518
|
-
return;
|
|
519
|
-
}
|
|
520
|
-
const projectRoot = opts.project ?? findProjectRoot(process.cwd()) ?? process.cwd();
|
|
521
|
-
const sessionId = opts.sessionId ?? readActiveSid(projectRoot);
|
|
522
|
-
if (sessionId === null) {
|
|
523
|
-
printResult(io, fail('code.detect-job', 'NO_ACTIVE_SESSION', 'no active session id; pass --session-id or set presence via `peaks skill presence:set peaks-code`', null, ['Re-run with --session-id <sid>']), opts.json);
|
|
524
|
-
process.exitCode = 1;
|
|
525
|
-
return;
|
|
526
|
-
}
|
|
527
|
-
// Prompt source: explicit --prompt > last-prompt.txt > empty.
|
|
528
|
-
let promptText = opts.prompt ?? '';
|
|
529
|
-
if (opts.prompt === undefined) {
|
|
530
|
-
const lastPromptPath = join(projectRoot, '.peaks', '_runtime', sessionId, 'txt', 'last-prompt.txt');
|
|
531
|
-
if (existsSync(lastPromptPath)) {
|
|
532
|
-
try {
|
|
533
|
-
promptText = readFileSync(lastPromptPath, 'utf8');
|
|
534
|
-
}
|
|
535
|
-
catch { // TODO(g2): legacy silent catch — grace: 1 minor release
|
|
536
|
-
promptText = '';
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
|
-
const record = writeJobShapeDecision(projectRoot, sessionId, {
|
|
541
|
-
isJob: opts.isJob === 'true',
|
|
542
|
-
rationale: opts.rationale,
|
|
543
|
-
suggestedJobId: opts.suggestedJobId,
|
|
544
|
-
suggestedStrategy: opts.suggestedStrategy,
|
|
545
|
-
confidence: opts.confidence,
|
|
546
|
-
prompt: promptText
|
|
547
|
-
}, { force: opts.force === true });
|
|
548
|
-
printResult(io, ok('code.detect-job', {
|
|
549
|
-
sessionId: record.sessionId,
|
|
550
|
-
promptHash: record.promptHash,
|
|
551
|
-
decision: record.decision,
|
|
552
|
-
schemaVersion: record.schemaVersion
|
|
553
|
-
}, [], [
|
|
554
|
-
`Decision recorded: isJob=${record.decision.isJob} strategy=${record.decision.suggestedStrategy} confidence=${record.decision.confidence}`,
|
|
555
|
-
`File: .peaks/_runtime/${record.sessionId}/job-shape.json`
|
|
556
|
-
]), opts.json);
|
|
557
|
-
}
|
|
558
|
-
catch (err) {
|
|
559
|
-
if (err instanceof JobShapeDecisionError) {
|
|
560
|
-
const code = err.code === JOB_SHAPE_ALREADY_DECIDED ? JOB_SHAPE_ALREADY_DECIDED : err.code === JOB_SHAPE_NOT_DECIDED ? JOB_SHAPE_NOT_DECIDED : err.code;
|
|
561
|
-
printResult(io, fail('code.detect-job', code, err.message, err.details ?? null, [
|
|
562
|
-
err.code === JOB_SHAPE_ALREADY_DECIDED
|
|
563
|
-
? 'Re-run with --force to overwrite the existing decision.'
|
|
564
|
-
: 'Re-run with valid flags.'
|
|
565
|
-
]), opts.json);
|
|
566
|
-
process.exitCode = 1;
|
|
567
|
-
return;
|
|
568
|
-
}
|
|
569
|
-
printResult(io, fail('code.detect-job', 'DETECT_JOB_FAILED', getErrorMessage(err), null, ['Verify the flags and try again']), opts.json);
|
|
570
|
-
process.exitCode = 1;
|
|
571
|
-
}
|
|
572
|
-
});
|
|
573
|
-
// v3.1.1 Step 0.8 — read-only validator. Downstream steps call this
|
|
574
|
-
// to refuse to proceed if the LLM has not yet recorded a decision.
|
|
575
|
-
addJsonOption(code
|
|
576
|
-
.command('read-job-shape')
|
|
577
|
-
.description('v3.1.1 Step 0.8: return the recorded Job-shape decision. ' +
|
|
578
|
-
'Returns JOB_SHAPE_NOT_DECIDED when the LLM has not yet recorded a verdict.')
|
|
579
|
-
.option('--session-id <sid>', 'override session id (default: read from active presence)')
|
|
580
|
-
.option('--project <path>', 'target project root (default: findProjectRoot(cwd))')).action((opts) => {
|
|
581
|
-
try {
|
|
582
|
-
const projectRoot = opts.project ?? findProjectRoot(process.cwd()) ?? process.cwd();
|
|
583
|
-
const sessionId = opts.sessionId ?? readActiveSid(projectRoot);
|
|
584
|
-
if (sessionId === null) {
|
|
585
|
-
printResult(io, fail('code.read-job-shape', 'NO_ACTIVE_SESSION', 'no active session id; pass --session-id or set presence via `peaks skill presence:set peaks-code`', null, ['Re-run with --session-id <sid>']), opts.json);
|
|
586
|
-
process.exitCode = 1;
|
|
587
|
-
return;
|
|
588
|
-
}
|
|
589
|
-
const record = readJobShapeDecision(projectRoot, sessionId);
|
|
590
|
-
printResult(io, ok('code.read-job-shape', {
|
|
591
|
-
sessionId: record.sessionId,
|
|
592
|
-
promptHash: record.promptHash,
|
|
593
|
-
decision: record.decision,
|
|
594
|
-
schemaVersion: record.schemaVersion
|
|
595
|
-
}, [], [
|
|
596
|
-
`Decision on file: isJob=${record.decision.isJob} strategy=${record.decision.suggestedStrategy} confidence=${record.decision.confidence}`
|
|
597
|
-
]), opts.json);
|
|
598
|
-
}
|
|
599
|
-
catch (err) {
|
|
600
|
-
if (err instanceof JobShapeDecisionError) {
|
|
601
|
-
printResult(io, fail('code.read-job-shape', err.code, err.message, err.details ?? null, [
|
|
602
|
-
err.code === JOB_SHAPE_NOT_DECIDED
|
|
603
|
-
? 'Run `peaks code detect-job` to record a decision.'
|
|
604
|
-
: 'Investigate the decision file integrity.'
|
|
605
|
-
]), opts.json);
|
|
606
|
-
process.exitCode = 1;
|
|
607
|
-
return;
|
|
608
|
-
}
|
|
609
|
-
printResult(io, fail('code.read-job-shape', 'READ_JOB_SHAPE_FAILED', getErrorMessage(err), null, ['Verify the project path and try again']), opts.json);
|
|
610
|
-
process.exitCode = 1;
|
|
611
|
-
}
|
|
612
|
-
});
|
|
613
|
-
// v3.1.2 Step 0.8 — Mechanical PreToolUse gate.
|
|
614
|
-
// Wire-installed by `peaks workspace init` (extends the existing hook
|
|
615
|
-
// installer). Exit code is the load-bearing contract:
|
|
616
|
-
// exit 0 → allow (with structured stdout describing the decision)
|
|
617
|
-
// exit 2 → block (stderr contains the BLOCKED: ... reason)
|
|
618
|
-
addJsonOption(code
|
|
619
|
-
.command('gate-step-08')
|
|
620
|
-
.description('v3.1.2: PreToolUse gate for Step 0.8 — allow when job-shape.json exists; ' +
|
|
621
|
-
'fail-closed backup regex when missing. Exit 0 = allow, exit 2 = block. ' +
|
|
622
|
-
'When the decision says isJob=true AND progress.json exists, the stdout ' +
|
|
623
|
-
'also carries `Next: slice #N+1 of M (<currentSlice>)` so the LLM cannot ' +
|
|
624
|
-
'wake up cold.')
|
|
625
|
-
.requiredOption('--project <path>', 'target project root (the hook passes "." so resolveCanonicalProjectRoot promotes it to the git root)')
|
|
626
|
-
.option('--session-id <sid>', 'override session id (default: read from active presence)')
|
|
627
|
-
.option('--prompt <text>', 'explicit prompt text (default: read last-prompt.txt; stdin ignored)')).action((opts) => {
|
|
628
|
-
try {
|
|
629
|
-
const sessionId = opts.sessionId ?? readActiveSid(opts.project);
|
|
630
|
-
if (sessionId === null) {
|
|
631
|
-
// No session binding — treat as allow (single-rid mode). The
|
|
632
|
-
// LLM has not yet anchored; we have nothing to gate against.
|
|
633
|
-
const envelope = ok('code.gate-step-08', {
|
|
634
|
-
allow: true,
|
|
635
|
-
mode: 'no-session',
|
|
636
|
-
decision: null,
|
|
637
|
-
nextSlice: null
|
|
638
|
-
}, [], [
|
|
639
|
-
'No active session id; gate passes through (single-rid mode).'
|
|
640
|
-
]);
|
|
641
|
-
printResult(io, envelope, opts.json);
|
|
642
|
-
return;
|
|
643
|
-
}
|
|
644
|
-
const evalInput = {
|
|
645
|
-
projectRoot: opts.project,
|
|
646
|
-
sessionId
|
|
647
|
-
};
|
|
648
|
-
if (opts.prompt !== undefined)
|
|
649
|
-
evalInput.prompt = opts.prompt;
|
|
650
|
-
const result = evaluateStep08(evalInput);
|
|
651
|
-
const verdict = result.verdict;
|
|
652
|
-
if (verdict.kind === 'allow-job') {
|
|
653
|
-
const envelope = ok('code.gate-step-08', {
|
|
654
|
-
allow: true,
|
|
655
|
-
mode: 'job',
|
|
656
|
-
decision: verdict.decision,
|
|
657
|
-
progress: verdict.progress,
|
|
658
|
-
nextSlice: result.nextSliceLine
|
|
659
|
-
}, [], result.nextSliceLine !== null ? [result.nextSliceLine] : []);
|
|
660
|
-
printResult(io, envelope, opts.json);
|
|
661
|
-
return;
|
|
662
|
-
}
|
|
663
|
-
if (verdict.kind === 'allow-single') {
|
|
664
|
-
const envelope = ok('code.gate-step-08', {
|
|
665
|
-
allow: true,
|
|
666
|
-
mode: 'single',
|
|
667
|
-
decision: null,
|
|
668
|
-
nextSlice: null
|
|
669
|
-
}, [], [
|
|
670
|
-
'job-shape.json says isJob=false; single-rid mode (gate allows).'
|
|
671
|
-
]);
|
|
672
|
-
printResult(io, envelope, opts.json);
|
|
673
|
-
return;
|
|
674
|
-
}
|
|
675
|
-
// block-missing-decision
|
|
676
|
-
if (verdict.promptHit) {
|
|
677
|
-
// Block: backup regex hit. Exit code 2 is the load-bearing
|
|
678
|
-
// signal for the PreToolUse hook.
|
|
679
|
-
const blockMessage = 'BLOCKED: prompt looks Job-shaped but peaks code detect-job has not been called. Run `peaks code detect-job --is-job true ...` to record your Job-shape verdict, then retry.';
|
|
680
|
-
const envelope = fail('code.gate-step-08', 'STEP_08_BLOCKED', blockMessage, {
|
|
681
|
-
promptSource: verdict.promptSource,
|
|
682
|
-
backupRegex: STEP_08_BACKUP_REGEX.toString()
|
|
683
|
-
}, [
|
|
684
|
-
'Run `peaks code detect-job --is-job true --rationale <text> --suggested-job-id <slug>` to record the Job-shape verdict.',
|
|
685
|
-
'Then re-run the Bash tool call.'
|
|
686
|
-
]);
|
|
687
|
-
io.stderr(`${blockMessage}\n`);
|
|
688
|
-
printResult(io, envelope, opts.json);
|
|
689
|
-
process.exitCode = 2;
|
|
690
|
-
return;
|
|
691
|
-
}
|
|
692
|
-
// No decision + no regex hit → allow.
|
|
693
|
-
const envelope = ok('code.gate-step-08', {
|
|
694
|
-
allow: true,
|
|
695
|
-
mode: 'undecided-no-regex-hit',
|
|
696
|
-
decision: null,
|
|
697
|
-
nextSlice: null,
|
|
698
|
-
promptSource: verdict.promptSource
|
|
699
|
-
}, [], [
|
|
700
|
-
'No job-shape.json AND no backup-regex match on prompt → allow (most prompts are not Job-shaped).'
|
|
701
|
-
]);
|
|
702
|
-
printResult(io, envelope, opts.json);
|
|
703
|
-
return;
|
|
704
|
-
}
|
|
705
|
-
catch (err) {
|
|
706
|
-
printResult(io, fail('code.gate-step-08', 'GATE_STEP_08_FAILED', getErrorMessage(err), null, [
|
|
707
|
-
'Verify the project path and try again'
|
|
708
|
-
]), opts.json);
|
|
709
|
-
process.exitCode = 1;
|
|
710
|
-
}
|
|
711
|
-
});
|
|
712
|
-
// v3.1.2 Step 11 / final handoff — Size-fear ban.
|
|
713
|
-
// Refuses to emit a final handoff while a Job has remaining slices.
|
|
714
|
-
addJsonOption(code
|
|
715
|
-
.command('emit-handoff')
|
|
716
|
-
.description('v3.1.2 Step 11 size-fear ban: under Job mode, refuse to emit a final ' +
|
|
717
|
-
'handoff while remaining > 0. Exit 0 = allow, exit 1 = block. Pass ' +
|
|
718
|
-
'--force-under-job to override (requires explicit user approval).')
|
|
719
|
-
.requiredOption('--project <path>', 'target project root')
|
|
720
|
-
.option('--session-id <sid>', 'override session id (default: read from active presence)')
|
|
721
|
-
.option('--job-id <jid>', 'override job id (default: read from job-shape.json decision.suggestedJobId)')
|
|
722
|
-
.option('--force-under-job', 'override the remaining>0 block (explicit user approval required)')).action((opts) => {
|
|
723
|
-
try {
|
|
724
|
-
const sessionId = opts.sessionId ?? readActiveSid(opts.project);
|
|
725
|
-
if (sessionId === null) {
|
|
726
|
-
const envelope = ok('code.emit-handoff', { allow: true, mode: 'no-session' }, [], [
|
|
727
|
-
'No active session id; gate passes through (single-rid mode).'
|
|
728
|
-
]);
|
|
729
|
-
printResult(io, envelope, opts.json);
|
|
730
|
-
return;
|
|
731
|
-
}
|
|
732
|
-
const evalInput = {
|
|
733
|
-
projectRoot: opts.project,
|
|
734
|
-
sessionId
|
|
735
|
-
};
|
|
736
|
-
if (opts.jobId !== undefined)
|
|
737
|
-
evalInput.jobId = opts.jobId;
|
|
738
|
-
if (opts.forceUnderJob === true)
|
|
739
|
-
evalInput.forceUnderJob = true;
|
|
740
|
-
const verdict = evaluateEmitHandoff(evalInput);
|
|
741
|
-
if (verdict.kind === 'allow-not-job') {
|
|
742
|
-
const envelope = ok('code.emit-handoff', { allow: true, mode: 'single' }, [], [
|
|
743
|
-
'job-shape.json says isJob=false (or absent); normal handoff allowed.'
|
|
744
|
-
]);
|
|
745
|
-
printResult(io, envelope, opts.json);
|
|
746
|
-
return;
|
|
747
|
-
}
|
|
748
|
-
if (verdict.kind === 'allow-done') {
|
|
749
|
-
const envelope = ok('code.emit-handoff', { allow: true, mode: 'job-done', remaining: verdict.remaining }, [], [
|
|
750
|
-
`Job is complete (remaining=0); handoff allowed.`
|
|
751
|
-
]);
|
|
752
|
-
printResult(io, envelope, opts.json);
|
|
753
|
-
return;
|
|
754
|
-
}
|
|
755
|
-
if (verdict.kind === 'allow-force-override') {
|
|
756
|
-
const envelope = ok('code.emit-handoff', { allow: true, mode: 'job-force-override', remaining: verdict.remaining }, [], [
|
|
757
|
-
`Job has ${verdict.remaining} remaining slices; --force-under-job override applied. Handoff allowed (explicit user approval).`
|
|
758
|
-
]);
|
|
759
|
-
printResult(io, envelope, opts.json);
|
|
760
|
-
return;
|
|
761
|
-
}
|
|
762
|
-
if (verdict.kind === 'block-not-initialized') {
|
|
763
|
-
const envelope = fail('code.emit-handoff', JOB_NOT_INITIALIZED, `Job ${verdict.jobId} has no state.json; peaks job init was skipped.`, { jobId: verdict.jobId }, [`Run \`peaks job init --job-id ${verdict.jobId} --slice-list <...>\` before emitting handoff.`]);
|
|
764
|
-
printResult(io, envelope, opts.json);
|
|
765
|
-
process.exitCode = 1;
|
|
766
|
-
return;
|
|
767
|
-
}
|
|
768
|
-
// block-remaining
|
|
769
|
-
const blockMessage = `BLOCKED: Job ${verdict.jobId} has ${verdict.remaining} remaining slices. Run \`peaks job status\`. Use --force-under-job only with explicit user approval.`;
|
|
770
|
-
const envelope = fail('code.emit-handoff', JOB_REMAINING_BLOCKED, blockMessage, { jobId: verdict.jobId, remaining: verdict.remaining }, [
|
|
771
|
-
`Run \`peaks job status --job-id ${verdict.jobId}\` to see remaining slices.`,
|
|
772
|
-
'Resume Step 0.81 (per-slice checkpoint loop) and continue until remaining === 0.',
|
|
773
|
-
'Use --force-under-job only with explicit user approval (size-fear ban override).'
|
|
774
|
-
]);
|
|
775
|
-
io.stderr(`${blockMessage}\n`);
|
|
776
|
-
printResult(io, envelope, opts.json);
|
|
777
|
-
process.exitCode = 1;
|
|
778
|
-
return;
|
|
779
|
-
}
|
|
780
|
-
catch (err) {
|
|
781
|
-
printResult(io, fail('code.emit-handoff', 'EMIT_HANDOFF_FAILED', getErrorMessage(err), null, [
|
|
782
|
-
'Verify the project path and try again'
|
|
783
|
-
]), opts.json);
|
|
784
|
-
process.exitCode = 1;
|
|
785
|
-
}
|
|
786
|
-
});
|
|
787
|
-
}
|
|
788
|
-
function readActiveSid(projectRoot) {
|
|
789
|
-
try {
|
|
790
|
-
const presence = getSkillPresence(projectRoot);
|
|
791
|
-
if (presence === null || presence === undefined)
|
|
792
|
-
return null;
|
|
793
|
-
return presence.sessionId ?? null;
|
|
794
|
-
}
|
|
795
|
-
catch { // TODO(g2): legacy silent catch — grace: 1 minor release (v2.14.0)
|
|
796
|
-
return null;
|
|
797
|
-
}
|
|
114
|
+
registerCodeModeGateCommands(code, io);
|
|
115
|
+
registerCodeJobShapeCommands(code, io);
|
|
116
|
+
registerCodeRuntimeCommands(code, io);
|
|
117
|
+
registerCodeRunCommand(code, io);
|
|
798
118
|
}
|