peaks-loop 3.1.1 → 4.0.0-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +62 -12
- package/CHANGELOG.md +74 -36
- package/README-en.md +58 -240
- package/README.md +49 -325
- package/agents/karpathy-reviewer.md +3 -3
- package/dist/src/cli/cli-helpers.d.ts +18 -0
- package/dist/src/cli/cli-helpers.js +8 -0
- package/dist/src/cli/commands/adapter-commands.d.ts +30 -0
- package/dist/src/cli/commands/adapter-commands.js +35 -0
- package/dist/src/cli/commands/context-commands.d.ts +1 -1
- package/dist/src/cli/commands/context-commands.js +1 -1
- package/dist/src/cli/commands/contract-commands.d.ts +1 -1
- package/dist/src/cli/commands/contract-commands.js +1 -1
- package/dist/src/cli/commands/core/session-command.js +12 -0
- package/dist/src/cli/commands/core/skill-command.js +4 -4
- package/dist/src/cli/commands/dispatch-commands.js +2 -2
- package/dist/src/cli/commands/job-commands.js +58 -5
- package/dist/src/cli/commands/observability-commands.js +1 -1
- package/dist/src/cli/commands/perf-audit-commands.js +2 -2
- package/dist/src/cli/commands/security-audit-commands.js +2 -2
- package/dist/src/cli/commands/sediment-commands.d.ts +80 -0
- package/dist/src/cli/commands/sediment-commands.js +640 -0
- package/dist/src/cli/commands/session-migrate-skill-name.d.ts +17 -0
- package/dist/src/cli/commands/session-migrate-skill-name.js +41 -0
- package/dist/src/cli/commands/skill-visibility.d.ts +8 -0
- package/dist/src/cli/commands/skill-visibility.js +63 -0
- package/dist/src/cli/commands/slice-commands.js +2 -2
- package/dist/src/cli/commands/solo-commands.d.ts +2 -2
- package/dist/src/cli/commands/solo-commands.js +246 -20
- package/dist/src/cli/commands/sub-agent-commands.d.ts +1 -1
- package/dist/src/cli/commands/sub-agent-commands.js +1 -1
- package/dist/src/cli/commands/understand-commands.js +1 -1
- package/dist/src/cli/commands/upgrade-commands.d.ts +1 -1
- package/dist/src/cli/commands/upgrade-commands.js +3 -3
- package/dist/src/cli/commands/user-touchpoint-commands.js +1 -1
- package/dist/src/cli/commands/verdict-aggregate-command.d.ts +1 -1
- package/dist/src/cli/commands/verdict-aggregate-command.js +2 -2
- package/dist/src/cli/commands/workflow-commands.js +2 -2
- package/dist/src/cli/commands/workspace/init-command.d.ts +3 -3
- package/dist/src/cli/commands/workspace/init-command.js +7 -7
- package/dist/src/cli/program.js +19 -2
- package/dist/src/services/adapter/adapter.d.ts +27 -0
- package/dist/src/services/adapter/adapter.js +5 -0
- package/dist/src/services/adapter/auto-adapter.d.ts +11 -0
- package/dist/src/services/adapter/auto-adapter.js +15 -0
- package/dist/src/services/adapter/claude-adapter.d.ts +14 -0
- package/dist/src/services/adapter/claude-adapter.js +40 -0
- package/dist/src/services/adapter/codex-adapter.d.ts +14 -0
- package/dist/src/services/adapter/codex-adapter.js +14 -0
- package/dist/src/services/adapter/copilot-adapter.d.ts +14 -0
- package/dist/src/services/adapter/copilot-adapter.js +14 -0
- package/dist/src/services/audit/enforcers/solo-code-ban.d.ts +1 -1
- package/dist/src/services/audit/enforcers/solo-code-ban.js +2 -2
- package/dist/src/services/audit/red-line-catalog.js +1 -1
- package/dist/src/services/audit/scanners/skills-tree-scanner.js +22 -0
- package/dist/src/services/context/auto-compact-dispatcher.d.ts +1 -1
- package/dist/src/services/dispatch/batch-counter.js +1 -1
- package/dist/src/services/dispatch/leak-detector.js +1 -1
- package/dist/src/services/doctor/doctor-service.js +2 -2
- package/dist/src/services/job/job-progress-store.d.ts +60 -0
- package/dist/src/services/job/job-progress-store.js +70 -0
- package/dist/src/services/job/job-resource-snapshot.js +29 -1
- package/dist/src/services/job/job-types.d.ts +4 -4
- package/dist/src/services/memory/project-memory-service.js +1 -1
- package/dist/src/services/migrate-skill-name/migrate.d.ts +17 -0
- package/dist/src/services/migrate-skill-name/migrate.js +152 -0
- package/dist/src/services/migrate-skill-name/schema.d.ts +42 -0
- package/dist/src/services/migrate-skill-name/schema.js +25 -0
- package/dist/src/services/observability/aggregation.d.ts +1 -1
- package/dist/src/services/observability/aggregation.js +1 -1
- package/dist/src/services/perf/perf-baseline-service.d.ts +1 -1
- package/dist/src/services/perf/perf-baseline-service.js +1 -1
- package/dist/src/services/prd/handoff-types.d.ts +1 -1
- package/dist/src/services/prd/handoff-types.js +1 -1
- package/dist/src/services/progress/progress-service.d.ts +1 -1
- package/dist/src/services/progress/progress-service.js +1 -1
- package/dist/src/services/rd/standards-diagnostic.js +1 -1
- package/dist/src/services/recommendations/capability-seed-mappings.js +1 -1
- package/dist/src/services/sc/sc-service.js +1 -1
- package/dist/src/services/sediment/dispose-confirm.d.ts +9 -0
- package/dist/src/services/sediment/dispose-confirm.js +5 -0
- package/dist/src/services/sediment/json-schema.d.ts +247 -0
- package/dist/src/services/sediment/json-schema.js +26 -0
- package/dist/src/services/sediment/manifest-lint.d.ts +13 -0
- package/dist/src/services/sediment/manifest-lint.js +11 -0
- package/dist/src/services/sediment/pool-paths.d.ts +22 -0
- package/dist/src/services/sediment/pool-paths.js +25 -0
- package/dist/src/services/sediment/pool-read.d.ts +20 -0
- package/dist/src/services/sediment/pool-read.js +73 -0
- package/dist/src/services/sediment/pool-rebuild-index.d.ts +15 -0
- package/dist/src/services/sediment/pool-rebuild-index.js +28 -0
- package/dist/src/services/sediment/pool-write.d.ts +14 -0
- package/dist/src/services/sediment/pool-write.js +25 -0
- package/dist/src/services/sediment/promotion-gate.d.ts +12 -0
- package/dist/src/services/sediment/promotion-gate.js +20 -0
- package/dist/src/services/sediment/types.d.ts +52 -0
- package/dist/src/services/sediment/types.js +1 -0
- package/dist/src/services/session/binding-store.d.ts +1 -1
- package/dist/src/services/session/binding-store.js +1 -1
- package/dist/src/services/session/caller-id-types.d.ts +1 -1
- package/dist/src/services/session/session-manager.d.ts +1 -1
- package/dist/src/services/session/session-manager.js +1 -1
- package/dist/src/services/skill/resume-detector.js +1 -1
- package/dist/src/services/skill/skill-scheduler.d.ts +1 -1
- package/dist/src/services/skill/skill-scheduler.js +1 -1
- package/dist/src/services/skillhub/release-diff.d.ts +18 -0
- package/dist/src/services/skillhub/release-diff.js +38 -0
- package/dist/src/services/skillhub/release-export.d.ts +8 -0
- package/dist/src/services/skillhub/release-export.js +31 -0
- package/dist/src/services/skillhub/release-gc-blobs.d.ts +13 -0
- package/dist/src/services/skillhub/release-gc-blobs.js +32 -0
- package/dist/src/services/skillhub/release-import.d.ts +7 -0
- package/dist/src/services/skillhub/release-import.js +59 -0
- package/dist/src/services/skillhub/release-retain.d.ts +23 -0
- package/dist/src/services/skillhub/release-retain.js +89 -0
- package/dist/src/services/skillhub/sqlite-store.d.ts +22 -0
- package/dist/src/services/skillhub/sqlite-store.js +47 -0
- package/dist/src/services/skillhub/tar-runtime.d.ts +21 -0
- package/dist/src/services/skillhub/tar-runtime.js +91 -0
- package/dist/src/services/skillhub/types.d.ts +105 -0
- package/dist/src/services/skillhub/types.js +1 -0
- package/dist/src/services/skills/skill-conformance-service.js +8 -5
- package/dist/src/services/skills/skill-presence-service.d.ts +4 -4
- package/dist/src/services/skills/skill-presence-service.js +2 -2
- package/dist/src/services/skills/skill-registry.js +27 -0
- package/dist/src/services/skills/skill-runbook-service.js +2 -2
- package/dist/src/services/slice/slice-check-service.js +1 -1
- package/dist/src/services/slice/slice-check-types.d.ts +1 -1
- package/dist/src/services/slice/slice-check-types.js +1 -1
- package/dist/src/services/slice/slice-decompose-types.d.ts +1 -1
- package/dist/src/services/slice/slice-decompose-types.js +1 -1
- package/dist/src/services/solo/auto-compact-orchestrator.d.ts +1 -1
- package/dist/src/services/solo/auto-compact-orchestrator.js +2 -2
- package/dist/src/services/solo/dag-orchestrator.d.ts +3 -3
- package/dist/src/services/solo/dag-orchestrator.js +4 -4
- package/dist/src/services/solo/emit-handoff.d.ts +49 -0
- package/dist/src/services/solo/emit-handoff.js +79 -0
- package/dist/src/services/solo/mode-gate.d.ts +2 -2
- package/dist/src/services/solo/post-compact-detector.js +2 -2
- package/dist/src/services/solo/status-line-renderer.d.ts +4 -4
- package/dist/src/services/solo/step-08-gate.d.ts +90 -0
- package/dist/src/services/solo/step-08-gate.js +136 -0
- package/dist/src/services/standards/missing-standards-detector.d.ts +1 -1
- package/dist/src/services/standards/missing-standards-detector.js +1 -1
- package/dist/src/services/standards/project-standards-service.d.ts +1 -1
- package/dist/src/services/standards/project-standards-service.js +4 -4
- package/dist/src/services/understand/understand-types.d.ts +1 -1
- package/dist/src/services/upgrade/1x-detector-service.js +1 -1
- package/dist/src/services/upgrade/upgrade-service.d.ts +34 -0
- package/dist/src/services/upgrade/upgrade-service.js +52 -30
- package/dist/src/services/verdict/verdict-aggregator.d.ts +1 -1
- package/dist/src/services/workflow/workflow-router-service.d.ts +1 -1
- package/dist/src/services/workflow/workflow-router-service.js +3 -3
- package/dist/src/services/workspace/claude-settings-template.d.ts +7 -2
- package/dist/src/services/workspace/claude-settings-template.js +42 -3
- package/dist/src/services/workspace/workspace-claude-settings-materializer.d.ts +1 -1
- package/dist/src/services/workspace/workspace-claude-settings-materializer.js +1 -1
- package/dist/src/services/workspace/workspace-service.d.ts +4 -4
- package/dist/src/services/workspace/workspace-service.js +2 -2
- package/dist/src/shared/paths.d.ts +1 -1
- package/dist/src/shared/paths.js +1 -1
- package/dist/src/shared/version.d.ts +1 -1
- package/dist/src/shared/version.js +1 -1
- package/dist/src/skills/peaks-maker/index.d.ts +5 -0
- package/dist/src/skills/peaks-maker/index.js +32 -0
- package/package.json +8 -3
- package/scripts/install-skills.mjs +29 -4
- package/skills/{peaks-prd → bee/peaks-prd}/SKILL.md +8 -2
- package/skills/{peaks-prd → bee/peaks-prd}/references/workflow.md +1 -1
- package/skills/{peaks-qa → bee/peaks-qa}/SKILL.md +10 -4
- package/skills/{peaks-qa → bee/peaks-qa}/references/browser-validation-contracts.md +2 -2
- package/skills/{peaks-qa → bee/peaks-qa}/references/external-capability-guidance.md +1 -1
- package/skills/{peaks-qa → bee/peaks-qa}/references/qa-fanout-contract.md +3 -3
- package/skills/{peaks-qa → bee/peaks-qa}/references/qa-sub-agent-dispatch.md +1 -1
- package/skills/{peaks-rd → bee/peaks-rd}/SKILL.md +13 -6
- package/skills/{peaks-rd → bee/peaks-rd}/references/browser-self-test-contracts.md +1 -1
- package/skills/{peaks-rd → bee/peaks-rd}/references/mock-data-placement.md +1 -1
- package/skills/{peaks-rd → bee/peaks-rd}/references/parallel-review-fanout.md +1 -1
- package/skills/{peaks-rd → bee/peaks-rd}/references/rd-runbook.md +1 -1
- package/skills/{peaks-rd → bee/peaks-rd}/references/rd-sub-agent-dispatch.md +2 -2
- package/skills/{peaks-rd → bee/peaks-rd}/references/rd-transition-gates.md +1 -1
- package/skills/{peaks-rd → bee/peaks-rd}/references/skill-presence-and-title.md +1 -1
- package/skills/{peaks-reviewer → bee/peaks-reviewer}/SKILL.md +2 -2
- package/skills/{peaks-sc → bee/peaks-sc}/SKILL.md +7 -1
- package/skills/{peaks-txt → bee/peaks-txt}/SKILL.md +9 -3
- package/skills/{peaks-ui → bee/peaks-ui}/SKILL.md +11 -5
- package/skills/peaks-audit/SKILL.md +1 -1
- package/skills/{peaks-solo → peaks-code}/SKILL.md +53 -104
- package/skills/{peaks-solo → peaks-code}/references/a2a-artifact-mapping.md +2 -2
- package/skills/{peaks-solo → peaks-code}/references/anchoring-and-session-info.md +4 -4
- package/skills/{peaks-solo → peaks-code}/references/artifact-contracts.md +2 -2
- package/skills/{peaks-solo → peaks-code}/references/browser-workflow.md +1 -1
- package/skills/peaks-code/references/command-migration.md +3 -0
- package/skills/{peaks-solo → peaks-code}/references/completion-handoff.md +2 -2
- package/skills/{peaks-solo → peaks-code}/references/context-governance.md +2 -2
- package/skills/{peaks-solo → peaks-code}/references/frontend-only-mode.md +1 -1
- package/skills/{peaks-solo → peaks-code}/references/local-artifact-workspace.md +1 -1
- package/skills/{peaks-solo → peaks-code}/references/micro-cycle.md +9 -9
- package/skills/{peaks-solo → peaks-code}/references/mode-selection-with-stale-presence.md +12 -12
- package/skills/{peaks-solo → peaks-code}/references/mode-selection.md +1 -1
- package/skills/{peaks-solo → peaks-code}/references/openspec-workflow.md +1 -1
- package/skills/{peaks-solo → peaks-code}/references/project-scan-checklist.md +1 -1
- package/skills/{peaks-solo → peaks-code}/references/refactor-mode.md +1 -1
- package/skills/{peaks-solo → peaks-code}/references/resume-detection.md +1 -1
- package/skills/{peaks-solo → peaks-code}/references/runbook.md +25 -5
- package/skills/{peaks-solo → peaks-code}/references/skill-presence-and-title.md +3 -3
- package/skills/{peaks-solo → peaks-code}/references/standards-preflight.md +1 -1
- package/skills/{peaks-solo → peaks-code}/references/step-0-55-1x-detection.md +5 -5
- package/skills/peaks-code/references/step-0-8-gate.md +60 -0
- package/skills/{peaks-solo → peaks-code}/references/sub-agent-dispatch.md +10 -10
- package/skills/{peaks-solo → peaks-code}/references/swarm-dispatch-contract.md +7 -7
- package/skills/{peaks-solo → peaks-code}/references/workflow-gates-and-types.md +3 -3
- package/skills/peaks-doctor/SKILL.md +1 -1
- package/skills/peaks-doctor/references/doctor-check-catalog.md +1 -1
- package/skills/peaks-final-review/SKILL.md +3 -3
- package/skills/peaks-final-review/references/4-dimensions.md +1 -1
- package/skills/peaks-ide/SKILL.md +1 -1
- package/skills/{peaks-solo-resume → peaks-resume}/SKILL.md +14 -14
- package/skills/peaks-sop/SKILL.md +1 -1
- package/skills/{peaks-solo-status → peaks-status}/SKILL.md +13 -13
- package/skills/{peaks-solo-test → peaks-test}/SKILL.md +11 -11
- package/skills/peaks-solo/references/command-migration.md +0 -3
- /package/skills/{peaks-perf-audit → bee/peaks-perf-audit}/SKILL.md +0 -0
- /package/skills/{peaks-perf-audit → bee/peaks-perf-audit}/references/audit-protocol.md +0 -0
- /package/skills/{peaks-prd → bee/peaks-prd}/references/artifact-contracts.md +0 -0
- /package/skills/{peaks-prd → bee/peaks-prd}/references/artifact-per-request.md +0 -0
- /package/skills/{peaks-prd → bee/peaks-prd}/references/command-migration.md +0 -0
- /package/skills/{peaks-prd → bee/peaks-prd}/references/prd-for-multi-pass.md +0 -0
- /package/skills/{peaks-qa → bee/peaks-qa}/references/artifact-contracts.md +0 -0
- /package/skills/{peaks-qa → bee/peaks-qa}/references/artifact-per-request.md +0 -0
- /package/skills/{peaks-qa → bee/peaks-qa}/references/codegraph-regression-focus.md +0 -0
- /package/skills/{peaks-qa → bee/peaks-qa}/references/command-migration.md +0 -0
- /package/skills/{peaks-qa → bee/peaks-qa}/references/openspec-validation-gate.md +0 -0
- /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-compact-handoff.md +0 -0
- /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-context-governance.md +0 -0
- /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-gstack-integration.md +0 -0
- /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-local-artifacts.md +0 -0
- /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-matt-pocock-integration.md +0 -0
- /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-perf-test-plan.md +0 -0
- /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-refactor-role.md +0 -0
- /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-runbook.md +0 -0
- /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-security-test-plan.md +0 -0
- /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-skill-presence.md +0 -0
- /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-standards-preflight.md +0 -0
- /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-transition-gates.md +0 -0
- /package/skills/{peaks-qa → bee/peaks-qa}/references/reading-handoff-frontmatter.md +0 -0
- /package/skills/{peaks-qa → bee/peaks-qa}/references/regression-gates.md +0 -0
- /package/skills/{peaks-qa → bee/peaks-qa}/references/requirement-boundary-recheck.md +0 -0
- /package/skills/{peaks-qa → bee/peaks-qa}/references/test-case-generation.md +0 -0
- /package/skills/{peaks-qa → bee/peaks-qa}/references/test-report-output.md +0 -0
- /package/skills/{peaks-rd → bee/peaks-rd}/references/artifact-and-standards-output.md +0 -0
- /package/skills/{peaks-rd → bee/peaks-rd}/references/artifact-contracts.md +0 -0
- /package/skills/{peaks-rd → bee/peaks-rd}/references/artifact-per-request.md +0 -0
- /package/skills/{peaks-rd → bee/peaks-rd}/references/browser-action-wrapper.md +0 -0
- /package/skills/{peaks-rd → bee/peaks-rd}/references/code-reviewer-4dim-hint.md +0 -0
- /package/skills/{peaks-rd → bee/peaks-rd}/references/codegraph-project-analysis.md +0 -0
- /package/skills/{peaks-rd → bee/peaks-rd}/references/command-migration.md +0 -0
- /package/skills/{peaks-rd → bee/peaks-rd}/references/compact-handoff.md +0 -0
- /package/skills/{peaks-rd → bee/peaks-rd}/references/external-references.md +0 -0
- /package/skills/{peaks-rd → bee/peaks-rd}/references/frontend-project-generation.md +0 -0
- /package/skills/{peaks-rd → bee/peaks-rd}/references/karpathy-reviewer-prompt.md +0 -0
- /package/skills/{peaks-rd → bee/peaks-rd}/references/library-version-awareness.md +0 -0
- /package/skills/{peaks-rd → bee/peaks-rd}/references/mandatory-perf-baseline.md +0 -0
- /package/skills/{peaks-rd → bee/peaks-rd}/references/matt-pocock-integration.md +0 -0
- /package/skills/{peaks-rd → bee/peaks-rd}/references/ocr-integration.md +0 -0
- /package/skills/{peaks-rd → bee/peaks-rd}/references/openspec-cli.md +0 -0
- /package/skills/{peaks-rd → bee/peaks-rd}/references/rd-context-governance.md +0 -0
- /package/skills/{peaks-rd → bee/peaks-rd}/references/rd-fanout-contracts.md +0 -0
- /package/skills/{peaks-rd → bee/peaks-rd}/references/rd-gstack-integration.md +0 -0
- /package/skills/{peaks-rd → bee/peaks-rd}/references/rd-standards-preflight.md +0 -0
- /package/skills/{peaks-rd → bee/peaks-rd}/references/reading-v2-slice-results.md +0 -0
- /package/skills/{peaks-rd → bee/peaks-rd}/references/refactor-workflow.md +0 -0
- /package/skills/{peaks-rd → bee/peaks-rd}/references/v2-12-fanout-collapse.md +0 -0
- /package/skills/{peaks-rd → bee/peaks-rd}/references/writing-handoff-frontmatter.md +0 -0
- /package/skills/{peaks-reviewer → bee/peaks-reviewer}/references/reviewer-prompt.md +0 -0
- /package/skills/{peaks-reviewer → bee/peaks-reviewer}/references/reviewer-schema.md +0 -0
- /package/skills/{peaks-sc → bee/peaks-sc}/references/artifact-contracts.md +0 -0
- /package/skills/{peaks-sc → bee/peaks-sc}/references/artifact-retention.md +0 -0
- /package/skills/{peaks-sc → bee/peaks-sc}/references/command-migration.md +0 -0
- /package/skills/{peaks-sc → bee/peaks-sc}/references/openspec-commit-boundaries.md +0 -0
- /package/skills/{peaks-security-audit → bee/peaks-security-audit}/SKILL.md +0 -0
- /package/skills/{peaks-security-audit → bee/peaks-security-audit}/references/audit-protocol.md +0 -0
- /package/skills/{peaks-txt → bee/peaks-txt}/references/artifact-contracts.md +0 -0
- /package/skills/{peaks-txt → bee/peaks-txt}/references/command-migration.md +0 -0
- /package/skills/{peaks-txt → bee/peaks-txt}/references/context-capsule.md +0 -0
- /package/skills/{peaks-ui → bee/peaks-ui}/references/artifact-contracts.md +0 -0
- /package/skills/{peaks-ui → bee/peaks-ui}/references/artifact-per-request.md +0 -0
- /package/skills/{peaks-ui → bee/peaks-ui}/references/command-migration.md +0 -0
- /package/skills/{peaks-ui → bee/peaks-ui}/references/workflow.md +0 -0
- /package/skills/{peaks-solo → peaks-code}/references/boundaries.md +0 -0
- /package/skills/{peaks-solo → peaks-code}/references/checkpoint-resume.md +0 -0
- /package/skills/{peaks-solo → peaks-code}/references/codegraph-orchestration.md +0 -0
- /package/skills/{peaks-solo → peaks-code}/references/cross-date-session-check.md +0 -0
- /package/skills/{peaks-solo → peaks-code}/references/dag-orchestrator.md +0 -0
- /package/skills/{peaks-solo → peaks-code}/references/envelope-contract.md +0 -0
- /package/skills/{peaks-solo → peaks-code}/references/existing-system-extraction.md +0 -0
- /package/skills/{peaks-solo → peaks-code}/references/external-references.md +0 -0
- /package/skills/{peaks-solo → peaks-code}/references/external-skill-invocation.md +0 -0
- /package/skills/{peaks-solo → peaks-code}/references/fanout-mandatory.md +0 -0
- /package/skills/{peaks-solo → peaks-code}/references/fast-mode.md +0 -0
- /package/skills/{peaks-solo → peaks-code}/references/gstack-integration.md +0 -0
- /package/skills/{peaks-solo → peaks-code}/references/headroom-integration.md +0 -0
- /package/skills/{peaks-solo → peaks-code}/references/job-loop.md +0 -0
- /package/skills/{peaks-solo → peaks-code}/references/periodic-checkpoint.md +0 -0
- /package/skills/{peaks-solo → peaks-code}/references/playwright-mcp-multi-terminal.md +0 -0
- /package/skills/{peaks-solo → peaks-code}/references/project-memory-loading.md +0 -0
- /package/skills/{peaks-solo → peaks-code}/references/quality-gate-cheatsheet.md +0 -0
- /package/skills/{peaks-solo → peaks-code}/references/workflow.md +0 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { resolve } from 'node:path';
|
|
2
|
+
import { migrateSkillName } from '../../services/migrate-skill-name/migrate.js';
|
|
3
|
+
import { getErrorMessage } from '../cli-helpers.js';
|
|
4
|
+
export function registerSessionMigrateSkillNameCommand(session) {
|
|
5
|
+
session
|
|
6
|
+
.command('migrate-skill-name')
|
|
7
|
+
.description('Rewrite skill-name strings under .peaks/_runtime/** (idempotent, dry-run by default). ' +
|
|
8
|
+
'Use --apply to write through. Skips .peaks/memory/** and .peaks/skills/.system/bees/.')
|
|
9
|
+
.requiredOption('--from <old>', 'old skill name (e.g. peaks-code)')
|
|
10
|
+
.requiredOption('--to <new>', 'new skill name (e.g. peaks-code)')
|
|
11
|
+
.option('--apply', 'write through (default is dry-run)', false)
|
|
12
|
+
.option('--project <path>', 'project root (defaults to current directory)', '.')
|
|
13
|
+
.option('--json', 'emit a JSON envelope to stdout', false)
|
|
14
|
+
.action((opts) => {
|
|
15
|
+
try {
|
|
16
|
+
const projectRoot = resolve(process.cwd(), opts.project ?? '.');
|
|
17
|
+
const result = migrateSkillName({
|
|
18
|
+
projectRoot,
|
|
19
|
+
from: opts.from,
|
|
20
|
+
to: opts.to,
|
|
21
|
+
apply: opts.apply === true,
|
|
22
|
+
});
|
|
23
|
+
if (opts.json === true) {
|
|
24
|
+
process.stdout.write(JSON.stringify(result, null, 2) + '\n');
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
process.stdout.write(`Scanned: ${result.scannedFiles}\n` +
|
|
28
|
+
`Modified: ${result.modifiedFiles}\n` +
|
|
29
|
+
`Key-value replacements: ${result.keyValueReplacements}\n` +
|
|
30
|
+
`String replacements: ${result.stringReplacements}\n` +
|
|
31
|
+
`Skipped: ${result.skipped.length} path(s)\n` +
|
|
32
|
+
`Errors: ${result.errors.length}\n`);
|
|
33
|
+
}
|
|
34
|
+
process.exitCode = result.ok ? 0 : 1;
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
process.stderr.write(getErrorMessage(error) + '\n');
|
|
38
|
+
process.exitCode = 1;
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
export interface SkillVisibility {
|
|
3
|
+
name: string;
|
|
4
|
+
userInvocable: boolean;
|
|
5
|
+
visibility: 'public' | 'internal';
|
|
6
|
+
}
|
|
7
|
+
export declare function listSkillsVisibility(repoRoot: string): SkillVisibility[];
|
|
8
|
+
export declare function registerSkillVisibilityCommand(program: Command, repoRoot: string): void;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `peaks skill:visibility` — Skill visibility CLI surface.
|
|
3
|
+
*
|
|
4
|
+
* Slice: Task 1 of peaks-code → peaks-code rename plan.
|
|
5
|
+
*
|
|
6
|
+
* Reads `.claude-plugin/marketplace.json`, resolves each skill entry's
|
|
7
|
+
* visibility (public / internal) from the optional `userInvocable`
|
|
8
|
+
* field, and emits either:
|
|
9
|
+
* - a TSV list (`name \t visibility`) for human use
|
|
10
|
+
* - a JSON envelope `{ ok, skills }` for programmatic use
|
|
11
|
+
*
|
|
12
|
+
* Schema contract:
|
|
13
|
+
* - internal: `userInvocable: false`
|
|
14
|
+
* - public (default): `userInvocable` omitted OR `true`
|
|
15
|
+
*
|
|
16
|
+
* The skill list lives at `plugins[0].skills` in marketplace.json;
|
|
17
|
+
* entries are objects of shape `{ name, path?, userInvocable?, description? }`.
|
|
18
|
+
* Older string-array shapes are auto-coerced (each string is treated as
|
|
19
|
+
* a public skill whose name is the basename of the path).
|
|
20
|
+
*/
|
|
21
|
+
import { readFileSync } from 'node:fs';
|
|
22
|
+
import { join, basename } from 'node:path';
|
|
23
|
+
export function listSkillsVisibility(repoRoot) {
|
|
24
|
+
const marketplacePath = join(repoRoot, '.claude-plugin', 'marketplace.json');
|
|
25
|
+
const raw = readFileSync(marketplacePath, 'utf-8');
|
|
26
|
+
const parsed = JSON.parse(raw);
|
|
27
|
+
const skills = parsed.plugins?.[0]?.skills ?? [];
|
|
28
|
+
return skills.map((entry) => {
|
|
29
|
+
if (typeof entry === 'string') {
|
|
30
|
+
return {
|
|
31
|
+
name: basename(entry),
|
|
32
|
+
userInvocable: true,
|
|
33
|
+
visibility: 'public',
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
const userInvocable = entry.userInvocable !== false;
|
|
37
|
+
return {
|
|
38
|
+
name: entry.name ?? '',
|
|
39
|
+
userInvocable,
|
|
40
|
+
visibility: userInvocable ? 'public' : 'internal',
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
export function registerSkillVisibilityCommand(program, repoRoot) {
|
|
45
|
+
const cmd = program
|
|
46
|
+
.command('skill:visibility')
|
|
47
|
+
.description('List skill visibility (public vs internal)')
|
|
48
|
+
.option('--list', 'List all skills')
|
|
49
|
+
.option('--name <name>', 'Query single skill')
|
|
50
|
+
.option('--json', 'JSON output');
|
|
51
|
+
cmd.action((opts) => {
|
|
52
|
+
const all = listSkillsVisibility(repoRoot);
|
|
53
|
+
const filtered = opts.name ? all.filter((s) => s.name === opts.name) : all;
|
|
54
|
+
if (opts.json) {
|
|
55
|
+
process.stdout.write(JSON.stringify({ ok: true, skills: filtered }, null, 2) + '\n');
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
for (const s of filtered) {
|
|
59
|
+
process.stdout.write(`${s.name}\t${s.visibility}\n`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
@@ -26,8 +26,8 @@ export function registerSliceCommands(program, io) {
|
|
|
26
26
|
.option('--project <path>', 'target project root', '.')
|
|
27
27
|
.option('--rid <rid>', 'request id; defaults to the active current-change binding')
|
|
28
28
|
.option('--refresh-fanout', 're-run the 3-way review fan-out (peaks-rd) even if the review files already exist', false)
|
|
29
|
-
.option('--run-tests', 'opt in to the FULL test suite at the boundary (default is the changed-only suite via `vitest run --changed`); use the peaks-
|
|
30
|
-
.option('--skip-tests', 'skip the unit-test stage entirely (e.g. docs-only slices); use the peaks-
|
|
29
|
+
.option('--run-tests', 'opt in to the FULL test suite at the boundary (default is the changed-only suite via `vitest run --changed`); use the peaks-test skill to run the full suite standalone', false)
|
|
30
|
+
.option('--skip-tests', 'skip the unit-test stage entirely (e.g. docs-only slices); use the peaks-test skill to run the full suite manually if you want a separate check', false)
|
|
31
31
|
.option('--allow-pre-existing-failures', 'opt-in: if the unit-test stage fails, report it as `skipped` with a reason naming the failure count (useful when the repo has unrelated pre-existing failures; the long-term fix is to .skip or coverage.exclude those tests). Only meaningful with --run-tests or the default changed-only mode.', false)).action(async (options) => {
|
|
32
32
|
try {
|
|
33
33
|
const projectRoot = resolveCanonicalProjectRoot(options.project);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Slice 2 — `peaks solo [--fast] <change-id>` (peaks-
|
|
2
|
+
* Slice 2 — `peaks solo [--fast] <change-id>` (peaks-code fast mode).
|
|
3
3
|
*
|
|
4
|
-
* The `peaks-
|
|
4
|
+
* The `peaks-code` SKILL orchestrates an LLM-side workflow:
|
|
5
5
|
* load-memory -> standards-preflight -> rd-cycle -> qa-cycle -> emit-txt
|
|
6
6
|
*
|
|
7
7
|
* The CLI surface here is intentionally narrow: it builds a SoloPlan and
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Slice 2 — `peaks solo [--fast] <change-id>` (peaks-
|
|
2
|
+
* Slice 2 — `peaks solo [--fast] <change-id>` (peaks-code fast mode).
|
|
3
3
|
*
|
|
4
|
-
* The `peaks-
|
|
4
|
+
* The `peaks-code` SKILL orchestrates an LLM-side workflow:
|
|
5
5
|
* load-memory -> standards-preflight -> rd-cycle -> qa-cycle -> emit-txt
|
|
6
6
|
*
|
|
7
7
|
* The CLI surface here is intentionally narrow: it builds a SoloPlan and
|
|
@@ -26,6 +26,8 @@ import { getSkillPresence, checkStalePresence } from '../../services/skills/skil
|
|
|
26
26
|
import { detectPostCompactResume, formatPostCompactResumeLogLine } from '../../services/solo/post-compact-detector.js';
|
|
27
27
|
import { runAutoCompact } from '../../services/solo/auto-compact-orchestrator.js';
|
|
28
28
|
import { readJobShapeDecision, writeJobShapeDecision, JobShapeDecisionError, JOB_SHAPE_NOT_DECIDED, JOB_SHAPE_ALREADY_DECIDED } from '../../services/solo/job-shape-decision.js';
|
|
29
|
+
import { evaluateStep08, STEP_08_BACKUP_REGEX } from '../../services/solo/step-08-gate.js';
|
|
30
|
+
import { evaluateEmitHandoff, JOB_NOT_INITIALIZED, JOB_REMAINING_BLOCKED } from '../../services/solo/emit-handoff.js';
|
|
29
31
|
const STEP_ORDER = [
|
|
30
32
|
'load-memory',
|
|
31
33
|
'standards-preflight',
|
|
@@ -107,7 +109,7 @@ export async function runSoloFast(opts) {
|
|
|
107
109
|
export function registerSoloCommands(program, io) {
|
|
108
110
|
const solo = program
|
|
109
111
|
.command('solo')
|
|
110
|
-
.description('peaks-
|
|
112
|
+
.description('peaks-code LLM-side workflow planner (slice 2 fast mode)');
|
|
111
113
|
solo
|
|
112
114
|
.command('plan')
|
|
113
115
|
.description('Build and print a SoloPlan without executing it')
|
|
@@ -236,7 +238,7 @@ export function registerSoloCommands(program, io) {
|
|
|
236
238
|
}
|
|
237
239
|
}, [], [
|
|
238
240
|
`Recorded outer session id "${stalePresence.recordedOuterSessionId ?? '?'}" does not match current outer session id "${stalePresence.currentOuterSessionId ?? '?'}".`,
|
|
239
|
-
`peaks-
|
|
241
|
+
`peaks-code Step 1 must AskUserQuestion to confirm the mode for THIS session (slice 002 AC-2).`
|
|
240
242
|
]), opts.json);
|
|
241
243
|
return;
|
|
242
244
|
}
|
|
@@ -304,14 +306,14 @@ export function registerSoloCommands(program, io) {
|
|
|
304
306
|
.command('post-compact-detect')
|
|
305
307
|
.description('v2.11.0 D7: detect whether the current invocation is a same-day post-compact resume. ' +
|
|
306
308
|
'Auto-resumes (no AskUserQuestion) when the most-recent checkpoint is from today, has a mode field, ' +
|
|
307
|
-
'and the active skill is peaks-
|
|
309
|
+
'and the active skill is peaks-code. Falls through to the normal Step 0.7 flow otherwise.')
|
|
308
310
|
.requiredOption('--project <path>', 'target project root')
|
|
309
311
|
.option('--session-id <sid>', 'override session id (default: read from active presence)')
|
|
310
312
|
.option('--active-skill <skill>', 'override active skill (test seam; default: read from presence)')).action(async (opts) => {
|
|
311
313
|
try {
|
|
312
314
|
const sessionId = opts.sessionId ?? readActiveSid(opts.project);
|
|
313
315
|
if (sessionId === null) {
|
|
314
|
-
printResult(io, fail('solo.post-compact-detect', 'NO_ACTIVE_SESSION', 'no active session id; pass --session-id or set presence via `peaks skill presence:set peaks-
|
|
316
|
+
printResult(io, fail('solo.post-compact-detect', 'NO_ACTIVE_SESSION', 'no active session id; pass --session-id or set presence via `peaks skill presence:set peaks-code`', null, ['Re-run with --session-id <sid>']), opts.json);
|
|
315
317
|
process.exitCode = 1;
|
|
316
318
|
return;
|
|
317
319
|
}
|
|
@@ -383,38 +385,88 @@ export function registerSoloCommands(program, io) {
|
|
|
383
385
|
'without requiring the LLM to pass --prompt-size <bytes> manually. ' +
|
|
384
386
|
'Adapter-driven (no hard-coded IDE names): Claude Code is the MVP ' +
|
|
385
387
|
'implementation; trae / codex / cursor / qoder / tongyi-lingma / ' +
|
|
386
|
-
'hermes / openclaw register their own env-var via IdeAdapter.compact.'
|
|
388
|
+
'hermes / openclaw register their own env-var via IdeAdapter.compact. ' +
|
|
389
|
+
'v3.1.2: when --enforce-job-mode is set OR job-shape.json says isJob=true, ' +
|
|
390
|
+
'≥0.85 emits action=auto-compact-now (MANDATORY, not advisory) and ' +
|
|
391
|
+
'≥0.95 emits action=red-line (forced hook fires next turn).')
|
|
387
392
|
.requiredOption('--project <path>', 'target project root')
|
|
388
|
-
.option('--session-id <sid>', 'override session id (default: read from active presence)')
|
|
393
|
+
.option('--session-id <sid>', 'override session id (default: read from active presence)')
|
|
394
|
+
.option('--enforce-job-mode', 'v3.1.2: treat ≥0.85 as MANDATORY auto-compact (not advisory). Auto-enabled when job-shape.json says isJob=true.')).action(async (opts) => {
|
|
389
395
|
try {
|
|
390
396
|
const { readContextPercent } = await import('../../services/context/auto-compact-reader.js');
|
|
397
|
+
// v3.1.2: detect Job mode from job-shape.json when --enforce-job-mode
|
|
398
|
+
// is not explicitly passed. The LLM is the source of truth for
|
|
399
|
+
// whether the request is Job-shaped; the recorded decision is.
|
|
400
|
+
let isJobMode = opts.enforceJobMode === true;
|
|
401
|
+
if (!isJobMode) {
|
|
402
|
+
try {
|
|
403
|
+
const sessionIdForDecision = opts.sessionId ?? readActiveSid(opts.project);
|
|
404
|
+
if (sessionIdForDecision !== null) {
|
|
405
|
+
const record = readJobShapeDecision(opts.project, sessionIdForDecision);
|
|
406
|
+
if (record.decision.isJob)
|
|
407
|
+
isJobMode = true;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
catch (err) {
|
|
411
|
+
if (!(err instanceof JobShapeDecisionError))
|
|
412
|
+
throw err;
|
|
413
|
+
// missing/malformed decision file is fine — fall back to advisory.
|
|
414
|
+
}
|
|
415
|
+
}
|
|
391
416
|
const probe = readContextPercent({
|
|
392
417
|
projectRoot: opts.project,
|
|
393
418
|
sessionId: opts.sessionId ?? readActiveSid(opts.project) ?? 'unknown',
|
|
394
419
|
env: process.env
|
|
395
420
|
});
|
|
396
421
|
const ratioPct = (probe.ratio * 100).toFixed(1);
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
422
|
+
let action = 'ok';
|
|
423
|
+
let next = null;
|
|
424
|
+
if (probe.ratio >= 0.95) {
|
|
425
|
+
action = isJobMode ? 'red-line' : 'red-line';
|
|
426
|
+
next = 'peaks session auto-compact-hook';
|
|
427
|
+
}
|
|
428
|
+
else if (probe.ratio >= 0.85) {
|
|
429
|
+
if (isJobMode) {
|
|
430
|
+
action = 'auto-compact-now';
|
|
431
|
+
next = 'peaks session auto-compact --execute';
|
|
432
|
+
}
|
|
433
|
+
else {
|
|
434
|
+
action = 'soft-warn';
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
else if (probe.ratio >= 0.5) {
|
|
438
|
+
action = 'soft-warn';
|
|
439
|
+
}
|
|
440
|
+
const verdict = action === 'red-line' ? 'red-line'
|
|
441
|
+
: action === 'auto-compact-now' ? 'pre-compact'
|
|
442
|
+
: action === 'soft-warn' ? 'soft-warn'
|
|
400
443
|
: 'ok';
|
|
444
|
+
const jobModeNotice = isJobMode
|
|
445
|
+
? 'Job mode enforced: ≥0.85 is MANDATORY auto-compact (v3.1.2).'
|
|
446
|
+
: 'Advisory mode (single-rid): ≥0.85 is recommended, not mandatory.';
|
|
401
447
|
printResult(io, ok('solo.context-now', {
|
|
402
448
|
ratio: probe.ratio,
|
|
403
449
|
ratioPct: `${ratioPct}%`,
|
|
404
450
|
verdict,
|
|
451
|
+
action,
|
|
452
|
+
next,
|
|
453
|
+
jobMode: isJobMode,
|
|
405
454
|
source: probe.source,
|
|
406
455
|
ide: probe.ide,
|
|
407
456
|
capacityBytes: probe.capacityBytes,
|
|
408
457
|
rawBytes: probe.rawBytes ?? null,
|
|
409
458
|
capturedAt: probe.capturedAt
|
|
410
459
|
}, [], [
|
|
411
|
-
|
|
412
|
-
? `RED LINE: ≥ 95%.
|
|
413
|
-
:
|
|
414
|
-
? `
|
|
415
|
-
:
|
|
416
|
-
?
|
|
417
|
-
|
|
460
|
+
action === 'red-line'
|
|
461
|
+
? `RED LINE: ≥ 95%. Next: \`${next}\` (PreToolUse hook fires next turn).`
|
|
462
|
+
: action === 'auto-compact-now'
|
|
463
|
+
? `Job-mode MANDATORY auto-compact. Solo MUST call \`${next}\` WITHOUT confirmation.`
|
|
464
|
+
: action === 'soft-warn'
|
|
465
|
+
? isJobMode
|
|
466
|
+
? `Job mode soft-warn (50–85%). Continue working; the next \`peaks context now\` will re-check.`
|
|
467
|
+
: `Soft warn (50–85%). Continue working; the next \`peaks context now\` will re-check.`
|
|
468
|
+
: `Below 50%. No action required.`,
|
|
469
|
+
jobModeNotice
|
|
418
470
|
]), true);
|
|
419
471
|
}
|
|
420
472
|
catch (err) {
|
|
@@ -468,7 +520,7 @@ export function registerSoloCommands(program, io) {
|
|
|
468
520
|
const projectRoot = opts.project ?? findProjectRoot(process.cwd()) ?? process.cwd();
|
|
469
521
|
const sessionId = opts.sessionId ?? readActiveSid(projectRoot);
|
|
470
522
|
if (sessionId === null) {
|
|
471
|
-
printResult(io, fail('solo.detect-job', 'NO_ACTIVE_SESSION', 'no active session id; pass --session-id or set presence via `peaks skill presence:set peaks-
|
|
523
|
+
printResult(io, fail('solo.detect-job', 'NO_ACTIVE_SESSION', 'no active session id; pass --session-id or set presence via `peaks skill presence:set peaks-code`', null, ['Re-run with --session-id <sid>']), opts.json);
|
|
472
524
|
process.exitCode = 1;
|
|
473
525
|
return;
|
|
474
526
|
}
|
|
@@ -530,7 +582,7 @@ export function registerSoloCommands(program, io) {
|
|
|
530
582
|
const projectRoot = opts.project ?? findProjectRoot(process.cwd()) ?? process.cwd();
|
|
531
583
|
const sessionId = opts.sessionId ?? readActiveSid(projectRoot);
|
|
532
584
|
if (sessionId === null) {
|
|
533
|
-
printResult(io, fail('solo.read-job-shape', 'NO_ACTIVE_SESSION', 'no active session id; pass --session-id or set presence via `peaks skill presence:set peaks-
|
|
585
|
+
printResult(io, fail('solo.read-job-shape', 'NO_ACTIVE_SESSION', 'no active session id; pass --session-id or set presence via `peaks skill presence:set peaks-code`', null, ['Re-run with --session-id <sid>']), opts.json);
|
|
534
586
|
process.exitCode = 1;
|
|
535
587
|
return;
|
|
536
588
|
}
|
|
@@ -558,6 +610,180 @@ export function registerSoloCommands(program, io) {
|
|
|
558
610
|
process.exitCode = 1;
|
|
559
611
|
}
|
|
560
612
|
});
|
|
613
|
+
// v3.1.2 Step 0.8 — Mechanical PreToolUse gate.
|
|
614
|
+
// Wire-installed by `peaks workspace init` (extends the existing hook
|
|
615
|
+
// installer). Exit code is the load-bearing contract:
|
|
616
|
+
// exit 0 → allow (with structured stdout describing the decision)
|
|
617
|
+
// exit 2 → block (stderr contains the BLOCKED: ... reason)
|
|
618
|
+
addJsonOption(solo
|
|
619
|
+
.command('gate-step-08')
|
|
620
|
+
.description('v3.1.2: PreToolUse gate for Step 0.8 — allow when job-shape.json exists; ' +
|
|
621
|
+
'fail-closed backup regex when missing. Exit 0 = allow, exit 2 = block. ' +
|
|
622
|
+
'When the decision says isJob=true AND progress.json exists, the stdout ' +
|
|
623
|
+
'also carries `Next: slice #N+1 of M (<currentSlice>)` so the LLM cannot ' +
|
|
624
|
+
'wake up cold.')
|
|
625
|
+
.requiredOption('--project <path>', 'target project root (the hook passes "." so resolveCanonicalProjectRoot promotes it to the git root)')
|
|
626
|
+
.option('--session-id <sid>', 'override session id (default: read from active presence)')
|
|
627
|
+
.option('--prompt <text>', 'explicit prompt text (default: read last-prompt.txt; stdin ignored)')).action((opts) => {
|
|
628
|
+
try {
|
|
629
|
+
const sessionId = opts.sessionId ?? readActiveSid(opts.project);
|
|
630
|
+
if (sessionId === null) {
|
|
631
|
+
// No session binding — treat as allow (single-rid mode). The
|
|
632
|
+
// LLM has not yet anchored; we have nothing to gate against.
|
|
633
|
+
const envelope = ok('solo.gate-step-08', {
|
|
634
|
+
allow: true,
|
|
635
|
+
mode: 'no-session',
|
|
636
|
+
decision: null,
|
|
637
|
+
nextSlice: null
|
|
638
|
+
}, [], [
|
|
639
|
+
'No active session id; gate passes through (single-rid mode).'
|
|
640
|
+
]);
|
|
641
|
+
printResult(io, envelope, opts.json);
|
|
642
|
+
return;
|
|
643
|
+
}
|
|
644
|
+
const evalInput = {
|
|
645
|
+
projectRoot: opts.project,
|
|
646
|
+
sessionId
|
|
647
|
+
};
|
|
648
|
+
if (opts.prompt !== undefined)
|
|
649
|
+
evalInput.prompt = opts.prompt;
|
|
650
|
+
const result = evaluateStep08(evalInput);
|
|
651
|
+
const verdict = result.verdict;
|
|
652
|
+
if (verdict.kind === 'allow-job') {
|
|
653
|
+
const envelope = ok('solo.gate-step-08', {
|
|
654
|
+
allow: true,
|
|
655
|
+
mode: 'job',
|
|
656
|
+
decision: verdict.decision,
|
|
657
|
+
progress: verdict.progress,
|
|
658
|
+
nextSlice: result.nextSliceLine
|
|
659
|
+
}, [], result.nextSliceLine !== null ? [result.nextSliceLine] : []);
|
|
660
|
+
printResult(io, envelope, opts.json);
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
663
|
+
if (verdict.kind === 'allow-single') {
|
|
664
|
+
const envelope = ok('solo.gate-step-08', {
|
|
665
|
+
allow: true,
|
|
666
|
+
mode: 'single',
|
|
667
|
+
decision: null,
|
|
668
|
+
nextSlice: null
|
|
669
|
+
}, [], [
|
|
670
|
+
'job-shape.json says isJob=false; single-rid mode (gate allows).'
|
|
671
|
+
]);
|
|
672
|
+
printResult(io, envelope, opts.json);
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
675
|
+
// block-missing-decision
|
|
676
|
+
if (verdict.promptHit) {
|
|
677
|
+
// Block: backup regex hit. Exit code 2 is the load-bearing
|
|
678
|
+
// signal for the PreToolUse hook.
|
|
679
|
+
const blockMessage = 'BLOCKED: prompt looks Job-shaped but peaks solo detect-job has not been called. Run `peaks solo detect-job --is-job true ...` to record your Job-shape verdict, then retry.';
|
|
680
|
+
const envelope = fail('solo.gate-step-08', 'STEP_08_BLOCKED', blockMessage, {
|
|
681
|
+
promptSource: verdict.promptSource,
|
|
682
|
+
backupRegex: STEP_08_BACKUP_REGEX.toString()
|
|
683
|
+
}, [
|
|
684
|
+
'Run `peaks solo detect-job --is-job true --rationale <text> --suggested-job-id <slug>` to record the Job-shape verdict.',
|
|
685
|
+
'Then re-run the Bash tool call.'
|
|
686
|
+
]);
|
|
687
|
+
io.stderr(`${blockMessage}\n`);
|
|
688
|
+
printResult(io, envelope, opts.json);
|
|
689
|
+
process.exitCode = 2;
|
|
690
|
+
return;
|
|
691
|
+
}
|
|
692
|
+
// No decision + no regex hit → allow.
|
|
693
|
+
const envelope = ok('solo.gate-step-08', {
|
|
694
|
+
allow: true,
|
|
695
|
+
mode: 'undecided-no-regex-hit',
|
|
696
|
+
decision: null,
|
|
697
|
+
nextSlice: null,
|
|
698
|
+
promptSource: verdict.promptSource
|
|
699
|
+
}, [], [
|
|
700
|
+
'No job-shape.json AND no backup-regex match on prompt → allow (most prompts are not Job-shaped).'
|
|
701
|
+
]);
|
|
702
|
+
printResult(io, envelope, opts.json);
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
catch (err) {
|
|
706
|
+
printResult(io, fail('solo.gate-step-08', 'GATE_STEP_08_FAILED', getErrorMessage(err), null, [
|
|
707
|
+
'Verify the project path and try again'
|
|
708
|
+
]), opts.json);
|
|
709
|
+
process.exitCode = 1;
|
|
710
|
+
}
|
|
711
|
+
});
|
|
712
|
+
// v3.1.2 Step 11 / final handoff — Size-fear ban.
|
|
713
|
+
// Refuses to emit a final handoff while a Job has remaining slices.
|
|
714
|
+
addJsonOption(solo
|
|
715
|
+
.command('emit-handoff')
|
|
716
|
+
.description('v3.1.2 Step 11 size-fear ban: under Job mode, refuse to emit a final ' +
|
|
717
|
+
'handoff while remaining > 0. Exit 0 = allow, exit 1 = block. Pass ' +
|
|
718
|
+
'--force-under-job to override (requires explicit user approval).')
|
|
719
|
+
.requiredOption('--project <path>', 'target project root')
|
|
720
|
+
.option('--session-id <sid>', 'override session id (default: read from active presence)')
|
|
721
|
+
.option('--job-id <jid>', 'override job id (default: read from job-shape.json decision.suggestedJobId)')
|
|
722
|
+
.option('--force-under-job', 'override the remaining>0 block (explicit user approval required)')).action((opts) => {
|
|
723
|
+
try {
|
|
724
|
+
const sessionId = opts.sessionId ?? readActiveSid(opts.project);
|
|
725
|
+
if (sessionId === null) {
|
|
726
|
+
const envelope = ok('solo.emit-handoff', { allow: true, mode: 'no-session' }, [], [
|
|
727
|
+
'No active session id; gate passes through (single-rid mode).'
|
|
728
|
+
]);
|
|
729
|
+
printResult(io, envelope, opts.json);
|
|
730
|
+
return;
|
|
731
|
+
}
|
|
732
|
+
const evalInput = {
|
|
733
|
+
projectRoot: opts.project,
|
|
734
|
+
sessionId
|
|
735
|
+
};
|
|
736
|
+
if (opts.jobId !== undefined)
|
|
737
|
+
evalInput.jobId = opts.jobId;
|
|
738
|
+
if (opts.forceUnderJob === true)
|
|
739
|
+
evalInput.forceUnderJob = true;
|
|
740
|
+
const verdict = evaluateEmitHandoff(evalInput);
|
|
741
|
+
if (verdict.kind === 'allow-not-job') {
|
|
742
|
+
const envelope = ok('solo.emit-handoff', { allow: true, mode: 'single' }, [], [
|
|
743
|
+
'job-shape.json says isJob=false (or absent); normal handoff allowed.'
|
|
744
|
+
]);
|
|
745
|
+
printResult(io, envelope, opts.json);
|
|
746
|
+
return;
|
|
747
|
+
}
|
|
748
|
+
if (verdict.kind === 'allow-done') {
|
|
749
|
+
const envelope = ok('solo.emit-handoff', { allow: true, mode: 'job-done', remaining: verdict.remaining }, [], [
|
|
750
|
+
`Job is complete (remaining=0); handoff allowed.`
|
|
751
|
+
]);
|
|
752
|
+
printResult(io, envelope, opts.json);
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
755
|
+
if (verdict.kind === 'allow-force-override') {
|
|
756
|
+
const envelope = ok('solo.emit-handoff', { allow: true, mode: 'job-force-override', remaining: verdict.remaining }, [], [
|
|
757
|
+
`Job has ${verdict.remaining} remaining slices; --force-under-job override applied. Handoff allowed (explicit user approval).`
|
|
758
|
+
]);
|
|
759
|
+
printResult(io, envelope, opts.json);
|
|
760
|
+
return;
|
|
761
|
+
}
|
|
762
|
+
if (verdict.kind === 'block-not-initialized') {
|
|
763
|
+
const envelope = fail('solo.emit-handoff', JOB_NOT_INITIALIZED, `Job ${verdict.jobId} has no state.json; peaks job init was skipped.`, { jobId: verdict.jobId }, [`Run \`peaks job init --job-id ${verdict.jobId} --slice-list <...>\` before emitting handoff.`]);
|
|
764
|
+
printResult(io, envelope, opts.json);
|
|
765
|
+
process.exitCode = 1;
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
768
|
+
// block-remaining
|
|
769
|
+
const blockMessage = `BLOCKED: Job ${verdict.jobId} has ${verdict.remaining} remaining slices. Run \`peaks job status\`. Use --force-under-job only with explicit user approval.`;
|
|
770
|
+
const envelope = fail('solo.emit-handoff', JOB_REMAINING_BLOCKED, blockMessage, { jobId: verdict.jobId, remaining: verdict.remaining }, [
|
|
771
|
+
`Run \`peaks job status --job-id ${verdict.jobId}\` to see remaining slices.`,
|
|
772
|
+
'Resume Step 0.81 (per-slice checkpoint loop) and continue until remaining === 0.',
|
|
773
|
+
'Use --force-under-job only with explicit user approval (size-fear ban override).'
|
|
774
|
+
]);
|
|
775
|
+
io.stderr(`${blockMessage}\n`);
|
|
776
|
+
printResult(io, envelope, opts.json);
|
|
777
|
+
process.exitCode = 1;
|
|
778
|
+
return;
|
|
779
|
+
}
|
|
780
|
+
catch (err) {
|
|
781
|
+
printResult(io, fail('solo.emit-handoff', 'EMIT_HANDOFF_FAILED', getErrorMessage(err), null, [
|
|
782
|
+
'Verify the project path and try again'
|
|
783
|
+
]), opts.json);
|
|
784
|
+
process.exitCode = 1;
|
|
785
|
+
}
|
|
786
|
+
});
|
|
561
787
|
}
|
|
562
788
|
function readActiveSid(projectRoot) {
|
|
563
789
|
try {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* - `sub-agent-shared.ts` — shared types, constants, helpers
|
|
14
14
|
*
|
|
15
15
|
* Skill-first / CLI-auxiliary red line (PB-4 / AC-19/20):
|
|
16
|
-
* These commands are primitives that the peaks-
|
|
16
|
+
* These commands are primitives that the peaks-code / peaks-rd /
|
|
17
17
|
* peaks-qa SKILL.md compose. Users do NOT invoke them directly.
|
|
18
18
|
*/
|
|
19
19
|
import type { Command } from 'commander';
|
|
@@ -9,7 +9,7 @@ export function registerSubAgentCommands(program, io) {
|
|
|
9
9
|
const subAgent = program
|
|
10
10
|
.command('sub-agent')
|
|
11
11
|
.description('Sub-agent dispatch primitive (skill-first / CLI-auxiliary). ' +
|
|
12
|
-
'These commands are the primitives that peaks-
|
|
12
|
+
'These commands are the primitives that peaks-code / peaks-rd / ' +
|
|
13
13
|
'peaks-qa SKILL.md compose. Users do not invoke this directly.');
|
|
14
14
|
registerDispatchCommand(subAgent, io);
|
|
15
15
|
registerHeartbeatCommand(subAgent, io);
|
|
@@ -77,7 +77,7 @@ export function registerUnderstandCommands(program, io) {
|
|
|
77
77
|
}
|
|
78
78
|
});
|
|
79
79
|
// L3.1: opt-in UX subcommand. Returns the AskUserQuestion payload that
|
|
80
|
-
// the LLM-side UX layer (peaks-
|
|
80
|
+
// the LLM-side UX layer (peaks-code / peaks-ide) should surface when
|
|
81
81
|
// uaPrompt === 'unset' and UA is absent. When uaPrompt is skip-this-session
|
|
82
82
|
// or skip-forever, returns a no-op envelope (caller does not prompt).
|
|
83
83
|
addJsonOption(understand
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* hooks-install / skill-sync / audit-verify + write-upgrade-record.
|
|
14
14
|
*
|
|
15
15
|
* The `--detect-1x` flag (added in slice 3) is a read-only
|
|
16
|
-
* probe that the peaks-
|
|
16
|
+
* probe that the peaks-code skill calls to gate the
|
|
17
17
|
* AskUserQuestion that prompts the 1.x → 2.0 upgrade. The
|
|
18
18
|
* probe returns the JSON envelope from the
|
|
19
19
|
* 1x-detector-service; it does NOT modify any files.
|
|
@@ -8,11 +8,11 @@ import { fail, ok } from '../../shared/result.js';
|
|
|
8
8
|
export function registerUpgradeCommands(program, io) {
|
|
9
9
|
addJsonOption(program
|
|
10
10
|
.command('upgrade')
|
|
11
|
-
.description('Upgrade a peaks-loop 1.x project to 2.0. Umbrella that orquestrates 7 sub-commands: config-migrate / standards-migrate / memory-extract / hooks-install / skill-sync / audit-verify + write-upgrade-record. Per the "one-key completion" tenet, prefer letting `npm i -g peaks-loop@2.0` postinstall run this for you. Use `--detect-1x` for a read-only probe (no file writes) that the peaks-
|
|
11
|
+
.description('Upgrade a peaks-loop 1.x project to 2.0. Umbrella that orquestrates 7 sub-commands: config-migrate / standards-migrate / memory-extract / hooks-install / skill-sync / audit-verify + write-upgrade-record. Per the "one-key completion" tenet, prefer letting `npm i -g peaks-loop@2.0` postinstall run this for you. Use `--detect-1x` for a read-only probe (no file writes) that the peaks-code skill uses to gate the 1.x → 2.0 AskUserQuestion.')
|
|
12
12
|
.option('--to <version>', 'target version (only "2.0" supported)', '2.0')
|
|
13
13
|
.option('--project <path>', 'project root to upgrade (default: cwd)')
|
|
14
14
|
.option('--auto', 'non-interactive: accept soft-fail on any sub-step (used by the postinstall hook)')
|
|
15
|
-
.option('--detect-1x', 'read-only probe: returns the 1.x state as JSON (no file writes); consumed by peaks-
|
|
15
|
+
.option('--detect-1x', 'read-only probe: returns the 1.x state as JSON (no file writes); consumed by peaks-code Step 0.55 to gate the AskUserQuestion')
|
|
16
16
|
.option('--apply-init', 'slice 4 (slice 2026-06-13-selfheal-claude-settings-template): run initWorkspace so the drift-driven self-heal fires on the consumer-project .claude/settings.local.json and the offline .peaks/.claude-settings-template.json. Idempotent. Use after a peaks-loop version bump if you do not otherwise re-run init. Mutually exclusive with --detect-1x.')).action(async (options) => {
|
|
17
17
|
const projectRoot = options.project ?? process.cwd();
|
|
18
18
|
// Branch 1: --detect-1x (read-only probe)
|
|
@@ -21,7 +21,7 @@ export function registerUpgradeCommands(program, io) {
|
|
|
21
21
|
const state = detect1xProjectState(projectRoot);
|
|
22
22
|
const nextActions = [];
|
|
23
23
|
if (state.isOneX) {
|
|
24
|
-
nextActions.push(`Detected 1.x state. peaks-
|
|
24
|
+
nextActions.push(`Detected 1.x state. peaks-code Step 0.55 should present an AskUserQuestion to invoke \`peaks upgrade --to 2.0 --auto --project ${state.projectRoot ?? projectRoot}\`.`);
|
|
25
25
|
}
|
|
26
26
|
else {
|
|
27
27
|
nextActions.push('No 1.x state detected. Proceed with the standing 2.0 layout.');
|
|
@@ -23,7 +23,7 @@ export function registerUserTouchpointCommands(program, io) {
|
|
|
23
23
|
// user-touchpoints / commit-boundary-actions.
|
|
24
24
|
//
|
|
25
25
|
// We do NOT create a new `peaks solo` CLI command here because that
|
|
26
|
-
// would conflict with the peaks-
|
|
26
|
+
// would conflict with the peaks-code skill presence tracking (see
|
|
27
27
|
// `src/services/skills/skill-presence-service.ts`).
|
|
28
28
|
addJsonOption(program
|
|
29
29
|
.command('gate-classify')
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Reads the 5 envelope sources under `.peaks/_runtime/<sid>/` for a
|
|
5
5
|
* given rid, runs `aggregateVerdict()`, and prints the verdict +
|
|
6
|
-
* reasons JSON envelope. Used by peaks-
|
|
6
|
+
* reasons JSON envelope. Used by peaks-code / peaks-final-review to
|
|
7
7
|
* cross-check the slice-level verdict without booting the full
|
|
8
8
|
* 5-skill fanout.
|
|
9
9
|
*
|
|
@@ -10,10 +10,10 @@ const KARPATHY_REL = 'rd/karpathy-review.md';
|
|
|
10
10
|
const MUT_REL = 'mut/mut-report.json';
|
|
11
11
|
const QA_REL = 'qa/test-reports';
|
|
12
12
|
export function registerVerdictAggregateCommands(program, io) {
|
|
13
|
-
const verdict = program.command('verdict').description('Aggregate the 5 envelope sources feeding peaks-
|
|
13
|
+
const verdict = program.command('verdict').description('Aggregate the 5 envelope sources feeding peaks-code verdict logic');
|
|
14
14
|
addJsonOption(verdict
|
|
15
15
|
.command('aggregate')
|
|
16
|
-
.description('Aggregate 5 envelope sources (security / perf / karpathy / mut / qa) and print the verdict + reasons JSON envelope. Used by peaks-
|
|
16
|
+
.description('Aggregate 5 envelope sources (security / perf / karpathy / mut / qa) and print the verdict + reasons JSON envelope. Used by peaks-code and peaks-final-review.')
|
|
17
17
|
.requiredOption('--from-rid <rid>', 'request id, e.g. 2026-06-27-...')
|
|
18
18
|
.option('--sid <sid>', 'session id, e.g. 2026-06-27-session-...; default: project default')
|
|
19
19
|
.option('--project <path>', 'project root (default: cwd)')).action(async (options) => {
|
|
@@ -330,7 +330,7 @@ function addAutonomousResumeInitOptions(command) {
|
|
|
330
330
|
export function registerWorkflowCommands(program, io) {
|
|
331
331
|
const refactor = program.command('refactor').description('Plan a Peaks refactor run without modifying code');
|
|
332
332
|
addJsonOption(refactor
|
|
333
|
-
.option('--solo', 'use peaks-
|
|
333
|
+
.option('--solo', 'use peaks-code orchestration mode')
|
|
334
334
|
.option('--rd', 'use peaks-rd direct mode')
|
|
335
335
|
.option('--dry-run', 'print gates and required artifacts', true)
|
|
336
336
|
.option('--no-dry-run', 'unsupported: do not modify code from this command')).action((options) => {
|
|
@@ -410,7 +410,7 @@ export function registerWorkflowCommands(program, io) {
|
|
|
410
410
|
// because we read, not write, the binding.
|
|
411
411
|
const sessionId = getSessionId(options.project);
|
|
412
412
|
if (sessionId === null) {
|
|
413
|
-
printResult(io, fail('workflow.skip', 'NO_ACTIVE_SESSION', `project "${options.project}" has no peaks-
|
|
413
|
+
printResult(io, fail('workflow.skip', 'NO_ACTIVE_SESSION', `project "${options.project}" has no peaks-code session binding; run \`peaks workspace init --project ${options.project} --json\` first`, { applied: false }, [`peaks workspace init --project ${options.project} --json`]), options.json);
|
|
414
414
|
process.exitCode = 1;
|
|
415
415
|
return;
|
|
416
416
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `peaks workspace init` — slice 006 + 007 + 014 + 018 + 2026-06-16-peaks-
|
|
2
|
+
* `peaks workspace init` — slice 006 + 007 + 014 + 018 + 2026-06-16-peaks-code-auto-scaffold.
|
|
3
3
|
*
|
|
4
4
|
* Extracted from `src/cli/commands/workspace-commands.ts` (slice
|
|
5
5
|
* 2026-06-16-workspace-commands-split) to keep that entry file under the
|
|
@@ -45,11 +45,11 @@ export type WorkspaceInitOptions = {
|
|
|
45
45
|
* (commander `--no-` prefix) is `true`; pass `--no-claude-hooks` to
|
|
46
46
|
* set this to `false`. The wrapper reads this as `=== false` to
|
|
47
47
|
* skip the materialization. The bypass is documented in
|
|
48
|
-
* `peaks-
|
|
48
|
+
* `peaks-code/references/anchoring-and-session-info.md`.
|
|
49
49
|
*/
|
|
50
50
|
claudeHooks?: boolean;
|
|
51
51
|
/**
|
|
52
|
-
* Slice 2026-06-16-peaks-
|
|
52
|
+
* Slice 2026-06-16-peaks-code-auto-scaffold (RD#7): opt-in flag to
|
|
53
53
|
* auto-scaffold `.claude/rules/{common,<language>}/` when missing.
|
|
54
54
|
* Default `false` — the diagnostic fires but no write happens.
|
|
55
55
|
* Set to `true` (via `--init-standards`) to also run
|