peaks-loop 4.0.0-beta.9 → 4.0.1
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 +910 -141
- package/README-en.md +26 -7
- package/README.md +75 -6
- 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 +47 -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
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* G7.4 path safety + G8 path safety — R-2 symlink/junction guard for
|
|
3
|
-
* sub-agent artifact + shared channel paths.
|
|
4
|
-
*
|
|
5
|
-
* Slice #009's `assertSafeDispatchRecordPath` covers the dispatch record
|
|
6
|
-
* path. This module covers two adjacent paths under the same canonical
|
|
7
|
-
* root (`.peaks/_sub_agents/<sid>/`):
|
|
8
|
-
*
|
|
9
|
-
* - `artifacts/<rid>-<role>-<idx>.<ext>` (G7 write-artifact)
|
|
10
|
-
* - `shared/<batchId>.json` (G8 share / shared-read)
|
|
11
|
-
*
|
|
12
|
-
* Both reuse the same R-2 logic: reject `..` segments BEFORE the OS
|
|
13
|
-
* resolver collapses them (POSIX normalize silently drops `..`), reject
|
|
14
|
-
* absolute paths that escape the canonical root, resolve symlinks via
|
|
15
|
-
* `realpathSync` and re-check the resolved path.
|
|
16
|
-
*
|
|
17
|
-
* The canonical-root pattern is intentionally identical to the slice #009
|
|
18
|
-
* helper, so future audits can reuse one mental model: "all sub-agent
|
|
19
|
-
* state files must live under `.peaks/_sub_agents/<sid>/` and pass the
|
|
20
|
-
* same R-2 guard."
|
|
21
|
-
*/
|
|
22
|
-
import { realpathSync } from 'node:fs';
|
|
23
|
-
import { dirname, isAbsolute, relative, resolve } from 'node:path';
|
|
24
|
-
const SUB_AGENTS_DIR = '_sub_agents';
|
|
25
|
-
const ARTIFACTS_SUBDIR = 'artifacts';
|
|
26
|
-
const SHARED_SUBDIR = 'shared';
|
|
27
|
-
const ARTIFACT_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*\.[A-Za-z0-9]+$/;
|
|
28
|
-
const BATCH_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
29
|
-
/** Build the canonical artifact path for a given session/rid/role/idx/ext. */
|
|
30
|
-
export function artifactPath(projectRoot, sid, rid, role, idx, ext = 'md') {
|
|
31
|
-
if (typeof role !== 'string' || role.length === 0) {
|
|
32
|
-
throw new Error('artifactPath: role must be non-empty');
|
|
33
|
-
}
|
|
34
|
-
if (!Number.isInteger(idx) || idx < 1) {
|
|
35
|
-
throw new Error(`artifactPath: idx must be positive integer (got ${idx})`);
|
|
36
|
-
}
|
|
37
|
-
const safeSid = sanitizeSegment(sid, 'sessionId');
|
|
38
|
-
const safeRid = sanitizeSegment(rid, 'requestId');
|
|
39
|
-
const safeRole = sanitizeSegment(role, 'role');
|
|
40
|
-
const safeExt = ext.replace(/[^A-Za-z0-9]/g, '');
|
|
41
|
-
if (safeExt.length === 0) {
|
|
42
|
-
throw new Error(`artifactPath: ext must be alphanumeric (got "${ext}")`);
|
|
43
|
-
}
|
|
44
|
-
return resolve(projectRoot, '.peaks', SUB_AGENTS_DIR, safeSid, ARTIFACTS_SUBDIR, `${safeRid}-${safeRole}-${String(idx).padStart(3, '0')}.${safeExt}`);
|
|
45
|
-
}
|
|
46
|
-
/** Build the canonical shared channel path. */
|
|
47
|
-
export function sharedChannelPath(projectRoot, sid, rid, batchId) {
|
|
48
|
-
if (typeof batchId !== 'string' || batchId.length === 0) {
|
|
49
|
-
throw new Error('sharedChannelPath: batchId must be non-empty');
|
|
50
|
-
}
|
|
51
|
-
const safeSid = sanitizeSegment(sid, 'sessionId');
|
|
52
|
-
const safeRid = sanitizeSegment(rid, 'requestId');
|
|
53
|
-
if (!BATCH_ID_PATTERN.test(batchId)) {
|
|
54
|
-
throw new Error(`sharedChannelPath: batchId must match ${BATCH_ID_PATTERN} (got "${batchId}")`);
|
|
55
|
-
}
|
|
56
|
-
return resolve(projectRoot, '.peaks', SUB_AGENTS_DIR, safeSid, SHARED_SUBDIR, `${safeRid}-${batchId}.json`);
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Assert that `artifactPath` lives under
|
|
60
|
-
* `projectRoot/.peaks/_sub_agents/<sid>/artifacts/`. Rejects
|
|
61
|
-
* symlink/junction escapes and `..` segments.
|
|
62
|
-
*
|
|
63
|
-
* Throws an Error with `.code = 'INVALID_ARTIFACT_PATH'` on rejection.
|
|
64
|
-
*/
|
|
65
|
-
export function assertSafeArtifactPath(artifactPathInput, projectRoot) {
|
|
66
|
-
if (!isAbsolute(artifactPathInput)) {
|
|
67
|
-
throw invalidPathError(artifactPathInput, 'must be absolute');
|
|
68
|
-
}
|
|
69
|
-
const rawSegments = artifactPathInput.split(/[\\/]/);
|
|
70
|
-
if (rawSegments.includes('..')) {
|
|
71
|
-
throw invalidPathError(artifactPathInput, 'must not contain .. segments');
|
|
72
|
-
}
|
|
73
|
-
const expected = resolve(projectRoot, '.peaks', SUB_AGENTS_DIR);
|
|
74
|
-
const rel = relative(expected, artifactPathInput);
|
|
75
|
-
if (rel.startsWith('..') || isAbsolute(rel)) {
|
|
76
|
-
throw invalidPathError(artifactPathInput, 'must be under .peaks/_sub_agents/');
|
|
77
|
-
}
|
|
78
|
-
let realArtifact;
|
|
79
|
-
let realRoot;
|
|
80
|
-
try {
|
|
81
|
-
const parent = dirname(artifactPathInput);
|
|
82
|
-
const realParent = realpathSync(parent);
|
|
83
|
-
realArtifact = resolve(realParent, artifactPathInput.slice(parent.length + 1));
|
|
84
|
-
realRoot = realpathSync(projectRoot);
|
|
85
|
-
}
|
|
86
|
-
catch {
|
|
87
|
-
const fallback = resolve(projectRoot, '.peaks', SUB_AGENTS_DIR);
|
|
88
|
-
const rel2 = relative(fallback, artifactPathInput);
|
|
89
|
-
if (rel2.startsWith('..') || isAbsolute(rel2)) {
|
|
90
|
-
throw invalidPathError(artifactPathInput, 'must be under .peaks/_sub_agents/');
|
|
91
|
-
}
|
|
92
|
-
return artifactPathInput;
|
|
93
|
-
}
|
|
94
|
-
const realRel = relative(realRoot, realArtifact);
|
|
95
|
-
if (realRel.startsWith('..') || isAbsolute(realRel)) {
|
|
96
|
-
throw invalidPathError(artifactPathInput, 'symlink/junction escapes project root');
|
|
97
|
-
}
|
|
98
|
-
const realExpected = resolve(realRoot, '.peaks', SUB_AGENTS_DIR);
|
|
99
|
-
const realRelExpected = relative(realExpected, realArtifact);
|
|
100
|
-
if (realRelExpected.startsWith('..') || isAbsolute(realRelExpected)) {
|
|
101
|
-
throw invalidPathError(artifactPathInput, 'must be under .peaks/_sub_agents/');
|
|
102
|
-
}
|
|
103
|
-
return realArtifact;
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Assert that `channelPath` lives under
|
|
107
|
-
* `projectRoot/.peaks/_sub_agents/<sid>/shared/`. Same R-2 logic as
|
|
108
|
-
* `assertSafeArtifactPath` but with a different canonical subdir.
|
|
109
|
-
*
|
|
110
|
-
* Throws an Error with `.code = 'INVALID_SHARED_CHANNEL_PATH'` on rejection.
|
|
111
|
-
*/
|
|
112
|
-
export function assertSafeSharedChannelPath(channelPathInput, projectRoot) {
|
|
113
|
-
if (!isAbsolute(channelPathInput)) {
|
|
114
|
-
throw invalidPathErrorShared(channelPathInput, 'must be absolute');
|
|
115
|
-
}
|
|
116
|
-
const rawSegments = channelPathInput.split(/[\\/]/);
|
|
117
|
-
if (rawSegments.includes('..')) {
|
|
118
|
-
throw invalidPathErrorShared(channelPathInput, 'must not contain .. segments');
|
|
119
|
-
}
|
|
120
|
-
const expected = resolve(projectRoot, '.peaks', SUB_AGENTS_DIR);
|
|
121
|
-
const rel = relative(expected, channelPathInput);
|
|
122
|
-
if (rel.startsWith('..') || isAbsolute(rel)) {
|
|
123
|
-
throw invalidPathErrorShared(channelPathInput, 'must be under .peaks/_sub_agents/shared/');
|
|
124
|
-
}
|
|
125
|
-
let realChannel;
|
|
126
|
-
let realRoot;
|
|
127
|
-
try {
|
|
128
|
-
const parent = dirname(channelPathInput);
|
|
129
|
-
const realParent = realpathSync(parent);
|
|
130
|
-
realChannel = resolve(realParent, channelPathInput.slice(parent.length + 1));
|
|
131
|
-
realRoot = realpathSync(projectRoot);
|
|
132
|
-
}
|
|
133
|
-
catch {
|
|
134
|
-
const fallback = resolve(projectRoot, '.peaks', SUB_AGENTS_DIR);
|
|
135
|
-
const rel2 = relative(fallback, channelPathInput);
|
|
136
|
-
if (rel2.startsWith('..') || isAbsolute(rel2)) {
|
|
137
|
-
throw invalidPathErrorShared(channelPathInput, 'must be under .peaks/_sub_agents/shared/');
|
|
138
|
-
}
|
|
139
|
-
return channelPathInput;
|
|
140
|
-
}
|
|
141
|
-
const realRel = relative(realRoot, realChannel);
|
|
142
|
-
if (realRel.startsWith('..') || isAbsolute(realRel)) {
|
|
143
|
-
throw invalidPathErrorShared(channelPathInput, 'symlink/junction escapes project root');
|
|
144
|
-
}
|
|
145
|
-
const realExpected = resolve(realRoot, '.peaks', SUB_AGENTS_DIR);
|
|
146
|
-
const realRelExpected = relative(realExpected, realChannel);
|
|
147
|
-
if (realRelExpected.startsWith('..') || isAbsolute(realRelExpected)) {
|
|
148
|
-
throw invalidPathErrorShared(channelPathInput, 'must be under .peaks/_sub_agents/shared/');
|
|
149
|
-
}
|
|
150
|
-
return realChannel;
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Soft-warn check on the artifact file name pattern. Returns null if
|
|
154
|
-
* the name matches `<rid>-<role>-<idx>.<ext>`, otherwise returns a
|
|
155
|
-
* warning string. Does NOT reject (the path is still in the canonical
|
|
156
|
-
* dir; the warning is for human/audit readability per G7.4.c).
|
|
157
|
-
*/
|
|
158
|
-
export function checkArtifactNameConvention(artifactPathInput) {
|
|
159
|
-
const base = artifactPathInput.split(/[\\/]/).pop() ?? '';
|
|
160
|
-
if (ARTIFACT_NAME_PATTERN.test(base)) {
|
|
161
|
-
return null;
|
|
162
|
-
}
|
|
163
|
-
return `Artifact file name does not match <rid>-<role>-<idx>.<ext> convention: ${base}`;
|
|
164
|
-
}
|
|
165
|
-
function sanitizeSegment(value, field) {
|
|
166
|
-
if (typeof value !== 'string' || value.length === 0) {
|
|
167
|
-
throw new Error(`${field} must be non-empty`);
|
|
168
|
-
}
|
|
169
|
-
if (value.length > 256) {
|
|
170
|
-
throw new Error(`${field} must be ≤ 256 chars (got ${value.length})`);
|
|
171
|
-
}
|
|
172
|
-
for (let i = 0; i < value.length; i += 1) {
|
|
173
|
-
const code = value.charCodeAt(i);
|
|
174
|
-
if (code <= 0x20 || code === 0x7F) {
|
|
175
|
-
throw new Error(`${field} must not contain whitespace or control characters`);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
if (value.includes('..') || value.includes('/') || value.includes('\\')) {
|
|
179
|
-
throw new Error(`${field} must not contain '..' or path separators`);
|
|
180
|
-
}
|
|
181
|
-
return value;
|
|
182
|
-
}
|
|
183
|
-
function invalidPathError(path, reason) {
|
|
184
|
-
const e = new Error(`Invalid artifact path: ${reason} (path: ${path})`);
|
|
185
|
-
e.code = 'INVALID_ARTIFACT_PATH';
|
|
186
|
-
return e;
|
|
187
|
-
}
|
|
188
|
-
function invalidPathErrorShared(path, reason) {
|
|
189
|
-
const e = new Error(`Invalid shared channel path: ${reason} (path: ${path})`);
|
|
190
|
-
e.code = 'INVALID_SHARED_CHANNEL_PATH';
|
|
191
|
-
return e;
|
|
192
|
-
}
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
export interface SharedChannelEntry {
|
|
2
|
-
readonly version: 1;
|
|
3
|
-
readonly at: string;
|
|
4
|
-
readonly from: string;
|
|
5
|
-
readonly key: string;
|
|
6
|
-
readonly value: Readonly<Record<string, unknown>>;
|
|
7
|
-
readonly valueSize: number;
|
|
8
|
-
}
|
|
9
|
-
export interface SharedChannel {
|
|
10
|
-
readonly batchId: string;
|
|
11
|
-
readonly createdAt: string;
|
|
12
|
-
readonly updatedAt: string;
|
|
13
|
-
readonly entries: Readonly<Record<string, SharedChannelEntry>>;
|
|
14
|
-
}
|
|
15
|
-
export declare const SHARED_CHANNEL_MAX_VALUE_BYTES: number;
|
|
16
|
-
export declare const SHARED_CHANNEL_SOFT_VALUE_WARN = 1024;
|
|
17
|
-
export declare const SHARED_CHANNEL_MAX_FILE_BYTES: number;
|
|
18
|
-
export declare const SHARED_CHANNEL_TTL_DAYS = 30;
|
|
19
|
-
export type WriteSharedEntryResult = {
|
|
20
|
-
readonly ok: true;
|
|
21
|
-
readonly entry: SharedChannelEntry;
|
|
22
|
-
readonly channelSize: number;
|
|
23
|
-
readonly lastWriteWins: boolean;
|
|
24
|
-
readonly softWarning: boolean;
|
|
25
|
-
} | {
|
|
26
|
-
readonly ok: false;
|
|
27
|
-
readonly code: 'VALUE_TOO_LARGE' | 'INVALID_BATCH_ID' | 'WRITE_ERROR';
|
|
28
|
-
readonly message: string;
|
|
29
|
-
};
|
|
30
|
-
/**
|
|
31
|
-
* Write a shared entry to the per-batch channel file. Atomic-write
|
|
32
|
-
* (tmp + rename). Returns the new entry + channel size + last-write-wins
|
|
33
|
-
* flag (true if the key already existed; the new value overwrites).
|
|
34
|
-
*
|
|
35
|
-
* RL-25 size limit: `value ≥ 64KB` is hard-rejected with `VALUE_TOO_LARGE`.
|
|
36
|
-
* `value > 1KB and < 64KB` is a soft warning (returned in the result).
|
|
37
|
-
*/
|
|
38
|
-
export declare function writeSharedEntry(opts: {
|
|
39
|
-
projectRoot: string;
|
|
40
|
-
sid: string;
|
|
41
|
-
rid: string;
|
|
42
|
-
batchId: string;
|
|
43
|
-
key: string;
|
|
44
|
-
from: string;
|
|
45
|
-
value: Record<string, unknown>;
|
|
46
|
-
}): WriteSharedEntryResult;
|
|
47
|
-
/**
|
|
48
|
-
* Read the shared channel for a batch. Returns the channel with all
|
|
49
|
-
* matching entries. Filters: `--since` (ISO8601) and `--key` (glob
|
|
50
|
-
* pattern; simple `*` wildcard, no regex).
|
|
51
|
-
*
|
|
52
|
-
* If the channel file does not exist, returns an empty channel
|
|
53
|
-
* (this is the dispatcher's "fresh batch" view).
|
|
54
|
-
*/
|
|
55
|
-
export declare function readSharedChannel(opts: {
|
|
56
|
-
projectRoot: string;
|
|
57
|
-
sid: string;
|
|
58
|
-
rid: string;
|
|
59
|
-
batchId: string;
|
|
60
|
-
since?: string;
|
|
61
|
-
keyPattern?: string;
|
|
62
|
-
}): SharedChannel;
|
|
63
|
-
/**
|
|
64
|
-
* Garbage-collect a single channel. Returns true if the file was
|
|
65
|
-
* deleted, false if it did not exist.
|
|
66
|
-
*/
|
|
67
|
-
export declare function gcChannel(opts: {
|
|
68
|
-
projectRoot: string;
|
|
69
|
-
sid: string;
|
|
70
|
-
rid: string;
|
|
71
|
-
batchId: string;
|
|
72
|
-
}): boolean;
|
|
73
|
-
/**
|
|
74
|
-
* Check if a channel file is older than `SHARED_CHANNEL_TTL_DAYS` days
|
|
75
|
-
* and should be GC'd as an orphan. Returns true if file is missing
|
|
76
|
-
* (already GC'd) or older than TTL.
|
|
77
|
-
*/
|
|
78
|
-
export declare function isOrphanChannel(opts: {
|
|
79
|
-
projectRoot: string;
|
|
80
|
-
sid: string;
|
|
81
|
-
rid: string;
|
|
82
|
-
batchId: string;
|
|
83
|
-
now?: Date;
|
|
84
|
-
}): boolean;
|
|
85
|
-
/**
|
|
86
|
-
* Compile a simple key pattern with `*` wildcards to a matcher. Only
|
|
87
|
-
* `*` is special; everything else is a literal. `*` matches zero or
|
|
88
|
-
* more characters. Examples:
|
|
89
|
-
* "rd.*" matches "rd.completed", "rd.found-blocker"
|
|
90
|
-
* "*.completed" matches "rd.completed", "qa.completed"
|
|
91
|
-
* "*" matches everything
|
|
92
|
-
*/
|
|
93
|
-
export declare function compileKeyPattern(pattern: string): (key: string) => boolean;
|
|
@@ -1,308 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* G8 — cross sub-agent shared channel (RL-23..RL-26, AC-47..AC-49).
|
|
3
|
-
*
|
|
4
|
-
* Dispatcher-mediated indirect signal: sub-agent A writes a shared entry,
|
|
5
|
-
* the dispatcher stores it in a per-batch JSON file, sub-agent B (still
|
|
6
|
-
* in flight) reads it. A and B never directly talk. This is the
|
|
7
|
-
* pseudo-swarm property 3 upgrade; it is NOT peer-to-peer messaging.
|
|
8
|
-
*
|
|
9
|
-
* Path convention (G8.3):
|
|
10
|
-
* `.peaks/_sub_agents/<sid>/shared/<rid>-<batchId>.json`
|
|
11
|
-
*
|
|
12
|
-
* The file is atomic-write (tmp + rename). Last-write-wins by key. Value
|
|
13
|
-
* size limit: ≤ 1KB soft warn, ≥ 64KB hard reject. File size cap: 1MB
|
|
14
|
-
* with LRU eviction.
|
|
15
|
-
*
|
|
16
|
-
* See: `.peaks/memory/sub-agent-shared-channel-cross-completion.md` for
|
|
17
|
-
* the full G8 rule.
|
|
18
|
-
*/
|
|
19
|
-
import { existsSync, mkdirSync, readFileSync, renameSync, statSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
20
|
-
import { dirname } from 'node:path';
|
|
21
|
-
import { assertSafeSharedChannelPath, sharedChannelPath } from './dispatch-context-guard.js';
|
|
22
|
-
import { withFileLockSync } from '../filesystem/file-lock.js';
|
|
23
|
-
export const SHARED_CHANNEL_MAX_VALUE_BYTES = 64 * 1024; // 64KB hard reject
|
|
24
|
-
export const SHARED_CHANNEL_SOFT_VALUE_WARN = 1024; // 1KB soft warning
|
|
25
|
-
export const SHARED_CHANNEL_MAX_FILE_BYTES = 1024 * 1024; // 1MB LRU cap
|
|
26
|
-
export const SHARED_CHANNEL_TTL_DAYS = 30; // 30-day TTL on orphan channels
|
|
27
|
-
/**
|
|
28
|
-
* Write a shared entry to the per-batch channel file. Atomic-write
|
|
29
|
-
* (tmp + rename). Returns the new entry + channel size + last-write-wins
|
|
30
|
-
* flag (true if the key already existed; the new value overwrites).
|
|
31
|
-
*
|
|
32
|
-
* RL-25 size limit: `value ≥ 64KB` is hard-rejected with `VALUE_TOO_LARGE`.
|
|
33
|
-
* `value > 1KB and < 64KB` is a soft warning (returned in the result).
|
|
34
|
-
*/
|
|
35
|
-
export function writeSharedEntry(opts) {
|
|
36
|
-
if (typeof opts.key !== 'string' || opts.key.length === 0) {
|
|
37
|
-
return { ok: false, code: 'INVALID_BATCH_ID', message: 'key must be non-empty' };
|
|
38
|
-
}
|
|
39
|
-
if (typeof opts.from !== 'string' || opts.from.length === 0) {
|
|
40
|
-
return { ok: false, code: 'INVALID_BATCH_ID', message: 'from must be non-empty' };
|
|
41
|
-
}
|
|
42
|
-
if (opts.value === null || typeof opts.value !== 'object' || Array.isArray(opts.value)) {
|
|
43
|
-
return {
|
|
44
|
-
ok: false,
|
|
45
|
-
code: 'INVALID_BATCH_ID',
|
|
46
|
-
message: 'value must be a JSON object (not array, not primitive)'
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
const valueSize = Buffer.byteLength(JSON.stringify(opts.value), 'utf8');
|
|
50
|
-
if (valueSize >= SHARED_CHANNEL_MAX_VALUE_BYTES) {
|
|
51
|
-
return {
|
|
52
|
-
ok: false,
|
|
53
|
-
code: 'VALUE_TOO_LARGE',
|
|
54
|
-
message: `value size ${valueSize} bytes exceeds limit ${SHARED_CHANNEL_MAX_VALUE_BYTES} bytes (RL-25)`
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
const softWarning = valueSize > SHARED_CHANNEL_SOFT_VALUE_WARN;
|
|
58
|
-
const channelFile = sharedChannelPath(opts.projectRoot, opts.sid, opts.rid, opts.batchId);
|
|
59
|
-
assertSafeSharedChannelPath(channelFile, opts.projectRoot);
|
|
60
|
-
// Slice 2026-06-23-audit-3rd #2: the read-modify-write sequence below
|
|
61
|
-
// is wrapped in withFileLockSync to prevent lost updates from two
|
|
62
|
-
// concurrent `peaks sub-agent share` calls landing on the same batch.
|
|
63
|
-
// Without the lock, the second writer's read sees a stale channel,
|
|
64
|
-
// and its renameSync silently overwrites the first writer's entry.
|
|
65
|
-
return withFileLockSync(channelFile, () => {
|
|
66
|
-
let channel;
|
|
67
|
-
try {
|
|
68
|
-
channel = readChannelOrEmpty(channelFile, opts.batchId);
|
|
69
|
-
}
|
|
70
|
-
catch (err) {
|
|
71
|
-
return {
|
|
72
|
-
ok: false,
|
|
73
|
-
code: 'WRITE_ERROR',
|
|
74
|
-
message: `failed to read existing channel: ${err.message}`
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
const lastWriteWins = Object.prototype.hasOwnProperty.call(channel.entries, opts.key);
|
|
78
|
-
// LRU eviction: if writing would push the file over the 1MB cap,
|
|
79
|
-
// evict oldest entries until the new write fits.
|
|
80
|
-
const entry = {
|
|
81
|
-
version: 1,
|
|
82
|
-
at: new Date().toISOString(),
|
|
83
|
-
from: opts.from,
|
|
84
|
-
key: opts.key,
|
|
85
|
-
value: Object.freeze({ ...opts.value }),
|
|
86
|
-
valueSize
|
|
87
|
-
};
|
|
88
|
-
const projectedChannel = {
|
|
89
|
-
...channel,
|
|
90
|
-
updatedAt: entry.at,
|
|
91
|
-
entries: { ...channel.entries, [opts.key]: entry }
|
|
92
|
-
};
|
|
93
|
-
const projectedSize = JSON.stringify(projectedChannel).length;
|
|
94
|
-
let lruEvicted = 0;
|
|
95
|
-
if (projectedSize > SHARED_CHANNEL_MAX_FILE_BYTES) {
|
|
96
|
-
const sortedKeys = Object.keys(projectedChannel.entries).sort((a, b) => {
|
|
97
|
-
const ea = projectedChannel.entries[a];
|
|
98
|
-
const eb = projectedChannel.entries[b];
|
|
99
|
-
if (!ea || !eb)
|
|
100
|
-
return 0;
|
|
101
|
-
return ea.at.localeCompare(eb.at);
|
|
102
|
-
});
|
|
103
|
-
let working = projectedChannel;
|
|
104
|
-
while (JSON.stringify(working).length > SHARED_CHANNEL_MAX_FILE_BYTES &&
|
|
105
|
-
sortedKeys.length > 0) {
|
|
106
|
-
const oldestKey = sortedKeys.shift();
|
|
107
|
-
if (oldestKey === opts.key) {
|
|
108
|
-
// Don't evict the entry we just wrote.
|
|
109
|
-
break;
|
|
110
|
-
}
|
|
111
|
-
const nextEntries = {};
|
|
112
|
-
for (const [k, v] of Object.entries(working.entries)) {
|
|
113
|
-
if (k !== oldestKey) {
|
|
114
|
-
nextEntries[k] = v;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
working = { ...working, entries: nextEntries };
|
|
118
|
-
lruEvicted += 1;
|
|
119
|
-
}
|
|
120
|
-
try {
|
|
121
|
-
writeAtomic(channelFile, working);
|
|
122
|
-
}
|
|
123
|
-
catch (err) {
|
|
124
|
-
return {
|
|
125
|
-
ok: false,
|
|
126
|
-
code: 'WRITE_ERROR',
|
|
127
|
-
message: `failed to write channel after LRU eviction: ${err.message}`
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
return {
|
|
131
|
-
ok: true,
|
|
132
|
-
entry,
|
|
133
|
-
channelSize: JSON.stringify(working).length,
|
|
134
|
-
lastWriteWins,
|
|
135
|
-
softWarning
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
try {
|
|
139
|
-
writeAtomic(channelFile, projectedChannel);
|
|
140
|
-
}
|
|
141
|
-
catch (err) {
|
|
142
|
-
return {
|
|
143
|
-
ok: false,
|
|
144
|
-
code: 'WRITE_ERROR',
|
|
145
|
-
message: `failed to write channel: ${err.message}`
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
// lruEvicted is 0 here; expose the count through the size of the
|
|
149
|
-
// returned channel for caller diagnostics.
|
|
150
|
-
void lruEvicted;
|
|
151
|
-
return {
|
|
152
|
-
ok: true,
|
|
153
|
-
entry,
|
|
154
|
-
channelSize: projectedSize,
|
|
155
|
-
lastWriteWins,
|
|
156
|
-
softWarning
|
|
157
|
-
};
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* Read the shared channel for a batch. Returns the channel with all
|
|
162
|
-
* matching entries. Filters: `--since` (ISO8601) and `--key` (glob
|
|
163
|
-
* pattern; simple `*` wildcard, no regex).
|
|
164
|
-
*
|
|
165
|
-
* If the channel file does not exist, returns an empty channel
|
|
166
|
-
* (this is the dispatcher's "fresh batch" view).
|
|
167
|
-
*/
|
|
168
|
-
export function readSharedChannel(opts) {
|
|
169
|
-
const channelFile = sharedChannelPath(opts.projectRoot, opts.sid, opts.rid, opts.batchId);
|
|
170
|
-
assertSafeSharedChannelPath(channelFile, opts.projectRoot);
|
|
171
|
-
const channel = readChannelOrEmpty(channelFile, opts.batchId);
|
|
172
|
-
const since = opts.since;
|
|
173
|
-
const pattern = opts.keyPattern;
|
|
174
|
-
if (!since && !pattern) {
|
|
175
|
-
return channel;
|
|
176
|
-
}
|
|
177
|
-
const filteredEntries = {};
|
|
178
|
-
const matcher = pattern ? compileKeyPattern(pattern) : null;
|
|
179
|
-
for (const [k, v] of Object.entries(channel.entries)) {
|
|
180
|
-
if (since && v.at < since)
|
|
181
|
-
continue;
|
|
182
|
-
if (matcher && !matcher(k))
|
|
183
|
-
continue;
|
|
184
|
-
filteredEntries[k] = v;
|
|
185
|
-
}
|
|
186
|
-
return { ...channel, entries: filteredEntries };
|
|
187
|
-
}
|
|
188
|
-
/**
|
|
189
|
-
* Garbage-collect a single channel. Returns true if the file was
|
|
190
|
-
* deleted, false if it did not exist.
|
|
191
|
-
*/
|
|
192
|
-
export function gcChannel(opts) {
|
|
193
|
-
const channelFile = sharedChannelPath(opts.projectRoot, opts.sid, opts.rid, opts.batchId);
|
|
194
|
-
if (!existsSync(channelFile)) {
|
|
195
|
-
return false;
|
|
196
|
-
}
|
|
197
|
-
// Best-effort delete; R-2 guard not strictly needed (we built the path)
|
|
198
|
-
// but kept for safety.
|
|
199
|
-
assertSafeSharedChannelPath(channelFile, opts.projectRoot);
|
|
200
|
-
try {
|
|
201
|
-
unlinkSync(channelFile);
|
|
202
|
-
return true;
|
|
203
|
-
}
|
|
204
|
-
catch {
|
|
205
|
-
return false;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* Check if a channel file is older than `SHARED_CHANNEL_TTL_DAYS` days
|
|
210
|
-
* and should be GC'd as an orphan. Returns true if file is missing
|
|
211
|
-
* (already GC'd) or older than TTL.
|
|
212
|
-
*/
|
|
213
|
-
export function isOrphanChannel(opts) {
|
|
214
|
-
const channelFile = sharedChannelPath(opts.projectRoot, opts.sid, opts.rid, opts.batchId);
|
|
215
|
-
if (!existsSync(channelFile)) {
|
|
216
|
-
return true;
|
|
217
|
-
}
|
|
218
|
-
const s = statSync(channelFile);
|
|
219
|
-
const now = opts.now ?? new Date();
|
|
220
|
-
const ageMs = now.getTime() - s.mtimeMs;
|
|
221
|
-
const ttlMs = SHARED_CHANNEL_TTL_DAYS * 24 * 60 * 60 * 1000;
|
|
222
|
-
return ageMs > ttlMs;
|
|
223
|
-
}
|
|
224
|
-
// ─── internals ───────────────────────────────────────────────────────
|
|
225
|
-
function readChannelOrEmpty(channelFile, batchId) {
|
|
226
|
-
if (!existsSync(channelFile)) {
|
|
227
|
-
const now = new Date().toISOString();
|
|
228
|
-
return { batchId, createdAt: now, updatedAt: now, entries: {} };
|
|
229
|
-
}
|
|
230
|
-
let parsed;
|
|
231
|
-
try {
|
|
232
|
-
parsed = JSON.parse(readFileSync(channelFile, 'utf8'));
|
|
233
|
-
}
|
|
234
|
-
catch {
|
|
235
|
-
const now = new Date().toISOString();
|
|
236
|
-
return { batchId, createdAt: now, updatedAt: now, entries: {} };
|
|
237
|
-
}
|
|
238
|
-
if (!isObject(parsed)) {
|
|
239
|
-
const now = new Date().toISOString();
|
|
240
|
-
return { batchId, createdAt: now, updatedAt: now, entries: {} };
|
|
241
|
-
}
|
|
242
|
-
const obj = parsed;
|
|
243
|
-
const batchIdField = typeof obj.batchId === 'string' ? obj.batchId : batchId;
|
|
244
|
-
const createdAt = typeof obj.createdAt === 'string' ? obj.createdAt : new Date().toISOString();
|
|
245
|
-
const updatedAt = typeof obj.updatedAt === 'string' ? obj.updatedAt : createdAt;
|
|
246
|
-
const entriesField = isObject(obj.entries) ? obj.entries : {};
|
|
247
|
-
const entries = {};
|
|
248
|
-
for (const [k, v] of Object.entries(entriesField)) {
|
|
249
|
-
if (isValidEntry(v)) {
|
|
250
|
-
entries[k] = v;
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
return { batchId: batchIdField, createdAt, updatedAt, entries };
|
|
254
|
-
}
|
|
255
|
-
function isValidEntry(v) {
|
|
256
|
-
if (!isObject(v))
|
|
257
|
-
return false;
|
|
258
|
-
// Slice 2026-06-23-audit-4th #E2: pre-versioning records (no
|
|
259
|
-
// `version` field) are still accepted on read for backward compat.
|
|
260
|
-
// The writer stamps `version: 1` going forward; readers default
|
|
261
|
-
// missing/legacy entries to version 1 in memory.
|
|
262
|
-
if (!('version' in v) || v.version === 1) {
|
|
263
|
-
return (typeof v.at === 'string' &&
|
|
264
|
-
typeof v.from === 'string' &&
|
|
265
|
-
typeof v.key === 'string' &&
|
|
266
|
-
isObject(v.value) &&
|
|
267
|
-
typeof v.valueSize === 'number');
|
|
268
|
-
}
|
|
269
|
-
// Future versions: read-side handler can branch on `v.version` once
|
|
270
|
-
// v2 lands. For now, anything other than 1 is rejected.
|
|
271
|
-
return false;
|
|
272
|
-
}
|
|
273
|
-
function isObject(v) {
|
|
274
|
-
return typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
275
|
-
}
|
|
276
|
-
function writeAtomic(path, channel) {
|
|
277
|
-
const dir = dirname(path);
|
|
278
|
-
// Slice 2026-06-23-audit-3rd #11: skip mkdirSync when the dir already
|
|
279
|
-
// exists. The `recursive: true` mkdir is a syscall (~50µs on macOS,
|
|
280
|
-
// ~10ms on cold Windows cache); the `existsSync` short-circuit saves
|
|
281
|
-
// it on the hot path (every `peaks sub-agent share` + every
|
|
282
|
-
// `peaks sub-agent heartbeat`).
|
|
283
|
-
if (!existsSync(dir)) {
|
|
284
|
-
mkdirSync(dir, { recursive: true });
|
|
285
|
-
}
|
|
286
|
-
const tmp = `${path}.tmp-${process.pid}-${Date.now()}`;
|
|
287
|
-
writeFileSync(tmp, JSON.stringify(channel, null, 2) + '\n', 'utf8');
|
|
288
|
-
renameSync(tmp, path);
|
|
289
|
-
}
|
|
290
|
-
/**
|
|
291
|
-
* Compile a simple key pattern with `*` wildcards to a matcher. Only
|
|
292
|
-
* `*` is special; everything else is a literal. `*` matches zero or
|
|
293
|
-
* more characters. Examples:
|
|
294
|
-
* "rd.*" matches "rd.completed", "rd.found-blocker"
|
|
295
|
-
* "*.completed" matches "rd.completed", "qa.completed"
|
|
296
|
-
* "*" matches everything
|
|
297
|
-
*/
|
|
298
|
-
export function compileKeyPattern(pattern) {
|
|
299
|
-
if (pattern === '*') {
|
|
300
|
-
return () => true;
|
|
301
|
-
}
|
|
302
|
-
const escaped = pattern
|
|
303
|
-
.split('*')
|
|
304
|
-
.map((part) => part.replace(/[.+?^${}()|[\]\\]/g, '\\$&'))
|
|
305
|
-
.join('.*');
|
|
306
|
-
const re = new RegExp(`^${escaped}$`);
|
|
307
|
-
return (key) => re.test(key);
|
|
308
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export declare class LockTimeoutError extends Error {
|
|
2
|
-
readonly code = "LOCK_TIMEOUT";
|
|
3
|
-
readonly lockPath: string;
|
|
4
|
-
constructor(lockPath: string, attempts: number);
|
|
5
|
-
}
|
|
6
|
-
/**
|
|
7
|
-
* Run `fn` while holding an exclusive lock on a sidecar file at
|
|
8
|
-
* `<filePath>.lock`. The lock is released in `finally` (close fd +
|
|
9
|
-
* unlink lock file). Throws LockTimeoutError after MAX_LOCK_RETRIES.
|
|
10
|
-
*/
|
|
11
|
-
export declare function withFileLockSync<T>(filePath: string, fn: () => T): T;
|