peaks-loop 4.0.0-beta.9 → 4.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +572 -234
- package/README-en.md +67 -30
- package/README.md +67 -30
- package/agents/karpathy-reviewer.md +33 -0
- package/bin/peaks.js +0 -0
- package/dist/cli/cli-helpers.d.ts +31 -6
- package/dist/cli/cli-helpers.js +48 -25
- package/dist/cli/commands/_register.d.ts +3 -0
- package/dist/cli/commands/_register.js +139 -0
- package/dist/cli/commands/_super.d.ts +10 -0
- package/dist/cli/commands/_super.js +97 -0
- package/dist/cli/commands/adapter-commands-s2a.js +1 -1
- package/dist/cli/commands/asset-commands.js +33 -16
- package/dist/cli/commands/audit-commands.js +2 -2
- package/dist/cli/commands/autonomous-swarm-commands.d.ts +12 -0
- package/dist/cli/commands/autonomous-swarm-commands.js +120 -0
- package/dist/cli/commands/bee-commands.js +1 -1
- package/dist/cli/commands/capability-commands.js +1 -1
- package/dist/cli/commands/capability-worker-config-sc-commands.js +0 -2
- package/dist/cli/commands/changeset-commands.d.ts +13 -0
- package/dist/cli/commands/changeset-commands.js +46 -0
- package/dist/cli/commands/code-commands.d.ts +11 -1
- package/dist/cli/commands/code-commands.js +19 -699
- package/dist/cli/commands/code-job-shape-commands.d.ts +9 -0
- package/dist/cli/commands/code-job-shape-commands.js +164 -0
- package/dist/cli/commands/code-mode-gate-commands.d.ts +9 -0
- package/dist/cli/commands/code-mode-gate-commands.js +223 -0
- package/dist/cli/commands/code-review-commands.js +2 -2
- package/dist/cli/commands/code-run-command.d.ts +12 -0
- package/dist/cli/commands/code-run-command.js +68 -0
- package/dist/cli/commands/code-runtime-commands.d.ts +11 -0
- package/dist/cli/commands/code-runtime-commands.js +391 -0
- package/dist/cli/commands/codegraph-commands.js +1 -1
- package/dist/cli/commands/compact-command.js +53 -1
- package/dist/cli/commands/complexity-commands.js +1 -1
- package/dist/cli/commands/config-commands.js +4 -75
- package/dist/cli/commands/container-commands.d.ts +28 -0
- package/dist/cli/commands/container-commands.js +221 -0
- package/dist/cli/commands/context-commands.js +3 -2
- package/dist/cli/commands/core/artifacts-command.js +1 -1
- package/dist/cli/commands/core/binding-commands.js +1 -1
- package/dist/cli/commands/core/doctor-command.js +63 -3
- package/dist/cli/commands/core/memory-command.js +1 -1
- package/dist/cli/commands/core/profile-command.js +1 -1
- package/dist/cli/commands/core/proxy-command.js +1 -1
- package/dist/cli/commands/core/session-command.js +9 -7
- package/dist/cli/commands/core/skill-command.js +7 -4
- package/dist/cli/commands/core/standards-command.js +1 -1
- package/dist/cli/commands/cron-commands.d.ts +57 -0
- package/dist/cli/commands/cron-commands.js +257 -0
- package/dist/cli/commands/cron-scheduler-commands.d.ts +47 -0
- package/dist/cli/commands/cron-scheduler-commands.js +284 -0
- package/dist/cli/commands/dashboard-commands.d.ts +4 -0
- package/dist/cli/commands/dashboard-commands.js +10 -0
- package/dist/cli/commands/dashboard-long-run.d.ts +25 -0
- package/dist/cli/commands/dashboard-long-run.js +122 -0
- package/dist/cli/commands/dashboard-summary.d.ts +12 -0
- package/dist/cli/commands/dashboard-summary.js +58 -0
- package/dist/cli/commands/dispatch-commands.d.ts +0 -7
- package/dist/cli/commands/dispatch-commands.js +372 -8
- package/dist/cli/commands/dispatch-from-dag.js +4 -1
- package/dist/cli/commands/doc-commands.js +1 -1
- package/dist/cli/commands/ecc-commands.d.ts +30 -0
- package/dist/cli/commands/ecc-commands.js +119 -0
- package/dist/cli/commands/evolution-commands.js +1 -1
- package/dist/cli/commands/feedback-commands.js +1 -1
- package/dist/cli/commands/final-review-commands.js +1 -1
- package/dist/cli/commands/fixture-commands.js +1 -1
- package/dist/cli/commands/fork-commands.js +1 -1
- package/dist/cli/commands/gate-commands.js +128 -6
- package/dist/cli/commands/governance-classify-contract-commands.d.ts +21 -0
- package/dist/cli/commands/governance-classify-contract-commands.js +273 -0
- package/dist/cli/commands/heartbeat-commands.js +76 -5
- package/dist/cli/commands/heartbeat-watch-command.d.ts +31 -0
- package/dist/cli/commands/heartbeat-watch-command.js +146 -0
- package/dist/cli/commands/hook-handle.js +1 -1
- package/dist/cli/commands/hooks-commands.js +126 -10
- package/dist/cli/commands/ide-commands.js +1 -1
- package/dist/cli/commands/impact-commands.js +1 -1
- package/dist/cli/commands/job-commands.js +34 -1
- package/dist/cli/commands/lease-metrics-commands.d.ts +67 -0
- package/dist/cli/commands/lease-metrics-commands.js +231 -0
- package/dist/cli/commands/lease-stats-commands.d.ts +65 -0
- package/dist/cli/commands/lease-stats-commands.js +107 -0
- package/dist/cli/commands/legacy-commands.js +1 -1
- package/dist/cli/commands/log-commands.js +1 -1
- package/dist/cli/commands/loop-commands.js +1 -1
- package/dist/cli/commands/loop-eval-commands.js +1 -1
- package/dist/cli/commands/memory-commands.js +1 -1
- package/dist/cli/commands/migrate-1-4-1-command.js +1 -1
- package/dist/cli/commands/migrate-v2-10-to-v2-11-command.js +1 -1
- package/dist/cli/commands/mut-commands.d.ts +1 -1
- package/dist/cli/commands/mut-commands.js +1 -5
- package/dist/cli/commands/observability-commands.js +1 -1
- package/dist/cli/commands/openspec-commands.js +65 -4
- package/dist/cli/commands/perf-audit-commands.js +3 -3
- package/dist/cli/commands/perf-commands.js +1 -1
- package/dist/cli/commands/polyrepo-commands.js +1 -1
- package/dist/cli/commands/prd-blocks-commands.js +1 -1
- package/dist/cli/commands/prd-commands.js +4 -2
- package/dist/cli/commands/preferences-commands.js +23 -3
- package/dist/cli/commands/project-commands.js +1 -1
- package/dist/cli/commands/qa-business-review-commands.js +1 -1
- package/dist/cli/commands/qa-commands.d.ts +1 -1
- package/dist/cli/commands/qa-commands.js +39 -3
- package/dist/cli/commands/release-commands.d.ts +15 -0
- package/dist/cli/commands/release-commands.js +113 -21
- package/dist/cli/commands/request-commands.js +1 -1
- package/dist/cli/commands/retrospective-commands.js +1 -1
- package/dist/cli/commands/reviewer-commands.js +1 -1
- package/dist/cli/commands/role-commands.js +1 -1
- package/dist/cli/commands/runtime-commands-helpers.d.ts +7 -0
- package/dist/cli/commands/runtime-commands-helpers.js +24 -0
- package/dist/cli/commands/runtime-commands.js +1 -2
- package/dist/cli/commands/sc-commands.js +4 -2
- package/dist/cli/commands/scan-commands.js +1 -1
- package/dist/cli/commands/security-audit-commands.js +3 -3
- package/dist/cli/commands/sediment-commands.js +10 -1
- package/dist/cli/commands/session-24h-mode.d.ts +26 -0
- package/dist/cli/commands/session-24h-mode.js +196 -0
- package/dist/cli/commands/share-commands.d.ts +19 -0
- package/dist/cli/commands/share-commands.js +121 -2
- package/dist/cli/commands/skill-conformance-commands.js +1 -1
- package/dist/cli/commands/skill-loop-engineering-readiness-commands.js +1 -1
- package/dist/cli/commands/skill-search-commands.js +4 -1
- package/dist/cli/commands/slice-commands.js +1 -1
- package/dist/cli/commands/slice-integrate-commands.js +1 -1
- package/dist/cli/commands/slice-review-commands.js +1 -1
- package/dist/cli/commands/smoke-commands.js +1 -1
- package/dist/cli/commands/sop-commands.js +1 -1
- package/dist/cli/commands/spill-demo-command.d.ts +7 -0
- package/dist/cli/commands/spill-demo-command.js +29 -0
- package/dist/cli/commands/statusline-commands.d.ts +12 -0
- package/dist/cli/commands/statusline-commands.js +79 -17
- package/dist/cli/commands/sub-agent-commands.js +2 -1
- package/dist/cli/commands/sub-agent-shared.d.ts +10 -0
- package/dist/cli/commands/sub-agent-shared.js +24 -1
- package/dist/cli/commands/swarm-commands.d.ts +13 -0
- package/dist/cli/commands/swarm-commands.js +77 -0
- package/dist/cli/commands/tech-commands.d.ts +64 -0
- package/dist/cli/commands/tech-commands.js +195 -0
- package/dist/cli/commands/understand-commands.js +1 -1
- package/dist/cli/commands/upgrade-commands.d.ts +2 -0
- package/dist/cli/commands/upgrade-commands.js +40 -5
- package/dist/cli/commands/user-touchpoint-commands.js +1 -1
- package/dist/cli/commands/verdict-aggregate-command.js +1 -1
- package/dist/cli/commands/vm-commands.d.ts +31 -0
- package/dist/cli/commands/vm-commands.js +274 -0
- package/dist/cli/commands/workflow-commands.js +24 -1
- package/dist/cli/commands/workflow-plan-commands.js +1 -1
- package/dist/cli/commands/workspace/init-command.js +1 -1
- package/dist/cli/commands/workspace/migrate-command.js +1 -1
- package/dist/cli/commands/workspace/reconcile-command.js +1 -1
- package/dist/cli/commands/worktree-auth-commands.d.ts +29 -0
- package/dist/cli/commands/worktree-auth-commands.js +652 -0
- package/dist/cli/index.js +58 -13
- package/dist/cli/program.d.ts +2 -2
- package/dist/cli/program.js +86 -281
- package/dist/services/24h-mode/decider.d.ts +103 -0
- package/dist/services/24h-mode/decider.js +144 -0
- package/dist/services/24h-mode/index.d.ts +12 -0
- package/dist/services/24h-mode/index.js +12 -0
- package/dist/services/24h-mode/state.d.ts +48 -0
- package/dist/services/24h-mode/state.js +51 -0
- package/dist/services/24h-mode/store.d.ts +27 -0
- package/dist/services/24h-mode/store.js +119 -0
- package/dist/services/artifacts/artifact-prerequisites.js +1 -1
- package/dist/services/artifacts/request-artifact-service.js +1 -1
- package/dist/services/artifacts/workspace-service.js +1 -1
- package/dist/services/audit/enforcers/lint-bee-runtime-contract.d.ts +25 -0
- package/dist/services/audit/enforcers/lint-bee-runtime-contract.js +91 -0
- package/dist/services/audit/enforcers/lint-peaks-code-runtime.d.ts +16 -0
- package/dist/services/audit/enforcers/lint-peaks-code-runtime.js +31 -0
- package/dist/services/audit/enforcers/lint-peaks-skill-runtime.d.ts +23 -0
- package/dist/services/audit/enforcers/lint-peaks-skill-runtime.js +59 -0
- package/dist/services/audit/enforcers/lint-peaks-ui-sc-txt-runtime.d.ts +28 -0
- package/dist/services/audit/enforcers/lint-peaks-ui-sc-txt-runtime.js +86 -0
- package/dist/services/audit/enforcers/lint-prd-artifact-handoff.d.ts +16 -0
- package/dist/services/audit/enforcers/lint-prd-artifact-handoff.js +41 -0
- package/dist/services/audit/enforcers/lint-prd-source-snapshot.d.ts +27 -0
- package/dist/services/audit/enforcers/lint-prd-source-snapshot.js +47 -0
- package/dist/services/audit/enforcers/lint-qa-gateguard-and-runtime.d.ts +19 -0
- package/dist/services/audit/enforcers/lint-qa-gateguard-and-runtime.js +47 -0
- package/dist/services/audit/enforcers/lint-rd-handoff-coverage.d.ts +18 -0
- package/dist/services/audit/enforcers/lint-rd-handoff-coverage.js +70 -0
- package/dist/services/audit/enforcers/lint-skill-presence-mandatory.d.ts +25 -0
- package/dist/services/audit/enforcers/lint-skill-presence-mandatory.js +53 -0
- package/dist/services/audit/red-line-catalog-p2-a.d.ts +0 -6
- package/dist/services/audit/red-line-catalog-p2-a.js +230 -1
- package/dist/services/audit/static-service.d.ts +32 -25
- package/dist/services/audit/static-service.js +30 -109
- package/dist/services/audit-independent/index.d.ts +2 -0
- package/dist/services/audit-independent/index.js +2 -0
- package/dist/services/autonomous-swarm/autonomous-swarm-service.d.ts +127 -0
- package/dist/services/autonomous-swarm/autonomous-swarm-service.js +446 -0
- package/dist/services/changeset/changeset-check-service.d.ts +22 -0
- package/dist/services/changeset/changeset-check-service.js +47 -0
- package/dist/services/code/auto-compact-modes.d.ts +30 -0
- package/dist/services/code/auto-compact-modes.js +38 -0
- package/dist/services/code/auto-compact-orchestrator.d.ts +43 -5
- package/dist/services/code/auto-compact-orchestrator.js +101 -21
- package/dist/services/code/dag-orchestrator.d.ts +30 -1
- package/dist/services/code/dag-orchestrator.js +106 -1
- package/dist/services/code/status-line-renderer.d.ts +2 -0
- package/dist/services/code/status-line-renderer.js +21 -3
- package/dist/services/code-review/ocr-service.d.ts +1 -1
- package/dist/services/code-review/ocr-service.js +6 -3
- package/dist/services/compact-history/compact-history-service.d.ts +41 -0
- package/dist/services/compact-history/compact-history-service.js +62 -0
- package/dist/services/compact-statusline/compact-statusline-service.d.ts +16 -0
- package/dist/services/compact-statusline/compact-statusline-service.js +83 -0
- package/dist/services/config/config-service.d.ts +1 -12
- package/dist/services/config/config-service.js +3 -72
- package/dist/services/config/config-types.d.ts +2 -4
- package/dist/services/config/config-types.js +1 -1
- package/dist/services/container/container-lease.d.ts +67 -0
- package/dist/services/container/container-lease.js +135 -0
- package/dist/services/context/auto-compact-dispatcher.d.ts +40 -5
- package/dist/services/context/auto-compact-dispatcher.js +32 -102
- package/dist/services/context/auto-compact-reader.js +1 -1
- package/dist/services/context/auto-compact-types.d.ts +27 -2
- package/dist/services/context/auto-compact-types.js +8 -1
- package/dist/services/context/build-dispatch-system-prompt.d.ts +75 -0
- package/dist/services/context/build-dispatch-system-prompt.js +117 -0
- package/dist/services/context/collector.d.ts +2 -2
- package/dist/services/context/context-builder.d.ts +4 -4
- package/dist/services/context/context-schema.d.ts +48 -48
- package/dist/services/context/ide-detect.d.ts +4 -0
- package/dist/services/context/ide-detect.js +24 -0
- package/dist/services/context/main-session-monitor.d.ts +1 -4
- package/dist/services/context/main-session-monitor.js +1 -24
- package/dist/services/context/memory-index-reader.d.ts +8 -0
- package/dist/services/context/memory-index-reader.js +57 -0
- package/dist/services/context/memory-lru-cache.d.ts +12 -0
- package/dist/services/context/memory-lru-cache.js +60 -0
- package/dist/services/context/memory-preflight-config.d.ts +19 -0
- package/dist/services/context/memory-preflight-config.js +25 -0
- package/dist/services/context/memory-preflight-service.d.ts +19 -0
- package/dist/services/context/memory-preflight-service.js +120 -0
- package/dist/services/context/spillover-store.d.ts +23 -0
- package/dist/services/context/spillover-store.js +155 -0
- package/dist/services/context/spillover-types.d.ts +18 -0
- package/dist/services/context/spillover-types.js +1 -0
- package/dist/services/crystallization/crystallization-service.d.ts +22 -5
- package/dist/services/crystallization/crystallization-service.js +8 -14
- package/dist/services/crystallization/crystallization-types.d.ts +6 -6
- package/dist/services/crystallization/evidence-brief-builder.d.ts +1 -1
- package/dist/services/crystallization/index.d.ts +13 -0
- package/dist/services/crystallization/index.js +13 -0
- package/dist/services/dashboard/project-dashboard-service.js +2 -2
- package/dist/services/dispatch/await-batch.d.ts +70 -0
- package/dist/services/dispatch/await-batch.js +272 -0
- package/dist/services/dispatch/batch-counter.js +1 -1
- package/dist/services/dispatch/dispatch-record-writer.d.ts +126 -4
- package/dist/services/dispatch/dispatch-record-writer.js +239 -9
- package/dist/services/dispatch/slice-dag.d.ts +46 -0
- package/dist/services/dispatch/slice-dag.js +6 -0
- package/dist/services/dispatch/stage-enum.d.ts +27 -0
- package/dist/services/dispatch/stage-enum.js +48 -0
- package/dist/services/dispatch/startup-timeout.d.ts +86 -0
- package/dist/services/dispatch/startup-timeout.js +97 -0
- package/dist/services/dispatch/sub-agent-dispatcher.js +40 -89
- package/dist/services/dispatch/test-tool-detection.d.ts +25 -1
- package/dist/services/dispatch/test-tool-detection.js +80 -0
- package/dist/services/doctor/doctor-service/checks/check-id-schema.d.ts +18 -0
- package/dist/services/doctor/doctor-service/checks/check-id-schema.js +64 -0
- package/dist/services/doctor/doctor-service/checks/codegraph-capability.d.ts +14 -0
- package/dist/services/doctor/doctor-service/checks/codegraph-capability.js +69 -0
- package/dist/services/doctor/doctor-service/checks/dist-source-version.d.ts +32 -0
- package/dist/services/doctor/doctor-service/checks/dist-source-version.js +110 -0
- package/dist/services/doctor/doctor-service/checks/gateguard-conflict.d.ts +24 -0
- package/dist/services/doctor/doctor-service/checks/gateguard-conflict.js +164 -0
- package/dist/services/doctor/doctor-service/checks/l3-memory-health.d.ts +16 -0
- package/dist/services/doctor/doctor-service/checks/l3-memory-health.js +57 -0
- package/dist/services/doctor/doctor-service/checks/l3-orphan-sessions.d.ts +19 -0
- package/dist/services/doctor/doctor-service/checks/l3-orphan-sessions.js +66 -0
- package/dist/services/doctor/doctor-service/checks/schema-validity.d.ts +10 -0
- package/dist/services/doctor/doctor-service/checks/schema-validity.js +33 -0
- package/dist/services/doctor/doctor-service/checks/skill-apply-note.d.ts +20 -0
- package/dist/services/doctor/doctor-service/checks/skill-apply-note.js +85 -0
- package/dist/services/doctor/doctor-service/checks/skill-existence.d.ts +13 -0
- package/dist/services/doctor/doctor-service/checks/skill-existence.js +30 -0
- package/dist/services/doctor/doctor-service/checks/skill-name-match.d.ts +10 -0
- package/dist/services/doctor/doctor-service/checks/skill-name-match.js +25 -0
- package/dist/services/doctor/doctor-service/checks/skill-parse.d.ts +10 -0
- package/dist/services/doctor/doctor-service/checks/skill-parse.js +19 -0
- package/dist/services/doctor/doctor-service/checks/skill-presence.d.ts +21 -0
- package/dist/services/doctor/doctor-service/checks/skill-presence.js +75 -0
- package/dist/services/doctor/doctor-service/checks/skill-runbook.d.ts +14 -0
- package/dist/services/doctor/doctor-service/checks/skill-runbook.js +47 -0
- package/dist/services/doctor/doctor-service/checks/statusline-install.d.ts +14 -0
- package/dist/services/doctor/doctor-service/checks/statusline-install.js +32 -0
- package/dist/services/doctor/doctor-service/checks/statusline-runtime.d.ts +13 -0
- package/dist/services/doctor/doctor-service/checks/statusline-runtime.js +30 -0
- package/dist/services/doctor/doctor-service/checks/user-config.d.ts +11 -0
- package/dist/services/doctor/doctor-service/checks/user-config.js +27 -0
- package/dist/services/doctor/doctor-service/checks/workspace-init.d.ts +16 -0
- package/dist/services/doctor/doctor-service/checks/workspace-init.js +34 -0
- package/dist/services/doctor/doctor-service/checks/workspace-layout.d.ts +33 -0
- package/dist/services/doctor/doctor-service/checks/workspace-layout.js +180 -0
- package/dist/services/doctor/doctor-service/index.d.ts +48 -0
- package/dist/services/doctor/doctor-service/index.js +254 -0
- package/dist/services/doctor/doctor-service/plugin-registry.d.ts +41 -0
- package/dist/services/doctor/doctor-service/plugin-registry.js +77 -0
- package/dist/services/doctor/doctor-service/report/final-summary.d.ts +20 -0
- package/dist/services/doctor/doctor-service/report/final-summary.js +29 -0
- package/dist/services/doctor/doctor-service/types.d.ts +245 -0
- package/dist/services/doctor/doctor-service/types.js +15 -0
- package/dist/services/doctor/doctor-service.d.ts +15 -146
- package/dist/services/doctor/doctor-service.js +22 -926
- package/dist/services/doctor/index.d.ts +22 -0
- package/dist/services/doctor/index.js +22 -0
- package/dist/services/env/shell-probe.d.ts +71 -0
- package/dist/services/env/shell-probe.js +161 -0
- package/dist/services/evolution/evolution-types.d.ts +39 -39
- package/dist/services/final-review/final-review-service.d.ts +11 -1
- package/dist/services/final-review/index.d.ts +2 -0
- package/dist/services/final-review/index.js +1 -0
- package/dist/services/hooks/auto-compact-hook-install.d.ts +4 -5
- package/dist/services/hooks/auto-compact-hook-install.js +4 -5
- package/dist/services/hooks/worktree-authorization-gate.d.ts +205 -0
- package/dist/services/hooks/worktree-authorization-gate.js +492 -0
- package/dist/services/ide/adapters/claude-code-adapter.js +2 -2
- package/dist/services/ide/adapters/qoder-adapter.d.ts +25 -0
- package/dist/services/ide/adapters/qoder-adapter.js +57 -0
- package/dist/services/ide/adapters/tongyi-lingma-adapter.d.ts +16 -0
- package/dist/services/ide/adapters/tongyi-lingma-adapter.js +45 -0
- package/dist/services/ide/ide-registry.js +6 -0
- package/dist/services/ide/ide-types.d.ts +1 -1
- package/dist/services/job/job-types.d.ts +56 -56
- package/dist/services/job-snapshot/index.d.ts +8 -0
- package/dist/services/job-snapshot/index.js +7 -0
- package/dist/services/{job/job-resource-snapshot.d.ts → job-snapshot/snapshot.d.ts} +1 -1
- package/dist/services/job-snapshot/types.d.ts +7 -0
- package/dist/services/job-snapshot/types.js +1 -0
- package/dist/services/karpathy-cost/karpathy-cost-check-service.d.ts +67 -0
- package/dist/services/karpathy-cost/karpathy-cost-check-service.js +108 -0
- package/dist/services/log/retention.d.ts +16 -0
- package/dist/services/log/retention.js +17 -0
- package/dist/services/loop/loop-bee-relation-types.d.ts +6 -6
- package/dist/services/loop/loop-release-types.d.ts +24 -24
- package/dist/services/loop/monotonic-runner.d.ts +17 -11
- package/dist/services/loop/monotonic-runner.js +118 -79
- package/dist/services/memory/project-memory-service/index/kind-dispatch.d.ts +8 -0
- package/dist/services/memory/project-memory-service/index/kind-dispatch.js +253 -0
- package/dist/services/memory/project-memory-service/index/ranking.d.ts +6 -0
- package/dist/services/memory/project-memory-service/index/ranking.js +171 -0
- package/dist/services/memory/project-memory-service/index/search.d.ts +34 -0
- package/dist/services/memory/project-memory-service/index/search.js +194 -0
- package/dist/services/memory/project-memory-service/index.d.ts +9 -0
- package/dist/services/memory/project-memory-service/index.js +24 -0
- package/dist/services/memory/project-memory-service/parsers/frontmatter.d.ts +9 -0
- package/dist/services/memory/project-memory-service/parsers/frontmatter.js +106 -0
- package/dist/services/memory/project-memory-service/parsers/markdown-pure.d.ts +7 -0
- package/dist/services/memory/project-memory-service/parsers/markdown-pure.js +96 -0
- package/dist/services/memory/project-memory-service/store/atomic-write.d.ts +5 -0
- package/dist/services/memory/project-memory-service/store/atomic-write.js +56 -0
- package/dist/services/memory/project-memory-service/store/paths.d.ts +8 -0
- package/dist/services/memory/project-memory-service/store/paths.js +116 -0
- package/dist/services/memory/project-memory-service/types.d.ts +128 -0
- package/dist/services/memory/project-memory-service/types.js +9 -0
- package/dist/services/memory/project-memory-service.d.ts +1 -167
- package/dist/services/memory/project-memory-service.js +19 -816
- package/dist/services/migrate-skill-name/schema.d.ts +2 -2
- package/dist/services/observability/aggregation.d.ts +27 -0
- package/dist/services/observability/aggregation.js +72 -0
- package/dist/services/observability/observability-service.d.ts +73 -7
- package/dist/services/observability/observability-service.js +87 -1
- package/dist/services/openspec/artifact-boundary.d.ts +138 -0
- package/dist/services/openspec/artifact-boundary.js +150 -0
- package/dist/services/openspec/coverage-evidence-reader.d.ts +191 -0
- package/dist/services/openspec/coverage-evidence-reader.js +386 -0
- package/dist/services/openspec/openspec-archive-service.d.ts +70 -0
- package/dist/services/openspec/openspec-archive-service.js +320 -8
- package/dist/services/openspec/openspec-bridge-service.js +1 -1
- package/dist/services/openspec/openspec-init-service.js +1 -1
- package/dist/services/openspec/openspec-propose-from-doctor-service.js +1 -1
- package/dist/services/openspec/openspec-render-service.js +7 -4
- package/dist/services/openspec/openspec-scan-service.js +1 -1
- package/dist/services/openspec/openspec-validate-service.js +5 -4
- package/dist/services/preferences/preferences-service.js +10 -0
- package/dist/services/preferences/preferences-types.d.ts +13 -0
- package/dist/services/preferences/preferences-types.js +11 -0
- package/dist/services/qa/screenshot-archive-service.d.ts +51 -0
- package/dist/services/qa/screenshot-archive-service.js +134 -0
- package/dist/services/rd/rd-service.js +10 -11
- package/dist/services/rd/types.d.ts +32 -32
- package/dist/services/rd-swarm/rd-swarm-service.d.ts +60 -0
- package/dist/services/rd-swarm/rd-swarm-service.js +93 -0
- package/dist/services/recommendations/capability-seed-items.js +0 -1
- package/dist/services/recommendations/capability-seed-mappings.js +0 -1
- package/dist/services/recommendations/capability-seed-sources.js +0 -1
- package/dist/services/release/version-precheck-service.d.ts +51 -0
- package/dist/services/release/version-precheck-service.js +257 -0
- package/dist/services/scan/acceptance-coverage-service.js +1 -1
- package/dist/services/scan/archetype-service.js +1 -1
- package/dist/services/scan/existing-system-service.js +1 -1
- package/dist/services/scan/libraries-service.js +1 -1
- package/dist/services/sediment/json-schema.d.ts +40 -40
- package/dist/services/share/bundle-types.d.ts +12 -12
- package/dist/services/share/run-state-contract.d.ts +2 -2
- package/dist/services/skill/skill-search-service.d.ts +12 -7
- package/dist/services/skill/skill-search-service.js +8 -4
- package/dist/services/skillhub/migrations/001-initial.sql +71 -0
- package/dist/services/skillhub/migrations/002-loop-release.sql +32 -0
- package/dist/services/skillhub/migrations/003-loop-bee-relation.sql +35 -0
- package/dist/services/skillhub/migrations/004-loop-bee-extension.sql +65 -0
- package/dist/services/skillhub/migrations/005-evolution-evaluation.sql +81 -0
- package/dist/services/skillhub/migrations/006-crystallization-event.sql +92 -0
- package/dist/services/skills/hooks-settings-service.d.ts +75 -0
- package/dist/services/skills/hooks-settings-service.js +230 -2
- package/dist/services/skills/skill-registry.d.ts +1 -0
- package/dist/services/skills/skill-registry.js +6 -4
- package/dist/services/skills/skill-runbook-service.js +1 -1
- package/dist/services/slice/slice-check-service.js +1 -1
- package/dist/services/standards/main-session-monitor-ban-hook.d.ts +14 -0
- package/dist/services/standards/main-session-monitor-ban-hook.js +19 -0
- package/dist/services/standards/missing-standards-detector.d.ts +25 -0
- package/dist/services/standards/missing-standards-detector.js +43 -12
- package/dist/services/tech/tech-change-id-service.d.ts +82 -0
- package/dist/services/tech/tech-change-id-service.js +117 -0
- package/dist/services/understand/understand-hybrid-service.js +1 -1
- package/dist/services/understand/understand-scan-service.js +2 -2
- package/dist/services/upgrade/upgrade-service.js +4 -3
- package/dist/services/verdict/envelopes.d.ts +2 -2
- package/dist/services/verdict/envelopes.js +2 -2
- package/dist/services/verdict/verdict-aggregator.d.ts +3 -3
- package/dist/services/vm/vm-lease.d.ts +40 -0
- package/dist/services/vm/vm-lease.js +137 -0
- package/dist/services/workflow/autonomous-resume-writer.js +1 -1
- package/dist/services/workflow/pipeline-verify-gate-support.d.ts +47 -0
- package/dist/services/workflow/pipeline-verify-gate-support.js +194 -0
- package/dist/services/workflow/pipeline-verify-service.d.ts +17 -81
- package/dist/services/workflow/pipeline-verify-service.js +42 -218
- package/dist/services/workflow/pipeline-verify-types.d.ts +90 -0
- package/dist/services/workflow/pipeline-verify-types.js +10 -0
- package/dist/services/workflow/plan-reader.d.ts +1 -1
- package/dist/services/workflow/plan-reader.js +1 -1
- package/dist/services/workflow/plan-refresher.d.ts +1 -1
- package/dist/services/workflow/plan-refresher.js +1 -1
- package/dist/services/workflow/plan-trigger-detector.d.ts +1 -1
- package/dist/services/workflow/plan-trigger-detector.js +1 -1
- package/dist/services/workflow/workflow-autonomous-resume-helpers.d.ts +1 -1
- package/dist/services/workflow/workflow-autonomous-service.d.ts +2 -98
- package/dist/services/workflow/workflow-autonomous-types.d.ts +114 -0
- package/dist/services/workflow/workflow-autonomous-types.js +21 -0
- package/dist/services/workflow/workflow-router-service.js +18 -16
- package/dist/services/workflow/workflow-spec-lint.d.ts +13 -0
- package/dist/services/workflow/workflow-spec-lint.js +75 -0
- package/dist/services/workflow/workflow-spec-types.d.ts +100 -0
- package/dist/services/workflow/workflow-spec-types.js +13 -0
- package/dist/services/workflow/workflow-spec-yaml.d.ts +17 -0
- package/dist/services/workflow/workflow-spec-yaml.js +88 -0
- package/dist/services/workflow/workflow-spec.d.ts +11 -91
- package/dist/services/workflow/workflow-spec.js +16 -145
- package/dist/services/workspace/migrate-service.js +1 -1
- package/dist/services/workspace/workspace-service.js +1 -1
- package/dist/services/worktree/worktree-lease.d.ts +170 -0
- package/dist/services/worktree/worktree-lease.js +242 -0
- package/package.json +91 -51
- package/scripts/clean-dist.mjs +31 -1
- package/scripts/copy-templates.mjs +16 -0
- package/scripts/sync-version.mjs +53 -2
- package/skills/bee/peaks-perf-audit/SKILL.md +17 -0
- package/skills/bee/peaks-prd/SKILL.md +16 -0
- package/skills/bee/peaks-prd/test-prompts.json +12 -0
- package/skills/bee/peaks-qa/SKILL.md +16 -1
- package/skills/bee/peaks-qa/references/qa-sub-agent-dispatch.md +22 -0
- package/skills/bee/peaks-qa/test-prompts.json +12 -0
- package/skills/bee/peaks-rd/SKILL.md +29 -20
- package/skills/bee/peaks-rd/references/rd-sub-agent-dispatch.md +39 -0
- package/skills/bee/peaks-rd/test-prompts.json +12 -0
- package/skills/bee/peaks-reviewer/SKILL.md +17 -0
- package/skills/bee/peaks-sc/SKILL.md +16 -0
- package/skills/bee/peaks-security-audit/SKILL.md +17 -0
- package/skills/bee/peaks-txt/SKILL.md +16 -0
- package/skills/bee/peaks-txt/test-prompts.json +12 -0
- package/skills/bee/peaks-ui/SKILL.md +49 -43
- package/skills/bee/peaks-ui/test-prompts.json +12 -0
- package/skills/peaks-code/SKILL.md +54 -109
- package/skills/peaks-code/references/boundaries.md +15 -1
- package/skills/peaks-code/references/cron-scheduler-deployment.md +313 -0
- package/skills/peaks-code/references/external-skill-invocation.md +27 -0
- package/skills/peaks-code/references/lease-dashboard.html +224 -0
- package/skills/peaks-code/references/lease-stats.sample.json +26 -0
- package/skills/peaks-code/references/peaks-worktree-l2-enforcers.md +208 -0
- package/skills/peaks-code/references/periodic-checkpoint.md +4 -4
- package/skills/peaks-code/references/runbook.md +63 -1
- package/skills/peaks-code/references/startup-sequence.md +110 -0
- package/skills/peaks-code/references/step-0-8-gate.md +1 -1
- package/skills/peaks-code/references/sub-agent-dispatch.md +92 -1
- package/skills/peaks-code/references/worktree-governance.md +123 -0
- package/skills/peaks-code/test-prompts.json +12 -0
- package/skills/peaks-doctor/SKILL.md +1 -1
- package/skills/peaks-ide/SKILL.md +1 -1
- package/skills/peaks-solo/SKILL.md +21 -0
- package/skills/peaks-solo/references/triage-decision-table.md +6 -0
- package/skills/peaks-sop/test-prompts.json +17 -0
- package/dist/cli/commands/agent-commands.d.ts +0 -20
- package/dist/cli/commands/agent-commands.js +0 -48
- package/dist/cli/commands/classify-classify-commands.d.ts +0 -19
- package/dist/cli/commands/classify-classify-commands.js +0 -151
- package/dist/cli/commands/contract-commands.d.ts +0 -26
- package/dist/cli/commands/contract-commands.js +0 -114
- package/dist/cli/commands/session-auto-compact-hook-command.d.ts +0 -37
- package/dist/cli/commands/session-auto-compact-hook-command.js +0 -127
- package/dist/cli/commands/worker-commands.d.ts +0 -3
- package/dist/cli/commands/worker-commands.js +0 -52
- package/dist/services/agent/ecc-agent-service.d.ts +0 -47
- package/dist/services/agent/ecc-agent-service.js +0 -143
- package/dist/services/config/provider-service.d.ts +0 -48
- package/dist/services/config/provider-service.js +0 -143
- package/dist/services/context/dispatch-context-guard.d.ts +0 -27
- package/dist/services/context/dispatch-context-guard.js +0 -192
- package/dist/services/context/shared-channel.d.ts +0 -93
- package/dist/services/context/shared-channel.js +0 -308
- package/dist/services/filesystem/file-lock.d.ts +0 -11
- package/dist/services/filesystem/file-lock.js +0 -152
- package/dist/services/mut/assert-scanner.d.ts +0 -6
- package/dist/services/mut/assert-scanner.js +0 -116
- package/dist/services/mut/index.d.ts +0 -8
- package/dist/services/mut/index.js +0 -7
- package/dist/services/mut/mut-runner.d.ts +0 -39
- package/dist/services/mut/mut-runner.js +0 -29
- package/dist/services/mut/production-stryker.d.ts +0 -2
- package/dist/services/mut/production-stryker.js +0 -75
- package/dist/services/mut/report-builder.d.ts +0 -11
- package/dist/services/mut/report-builder.js +0 -110
- package/dist/services/mut/report-loader.d.ts +0 -31
- package/dist/services/mut/report-loader.js +0 -78
- package/dist/services/mut/thresholds.d.ts +0 -21
- package/dist/services/mut/thresholds.js +0 -22
- package/dist/services/mut/types.d.ts +0 -336
- package/dist/services/mut/types.js +0 -59
- package/dist/services/providers/minimax-provider-service.d.ts +0 -24
- package/dist/services/providers/minimax-provider-service.js +0 -143
- package/dist/services/providers/minimax-worker-service.d.ts +0 -21
- package/dist/services/providers/minimax-worker-service.js +0 -83
- package/dist/shared/fs.d.ts +0 -4
- package/dist/shared/fs.js +0 -26
- package/dist/shared/paths.d.ts +0 -6
- package/dist/shared/paths.js +0 -50
- package/dist/shared/result.d.ts +0 -22
- package/dist/shared/result.js +0 -46
- package/dist/shared/version.d.ts +0 -1
- package/dist/shared/version.js +0 -1
- package/examples/video-demo/README.md +0 -142
- package/examples/video-demo/out/en-closing-960.png +0 -0
- package/examples/video-demo/out/zh-closing-960.png +0 -0
- package/examples/video-demo/preview/peaks-loop-demo-en.mp4 +0 -0
- package/examples/video-demo/preview/peaks-loop-demo.mp4 +0 -0
- /package/dist/services/{job/job-resource-snapshot.js → job-snapshot/snapshot.js} +0 -0
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* peaks-loop Worktree Authorization Gate (slice 2026-07-27-worktree-user-auth).
|
|
3
|
+
*
|
|
4
|
+
* Project-level red line: no autonomous LLM path is allowed to create a
|
|
5
|
+
* Git worktree, switch Claude Code's Agent isolation to "worktree",
|
|
6
|
+
* or fabricate a clean-tree baseline via `git stash` — unless the user
|
|
7
|
+
* has, in the *current task / current session*, explicitly authorized
|
|
8
|
+
* that exact operation. Authorization is recorded by
|
|
9
|
+
* `peaks worktree auth grant` (see `worktree-auth-commands.ts`) and is
|
|
10
|
+
* scoped to:
|
|
11
|
+
*
|
|
12
|
+
* - sessionId: the active peaks session at grant time
|
|
13
|
+
* - requestId: the active peaks request at grant time (if any)
|
|
14
|
+
* - operation: one of the OperationType values
|
|
15
|
+
* - expiresAt: hard deadline (default +5 min from grant)
|
|
16
|
+
* - consumed: single-use vs multi-use (gate calls `consume()` on use)
|
|
17
|
+
*
|
|
18
|
+
* The gate is invoked from `peaks gate enforce` (the PreToolUse hook
|
|
19
|
+
* command) for every Bash / Agent / EnterWorktree tool call. It is
|
|
20
|
+
* fail-closed: a malformed grant file, a missing scope, an expired
|
|
21
|
+
* token, or any other evaluation error → deny with a structured
|
|
22
|
+
* `WORKTREE_USER_AUTH_REQUIRED` reason.
|
|
23
|
+
*
|
|
24
|
+
* Why this is a service, not just a regex: a regex can match the
|
|
25
|
+
* command but cannot check "did the current user just say so". The
|
|
26
|
+
* user-originated authorization is a current-task file artifact;
|
|
27
|
+
* the gate is its consumer.
|
|
28
|
+
*
|
|
29
|
+
* Why single-use by default: an LLM can pass the gate once per
|
|
30
|
+
* authorized intent. If the same LLM needs to run a second
|
|
31
|
+
* `git worktree add` later, it must `peaks worktree auth grant`
|
|
32
|
+
* again — which is exactly the moment the user can say no. Multi-use
|
|
33
|
+
* is a deliberate opt-in via `--multi`.
|
|
34
|
+
*/
|
|
35
|
+
import { createHash } from 'node:crypto';
|
|
36
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
37
|
+
import { dirname, join } from 'node:path';
|
|
38
|
+
import { deserializeLease, isLeaseActive, leaseFilePath, } from '../worktree/worktree-lease.js';
|
|
39
|
+
import { containerLeaseFilePath, deserializeContainerLease, isContainerLeaseActive, } from '../container/container-lease.js';
|
|
40
|
+
export const WORKTREE_AUTH_FILE = 'worktree-auth.json';
|
|
41
|
+
/** Stable identifier of the current "user authorization" — derived from session + tool + key args. */
|
|
42
|
+
export function currentAuthFingerprint(input) {
|
|
43
|
+
// 16 hex chars is enough for tie-breaking; the gate never uses this as a security boundary, only as a
|
|
44
|
+
// log-correlation key.
|
|
45
|
+
const seed = `${input.sessionId}|${input.toolName}|${input.command ?? ''}|${input.isolation ?? ''}`;
|
|
46
|
+
return createHash('sha1').update(seed).digest('hex').slice(0, 16);
|
|
47
|
+
}
|
|
48
|
+
/** The file the gate reads. Default location: `.peaks/_runtime/<sessionId>/worktree-auth.json`. */
|
|
49
|
+
export function worktreeAuthFilePath(projectRoot, sessionId) {
|
|
50
|
+
return join(projectRoot, '.peaks', '_runtime', sessionId, WORKTREE_AUTH_FILE);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Read + validate the on-disk grant file. Returns `null` for "no file" (not an error — just no auth
|
|
54
|
+
* recorded yet). Throws `WorktreeAuthFileInvalidError` for malformed JSON / wrong shape / wrong
|
|
55
|
+
* sessionId — the gate treats this as deny, not allow. We never silently fail open.
|
|
56
|
+
*/
|
|
57
|
+
export function readAuthorization(projectRoot, sessionId) {
|
|
58
|
+
const path = worktreeAuthFilePath(projectRoot, sessionId);
|
|
59
|
+
if (!existsSync(path))
|
|
60
|
+
return null;
|
|
61
|
+
const raw = readFileSync(path, 'utf8');
|
|
62
|
+
let parsed;
|
|
63
|
+
try {
|
|
64
|
+
parsed = JSON.parse(raw);
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
throw new WorktreeAuthFileInvalidError(`worktree-auth.json: invalid JSON (${error.message})`, { path });
|
|
68
|
+
}
|
|
69
|
+
if (!isAuthorizationFile(parsed)) {
|
|
70
|
+
throw new WorktreeAuthFileInvalidError('worktree-auth.json: shape does not match AuthorizationFile', { path });
|
|
71
|
+
}
|
|
72
|
+
if (parsed.sessionId !== sessionId) {
|
|
73
|
+
throw new WorktreeAuthFileInvalidError(`worktree-auth.json: sessionId mismatch (file=${parsed.sessionId}, caller=${sessionId})`, { path });
|
|
74
|
+
}
|
|
75
|
+
return parsed;
|
|
76
|
+
}
|
|
77
|
+
export class WorktreeAuthFileInvalidError extends Error {
|
|
78
|
+
path;
|
|
79
|
+
constructor(message, opts) {
|
|
80
|
+
super(message);
|
|
81
|
+
this.name = 'WorktreeAuthFileInvalidError';
|
|
82
|
+
this.path = opts.path;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function isAuthorizationFile(value) {
|
|
86
|
+
if (value === null || typeof value !== 'object')
|
|
87
|
+
return false;
|
|
88
|
+
const v = value;
|
|
89
|
+
if (v.schemaVersion !== 1)
|
|
90
|
+
return false;
|
|
91
|
+
if (typeof v.sessionId !== 'string')
|
|
92
|
+
return false;
|
|
93
|
+
if (typeof v.createdAt !== 'string')
|
|
94
|
+
return false;
|
|
95
|
+
if (!Array.isArray(v.grants))
|
|
96
|
+
return false;
|
|
97
|
+
return v.grants.every(isWorktreeAuthorization);
|
|
98
|
+
}
|
|
99
|
+
function isWorktreeAuthorization(value) {
|
|
100
|
+
if (value === null || typeof value !== 'object')
|
|
101
|
+
return false;
|
|
102
|
+
const g = value;
|
|
103
|
+
if (typeof g.operation !== 'string')
|
|
104
|
+
return false;
|
|
105
|
+
if (!isOperationType(g.operation))
|
|
106
|
+
return false;
|
|
107
|
+
if (typeof g.reason !== 'string')
|
|
108
|
+
return false;
|
|
109
|
+
if (g.promptHash !== null && typeof g.promptHash !== 'string')
|
|
110
|
+
return false;
|
|
111
|
+
if (g.requestId !== null && typeof g.requestId !== 'string')
|
|
112
|
+
return false;
|
|
113
|
+
if (typeof g.issuedAt !== 'string')
|
|
114
|
+
return false;
|
|
115
|
+
if (typeof g.expiresAt !== 'string')
|
|
116
|
+
return false;
|
|
117
|
+
if (typeof g.consume !== 'boolean')
|
|
118
|
+
return false;
|
|
119
|
+
if (typeof g.consumed !== 'boolean')
|
|
120
|
+
return false;
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
function isOperationType(value) {
|
|
124
|
+
return (value === 'git-worktree' ||
|
|
125
|
+
value === 'agent-isolation-worktree' ||
|
|
126
|
+
value === 'git-stash-mutating' ||
|
|
127
|
+
value === 'git-worktree-other');
|
|
128
|
+
}
|
|
129
|
+
/** The narrow set of worktree-mutating `git` commands the gate actually blocks. Tightly scoped on purpose. */
|
|
130
|
+
const GIT_WORKTREE_REGEX = /^\s*git\s+worktree(?:\s+(add|remove|prune|lock|unlock|move|repair))?\b/;
|
|
131
|
+
const GIT_STASH_MUTATING_REGEX = /^\s*git\s+stash(?:\s+(push|pop|save|create|drop|store|clear|apply))(?:\s+|$)/;
|
|
132
|
+
/**
|
|
133
|
+
* Map the actual tool call to an `OperationType` the gate should look up. Returns `null` for tool calls
|
|
134
|
+
* the gate does not care about (e.g. `Read`, `Glob`, or `Bash` running `ls`). The regex is deliberately
|
|
135
|
+
* conservative: anything ambiguous returns `null` (allow).
|
|
136
|
+
*/
|
|
137
|
+
export function classifyToolCall(input) {
|
|
138
|
+
if (input.toolName === 'Agent') {
|
|
139
|
+
return input.isolation === 'worktree' ? 'agent-isolation-worktree' : null;
|
|
140
|
+
}
|
|
141
|
+
if (input.toolName === 'EnterWorktree') {
|
|
142
|
+
// Claude Code's explicit EnterWorktree tool — same authorization as the Agent isolation worktree path.
|
|
143
|
+
return 'agent-isolation-worktree';
|
|
144
|
+
}
|
|
145
|
+
if (input.toolName === 'Workflow') {
|
|
146
|
+
// Future-proofing: if an IDE ever exposes a worktree-creating Workflow tool, route it through the same
|
|
147
|
+
// gate. No Claude-Code tool currently exists, so this is a defensive default.
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
if (input.toolName === 'Bash') {
|
|
151
|
+
if (typeof input.command !== 'string' || input.command.length === 0)
|
|
152
|
+
return null;
|
|
153
|
+
if (GIT_STASH_MUTATING_REGEX.test(input.command))
|
|
154
|
+
return 'git-stash-mutating';
|
|
155
|
+
if (GIT_WORKTREE_REGEX.test(input.command))
|
|
156
|
+
return 'git-worktree';
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Core gate decision. Pure: takes a `WorktreeAuthCheckInput` + the parsed `AuthorizationFile`,
|
|
163
|
+
* returns `WorktreeAuthDecision`. Side effects (consume / file rewrite) are NOT performed here — see
|
|
164
|
+
* `evaluateWorktreeAuth` for the write-then-evaluate pattern that `peaks gate enforce` uses.
|
|
165
|
+
*/
|
|
166
|
+
export function decideFromAuthorization(input, operation, file) {
|
|
167
|
+
if (file === null) {
|
|
168
|
+
return {
|
|
169
|
+
allow: false,
|
|
170
|
+
code: 'WORKTREE_USER_AUTH_REQUIRED',
|
|
171
|
+
reason: `No current-task user authorization for "${operation}" (session=${input.sessionId}).`,
|
|
172
|
+
remediation: `Ask the user to explicitly authorize this worktree-mutating operation, then run \`peaks worktree auth grant --operation ${operation} --reason "<why>"\` ` +
|
|
173
|
+
`before the tool call retries. Re-running with --consume=false and a longer --ttl is allowed but should be rare.`
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
const now = Date.now();
|
|
177
|
+
// First try to find a requestId-matched, non-consumed, unexpired grant. If none is found,
|
|
178
|
+
// we drop the requestId filter and look again — that gives us a clean two-tier distinction
|
|
179
|
+
// between "this rid is scoped to a different rid" and "all grants are stale/expired".
|
|
180
|
+
const requestMatched = file.grants
|
|
181
|
+
.filter((g) => g.operation === operation)
|
|
182
|
+
.filter((g) => !g.consumed)
|
|
183
|
+
.filter((g) => Date.parse(g.expiresAt) > now)
|
|
184
|
+
.find((g) => g.requestId === null || g.requestId === input.requestId);
|
|
185
|
+
if (requestMatched !== undefined) {
|
|
186
|
+
return { allow: true, authorization: requestMatched, remaining: file.grants.length, viaLease: null };
|
|
187
|
+
}
|
|
188
|
+
// No live grant matched the current rid (or the caller's rid is null). Diagnose why.
|
|
189
|
+
const sameOpAnyState = file.grants.filter((g) => g.operation === operation);
|
|
190
|
+
if (sameOpAnyState.length === 0) {
|
|
191
|
+
return {
|
|
192
|
+
allow: false,
|
|
193
|
+
code: 'WORKTREE_USER_AUTH_REQUIRED',
|
|
194
|
+
reason: `No grant for operation "${operation}" in this session.`,
|
|
195
|
+
remediation: `Run \`peaks worktree auth grant --operation ${operation} --reason "<why>"\` from the LLM after the user has explicitly asked for the operation.`
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
const ridScoped = sameOpAnyState.find((g) => g.requestId !== null);
|
|
199
|
+
const ridMatchesScope = ridScoped !== undefined && (input.requestId === null || ridScoped.requestId === input.requestId);
|
|
200
|
+
if (ridScoped !== undefined && !ridMatchesScope) {
|
|
201
|
+
return {
|
|
202
|
+
allow: false,
|
|
203
|
+
code: 'WORKTREE_USER_AUTH_REQUEST_MISMATCH',
|
|
204
|
+
reason: `Grant for "${operation}" is scoped to requestId=${ridScoped.requestId} but the current tool call carries requestId=${input.requestId ?? 'null'}.`,
|
|
205
|
+
remediation: `Either drop the requestId scope from the grant (\`peaks worktree auth grant --operation ${operation} --no-request-id\`) or operate under the scoped request.`
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
// Otherwise: every grant for the operation is either consumed or expired.
|
|
209
|
+
const hasUnexpired = sameOpAnyState.some((g) => Date.parse(g.expiresAt) > now);
|
|
210
|
+
if (!hasUnexpired) {
|
|
211
|
+
return {
|
|
212
|
+
allow: false,
|
|
213
|
+
code: 'WORKTREE_USER_AUTH_EXPIRED',
|
|
214
|
+
reason: `All grants for operation "${operation}" in this session have expired.`,
|
|
215
|
+
remediation: `Re-run \`peaks worktree auth grant --operation ${operation} --reason "<why>"\` (default TTL 5 min) before the tool call retries.`
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
// Grants exist and at least one is unexpired, but every non-expired one is consumed.
|
|
219
|
+
return {
|
|
220
|
+
allow: false,
|
|
221
|
+
code: 'WORKTREE_USER_AUTH_REQUIRED',
|
|
222
|
+
reason: `All unexpired grants for operation "${operation}" in this session are already consumed.`,
|
|
223
|
+
remediation: `Re-run \`peaks worktree auth grant --operation ${operation} --reason "<why>"\` to issue a fresh grant (or pass --multi to make it multi-use).`
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Public entry point used by `peaks gate enforce`. Reads the auth file, decides, and (when consume=true
|
|
228
|
+
* and the call is allowed) atomically rewrites the file with `consumed: true` on the matching grant.
|
|
229
|
+
*
|
|
230
|
+
* Returns `deny` on any internal error: malformed file, IO failure, missing session binding, etc. The
|
|
231
|
+
* gate is fail-closed — never allow on error.
|
|
232
|
+
*/
|
|
233
|
+
export function evaluateWorktreeAuth(input) {
|
|
234
|
+
const operation = classifyToolCall(input);
|
|
235
|
+
if (operation === null) {
|
|
236
|
+
// Pass-through (Read, Glob, etc., and any Bash that isn't worktree-mutating).
|
|
237
|
+
return {
|
|
238
|
+
allow: true,
|
|
239
|
+
authorization: syntheticAllow(),
|
|
240
|
+
remaining: 0,
|
|
241
|
+
viaLease: null
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
let file;
|
|
245
|
+
try {
|
|
246
|
+
file = readAuthorization(input.projectRoot, input.sessionId);
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
if (error instanceof WorktreeAuthFileInvalidError) {
|
|
250
|
+
return {
|
|
251
|
+
allow: false,
|
|
252
|
+
code: 'WORKTREE_USER_AUTH_FILE_INVALID',
|
|
253
|
+
reason: `worktree-auth.json present but invalid: ${error.message}`,
|
|
254
|
+
remediation: `Delete the malformed file (\`rm ${error.path}\`) and re-run \`peaks worktree auth grant --operation ${operation} --reason "<why>"\`. ` +
|
|
255
|
+
`For security, the gate never fails open on a malformed grant file.`
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
return {
|
|
259
|
+
allow: false,
|
|
260
|
+
code: 'WORKTREE_USER_AUTH_FILE_INVALID',
|
|
261
|
+
reason: `worktree-auth.json IO error: ${error.message}`,
|
|
262
|
+
remediation: `Re-run \`peaks worktree auth grant --operation ${operation} --reason "<why>"\` and retry.`
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
const decision = decideFromAuthorization(input, operation, file);
|
|
266
|
+
if (decision.allow) {
|
|
267
|
+
if (decision.authorization !== null && decision.authorization.consume) {
|
|
268
|
+
try {
|
|
269
|
+
markConsumed(input.projectRoot, input.sessionId, decision.authorization);
|
|
270
|
+
}
|
|
271
|
+
catch (error) {
|
|
272
|
+
// Best-effort: the gate already issued an allow. We do NOT revoke; the next call will see the
|
|
273
|
+
// un-consumed grant and try again. This is preferable to denying a legitimate operation because
|
|
274
|
+
// of a write failure.
|
|
275
|
+
return {
|
|
276
|
+
allow: true,
|
|
277
|
+
authorization: decision.authorization,
|
|
278
|
+
remaining: 0,
|
|
279
|
+
viaLease: null
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return decision;
|
|
284
|
+
}
|
|
285
|
+
// Auth denied — try the lease fallback. The lease is a SECOND authorization path that sub-agents
|
|
286
|
+
// that have adopted the spawn/release CLI (Part 1 + 2.A) use; sub-agents that still rely on
|
|
287
|
+
// `peaks worktree auth grant` are unaffected (their grants already allowed above).
|
|
288
|
+
if (input.leaseId === null || input.leaseId === undefined || input.leaseId.length === 0) {
|
|
289
|
+
// Part 19: try the container lease fallback before giving up.
|
|
290
|
+
if (input.containerLeaseId !== null && input.containerLeaseId !== undefined && input.containerLeaseId.length > 0) {
|
|
291
|
+
return decideFromContainerLease(input);
|
|
292
|
+
}
|
|
293
|
+
return decision;
|
|
294
|
+
}
|
|
295
|
+
const leaseResult = decideFromLease(input);
|
|
296
|
+
if (leaseResult.allow)
|
|
297
|
+
return leaseResult;
|
|
298
|
+
// Part 19: if the worktree lease did not allow, try the container
|
|
299
|
+
// lease as a second lease path (sub-agents with container
|
|
300
|
+
// isolation).
|
|
301
|
+
if (input.containerLeaseId !== null && input.containerLeaseId !== undefined && input.containerLeaseId.length > 0) {
|
|
302
|
+
return decideFromContainerLease(input);
|
|
303
|
+
}
|
|
304
|
+
return leaseResult;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Part 19: L4 container lease fallback. Reads the container
|
|
308
|
+
* lease file at `.peaks/_runtime/<sid>/container-leases/<id>.json`
|
|
309
|
+
* and permits the operation iff the lease is `isContainerLeaseActive`
|
|
310
|
+
* and its `rid` matches the current peaks request. Mirrors
|
|
311
|
+
* `decideFromLease` for the L4 container surface; the L2 worktree
|
|
312
|
+
* lease is the L2 path, this is the L4 path.
|
|
313
|
+
*
|
|
314
|
+
* On malformed file / non-active / rid mismatch the function
|
|
315
|
+
* fails closed with the new error codes
|
|
316
|
+
* (CONTAINER_LEASE_FILE_INVALID / NOT_ACTIVE / REQUEST_MISMATCH).
|
|
317
|
+
*/
|
|
318
|
+
export function decideFromContainerLease(input) {
|
|
319
|
+
const containerLeaseId = input.containerLeaseId ?? '';
|
|
320
|
+
const file = containerLeaseFilePath(`${input.projectRoot}/.peaks/_runtime/${input.sessionId}`, containerLeaseId);
|
|
321
|
+
if (!existsSync(file)) {
|
|
322
|
+
return {
|
|
323
|
+
allow: false,
|
|
324
|
+
code: 'CONTAINER_LEASE_FILE_INVALID',
|
|
325
|
+
reason: `No container lease at ${file} (leaseId=${containerLeaseId}).`,
|
|
326
|
+
remediation: `Run \`peaks container spawn --rid <rid> --role <role> --purpose "<why>"\` to create the lease, then re-run. The PEAKS_CONTAINER_LEASE_ID env is the source of truth (dispatch injects it).`
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
let lease;
|
|
330
|
+
try {
|
|
331
|
+
lease = deserializeContainerLease(readFileSync(file, 'utf8'));
|
|
332
|
+
}
|
|
333
|
+
catch (err) {
|
|
334
|
+
return {
|
|
335
|
+
allow: false,
|
|
336
|
+
code: 'CONTAINER_LEASE_FILE_INVALID',
|
|
337
|
+
reason: `Container lease at ${file} is unreadable / malformed: ${err.message}`,
|
|
338
|
+
remediation: `Delete the malformed lease file (\`rm ${file}\`) and re-spawn. The gate never fails open on a malformed lease.`
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
if (input.requestId !== null && lease.rid !== input.requestId) {
|
|
342
|
+
return {
|
|
343
|
+
allow: false,
|
|
344
|
+
code: 'CONTAINER_LEASE_REQUEST_MISMATCH',
|
|
345
|
+
reason: `Container lease rid=${lease.rid} does not match current requestId=${input.requestId}.`,
|
|
346
|
+
remediation: `Either re-spawn a container lease for the current rid, or operate under the lease's own rid.`
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
if (!isContainerLeaseActive(lease)) {
|
|
350
|
+
return {
|
|
351
|
+
allow: false,
|
|
352
|
+
code: 'CONTAINER_LEASE_NOT_ACTIVE',
|
|
353
|
+
reason: `Container lease ${lease.leaseId} is not active (status=${lease.status}, remainingMs=${lease.expiresAt - Date.now()}).`,
|
|
354
|
+
remediation: `Run \`peaks container release --lease-id ${lease.leaseId}\` to clean up, then \`peaks container spawn ...\` to create a new lease.`
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
return { allow: true, authorization: null, remaining: 0, viaLease: lease };
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Pure: consult the lease file referenced by `input.leaseId` and decide
|
|
361
|
+
* whether the operation may proceed under the lease. Mirrors the
|
|
362
|
+
* `decideFromAuthorization` contract: malformed lease → fail-closed;
|
|
363
|
+
* rid mismatch → deny; non-active lease → deny.
|
|
364
|
+
*/
|
|
365
|
+
export function decideFromLease(input) {
|
|
366
|
+
const leaseId = input.leaseId ?? '';
|
|
367
|
+
// `leaseFilePath` expects the per-session runtime dir as its first
|
|
368
|
+
// argument, NOT the project root. Compose the same path the spawn
|
|
369
|
+
// CLI writes to (`<projectRoot>/.peaks/_runtime/<sid>`).
|
|
370
|
+
const runtimeDir = `${input.projectRoot.replace(/[\\/]+$/, '')}/.peaks/_runtime/${input.sessionId}`;
|
|
371
|
+
const file = leaseFilePath(runtimeDir, leaseId);
|
|
372
|
+
if (!existsSync(file)) {
|
|
373
|
+
return {
|
|
374
|
+
allow: false,
|
|
375
|
+
code: 'WORKTREE_USER_AUTH_REQUIRED',
|
|
376
|
+
reason: `No worktree auth grant AND no lease at ${file} (leaseId=${leaseId}).`,
|
|
377
|
+
remediation: `Either run \`peaks worktree auth grant --operation <op> --reason "<why>"\` or ` +
|
|
378
|
+
`run \`peaks worktree spawn --rid <rid> --role <role> --purpose "<why>"\` to create the lease.`
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
let lease;
|
|
382
|
+
try {
|
|
383
|
+
lease = deserializeLease(readFileSync(file, 'utf8'));
|
|
384
|
+
}
|
|
385
|
+
catch (error) {
|
|
386
|
+
return {
|
|
387
|
+
allow: false,
|
|
388
|
+
code: 'WORKTREE_LEASE_FILE_INVALID',
|
|
389
|
+
reason: `Lease file at ${file} is unreadable/malformed: ${error.message}`,
|
|
390
|
+
remediation: `Delete the malformed lease (\`rm ${file}\`) and re-spawn. The gate never fails open on a malformed lease.`
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
if (input.requestId !== null && lease.rid !== input.requestId) {
|
|
394
|
+
return {
|
|
395
|
+
allow: false,
|
|
396
|
+
code: 'WORKTREE_LEASE_REQUEST_MISMATCH',
|
|
397
|
+
reason: `Lease rid=${lease.rid} does not match current requestId=${input.requestId}.`,
|
|
398
|
+
remediation: `Either re-spawn a lease for the current rid, or operate under the lease's own rid.`
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
if (!isLeaseActive(lease)) {
|
|
402
|
+
return {
|
|
403
|
+
allow: false,
|
|
404
|
+
code: 'WORKTREE_LEASE_NOT_ACTIVE',
|
|
405
|
+
reason: `Lease ${lease.leaseId} is not active (status=${lease.status}, remainingMs=${lease.expiresAt - Date.now()}).`,
|
|
406
|
+
remediation: `Run \`peaks worktree renew --lease-id ${lease.leaseId}\` to extend, or \`peaks worktree spawn ...\` to create a new lease.`
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
return { allow: true, authorization: null, remaining: 0, viaLease: lease };
|
|
410
|
+
}
|
|
411
|
+
/** Mark a single-use grant as consumed. Writes the whole file back atomically (write to .tmp + rename). */
|
|
412
|
+
function markConsumed(projectRoot, sessionId, consumed) {
|
|
413
|
+
const path = worktreeAuthFilePath(projectRoot, sessionId);
|
|
414
|
+
if (!existsSync(path)) {
|
|
415
|
+
// Race: the file vanished between read and write. Treat as "already consumed" — re-running
|
|
416
|
+
// `peaks worktree auth grant` is the recovery path; we do not write a partial file.
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
const file = readAuthorization(projectRoot, sessionId);
|
|
420
|
+
if (file === null)
|
|
421
|
+
return;
|
|
422
|
+
const next = {
|
|
423
|
+
...file,
|
|
424
|
+
grants: file.grants.map((g) => g === consumed || isSameGrant(g, consumed) ? { ...g, consumed: true } : g)
|
|
425
|
+
};
|
|
426
|
+
writeAuthorizationAtomic(path, next);
|
|
427
|
+
}
|
|
428
|
+
function isSameGrant(a, b) {
|
|
429
|
+
return (a.operation === b.operation &&
|
|
430
|
+
a.issuedAt === b.issuedAt &&
|
|
431
|
+
a.expiresAt === b.expiresAt &&
|
|
432
|
+
a.reason === b.reason);
|
|
433
|
+
}
|
|
434
|
+
function writeAuthorizationAtomic(path, file) {
|
|
435
|
+
const dir = dirname(path);
|
|
436
|
+
if (!existsSync(dir))
|
|
437
|
+
mkdirSync(dir, { recursive: true });
|
|
438
|
+
// The on-disk schema is plain JSON; we keep the same writer used by other peaks artifacts to make
|
|
439
|
+
// diffs and recovery tools work the same way.
|
|
440
|
+
const tmp = `${path}.tmp`;
|
|
441
|
+
writeFileSync(tmp, `${JSON.stringify(file, null, 2)}\n`, 'utf8');
|
|
442
|
+
// fs.renameSync is atomic on POSIX and best-effort on Windows — the same caveat every other peaks
|
|
443
|
+
// artifact writer has; we accept it for parity.
|
|
444
|
+
renameSync(tmp, path);
|
|
445
|
+
}
|
|
446
|
+
/** A synthetic "allow" decision returned for tool calls the gate does not inspect. Uses a real
|
|
447
|
+
* far-future date (year 9999) so the timestamp serializes safely. */
|
|
448
|
+
function syntheticAllow() {
|
|
449
|
+
return {
|
|
450
|
+
operation: 'git-worktree',
|
|
451
|
+
reason: 'passthrough',
|
|
452
|
+
promptHash: null,
|
|
453
|
+
requestId: null,
|
|
454
|
+
issuedAt: '1970-01-01T00:00:00.000Z',
|
|
455
|
+
expiresAt: '9999-12-31T23:59:59.999Z',
|
|
456
|
+
consume: false,
|
|
457
|
+
consumed: true
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
/** CLI writer used by `peaks worktree auth grant`. Replaces (does not merge) the grant list — pass
|
|
461
|
+
* the existing grants through if you want a multi-grant file. */
|
|
462
|
+
export function writeAuthorization(projectRoot, sessionId, authorization) {
|
|
463
|
+
const existing = readAuthorization(projectRoot, sessionId);
|
|
464
|
+
const next = {
|
|
465
|
+
schemaVersion: 1,
|
|
466
|
+
sessionId,
|
|
467
|
+
createdAt: existing?.createdAt ?? new Date().toISOString(),
|
|
468
|
+
grants: [...(existing?.grants ?? []), authorization]
|
|
469
|
+
};
|
|
470
|
+
const path = worktreeAuthFilePath(projectRoot, sessionId);
|
|
471
|
+
writeAuthorizationAtomic(path, next);
|
|
472
|
+
}
|
|
473
|
+
/** Revoke (delete) every unconsumed grant in the file. Used by `peaks worktree auth revoke`. */
|
|
474
|
+
export function clearAllGrants(projectRoot, sessionId) {
|
|
475
|
+
const file = readAuthorization(projectRoot, sessionId);
|
|
476
|
+
if (file === null)
|
|
477
|
+
return { removed: 0 };
|
|
478
|
+
const remaining = file.grants.filter((g) => g.consumed);
|
|
479
|
+
const removed = file.grants.length - remaining.length;
|
|
480
|
+
if (remaining.length === 0) {
|
|
481
|
+
const path = worktreeAuthFilePath(projectRoot, sessionId);
|
|
482
|
+
if (existsSync(path)) {
|
|
483
|
+
unlinkSync(path);
|
|
484
|
+
}
|
|
485
|
+
return { removed };
|
|
486
|
+
}
|
|
487
|
+
writeAuthorizationAtomic(worktreeAuthFilePath(projectRoot, sessionId), {
|
|
488
|
+
...file,
|
|
489
|
+
grants: remaining
|
|
490
|
+
});
|
|
491
|
+
return { removed };
|
|
492
|
+
}
|
|
@@ -60,7 +60,7 @@ export const CLAUDE_CODE_ADAPTER = {
|
|
|
60
60
|
// Pathway = 'ide-native' (not 'shell-exec') so the dispatcher
|
|
61
61
|
// routes main-session compacts through the PreToolUse hook in
|
|
62
62
|
// `.claude/settings.local.json`. The hook fires
|
|
63
|
-
// `peaks
|
|
63
|
+
// `peaks compact auto` on the NEXT Bash/Task tool
|
|
64
64
|
// call from the runner, which in-band spawns `claude --compact`
|
|
65
65
|
// against the CURRENT runner — not a child process (the
|
|
66
66
|
// shell-exec spawn-new-claude bug documented in
|
|
@@ -71,7 +71,7 @@ export const CLAUDE_CODE_ADAPTER = {
|
|
|
71
71
|
envVarForContextPercent: 'CLAUDE_CONTEXT_USAGE_PERCENT',
|
|
72
72
|
compactCommand: 'claude --compact',
|
|
73
73
|
compactPathway: 'ide-native',
|
|
74
|
-
postCompactDetectCommand: 'peaks
|
|
74
|
+
postCompactDetectCommand: 'peaks compact auto --json'
|
|
75
75
|
},
|
|
76
76
|
// Slice #011: standards profile. Claude Code reads its constitution at
|
|
77
77
|
// CLAUDE.md + module-level rules under .claude/rules/**. The values mirror
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Qoder IDE adapter (slice 2026-07-25-qoder-adapter-ship) — peaks-loop
|
|
3
|
+
* 第八个内置 IDE 适配器(填表)。
|
|
4
|
+
*
|
|
5
|
+
* 不可消除的 per-IDE 字段(本 slice 填表;字段值暂为占位):
|
|
6
|
+
* - settings.dirName = '.qoder' : Qoder 项目根下的配置目录(UNVERIFIED)
|
|
7
|
+
* - settings.settingsFileName = 'settings.json'(UNVERIFIED)
|
|
8
|
+
* - envVar = 'QODER_PROJECT_DIR' : Qoder 注入的 env 变量(UNVERIFIED)
|
|
9
|
+
* - hookEvent = 'PreToolUse' : 现代 IDE 通用约定(UNVERIFIED — 待真实 Qoder 安装验证)
|
|
10
|
+
* - toolMatcher = 'Bash' : 同上(UNVERIFIED)
|
|
11
|
+
*
|
|
12
|
+
* Slice 2026-07-25-qoder-adapter-ship 状态:
|
|
13
|
+
* - Slim adapter shape 跟 hermes-adapter.ts / claude-code-adapter.ts 同型,
|
|
14
|
+
* 验证 slice #1 抽出的形状在第 8 个 IDE 上仍然可以"填表"接入。
|
|
15
|
+
* - 5 fields (dirName / settingsFileName / envVar / hookEvent / toolMatcher)
|
|
16
|
+
* 均为占位值并标记 UNVERIFIED;待真实 Qoder 安装可用后再走 VERIFIED 路径
|
|
17
|
+
* (见 PRD §3 step 5 + 多 IDE 治理政策
|
|
18
|
+
* .peaks/memory/2026-07-24-multi-ide-adapter-policy.md)。
|
|
19
|
+
* - 见 [[2026-07-24-multi-ide-adapter-policy]] 了解 UNVERIFIED → VERIFIED
|
|
20
|
+
* 的迁移路径与 7-step checklist。
|
|
21
|
+
* - 本 slice 不修改 src/services/ide/ide-types.ts(IdeId union 已经在
|
|
22
|
+
* line 21 包含 'qoder'),不修改既有 adapter 文件,不修改既有测试。
|
|
23
|
+
*/
|
|
24
|
+
import type { IdeAdapter } from '../ide-types.js';
|
|
25
|
+
export declare const QODER_ADAPTER: IdeAdapter;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Qoder IDE adapter (slice 2026-07-25-qoder-adapter-ship) — peaks-loop
|
|
3
|
+
* 第八个内置 IDE 适配器(填表)。
|
|
4
|
+
*
|
|
5
|
+
* 不可消除的 per-IDE 字段(本 slice 填表;字段值暂为占位):
|
|
6
|
+
* - settings.dirName = '.qoder' : Qoder 项目根下的配置目录(UNVERIFIED)
|
|
7
|
+
* - settings.settingsFileName = 'settings.json'(UNVERIFIED)
|
|
8
|
+
* - envVar = 'QODER_PROJECT_DIR' : Qoder 注入的 env 变量(UNVERIFIED)
|
|
9
|
+
* - hookEvent = 'PreToolUse' : 现代 IDE 通用约定(UNVERIFIED — 待真实 Qoder 安装验证)
|
|
10
|
+
* - toolMatcher = 'Bash' : 同上(UNVERIFIED)
|
|
11
|
+
*
|
|
12
|
+
* Slice 2026-07-25-qoder-adapter-ship 状态:
|
|
13
|
+
* - Slim adapter shape 跟 hermes-adapter.ts / claude-code-adapter.ts 同型,
|
|
14
|
+
* 验证 slice #1 抽出的形状在第 8 个 IDE 上仍然可以"填表"接入。
|
|
15
|
+
* - 5 fields (dirName / settingsFileName / envVar / hookEvent / toolMatcher)
|
|
16
|
+
* 均为占位值并标记 UNVERIFIED;待真实 Qoder 安装可用后再走 VERIFIED 路径
|
|
17
|
+
* (见 PRD §3 step 5 + 多 IDE 治理政策
|
|
18
|
+
* .peaks/memory/2026-07-24-multi-ide-adapter-policy.md)。
|
|
19
|
+
* - 见 [[2026-07-24-multi-ide-adapter-policy]] 了解 UNVERIFIED → VERIFIED
|
|
20
|
+
* 的迁移路径与 7-step checklist。
|
|
21
|
+
* - 本 slice 不修改 src/services/ide/ide-types.ts(IdeId union 已经在
|
|
22
|
+
* line 21 包含 'qoder'),不修改既有 adapter 文件,不修改既有测试。
|
|
23
|
+
*/
|
|
24
|
+
import { homedir } from 'node:os';
|
|
25
|
+
import { join, resolve } from 'node:path';
|
|
26
|
+
import { traeSubAgentDispatcher } from '../../dispatch/sub-agent-dispatcher.js';
|
|
27
|
+
export const QODER_ADAPTER = {
|
|
28
|
+
id: 'qoder',
|
|
29
|
+
displayName: 'Qoder',
|
|
30
|
+
settings: {
|
|
31
|
+
dirName: '.qoder', // UNVERIFIED — placeholder; pending real Qoder 1.x fixture
|
|
32
|
+
settingsFileName: 'settings.json', // UNVERIFIED — placeholder
|
|
33
|
+
resolveSettingsFile: (scope, projectRoot) => {
|
|
34
|
+
const root = scope === 'global' ? homedir() : resolve(projectRoot ?? homedir());
|
|
35
|
+
return join(root, '.qoder', 'settings.json');
|
|
36
|
+
},
|
|
37
|
+
supportsScope: (scope) => scope === 'project' || scope === 'global'
|
|
38
|
+
},
|
|
39
|
+
envVar: 'QODER_PROJECT_DIR', // UNVERIFIED
|
|
40
|
+
hookEvent: 'PreToolUse', // UNVERIFIED
|
|
41
|
+
toolMatcher: 'Bash', // UNVERIFIED
|
|
42
|
+
// Slice 2026-07-25-qoder-adapter-ship: Qoder sub-agent dispatcher UNVERIFIED —
|
|
43
|
+
// pending real Qoder dogfood. Reusing the Trae dispatcher as a uniform
|
|
44
|
+
// placeholder (same rationale as hermes-adapter.ts: byte-stable shape
|
|
45
|
+
// across placeholder adapters).
|
|
46
|
+
subAgentDispatcher: traeSubAgentDispatcher,
|
|
47
|
+
// Slice 2026-07-25-qoder-adapter-ship: Qoder PreToolUse is the assumed hook
|
|
48
|
+
// path. UNVERIFIED — will be re-evaluated against a real Qoder install.
|
|
49
|
+
promptSizeAware: true,
|
|
50
|
+
installHints: [
|
|
51
|
+
'Restart Qoder (or reload the workspace) so the PreToolUse hooks take effect.'
|
|
52
|
+
],
|
|
53
|
+
capabilities: {
|
|
54
|
+
gateEnforce: true,
|
|
55
|
+
statusline: true
|
|
56
|
+
}
|
|
57
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tongyi Lingma IDE adapter (slice 2026-07-25-tongyi-lingma-adapter-ship) —
|
|
3
|
+
* peaks-loop 第九个内置 IDE 适配器(填表)。
|
|
4
|
+
*
|
|
5
|
+
* 不可消除的 per-IDE 字段(本 slice 填表;字段值暂为占位):
|
|
6
|
+
* - settings.dirName = '.lingma' (UNVERIFIED)
|
|
7
|
+
* - settings.settingsFileName = 'settings.json' (UNVERIFIED)
|
|
8
|
+
* - envVar = 'TONGYI_LINGMA_PROJECT_DIR' (UNVERIFIED)
|
|
9
|
+
* - hookEvent = 'PreToolUse' (UNVERIFIED)
|
|
10
|
+
* - toolMatcher = 'Bash' (UNVERIFIED)
|
|
11
|
+
*
|
|
12
|
+
* 这些字段在真实 Tongyi Lingma 安装 dogfood 完成前不得标记 VERIFIED。
|
|
13
|
+
* 见 [[2026-07-24-multi-ide-adapter-policy]] §3 step 5。
|
|
14
|
+
*/
|
|
15
|
+
import type { IdeAdapter } from '../ide-types.js';
|
|
16
|
+
export declare const TONGYI_LINGMA_ADAPTER: IdeAdapter;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tongyi Lingma IDE adapter (slice 2026-07-25-tongyi-lingma-adapter-ship) —
|
|
3
|
+
* peaks-loop 第九个内置 IDE 适配器(填表)。
|
|
4
|
+
*
|
|
5
|
+
* 不可消除的 per-IDE 字段(本 slice 填表;字段值暂为占位):
|
|
6
|
+
* - settings.dirName = '.lingma' (UNVERIFIED)
|
|
7
|
+
* - settings.settingsFileName = 'settings.json' (UNVERIFIED)
|
|
8
|
+
* - envVar = 'TONGYI_LINGMA_PROJECT_DIR' (UNVERIFIED)
|
|
9
|
+
* - hookEvent = 'PreToolUse' (UNVERIFIED)
|
|
10
|
+
* - toolMatcher = 'Bash' (UNVERIFIED)
|
|
11
|
+
*
|
|
12
|
+
* 这些字段在真实 Tongyi Lingma 安装 dogfood 完成前不得标记 VERIFIED。
|
|
13
|
+
* 见 [[2026-07-24-multi-ide-adapter-policy]] §3 step 5。
|
|
14
|
+
*/
|
|
15
|
+
import { homedir } from 'node:os';
|
|
16
|
+
import { join, resolve } from 'node:path';
|
|
17
|
+
import { traeSubAgentDispatcher } from '../../dispatch/sub-agent-dispatcher.js';
|
|
18
|
+
export const TONGYI_LINGMA_ADAPTER = {
|
|
19
|
+
id: 'tongyi-lingma',
|
|
20
|
+
displayName: 'Tongyi Lingma',
|
|
21
|
+
settings: {
|
|
22
|
+
dirName: '.lingma', // UNVERIFIED — placeholder; pending real Tongyi Lingma fixture
|
|
23
|
+
settingsFileName: 'settings.json', // UNVERIFIED — placeholder
|
|
24
|
+
resolveSettingsFile: (scope, projectRoot) => {
|
|
25
|
+
const root = scope === 'global' ? homedir() : resolve(projectRoot ?? homedir());
|
|
26
|
+
return join(root, '.lingma', 'settings.json');
|
|
27
|
+
},
|
|
28
|
+
supportsScope: (scope) => scope === 'project' || scope === 'global'
|
|
29
|
+
},
|
|
30
|
+
envVar: 'TONGYI_LINGMA_PROJECT_DIR', // UNVERIFIED
|
|
31
|
+
hookEvent: 'PreToolUse', // UNVERIFIED
|
|
32
|
+
toolMatcher: 'Bash', // UNVERIFIED
|
|
33
|
+
// UNVERIFIED — reuse Trae's dispatcher until real-install dogfood confirms
|
|
34
|
+
// Tongyi Lingma's native sub-agent dispatch surface.
|
|
35
|
+
subAgentDispatcher: traeSubAgentDispatcher,
|
|
36
|
+
// UNVERIFIED — PreToolUse is the assumed hook path.
|
|
37
|
+
promptSizeAware: true,
|
|
38
|
+
installHints: [
|
|
39
|
+
'Restart Tongyi Lingma (or reload the workspace) so the PreToolUse hooks take effect.'
|
|
40
|
+
],
|
|
41
|
+
capabilities: {
|
|
42
|
+
gateEnforce: true,
|
|
43
|
+
statusline: true
|
|
44
|
+
}
|
|
45
|
+
};
|