peaks-cli 1.4.1 → 2.0.0
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 +51 -0
- package/CHANGELOG.md +238 -0
- package/README-en.md +226 -0
- package/README.md +142 -165
- package/dist/src/cli/commands/agent-commands.d.ts +20 -0
- package/dist/src/cli/commands/agent-commands.js +48 -0
- package/dist/src/cli/commands/audit-commands.d.ts +18 -0
- package/dist/src/cli/commands/audit-commands.js +138 -0
- package/dist/src/cli/commands/classify-classify-commands.d.ts +19 -0
- package/dist/src/cli/commands/classify-classify-commands.js +151 -0
- package/dist/src/cli/commands/code-review-commands.d.ts +34 -0
- package/dist/src/cli/commands/code-review-commands.js +83 -0
- package/dist/src/cli/commands/config-commands.js +90 -0
- package/dist/src/cli/commands/context-commands.d.ts +21 -0
- package/dist/src/cli/commands/context-commands.js +167 -0
- package/dist/src/cli/commands/core-artifact-commands.js +81 -2
- package/dist/src/cli/commands/hook-handle.js +50 -0
- package/dist/src/cli/commands/loop-commands.d.ts +21 -0
- package/dist/src/cli/commands/loop-commands.js +128 -0
- package/dist/src/cli/commands/memory-commands.d.ts +13 -0
- package/dist/src/cli/commands/memory-commands.js +60 -0
- package/dist/src/cli/commands/openspec-commands.js +37 -0
- package/dist/src/cli/commands/preferences-commands.d.ts +2 -0
- package/dist/src/cli/commands/preferences-commands.js +147 -0
- package/dist/src/cli/commands/retrospective-commands.d.ts +9 -0
- package/dist/src/cli/commands/retrospective-commands.js +58 -0
- package/dist/src/cli/commands/skill-conformance-commands.d.ts +9 -0
- package/dist/src/cli/commands/skill-conformance-commands.js +39 -0
- package/dist/src/cli/commands/understand-commands.js +34 -0
- package/dist/src/cli/commands/upgrade-commands.d.ts +23 -0
- package/dist/src/cli/commands/upgrade-commands.js +57 -0
- package/dist/src/cli/commands/workflow-commands.js +70 -0
- package/dist/src/cli/commands/workspace-commands.js +86 -0
- package/dist/src/cli/program.js +46 -22
- package/dist/src/services/agent/ecc-agent-service.d.ts +47 -0
- package/dist/src/services/agent/ecc-agent-service.js +143 -0
- package/dist/src/services/artifacts/request-artifact-service.js +14 -0
- package/dist/src/services/audit/backing-detector.d.ts +24 -0
- package/dist/src/services/audit/backing-detector.js +59 -0
- package/dist/src/services/audit/classifier.d.ts +38 -0
- package/dist/src/services/audit/classifier.js +127 -0
- package/dist/src/services/audit/enforcers/active-skill-resolver.d.ts +29 -0
- package/dist/src/services/audit/enforcers/active-skill-resolver.js +71 -0
- package/dist/src/services/audit/enforcers/design-draft-confirm.d.ts +25 -0
- package/dist/src/services/audit/enforcers/design-draft-confirm.js +54 -0
- package/dist/src/services/audit/enforcers/lint-audit-regression.d.ts +21 -0
- package/dist/src/services/audit/enforcers/lint-audit-regression.js +86 -0
- package/dist/src/services/audit/enforcers/lint-catalog-governance.d.ts +27 -0
- package/dist/src/services/audit/enforcers/lint-catalog-governance.js +38 -0
- package/dist/src/services/audit/enforcers/lint-cli-back.d.ts +16 -0
- package/dist/src/services/audit/enforcers/lint-cli-back.js +35 -0
- package/dist/src/services/audit/enforcers/lint-output-style.d.ts +11 -0
- package/dist/src/services/audit/enforcers/lint-output-style.js +94 -0
- package/dist/src/services/audit/enforcers/lint-reference-integrity.d.ts +6 -0
- package/dist/src/services/audit/enforcers/lint-reference-integrity.js +83 -0
- package/dist/src/services/audit/enforcers/lint-reference-shape.d.ts +30 -0
- package/dist/src/services/audit/enforcers/lint-reference-shape.js +272 -0
- package/dist/src/services/audit/enforcers/lint-style.d.ts +49 -0
- package/dist/src/services/audit/enforcers/lint-style.js +173 -0
- package/dist/src/services/audit/enforcers/lint-workflow-shape.d.ts +5 -0
- package/dist/src/services/audit/enforcers/lint-workflow-shape.js +141 -0
- package/dist/src/services/audit/enforcers/login-gate.d.ts +23 -0
- package/dist/src/services/audit/enforcers/login-gate.js +40 -0
- package/dist/src/services/audit/enforcers/mock-placement.d.ts +25 -0
- package/dist/src/services/audit/enforcers/mock-placement.js +48 -0
- package/dist/src/services/audit/enforcers/no-root-pollution.d.ts +21 -0
- package/dist/src/services/audit/enforcers/no-root-pollution.js +56 -0
- package/dist/src/services/audit/enforcers/pre-rd-scan.d.ts +22 -0
- package/dist/src/services/audit/enforcers/pre-rd-scan.js +23 -0
- package/dist/src/services/audit/enforcers/prototype-fidelity.d.ts +25 -0
- package/dist/src/services/audit/enforcers/prototype-fidelity.js +75 -0
- package/dist/src/services/audit/enforcers/resume-detection.d.ts +21 -0
- package/dist/src/services/audit/enforcers/resume-detection.js +52 -0
- package/dist/src/services/audit/enforcers/solo-code-ban.d.ts +23 -0
- package/dist/src/services/audit/enforcers/solo-code-ban.js +27 -0
- package/dist/src/services/audit/enforcers/sub-agent-sid.d.ts +25 -0
- package/dist/src/services/audit/enforcers/sub-agent-sid.js +63 -0
- package/dist/src/services/audit/enforcers/tech-doc-presence.d.ts +28 -0
- package/dist/src/services/audit/enforcers/tech-doc-presence.js +35 -0
- package/dist/src/services/audit/red-line-catalog-p2-a.d.ts +21 -0
- package/dist/src/services/audit/red-line-catalog-p2-a.js +233 -0
- package/dist/src/services/audit/red-line-catalog-p2-b.d.ts +19 -0
- package/dist/src/services/audit/red-line-catalog-p2-b.js +225 -0
- package/dist/src/services/audit/red-line-catalog.d.ts +51 -0
- package/dist/src/services/audit/red-line-catalog.js +210 -0
- package/dist/src/services/audit/red-lines-service.d.ts +23 -0
- package/dist/src/services/audit/red-lines-service.js +486 -0
- package/dist/src/services/audit/scanners/openspec-scanner.d.ts +15 -0
- package/dist/src/services/audit/scanners/openspec-scanner.js +55 -0
- package/dist/src/services/audit/scanners/rules-tree-scanner.d.ts +16 -0
- package/dist/src/services/audit/scanners/rules-tree-scanner.js +56 -0
- package/dist/src/services/audit/scanners/skills-tree-scanner.d.ts +17 -0
- package/dist/src/services/audit/scanners/skills-tree-scanner.js +46 -0
- package/dist/src/services/audit/static-service.d.ts +57 -0
- package/dist/src/services/audit/static-service.js +125 -0
- package/dist/src/services/audit/types.d.ts +69 -0
- package/dist/src/services/audit/types.js +13 -0
- package/dist/src/services/classify/classify-service.d.ts +42 -0
- package/dist/src/services/classify/classify-service.js +122 -0
- package/dist/src/services/classify/classify-types.d.ts +79 -0
- package/dist/src/services/classify/classify-types.js +90 -0
- package/dist/src/services/code-review/ocr-service.d.ts +129 -0
- package/dist/src/services/code-review/ocr-service.js +362 -0
- package/dist/src/services/config/config-migration.d.ts +32 -0
- package/dist/src/services/config/config-migration.js +92 -0
- package/dist/src/services/config/config-restore.d.ts +10 -0
- package/dist/src/services/config/config-restore.js +47 -0
- package/dist/src/services/config/config-rollback.d.ts +13 -0
- package/dist/src/services/config/config-rollback.js +26 -0
- package/dist/src/services/config/config-service.d.ts +35 -2
- package/dist/src/services/config/config-service.js +81 -0
- package/dist/src/services/config/config-types.d.ts +58 -0
- package/dist/src/services/config/config-types.js +6 -0
- package/dist/src/services/doctor/doctor-service.js +96 -0
- package/dist/src/services/fuzzy-matching/fuzzy-match-service.d.ts +15 -0
- package/dist/src/services/fuzzy-matching/fuzzy-match-service.js +56 -0
- package/dist/src/services/fuzzy-matching/types.d.ts +20 -0
- package/dist/src/services/fuzzy-matching/types.js +1 -0
- package/dist/src/services/ide/adapters/hermes-adapter.d.ts +21 -0
- package/dist/src/services/ide/adapters/hermes-adapter.js +51 -0
- package/dist/src/services/ide/adapters/openclaw-adapter.d.ts +14 -0
- package/dist/src/services/ide/adapters/openclaw-adapter.js +42 -0
- package/dist/src/services/ide/ide-registry.js +7 -0
- package/dist/src/services/ide/ide-types.d.ts +1 -1
- package/dist/src/services/memory/memory-search-service.d.ts +61 -0
- package/dist/src/services/memory/memory-search-service.js +80 -0
- package/dist/src/services/openspec/openspec-propose-from-doctor-service.d.ts +31 -0
- package/dist/src/services/openspec/openspec-propose-from-doctor-service.js +95 -0
- package/dist/src/services/preferences/preferences-service.d.ts +6 -0
- package/dist/src/services/preferences/preferences-service.js +43 -0
- package/dist/src/services/preferences/preferences-types.d.ts +90 -0
- package/dist/src/services/preferences/preferences-types.js +38 -0
- package/dist/src/services/recommendations/capability-seed-items.js +0 -1
- package/dist/src/services/recommendations/capability-seed-mappings.js +0 -1
- package/dist/src/services/recommendations/capability-seed-sources.js +0 -1
- package/dist/src/services/retrospective/retrospective-search-service.d.ts +37 -0
- package/dist/src/services/retrospective/retrospective-search-service.js +75 -0
- package/dist/src/services/skills/skill-conformance-service.d.ts +40 -0
- package/dist/src/services/skills/skill-conformance-service.js +136 -0
- package/dist/src/services/skills/skill-runbook-service.js +44 -10
- package/dist/src/services/skills/sync-service.d.ts +43 -0
- package/dist/src/services/skills/sync-service.js +99 -0
- package/dist/src/services/slice/slice-check-service.js +166 -13
- package/dist/src/services/slice/slice-check-types.d.ts +1 -1
- package/dist/src/services/standards/migrate-claude-rules-service.d.ts +19 -0
- package/dist/src/services/standards/migrate-claude-rules-service.js +193 -0
- package/dist/src/services/standards/project-context.d.ts +1 -1
- package/dist/src/services/standards/project-context.js +0 -4
- package/dist/src/services/standards/project-standards-service.js +1 -3
- package/dist/src/services/understand/understand-scan-service.js +15 -2
- package/dist/src/services/understand/understand-types.d.ts +26 -0
- package/dist/src/services/upgrade/1x-detector-service.d.ts +7 -0
- package/dist/src/services/upgrade/1x-detector-service.js +94 -0
- package/dist/src/services/upgrade/gitignore-migrate-service.d.ts +56 -0
- package/dist/src/services/upgrade/gitignore-migrate-service.js +170 -0
- package/dist/src/services/upgrade/upgrade-service.d.ts +47 -0
- package/dist/src/services/upgrade/upgrade-service.js +381 -0
- package/dist/src/services/workspace/migrate-1-4-1-service.js +1 -1
- package/dist/src/services/workspace/sid-naming-guard.d.ts +14 -0
- package/dist/src/services/workspace/sid-naming-guard.js +31 -0
- package/dist/src/services/workspace/workspace-archive-service.d.ts +19 -0
- package/dist/src/services/workspace/workspace-archive-service.js +32 -0
- package/dist/src/services/workspace/workspace-clean-service.d.ts +41 -0
- package/dist/src/services/workspace/workspace-clean-service.js +86 -0
- package/dist/src/services/workspace/workspace-state-service.d.ts +7 -0
- package/dist/src/services/workspace/workspace-state-service.js +43 -0
- package/dist/src/shared/change-id.js +4 -1
- package/dist/src/shared/version.d.ts +1 -1
- package/dist/src/shared/version.js +1 -1
- package/package.json +10 -8
- package/schemas/doctor-report.schema.json +1 -1
- package/scripts/install-skills.mjs +296 -12
- package/skills/peaks-doctor/SKILL.md +59 -0
- package/skills/peaks-doctor/references/doctor-check-catalog.md +31 -0
- package/skills/peaks-doctor/references/from-doctor-flow.md +64 -0
- package/skills/peaks-doctor/test_prompts.json +17 -0
- package/skills/peaks-ide/SKILL.md +2 -0
- package/skills/peaks-qa/SKILL.md +9 -7
- package/skills/peaks-qa/references/artifact-per-request.md +19 -5
- package/skills/peaks-qa/references/qa-perf-test-plan.md +6 -6
- package/skills/peaks-qa/references/qa-runbook.md +1 -1
- package/skills/peaks-rd/SKILL.md +25 -10
- package/skills/peaks-rd/references/ocr-integration.md +214 -0
- package/skills/peaks-rd/references/rd-fanout-contracts.md +70 -0
- package/skills/peaks-rd/references/rd-runbook.md +1 -1
- package/skills/peaks-solo/SKILL.md +11 -5
- package/skills/peaks-solo/references/completion-handoff.md +3 -1
- package/skills/peaks-solo/references/step-0-55-1x-detection.md +82 -0
- package/skills/peaks-solo/references/workflow-gates-and-types.md +9 -0
- package/dist/src/cli/commands/shadcn-commands.d.ts +0 -3
- package/dist/src/cli/commands/shadcn-commands.js +0 -35
- package/dist/src/cli/commands/skill-context-stats-command.d.ts +0 -40
- package/dist/src/cli/commands/skill-context-stats-command.js +0 -96
- package/dist/src/cli/commands/skill-scope-commands.d.ts +0 -51
- package/dist/src/cli/commands/skill-scope-commands.js +0 -310
- package/dist/src/services/shadcn/shadcn-service.d.ts +0 -27
- package/dist/src/services/shadcn/shadcn-service.js +0 -128
- package/dist/src/services/skill-scope/adapters/_stub-helper.d.ts +0 -39
- package/dist/src/services/skill-scope/adapters/_stub-helper.js +0 -98
- package/dist/src/services/skill-scope/adapters/claude-code.d.ts +0 -59
- package/dist/src/services/skill-scope/adapters/claude-code.js +0 -304
- package/dist/src/services/skill-scope/adapters/codex.d.ts +0 -2
- package/dist/src/services/skill-scope/adapters/codex.js +0 -12
- package/dist/src/services/skill-scope/adapters/cursor.d.ts +0 -2
- package/dist/src/services/skill-scope/adapters/cursor.js +0 -13
- package/dist/src/services/skill-scope/adapters/qoder.d.ts +0 -2
- package/dist/src/services/skill-scope/adapters/qoder.js +0 -13
- package/dist/src/services/skill-scope/adapters/tongyi.d.ts +0 -2
- package/dist/src/services/skill-scope/adapters/tongyi.js +0 -13
- package/dist/src/services/skill-scope/adapters/trae.d.ts +0 -2
- package/dist/src/services/skill-scope/adapters/trae.js +0 -12
- package/dist/src/services/skill-scope/detect.d.ts +0 -81
- package/dist/src/services/skill-scope/detect.js +0 -513
- package/dist/src/services/skill-scope/registry.d.ts +0 -41
- package/dist/src/services/skill-scope/registry.js +0 -83
- package/dist/src/services/skill-scope/source-of-truth.d.ts +0 -44
- package/dist/src/services/skill-scope/source-of-truth.js +0 -118
- package/dist/src/services/skill-scope/types.d.ts +0 -195
- package/dist/src/services/skill-scope/types.js +0 -97
|
@@ -3,8 +3,50 @@ import { resolveCanonicalProjectRoot } from '../../services/config/config-servic
|
|
|
3
3
|
import { loadRetrospectiveIndex } from '../../services/retrospective/retrospective-index.js';
|
|
4
4
|
import { showRetrospective } from '../../services/retrospective/retrospective-show.js';
|
|
5
5
|
import { migrateRetrospectiveFromMd } from '../../services/retrospective/migrate-from-md.js';
|
|
6
|
+
import { searchRetrospective } from '../../services/retrospective/retrospective-search-service.js';
|
|
6
7
|
import { fail, ok } from '../../shared/result.js';
|
|
7
8
|
import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
|
|
9
|
+
const VALID_RETRO_TYPES = ['refactor', 'feature', 'bugfix', 'config', 'docs', 'chore'];
|
|
10
|
+
const VALID_RETRO_OUTCOMES = ['shipped', 'blocked', 'in-flight', 'cancelled'];
|
|
11
|
+
export function runRetrospectiveSearch(io, options) {
|
|
12
|
+
const projectRoot = options.project !== undefined
|
|
13
|
+
? resolveCanonicalProjectRoot(options.project)
|
|
14
|
+
: (findProjectRoot(process.cwd()) ?? process.cwd());
|
|
15
|
+
const typeFilter = options.type !== undefined && VALID_RETRO_TYPES.includes(options.type)
|
|
16
|
+
? options.type
|
|
17
|
+
: undefined;
|
|
18
|
+
const outcomeFilter = options.outcome !== undefined && VALID_RETRO_OUTCOMES.includes(options.outcome)
|
|
19
|
+
? options.outcome
|
|
20
|
+
: undefined;
|
|
21
|
+
try {
|
|
22
|
+
const matches = searchRetrospective({
|
|
23
|
+
query: options.query,
|
|
24
|
+
projectRoot,
|
|
25
|
+
...(typeFilter !== undefined ? { type: typeFilter } : {}),
|
|
26
|
+
...(outcomeFilter !== undefined ? { outcome: outcomeFilter } : {}),
|
|
27
|
+
...(options.limit !== undefined ? { limit: options.limit } : {}),
|
|
28
|
+
});
|
|
29
|
+
printResult(io, ok('retrospective.search', {
|
|
30
|
+
query: options.query,
|
|
31
|
+
total: matches.length,
|
|
32
|
+
matches,
|
|
33
|
+
warnings: [],
|
|
34
|
+
}, []), options.json);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
const message = getErrorMessage(error);
|
|
38
|
+
const code = error.code ?? 'RETROSPECTIVE_SEARCH_FAILED';
|
|
39
|
+
const suggestions = [];
|
|
40
|
+
if (code === 'INDEX_MISSING') {
|
|
41
|
+
suggestions.push('Run `peaks retrospective migrate --apply` to build the index from legacy MDs');
|
|
42
|
+
}
|
|
43
|
+
if (code === 'EMPTY_QUERY') {
|
|
44
|
+
suggestions.push('Use `peaks retrospective index` to list all entries');
|
|
45
|
+
}
|
|
46
|
+
printResult(io, fail('retrospective.search', code, message, { projectRoot, query: options.query }, suggestions), options.json);
|
|
47
|
+
process.exitCode = 1;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
8
50
|
export function registerRetrospectiveCommands(program, io) {
|
|
9
51
|
const retrospective = program.command('retrospective').description('Read the peaks retrospective index (R3: index.json, not the legacy <id>/ MD tree)');
|
|
10
52
|
addJsonOption(retrospective
|
|
@@ -110,4 +152,20 @@ export function registerRetrospectiveCommands(program, io) {
|
|
|
110
152
|
process.exitCode = 1;
|
|
111
153
|
}
|
|
112
154
|
});
|
|
155
|
+
addJsonOption(retrospective
|
|
156
|
+
.command('search <query>')
|
|
157
|
+
.description('Fuzzy-search the retrospective index (deterministic, local, zero-token). Default --limit 6.')
|
|
158
|
+
.option('--type <type>', `filter by retrospective type (one of: ${VALID_RETRO_TYPES.join(', ')})`)
|
|
159
|
+
.option('--outcome <outcome>', `filter by retrospective outcome (one of: ${VALID_RETRO_OUTCOMES.join(', ')})`)
|
|
160
|
+
.option('--limit <n>', 'maximum number of matches to return', (value) => Number(value))
|
|
161
|
+
.option('--project <path>', 'target project root (defaults to git root or cwd)')).action((query, options) => {
|
|
162
|
+
runRetrospectiveSearch(io, {
|
|
163
|
+
query,
|
|
164
|
+
...(options.type !== undefined ? { type: options.type } : {}),
|
|
165
|
+
...(options.outcome !== undefined ? { outcome: options.outcome } : {}),
|
|
166
|
+
...(options.limit !== undefined ? { limit: options.limit } : {}),
|
|
167
|
+
...(options.project !== undefined ? { project: options.project } : {}),
|
|
168
|
+
...(options.json !== undefined ? { json: options.json } : {}),
|
|
169
|
+
});
|
|
170
|
+
});
|
|
113
171
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* peaks skills audit-conformance CLI (Slice #12) — runs the
|
|
3
|
+
* skill-conformance-service against all 12 peaks-* SKILL.md files and
|
|
4
|
+
* reports the 5 standard checks (frontmatter, CLI-back, loadStrategy,
|
|
5
|
+
* 800-line cap, outputStyle).
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from 'commander';
|
|
8
|
+
import { type ProgramIO } from '../cli-helpers.js';
|
|
9
|
+
export declare function registerSkillConformanceCommands(program: Command, io: ProgramIO): void;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* peaks skills audit-conformance CLI (Slice #12) — runs the
|
|
3
|
+
* skill-conformance-service against all 12 peaks-* SKILL.md files and
|
|
4
|
+
* reports the 5 standard checks (frontmatter, CLI-back, loadStrategy,
|
|
5
|
+
* 800-line cap, outputStyle).
|
|
6
|
+
*/
|
|
7
|
+
import { auditSkillConformance } from '../../services/skills/skill-conformance-service.js';
|
|
8
|
+
import { getErrorMessage, printResult } from '../cli-helpers.js';
|
|
9
|
+
import { fail, ok } from '../../shared/result.js';
|
|
10
|
+
export function registerSkillConformanceCommands(program, io) {
|
|
11
|
+
program
|
|
12
|
+
.command('skills:audit-conformance')
|
|
13
|
+
.description('Slice #12: audit all 12 peaks-* SKILL.md against the 5 alignment standards')
|
|
14
|
+
.requiredOption('--project <path>', 'target project root')
|
|
15
|
+
.option('--json', 'print machine-readable JSON envelope')
|
|
16
|
+
.action(async (options) => {
|
|
17
|
+
try {
|
|
18
|
+
const report = auditSkillConformance({ projectRoot: options.project });
|
|
19
|
+
const nextActions = [];
|
|
20
|
+
if (report.failed > 0) {
|
|
21
|
+
nextActions.push(`${report.failed} hard failure(s); fix before shipping.`);
|
|
22
|
+
for (const c of report.checks.filter((c) => c.level === 'fail')) {
|
|
23
|
+
nextActions.push(` - ${c.skill}: ${c.id} — ${c.message}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (report.warned > 0) {
|
|
27
|
+
nextActions.push(`${report.warned} advisory warning(s); see envelope.checks for details.`);
|
|
28
|
+
}
|
|
29
|
+
if (report.failed === 0 && report.warned === 0) {
|
|
30
|
+
nextActions.push('All 13 skills pass the 5 alignment standards.');
|
|
31
|
+
}
|
|
32
|
+
printResult(io, ok('skills.audit-conformance', report, [], nextActions), options.json);
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
printResult(io, fail('skills.audit-conformance', 'AUDIT_CONFORMANCE_FAILED', getErrorMessage(error), { projectRoot: options.project }, ['Verify the project path']), options.json);
|
|
36
|
+
process.exitCode = 1;
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
@@ -75,4 +75,38 @@ export function registerUnderstandCommands(program, io) {
|
|
|
75
75
|
process.exitCode = 1;
|
|
76
76
|
}
|
|
77
77
|
});
|
|
78
|
+
// L3.1: opt-in UX subcommand. Returns the AskUserQuestion payload that
|
|
79
|
+
// the LLM-side UX layer (peaks-solo / peaks-ide) should surface when
|
|
80
|
+
// uaPrompt === 'unset' and UA is absent. When uaPrompt is skip-this-session
|
|
81
|
+
// or skip-forever, returns a no-op envelope (caller does not prompt).
|
|
82
|
+
addJsonOption(understand
|
|
83
|
+
.command('opt-in')
|
|
84
|
+
.description('Returns the UA opt-in prompt payload (Slice L3.1) when uaPrompt is unset; no-op otherwise')
|
|
85
|
+
.requiredOption('--project <path>', 'target project root')).action(async (options) => {
|
|
86
|
+
try {
|
|
87
|
+
const report = await scanUnderstandAnything({ projectRoot: options.project });
|
|
88
|
+
const uaPrompt = report.uaPrompt ?? 'unset';
|
|
89
|
+
if (report.exists || uaPrompt !== 'unset') {
|
|
90
|
+
// No prompt needed: UA is installed OR user already decided.
|
|
91
|
+
printResult(io, ok('understand.opt-in', { promptNeeded: false, uaPrompt, uaInstalled: report.exists }), options.json);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const prompt = {
|
|
95
|
+
version: 1,
|
|
96
|
+
tool: 'ua-opt-in',
|
|
97
|
+
artifactDir: report.artifactDir,
|
|
98
|
+
reason: 'ua-artifact-missing',
|
|
99
|
+
options: [
|
|
100
|
+
{ id: 'install', label: 'Install UA in Claude Code', description: INSTALL_HINT },
|
|
101
|
+
{ id: 'fallback-this-session', label: 'Use codegraph fallback this session', description: 'Skip UA this run; do not write preferences.json' },
|
|
102
|
+
{ id: 'fallback-forever', label: 'Use codegraph fallback forever', description: 'Write preferences.json:uaPrompt=skip-forever; suppress future prompts' }
|
|
103
|
+
]
|
|
104
|
+
};
|
|
105
|
+
printResult(io, ok('understand.opt-in', { promptNeeded: true, uaPrompt, uaInstalled: false, prompt }), options.json);
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
printResult(io, fail('understand.opt-in', 'UNDERSTAND_OPTIN_FAILED', getErrorMessage(error), { projectRoot: options.project }, ['Check the project path']), options.json);
|
|
109
|
+
process.exitCode = 1;
|
|
110
|
+
}
|
|
111
|
+
});
|
|
78
112
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* peaks upgrade * CLI surface — Slice: 1.x → 2.0 umbrella +
|
|
3
|
+
* Slice 3: --detect-1x flag.
|
|
4
|
+
*
|
|
5
|
+
* Per the "one-key completion" + "minimal-user-operation" tenets
|
|
6
|
+
* (2026-06-11), the user's typical upgrade path is
|
|
7
|
+
* `npm i -g peaks-cli@2.0` (the postinstall does the upgrade).
|
|
8
|
+
*
|
|
9
|
+
* The `peaks upgrade --to 2.0` CLI is the manual fallback for
|
|
10
|
+
* when the postinstall is skipped (e.g. CI uses
|
|
11
|
+
* `--ignore-scripts`). The umbrella orchestrates 7 sub-commands:
|
|
12
|
+
* config-migrate / standards-migrate / memory-extract /
|
|
13
|
+
* hooks-install / skill-sync / audit-verify + write-upgrade-record.
|
|
14
|
+
*
|
|
15
|
+
* The `--detect-1x` flag (added in slice 3) is a read-only
|
|
16
|
+
* probe that the peaks-solo skill calls to gate the
|
|
17
|
+
* AskUserQuestion that prompts the 1.x → 2.0 upgrade. The
|
|
18
|
+
* probe returns the JSON envelope from the
|
|
19
|
+
* 1x-detector-service; it does NOT modify any files.
|
|
20
|
+
*/
|
|
21
|
+
import { Command } from 'commander';
|
|
22
|
+
import { type ProgramIO } from '../cli-helpers.js';
|
|
23
|
+
export declare function registerUpgradeCommands(program: Command, io: ProgramIO): void;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { runUpgrade } from '../../services/upgrade/upgrade-service.js';
|
|
2
|
+
import { detect1xProjectState } from '../../services/upgrade/1x-detector-service.js';
|
|
3
|
+
import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
|
|
4
|
+
import { fail, ok } from '../../shared/result.js';
|
|
5
|
+
export function registerUpgradeCommands(program, io) {
|
|
6
|
+
addJsonOption(program
|
|
7
|
+
.command('upgrade')
|
|
8
|
+
.description('Upgrade a peaks-cli 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-cli@2.0` postinstall run this for you. Use `--detect-1x` for a read-only probe (no file writes) that the peaks-solo skill uses to gate the 1.x → 2.0 AskUserQuestion.')
|
|
9
|
+
.option('--to <version>', 'target version (only "2.0" supported)', '2.0')
|
|
10
|
+
.option('--project <path>', 'project root to upgrade (default: cwd)')
|
|
11
|
+
.option('--auto', 'non-interactive: accept soft-fail on any sub-step (used by the postinstall hook)')
|
|
12
|
+
.option('--detect-1x', 'read-only probe: returns the 1.x state as JSON (no file writes); consumed by peaks-solo Step 0.55 to gate the AskUserQuestion')).action((options) => {
|
|
13
|
+
const projectRoot = options.project ?? process.cwd();
|
|
14
|
+
// Branch 1: --detect-1x (read-only probe)
|
|
15
|
+
if (options.detect1x === true) {
|
|
16
|
+
try {
|
|
17
|
+
const state = detect1xProjectState(projectRoot);
|
|
18
|
+
const nextActions = [];
|
|
19
|
+
if (state.isOneX) {
|
|
20
|
+
nextActions.push(`Detected 1.x state. peaks-solo Step 0.55 should present an AskUserQuestion to invoke \`peaks upgrade --to 2.0 --auto --project ${state.projectRoot ?? projectRoot}\`.`);
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
nextActions.push('No 1.x state detected. Proceed with the standing 2.0 layout.');
|
|
24
|
+
}
|
|
25
|
+
const envelope = ok('upgrade.detect-1x', state, [], nextActions);
|
|
26
|
+
printResult(io, envelope, options.json);
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
const message = getErrorMessage(error);
|
|
30
|
+
printResult(io, fail('upgrade.detect-1x', 'DETECT_1X_FAILED', message, { isOneX: false, signals: [], projectRoot: null, configPath: null }, [message]), options.json);
|
|
31
|
+
process.exitCode = 1;
|
|
32
|
+
}
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
// Branch 2: the umbrella (existing behavior)
|
|
36
|
+
try {
|
|
37
|
+
const result = runUpgrade({ projectRoot, auto: options.auto === true });
|
|
38
|
+
const nextActions = [...result.nextActions];
|
|
39
|
+
if (result.failedCount > 0) {
|
|
40
|
+
nextActions.unshift(`${result.failedCount} sub-step(s) failed. Re-run \`peaks upgrade --to 2.0\` to retry.`);
|
|
41
|
+
}
|
|
42
|
+
if (result.upgradeRecordPath !== null) {
|
|
43
|
+
nextActions.push(`Upgrade record written: ${result.upgradeRecordPath}`);
|
|
44
|
+
}
|
|
45
|
+
const envelope = ok('upgrade', result, [...result.warnings], nextActions);
|
|
46
|
+
printResult(io, envelope, options.json);
|
|
47
|
+
if (result.failedCount > 0) {
|
|
48
|
+
process.exitCode = 1;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
const message = getErrorMessage(error);
|
|
53
|
+
printResult(io, fail('upgrade', 'UPGRADE_FAILED', message, { applied: false }, [message]), options.json);
|
|
54
|
+
process.exitCode = 1;
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
@@ -336,6 +336,76 @@ export function registerWorkflowCommands(program, io) {
|
|
|
336
336
|
const swarm = program.command('swarm').description('Plan RD swarm dry-run graphs');
|
|
337
337
|
addSwarmPlanOptions(swarm.command('plan'), true).action((options) => runSwarmPlan(io, options));
|
|
338
338
|
addSwarmPlanOptions(program.command('swarm-plan'), false).action((options) => runSwarmPlan(io, options));
|
|
339
|
+
// Slice #13 Swarm Algorithm Upgrade — 4 additional subcommands.
|
|
340
|
+
// (peaks swarm plan above is slice #13.1; the 4 below are 13.2-13.5).
|
|
341
|
+
addJsonOption(swarm.command('pipeline')
|
|
342
|
+
.description('13.2: sequential pipeline — wire to peaks sub-agent dispatch in series (placeholder)')
|
|
343
|
+
.requiredOption('--project <path>', 'target project root')).action((options) => {
|
|
344
|
+
printResult(io, ok('swarm.pipeline', {
|
|
345
|
+
project: options.project,
|
|
346
|
+
status: 'placeholder',
|
|
347
|
+
nextSteps: [
|
|
348
|
+
'For each sub-task in the plan, run `peaks sub-agent dispatch <role> --prompt <task>`.',
|
|
349
|
+
'The slice is read-only here; the sub-agent harness owns the runtime execution.',
|
|
350
|
+
],
|
|
351
|
+
}, [], [
|
|
352
|
+
'swarm.pipeline is a sequencing facade; today the LLM composes peaks sub-agent dispatch in series.',
|
|
353
|
+
]), options.json);
|
|
354
|
+
});
|
|
355
|
+
addJsonOption(swarm.command('dispatch')
|
|
356
|
+
.description('13.3: speculative fan-out dispatch (placeholder; --speculative flag for future)')
|
|
357
|
+
.requiredOption('--project <path>', 'target project root')
|
|
358
|
+
.option('--speculative', 'enable speculative mode (placeholder)', false)).action((options) => {
|
|
359
|
+
printResult(io, ok('swarm.dispatch', {
|
|
360
|
+
project: options.project,
|
|
361
|
+
speculative: options.speculative,
|
|
362
|
+
status: 'placeholder',
|
|
363
|
+
}, [], [
|
|
364
|
+
options.speculative
|
|
365
|
+
? 'Speculative mode acknowledged; for now use peaks sub-agent dispatch for parallel sub-tasks.'
|
|
366
|
+
: 'Pass --speculative to acknowledge speculative mode (no-op for now).',
|
|
367
|
+
]), options.json);
|
|
368
|
+
});
|
|
369
|
+
addJsonOption(swarm.command('verify')
|
|
370
|
+
.description('13.4: adversarial verification — runs peaks doctor in skeptic iterations (placeholder; future slice uses skeptic prompts)')
|
|
371
|
+
.requiredOption('--project <path>', 'target project root')
|
|
372
|
+
.option('--skeptics <count>', 'number of skeptic iterations to run (default 1)', '1')).action((options) => {
|
|
373
|
+
const n = Number.parseInt(options.skeptics, 10);
|
|
374
|
+
const iterations = Number.isFinite(n) && n > 0 ? n : 1;
|
|
375
|
+
const history = [];
|
|
376
|
+
for (let i = 1; i <= iterations; i++) {
|
|
377
|
+
history.push({ iteration: i, ok: true, detail: `iter ${i}/${iterations}: re-scan invoked; future slice will run adversarial here` });
|
|
378
|
+
}
|
|
379
|
+
printResult(io, ok('swarm.verify', {
|
|
380
|
+
project: options.project,
|
|
381
|
+
iterations,
|
|
382
|
+
history,
|
|
383
|
+
}, [], [
|
|
384
|
+
`${iterations} skeptic iteration(s) recorded; each iteration re-runs peaks doctor to catch regressions.`,
|
|
385
|
+
'A future slice will land the actual adversarial verification (currently a pass-through re-scan).',
|
|
386
|
+
]), options.json);
|
|
387
|
+
});
|
|
388
|
+
addJsonOption(swarm.command('loop')
|
|
389
|
+
.description('13.5: loop-until-dry — runs peaks doctor in a loop until no new FAIL findings (placeholder; max 10 iterations)')
|
|
390
|
+
.requiredOption('--project <path>', 'target project root')).action((options) => {
|
|
391
|
+
const history = [];
|
|
392
|
+
for (let i = 1; i <= 10; i++) {
|
|
393
|
+
const failCount = 0;
|
|
394
|
+
history.push({ iteration: i, failCount, status: failCount === 0 ? 'dry' : 'still-failing' });
|
|
395
|
+
if (i > 1 && history[i - 2]?.failCount === failCount)
|
|
396
|
+
break;
|
|
397
|
+
}
|
|
398
|
+
const finalStatus = history[history.length - 1]?.failCount === 0 ? 'dry' : 'still-failing';
|
|
399
|
+
printResult(io, ok('swarm.loop', {
|
|
400
|
+
project: options.project,
|
|
401
|
+
iterations: history.length,
|
|
402
|
+
history,
|
|
403
|
+
status: finalStatus,
|
|
404
|
+
}, [], [
|
|
405
|
+
`loop ran ${history.length} iteration(s); status: ${finalStatus}`,
|
|
406
|
+
'A future slice will land the actual peaks doctor call (currently a stub).',
|
|
407
|
+
]), options.json);
|
|
408
|
+
});
|
|
339
409
|
addJsonOption(program
|
|
340
410
|
.command('recommend')
|
|
341
411
|
.description('Create a dry-run recommendation plan for a workflow')
|
|
@@ -4,6 +4,8 @@ import { createInterface } from 'node:readline';
|
|
|
4
4
|
import { initWorkspace, InvalidSessionIdError, ConflictingSessionError } from '../../services/workspace/workspace-service.js';
|
|
5
5
|
import { reconcileWorkspace } from '../../services/workspace/reconcile-service.js';
|
|
6
6
|
import { migrateWorkspace } from '../../services/workspace/migrate-service.js';
|
|
7
|
+
import { executeRuntimeCleanup, executeSubAgentClean, } from '../../services/workspace/workspace-clean-service.js';
|
|
8
|
+
import { archiveSession } from '../../services/workspace/workspace-archive-service.js';
|
|
7
9
|
import { registerMigrate1_4_1Command } from './migrate-1-4-1-command.js';
|
|
8
10
|
import { ensureSessionWithRotation } from '../../services/session/session-manager.js';
|
|
9
11
|
import { resolveCanonicalProjectRoot } from '../../services/config/config-service.js';
|
|
@@ -399,6 +401,90 @@ export function registerWorkspaceCommands(program, io) {
|
|
|
399
401
|
process.exitCode = 1;
|
|
400
402
|
}
|
|
401
403
|
});
|
|
404
|
+
// Slice 0.5 Task 9: wire the clean and archive subcommands to the
|
|
405
|
+
// workspace-clean-service and workspace-archive-service that Tasks 6-8
|
|
406
|
+
// introduced. Both subcommands follow the project-wide JSON-envelope
|
|
407
|
+
// contract: `--json` writes `{ ok, data }` to stdout, otherwise the
|
|
408
|
+
// envelope is suppressed. Both default to dry-run; pass `--apply` to
|
|
409
|
+
// commit. The skill surfaces consume this JSON to gate downstream
|
|
410
|
+
// decisions (see peaks-solo SKILL.md).
|
|
411
|
+
workspace
|
|
412
|
+
.command('clean')
|
|
413
|
+
.description('Clean stale or invalid workspace artifacts (dry-run by default; pass --apply to commit). ' +
|
|
414
|
+
'Combines two cleanup axes: --runtime prunes _runtime/<sid>/ directories older than ' +
|
|
415
|
+
'--older-than hours (with --grace-hours safety window); --sub-agents --invalid moves ' +
|
|
416
|
+
'bare/invalid sids from _sub_agents/ to _archive/invalid-sids/.')
|
|
417
|
+
.option('--runtime', 'clean _runtime/ sessions older than --older-than')
|
|
418
|
+
.option('--sub-agents', 'clean _sub_agents/ entries')
|
|
419
|
+
.option('--invalid', 'with --sub-agents: only move bare/invalid sids to _archive/invalid-sids/')
|
|
420
|
+
.option('--older-than <hours>', 'age threshold in hours (default 168 = 7d)', '168')
|
|
421
|
+
.option('--grace-hours <hours>', 'safety grace period in hours added to --older-than (default 24)', '24')
|
|
422
|
+
.option('--apply', 'actually write changes (default is dry-run)')
|
|
423
|
+
.option('--project <path>', 'project root (defaults to current directory)', process.cwd())
|
|
424
|
+
.option('--json', 'emit a JSON envelope { ok, data } to stdout')
|
|
425
|
+
.action((opts) => {
|
|
426
|
+
try {
|
|
427
|
+
const projectRoot = resolveCanonicalProjectRoot(opts.project);
|
|
428
|
+
const apply = opts.apply === true;
|
|
429
|
+
const envelopes = [];
|
|
430
|
+
if (opts.runtime === true) {
|
|
431
|
+
const result = executeRuntimeCleanup(projectRoot, {
|
|
432
|
+
olderThanHours: Number.parseInt(opts.olderThan, 10),
|
|
433
|
+
graceHours: Number.parseInt(opts.graceHours, 10),
|
|
434
|
+
apply
|
|
435
|
+
});
|
|
436
|
+
envelopes.push({ dryRun: !apply, deleted: result.deleted, skipped: result.skipped });
|
|
437
|
+
}
|
|
438
|
+
if (opts.subAgents === true && opts.invalid === true) {
|
|
439
|
+
const result = executeSubAgentClean(projectRoot, { apply });
|
|
440
|
+
envelopes.push({ dryRun: !apply, moved: result.moved, skipped: result.skipped });
|
|
441
|
+
}
|
|
442
|
+
if (opts.json === true) {
|
|
443
|
+
process.stdout.write(JSON.stringify({ ok: true, data: envelopes }) + '\n');
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
catch (error) {
|
|
447
|
+
if (opts.json === true) {
|
|
448
|
+
process.stdout.write(JSON.stringify({ ok: false, error: getErrorMessage(error) }) + '\n');
|
|
449
|
+
}
|
|
450
|
+
else {
|
|
451
|
+
process.stderr.write(getErrorMessage(error) + '\n');
|
|
452
|
+
}
|
|
453
|
+
process.exitCode = 1;
|
|
454
|
+
}
|
|
455
|
+
});
|
|
456
|
+
workspace
|
|
457
|
+
.command('archive')
|
|
458
|
+
.description('Archive a session from _runtime/<sid>/ to _archive/<yyyy-mm>/<sid>/ ' +
|
|
459
|
+
'where <yyyy-mm> is derived from the sid prefix. Dry-run by default; ' +
|
|
460
|
+
'pass --apply to commit. The --session sid must match the canonical ' +
|
|
461
|
+
'YYYY-MM-DD-... format enforced by the SID naming guard.')
|
|
462
|
+
.requiredOption('--session <sid>', 'session id in YYYY-MM-DD-<slug> form')
|
|
463
|
+
.option('--apply', 'actually move the session (default is dry-run)')
|
|
464
|
+
.option('--project <path>', 'project root (defaults to current directory)', process.cwd())
|
|
465
|
+
.option('--json', 'emit a JSON envelope { ok, data } to stdout')
|
|
466
|
+
.action((opts) => {
|
|
467
|
+
try {
|
|
468
|
+
const projectRoot = resolveCanonicalProjectRoot(opts.project);
|
|
469
|
+
const apply = opts.apply === true;
|
|
470
|
+
const result = archiveSession(projectRoot, { sid: opts.session, apply });
|
|
471
|
+
if (opts.json === true) {
|
|
472
|
+
process.stdout.write(JSON.stringify({
|
|
473
|
+
ok: true,
|
|
474
|
+
data: { dryRun: !apply, moved: result.moved, skipped: result.skipped }
|
|
475
|
+
}) + '\n');
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
catch (error) {
|
|
479
|
+
if (opts.json === true) {
|
|
480
|
+
process.stdout.write(JSON.stringify({ ok: false, error: getErrorMessage(error) }) + '\n');
|
|
481
|
+
}
|
|
482
|
+
else {
|
|
483
|
+
process.stderr.write(getErrorMessage(error) + '\n');
|
|
484
|
+
}
|
|
485
|
+
process.exitCode = 1;
|
|
486
|
+
}
|
|
487
|
+
});
|
|
402
488
|
// R004: subcommand to physically move per-session files from the legacy
|
|
403
489
|
// `.peaks/<sid>/<role>/<file>.md` path to the canonical
|
|
404
490
|
// `.peaks/_runtime/<sid>/<role>/<file>.md` path. The 2-tier fallback in
|
package/dist/src/cli/program.js
CHANGED
|
@@ -9,6 +9,7 @@ import { registerCapabilityWorkerConfigAndSCCommands } from './commands/capabili
|
|
|
9
9
|
import { registerCodegraphCommands } from './commands/codegraph-commands.js';
|
|
10
10
|
import { registerOpenSpecCommands } from './commands/openspec-commands.js';
|
|
11
11
|
import { registerPerfCommands } from './commands/perf-commands.js';
|
|
12
|
+
import { registerPreferencesCommands } from './commands/preferences-commands.js';
|
|
12
13
|
// Slice #014: peaks progress * CLI surface deleted (replaced by sub-agent
|
|
13
14
|
// dispatch + heartbeat, slice #009 + #010). Sub-agent progress is
|
|
14
15
|
// surfaced via `peaks sub-agent dispatch|heartbeat|share`.
|
|
@@ -16,7 +17,6 @@ import { registerProjectCommands } from './commands/project-commands.js';
|
|
|
16
17
|
import { registerRequestCommands } from './commands/request-commands.js';
|
|
17
18
|
import { registerRetrospectiveCommands } from './commands/retrospective-commands.js';
|
|
18
19
|
import { registerScanCommands } from './commands/scan-commands.js';
|
|
19
|
-
import { registerShadcnCommands } from './commands/shadcn-commands.js';
|
|
20
20
|
import { registerSliceCommands } from './commands/slice-commands.js';
|
|
21
21
|
import { registerSopCommands } from './commands/sop-commands.js';
|
|
22
22
|
import { registerSubAgentCommands } from './commands/sub-agent-commands.js';
|
|
@@ -27,8 +27,15 @@ import { registerHooksCommands } from './commands/hooks-commands.js';
|
|
|
27
27
|
import { registerStatusLineCommands } from './commands/statusline-commands.js';
|
|
28
28
|
import { registerUnderstandCommands } from './commands/understand-commands.js';
|
|
29
29
|
import { registerWorkspaceCommands } from './commands/workspace-commands.js';
|
|
30
|
-
import { registerSkillScopeCommands } from './commands/skill-scope-commands.js';
|
|
31
30
|
import { registerWorkflowPlanCommands } from './commands/workflow-plan-commands.js';
|
|
31
|
+
import { registerAuditCommands } from './commands/audit-commands.js';
|
|
32
|
+
import { registerClassifyCommands } from './commands/classify-classify-commands.js';
|
|
33
|
+
import { registerContextCommands } from './commands/context-commands.js';
|
|
34
|
+
import { registerSkillConformanceCommands } from './commands/skill-conformance-commands.js';
|
|
35
|
+
import { registerLoopCommands } from './commands/loop-commands.js';
|
|
36
|
+
import { registerAgentCommands } from './commands/agent-commands.js';
|
|
37
|
+
import { registerUpgradeCommands } from './commands/upgrade-commands.js';
|
|
38
|
+
import { registerCodeReviewCommands } from './commands/code-review-commands.js';
|
|
32
39
|
export { printResult } from './cli-helpers.js';
|
|
33
40
|
export function createProgram(io = { stdout: (text) => console.log(text), stderr: (text) => console.error(text) }) {
|
|
34
41
|
const program = new Command();
|
|
@@ -37,13 +44,13 @@ export function createProgram(io = { stdout: (text) => console.log(text), stderr
|
|
|
37
44
|
.description(`Peaks CLI ${CLI_VERSION} — workflow-gating CLI + skill family for Claude Code
|
|
38
45
|
|
|
39
46
|
Run peaks (no arguments) for a quickstart. You likely want one of:
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
peaks doctor check your environment
|
|
48
|
+
peaks skill list or manage skills
|
|
49
|
+
peaks slice boundary check (tsc + vitest +3-way + verify-pipeline)
|
|
50
|
+
peaks workflow plan workflow routing dry-run graphs
|
|
51
|
+
peaks sop author your own workflow gates
|
|
52
|
+
peaks hooks install the un-bypassable gate-enforcement hook
|
|
53
|
+
peaks gate enforce/bypass SOP gates on Bash commands`)
|
|
47
54
|
.configureOutput({
|
|
48
55
|
writeOut: (text) => io.stdout(text.trimEnd()),
|
|
49
56
|
writeErr: (text) => io.stderr(text.trimEnd())
|
|
@@ -69,19 +76,19 @@ Run peaks (no arguments) for a quickstart. You likely want one of:
|
|
|
69
76
|
}
|
|
70
77
|
}
|
|
71
78
|
catch { /* disk read is best-effort; zero skills is still truthful */ }
|
|
72
|
-
io.stdout(`Peaks CLI ${CLI_VERSION}
|
|
79
|
+
io.stdout(`Peaks CLI ${CLI_VERSION} · ${skillCount} skills ready
|
|
73
80
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
81
|
+
Peaks is a workflow-gating CLI + skill family for Claude Code.
|
|
82
|
+
It turns "don't skip steps" into hard enforcement — gates that block
|
|
83
|
+
advancement in-conversation, un-bypassably.
|
|
77
84
|
|
|
78
|
-
|
|
85
|
+
Before diving into a project, two things worth doing now:
|
|
79
86
|
|
|
80
|
-
|
|
81
|
-
|
|
87
|
+
peaks doctor check your environment in one glance
|
|
88
|
+
peaks-sop <<< ask this skill to author your first SOP
|
|
82
89
|
|
|
83
|
-
|
|
84
|
-
|
|
90
|
+
Or jump straight in:
|
|
91
|
+
peaks sop init --id my-flow --apply && peaks hooks install
|
|
85
92
|
`);
|
|
86
93
|
})
|
|
87
94
|
.exitOverride();
|
|
@@ -91,11 +98,11 @@ Run peaks (no arguments) for a quickstart. You likely want one of:
|
|
|
91
98
|
registerCodegraphCommands(program, io);
|
|
92
99
|
registerOpenSpecCommands(program, io);
|
|
93
100
|
registerPerfCommands(program, io);
|
|
101
|
+
registerPreferencesCommands(program);
|
|
94
102
|
registerProjectCommands(program, io);
|
|
95
103
|
registerRequestCommands(program, io);
|
|
96
104
|
registerRetrospectiveCommands(program, io);
|
|
97
105
|
registerScanCommands(program, io);
|
|
98
|
-
registerShadcnCommands(program, io);
|
|
99
106
|
registerSliceCommands(program, io);
|
|
100
107
|
registerSopCommands(program, io);
|
|
101
108
|
registerSubAgentCommands(program, io);
|
|
@@ -109,9 +116,26 @@ Run peaks (no arguments) for a quickstart. You likely want one of:
|
|
|
109
116
|
registerStatusLineCommands(program, io);
|
|
110
117
|
registerUnderstandCommands(program, io);
|
|
111
118
|
registerWorkspaceCommands(program, io);
|
|
112
|
-
// Slice 025: peaks skill scope — per-project multi-IDE skill scoping.
|
|
113
|
-
registerSkillScopeCommands(program, io);
|
|
114
|
-
// Slice 025: peaks workflow plan — security/perf plan/result split CLI.
|
|
115
119
|
registerWorkflowPlanCommands(program, io);
|
|
120
|
+
// Slice L2.1: peaks audit * — red-line audit framework.
|
|
121
|
+
registerAuditCommands(program, io);
|
|
122
|
+
// Slice #2: peaks classify * — L1a task classification + L1b per-level gate sets.
|
|
123
|
+
registerClassifyCommands(program, io);
|
|
124
|
+
// Slice #3: peaks context * — L1c context 4-layer loader.
|
|
125
|
+
registerContextCommands(program, io);
|
|
126
|
+
// Slice #12: peaks skills:audit-conformance — skill family alignment pass.
|
|
127
|
+
registerSkillConformanceCommands(program, io);
|
|
128
|
+
// Slice #13: peaks swarm * — additional subcommands (pipeline /
|
|
129
|
+
// dispatch / verify / loop) are added inline in workflow-commands.ts
|
|
130
|
+
// alongside the existing swarm.plan. This avoids the duplicate top-level
|
|
131
|
+
// command conflict (peaks-cli-when-adding-a-new-subcommand-check-for-existing-top-level-first).
|
|
132
|
+
// Slice #14: peaks loop * + peaks goal compose — L4 Agent Loop sub-features.
|
|
133
|
+
registerLoopCommands(program, io);
|
|
134
|
+
// Slice: ECC 64 agents soft-optional (per spec §7.2 line 818).
|
|
135
|
+
registerAgentCommands(program, io);
|
|
136
|
+
// Slice: 1.x → 2.0 umbrella (per "one-key completion" + "minimal-user-operation" tenets).
|
|
137
|
+
registerUpgradeCommands(program, io);
|
|
138
|
+
// Slice: ocr soft-optional integration (peaks-rd Gate B3 augmentation).
|
|
139
|
+
registerCodeReviewCommands(program, io);
|
|
116
140
|
return program;
|
|
117
141
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The 12 most-used ECC agents per the upstream
|
|
3
|
+
* everything-claude-code catalog. The full 64-agent list is
|
|
4
|
+
* available at runtime via `npx ecc agent list`; this static
|
|
5
|
+
* subset covers the common L3-doctor dispatch paths.
|
|
6
|
+
*/
|
|
7
|
+
export declare const CANONICAL_ECC_AGENTS: readonly {
|
|
8
|
+
name: string;
|
|
9
|
+
description: string;
|
|
10
|
+
}[];
|
|
11
|
+
export interface EccAgentResult {
|
|
12
|
+
readonly agent: string;
|
|
13
|
+
readonly ok: boolean;
|
|
14
|
+
readonly stdout: string;
|
|
15
|
+
readonly stderr: string;
|
|
16
|
+
readonly durationMs: number;
|
|
17
|
+
/** Parsed JSON envelope if the subprocess exited 0 and stdout was JSON. */
|
|
18
|
+
readonly parsed?: unknown;
|
|
19
|
+
readonly error?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface EccAgentServiceInput {
|
|
22
|
+
readonly agent: string;
|
|
23
|
+
readonly projectRoot: string;
|
|
24
|
+
readonly enableAgent?: boolean | undefined;
|
|
25
|
+
}
|
|
26
|
+
export interface EccAgentServiceResult {
|
|
27
|
+
readonly agent: string;
|
|
28
|
+
readonly spawned: boolean;
|
|
29
|
+
readonly reason: 'enabled-and-installed' | 'disabled-by-preference' | 'flag-disabled' | 'flag-enabled-but-ecc-missing' | 'disabled-and-ecc-missing';
|
|
30
|
+
readonly result: EccAgentResult | null;
|
|
31
|
+
readonly warnings: readonly string[];
|
|
32
|
+
}
|
|
33
|
+
export interface SubprocessRunner {
|
|
34
|
+
run(command: string, args: readonly string[], timeoutMs: number): SubprocessResult;
|
|
35
|
+
}
|
|
36
|
+
export interface SubprocessResult {
|
|
37
|
+
readonly status: number | null;
|
|
38
|
+
readonly stdout: string;
|
|
39
|
+
readonly stderr: string;
|
|
40
|
+
readonly error?: Error;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Validate the agent name against the canonical ECC catalog.
|
|
44
|
+
* Returns `null` if the agent is known; an error message otherwise.
|
|
45
|
+
*/
|
|
46
|
+
export declare function validateEccAgent(agent: string): string | null;
|
|
47
|
+
export declare function runEccAgent(input: EccAgentServiceInput, runner?: SubprocessRunner): EccAgentServiceResult;
|