peaks-loop 4.1.2 → 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 +136 -47
- package/CHANGELOG.md +112 -0
- package/README-en.md +1 -1
- package/README.md +1 -1
- package/contracts/readonly-argv-whitelist.json +211 -0
- 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/audit-artifact-runners.d.ts +16 -0
- package/dist/cli/commands/audit-artifact-runners.js +170 -0
- package/dist/cli/commands/audit-command-shared.d.ts +97 -0
- package/dist/cli/commands/audit-command-shared.js +60 -0
- package/dist/cli/commands/audit-commands.d.ts +7 -31
- package/dist/cli/commands/audit-commands.js +64 -473
- package/dist/cli/commands/audit-goal-runners.d.ts +17 -0
- package/dist/cli/commands/audit-goal-runners.js +114 -0
- package/dist/cli/commands/audit-red-lines-runners.d.ts +11 -0
- package/dist/cli/commands/audit-red-lines-runners.js +43 -0
- package/dist/cli/commands/audit-refusal-data.d.ts +23 -0
- package/dist/cli/commands/audit-refusal-data.js +69 -0
- package/dist/cli/commands/audit-static-runners.d.ts +13 -0
- package/dist/cli/commands/audit-static-runners.js +139 -0
- package/dist/cli/commands/await-runners.d.ts +11 -0
- package/dist/cli/commands/await-runners.js +148 -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-auto-compact-command.d.ts +3 -0
- package/dist/cli/commands/code-auto-compact-command.js +124 -0
- package/dist/cli/commands/code-auto-compact-envelope.d.ts +22 -0
- package/dist/cli/commands/code-auto-compact-envelope.js +39 -0
- package/dist/cli/commands/code-context-audit-command.d.ts +3 -0
- package/dist/cli/commands/code-context-audit-command.js +68 -0
- package/dist/cli/commands/code-context-now-command.d.ts +3 -0
- package/dist/cli/commands/code-context-now-command.js +124 -0
- package/dist/cli/commands/code-context-now-envelope.d.ts +66 -0
- package/dist/cli/commands/code-context-now-envelope.js +136 -0
- package/dist/cli/commands/code-context-now-mapping.d.ts +27 -0
- package/dist/cli/commands/code-context-now-mapping.js +43 -0
- package/dist/cli/commands/code-emit-handoff-command.d.ts +3 -0
- package/dist/cli/commands/code-emit-handoff-command.js +136 -0
- package/dist/cli/commands/code-gate-step-08-command.d.ts +3 -0
- package/dist/cli/commands/code-gate-step-08-command.js +155 -0
- package/dist/cli/commands/code-post-compact-detect-command.d.ts +3 -0
- package/dist/cli/commands/code-post-compact-detect-command.js +50 -0
- package/dist/cli/commands/code-runtime-commands.d.ts +9 -43
- package/dist/cli/commands/code-runtime-commands.js +20 -672
- package/dist/cli/commands/code-runtime-session.d.ts +1 -0
- package/dist/cli/commands/code-runtime-session.js +15 -0
- 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/compact-command.d.ts +6 -2
- package/dist/cli/commands/compact-command.js +12 -559
- package/dist/cli/commands/compact-dry-run-command.d.ts +3 -0
- package/dist/cli/commands/compact-dry-run-command.js +87 -0
- package/dist/cli/commands/compact-force-command.d.ts +3 -0
- package/dist/cli/commands/compact-force-command.js +98 -0
- package/dist/cli/commands/compact-harness-window-command.d.ts +3 -0
- package/dist/cli/commands/compact-harness-window-command.js +174 -0
- package/dist/cli/commands/compact-history-command.d.ts +3 -0
- package/dist/cli/commands/compact-history-command.js +89 -0
- package/dist/cli/commands/compact-read-commands.d.ts +3 -0
- package/dist/cli/commands/compact-read-commands.js +123 -0
- package/dist/cli/commands/compact-settle-command.d.ts +3 -0
- package/dist/cli/commands/compact-settle-command.js +130 -0
- package/dist/cli/commands/compact-shared.d.ts +9 -0
- package/dist/cli/commands/compact-shared.js +26 -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/skill-command.d.ts +1 -44
- package/dist/cli/commands/core/skill-command.js +13 -541
- package/dist/cli/commands/core/skill-context-verdict.d.ts +38 -0
- package/dist/cli/commands/core/skill-context-verdict.js +63 -0
- package/dist/cli/commands/core/skill-generated-config-notice.d.ts +41 -0
- package/dist/cli/commands/core/skill-generated-config-notice.js +75 -0
- package/dist/cli/commands/core/skill-heartbeat-commands.d.ts +3 -0
- package/dist/cli/commands/core/skill-heartbeat-commands.js +50 -0
- package/dist/cli/commands/core/skill-presence-commands.d.ts +3 -0
- package/dist/cli/commands/core/skill-presence-commands.js +123 -0
- package/dist/cli/commands/core/skill-presence-housekeeping-commands.d.ts +3 -0
- package/dist/cli/commands/core/skill-presence-housekeeping-commands.js +165 -0
- package/dist/cli/commands/core/skill-registry-commands.d.ts +3 -0
- package/dist/cli/commands/core/skill-registry-commands.js +117 -0
- package/dist/cli/commands/core/skill-runbook-command.d.ts +3 -0
- package/dist/cli/commands/core/skill-runbook-command.js +29 -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-command-spec.d.ts +2 -0
- package/dist/cli/commands/dispatch-command-spec.js +62 -0
- package/dist/cli/commands/dispatch-commands.js +159 -775
- 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-detached-branch.d.ts +3 -0
- package/dist/cli/commands/dispatch-detached-branch.js +58 -0
- package/dist/cli/commands/dispatch-envelope.d.ts +36 -0
- package/dist/cli/commands/dispatch-envelope.js +104 -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/dispatch-isolation-lease.d.ts +17 -0
- package/dist/cli/commands/dispatch-isolation-lease.js +149 -0
- package/dist/cli/commands/dispatch-preflight.d.ts +7 -0
- package/dist/cli/commands/dispatch-preflight.js +105 -0
- package/dist/cli/commands/dispatch-prompt-blocks.d.ts +10 -0
- package/dist/cli/commands/dispatch-prompt-blocks.js +56 -0
- package/dist/cli/commands/dispatch-prompt-composition.d.ts +30 -0
- package/dist/cli/commands/dispatch-prompt-composition.js +171 -0
- package/dist/cli/commands/dispatch-record-write.d.ts +24 -0
- package/dist/cli/commands/dispatch-record-write.js +96 -0
- package/dist/cli/commands/dispatch-tool-call.d.ts +15 -0
- package/dist/cli/commands/dispatch-tool-call.js +128 -0
- package/dist/cli/commands/evolution-command-shared.d.ts +78 -0
- package/dist/cli/commands/evolution-command-shared.js +107 -0
- package/dist/cli/commands/evolution-commands.d.ts +11 -1
- package/dist/cli/commands/evolution-commands.js +19 -350
- package/dist/cli/commands/evolution-evaluate-command.d.ts +24 -0
- package/dist/cli/commands/evolution-evaluate-command.js +138 -0
- package/dist/cli/commands/evolution-propose-command.d.ts +23 -0
- package/dist/cli/commands/evolution-propose-command.js +145 -0
- package/dist/cli/commands/evolution-status-command.d.ts +17 -0
- package/dist/cli/commands/evolution-status-command.js +41 -0
- package/dist/cli/commands/evolution-verdict-commands.d.ts +30 -0
- package/dist/cli/commands/evolution-verdict-commands.js +100 -0
- 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/finalize-accumulator.d.ts +44 -0
- package/dist/cli/commands/finalize-accumulator.js +55 -0
- package/dist/cli/commands/finalize-branches.d.ts +34 -0
- package/dist/cli/commands/finalize-branches.js +119 -0
- package/dist/cli/commands/finalize-runners.d.ts +3 -0
- package/dist/cli/commands/finalize-runners.js +92 -0
- package/dist/cli/commands/finalize-selection.d.ts +65 -0
- package/dist/cli/commands/finalize-selection.js +35 -0
- package/dist/cli/commands/gate-commands.js +26 -8
- 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/job-checkpoint-commands.d.ts +3 -0
- package/dist/cli/commands/job-checkpoint-commands.js +157 -0
- package/dist/cli/commands/job-command-shared.d.ts +109 -0
- package/dist/cli/commands/job-command-shared.js +72 -0
- package/dist/cli/commands/job-commands.d.ts +4 -64
- package/dist/cli/commands/job-commands.js +42 -552
- package/dist/cli/commands/job-cost-check-command.d.ts +3 -0
- package/dist/cli/commands/job-cost-check-command.js +41 -0
- package/dist/cli/commands/job-init-status-commands.d.ts +3 -0
- package/dist/cli/commands/job-init-status-commands.js +149 -0
- package/dist/cli/commands/job-run-commands.d.ts +3 -0
- package/dist/cli/commands/job-run-commands.js +97 -0
- package/dist/cli/commands/job-state-root.d.ts +35 -0
- package/dist/cli/commands/job-state-root.js +76 -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-eval-capture-index.d.ts +4 -0
- package/dist/cli/commands/loop-eval-capture-index.js +44 -0
- package/dist/cli/commands/loop-eval-commands.d.ts +8 -5
- package/dist/cli/commands/loop-eval-commands.js +12 -626
- package/dist/cli/commands/loop-eval-eval-command.d.ts +3 -0
- package/dist/cli/commands/loop-eval-eval-command.js +168 -0
- package/dist/cli/commands/loop-eval-monotonic-command.d.ts +3 -0
- package/dist/cli/commands/loop-eval-monotonic-command.js +90 -0
- package/dist/cli/commands/loop-eval-parents.d.ts +7 -0
- package/dist/cli/commands/loop-eval-parents.js +20 -0
- package/dist/cli/commands/loop-eval-run-code.d.ts +7 -0
- package/dist/cli/commands/loop-eval-run-code.js +40 -0
- package/dist/cli/commands/loop-eval-run-command.d.ts +3 -0
- package/dist/cli/commands/loop-eval-run-command.js +113 -0
- package/dist/cli/commands/loop-eval-spec-commands.d.ts +3 -0
- package/dist/cli/commands/loop-eval-spec-commands.js +165 -0
- package/dist/cli/commands/loop-eval-spec-lint-command.d.ts +3 -0
- package/dist/cli/commands/loop-eval-spec-lint-command.js +42 -0
- package/dist/cli/commands/loop-eval-workflow-commands.d.ts +3 -0
- package/dist/cli/commands/loop-eval-workflow-commands.js +141 -0
- 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/mcp-commands.d.ts +10 -0
- package/dist/cli/commands/mcp-commands.js +157 -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/request-command-options.d.ts +49 -0
- package/dist/cli/commands/request-command-options.js +1 -0
- package/dist/cli/commands/request-commands.d.ts +3 -9
- package/dist/cli/commands/request-commands.js +17 -522
- package/dist/cli/commands/request-init-command.d.ts +3 -0
- package/dist/cli/commands/request-init-command.js +100 -0
- package/dist/cli/commands/request-lint-command.d.ts +3 -0
- package/dist/cli/commands/request-lint-command.js +50 -0
- package/dist/cli/commands/request-list-command.d.ts +10 -0
- package/dist/cli/commands/request-list-command.js +53 -0
- package/dist/cli/commands/request-repair-status-command.d.ts +3 -0
- package/dist/cli/commands/request-repair-status-command.js +61 -0
- package/dist/cli/commands/request-show-command.d.ts +3 -0
- package/dist/cli/commands/request-show-command.js +56 -0
- package/dist/cli/commands/request-transition-command.d.ts +3 -0
- package/dist/cli/commands/request-transition-command.js +122 -0
- package/dist/cli/commands/request-transition-failures.d.ts +8 -0
- package/dist/cli/commands/request-transition-failures.js +90 -0
- package/dist/cli/commands/request-transition-hooks.d.ts +50 -0
- package/dist/cli/commands/request-transition-hooks.js +115 -0
- package/dist/cli/commands/request-transition-preflight.d.ts +10 -0
- package/dist/cli/commands/request-transition-preflight.js +107 -0
- package/dist/cli/commands/scan-command-shared.d.ts +96 -0
- package/dist/cli/commands/scan-command-shared.js +83 -0
- package/dist/cli/commands/scan-commands.d.ts +3 -2
- package/dist/cli/commands/scan-commands.js +23 -463
- package/dist/cli/commands/scan-inventory-commands.d.ts +3 -0
- package/dist/cli/commands/scan-inventory-commands.js +96 -0
- package/dist/cli/commands/scan-project-commands.d.ts +3 -0
- package/dist/cli/commands/scan-project-commands.js +65 -0
- package/dist/cli/commands/scan-scope-commands.d.ts +3 -0
- package/dist/cli/commands/scan-scope-commands.js +149 -0
- package/dist/cli/commands/scan-scope-helpers.d.ts +8 -0
- package/dist/cli/commands/scan-scope-helpers.js +54 -0
- package/dist/cli/commands/scan-structural-commands.d.ts +3 -0
- package/dist/cli/commands/scan-structural-commands.js +113 -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/share-commands.d.ts +12 -68
- package/dist/cli/commands/share-commands.js +47 -556
- package/dist/cli/commands/share-error-hints.d.ts +14 -0
- package/dist/cli/commands/share-error-hints.js +38 -0
- package/dist/cli/commands/share-identity.d.ts +13 -0
- package/dist/cli/commands/share-identity.js +22 -0
- package/dist/cli/commands/share-record-paths.d.ts +37 -0
- package/dist/cli/commands/share-record-paths.js +68 -0
- package/dist/cli/commands/share-runners.d.ts +3 -0
- package/dist/cli/commands/share-runners.js +158 -0
- package/dist/cli/commands/shared-read-runners.d.ts +3 -0
- package/dist/cli/commands/shared-read-runners.js +51 -0
- package/dist/cli/commands/slice-check-command.d.ts +3 -0
- package/dist/cli/commands/slice-check-command.js +54 -0
- package/dist/cli/commands/slice-commands.d.ts +2 -22
- package/dist/cli/commands/slice-commands.js +18 -517
- package/dist/cli/commands/slice-decompose-artifacts.d.ts +18 -0
- package/dist/cli/commands/slice-decompose-artifacts.js +79 -0
- package/dist/cli/commands/slice-decompose-command.d.ts +3 -0
- package/dist/cli/commands/slice-decompose-command.js +123 -0
- package/dist/cli/commands/slice-list-commands.d.ts +3 -0
- package/dist/cli/commands/slice-list-commands.js +182 -0
- package/dist/cli/commands/slice-pick-command.d.ts +3 -0
- package/dist/cli/commands/slice-pick-command.js +60 -0
- package/dist/cli/commands/slice-plan-command.d.ts +24 -0
- package/dist/cli/commands/slice-plan-command.js +111 -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-commands.d.ts +10 -1
- package/dist/cli/commands/workflow-commands.js +6 -594
- package/dist/cli/commands/workflow-gate-commands.d.ts +3 -0
- package/dist/cli/commands/workflow-gate-commands.js +116 -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-plan-helpers.d.ts +48 -0
- package/dist/cli/commands/workflow-plan-helpers.js +103 -0
- package/dist/cli/commands/workflow-planning-commands.d.ts +3 -0
- package/dist/cli/commands/workflow-planning-commands.js +56 -0
- package/dist/cli/commands/workflow-swarm-actions.d.ts +7 -0
- package/dist/cli/commands/workflow-swarm-actions.js +109 -0
- package/dist/cli/commands/workflow-swarm-commands.d.ts +3 -0
- package/dist/cli/commands/workflow-swarm-commands.js +138 -0
- package/dist/cli/commands/workflow-tech-actions.d.ts +10 -0
- package/dist/cli/commands/workflow-tech-actions.js +150 -0
- package/dist/cli/commands/workflow-terminalize-command.d.ts +3 -0
- package/dist/cli/commands/workflow-terminalize-command.js +56 -0
- package/dist/cli/commands/workspace/init-actions.d.ts +10 -0
- package/dist/cli/commands/workspace/init-actions.js +199 -0
- package/dist/cli/commands/workspace/init-codegraph-stake.d.ts +10 -0
- package/dist/cli/commands/workspace/init-codegraph-stake.js +54 -0
- package/dist/cli/commands/workspace/init-command.d.ts +8 -124
- package/dist/cli/commands/workspace/init-command.js +59 -623
- package/dist/cli/commands/workspace/init-context.d.ts +58 -0
- package/dist/cli/commands/workspace/init-context.js +121 -0
- package/dist/cli/commands/workspace/init-envelope.d.ts +3 -0
- package/dist/cli/commands/workspace/init-envelope.js +34 -0
- package/dist/cli/commands/workspace/init-failures.d.ts +3 -0
- package/dist/cli/commands/workspace/init-failures.js +84 -0
- package/dist/cli/commands/workspace/init-hooks-decision.d.ts +24 -0
- package/dist/cli/commands/workspace/init-hooks-decision.js +189 -0
- package/dist/cli/commands/workspace/init-options.d.ts +102 -0
- package/dist/cli/commands/workspace/init-options.js +1 -0
- package/dist/cli/commands/worktree-lease-commands.d.ts +10 -6
- package/dist/cli/commands/worktree-lease-commands.js +42 -512
- package/dist/cli/commands/worktree-lease-gc-command.d.ts +12 -0
- package/dist/cli/commands/worktree-lease-gc-command.js +117 -0
- package/dist/cli/commands/worktree-lease-git.d.ts +22 -0
- package/dist/cli/commands/worktree-lease-git.js +48 -0
- package/dist/cli/commands/worktree-lease-list-command.d.ts +12 -0
- package/dist/cli/commands/worktree-lease-list-command.js +100 -0
- package/dist/cli/commands/worktree-lease-load.d.ts +37 -0
- package/dist/cli/commands/worktree-lease-load.js +28 -0
- package/dist/cli/commands/worktree-lease-release-command.d.ts +13 -0
- package/dist/cli/commands/worktree-lease-release-command.js +105 -0
- package/dist/cli/commands/worktree-lease-renew-command.d.ts +11 -0
- package/dist/cli/commands/worktree-lease-renew-command.js +99 -0
- package/dist/cli/commands/worktree-lease-session.d.ts +22 -0
- package/dist/cli/commands/worktree-lease-session.js +29 -0
- package/dist/cli/commands/worktree-lease-spawn-command.d.ts +11 -0
- package/dist/cli/commands/worktree-lease-spawn-command.js +119 -0
- package/dist/cli/commands/worktree-lease-status-command.d.ts +11 -0
- package/dist/cli/commands/worktree-lease-status-command.js +86 -0
- package/dist/cli/commands/worktree-lease-store.d.ts +19 -0
- package/dist/cli/commands/worktree-lease-store.js +24 -0
- package/dist/cli/program.js +5 -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/distribution/mcp-install-runner.d.ts +21 -0
- package/dist/services/distribution/mcp-install-runner.js +59 -0
- package/dist/services/distribution/mcp-install.d.ts +95 -0
- package/dist/services/distribution/mcp-install.js +179 -0
- package/dist/services/distribution/plugin-manifest.d.ts +97 -0
- package/dist/services/distribution/plugin-manifest.js +126 -0
- package/dist/services/hooks/mcp-surface-gate.d.ts +19 -0
- package/dist/services/hooks/mcp-surface-gate.js +87 -0
- package/dist/services/ide/adapters/claude-code-adapter.d.ts +4 -35
- package/dist/services/ide/adapters/claude-code-adapter.js +48 -171
- package/dist/services/ide/adapters/claude-code-local-state.d.ts +28 -0
- package/dist/services/ide/adapters/claude-code-local-state.js +112 -0
- package/dist/services/ide/adapters/claude-code-model-window.d.ts +37 -0
- package/dist/services/ide/adapters/claude-code-model-window.js +113 -0
- package/dist/services/ide/ide-mcp-install-types.d.ts +78 -0
- package/dist/services/ide/ide-mcp-install-types.js +104 -0
- package/dist/services/ide/ide-types.d.ts +45 -1
- package/dist/services/ide/mcp-tool-matcher.d.ts +34 -0
- package/dist/services/ide/mcp-tool-matcher.js +84 -0
- package/dist/services/lint/npx-resolver.js +7 -0
- package/dist/services/mcp/cli-executor.d.ts +36 -0
- package/dist/services/mcp/cli-executor.js +97 -0
- package/dist/services/mcp/json-rpc.d.ts +81 -0
- package/dist/services/mcp/json-rpc.js +116 -0
- package/dist/services/mcp/memory-tool.d.ts +3 -0
- package/dist/services/mcp/memory-tool.js +62 -0
- package/dist/services/mcp/server-main.d.ts +1 -0
- package/dist/services/mcp/server-main.js +66 -0
- package/dist/services/mcp/server.d.ts +22 -0
- package/dist/services/mcp/server.js +152 -0
- package/dist/services/mcp/surface.d.ts +62 -0
- package/dist/services/mcp/surface.js +198 -0
- package/dist/services/mcp/tool-core.d.ts +42 -0
- package/dist/services/mcp/tool-core.js +137 -0
- package/dist/services/mcp/tools.d.ts +13 -0
- package/dist/services/mcp/tools.js +58 -0
- package/dist/services/readonly-surface/argv-guard.d.ts +32 -0
- package/dist/services/readonly-surface/argv-guard.js +164 -0
- package/dist/services/readonly-surface/readonly-whitelist.d.ts +147 -0
- package/dist/services/readonly-surface/readonly-whitelist.js +107 -0
- package/dist/services/readonly-surface/whitelist-generator.d.ts +64 -0
- package/dist/services/readonly-surface/whitelist-generator.js +212 -0
- package/dist/services/skills/hooks-codegate-superpowers.d.ts +1 -0
- package/dist/services/skills/hooks-codegate-superpowers.js +26 -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 -649
- 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 +17 -6
- package/scripts/install-skills-bundles.mjs +233 -0
- package/scripts/install-skills-fs.mjs +148 -0
- package/scripts/install-skills-ide.mjs +279 -0
- package/scripts/install-skills-output-style-default.mjs +196 -0
- package/scripts/install-skills-output-styles.mjs +121 -0
- package/scripts/install-skills-report.mjs +42 -0
- package/scripts/install-skills-user-config.mjs +198 -0
- package/scripts/install-skills.mjs +36 -1066
- package/scripts/watch-tree.mjs +140 -0
- package/scripts/watch.mjs +4 -126
- package/skills/peaks-status/SKILL.md +31 -13
|
@@ -1,100 +1,39 @@
|
|
|
1
1
|
import { existsSync } from 'node:fs';
|
|
2
2
|
import { homedir } from 'node:os';
|
|
3
|
-
import {
|
|
4
|
-
import { assertSafeSettingsFile } from '../ide/shared/safe-path.js';
|
|
5
|
-
import { atomicWriteJson, readJsonObjectFile } from '../ide/shared/atomic-json.js';
|
|
3
|
+
import { atomicWriteJson } from '../ide/shared/atomic-json.js';
|
|
6
4
|
import { getAdapter } from '../ide/ide-registry.js';
|
|
7
|
-
import { resolveHookSpec, resolveHookEntries, hasHookSpec, resolveLegacySentinels,
|
|
5
|
+
import { resolveHookSpec, resolveHookEntries, hasHookSpec, resolveLegacySentinels, hasExternalGateExemptions, withExternalGateExemptions } from './hooks-codegate-superpowers.js';
|
|
8
6
|
export { HOOK_ENFORCE_SENTINEL, HOOK_CODE_GATE_SENTINEL, HOOK_CODE_GATE_MATCHER, HOOK_CODE_GATE_EVENT, HOOK_CODE_GATE_COMMAND, SUPERPOWERS_DENIED_SKILLS } from './hooks-codegate-superpowers.js';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
export { readInstalledEntriesFromSettings } from './hooks-settings-read-installed.js';
|
|
8
|
+
export { TRIGGER_PHRASES, listSuperpowersDenyEntries, withSuperpowersSkillDenylist, withTriggeredDenyList, withoutSuperpowersSkillDenylist, withoutTriggeredDenyList } from './hooks-settings-deny-list.js';
|
|
9
|
+
import { assertSafeSettingsPathCompat, resolveLocalSettingsPath, resolveSettingsRoot } from './hooks-settings-paths.js';
|
|
10
|
+
import { describeEntryTargets, isInstalledForEntries, readSettingsFile, targetIsSatisfied, withHooksInstalled } from './hooks-settings-file-shape.js';
|
|
11
|
+
import { applyRemovalToTarget, hookStatusFromTargets, removedResult, unsupportedHookStatus } from './hooks-settings-envelopes.js';
|
|
12
|
+
import { withSuperpowersSkillDenylist, withTriggeredDenyList } from './hooks-settings-deny-list.js';
|
|
13
|
+
/** Default (claude-code) hook command. */
|
|
14
14
|
export const HOOK_ENFORCE_COMMAND = `peaks gate enforce --project "\${CLAUDE_PROJECT_DIR}" --json`;
|
|
15
|
-
function resolveIde(options) {
|
|
16
|
-
return options?.ide ?? 'claude-code';
|
|
17
|
-
}
|
|
18
|
-
/** Slice #013: read the skipProgress opt-in flag. Slice #014: the underlying install no longer emits the progress-start entry, so the flag is effectively a no-op (kept for API stability). */
|
|
19
|
-
function resolveSkipProgress(options) {
|
|
20
|
-
return options?.skipProgress === true;
|
|
21
|
-
}
|
|
22
|
-
/** Resolve settings root dir for a scope. */
|
|
23
|
-
function resolveSettingsRoot(scope, projectRoot) {
|
|
24
|
-
if (scope === 'global')
|
|
25
|
-
return resolve(homedir());
|
|
26
|
-
if (!projectRoot) {
|
|
27
|
-
throw new Error('Project scope requires a project root');
|
|
28
|
-
}
|
|
29
|
-
return resolve(projectRoot);
|
|
30
|
-
}
|
|
31
15
|
function resolveSettingsPath(scope, ide, projectRoot) {
|
|
32
|
-
const root = resolveSettingsRoot(scope, projectRoot);
|
|
33
16
|
const adapter = getAdapter(ide);
|
|
34
17
|
return adapter.settings.resolveSettingsFile(scope, scope === 'global' ? homedir() : projectRoot);
|
|
35
18
|
}
|
|
36
|
-
function
|
|
37
|
-
|
|
38
|
-
assertSafeSettingsFile(scope, root, adapter.settings.dirName, adapter.settings.settingsFileName);
|
|
39
|
-
// The compat path receives the already-computed settingsPath; double-check
|
|
40
|
-
// that the computed path matches what assertSafeSettingsFile would have
|
|
41
|
-
// produced. This guards against drift between the two resolvers.
|
|
42
|
-
const expected = adapter.settings.resolveSettingsFile(scope, scope === 'global' ? homedir() : root);
|
|
43
|
-
if (expected !== settingsPath) {
|
|
44
|
-
throw new Error(`settings path drift: ${expected} vs ${settingsPath}`);
|
|
45
|
-
}
|
|
19
|
+
function resolveIde(options) {
|
|
20
|
+
return options?.ide ?? 'claude-code';
|
|
46
21
|
}
|
|
47
22
|
/**
|
|
48
|
-
*
|
|
49
|
-
* Code's `.claude/settings.local.json`), or `undefined` when there is none.
|
|
50
|
-
*
|
|
51
|
-
* B3(b) 2026-09-13: the machine-local layer is an adapter-DECLARED capability,
|
|
52
|
-
* not a name list. It used to be two hardcoded facts here — a `Set(['claude-code'])`
|
|
53
|
-
* membership test and the filename literal `'settings.local.json'` — i.e. a
|
|
54
|
-
* module that routes per-IDE was itself naming one IDE and one IDE's file.
|
|
55
|
-
* Both now read off the adapter that owns them
|
|
56
|
-
* (`IdeSettingsLocation.localSettingsFileName`), exactly as
|
|
57
|
-
* `auto-compact-dispatcher.ts` already did for the same field.
|
|
58
|
-
*
|
|
59
|
-
* Behaviour is UNCHANGED, and that was verified rather than assumed: over all
|
|
60
|
-
* nine registered `IdeId`s, `IDES_WITH_LOCAL_SETTINGS.has(id)` was `true` for
|
|
61
|
-
* exactly the ids whose adapter declares `localSettingsFileName` (claude-code
|
|
62
|
-
* alone, `'settings.local.json'`). So the set was an exact duplicate of a
|
|
63
|
-
* declaration the adapters already carried, not an independent policy — and
|
|
64
|
-
* a new adapter that declares the field now gets this path for free instead
|
|
65
|
-
* of being silently denied it.
|
|
23
|
+
* The peaks-managed entries grouped by the settings file that carries each one.
|
|
66
24
|
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* relocating there.
|
|
25
|
+
* Peaks hooks normally land in the adapter's settings file. The gate-enforce Bash
|
|
26
|
+
* entry is the exception: on Windows its `shell` is pinned to `powershell`, because
|
|
27
|
+
* the default Git-Bash shell force-allocates a console window on every Bash tool call.
|
|
28
|
+
* A machine-specific value must never be committed into the SHARED file a macOS/Linux
|
|
29
|
+
* teammate reads, so that entry lands in the machine-local file instead; routing keys
|
|
30
|
+
* off its own `machineLocal` flag, never off `process.platform`.
|
|
74
31
|
*/
|
|
75
|
-
function resolveLocalSettingsPath(scope, ide, projectRoot) {
|
|
76
|
-
if (scope === 'global')
|
|
77
|
-
return undefined;
|
|
78
|
-
const adapter = getAdapter(ide);
|
|
79
|
-
const localFileName = adapter.settings.localSettingsFileName;
|
|
80
|
-
// `undefined` = this IDE has no machine-local layer. Note the order: a
|
|
81
|
-
// caller reaching here with an id the registry does not know still throws
|
|
82
|
-
// from `getAdapter` above, exactly as it did before — every path into this
|
|
83
|
-
// function already called `getAdapter(ide)` via `resolveSettingsPath`, so
|
|
84
|
-
// no new throw path is introduced.
|
|
85
|
-
if (localFileName === undefined)
|
|
86
|
-
return undefined;
|
|
87
|
-
const root = resolveSettingsRoot(scope, projectRoot);
|
|
88
|
-
assertSafeSettingsFile(scope, root, adapter.settings.dirName, localFileName);
|
|
89
|
-
return join(root, adapter.settings.dirName, localFileName);
|
|
90
|
-
}
|
|
91
32
|
function resolveHookTargets(scope, ide, projectRoot) {
|
|
92
33
|
const sharedPath = resolveSettingsPath(scope, ide, projectRoot);
|
|
93
34
|
const localPath = resolveLocalSettingsPath(scope, ide, projectRoot);
|
|
94
35
|
const wantsEnvExemptions = ide === 'claude-code';
|
|
95
36
|
if (localPath === undefined || localPath === sharedPath) {
|
|
96
|
-
// Global scope lands here: the user-level file is already machine-local,
|
|
97
|
-
// so it is the safe target (there is no sibling to prefer).
|
|
98
37
|
return [
|
|
99
38
|
{
|
|
100
39
|
settingsPath: sharedPath,
|
|
@@ -114,187 +53,32 @@ function resolveHookTargets(scope, ide, projectRoot) {
|
|
|
114
53
|
}
|
|
115
54
|
return [shared, local];
|
|
116
55
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
function describeEntryTargets(targets) {
|
|
126
|
-
return targets.flatMap((target) => target.entries.map((entry) => ({
|
|
127
|
-
matcher: entry.matcher,
|
|
128
|
-
sentinel: entry.sentinel,
|
|
129
|
-
settingsPath: target.settingsPath
|
|
130
|
-
})));
|
|
131
|
-
}
|
|
132
|
-
/** Read a settings file as an object, or `{}` when it does not exist yet. */
|
|
133
|
-
function readSettingsFile(settingsPath) {
|
|
134
|
-
return existsSync(settingsPath) ? readJsonObjectFile(settingsPath) : {};
|
|
135
|
-
}
|
|
136
|
-
/** Read the existing hook array entries for the adapter's hookEvent (tolerant of any prior shape). */
|
|
137
|
-
function readHookEventEntries(settings, eventKey) {
|
|
138
|
-
const hooks = settings.hooks;
|
|
139
|
-
if (!hooks || typeof hooks !== 'object' || Array.isArray(hooks))
|
|
140
|
-
return [];
|
|
141
|
-
const arr = hooks[eventKey];
|
|
142
|
-
return Array.isArray(arr) ? arr : [];
|
|
143
|
-
}
|
|
144
|
-
/** Read the existing hook array entries from a `settings.hooks` object (already extracted). */
|
|
145
|
-
function readHookEntriesFromHooks(hooks, eventKey) {
|
|
146
|
-
const arr = hooks[eventKey];
|
|
147
|
-
return Array.isArray(arr) ? arr : [];
|
|
148
|
-
}
|
|
149
|
-
/** True when every command handler in the entry matches a known peaks sentinel for the given IDE. */
|
|
150
|
-
function entryIsPeaksManaged(entry, sentinels) {
|
|
151
|
-
const handlers = Array.isArray(entry?.hooks) ? entry.hooks : [];
|
|
152
|
-
if (handlers.length === 0)
|
|
153
|
-
return false;
|
|
154
|
-
return handlers.every((h) => {
|
|
155
|
-
if (typeof h?.command !== 'string')
|
|
156
|
-
return false;
|
|
157
|
-
const cmd = h.command;
|
|
158
|
-
return sentinels.some((sentinel) => cmd.includes(sentinel));
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Slice #014: read the *actually-installed* peaks-managed hook entries
|
|
163
|
-
* from a settings object. Replaces the pre-#014 `listInstalledEntriesForIde`
|
|
164
|
-
* helper in `hooks-commands.ts`, which returned the IDE-EXPECTED list
|
|
165
|
-
* (a hardcoded 2-entry array per adapter) rather than what was on disk.
|
|
166
|
-
* That bug surfaced when slice #013's local cleanup installed
|
|
167
|
-
* `peaks hooks install --no-progress` (gate-enforce only), but the
|
|
168
|
-
* status command still reported `entries: [Bash, Task]` because the
|
|
169
|
-
* helper didn't read the file.
|
|
170
|
-
*
|
|
171
|
-
* The new helper:
|
|
172
|
-
* 1. reads each `hooks.<event>` array,
|
|
173
|
-
* 2. filters to entries that are peaks-managed for the given IDE
|
|
174
|
-
* (matches the legacy sentinel set: gate-enforce + the no-longer-
|
|
175
|
-
* installed progress-start),
|
|
176
|
-
* 3. returns one `{ matcher, sentinel }` row per entry, taking the
|
|
177
|
-
* FIRST matching sentinel per entry (entries have a single command
|
|
178
|
-
* handler in practice, but the loop tolerates multi-handler
|
|
179
|
-
* entries by taking the first match).
|
|
180
|
-
*
|
|
181
|
-
* Pre-#014 settings.json files that have a stale progress-start entry
|
|
182
|
-
* will see it surface in the result. This is intentional: the status
|
|
183
|
-
* command is the user's tool for "what is on disk right now", and
|
|
184
|
-
* surfacing a stale entry is the only way the user can know to run
|
|
185
|
-
* `peaks hooks install` (which now strips it) or `peaks hooks
|
|
186
|
-
* uninstall` (which removes it).
|
|
187
|
-
*/
|
|
188
|
-
export function readInstalledEntriesFromSettings(settings, ide) {
|
|
189
|
-
const sentinels = resolveLegacySentinels(ide);
|
|
190
|
-
// Walk every event key the settings file has, not just the
|
|
191
|
-
// adapter-declared one. A pre-#014 install could have left a
|
|
192
|
-
// progress-start entry on a different event than the gate-enforce
|
|
193
|
-
// entry (Trae: both on beforeToolCall, but a stale install on a
|
|
194
|
-
// future IDE could split them).
|
|
195
|
-
const hooksRoot = settings.hooks;
|
|
196
|
-
if (!hooksRoot || typeof hooksRoot !== 'object' || Array.isArray(hooksRoot))
|
|
197
|
-
return [];
|
|
198
|
-
const result = [];
|
|
199
|
-
for (const eventKey of Object.keys(hooksRoot)) {
|
|
200
|
-
const entries = readHookEntriesFromHooks(hooksRoot, eventKey);
|
|
201
|
-
for (const entry of entries) {
|
|
202
|
-
if (!entryIsPeaksManaged(entry, sentinels))
|
|
203
|
-
continue;
|
|
204
|
-
const matcher = typeof entry.matcher === 'string' ? entry.matcher : '';
|
|
205
|
-
// Find the first matching sentinel inside the entry's command
|
|
206
|
-
// handlers. For each handler, find the first sentinel substring
|
|
207
|
-
// it contains. We pick the first handler's first matching
|
|
208
|
-
// sentinel (entries have a single command in practice).
|
|
209
|
-
const firstHandler = Array.isArray(entry.hooks) ? entry.hooks[0] : undefined;
|
|
210
|
-
const cmd = typeof firstHandler?.command === 'string' ? firstHandler.command : '';
|
|
211
|
-
const sentinel = sentinels.find((s) => cmd.includes(s));
|
|
212
|
-
if (matcher === '' || sentinel === undefined)
|
|
213
|
-
continue;
|
|
214
|
-
result.push({ matcher, sentinel });
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
return result;
|
|
218
|
-
}
|
|
219
|
-
/**
|
|
220
|
-
* Merge the peaks-managed Skill denylist into the existing settings object.
|
|
221
|
-
* Preserves every other `permissions.deny` entry the user (or another tool)
|
|
222
|
-
* has written so the install is additive, not destructive. The output is
|
|
223
|
-
* always deterministic: the same input always yields the same output,
|
|
224
|
-
* regardless of insertion order in the source array.
|
|
225
|
-
*
|
|
226
|
-
* Defensive behavior:
|
|
227
|
-
* - `settings.permissions` is missing or non-object → install creates a
|
|
228
|
-
* fresh `permissions: { deny: [...our entries] }` object.
|
|
229
|
-
* - `settings.permissions.deny` is missing or non-array → install replaces
|
|
230
|
-
* the field with a fresh array containing only our entries.
|
|
231
|
-
* - Duplicate entries (any source) are collapsed to one via `new Set`.
|
|
232
|
-
*
|
|
233
|
-
* The function is pure: it does not mutate the input. Atomic write happens
|
|
234
|
-
* at the call site (`applyHookInstall`).
|
|
235
|
-
*/
|
|
236
|
-
export function withSuperpowersSkillDenylist(settings) {
|
|
237
|
-
const ourEntries = SUPERPOWERS_DENIED_SKILLS.map(formatSuperpowersDenyEntry);
|
|
238
|
-
const permissions = settings.permissions &&
|
|
239
|
-
typeof settings.permissions === 'object' &&
|
|
240
|
-
!Array.isArray(settings.permissions)
|
|
241
|
-
? settings.permissions
|
|
242
|
-
: {};
|
|
243
|
-
const existingDeny = Array.isArray(permissions.deny)
|
|
244
|
-
? permissions.deny.filter((d) => typeof d === 'string')
|
|
245
|
-
: [];
|
|
246
|
-
const otherDeny = existingDeny.filter((d) => !SUPERPOWERS_DENY_SENTINELS.has(d));
|
|
247
|
-
const finalDeny = [...new Set([...otherDeny, ...ourEntries])];
|
|
56
|
+
function readInstallEnvelope(scope, projectRoot, options, alreadyInstalled) {
|
|
57
|
+
const ide = resolveIde(options);
|
|
58
|
+
const root = resolveSettingsRoot(scope, projectRoot);
|
|
59
|
+
const settingsPath = resolveSettingsPath(scope, ide, projectRoot);
|
|
60
|
+
assertSafeSettingsPathCompat(scope, ide, root, settingsPath);
|
|
61
|
+
const targets = resolveHookTargets(scope, ide, projectRoot);
|
|
62
|
+
const spec = resolveHookSpec(ide);
|
|
63
|
+
const localTarget = targets.find((t) => t.settingsPath !== settingsPath);
|
|
248
64
|
return {
|
|
249
|
-
|
|
250
|
-
|
|
65
|
+
ide,
|
|
66
|
+
targets,
|
|
67
|
+
settingsPath,
|
|
68
|
+
plan: {
|
|
69
|
+
scope,
|
|
70
|
+
settingsPath,
|
|
71
|
+
exists: existsSync(settingsPath),
|
|
72
|
+
// Written here, in the published field order a `--json` caller reads.
|
|
73
|
+
alreadyInstalled: alreadyInstalled(targets, ide),
|
|
74
|
+
desiredCommand: spec.hookEnforceCommand,
|
|
75
|
+
sentinel: spec.hookEnforceSentinel,
|
|
76
|
+
matcher: spec.hookEnforceMatcher,
|
|
77
|
+
...(localTarget !== undefined ? { localSettingsPath: localTarget.settingsPath } : {}),
|
|
78
|
+
entryTargets: describeEntryTargets(targets)
|
|
79
|
+
}
|
|
251
80
|
};
|
|
252
81
|
}
|
|
253
|
-
/**
|
|
254
|
-
* Inverse of `withSuperpowersSkillDenylist`. Removes every peaks-managed
|
|
255
|
-
* `UseSkill(...)` entry from the deny list. If the resulting deny list is
|
|
256
|
-
* empty, the `deny` field itself is deleted; if the `permissions` object
|
|
257
|
-
* becomes empty, the `permissions` field itself is deleted. This is the
|
|
258
|
-
* uninstall path: every field we wrote must be removed exactly, and no
|
|
259
|
-
* other field may be touched.
|
|
260
|
-
*
|
|
261
|
-
* Pure (no mutation).
|
|
262
|
-
*/
|
|
263
|
-
export function withoutSuperpowersSkillDenylist(settings) {
|
|
264
|
-
const permissions = settings.permissions &&
|
|
265
|
-
typeof settings.permissions === 'object' &&
|
|
266
|
-
!Array.isArray(settings.permissions)
|
|
267
|
-
? settings.permissions
|
|
268
|
-
: {};
|
|
269
|
-
if (!Array.isArray(permissions.deny)) {
|
|
270
|
-
return settings;
|
|
271
|
-
}
|
|
272
|
-
const remainingDeny = permissions.deny
|
|
273
|
-
.filter((d) => typeof d === 'string')
|
|
274
|
-
.filter((d) => !SUPERPOWERS_DENY_SENTINELS.has(d));
|
|
275
|
-
const nextPermissions = { ...permissions };
|
|
276
|
-
if (remainingDeny.length > 0) {
|
|
277
|
-
nextPermissions.deny = remainingDeny;
|
|
278
|
-
}
|
|
279
|
-
else {
|
|
280
|
-
delete nextPermissions.deny;
|
|
281
|
-
}
|
|
282
|
-
if (Object.keys(nextPermissions).length === 0) {
|
|
283
|
-
// The whole `permissions` object is empty (no deny, no allow, no other
|
|
284
|
-
// sub-fields). Drop it to avoid leaving an empty object on disk.
|
|
285
|
-
const { permissions: _omit, ...rest } = settings;
|
|
286
|
-
return rest;
|
|
287
|
-
}
|
|
288
|
-
return { ...settings, permissions: nextPermissions };
|
|
289
|
-
}
|
|
290
|
-
/**
|
|
291
|
-
* Read-only introspection. Returns the deny entries that `peaks hooks
|
|
292
|
-
* install` would write today. Useful for `peaks hooks status` and the
|
|
293
|
-
* dry-run envelope.
|
|
294
|
-
*/
|
|
295
|
-
export function listSuperpowersDenyEntries() {
|
|
296
|
-
return SUPERPOWERS_DENIED_SKILLS.map(formatSuperpowersDenyEntry);
|
|
297
|
-
}
|
|
298
82
|
/** Default (claude-code) peaks-managed hook entries — kept as a stable export for tests. Slice #014: only the gate-enforce entry. */
|
|
299
83
|
export const PEAKS_HOOK_ENTRIES = (() => {
|
|
300
84
|
const spec = resolveHookSpec('claude-code');
|
|
@@ -307,203 +91,30 @@ export const PEAKS_HOOK_ENTRIES = (() => {
|
|
|
307
91
|
}
|
|
308
92
|
];
|
|
309
93
|
})();
|
|
310
|
-
function isInstalledForEntries(settings, entries) {
|
|
311
|
-
const sentinels = entries.map((e) => e.sentinel);
|
|
312
|
-
// Check every distinct event key our entries could be on.
|
|
313
|
-
const eventKeys = new Set(entries.map((e) => e.event));
|
|
314
|
-
for (const eventKey of eventKeys) {
|
|
315
|
-
if (readHookEventEntries(settings, eventKey).some((e) => entryIsPeaksManaged(e, sentinels))) {
|
|
316
|
-
return true;
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
return false;
|
|
320
|
-
}
|
|
321
|
-
/**
|
|
322
|
-
* Slice #014: detect the "stale progress entry after pre-#014 install"
|
|
323
|
-
* case. The desired shape is gate-enforce-only. If the file currently
|
|
324
|
-
* has a peaks-managed progress-start entry (left behind by a pre-#014
|
|
325
|
-
* install), the install is NOT a no-op — it must strip the stale
|
|
326
|
-
* entry. This helper returns true exactly when the desired shape is
|
|
327
|
-
* fully reflected on disk: gate-enforce present AND no legacy
|
|
328
|
-
* progress-start present.
|
|
329
|
-
*/
|
|
330
|
-
function shapeMatchesDesired(settings, entries, allPeaksSentinels) {
|
|
331
|
-
const eventKeys = new Set(entries.map((e) => e.event));
|
|
332
|
-
for (const eventKey of eventKeys) {
|
|
333
|
-
// Only the entries that belong to THIS event key can be expected on it —
|
|
334
|
-
// the desired set must be per-event, or a target whose entries span two
|
|
335
|
-
// event keys (claude-code: SessionStart + PreToolUse) would never look
|
|
336
|
-
// installed and every `peaks hooks install` would rewrite the files.
|
|
337
|
-
const desiredSentinels = new Set(entries.filter((e) => e.event === eventKey).map((e) => e.sentinel));
|
|
338
|
-
const present = readHookEventEntries(settings, eventKey);
|
|
339
|
-
const peaksPresent = present.filter((e) => entryIsPeaksManaged(e, allPeaksSentinels));
|
|
340
|
-
// (a) every peaks-managed entry currently on disk must match the
|
|
341
|
-
// desired sentinel set (no stale entries the caller wants removed).
|
|
342
|
-
for (const entry of peaksPresent) {
|
|
343
|
-
const entrySentinels = (entry.hooks ?? [])
|
|
344
|
-
.map((h) => allPeaksSentinels.find((s) => String(h.command ?? '').includes(s)))
|
|
345
|
-
.filter((s) => Boolean(s));
|
|
346
|
-
if (entrySentinels.some((s) => !desiredSentinels.has(s))) {
|
|
347
|
-
return false;
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
// (b) every desired entry must be on disk AND carry the matcher it declares.
|
|
351
|
-
// Presence alone cannot see a WRONG matcher, and a wrong matcher is not
|
|
352
|
-
// cosmetic: `''` and `Bash|Task` route the same command to different
|
|
353
|
-
// tool sets, so the entry is present while the hook never fires on the
|
|
354
|
-
// residual R2): a `PostCompact` entry hand-corrupted to matcher
|
|
355
|
-
// `auto|manual` survived `peaks hooks install` unchanged, and the
|
|
356
|
-
// installer was structurally unable to repair it.
|
|
357
|
-
// An absent matcher reads as `''` — the form Claude Code takes as "every
|
|
358
|
-
// source" — so a file written before matchers were explicit converges
|
|
359
|
-
// once instead of churning on every install.
|
|
360
|
-
for (const desired of entries.filter((e) => e.event === eventKey)) {
|
|
361
|
-
const onDisk = peaksPresent.find((entry) => (entry.hooks ?? []).some((h) => String(h.command ?? '').includes(desired.sentinel)));
|
|
362
|
-
if (onDisk === undefined || (onDisk.matcher ?? '') !== desired.matcher)
|
|
363
|
-
return false;
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
return true;
|
|
367
|
-
}
|
|
368
94
|
export function planHookInstall(scope, projectRoot, options) {
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
const spec = resolveHookSpec(ide);
|
|
377
|
-
const localTarget = targets.find((t) => t.settingsPath !== settingsPath);
|
|
378
|
-
return {
|
|
379
|
-
scope,
|
|
380
|
-
settingsPath,
|
|
381
|
-
exists,
|
|
382
|
-
// The env clause mirrors `applyHookInstall`'s: without it the dry-run would
|
|
383
|
-
// claim "nothing to do" about a file the install is going to write.
|
|
384
|
-
alreadyInstalled: targets.every((t) => {
|
|
385
|
-
const settings = readSettingsFile(t.settingsPath);
|
|
386
|
-
return (isInstalledForEntries(settings, t.entries) &&
|
|
387
|
-
(t.envExemptions !== true || hasExternalGateExemptions(settings)));
|
|
388
|
-
}),
|
|
389
|
-
desiredCommand: spec.hookEnforceCommand,
|
|
390
|
-
sentinel: spec.hookEnforceSentinel,
|
|
391
|
-
matcher: spec.hookEnforceMatcher,
|
|
392
|
-
...(localTarget !== undefined ? { localSettingsPath: localTarget.settingsPath } : {}),
|
|
393
|
-
entryTargets: describeEntryTargets(targets)
|
|
394
|
-
};
|
|
395
|
-
}
|
|
396
|
-
/**
|
|
397
|
-
* Merge a target's peaks-managed hook entries into `settings`, preserving
|
|
398
|
-
* all other keys and hooks. Entries routed to a DIFFERENT settings file are
|
|
399
|
-
* not part of `entries`, so the legacy-sentinel filter below strips them
|
|
400
|
-
* from this file (that is what migrates a gate-enforce entry that an older
|
|
401
|
-
* peaks release wrote into the shared file).
|
|
402
|
-
*/
|
|
403
|
-
function withHooksInstalled(settings, entries, allSentinels) {
|
|
404
|
-
const existingHooks = settings.hooks && typeof settings.hooks === 'object' && !Array.isArray(settings.hooks)
|
|
405
|
-
? settings.hooks
|
|
406
|
-
: {};
|
|
407
|
-
// Our entries may sit on more than one event key. Group by event so each
|
|
408
|
-
// event array is independently merged.
|
|
409
|
-
const ourByEvent = new Map();
|
|
410
|
-
for (const spec of entries) {
|
|
411
|
-
const list = ourByEvent.get(spec.event) ?? [];
|
|
412
|
-
list.push(spec);
|
|
413
|
-
ourByEvent.set(spec.event, list);
|
|
414
|
-
}
|
|
415
|
-
// Slice #014: the legacy sentinel set includes the progress-start
|
|
416
|
-
// sentinel so a pre-#014 install's stale progress-start entry is
|
|
417
|
-
// stripped by the filter (the file converges on the new
|
|
418
|
-
// gate-enforce-only shape, idempotently). The desired set (passed
|
|
419
|
-
// in below) only contains the gate-enforce sentinel.
|
|
420
|
-
const nextHooks = { ...existingHooks };
|
|
421
|
-
// An event key this file used to carry but whose entries all moved to the
|
|
422
|
-
// other file still needs its stale peaks entries stripped.
|
|
423
|
-
const eventKeys = new Set([...ourByEvent.keys(), ...Object.keys(existingHooks)]);
|
|
424
|
-
for (const eventKey of eventKeys) {
|
|
425
|
-
const existing = readHookEntriesFromHooks(nextHooks, eventKey);
|
|
426
|
-
const nonPeaks = existing.filter((entry) => !entryIsPeaksManaged(entry, allSentinels));
|
|
427
|
-
const ourFormatted = (ourByEvent.get(eventKey) ?? []).map((spec) => ({
|
|
428
|
-
matcher: spec.matcher,
|
|
429
|
-
hooks: [
|
|
430
|
-
{
|
|
431
|
-
type: 'command',
|
|
432
|
-
command: spec.command,
|
|
433
|
-
...(spec.shell !== undefined ? { shell: spec.shell } : {})
|
|
434
|
-
}
|
|
435
|
-
]
|
|
436
|
-
}));
|
|
437
|
-
const merged = [...nonPeaks, ...ourFormatted];
|
|
438
|
-
if (merged.length > 0) {
|
|
439
|
-
nextHooks[eventKey] = merged;
|
|
440
|
-
}
|
|
441
|
-
else {
|
|
442
|
-
delete nextHooks[eventKey];
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
return {
|
|
446
|
-
...settings,
|
|
447
|
-
hooks: nextHooks
|
|
448
|
-
};
|
|
95
|
+
// The env clause mirrors `applyHookInstall`'s: without it the dry run claims "nothing
|
|
96
|
+
// to do" about a file the install is about to write.
|
|
97
|
+
return readInstallEnvelope(scope, projectRoot, options, (targets) => targets.every((t) => {
|
|
98
|
+
const settings = readSettingsFile(t.settingsPath);
|
|
99
|
+
return (isInstalledForEntries(settings, t.entries) &&
|
|
100
|
+
(t.envExemptions !== true || hasExternalGateExemptions(settings)));
|
|
101
|
+
})).plan;
|
|
449
102
|
}
|
|
450
103
|
export function applyHookInstall(scope, projectRoot, options) {
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
const settingsPath =
|
|
455
|
-
assertSafeSettingsPathCompat(scope, ide, root, settingsPath);
|
|
456
|
-
const exists = existsSync(settingsPath);
|
|
457
|
-
const spec = resolveHookSpec(ide);
|
|
458
|
-
const targets = resolveHookTargets(scope, ide, projectRoot);
|
|
104
|
+
// `alreadyInstalled` reflects the FULL desired shape — gate-enforce-only, no stale
|
|
105
|
+
// progress-start entry, the external-gate exemption present. Presence alone is not
|
|
106
|
+
// enough: a file left by an older release would look installed forever.
|
|
107
|
+
const { ide, targets, settingsPath, plan: baseResult } = readInstallEnvelope(scope, projectRoot, options, (t, i) => t.every((target) => targetIsSatisfied(target, resolveLegacySentinels(i))));
|
|
459
108
|
const allSentinels = resolveLegacySentinels(ide);
|
|
460
|
-
|
|
461
|
-
// Slice #014: `alreadyInstalled` reflects the FULL desired shape
|
|
462
|
-
// (gate-enforce-only + no stale progress-start entry). Pre-#014
|
|
463
|
-
// installs that left a progress-start entry behind will be treated
|
|
464
|
-
// as not-yet-installed, so the merge strips the stale entry on the
|
|
465
|
-
// next install call. This is the only path that converges the file
|
|
466
|
-
// on the new shape; pure presence-checks are insufficient.
|
|
467
|
-
//
|
|
468
|
-
// The external-gate exemption is part of the desired shape too, so a project
|
|
469
|
-
// installed by a release that predates it still converges on upgrade.
|
|
470
|
-
const alreadyInstalled = targets.every((t) => targetIsSatisfied(t, allSentinels));
|
|
471
|
-
const baseResult = {
|
|
472
|
-
scope,
|
|
473
|
-
settingsPath,
|
|
474
|
-
exists,
|
|
475
|
-
alreadyInstalled,
|
|
476
|
-
desiredCommand: spec.hookEnforceCommand,
|
|
477
|
-
sentinel: spec.hookEnforceSentinel,
|
|
478
|
-
matcher: spec.hookEnforceMatcher,
|
|
479
|
-
...(localTarget !== undefined ? { localSettingsPath: localTarget.settingsPath } : {}),
|
|
480
|
-
entryTargets: describeEntryTargets(targets)
|
|
481
|
-
};
|
|
482
|
-
if (baseResult.alreadyInstalled) {
|
|
109
|
+
if (baseResult.alreadyInstalled)
|
|
483
110
|
return { ...baseResult, applied: false };
|
|
484
|
-
|
|
485
|
-
//
|
|
486
|
-
//
|
|
487
|
-
// helper is idempotent and additive: any user-written deny entries
|
|
488
|
-
// are preserved.
|
|
489
|
-
//
|
|
490
|
-
// withTriggeredDenyList. If the existing settings file has a
|
|
491
|
-
// superpowers / git-worktree / podman-run entry (any source),
|
|
492
|
-
// the install appends a defensive `Edit(deny-trigger:<phrase>)`
|
|
493
|
-
// entry. The chain cannot run raw `git worktree add` (or
|
|
494
|
-
// `podman run`) without an explicit `peaks hooks uninstall`
|
|
495
|
-
// first. Both helpers are pure + idempotent.
|
|
496
|
-
//
|
|
497
|
-
// The `permissions.deny` block lives in the adapter's settings file
|
|
498
|
-
// only (as it always has) — it is committed, so the deny list is
|
|
499
|
-
// shared; the machine-local file carries hook entries plus, for Claude
|
|
500
|
-
// Code, the third-party gate exemptions (machine-local by the same
|
|
501
|
-
// argument as the hook `shell` pin).
|
|
111
|
+
// The `permissions.deny` block rides the same atomic write as the hook entries, so
|
|
112
|
+
// the two halves of the install are always co-located. It lives in the adapter's
|
|
113
|
+
// settings file only — it is committed, so the deny list is shared.
|
|
502
114
|
for (const target of targets) {
|
|
503
115
|
let next = withHooksInstalled(readSettingsFile(target.settingsPath), target.entries, allSentinels);
|
|
504
|
-
if (target.envExemptions === true)
|
|
116
|
+
if (target.envExemptions === true)
|
|
505
117
|
next = withExternalGateExemptions(next);
|
|
506
|
-
}
|
|
507
118
|
const merged = target.settingsPath === settingsPath
|
|
508
119
|
? withTriggeredDenyList(withSuperpowersSkillDenylist(next))
|
|
509
120
|
: next;
|
|
@@ -517,227 +128,38 @@ export function removeHookInstall(scope, projectRoot, options) {
|
|
|
517
128
|
const settingsPath = resolveSettingsPath(scope, ide, projectRoot);
|
|
518
129
|
assertSafeSettingsPathCompat(scope, ide, root, settingsPath);
|
|
519
130
|
// An IDE with no HOOK_COMMAND_BY_IDE entry can never carry a peaks hook, so
|
|
520
|
-
// "remove it" is already true
|
|
521
|
-
//
|
|
522
|
-
// `
|
|
523
|
-
// a successful install there would claim an enforcement that cannot exist.
|
|
524
|
-
//
|
|
525
|
-
// `resolveHookTargets` below is what throws for these IDEs, so the check has
|
|
526
|
-
// to come first. Note `resolveSettingsPath` above still runs: an IDE the
|
|
527
|
-
// adapter registry does not know at all remains a hard error.
|
|
131
|
+
// "remove it" is already true: a no-op success, not a failure. This stays
|
|
132
|
+
// asymmetric with `applyHookInstall`, which fails closed for the same IDEs;
|
|
133
|
+
// `resolveHookTargets` below is what throws for them, so the check comes first.
|
|
528
134
|
if (!hasHookSpec(ide)) {
|
|
529
|
-
|
|
530
|
-
return {
|
|
531
|
-
scope,
|
|
532
|
-
settingsPath,
|
|
533
|
-
removed: false,
|
|
534
|
-
...(localSettingsPath !== undefined && localSettingsPath !== settingsPath
|
|
535
|
-
? { localSettingsPath }
|
|
536
|
-
: {})
|
|
537
|
-
};
|
|
135
|
+
return removedResult(scope, settingsPath, resolveLocalSettingsPath(scope, ide, projectRoot), false);
|
|
538
136
|
}
|
|
539
137
|
const targets = resolveHookTargets(scope, ide, projectRoot);
|
|
540
138
|
const localTarget = targets.find((t) => t.settingsPath !== settingsPath);
|
|
541
139
|
const present = targets.filter((t) => existsSync(t.settingsPath));
|
|
542
140
|
if (present.length === 0) {
|
|
543
|
-
return
|
|
544
|
-
scope,
|
|
545
|
-
settingsPath,
|
|
546
|
-
removed: false,
|
|
547
|
-
...(localTarget !== undefined ? { localSettingsPath: localTarget.settingsPath } : {})
|
|
548
|
-
};
|
|
141
|
+
return removedResult(scope, settingsPath, localTarget?.settingsPath, false);
|
|
549
142
|
}
|
|
550
|
-
//
|
|
551
|
-
//
|
|
552
|
-
// The legacy sentinel set covers both shapes so the uninstall
|
|
553
|
-
// converges the file on "no peaks-managed entries", regardless of
|
|
554
|
-
// what shape the file was in when the user ran uninstall.
|
|
143
|
+
// The legacy sentinel set covers BOTH the gate-enforce and the pre-#014 progress-start
|
|
144
|
+
// entries, so uninstall converges the file however it was shaped.
|
|
555
145
|
const sentinels = resolveLegacySentinels(ide);
|
|
556
146
|
let removedAny = false;
|
|
557
147
|
for (const target of present) {
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
// Scan every event key on disk as well as the ones we install on:
|
|
561
|
-
// entries may have been routed to the other settings file by a
|
|
562
|
-
// previous install.
|
|
563
|
-
const eventKeys = new Set([
|
|
564
|
-
...target.entries.map((e) => e.event),
|
|
565
|
-
...Object.keys(existingHooks)
|
|
566
|
-
]);
|
|
567
|
-
const nextHooks = { ...existingHooks };
|
|
568
|
-
for (const eventKey of eventKeys) {
|
|
569
|
-
const entries = readHookEntriesFromHooks(nextHooks, eventKey);
|
|
570
|
-
const kept = entries.filter((entry) => !entryIsPeaksManaged(entry, sentinels));
|
|
571
|
-
if (kept.length !== entries.length)
|
|
572
|
-
removedAny = true;
|
|
573
|
-
if (kept.length > 0) {
|
|
574
|
-
nextHooks[eventKey] = kept;
|
|
575
|
-
}
|
|
576
|
-
else {
|
|
577
|
-
delete nextHooks[eventKey];
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
const nextSettings = { ...settings };
|
|
581
|
-
if (Object.keys(nextHooks).length > 0) {
|
|
582
|
-
nextSettings.hooks = nextHooks;
|
|
148
|
+
if (applyRemovalToTarget(target, sentinels, target.settingsPath === settingsPath)) {
|
|
149
|
+
removedAny = true;
|
|
583
150
|
}
|
|
584
|
-
else {
|
|
585
|
-
delete nextSettings.hooks;
|
|
586
|
-
}
|
|
587
|
-
// Strips the peaks-managed `UseSkill(...)` deny entries alongside the
|
|
588
|
-
// hook entries; user-written entries are untouched. The helper self-
|
|
589
|
-
// decomposes an empty `permissions` object.
|
|
590
|
-
//
|
|
591
|
-
// trigger-style deny entries via withoutTriggeredDenyList. The
|
|
592
|
-
// chain of helpers is order-independent (each is idempotent and
|
|
593
|
-
// additive over the same set of peaks-managed entries).
|
|
594
|
-
let finalSettings = nextSettings;
|
|
595
|
-
if (target.envExemptions === true) {
|
|
596
|
-
finalSettings = withoutExternalGateExemptions(finalSettings);
|
|
597
|
-
}
|
|
598
|
-
if (target.settingsPath === settingsPath) {
|
|
599
|
-
finalSettings = withoutTriggeredDenyList(withoutSuperpowersSkillDenylist(finalSettings));
|
|
600
|
-
}
|
|
601
|
-
atomicWriteJson(target.settingsPath, finalSettings);
|
|
602
151
|
}
|
|
603
|
-
return
|
|
604
|
-
scope,
|
|
605
|
-
settingsPath,
|
|
606
|
-
removed: removedAny,
|
|
607
|
-
...(localTarget !== undefined ? { localSettingsPath: localTarget.settingsPath } : {})
|
|
608
|
-
};
|
|
152
|
+
return removedResult(scope, settingsPath, localTarget?.settingsPath, removedAny);
|
|
609
153
|
}
|
|
610
154
|
export function readHookStatus(scope, projectRoot, options) {
|
|
611
155
|
const ide = resolveIde(options);
|
|
612
156
|
const root = resolveSettingsRoot(scope, projectRoot);
|
|
613
157
|
const settingsPath = resolveSettingsPath(scope, ide, projectRoot);
|
|
614
158
|
assertSafeSettingsPathCompat(scope, ide, root, settingsPath);
|
|
615
|
-
//
|
|
616
|
-
// have one, so "what is installed?" has a definite answer
|
|
617
|
-
// no-op success, exactly like `removeHookInstall` — the query ran, the disk
|
|
618
|
-
// was read, and the honest reply is `supportsHooks: false, installed: false`.
|
|
619
|
-
// This stays asymmetric with `applyHookInstall`, which still fails closed for
|
|
620
|
-
// the same IDEs: reporting a successful INSTALL would claim an enforcement
|
|
621
|
-
// that cannot exist, whereas reporting a successful STATUS claims nothing.
|
|
622
|
-
//
|
|
623
|
-
// `resolveHookTargets` below is what throws for these IDEs, so the check has
|
|
624
|
-
// to come first. `resolveSettingsPath` above still runs: an IDE the adapter
|
|
625
|
-
// registry does not know at all remains a hard error.
|
|
159
|
+
// As in `removeHookInstall`: an IDE with no HOOK_COMMAND_BY_IDE entry has no hook on
|
|
160
|
+
// disk and can never have one, so "what is installed?" has a definite answer — nothing.
|
|
626
161
|
if (!hasHookSpec(ide)) {
|
|
627
|
-
|
|
628
|
-
return {
|
|
629
|
-
scope,
|
|
630
|
-
settingsPath,
|
|
631
|
-
exists: existsSync(settingsPath),
|
|
632
|
-
...(localSettingsPath !== undefined && localSettingsPath !== settingsPath
|
|
633
|
-
? { localSettingsPath, localExists: existsSync(localSettingsPath) }
|
|
634
|
-
: {}),
|
|
635
|
-
installed: false,
|
|
636
|
-
supportsHooks: false
|
|
637
|
-
};
|
|
638
|
-
}
|
|
639
|
-
const targets = resolveHookTargets(scope, ide, projectRoot);
|
|
640
|
-
const exists = existsSync(settingsPath);
|
|
641
|
-
const localTarget = targets.find((t) => t.settingsPath !== settingsPath);
|
|
642
|
-
return {
|
|
643
|
-
scope,
|
|
644
|
-
settingsPath,
|
|
645
|
-
exists,
|
|
646
|
-
...(localTarget !== undefined
|
|
647
|
-
? {
|
|
648
|
-
localSettingsPath: localTarget.settingsPath,
|
|
649
|
-
localExists: existsSync(localTarget.settingsPath)
|
|
650
|
-
}
|
|
651
|
-
: {}),
|
|
652
|
-
installed: targets.some((t) => {
|
|
653
|
-
const settings = readSettingsFile(t.settingsPath);
|
|
654
|
-
return Object.keys(settings).length > 0 && isInstalledForEntries(settings, t.entries);
|
|
655
|
-
}),
|
|
656
|
-
supportsHooks: true
|
|
657
|
-
};
|
|
658
|
-
}
|
|
659
|
-
/**
|
|
660
|
-
*
|
|
661
|
-
* In addition to the static SUPERPOWERS_DENIED_SKILLS list, peaks
|
|
662
|
-
* scans the existing settings file for "trigger phrases" that
|
|
663
|
-
* indicate the user has configured the superpowers chain (or
|
|
664
|
-
* any other auto-run worktree-creating tool) and appends a
|
|
665
|
-
* defensive deny to prevent the chain from running raw
|
|
666
|
-
* `git worktree add` (or `podman run`) directly.
|
|
667
|
-
*
|
|
668
|
-
* Triggers detected (substring match on the existing
|
|
669
|
-
* permissions.deny / permissions.allow list):
|
|
670
|
-
*
|
|
671
|
-
* - `superpowers:using-git-worktrees` — the chain's ground zero
|
|
672
|
-
* - `superpowers:brainstorming` etc. — the upstream skill
|
|
673
|
-
* - `Bash(git worktree add` — the user has explicitly
|
|
674
|
-
* allowed raw git worktree, which our L2 lease-aware gate
|
|
675
|
-
* would also intercept (defense in depth)
|
|
676
|
-
*
|
|
677
|
-
* Append-only — never replaces, never re-orders, never removes
|
|
678
|
-
* existing entries. Idempotent: re-running the install with
|
|
679
|
-
* the same input yields the same output.
|
|
680
|
-
*/
|
|
681
|
-
export const TRIGGER_PHRASES = Object.freeze([
|
|
682
|
-
'superpowers:using-git-worktrees',
|
|
683
|
-
'superpowers:brainstorming',
|
|
684
|
-
'superpowers:writing-plans',
|
|
685
|
-
'superpowers:subagent-driven-development',
|
|
686
|
-
'Bash(git worktree add',
|
|
687
|
-
'Bash(podman run'
|
|
688
|
-
]);
|
|
689
|
-
/**
|
|
690
|
-
* Format a trigger-phrase into a stable `Edit` deny entry. We deny
|
|
691
|
-
* `Edit` (not `Bash`) on the *settings file* itself, so the
|
|
692
|
-
* user cannot edit the trigger away without an explicit
|
|
693
|
-
* `peaks hooks uninstall` first. The skill name (when
|
|
694
|
-
* applicable) is the value after the colon.
|
|
695
|
-
*/
|
|
696
|
-
function formatTriggerDenyEntry(phrase) {
|
|
697
|
-
return `Edit(deny-trigger:${phrase})`;
|
|
698
|
-
}
|
|
699
|
-
export function withTriggeredDenyList(settings) {
|
|
700
|
-
const existingDeny = Array.isArray(settings.permissions?.deny)
|
|
701
|
-
? settings.permissions.deny.filter((d) => typeof d === 'string')
|
|
702
|
-
: [];
|
|
703
|
-
// Detect triggers in the existing allow + deny lists.
|
|
704
|
-
const existingAllow = Array.isArray(settings.permissions?.allow)
|
|
705
|
-
? settings.permissions.allow.filter((d) => typeof d === 'string')
|
|
706
|
-
: [];
|
|
707
|
-
const haystack = [...existingDeny, ...existingAllow].join('|');
|
|
708
|
-
const triggered = TRIGGER_PHRASES.filter((p) => haystack.includes(p));
|
|
709
|
-
if (triggered.length === 0)
|
|
710
|
-
return settings;
|
|
711
|
-
const triggeredEntries = triggered.map(formatTriggerDenyEntry);
|
|
712
|
-
const permissions = settings.permissions &&
|
|
713
|
-
typeof settings.permissions === 'object' &&
|
|
714
|
-
!Array.isArray(settings.permissions)
|
|
715
|
-
? settings.permissions
|
|
716
|
-
: {};
|
|
717
|
-
const otherDeny = existingDeny.filter((d) => !triggeredEntries.includes(d));
|
|
718
|
-
return {
|
|
719
|
-
...settings,
|
|
720
|
-
permissions: { ...permissions, deny: [...new Set([...otherDeny, ...triggeredEntries])] }
|
|
721
|
-
};
|
|
722
|
-
}
|
|
723
|
-
/** Inverse of withTriggeredDenyList: strip every deny-trigger entry. */
|
|
724
|
-
export function withoutTriggeredDenyList(settings) {
|
|
725
|
-
const permissions = settings.permissions &&
|
|
726
|
-
typeof settings.permissions === 'object' &&
|
|
727
|
-
!Array.isArray(settings.permissions)
|
|
728
|
-
? settings.permissions
|
|
729
|
-
: {};
|
|
730
|
-
const existingDeny = Array.isArray(permissions.deny)
|
|
731
|
-
? permissions.deny.filter((d) => typeof d === 'string')
|
|
732
|
-
: [];
|
|
733
|
-
const kept = existingDeny.filter((d) => !d.startsWith('Edit(deny-trigger:'));
|
|
734
|
-
const next = { ...permissions, deny: kept };
|
|
735
|
-
if (kept.length === 0)
|
|
736
|
-
delete next.deny;
|
|
737
|
-
if (Object.keys(next).length === 0) {
|
|
738
|
-
const out = { ...settings };
|
|
739
|
-
delete out.permissions;
|
|
740
|
-
return out;
|
|
162
|
+
return unsupportedHookStatus(scope, settingsPath, resolveLocalSettingsPath(scope, ide, projectRoot));
|
|
741
163
|
}
|
|
742
|
-
return
|
|
164
|
+
return hookStatusFromTargets(scope, settingsPath, resolveHookTargets(scope, ide, projectRoot));
|
|
743
165
|
}
|