peaks-loop 4.1.3 → 4.1.4
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/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +56 -0
- package/README-en.md +1 -1
- package/README.md +1 -1
- package/dist/cli/commands/asset-command-shared.d.ts +12 -0
- package/dist/cli/commands/asset-command-shared.js +45 -0
- package/dist/cli/commands/asset-commands.d.ts +6 -1
- package/dist/cli/commands/asset-commands.js +11 -372
- package/dist/cli/commands/asset-crystallize-command.d.ts +3 -0
- package/dist/cli/commands/asset-crystallize-command.js +60 -0
- package/dist/cli/commands/asset-crystallize-payload.d.ts +47 -0
- package/dist/cli/commands/asset-crystallize-payload.js +85 -0
- package/dist/cli/commands/asset-crystallize-runner.d.ts +3 -0
- package/dist/cli/commands/asset-crystallize-runner.js +133 -0
- package/dist/cli/commands/asset-dispose-command.d.ts +3 -0
- package/dist/cli/commands/asset-dispose-command.js +99 -0
- package/dist/cli/commands/asset-status-command.d.ts +3 -0
- package/dist/cli/commands/asset-status-command.js +100 -0
- package/dist/cli/commands/baseline-audit-command.d.ts +3 -0
- package/dist/cli/commands/baseline-audit-command.js +64 -0
- package/dist/cli/commands/baseline-command-shared.d.ts +23 -0
- package/dist/cli/commands/baseline-command-shared.js +39 -0
- package/dist/cli/commands/baseline-commands.js +33 -313
- package/dist/cli/commands/baseline-freeze-commands.d.ts +4 -0
- package/dist/cli/commands/baseline-freeze-commands.js +81 -0
- package/dist/cli/commands/baseline-guard-command.d.ts +3 -0
- package/dist/cli/commands/baseline-guard-command.js +52 -0
- package/dist/cli/commands/baseline-read-commands.d.ts +5 -0
- package/dist/cli/commands/baseline-read-commands.js +72 -0
- package/dist/cli/commands/baseline-rollback-commands.d.ts +4 -0
- package/dist/cli/commands/baseline-rollback-commands.js +88 -0
- package/dist/cli/commands/classify-downgrade-command.d.ts +9 -0
- package/dist/cli/commands/classify-downgrade-command.js +21 -0
- package/dist/cli/commands/classify-run-command.d.ts +9 -0
- package/dist/cli/commands/classify-run-command.js +73 -0
- package/dist/cli/commands/classify-signals.d.ts +5 -0
- package/dist/cli/commands/classify-signals.js +104 -0
- package/dist/cli/commands/code-emit-handoff-command.js +40 -3
- package/dist/cli/commands/code-gate-step-08-command.js +25 -9
- package/dist/cli/commands/codegraph-command-options.d.ts +22 -0
- package/dist/cli/commands/codegraph-command-options.js +22 -0
- package/dist/cli/commands/codegraph-commands.d.ts +2 -2
- package/dist/cli/commands/codegraph-commands.js +14 -397
- package/dist/cli/commands/codegraph-config-restore-command.d.ts +3 -0
- package/dist/cli/commands/codegraph-config-restore-command.js +200 -0
- package/dist/cli/commands/codegraph-proxy-commands.d.ts +10 -0
- package/dist/cli/commands/codegraph-proxy-commands.js +159 -0
- package/dist/cli/commands/codegraph-repair-commands.d.ts +3 -0
- package/dist/cli/commands/codegraph-repair-commands.js +94 -0
- package/dist/cli/commands/codegraph-status-command.d.ts +1 -1
- package/dist/cli/commands/codegraph-status-command.js +27 -214
- package/dist/cli/commands/codegraph-status-integrity.d.ts +44 -0
- package/dist/cli/commands/codegraph-status-integrity.js +121 -0
- package/dist/cli/commands/codegraph-status-json.d.ts +5 -0
- package/dist/cli/commands/codegraph-status-json.js +127 -0
- package/dist/cli/commands/container-command-shared.d.ts +60 -0
- package/dist/cli/commands/container-command-shared.js +52 -0
- package/dist/cli/commands/container-commands.d.ts +1 -1
- package/dist/cli/commands/container-commands.js +4 -216
- package/dist/cli/commands/container-release-command.d.ts +3 -0
- package/dist/cli/commands/container-release-command.js +105 -0
- package/dist/cli/commands/container-spawn-command.d.ts +3 -0
- package/dist/cli/commands/container-spawn-command.js +148 -0
- package/dist/cli/commands/context-check-command.d.ts +3 -0
- package/dist/cli/commands/context-check-command.js +81 -0
- package/dist/cli/commands/context-commands.d.ts +2 -7
- package/dist/cli/commands/context-commands.js +6 -276
- package/dist/cli/commands/context-layer-command.d.ts +3 -0
- package/dist/cli/commands/context-layer-command.js +34 -0
- package/dist/cli/commands/context-layer-fetchers.d.ts +15 -0
- package/dist/cli/commands/context-layer-fetchers.js +162 -0
- package/dist/cli/commands/context-status-command.d.ts +17 -0
- package/dist/cli/commands/context-status-command.js +41 -0
- package/dist/cli/commands/contract-write-command.d.ts +3 -0
- package/dist/cli/commands/contract-write-command.js +144 -0
- package/dist/cli/commands/core/doctor-bindings.d.ts +17 -0
- package/dist/cli/commands/core/doctor-bindings.js +30 -0
- package/dist/cli/commands/core/doctor-command.d.ts +4 -18
- package/dist/cli/commands/core/doctor-command.js +2 -323
- package/dist/cli/commands/core/doctor-logs.d.ts +8 -0
- package/dist/cli/commands/core/doctor-logs.js +32 -0
- package/dist/cli/commands/core/doctor-probes.d.ts +3 -0
- package/dist/cli/commands/core/doctor-probes.js +55 -0
- package/dist/cli/commands/core/doctor-run-command.d.ts +12 -0
- package/dist/cli/commands/core/doctor-run-command.js +172 -0
- package/dist/cli/commands/core/doctor-summary.d.ts +7 -0
- package/dist/cli/commands/core/doctor-summary.js +39 -0
- package/dist/cli/commands/core/memory-command-shared.d.ts +25 -0
- package/dist/cli/commands/core/memory-command-shared.js +20 -0
- package/dist/cli/commands/core/memory-command.d.ts +1 -1
- package/dist/cli/commands/core/memory-command.js +6 -227
- package/dist/cli/commands/core/memory-delegated-verbs.d.ts +4 -0
- package/dist/cli/commands/core/memory-delegated-verbs.js +178 -0
- package/dist/cli/commands/core/memory-extract-command.d.ts +3 -0
- package/dist/cli/commands/core/memory-extract-command.js +90 -0
- package/dist/cli/commands/core/memory-sync-command.d.ts +3 -0
- package/dist/cli/commands/core/memory-sync-command.js +38 -0
- package/dist/cli/commands/core/session-command.d.ts +1 -1
- package/dist/cli/commands/core/session-command.js +12 -206
- package/dist/cli/commands/core/session-info-command.d.ts +3 -0
- package/dist/cli/commands/core/session-info-command.js +142 -0
- package/dist/cli/commands/core/session-verb-commands.d.ts +5 -0
- package/dist/cli/commands/core/session-verb-commands.js +58 -0
- package/dist/cli/commands/core/standards-command.d.ts +1 -24
- package/dist/cli/commands/core/standards-command.js +33 -201
- package/dist/cli/commands/core/standards-init-command.d.ts +3 -0
- package/dist/cli/commands/core/standards-init-command.js +87 -0
- package/dist/cli/commands/core/standards-lint.d.ts +24 -0
- package/dist/cli/commands/core/standards-lint.js +57 -0
- package/dist/cli/commands/core/standards-migrate-command.d.ts +3 -0
- package/dist/cli/commands/core/standards-migrate-command.js +57 -0
- package/dist/cli/commands/cron-scheduler-commands.d.ts +5 -1
- package/dist/cli/commands/cron-scheduler-commands.js +36 -206
- package/dist/cli/commands/cron-scheduler-run-once-command.d.ts +7 -0
- package/dist/cli/commands/cron-scheduler-run-once-command.js +35 -0
- package/dist/cli/commands/cron-scheduler-shared.d.ts +6 -0
- package/dist/cli/commands/cron-scheduler-shared.js +48 -0
- package/dist/cli/commands/cron-scheduler-start-command.d.ts +7 -0
- package/dist/cli/commands/cron-scheduler-start-command.js +65 -0
- package/dist/cli/commands/cron-scheduler-status-command.d.ts +7 -0
- package/dist/cli/commands/cron-scheduler-status-command.js +46 -0
- package/dist/cli/commands/cron-scheduler-stop-command.d.ts +7 -0
- package/dist/cli/commands/cron-scheduler-stop-command.js +61 -0
- package/dist/cli/commands/dispatch-dag-envelope.d.ts +41 -0
- package/dist/cli/commands/dispatch-dag-envelope.js +49 -0
- package/dist/cli/commands/dispatch-dag-failure.d.ts +18 -0
- package/dist/cli/commands/dispatch-dag-failure.js +16 -0
- package/dist/cli/commands/dispatch-dag-preflight.d.ts +51 -0
- package/dist/cli/commands/dispatch-dag-preflight.js +105 -0
- package/dist/cli/commands/dispatch-dag-runners.d.ts +48 -0
- package/dist/cli/commands/dispatch-dag-runners.js +73 -0
- package/dist/cli/commands/dispatch-from-dag.d.ts +27 -0
- package/dist/cli/commands/dispatch-from-dag.js +87 -257
- package/dist/cli/commands/final-review-command-envelopes.d.ts +44 -0
- package/dist/cli/commands/final-review-command-envelopes.js +100 -0
- package/dist/cli/commands/final-review-command-shared.d.ts +52 -0
- package/dist/cli/commands/final-review-command-shared.js +35 -0
- package/dist/cli/commands/final-review-commands.d.ts +7 -27
- package/dist/cli/commands/final-review-commands.js +13 -240
- package/dist/cli/commands/final-review-prepare-command.d.ts +3 -0
- package/dist/cli/commands/final-review-prepare-command.js +200 -0
- package/dist/cli/commands/governance-classify-contract-commands.d.ts +23 -9
- package/dist/cli/commands/governance-classify-contract-commands.js +26 -269
- package/dist/cli/commands/hooks-command-shared.d.ts +42 -0
- package/dist/cli/commands/hooks-command-shared.js +32 -0
- package/dist/cli/commands/hooks-commands.d.ts +20 -0
- package/dist/cli/commands/hooks-commands.js +75 -309
- package/dist/cli/commands/hooks-install-envelopes.d.ts +6 -0
- package/dist/cli/commands/hooks-install-envelopes.js +144 -0
- package/dist/cli/commands/hooks-status-command.d.ts +3 -0
- package/dist/cli/commands/hooks-status-command.js +93 -0
- package/dist/cli/commands/hooks-uninstall-command.d.ts +3 -0
- package/dist/cli/commands/hooks-uninstall-command.js +43 -0
- package/dist/cli/commands/loop-command-shared.d.ts +31 -0
- package/dist/cli/commands/loop-command-shared.js +15 -0
- package/dist/cli/commands/loop-commands.d.ts +12 -17
- package/dist/cli/commands/loop-commands.js +56 -238
- package/dist/cli/commands/loop-export-command.d.ts +3 -0
- package/dist/cli/commands/loop-export-command.js +73 -0
- package/dist/cli/commands/loop-goal-compose-command.d.ts +3 -0
- package/dist/cli/commands/loop-goal-compose-command.js +36 -0
- package/dist/cli/commands/loop-import-command.d.ts +3 -0
- package/dist/cli/commands/loop-import-command.js +86 -0
- package/dist/cli/commands/loop-placeholder-commands.d.ts +3 -0
- package/dist/cli/commands/loop-placeholder-commands.js +52 -0
- package/dist/cli/commands/memory-command-shared.d.ts +59 -0
- package/dist/cli/commands/memory-command-shared.js +39 -0
- package/dist/cli/commands/memory-commands.d.ts +6 -79
- package/dist/cli/commands/memory-commands.js +19 -309
- package/dist/cli/commands/memory-ingest-command.d.ts +3 -0
- package/dist/cli/commands/memory-ingest-command.js +50 -0
- package/dist/cli/commands/memory-list-command.d.ts +16 -0
- package/dist/cli/commands/memory-list-command.js +129 -0
- package/dist/cli/commands/memory-reindex-command.d.ts +9 -0
- package/dist/cli/commands/memory-reindex-command.js +78 -0
- package/dist/cli/commands/memory-rotate-command.d.ts +3 -0
- package/dist/cli/commands/memory-rotate-command.js +55 -0
- package/dist/cli/commands/memory-search-command.d.ts +7 -0
- package/dist/cli/commands/memory-search-command.js +46 -0
- package/dist/cli/commands/openspec-archive-command.d.ts +3 -0
- package/dist/cli/commands/openspec-archive-command.js +55 -0
- package/dist/cli/commands/openspec-command-shared.d.ts +62 -0
- package/dist/cli/commands/openspec-command-shared.js +135 -0
- package/dist/cli/commands/openspec-commands.d.ts +1 -1
- package/dist/cli/commands/openspec-commands.js +33 -306
- package/dist/cli/commands/openspec-from-doctor-command.d.ts +3 -0
- package/dist/cli/commands/openspec-from-doctor-command.js +66 -0
- package/dist/cli/commands/openspec-init-command.d.ts +3 -0
- package/dist/cli/commands/openspec-init-command.js +49 -0
- package/dist/cli/commands/openspec-list-command.d.ts +3 -0
- package/dist/cli/commands/openspec-list-command.js +27 -0
- package/dist/cli/commands/openspec-render-command.d.ts +3 -0
- package/dist/cli/commands/openspec-render-command.js +33 -0
- package/dist/cli/commands/openspec-show-command.d.ts +3 -0
- package/dist/cli/commands/openspec-show-command.js +33 -0
- package/dist/cli/commands/openspec-to-rd-command.d.ts +3 -0
- package/dist/cli/commands/openspec-to-rd-command.js +33 -0
- package/dist/cli/commands/openspec-validate-command.d.ts +3 -0
- package/dist/cli/commands/openspec-validate-command.js +45 -0
- package/dist/cli/commands/playwright-browser-command.d.ts +8 -0
- package/dist/cli/commands/playwright-browser-command.js +61 -0
- package/dist/cli/commands/playwright-commands.d.ts +10 -62
- package/dist/cli/commands/playwright-commands.js +77 -400
- package/dist/cli/commands/playwright-envelope.d.ts +8 -0
- package/dist/cli/commands/playwright-envelope.js +29 -0
- package/dist/cli/commands/playwright-ls-stop-commands.d.ts +4 -0
- package/dist/cli/commands/playwright-ls-stop-commands.js +74 -0
- package/dist/cli/commands/playwright-session-store.d.ts +65 -0
- package/dist/cli/commands/playwright-session-store.js +189 -0
- package/dist/cli/commands/project-commands.d.ts +19 -0
- package/dist/cli/commands/project-commands.js +98 -259
- package/dist/cli/commands/project-context-command.d.ts +3 -0
- package/dist/cli/commands/project-context-command.js +44 -0
- package/dist/cli/commands/project-dashboard-command.d.ts +3 -0
- package/dist/cli/commands/project-dashboard-command.js +74 -0
- package/dist/cli/commands/project-knowledge-command.d.ts +3 -0
- package/dist/cli/commands/project-knowledge-command.js +48 -0
- package/dist/cli/commands/project-memories-show-command.d.ts +3 -0
- package/dist/cli/commands/project-memories-show-command.js +87 -0
- package/dist/cli/commands/project-memory-index-command.d.ts +3 -0
- package/dist/cli/commands/project-memory-index-command.js +31 -0
- package/dist/cli/commands/qa-archive-screenshots-command.d.ts +3 -0
- package/dist/cli/commands/qa-archive-screenshots-command.js +53 -0
- package/dist/cli/commands/qa-commands.d.ts +14 -87
- package/dist/cli/commands/qa-commands.js +17 -315
- package/dist/cli/commands/qa-context-prestep.d.ts +1 -0
- package/dist/cli/commands/qa-context-prestep.js +34 -0
- package/dist/cli/commands/qa-run-command.d.ts +3 -0
- package/dist/cli/commands/qa-run-command.js +105 -0
- package/dist/cli/commands/qa-run-options.d.ts +23 -0
- package/dist/cli/commands/qa-run-options.js +31 -0
- package/dist/cli/commands/qa-run-slice.d.ts +41 -0
- package/dist/cli/commands/qa-run-slice.js +145 -0
- package/dist/cli/commands/release-canary-command.d.ts +28 -0
- package/dist/cli/commands/release-canary-command.js +129 -0
- package/dist/cli/commands/release-command-shared.d.ts +13 -0
- package/dist/cli/commands/release-command-shared.js +18 -0
- package/dist/cli/commands/release-commands.d.ts +10 -18
- package/dist/cli/commands/release-commands.js +25 -298
- package/dist/cli/commands/release-done-command.d.ts +3 -0
- package/dist/cli/commands/release-done-command.js +64 -0
- package/dist/cli/commands/release-hotfix-command.d.ts +3 -0
- package/dist/cli/commands/release-hotfix-command.js +50 -0
- package/dist/cli/commands/release-plan-command.d.ts +3 -0
- package/dist/cli/commands/release-plan-command.js +33 -0
- package/dist/cli/commands/release-precheck-command.d.ts +3 -0
- package/dist/cli/commands/release-precheck-command.js +28 -0
- package/dist/cli/commands/release-promote-command.d.ts +3 -0
- package/dist/cli/commands/release-promote-command.js +34 -0
- package/dist/cli/commands/release-rollback-command.d.ts +3 -0
- package/dist/cli/commands/release-rollback-command.js +33 -0
- package/dist/cli/commands/release-watch-command.d.ts +3 -0
- package/dist/cli/commands/release-watch-command.js +44 -0
- package/dist/cli/commands/sediment-argv-flags.d.ts +54 -0
- package/dist/cli/commands/sediment-argv-flags.js +116 -0
- package/dist/cli/commands/sediment-command-shared.d.ts +15 -0
- package/dist/cli/commands/sediment-command-shared.js +5 -0
- package/dist/cli/commands/sediment-commands.d.ts +35 -59
- package/dist/cli/commands/sediment-commands.js +36 -590
- package/dist/cli/commands/sediment-pool-commands.d.ts +9 -0
- package/dist/cli/commands/sediment-pool-commands.js +185 -0
- package/dist/cli/commands/sediment-query-commands.d.ts +4 -0
- package/dist/cli/commands/sediment-query-commands.js +94 -0
- package/dist/cli/commands/sediment-release-commands.d.ts +8 -0
- package/dist/cli/commands/sediment-release-commands.js +232 -0
- package/dist/cli/commands/sop-advance-command.d.ts +3 -0
- package/dist/cli/commands/sop-advance-command.js +160 -0
- package/dist/cli/commands/sop-check-command.d.ts +3 -0
- package/dist/cli/commands/sop-check-command.js +44 -0
- package/dist/cli/commands/sop-command-shared.d.ts +23 -0
- package/dist/cli/commands/sop-command-shared.js +18 -0
- package/dist/cli/commands/sop-commands.d.ts +15 -1
- package/dist/cli/commands/sop-commands.js +26 -240
- package/dist/cli/commands/sop-init-command.d.ts +3 -0
- package/dist/cli/commands/sop-init-command.js +51 -0
- package/dist/cli/commands/sop-lint-command.d.ts +3 -0
- package/dist/cli/commands/sop-lint-command.js +64 -0
- package/dist/cli/commands/sop-register-command.d.ts +3 -0
- package/dist/cli/commands/sop-register-command.js +48 -0
- package/dist/cli/commands/sop-registry-command.d.ts +3 -0
- package/dist/cli/commands/sop-registry-command.js +30 -0
- package/dist/cli/commands/statusline-command-shared.d.ts +73 -0
- package/dist/cli/commands/statusline-command-shared.js +90 -0
- package/dist/cli/commands/statusline-commands.d.ts +1 -19
- package/dist/cli/commands/statusline-commands.js +48 -287
- package/dist/cli/commands/statusline-compact-command.d.ts +4 -0
- package/dist/cli/commands/statusline-compact-command.js +54 -0
- package/dist/cli/commands/statusline-install-command.d.ts +3 -0
- package/dist/cli/commands/statusline-install-command.js +48 -0
- package/dist/cli/commands/statusline-render-command.d.ts +9 -0
- package/dist/cli/commands/statusline-render-command.js +55 -0
- package/dist/cli/commands/statusline-status-command.d.ts +3 -0
- package/dist/cli/commands/statusline-status-command.js +23 -0
- package/dist/cli/commands/statusline-uninstall-command.d.ts +3 -0
- package/dist/cli/commands/statusline-uninstall-command.js +23 -0
- package/dist/cli/commands/test-command-run-helpers.d.ts +27 -0
- package/dist/cli/commands/test-command-run-helpers.js +73 -0
- package/dist/cli/commands/test-command-runner-resolution.d.ts +57 -0
- package/dist/cli/commands/test-command-runner-resolution.js +183 -0
- package/dist/cli/commands/test-commands.d.ts +8 -56
- package/dist/cli/commands/test-commands.js +26 -249
- package/dist/cli/commands/vm-command-shared.d.ts +23 -0
- package/dist/cli/commands/vm-command-shared.js +23 -0
- package/dist/cli/commands/vm-commands.d.ts +1 -28
- package/dist/cli/commands/vm-commands.js +36 -270
- package/dist/cli/commands/vm-hypervisor-runtime.d.ts +15 -0
- package/dist/cli/commands/vm-hypervisor-runtime.js +64 -0
- package/dist/cli/commands/vm-release-command.d.ts +5 -0
- package/dist/cli/commands/vm-release-command.js +101 -0
- package/dist/cli/commands/vm-spawn-command.d.ts +5 -0
- package/dist/cli/commands/vm-spawn-command.js +177 -0
- package/dist/cli/commands/web-command-shared.d.ts +12 -0
- package/dist/cli/commands/web-command-shared.js +30 -0
- package/dist/cli/commands/web-commands.d.ts +7 -14
- package/dist/cli/commands/web-commands.js +6 -314
- package/dist/cli/commands/web-install-command.d.ts +10 -0
- package/dist/cli/commands/web-install-command.js +116 -0
- package/dist/cli/commands/web-lifecycle-commands.d.ts +9 -30
- package/dist/cli/commands/web-lifecycle-commands.js +14 -322
- package/dist/cli/commands/web-login-command.d.ts +14 -0
- package/dist/cli/commands/web-login-command.js +189 -0
- package/dist/cli/commands/web-op-payload.d.ts +22 -0
- package/dist/cli/commands/web-op-payload.js +89 -0
- package/dist/cli/commands/web-op-refusals.d.ts +37 -0
- package/dist/cli/commands/web-op-refusals.js +73 -0
- package/dist/cli/commands/web-op-runner.d.ts +14 -0
- package/dist/cli/commands/web-op-runner.js +166 -0
- package/dist/cli/commands/web-status-command.d.ts +4 -0
- package/dist/cli/commands/web-status-command.js +32 -0
- package/dist/cli/commands/web-stop-command.d.ts +10 -0
- package/dist/cli/commands/web-stop-command.js +59 -0
- package/dist/cli/commands/web-verb-specs.d.ts +18 -0
- package/dist/cli/commands/web-verb-specs.js +66 -0
- package/dist/cli/commands/workflow-command-shared.d.ts +102 -0
- package/dist/cli/commands/workflow-command-shared.js +74 -0
- package/dist/cli/commands/workflow-graph-commands.d.ts +3 -0
- package/dist/cli/commands/workflow-graph-commands.js +73 -0
- package/dist/cli/commands/workflow-init-command.d.ts +3 -0
- package/dist/cli/commands/workflow-init-command.js +68 -0
- package/dist/cli/commands/workflow-lifecycle-commands.d.ts +9 -59
- package/dist/cli/commands/workflow-lifecycle-commands.js +14 -348
- package/dist/cli/commands/workflow-node-commands.d.ts +3 -0
- package/dist/cli/commands/workflow-node-commands.js +154 -0
- package/dist/cli/commands/workflow-terminalize-command.d.ts +3 -0
- package/dist/cli/commands/workflow-terminalize-command.js +56 -0
- package/dist/services/code/auto-compact-artifacts.d.ts +54 -0
- package/dist/services/code/auto-compact-artifacts.js +135 -0
- package/dist/services/code/auto-compact-attempt.d.ts +46 -0
- package/dist/services/code/auto-compact-attempt.js +88 -0
- package/dist/services/code/auto-compact-decision.d.ts +74 -0
- package/dist/services/code/auto-compact-decision.js +149 -0
- package/dist/services/code/auto-compact-dispatch-gate.d.ts +36 -0
- package/dist/services/code/auto-compact-dispatch-gate.js +86 -0
- package/dist/services/code/auto-compact-envelopes.d.ts +33 -0
- package/dist/services/code/auto-compact-envelopes.js +134 -0
- package/dist/services/code/auto-compact-history.d.ts +46 -0
- package/dist/services/code/auto-compact-history.js +17 -0
- package/dist/services/code/auto-compact-orchestrator.d.ts +11 -240
- package/dist/services/code/auto-compact-orchestrator.js +165 -686
- package/dist/services/code/auto-compact-run-types.d.ts +123 -0
- package/dist/services/code/auto-compact-run-types.js +1 -0
- package/dist/services/code/emit-handoff.d.ts +35 -1
- package/dist/services/code/emit-handoff.js +128 -7
- package/dist/services/code/step-08-gate.d.ts +28 -19
- package/dist/services/code/step-08-gate.js +92 -35
- package/dist/services/config/config-coercion.d.ts +7 -0
- package/dist/services/config/config-coercion.js +156 -0
- package/dist/services/config/config-file-io.d.ts +11 -0
- package/dist/services/config/config-file-io.js +61 -0
- package/dist/services/config/config-get.d.ts +2 -0
- package/dist/services/config/config-get.js +36 -0
- package/dist/services/config/config-global-loader.d.ts +15 -0
- package/dist/services/config/config-global-loader.js +111 -0
- package/dist/services/config/config-nested-path.d.ts +3 -0
- package/dist/services/config/config-nested-path.js +53 -0
- package/dist/services/config/config-primitives.d.ts +16 -0
- package/dist/services/config/config-primitives.js +24 -0
- package/dist/services/config/config-service.d.ts +9 -33
- package/dist/services/config/config-service.js +16 -665
- package/dist/services/config/config-validation.d.ts +19 -0
- package/dist/services/config/config-validation.js +152 -0
- package/dist/services/config/config-workspace.d.ts +10 -0
- package/dist/services/config/config-workspace.js +158 -0
- package/dist/services/skills/hooks-settings-deny-list.d.ts +61 -0
- package/dist/services/skills/hooks-settings-deny-list.js +173 -0
- package/dist/services/skills/hooks-settings-envelopes.d.ts +20 -0
- package/dist/services/skills/hooks-settings-envelopes.js +79 -0
- package/dist/services/skills/hooks-settings-file-shape.d.ts +43 -0
- package/dist/services/skills/hooks-settings-file-shape.js +207 -0
- package/dist/services/skills/hooks-settings-paths.d.ts +34 -0
- package/dist/services/skills/hooks-settings-paths.js +75 -0
- package/dist/services/skills/hooks-settings-read-installed.d.ts +39 -0
- package/dist/services/skills/hooks-settings-read-installed.js +60 -0
- package/dist/services/skills/hooks-settings-service.d.ts +12 -212
- package/dist/services/skills/hooks-settings-service.js +71 -657
- package/dist/services/skills/hooks-settings-types.d.ts +139 -0
- package/dist/services/skills/hooks-settings-types.js +1 -0
- package/dist/services/workspace/claude-settings-template-merge.d.ts +89 -0
- package/dist/services/workspace/claude-settings-template-merge.js +243 -0
- package/dist/services/workspace/claude-settings-template.d.ts +29 -87
- package/dist/services/workspace/claude-settings-template.js +81 -236
- package/package.json +5 -5
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type ProgramIO } from '../../cli-helpers.js';
|
|
2
|
+
/** A `--dry-run --apply` refusal, resolved per verb. */
|
|
3
|
+
export type FlagConflict = {
|
|
4
|
+
readonly command: string;
|
|
5
|
+
readonly code: string;
|
|
6
|
+
readonly nextActions: readonly string[];
|
|
7
|
+
readonly json: boolean | undefined;
|
|
8
|
+
readonly dryRun: boolean | undefined;
|
|
9
|
+
readonly apply: boolean | undefined;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* `--dry-run` and `--apply` are mutually exclusive: previewing and writing in
|
|
13
|
+
* one invocation has no defined meaning, so refuse before any work happens.
|
|
14
|
+
*/
|
|
15
|
+
export declare function refuseBothFlags(io: ProgramIO, conflict: FlagConflict): boolean;
|
|
16
|
+
/** A verb whose lazy `memory-commands.ts` import or run failed. */
|
|
17
|
+
export type BootstrapFailure = {
|
|
18
|
+
readonly command: string;
|
|
19
|
+
readonly code: string;
|
|
20
|
+
readonly message: string;
|
|
21
|
+
readonly json: boolean | undefined;
|
|
22
|
+
readonly nextActions?: readonly string[] | undefined;
|
|
23
|
+
};
|
|
24
|
+
/** Print the `*_BOOTSTRAP_FAILED` envelope and mark the process failed. */
|
|
25
|
+
export declare function emitBootstrapFailure(io: ProgramIO, failure: BootstrapFailure): void;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { fail } from 'peaks-loop-shared/result';
|
|
2
|
+
import { printResult } from '../../cli-helpers.js';
|
|
3
|
+
/**
|
|
4
|
+
* `--dry-run` and `--apply` are mutually exclusive: previewing and writing in
|
|
5
|
+
* one invocation has no defined meaning, so refuse before any work happens.
|
|
6
|
+
*/
|
|
7
|
+
export function refuseBothFlags(io, conflict) {
|
|
8
|
+
if (!(conflict.dryRun === true && conflict.apply === true))
|
|
9
|
+
return false;
|
|
10
|
+
printResult(io, fail(conflict.command, conflict.code, 'Use either --dry-run or --apply, not both', {}, [
|
|
11
|
+
...conflict.nextActions
|
|
12
|
+
]), conflict.json);
|
|
13
|
+
process.exitCode = 1;
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
/** Print the `*_BOOTSTRAP_FAILED` envelope and mark the process failed. */
|
|
17
|
+
export function emitBootstrapFailure(io, failure) {
|
|
18
|
+
printResult(io, fail(failure.command, failure.code, failure.message, {}, [...(failure.nextActions ?? [])]), failure.json);
|
|
19
|
+
process.exitCode = 1;
|
|
20
|
+
}
|
|
@@ -1,230 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
/** Derived from the canonical kind vocabulary — never hand-maintain a list here. */
|
|
5
|
-
const KIND_HELP = VALID_PROJECT_MEMORY_KINDS.join(', ');
|
|
1
|
+
import { registerMemoryDelegatedVerbs } from './memory-delegated-verbs.js';
|
|
2
|
+
import { registerMemoryExtractCommand } from './memory-extract-command.js';
|
|
3
|
+
import { registerMemorySyncCommand } from './memory-sync-command.js';
|
|
6
4
|
export function registerMemoryCommand(program, io) {
|
|
7
5
|
const memory = program.command('memory').description('Manage project-local Peaks memory');
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
.requiredOption('--project <path>', 'target project root')
|
|
12
|
-
.requiredOption('--artifact <path...>', 'skill artifact paths inside the project')
|
|
13
|
-
.option('--dry-run', 'preview writes without changing files')
|
|
14
|
-
.option('--apply', 'write extracted memories into project .peaks/memory')).action((options) => {
|
|
15
|
-
if (options.dryRun === true && options.apply === true) {
|
|
16
|
-
printResult(io, fail('memory.extract', 'INVALID_MEMORY_EXTRACT_FLAGS', 'Use either --dry-run or --apply, not both', {}, ['Run without --apply to preview writes, or pass --apply to write memories']), options.json);
|
|
17
|
-
process.exitCode = 1;
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
try {
|
|
21
|
-
const result = executeProjectMemoryExtract({
|
|
22
|
-
projectRoot: options.project,
|
|
23
|
-
artifactPaths: options.artifact,
|
|
24
|
-
apply: options.apply === true
|
|
25
|
-
});
|
|
26
|
-
// A block that was found but not extracted must not vanish silently: the
|
|
27
|
-
// parser's rejection reasons ride the envelope's existing `warnings`
|
|
28
|
-
// channel (JSON: `warnings[]`; human: `warning: …` on stderr). `data` is
|
|
29
|
-
// unchanged — this adds no field to the summary.
|
|
30
|
-
printResult(io, ok('memory.extract', summarizeProjectMemoryExtractResult(result), describeMemoryBlockDrops(result.droppedBlocks)), options.json);
|
|
31
|
-
}
|
|
32
|
-
catch (error) {
|
|
33
|
-
const refusal = error instanceof UnsafeMemoryError ? error : null;
|
|
34
|
-
printResult(io, fail('memory.extract', 'MEMORY_EXTRACT_FAILED', getErrorMessage(error),
|
|
35
|
-
// The check and the term are facts about the failure, so they ride
|
|
36
|
-
// the envelope's data — not just its prose. `fail()` redacts
|
|
37
|
-
// `message` (see `UnsafeMemoryError`), so the term would otherwise
|
|
38
|
-
// reach the reader as `[redacted]`; `data` is passed through.
|
|
39
|
-
refusal === null ? {} : { check: refusal.check, matchedTerm: refusal.matchedTerm }, memoryExtractNextActions(refusal)), options.json);
|
|
40
|
-
process.exitCode = 1;
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
addJsonOption(memory
|
|
44
|
-
.command('sync')
|
|
45
|
-
.description('Back up project .peaks/memory into the artifact workspace')
|
|
46
|
-
.requiredOption('--project <path>', 'target project root')
|
|
47
|
-
.requiredOption('--workspace <path>', 'artifact workspace path')
|
|
48
|
-
.option('--dry-run', 'preview copies without changing files')
|
|
49
|
-
.option('--apply', 'copy project .peaks/memory into artifact workspace backup')).action((options) => {
|
|
50
|
-
if (options.dryRun === true && options.apply === true) {
|
|
51
|
-
printResult(io, fail('memory.sync', 'INVALID_MEMORY_SYNC_FLAGS', 'Use either --dry-run or --apply, not both', {}, ['Run without --apply to preview copies, or pass --apply to back up memories']), options.json);
|
|
52
|
-
process.exitCode = 1;
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
try {
|
|
56
|
-
const result = executeProjectMemoryBackup({
|
|
57
|
-
projectRoot: options.project,
|
|
58
|
-
artifactWorkspacePath: options.workspace,
|
|
59
|
-
apply: options.apply === true
|
|
60
|
-
});
|
|
61
|
-
printResult(io, ok('memory.sync', summarizeProjectMemoryBackupResult(result)), options.json);
|
|
62
|
-
}
|
|
63
|
-
catch (error) {
|
|
64
|
-
printResult(io, fail('memory.sync', 'MEMORY_SYNC_FAILED', getErrorMessage(error), {}, [
|
|
65
|
-
'Use an artifact workspace outside the project root'
|
|
66
|
-
]), options.json);
|
|
67
|
-
process.exitCode = 1;
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
addJsonOption(memory
|
|
71
|
-
.command('list')
|
|
72
|
-
.description('List all memory entries from .peaks/memory/index.json. Pass --pick to spawn fzf for interactive multi-select; the picked subset is written to .peaks/memory/picked.json.')
|
|
73
|
-
.option('--kind <kind>', `filter by memory kind (one of: ${KIND_HELP})`)
|
|
74
|
-
.option('--pick', 'spawn fzf for interactive multi-select (requires fzf >= 0.38); writes picked.json')
|
|
75
|
-
.option('--fzf-bin <path>', 'override fzf binary path (default: fzf on PATH)', 'fzf')
|
|
76
|
-
.option('--summary', 'emit counts + names-of-first-N only (≤ 2 KB) instead of the full entry array; the default envelope is unchanged')
|
|
77
|
-
.option('--project <path>', 'target project root (defaults to git root or cwd)')).action((options) => {
|
|
78
|
-
void import('../memory-commands.js')
|
|
79
|
-
.then(({ runMemoryList }) => {
|
|
80
|
-
void runMemoryList(io, {
|
|
81
|
-
...(options.kind !== undefined ? { kind: options.kind } : {}),
|
|
82
|
-
...(options.pick === true ? { pick: true } : {}),
|
|
83
|
-
...(options.fzfBin ? { fzfBin: options.fzfBin } : {}),
|
|
84
|
-
...(options.project !== undefined ? { project: options.project } : {}),
|
|
85
|
-
...(options.summary === true ? { summary: true } : {}),
|
|
86
|
-
...(options.json !== undefined ? { json: options.json } : {})
|
|
87
|
-
});
|
|
88
|
-
})
|
|
89
|
-
.catch((error) => {
|
|
90
|
-
const msg = /brew install fzf|apt-get install fzf|older than required/.test(getErrorMessage(error))
|
|
91
|
-
? 'fzf binary not found or too old. Install with: brew install fzf (or apt: apt-get install fzf). peaks memory list --pick requires fzf >= 0.38.'
|
|
92
|
-
: getErrorMessage(error);
|
|
93
|
-
const code = /brew install fzf|apt-get install fzf|older than required/.test(msg)
|
|
94
|
-
? 'FZF_UNAVAILABLE'
|
|
95
|
-
: 'MEMORY_LIST_BOOTSTRAP_FAILED';
|
|
96
|
-
printResult(io, fail('memory.list', code, msg, {}, [
|
|
97
|
-
'Install fzf or run without --pick to list entries as JSON'
|
|
98
|
-
]), options.json);
|
|
99
|
-
if (code === 'FZF_UNAVAILABLE')
|
|
100
|
-
process.exitCode = 127;
|
|
101
|
-
else
|
|
102
|
-
process.exitCode = 1;
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
addJsonOption(memory
|
|
106
|
-
.command('reindex')
|
|
107
|
-
.description('Rebuild .peaks/memory/index.json from every memory file on disk and regenerate MEMORY.md; reports unclassified files and orphans both ways. Dry-run by default; pass --apply to write.')
|
|
108
|
-
.option('--project <path>', 'target project root (defaults to git root or cwd)')
|
|
109
|
-
.option('--dry-run', 'report drift without writing (default)')
|
|
110
|
-
.option('--apply', 'rebuild index.json and regenerate MEMORY.md')
|
|
111
|
-
.option('--summary', 'emit drift counts + names-of-first-N only (≤ 2 KB) instead of the full arrays; the default envelope is unchanged')).action((options) => {
|
|
112
|
-
void import('../memory-commands.js')
|
|
113
|
-
.then(({ runMemoryReindex }) => {
|
|
114
|
-
void runMemoryReindex(io, {
|
|
115
|
-
...(options.project !== undefined ? { project: options.project } : {}),
|
|
116
|
-
...(options.dryRun === true ? { dryRun: true } : {}),
|
|
117
|
-
...(options.apply === true ? { apply: true } : {}),
|
|
118
|
-
...(options.summary === true ? { summary: true } : {}),
|
|
119
|
-
...(options.json !== undefined ? { json: options.json } : {})
|
|
120
|
-
});
|
|
121
|
-
})
|
|
122
|
-
.catch((error) => {
|
|
123
|
-
printResult(io, fail('memory.reindex', 'MEMORY_REINDEX_BOOTSTRAP_FAILED', getErrorMessage(error), {}, []), options.json);
|
|
124
|
-
process.exitCode = 1;
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
addJsonOption(memory
|
|
128
|
-
.command('ingest')
|
|
129
|
-
.description('Import memories written by the IDE-side agent (~/.claude/projects/<hash>/memory/*.md) into the peaks-owned .peaks/memory store. The IDE-side dir is read-only. Dry-run by default; pass --apply to write.')
|
|
130
|
-
.option('--project <path>', 'target project root (defaults to git root or cwd)')
|
|
131
|
-
.option('--source-dir <path>', 'override the IDE-side memory directory')
|
|
132
|
-
.option('--dry-run', 'preview imports without writing (default)')
|
|
133
|
-
.option('--apply', 'write normalized memories into .peaks/memory')).action((options) => {
|
|
134
|
-
void import('../memory-commands.js')
|
|
135
|
-
.then(({ runMemoryIngest }) => {
|
|
136
|
-
void runMemoryIngest(io, {
|
|
137
|
-
...(options.project !== undefined ? { project: options.project } : {}),
|
|
138
|
-
...(options.sourceDir !== undefined ? { sourceDir: options.sourceDir } : {}),
|
|
139
|
-
...(options.dryRun === true ? { dryRun: true } : {}),
|
|
140
|
-
...(options.apply === true ? { apply: true } : {}),
|
|
141
|
-
...(options.json !== undefined ? { json: options.json } : {})
|
|
142
|
-
});
|
|
143
|
-
})
|
|
144
|
-
.catch((error) => {
|
|
145
|
-
printResult(io, fail('memory.ingest', 'MEMORY_INGEST_BOOTSTRAP_FAILED', getErrorMessage(error), {}, []), options.json);
|
|
146
|
-
process.exitCode = 1;
|
|
147
|
-
});
|
|
148
|
-
});
|
|
149
|
-
addJsonOption(memory
|
|
150
|
-
.command('rotate')
|
|
151
|
-
.description('Tier-driven retention for .peaks/memory/ (sediment pruning policy, tier 1: archive only, never delete). Tier assignment: explicit `metadata.tier: A|B|C|D` wins; else files under archived/ are D, files pinned in MEMORY.md are B, kinds rule/convention/project-rule are A, kinds decision/reference/feedback/module/bug/investigation/technical-pattern are B, everything else is C. Tier C older than 6 months (frontmatter updatedAt/updated/modified, else file mtime) and not pinned is archived; tier D is reported as a delete-candidate only. Tier A/B are never selected, every candidate must pass a reference grep against src/ + skills/, and --apply refuses an empty plan or a failed gate. Dry-run by default.')
|
|
152
|
-
.option('--project <path>', 'target project root (defaults to git root or cwd)')
|
|
153
|
-
.option('--dry-run', 'report the rotation plan without moving anything (default)')
|
|
154
|
-
.option('--apply', 'move tier-C candidates into .peaks/memory/archived/')).action((options) => {
|
|
155
|
-
void import('../memory-commands.js')
|
|
156
|
-
.then(({ runMemoryRotate }) => {
|
|
157
|
-
void runMemoryRotate(io, {
|
|
158
|
-
...(options.project !== undefined ? { project: options.project } : {}),
|
|
159
|
-
...(options.dryRun === true ? { dryRun: true } : {}),
|
|
160
|
-
...(options.apply === true ? { apply: true } : {}),
|
|
161
|
-
...(options.json !== undefined ? { json: options.json } : {})
|
|
162
|
-
});
|
|
163
|
-
})
|
|
164
|
-
.catch((error) => {
|
|
165
|
-
printResult(io, fail('memory.rotate', 'MEMORY_ROTATE_BOOTSTRAP_FAILED', getErrorMessage(error), {}, []), options.json);
|
|
166
|
-
process.exitCode = 1;
|
|
167
|
-
});
|
|
168
|
-
});
|
|
169
|
-
addJsonOption(memory
|
|
170
|
-
.command('search <query>')
|
|
171
|
-
.description('Fuzzy-search the memory index (deterministic, local, zero-token). Default --limit 6.')
|
|
172
|
-
.option('--kind <kind>', `filter by memory kind (one of: ${KIND_HELP})`)
|
|
173
|
-
.option('--limit <n>', 'maximum number of matches to return', (value) => Number(value))
|
|
174
|
-
.option('--project <path>', 'target project root (defaults to git root or cwd)')).action((query, options) => {
|
|
175
|
-
// Lazy import avoids a top-of-file import cycle (memory-commands.ts
|
|
176
|
-
// imports services that the rest of this file may also touch).
|
|
177
|
-
void import('../memory-commands.js')
|
|
178
|
-
.then(({ runMemorySearch }) => {
|
|
179
|
-
void runMemorySearch(io, {
|
|
180
|
-
query,
|
|
181
|
-
...(options.kind !== undefined ? { kind: options.kind } : {}),
|
|
182
|
-
...(options.limit !== undefined ? { limit: options.limit } : {}),
|
|
183
|
-
...(options.project !== undefined ? { project: options.project } : {}),
|
|
184
|
-
...(options.json !== undefined ? { json: options.json } : {})
|
|
185
|
-
});
|
|
186
|
-
})
|
|
187
|
-
.catch((error) => {
|
|
188
|
-
printResult(io, fail('memory.search', 'MEMORY_SEARCH_BOOTSTRAP_FAILED', getErrorMessage(error), {}, []), options.json);
|
|
189
|
-
process.exitCode = 1;
|
|
190
|
-
});
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
/**
|
|
194
|
-
* The remedy for a failed `memory extract`, chosen by the check that refused
|
|
195
|
-
* the write — the same `SENSITIVE_MEMORY_CHECKS` values the refusal message
|
|
196
|
-
* and envelope data are built from, so the message, the data and the advice
|
|
197
|
-
* cannot drift apart.
|
|
198
|
-
*
|
|
199
|
-
* WHY IT IS NOT ONE STATIC STRING. Every failure used to get "Check artifact
|
|
200
|
-
* paths and remove secrets before extracting memory" — including a refusal
|
|
201
|
-
* raised only because a memory TITLE contained a word like `authority`
|
|
202
|
-
* (slice C0). There was no secret anywhere in that memory, so the one thing
|
|
203
|
-
* the hint told the user to do was the one thing that could not help: it sent
|
|
204
|
-
* check that actually failed.
|
|
205
|
-
*
|
|
206
|
-
* `null` (a failure that is not a safety refusal — a path escape, a missing
|
|
207
|
-
* artifact) keeps the pre-C0 hint, which is about paths and secrets rather
|
|
208
|
-
* than about a check.
|
|
209
|
-
*/
|
|
210
|
-
function memoryExtractNextActions(refusal) {
|
|
211
|
-
if (refusal === null) {
|
|
212
|
-
return ['Check artifact paths and remove secrets before extracting memory'];
|
|
213
|
-
}
|
|
214
|
-
if (refusal.check === SENSITIVE_MEMORY_CHECKS.title) {
|
|
215
|
-
return [
|
|
216
|
-
'Retitle the memory so it is not named after a credential term, then re-run memory extract'
|
|
217
|
-
];
|
|
218
|
-
}
|
|
219
|
-
if (refusal.check === SENSITIVE_MEMORY_CHECKS.content) {
|
|
220
|
-
// Name the rule, not just the family. `matchedTerm` is a closed id
|
|
221
|
-
// (`credential-assignment`, `bearer-value`, `pem-private-key`, …), so the
|
|
222
|
-
// reader can tell a credential in the text from a sentence that merely has
|
|
223
|
-
// the shape of one — which is the difference between removing a value and
|
|
224
|
-
// rewording prose.
|
|
225
|
-
return [
|
|
226
|
-
`Remove the credential value the "${refusal.matchedTerm}" pattern matched, then re-run memory extract`
|
|
227
|
-
];
|
|
228
|
-
}
|
|
229
|
-
return ['Remove the credential value from the memory content, then re-run memory extract'];
|
|
6
|
+
registerMemoryExtractCommand(memory, io);
|
|
7
|
+
registerMemorySyncCommand(memory, io);
|
|
8
|
+
registerMemoryDelegatedVerbs(memory, io);
|
|
230
9
|
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
import { type ProgramIO } from '../../cli-helpers.js';
|
|
3
|
+
/** The five verbs whose bodies live in `memory-commands.ts`, in shipping order. */
|
|
4
|
+
export declare function registerMemoryDelegatedVerbs(memory: Command, io: ProgramIO): void;
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { addJsonOption, getErrorMessage, printResult } from '../../cli-helpers.js';
|
|
2
|
+
import { fail } from 'peaks-loop-shared/result';
|
|
3
|
+
import { VALID_PROJECT_MEMORY_KINDS } from '../../../services/memory/project-memory-service.js';
|
|
4
|
+
import { emitBootstrapFailure } from './memory-command-shared.js';
|
|
5
|
+
/** Derived from the canonical kind vocabulary — never hand-maintain a list here. */
|
|
6
|
+
const KIND_HELP = VALID_PROJECT_MEMORY_KINDS.join(', ');
|
|
7
|
+
/**
|
|
8
|
+
* Call a run function from the lazily imported `memory-commands.js`.
|
|
9
|
+
*
|
|
10
|
+
* The dynamic import avoids a top-of-file import cycle (memory-commands.ts
|
|
11
|
+
* imports services the rest of this family also touches).
|
|
12
|
+
*/
|
|
13
|
+
function delegateMemoryRun(args) {
|
|
14
|
+
void import('../memory-commands.js')
|
|
15
|
+
.then((mod) => {
|
|
16
|
+
void args.build(mod)(args.io, args.options);
|
|
17
|
+
})
|
|
18
|
+
.catch((error) => {
|
|
19
|
+
emitBootstrapFailure(args.io, {
|
|
20
|
+
command: args.spec.command,
|
|
21
|
+
code: args.spec.code,
|
|
22
|
+
message: getErrorMessage(error),
|
|
23
|
+
json: args.spec.json,
|
|
24
|
+
nextActions: args.spec.nextActions
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/** The bootstrap hint `memory list --pick` gives when fzf is missing or old. */
|
|
29
|
+
const FZF_UNAVAILABLE = /brew install fzf|apt-get install fzf|older than required/;
|
|
30
|
+
const FZF_MESSAGE = 'fzf binary not found or too old. Install with: brew install fzf (or apt: apt-get install fzf). peaks memory list --pick requires fzf >= 0.38.';
|
|
31
|
+
/**
|
|
32
|
+
* `--pick` needs a real fzf, so a missing binary is its own refusal with its
|
|
33
|
+
* own exit code (127, the shell's "command not found") rather than a generic
|
|
34
|
+
* bootstrap failure.
|
|
35
|
+
*/
|
|
36
|
+
function listBootstrapFailure(io, options, error) {
|
|
37
|
+
const msg = FZF_UNAVAILABLE.test(getErrorMessage(error)) ? FZF_MESSAGE : getErrorMessage(error);
|
|
38
|
+
const code = FZF_UNAVAILABLE.test(msg) ? 'FZF_UNAVAILABLE' : 'MEMORY_LIST_BOOTSTRAP_FAILED';
|
|
39
|
+
printResult(io, fail('memory.list', code, msg, {}, [
|
|
40
|
+
'Install fzf or run without --pick to list entries as JSON'
|
|
41
|
+
]), options.json);
|
|
42
|
+
if (code === 'FZF_UNAVAILABLE')
|
|
43
|
+
process.exitCode = 127;
|
|
44
|
+
else
|
|
45
|
+
process.exitCode = 1;
|
|
46
|
+
}
|
|
47
|
+
function registerMemoryList(memory, io) {
|
|
48
|
+
addJsonOption(memory
|
|
49
|
+
.command('list')
|
|
50
|
+
.description('List all memory entries from .peaks/memory/index.json. Pass --pick to spawn fzf for interactive multi-select; the picked subset is written to .peaks/memory/picked.json.')
|
|
51
|
+
.option('--kind <kind>', `filter by memory kind (one of: ${KIND_HELP})`)
|
|
52
|
+
.option('--pick', 'spawn fzf for interactive multi-select (requires fzf >= 0.38); writes picked.json')
|
|
53
|
+
.option('--fzf-bin <path>', 'override fzf binary path (default: fzf on PATH)', 'fzf')
|
|
54
|
+
.option('--summary', 'emit counts + names-of-first-N only (≤ 2 KB) instead of the full entry array; the default envelope is unchanged')
|
|
55
|
+
.option('--project <path>', 'target project root (defaults to git root or cwd)')).action((options) => {
|
|
56
|
+
void import('../memory-commands.js')
|
|
57
|
+
.then(({ runMemoryList }) => {
|
|
58
|
+
void runMemoryList(io, {
|
|
59
|
+
...(options.kind !== undefined ? { kind: options.kind } : {}),
|
|
60
|
+
...(options.pick === true ? { pick: true } : {}),
|
|
61
|
+
...(options.fzfBin ? { fzfBin: options.fzfBin } : {}),
|
|
62
|
+
...(options.project !== undefined ? { project: options.project } : {}),
|
|
63
|
+
...(options.summary === true ? { summary: true } : {}),
|
|
64
|
+
...(options.json !== undefined ? { json: options.json } : {})
|
|
65
|
+
});
|
|
66
|
+
})
|
|
67
|
+
.catch((error) => listBootstrapFailure(io, options, error));
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
function registerMemoryReindex(memory, io) {
|
|
71
|
+
addJsonOption(memory
|
|
72
|
+
.command('reindex')
|
|
73
|
+
.description('Rebuild .peaks/memory/index.json from every memory file on disk and regenerate MEMORY.md; reports unclassified files and orphans both ways. Dry-run by default; pass --apply to write.')
|
|
74
|
+
.option('--project <path>', 'target project root (defaults to git root or cwd)')
|
|
75
|
+
.option('--dry-run', 'report drift without writing (default)')
|
|
76
|
+
.option('--apply', 'rebuild index.json and regenerate MEMORY.md')
|
|
77
|
+
.option('--summary', 'emit drift counts + names-of-first-N only (≤ 2 KB) instead of the full arrays; the default envelope is unchanged')).action((options) => {
|
|
78
|
+
delegateMemoryRun({
|
|
79
|
+
io,
|
|
80
|
+
spec: {
|
|
81
|
+
command: 'memory.reindex',
|
|
82
|
+
code: 'MEMORY_REINDEX_BOOTSTRAP_FAILED',
|
|
83
|
+
json: options.json
|
|
84
|
+
},
|
|
85
|
+
options: {
|
|
86
|
+
...(options.project !== undefined ? { project: options.project } : {}),
|
|
87
|
+
...(options.dryRun === true ? { dryRun: true } : {}),
|
|
88
|
+
...(options.apply === true ? { apply: true } : {}),
|
|
89
|
+
...(options.summary === true ? { summary: true } : {}),
|
|
90
|
+
...(options.json !== undefined ? { json: options.json } : {})
|
|
91
|
+
},
|
|
92
|
+
build: (mod) => mod.runMemoryReindex
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
function registerMemoryIngest(memory, io) {
|
|
97
|
+
addJsonOption(memory
|
|
98
|
+
.command('ingest')
|
|
99
|
+
.description('Import memories written by the IDE-side agent (~/.claude/projects/<hash>/memory/*.md) into the peaks-owned .peaks/memory store. The IDE-side dir is read-only. Dry-run by default; pass --apply to write.')
|
|
100
|
+
.option('--project <path>', 'target project root (defaults to git root or cwd)')
|
|
101
|
+
.option('--source-dir <path>', 'override the IDE-side memory directory')
|
|
102
|
+
.option('--dry-run', 'preview imports without writing (default)')
|
|
103
|
+
.option('--apply', 'write normalized memories into .peaks/memory')).action((options) => {
|
|
104
|
+
delegateMemoryRun({
|
|
105
|
+
io,
|
|
106
|
+
spec: {
|
|
107
|
+
command: 'memory.ingest',
|
|
108
|
+
code: 'MEMORY_INGEST_BOOTSTRAP_FAILED',
|
|
109
|
+
json: options.json
|
|
110
|
+
},
|
|
111
|
+
options: {
|
|
112
|
+
...(options.project !== undefined ? { project: options.project } : {}),
|
|
113
|
+
...(options.sourceDir !== undefined ? { sourceDir: options.sourceDir } : {}),
|
|
114
|
+
...(options.dryRun === true ? { dryRun: true } : {}),
|
|
115
|
+
...(options.apply === true ? { apply: true } : {}),
|
|
116
|
+
...(options.json !== undefined ? { json: options.json } : {})
|
|
117
|
+
},
|
|
118
|
+
build: (mod) => mod.runMemoryIngest
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
function registerMemoryRotate(memory, io) {
|
|
123
|
+
addJsonOption(memory
|
|
124
|
+
.command('rotate')
|
|
125
|
+
.description('Tier-driven retention for .peaks/memory/ (sediment pruning policy, tier 1: archive only, never delete). Tier assignment: explicit `metadata.tier: A|B|C|D` wins; else files under archived/ are D, files pinned in MEMORY.md are B, kinds rule/convention/project-rule are A, kinds decision/reference/feedback/module/bug/investigation/technical-pattern are B, everything else is C. Tier C older than 6 months (frontmatter updatedAt/updated/modified, else file mtime) and not pinned is archived; tier D is reported as a delete-candidate only. Tier A/B are never selected, every candidate must pass a reference grep against src/ + skills/, and --apply refuses an empty plan or a failed gate. Dry-run by default.')
|
|
126
|
+
.option('--project <path>', 'target project root (defaults to git root or cwd)')
|
|
127
|
+
.option('--dry-run', 'report the rotation plan without moving anything (default)')
|
|
128
|
+
.option('--apply', 'move tier-C candidates into .peaks/memory/archived/')).action((options) => {
|
|
129
|
+
delegateMemoryRun({
|
|
130
|
+
io,
|
|
131
|
+
spec: {
|
|
132
|
+
command: 'memory.rotate',
|
|
133
|
+
code: 'MEMORY_ROTATE_BOOTSTRAP_FAILED',
|
|
134
|
+
json: options.json
|
|
135
|
+
},
|
|
136
|
+
options: {
|
|
137
|
+
...(options.project !== undefined ? { project: options.project } : {}),
|
|
138
|
+
...(options.dryRun === true ? { dryRun: true } : {}),
|
|
139
|
+
...(options.apply === true ? { apply: true } : {}),
|
|
140
|
+
...(options.json !== undefined ? { json: options.json } : {})
|
|
141
|
+
},
|
|
142
|
+
build: (mod) => mod.runMemoryRotate
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
function registerMemorySearch(memory, io) {
|
|
147
|
+
addJsonOption(memory
|
|
148
|
+
.command('search <query>')
|
|
149
|
+
.description('Fuzzy-search the memory index (deterministic, local, zero-token). Default --limit 6.')
|
|
150
|
+
.option('--kind <kind>', `filter by memory kind (one of: ${KIND_HELP})`)
|
|
151
|
+
.option('--limit <n>', 'maximum number of matches to return', (value) => Number(value))
|
|
152
|
+
.option('--project <path>', 'target project root (defaults to git root or cwd)')).action((query, options) => {
|
|
153
|
+
delegateMemoryRun({
|
|
154
|
+
io,
|
|
155
|
+
spec: {
|
|
156
|
+
command: 'memory.search',
|
|
157
|
+
code: 'MEMORY_SEARCH_BOOTSTRAP_FAILED',
|
|
158
|
+
json: options.json
|
|
159
|
+
},
|
|
160
|
+
options: {
|
|
161
|
+
query,
|
|
162
|
+
...(options.kind !== undefined ? { kind: options.kind } : {}),
|
|
163
|
+
...(options.limit !== undefined ? { limit: options.limit } : {}),
|
|
164
|
+
...(options.project !== undefined ? { project: options.project } : {}),
|
|
165
|
+
...(options.json !== undefined ? { json: options.json } : {})
|
|
166
|
+
},
|
|
167
|
+
build: (mod) => mod.runMemorySearch
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
/** The five verbs whose bodies live in `memory-commands.ts`, in shipping order. */
|
|
172
|
+
export function registerMemoryDelegatedVerbs(memory, io) {
|
|
173
|
+
registerMemoryList(memory, io);
|
|
174
|
+
registerMemoryReindex(memory, io);
|
|
175
|
+
registerMemoryIngest(memory, io);
|
|
176
|
+
registerMemoryRotate(memory, io);
|
|
177
|
+
registerMemorySearch(memory, io);
|
|
178
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { describeMemoryBlockDrops, executeProjectMemoryExtract, SENSITIVE_MEMORY_CHECKS, summarizeProjectMemoryExtractResult, UnsafeMemoryError } from '../../../services/memory/project-memory-service.js';
|
|
2
|
+
import { fail, ok } from 'peaks-loop-shared/result';
|
|
3
|
+
import { addJsonOption, getErrorMessage, printResult } from '../../cli-helpers.js';
|
|
4
|
+
import { refuseBothFlags } from './memory-command-shared.js';
|
|
5
|
+
/**
|
|
6
|
+
* The remedy for a failed `memory extract`, chosen by the check that refused
|
|
7
|
+
* the write — the same `SENSITIVE_MEMORY_CHECKS` values the refusal message
|
|
8
|
+
* and envelope data are built from, so the message, the data and the advice
|
|
9
|
+
* cannot drift apart.
|
|
10
|
+
*
|
|
11
|
+
* WHY IT IS NOT ONE STATIC STRING. Every failure used to get "Check artifact
|
|
12
|
+
* paths and remove secrets before extracting memory" — including a refusal
|
|
13
|
+
* raised only because a memory TITLE contained a word like `authority`
|
|
14
|
+
* (slice C0). There was no secret anywhere in that memory, so the one thing
|
|
15
|
+
* the hint told the user to do was the one thing that could not help: it sent
|
|
16
|
+
* check that actually failed.
|
|
17
|
+
*
|
|
18
|
+
* `null` (a failure that is not a safety refusal — a path escape, a missing
|
|
19
|
+
* artifact) keeps the pre-C0 hint, which is about paths and secrets rather
|
|
20
|
+
* than about a check.
|
|
21
|
+
*/
|
|
22
|
+
function memoryExtractNextActions(refusal) {
|
|
23
|
+
if (refusal === null) {
|
|
24
|
+
return ['Check artifact paths and remove secrets before extracting memory'];
|
|
25
|
+
}
|
|
26
|
+
if (refusal.check === SENSITIVE_MEMORY_CHECKS.title) {
|
|
27
|
+
return [
|
|
28
|
+
'Retitle the memory so it is not named after a credential term, then re-run memory extract'
|
|
29
|
+
];
|
|
30
|
+
}
|
|
31
|
+
if (refusal.check === SENSITIVE_MEMORY_CHECKS.content) {
|
|
32
|
+
// Name the rule, not just the family. `matchedTerm` is a closed id
|
|
33
|
+
// (`credential-assignment`, `bearer-value`, `pem-private-key`, …), so the
|
|
34
|
+
// reader can tell a credential in the text from a sentence that merely has
|
|
35
|
+
// the shape of one — which is the difference between removing a value and
|
|
36
|
+
// rewording prose.
|
|
37
|
+
return [
|
|
38
|
+
`Remove the credential value the "${refusal.matchedTerm}" pattern matched, then re-run memory extract`
|
|
39
|
+
];
|
|
40
|
+
}
|
|
41
|
+
return ['Remove the credential value from the memory content, then re-run memory extract'];
|
|
42
|
+
}
|
|
43
|
+
function runExtract(io, options) {
|
|
44
|
+
const result = executeProjectMemoryExtract({
|
|
45
|
+
projectRoot: options.project,
|
|
46
|
+
artifactPaths: options.artifact,
|
|
47
|
+
apply: options.apply === true
|
|
48
|
+
});
|
|
49
|
+
// A block that was found but not extracted must not vanish silently: the
|
|
50
|
+
// parser's rejection reasons ride the envelope's existing `warnings`
|
|
51
|
+
// channel (JSON: `warnings[]`; human: `warning: …` on stderr). `data` is
|
|
52
|
+
// unchanged — this adds no field to the summary.
|
|
53
|
+
printResult(io, ok('memory.extract', summarizeProjectMemoryExtractResult(result), describeMemoryBlockDrops(result.droppedBlocks)), options.json);
|
|
54
|
+
}
|
|
55
|
+
function emitExtractFailure(io, options, error) {
|
|
56
|
+
const refusal = error instanceof UnsafeMemoryError ? error : null;
|
|
57
|
+
printResult(io, fail('memory.extract', 'MEMORY_EXTRACT_FAILED', getErrorMessage(error),
|
|
58
|
+
// The check and the term are facts about the failure, so they ride
|
|
59
|
+
// the envelope's data — not just its prose. `fail()` redacts
|
|
60
|
+
// `message` (see `UnsafeMemoryError`), so the term would otherwise
|
|
61
|
+
// reach the reader as `[redacted]`; `data` is passed through.
|
|
62
|
+
refusal === null ? {} : { check: refusal.check, matchedTerm: refusal.matchedTerm }, memoryExtractNextActions(refusal)), options.json);
|
|
63
|
+
process.exitCode = 1;
|
|
64
|
+
}
|
|
65
|
+
export function registerMemoryExtractCommand(memory, io) {
|
|
66
|
+
addJsonOption(memory
|
|
67
|
+
.command('extract')
|
|
68
|
+
.description('Extract stable project memory from skill artifacts into project .peaks/memory')
|
|
69
|
+
.requiredOption('--project <path>', 'target project root')
|
|
70
|
+
.requiredOption('--artifact <path...>', 'skill artifact paths inside the project')
|
|
71
|
+
.option('--dry-run', 'preview writes without changing files')
|
|
72
|
+
.option('--apply', 'write extracted memories into project .peaks/memory')).action((options) => {
|
|
73
|
+
const refused = refuseBothFlags(io, {
|
|
74
|
+
command: 'memory.extract',
|
|
75
|
+
code: 'INVALID_MEMORY_EXTRACT_FLAGS',
|
|
76
|
+
nextActions: ['Run without --apply to preview writes, or pass --apply to write memories'],
|
|
77
|
+
json: options.json,
|
|
78
|
+
dryRun: options.dryRun,
|
|
79
|
+
apply: options.apply
|
|
80
|
+
});
|
|
81
|
+
if (refused)
|
|
82
|
+
return;
|
|
83
|
+
try {
|
|
84
|
+
runExtract(io, options);
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
emitExtractFailure(io, options, error);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { executeProjectMemoryBackup, summarizeProjectMemoryBackupResult } from '../../../services/memory/project-memory-service.js';
|
|
2
|
+
import { fail, ok } from 'peaks-loop-shared/result';
|
|
3
|
+
import { addJsonOption, getErrorMessage, printResult } from '../../cli-helpers.js';
|
|
4
|
+
import { refuseBothFlags } from './memory-command-shared.js';
|
|
5
|
+
export function registerMemorySyncCommand(memory, io) {
|
|
6
|
+
addJsonOption(memory
|
|
7
|
+
.command('sync')
|
|
8
|
+
.description('Back up project .peaks/memory into the artifact workspace')
|
|
9
|
+
.requiredOption('--project <path>', 'target project root')
|
|
10
|
+
.requiredOption('--workspace <path>', 'artifact workspace path')
|
|
11
|
+
.option('--dry-run', 'preview copies without changing files')
|
|
12
|
+
.option('--apply', 'copy project .peaks/memory into artifact workspace backup')).action((options) => {
|
|
13
|
+
const refused = refuseBothFlags(io, {
|
|
14
|
+
command: 'memory.sync',
|
|
15
|
+
code: 'INVALID_MEMORY_SYNC_FLAGS',
|
|
16
|
+
nextActions: ['Run without --apply to preview copies, or pass --apply to back up memories'],
|
|
17
|
+
json: options.json,
|
|
18
|
+
dryRun: options.dryRun,
|
|
19
|
+
apply: options.apply
|
|
20
|
+
});
|
|
21
|
+
if (refused)
|
|
22
|
+
return;
|
|
23
|
+
try {
|
|
24
|
+
const result = executeProjectMemoryBackup({
|
|
25
|
+
projectRoot: options.project,
|
|
26
|
+
artifactWorkspacePath: options.workspace,
|
|
27
|
+
apply: options.apply === true
|
|
28
|
+
});
|
|
29
|
+
printResult(io, ok('memory.sync', summarizeProjectMemoryBackupResult(result)), options.json);
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
printResult(io, fail('memory.sync', 'MEMORY_SYNC_FAILED', getErrorMessage(error), {}, [
|
|
33
|
+
'Use an artifact workspace outside the project root'
|
|
34
|
+
]), options.json);
|
|
35
|
+
process.exitCode = 1;
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|