peaks-cli 1.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.
Files changed (143) hide show
  1. package/LICENSE +52 -0
  2. package/README.md +417 -0
  3. package/bin/peaks.js +2 -0
  4. package/dist/src/cli/cli-helpers.d.ts +25 -0
  5. package/dist/src/cli/cli-helpers.js +78 -0
  6. package/dist/src/cli/commands/capability-commands.d.ts +5 -0
  7. package/dist/src/cli/commands/capability-commands.js +46 -0
  8. package/dist/src/cli/commands/capability-worker-config-sc-commands.d.ts +3 -0
  9. package/dist/src/cli/commands/capability-worker-config-sc-commands.js +10 -0
  10. package/dist/src/cli/commands/config-commands.d.ts +3 -0
  11. package/dist/src/cli/commands/config-commands.js +212 -0
  12. package/dist/src/cli/commands/core-artifact-commands.d.ts +3 -0
  13. package/dist/src/cli/commands/core-artifact-commands.js +200 -0
  14. package/dist/src/cli/commands/sc-commands.d.ts +3 -0
  15. package/dist/src/cli/commands/sc-commands.js +37 -0
  16. package/dist/src/cli/commands/worker-commands.d.ts +3 -0
  17. package/dist/src/cli/commands/worker-commands.js +52 -0
  18. package/dist/src/cli/commands/workflow-commands.d.ts +3 -0
  19. package/dist/src/cli/commands/workflow-commands.js +257 -0
  20. package/dist/src/cli/index.d.ts +1 -0
  21. package/dist/src/cli/index.js +14 -0
  22. package/dist/src/cli/program.d.ts +4 -0
  23. package/dist/src/cli/program.js +13 -0
  24. package/dist/src/services/artifacts/artifact-service.d.ts +43 -0
  25. package/dist/src/services/artifacts/artifact-service.js +97 -0
  26. package/dist/src/services/artifacts/workspace-service.d.ts +33 -0
  27. package/dist/src/services/artifacts/workspace-service.js +254 -0
  28. package/dist/src/services/config/config-service.d.ts +29 -0
  29. package/dist/src/services/config/config-service.js +501 -0
  30. package/dist/src/services/config/config-types.d.ts +63 -0
  31. package/dist/src/services/config/config-types.js +16 -0
  32. package/dist/src/services/config/model-routing.d.ts +4 -0
  33. package/dist/src/services/config/model-routing.js +15 -0
  34. package/dist/src/services/doctor/doctor-service.d.ts +18 -0
  35. package/dist/src/services/doctor/doctor-service.js +68 -0
  36. package/dist/src/services/memory/project-memory-service.d.ts +79 -0
  37. package/dist/src/services/memory/project-memory-service.js +306 -0
  38. package/dist/src/services/profiles/profile-service.d.ts +6 -0
  39. package/dist/src/services/profiles/profile-service.js +19 -0
  40. package/dist/src/services/providers/minimax-provider-service.d.ts +24 -0
  41. package/dist/src/services/providers/minimax-provider-service.js +143 -0
  42. package/dist/src/services/providers/minimax-worker-service.d.ts +21 -0
  43. package/dist/src/services/providers/minimax-worker-service.js +80 -0
  44. package/dist/src/services/proxy/proxy-service.d.ts +7 -0
  45. package/dist/src/services/proxy/proxy-service.js +31 -0
  46. package/dist/src/services/rd/rd-service.d.ts +88 -0
  47. package/dist/src/services/rd/rd-service.js +370 -0
  48. package/dist/src/services/recommendations/capability-availability.d.ts +5 -0
  49. package/dist/src/services/recommendations/capability-availability.js +40 -0
  50. package/dist/src/services/recommendations/capability-map-service.d.ts +7 -0
  51. package/dist/src/services/recommendations/capability-map-service.js +131 -0
  52. package/dist/src/services/recommendations/capability-seed-items.d.ts +2 -0
  53. package/dist/src/services/recommendations/capability-seed-items.js +131 -0
  54. package/dist/src/services/recommendations/capability-seed-mappings.d.ts +2 -0
  55. package/dist/src/services/recommendations/capability-seed-mappings.js +42 -0
  56. package/dist/src/services/recommendations/capability-seed-sources.d.ts +2 -0
  57. package/dist/src/services/recommendations/capability-seed-sources.js +35 -0
  58. package/dist/src/services/recommendations/recommendation-service.d.ts +8 -0
  59. package/dist/src/services/recommendations/recommendation-service.js +106 -0
  60. package/dist/src/services/recommendations/recommendation-types.d.ts +129 -0
  61. package/dist/src/services/recommendations/recommendation-types.js +1 -0
  62. package/dist/src/services/recommendations/seed-capability-catalog.d.ts +3 -0
  63. package/dist/src/services/recommendations/seed-capability-catalog.js +3 -0
  64. package/dist/src/services/refactor/refactor-service.d.ts +9 -0
  65. package/dist/src/services/refactor/refactor-service.js +33 -0
  66. package/dist/src/services/sc/index.d.ts +1 -0
  67. package/dist/src/services/sc/index.js +1 -0
  68. package/dist/src/services/sc/sc-service.d.ts +79 -0
  69. package/dist/src/services/sc/sc-service.js +223 -0
  70. package/dist/src/services/skills/skill-registry.d.ts +17 -0
  71. package/dist/src/services/skills/skill-registry.js +40 -0
  72. package/dist/src/services/standards/project-standards-service.d.ts +82 -0
  73. package/dist/src/services/standards/project-standards-service.js +383 -0
  74. package/dist/src/services/tech/tech-service.d.ts +69 -0
  75. package/dist/src/services/tech/tech-service.js +236 -0
  76. package/dist/src/services/workflow/workflow-autonomous-service.d.ts +99 -0
  77. package/dist/src/services/workflow/workflow-autonomous-service.js +526 -0
  78. package/dist/src/services/workflow/workflow-router-service.d.ts +85 -0
  79. package/dist/src/services/workflow/workflow-router-service.js +213 -0
  80. package/dist/src/shared/change-id.d.ts +15 -0
  81. package/dist/src/shared/change-id.js +76 -0
  82. package/dist/src/shared/frontmatter.d.ts +6 -0
  83. package/dist/src/shared/frontmatter.js +47 -0
  84. package/dist/src/shared/fs-utils.d.ts +4 -0
  85. package/dist/src/shared/fs-utils.js +16 -0
  86. package/dist/src/shared/fs.d.ts +4 -0
  87. package/dist/src/shared/fs.js +26 -0
  88. package/dist/src/shared/path-utils.d.ts +13 -0
  89. package/dist/src/shared/path-utils.js +56 -0
  90. package/dist/src/shared/paths.d.ts +6 -0
  91. package/dist/src/shared/paths.js +40 -0
  92. package/dist/src/shared/planner-response.d.ts +21 -0
  93. package/dist/src/shared/planner-response.js +26 -0
  94. package/dist/src/shared/platform.d.ts +6 -0
  95. package/dist/src/shared/platform.js +11 -0
  96. package/dist/src/shared/process.d.ts +5 -0
  97. package/dist/src/shared/process.js +12 -0
  98. package/dist/src/shared/result.d.ts +13 -0
  99. package/dist/src/shared/result.js +32 -0
  100. package/package.json +49 -0
  101. package/schemas/approval-record.schema.json +14 -0
  102. package/schemas/artifact-manifest.schema.json +16 -0
  103. package/schemas/artifact-retention-report.schema.json +17 -0
  104. package/schemas/artifact-workspace.schema.json +22 -0
  105. package/schemas/capability-availability.schema.json +36 -0
  106. package/schemas/capability-item.schema.json +37 -0
  107. package/schemas/capability-source.schema.json +30 -0
  108. package/schemas/change-impact.schema.json +15 -0
  109. package/schemas/context-capsule.schema.json +16 -0
  110. package/schemas/recommendation-plan.schema.json +37 -0
  111. package/schemas/refactor-slice-spec.schema.json +19 -0
  112. package/scripts/clean-dist.mjs +8 -0
  113. package/scripts/install-skills.mjs +76 -0
  114. package/scripts/watch.mjs +389 -0
  115. package/skills/peaks-prd/SKILL.md +42 -0
  116. package/skills/peaks-prd/references/artifact-contracts.md +3 -0
  117. package/skills/peaks-prd/references/command-migration.md +3 -0
  118. package/skills/peaks-prd/references/workflow.md +11 -0
  119. package/skills/peaks-qa/SKILL.md +45 -0
  120. package/skills/peaks-qa/references/artifact-contracts.md +3 -0
  121. package/skills/peaks-qa/references/command-migration.md +3 -0
  122. package/skills/peaks-qa/references/regression-gates.md +16 -0
  123. package/skills/peaks-rd/SKILL.md +56 -0
  124. package/skills/peaks-rd/references/artifact-contracts.md +3 -0
  125. package/skills/peaks-rd/references/command-migration.md +3 -0
  126. package/skills/peaks-rd/references/refactor-workflow.md +31 -0
  127. package/skills/peaks-sc/SKILL.md +30 -0
  128. package/skills/peaks-sc/references/artifact-contracts.md +3 -0
  129. package/skills/peaks-sc/references/artifact-retention.md +14 -0
  130. package/skills/peaks-sc/references/command-migration.md +3 -0
  131. package/skills/peaks-solo/SKILL.md +63 -0
  132. package/skills/peaks-solo/references/artifact-contracts.md +3 -0
  133. package/skills/peaks-solo/references/command-migration.md +3 -0
  134. package/skills/peaks-solo/references/refactor-mode.md +22 -0
  135. package/skills/peaks-solo/references/workflow.md +14 -0
  136. package/skills/peaks-txt/SKILL.md +48 -0
  137. package/skills/peaks-txt/references/artifact-contracts.md +3 -0
  138. package/skills/peaks-txt/references/command-migration.md +3 -0
  139. package/skills/peaks-txt/references/context-capsule.md +20 -0
  140. package/skills/peaks-ui/SKILL.md +35 -0
  141. package/skills/peaks-ui/references/artifact-contracts.md +3 -0
  142. package/skills/peaks-ui/references/command-migration.md +3 -0
  143. package/skills/peaks-ui/references/workflow.md +11 -0
@@ -0,0 +1,99 @@
1
+ import type { CapabilityItemType } from '../recommendations/recommendation-types.js';
2
+ import type { ModelProviderConfig, WorkspaceConfig } from '../config/config-types.js';
3
+ import { type RdPlanResult } from '../rd/rd-service.js';
4
+ import { type SoloMode, type WorkflowMode, type WorkflowRouterPlan } from './workflow-router-service.js';
5
+ export type CapabilitySurface = 'skill' | 'mcp' | 'plugin' | 'expert';
6
+ export type CapabilityPurpose = 'code-review' | 'security-review' | 'coding-standards' | 'docs-lookup' | 'browser-validation' | 'browser-debug' | 'design-context' | 'design-source' | 'code-search' | 'database-inspection' | 'browser-agent' | 'worker-guidance' | 'memory' | 'context-management' | 'ui-components' | 'spec-workflow' | 'repo-intelligence' | 'openspec' | 'workflow-methodology' | 'workflow-reference' | 'workflow-guidance' | 'product-guidance' | 'design-reference' | 'ui-reference' | 'engineering-guidance' | 'typescript-guidance' | 'quality-guidance' | 'skill-pack' | 'external-skill' | 'design-critique' | 'design-guidance' | 'cloud-skill-pack';
7
+ export type CapabilityActivation = 'available' | 'needs-install' | 'needs-credentials' | 'not-active';
8
+ export type CapabilityTrustLevel = 'local' | 'user-curated' | 'third-party';
9
+ export type CapabilityCandidate = {
10
+ readonly id: string;
11
+ readonly source: string;
12
+ readonly purpose: CapabilityPurpose;
13
+ readonly surface: CapabilitySurface;
14
+ readonly kind: CapabilitySurface;
15
+ readonly sourceType: CapabilityItemType;
16
+ readonly trustLevel: CapabilityTrustLevel;
17
+ readonly activation: CapabilityActivation;
18
+ readonly risk: readonly string[];
19
+ };
20
+ export type AutonomousWorkflowRequest = {
21
+ readonly mode: WorkflowMode;
22
+ readonly soloMode?: SoloMode;
23
+ readonly changeId: string;
24
+ readonly goal: string;
25
+ readonly maxWorkers?: number;
26
+ readonly dryRun: true;
27
+ readonly artifactWorkspacePath?: string;
28
+ readonly workspace?: WorkspaceConfig;
29
+ readonly config?: {
30
+ readonly economyMode?: boolean;
31
+ readonly swarmMode?: boolean;
32
+ readonly providers?: ModelProviderConfig;
33
+ };
34
+ };
35
+ export type AutonomousGoalPackage = {
36
+ readonly changeId: string;
37
+ readonly goal: string;
38
+ readonly nonGoals: readonly string[];
39
+ readonly preservedBehavior: readonly string[];
40
+ readonly acceptanceCriteria: readonly string[];
41
+ readonly doneCondition: string;
42
+ readonly resumeCondition: string;
43
+ readonly riskNotes: readonly string[];
44
+ };
45
+ export type AutonomousCapabilityPlan = {
46
+ readonly sources: readonly string[];
47
+ readonly policy: readonly string[];
48
+ readonly candidates: readonly CapabilityCandidate[];
49
+ readonly surfaces: readonly CapabilitySurface[];
50
+ readonly surfaceSummary: Record<CapabilitySurface, number>;
51
+ };
52
+ export type AutonomousResumePlan = {
53
+ readonly status: 'preview' | 'ready';
54
+ readonly checkpoints: readonly string[];
55
+ readonly requiredArtifacts: readonly string[];
56
+ readonly resumeInstructions: string;
57
+ };
58
+ export type AutonomousGoalCommand = {
59
+ readonly command: string;
60
+ readonly durable: false;
61
+ readonly reason: string;
62
+ };
63
+ export type AutonomousStoragePlan = {
64
+ readonly scope: 'user-local';
65
+ readonly artifactWorkspacePath: string | null;
66
+ readonly memoryBackupPath: string | null;
67
+ };
68
+ export type AutonomousMvpPackage = {
69
+ readonly mode: WorkflowMode;
70
+ readonly soloMode: SoloMode | undefined;
71
+ readonly executionMode: 'preview';
72
+ readonly dryRun: true;
73
+ readonly routePolicy: WorkflowRouterPlan['routePolicy'];
74
+ readonly rdWaveNames: readonly string[];
75
+ readonly capabilitySurfaces: readonly CapabilitySurface[];
76
+ readonly capabilityCountBySurface: Record<CapabilitySurface, number>;
77
+ readonly ready: boolean;
78
+ };
79
+ export type AutonomousWorkflowPlan = {
80
+ readonly available: boolean;
81
+ readonly behavior: 'preview' | 'ready';
82
+ readonly changeId: string;
83
+ readonly goal: string;
84
+ readonly mode: WorkflowMode;
85
+ readonly dryRun: true;
86
+ readonly goalPackage: AutonomousGoalPackage;
87
+ readonly goalCommand: AutonomousGoalCommand;
88
+ readonly capabilityPlan: AutonomousCapabilityPlan;
89
+ readonly storagePlan: AutonomousStoragePlan;
90
+ readonly routePlan: WorkflowRouterPlan;
91
+ readonly modelAssignments: WorkflowRouterPlan['modelAssignments'];
92
+ readonly rdPlan: RdPlanResult;
93
+ readonly resumePlan: AutonomousResumePlan;
94
+ readonly mvpPackage: AutonomousMvpPackage;
95
+ readonly constraints: readonly string[];
96
+ readonly blockedReasons: readonly string[];
97
+ readonly nextActions: readonly string[];
98
+ };
99
+ export declare function createAutonomousWorkflowPlan(request: AutonomousWorkflowRequest): AutonomousWorkflowPlan;
@@ -0,0 +1,526 @@
1
+ import { closeSync, fstatSync, lstatSync, openSync, readSync, realpathSync, statSync } from 'node:fs';
2
+ import { isAbsolute, join, relative, resolve } from 'node:path';
3
+ import { buildArtifactRelativePath, validateChangeIdOrThrow } from '../../shared/change-id.js';
4
+ import { WORKSPACE_UNAVAILABLE_NEXT_ACTIONS } from '../../shared/planner-response.js';
5
+ import { getLocalArtifactPath, hasValidArtifactWorkspace } from '../artifacts/workspace-service.js';
6
+ import { createCapabilityMapPlan } from '../recommendations/capability-map-service.js';
7
+ import { createRdSwarmPlan } from '../rd/rd-service.js';
8
+ import { createWorkflowRouterPlan } from './workflow-router-service.js';
9
+ const AUTONOMOUS_CONSTRAINTS = Object.freeze([
10
+ 'dry-run-only',
11
+ 'do-not-launch-workers',
12
+ 'do-not-install-capabilities',
13
+ 'do-not-mutate-claude-settings',
14
+ 'do-not-mutate-target-repo',
15
+ 'artifact-backed-resume-required',
16
+ 'evidence-before-resume'
17
+ ]);
18
+ const RESUME_ARTIFACTS_MISSING_NEXT_ACTIONS = Object.freeze([
19
+ 'Persist autonomous goal package, RD plan, checkpoint, validation evidence, and resume instructions before autonomous resume.'
20
+ ]);
21
+ const RESUME_ARTIFACTS_INVALID_NEXT_ACTIONS = Object.freeze([
22
+ 'Refresh autonomous resume artifacts with matching change ids, valid JSON state, and passed validation evidence before autonomous resume.'
23
+ ]);
24
+ const MAX_RESUME_ARTIFACT_BYTES = 256_000;
25
+ function normalizeGoal(goal) {
26
+ const normalized = goal.trim();
27
+ if (!normalized) {
28
+ throw new Error('Goal must be non-empty');
29
+ }
30
+ return normalized;
31
+ }
32
+ function resolveArtifactWorkspacePath(request) {
33
+ return request.artifactWorkspacePath ?? (request.workspace ? getLocalArtifactPath(request.workspace) : undefined);
34
+ }
35
+ function hasArtifactWorkspace(request, artifactWorkspacePath) {
36
+ return !!request.workspace && !!artifactWorkspacePath && hasValidArtifactWorkspace(request.workspace, artifactWorkspacePath);
37
+ }
38
+ function createGoalPackage(changeId, goal) {
39
+ return {
40
+ changeId,
41
+ goal,
42
+ nonGoals: [
43
+ 'Change product behavior without explicit approval.',
44
+ 'Install MCP servers, hooks, agents, or router configuration during dry-run planning.',
45
+ 'Store API keys or provider credentials in Peaks artifacts.'
46
+ ],
47
+ preservedBehavior: [
48
+ 'Existing product behavior remains stable unless the accepted goal explicitly changes it.',
49
+ 'Existing repository source files are not mutated by dry-run planning.',
50
+ 'Intermediate artifacts remain outside the target repository source tree.'
51
+ ],
52
+ acceptanceCriteria: [
53
+ 'A resumable autonomous RD plan exists with checkpoints, worker queue, and validation evidence requirements.',
54
+ 'Curated capabilities from docs/accessRepo.md and docs/mcpServer.md are considered before custom implementation.',
55
+ 'Resume after compact verifies checkpoints and evidence before continuing.',
56
+ 'All execution remains dry-run until explicitly approved.'
57
+ ],
58
+ doneCondition: `The ${changeId} autonomous plan is complete when all acceptance criteria pass, the worker queue is empty or blocked with next actions, and validation evidence is recorded.`,
59
+ resumeCondition: `Resume ${changeId} only after checkpoint artifacts, worker queue state, and validation evidence requirements have been verified.`,
60
+ riskNotes: [
61
+ 'Claude Code /goal is session-scoped and cannot be the only durable state source.',
62
+ 'External capabilities may require installation, credentials, network access, or settings changes.',
63
+ 'Large swarms need conflict groups and reducer evidence to avoid unsafe parallel edits.'
64
+ ]
65
+ };
66
+ }
67
+ const CAPABILITY_SURFACES = ['skill', 'mcp', 'plugin', 'expert'];
68
+ function createCapabilitySurfaceSummary() {
69
+ return {
70
+ skill: 0,
71
+ mcp: 0,
72
+ plugin: 0,
73
+ expert: 0
74
+ };
75
+ }
76
+ function getCapabilitySurface(itemType) {
77
+ if (itemType === 'skill')
78
+ return 'skill';
79
+ if (itemType === 'mcp')
80
+ return 'mcp';
81
+ if (itemType === 'agent')
82
+ return 'expert';
83
+ return 'plugin';
84
+ }
85
+ function getCapabilityTrustLevel(sourceId) {
86
+ if (sourceId === 'skills/*/SKILL.md' || sourceId === 'local-peaks-skills') {
87
+ return 'local';
88
+ }
89
+ if (sourceId.startsWith('everything-claude-code')
90
+ || sourceId.startsWith('ruflo-')
91
+ || sourceId === 'superpowers'
92
+ || sourceId === 'openspec'
93
+ || sourceId === 'gstack'
94
+ || sourceId === 'impeccable'
95
+ || sourceId === 'andrej-karpathy-skills'
96
+ || sourceId === 'mattpocock-skills') {
97
+ return 'user-curated';
98
+ }
99
+ return 'third-party';
100
+ }
101
+ function getCapabilityPurpose(item) {
102
+ switch (item.category) {
103
+ case 'browser-validation':
104
+ case 'browser-debug':
105
+ case 'design-context':
106
+ case 'code-search':
107
+ case 'database-inspection':
108
+ case 'browser-agent':
109
+ case 'docs-lookup':
110
+ case 'design-source':
111
+ case 'code-review':
112
+ case 'security-review':
113
+ case 'coding-standards':
114
+ case 'worker-guidance':
115
+ case 'memory':
116
+ case 'context-management':
117
+ case 'ui-components':
118
+ case 'spec-workflow':
119
+ case 'repo-intelligence':
120
+ case 'openspec':
121
+ case 'workflow-methodology':
122
+ case 'workflow-reference':
123
+ case 'workflow-guidance':
124
+ case 'product-guidance':
125
+ case 'design-reference':
126
+ case 'ui-reference':
127
+ case 'engineering-guidance':
128
+ case 'typescript-guidance':
129
+ case 'quality-guidance':
130
+ case 'skill-pack':
131
+ case 'external-skill':
132
+ case 'design-critique':
133
+ case 'design-guidance':
134
+ case 'cloud-skill-pack':
135
+ return item.category;
136
+ default:
137
+ return item.itemType === 'mcp' ? 'docs-lookup' : 'workflow-guidance';
138
+ }
139
+ }
140
+ function getCapabilityActivation(status, itemType) {
141
+ switch (status) {
142
+ case 'available':
143
+ return 'available';
144
+ case 'installable':
145
+ return itemType === 'mcp' ? 'needs-credentials' : 'needs-install';
146
+ case 'disabled':
147
+ return 'not-active';
148
+ case 'unknown':
149
+ default:
150
+ return itemType === 'mcp' ? 'needs-credentials' : 'not-active';
151
+ }
152
+ }
153
+ function createCapabilityPlan(request) {
154
+ const catalogPlan = createCapabilityMapPlan({ installedCapabilityIds: request.workspace?.installedCapabilityIds ?? [] });
155
+ const surfaceSummary = createCapabilitySurfaceSummary();
156
+ const candidates = catalogPlan.items.map((item) => {
157
+ const surface = getCapabilitySurface(item.itemType);
158
+ const availability = catalogPlan.availability.find((availability) => availability.capabilityId === item.capabilityId);
159
+ surfaceSummary[surface] += 1;
160
+ return {
161
+ id: item.capabilityId,
162
+ source: item.sourceId,
163
+ purpose: getCapabilityPurpose(item),
164
+ surface,
165
+ kind: surface,
166
+ sourceType: item.itemType,
167
+ trustLevel: getCapabilityTrustLevel(item.sourceId),
168
+ activation: getCapabilityActivation(availability?.status ?? 'unknown', item.itemType),
169
+ risk: [item.riskLevel]
170
+ };
171
+ });
172
+ candidates.push({
173
+ id: 'local-peaks-skills',
174
+ source: 'skills/*/SKILL.md',
175
+ purpose: 'workflow-methodology',
176
+ surface: 'skill',
177
+ kind: 'skill',
178
+ sourceType: 'skill',
179
+ trustLevel: 'local',
180
+ activation: 'available',
181
+ risk: ['local-skill-boundary-misuse']
182
+ });
183
+ surfaceSummary.skill += 1;
184
+ return {
185
+ sources: uniqueStrings(['docs/accessRepo.md', 'docs/mcpServer.md', 'skills/*/SKILL.md', ...catalogPlan.sources.map((source) => source.sourceId)]),
186
+ policy: [
187
+ 'reuse-curated-capabilities-before-custom-build',
188
+ 'plan-capability-use-before-activation',
189
+ 'require-explicit-approval-for-install-credentials-network-or-settings-mutation'
190
+ ],
191
+ candidates,
192
+ surfaces: [...CAPABILITY_SURFACES],
193
+ surfaceSummary
194
+ };
195
+ }
196
+ function createMvpPackage(request, routePlan, rdPlan, capabilityPlan, ready) {
197
+ return {
198
+ mode: request.mode,
199
+ soloMode: routePlan.soloMode,
200
+ executionMode: 'preview',
201
+ dryRun: true,
202
+ routePolicy: routePlan.routePolicy,
203
+ rdWaveNames: rdPlan.waves.map((wave) => wave.name),
204
+ capabilitySurfaces: [...capabilityPlan.surfaces],
205
+ capabilityCountBySurface: { ...capabilityPlan.surfaceSummary },
206
+ ready
207
+ };
208
+ }
209
+ function createGoalCommand(goalPackage) {
210
+ return {
211
+ command: `/goal ${goalPackage.doneCondition}`,
212
+ durable: false,
213
+ reason: 'Claude Code /goal can help continue across turns in the current session, but Peaks artifacts remain the durable state.'
214
+ };
215
+ }
216
+ function getResumeRequiredArtifacts(changeId) {
217
+ return [
218
+ buildArtifactRelativePath(changeId, 'prd', 'autonomous-goal-package.json'),
219
+ buildArtifactRelativePath(changeId, 'swarm', 'autonomous-rd-plan.json'),
220
+ buildArtifactRelativePath(changeId, 'swarm', 'checkpoints', 'checkpoint-1.json'),
221
+ buildArtifactRelativePath(changeId, 'swarm', 'evidence', 'validation-report.md'),
222
+ buildArtifactRelativePath(changeId, 'swarm', 'resume-instructions.md')
223
+ ];
224
+ }
225
+ function isObjectRecord(value) {
226
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
227
+ }
228
+ function isInsidePath(childPath, parentPath) {
229
+ const relativePath = relative(parentPath, childPath);
230
+ return relativePath === '' || (!relativePath.startsWith('..') && !isAbsolute(relativePath));
231
+ }
232
+ function readFully(fd, size) {
233
+ const buffer = Buffer.alloc(size);
234
+ let offset = 0;
235
+ while (offset < size) {
236
+ const bytesRead = readSync(fd, buffer, offset, size - offset, offset);
237
+ if (bytesRead === 0) {
238
+ return null;
239
+ }
240
+ offset += bytesRead;
241
+ }
242
+ return buffer.toString('utf8');
243
+ }
244
+ function readResumeArtifact(artifactWorkspacePath, artifact) {
245
+ const artifactPath = resolve(artifactWorkspacePath, artifact);
246
+ try {
247
+ const artifactWorkspaceRealPath = realpathSync(artifactWorkspacePath);
248
+ const artifactStat = lstatSync(artifactPath);
249
+ if (artifactStat.isSymbolicLink() || !artifactStat.isFile() || artifactStat.size > MAX_RESUME_ARTIFACT_BYTES) {
250
+ return null;
251
+ }
252
+ const artifactRealPath = realpathSync(artifactPath);
253
+ if (!isInsidePath(artifactRealPath, artifactWorkspaceRealPath)) {
254
+ return null;
255
+ }
256
+ const fd = openSync(artifactPath, 'r');
257
+ try {
258
+ const openedStat = fstatSync(fd);
259
+ const currentStat = statSync(artifactPath);
260
+ if (!openedStat.isFile() || openedStat.size > MAX_RESUME_ARTIFACT_BYTES || openedStat.dev !== artifactStat.dev || openedStat.ino !== artifactStat.ino || openedStat.dev !== currentStat.dev || openedStat.ino !== currentStat.ino) {
261
+ return null;
262
+ }
263
+ return readFully(fd, openedStat.size);
264
+ }
265
+ finally {
266
+ closeSync(fd);
267
+ }
268
+ }
269
+ catch {
270
+ return null;
271
+ }
272
+ }
273
+ function getExpectedResumeArtifactType(artifact) {
274
+ if (artifact.endsWith('/autonomous-goal-package.json'))
275
+ return 'goal-package';
276
+ if (artifact.endsWith('/autonomous-rd-plan.json'))
277
+ return 'rd-plan';
278
+ if (artifact.endsWith('/checkpoint-1.json'))
279
+ return 'checkpoint';
280
+ if (artifact.endsWith('/validation-report.md'))
281
+ return 'validation-report';
282
+ return 'resume-instructions';
283
+ }
284
+ function hasStringArray(value) {
285
+ return Array.isArray(value) && value.length > 0 && value.every((item) => typeof item === 'string' && item.trim().length > 0);
286
+ }
287
+ function hasValidGoalPackageJson(parsed, goal) {
288
+ return parsed.goal === goal
289
+ && typeof parsed.doneCondition === 'string'
290
+ && parsed.doneCondition.trim().length > 0
291
+ && typeof parsed.resumeCondition === 'string'
292
+ && parsed.resumeCondition.trim().length > 0
293
+ && hasStringArray(parsed.acceptanceCriteria);
294
+ }
295
+ function hasValidRdPlanJson(parsed) {
296
+ return parsed.workerQueueStatus === 'ready'
297
+ && typeof parsed.taskCount === 'number'
298
+ && Number.isInteger(parsed.taskCount)
299
+ && parsed.taskCount > 0
300
+ && parsed.reducerRequired === true;
301
+ }
302
+ function hasValidCheckpointJson(parsed) {
303
+ return parsed.checkpointId === 'checkpoint-1'
304
+ && typeof parsed.createdAt === 'string'
305
+ && parsed.createdAt.trim().length > 0
306
+ && isObjectRecord(parsed.workerQueueState)
307
+ && hasStringArray(parsed.validationRefs);
308
+ }
309
+ function parseJsonObject(content) {
310
+ try {
311
+ const parsed = JSON.parse(content);
312
+ return isObjectRecord(parsed) ? parsed : null;
313
+ }
314
+ catch {
315
+ return null;
316
+ }
317
+ }
318
+ function hasValidJsonMetadata(content, changeId, artifactType, goal) {
319
+ const parsed = parseJsonObject(content);
320
+ if (parsed === null || parsed.changeId !== changeId || parsed.artifactType !== artifactType || parsed.status !== 'ready') {
321
+ return false;
322
+ }
323
+ if (artifactType === 'goal-package')
324
+ return hasValidGoalPackageJson(parsed, goal);
325
+ if (artifactType === 'rd-plan')
326
+ return hasValidRdPlanJson(parsed);
327
+ return artifactType === 'checkpoint' && hasValidCheckpointJson(parsed);
328
+ }
329
+ function parseFrontMatter(content) {
330
+ const lines = content.split(/\r?\n/);
331
+ if (lines[0] !== '---') {
332
+ return null;
333
+ }
334
+ const endIndex = lines.slice(1).findIndex((line) => line === '---');
335
+ if (endIndex === -1) {
336
+ return null;
337
+ }
338
+ const metadata = new Map();
339
+ for (const line of lines.slice(1, endIndex + 1)) {
340
+ const separatorIndex = line.indexOf(':');
341
+ if (separatorIndex === -1) {
342
+ return null;
343
+ }
344
+ metadata.set(line.slice(0, separatorIndex).trim(), line.slice(separatorIndex + 1).trim());
345
+ }
346
+ return Object.fromEntries(metadata);
347
+ }
348
+ function getMarkdownBody(content) {
349
+ const lines = content.split(/\r?\n/);
350
+ const endIndex = lines.slice(1).findIndex((line) => line === '---');
351
+ return endIndex === -1 ? '' : lines.slice(endIndex + 2).join('\n');
352
+ }
353
+ function hasValidationReportBody(body) {
354
+ return body.includes('Validation summary:')
355
+ && body.includes('Checks:')
356
+ && body.includes('Result: passed')
357
+ && body.includes('Evidence refs:');
358
+ }
359
+ function hasResumeInstructionsBody(body) {
360
+ return body.includes('Resume steps:')
361
+ && body.includes('Preconditions:')
362
+ && body.includes('Blocked actions:')
363
+ && body.includes('Next actions:');
364
+ }
365
+ function extractMarkdownListSection(body, heading) {
366
+ const lines = body.split(/\r?\n/);
367
+ const startIndex = lines.findIndex((line) => line.trim() === heading);
368
+ if (startIndex === -1) {
369
+ return [];
370
+ }
371
+ const sectionLines = lines.slice(startIndex + 1);
372
+ const nextHeadingIndex = sectionLines.findIndex((line) => /^[A-Z][A-Za-z ]+:$/.test(line.trim()));
373
+ const sectionEndIndex = nextHeadingIndex + 1 || sectionLines.length;
374
+ return sectionLines.slice(0, sectionEndIndex)
375
+ .map((line) => line.trim())
376
+ .filter((line) => line.startsWith('- '))
377
+ .map((line) => line.slice(2).trim())
378
+ .filter((line) => line.length > 0);
379
+ }
380
+ function getCheckpointValidationRefs(checkpointContent) {
381
+ const parsed = parseJsonObject(checkpointContent);
382
+ return parsed && hasStringArray(parsed.validationRefs) ? parsed.validationRefs : [];
383
+ }
384
+ function isSafeEvidenceRef(ref) {
385
+ return ref.toLowerCase() !== 'validation-report.md' && /^[A-Za-z0-9][A-Za-z0-9._-]*\.md$/.test(ref) && !ref.includes('..');
386
+ }
387
+ function evidenceRefsExist(artifactWorkspacePath, changeId, refs) {
388
+ return refs.every((ref) => isSafeEvidenceRef(ref) && readResumeArtifact(artifactWorkspacePath, buildArtifactRelativePath(changeId, 'swarm', 'evidence', ref)) !== null);
389
+ }
390
+ function hasMatchingEvidenceRefs(artifactWorkspacePath, changeId, validationReportContent, checkpointContent) {
391
+ const expectedRefs = getCheckpointValidationRefs(checkpointContent);
392
+ const actualRefs = extractMarkdownListSection(getMarkdownBody(validationReportContent), 'Evidence refs:');
393
+ return expectedRefs.length > 0
394
+ && expectedRefs.length === actualRefs.length
395
+ && expectedRefs.every((expectedRef, index) => expectedRef === actualRefs[index])
396
+ && evidenceRefsExist(artifactWorkspacePath, changeId, expectedRefs);
397
+ }
398
+ function hasValidMarkdownMetadata(content, changeId, artifactType) {
399
+ const metadata = parseFrontMatter(content);
400
+ if (metadata === null || metadata.changeId !== changeId || metadata.artifactType !== artifactType || metadata.status !== 'passed') {
401
+ return false;
402
+ }
403
+ const body = getMarkdownBody(content);
404
+ return artifactType === 'validation-report' ? hasValidationReportBody(body) : hasResumeInstructionsBody(body);
405
+ }
406
+ function isValidResumeArtifact(artifact, content, changeId, goal) {
407
+ if (!content.trim()) {
408
+ return false;
409
+ }
410
+ const artifactType = getExpectedResumeArtifactType(artifact);
411
+ return artifact.endsWith('.json')
412
+ ? hasValidJsonMetadata(content, changeId, artifactType, goal)
413
+ : hasValidMarkdownMetadata(content, changeId, artifactType);
414
+ }
415
+ function getResumeArtifactsStatus(artifactWorkspacePath, requiredArtifacts, changeId, goal) {
416
+ let hasInvalidArtifact = false;
417
+ const artifactContents = new Map();
418
+ for (const artifact of requiredArtifacts) {
419
+ const content = readResumeArtifact(artifactWorkspacePath, artifact);
420
+ if (content === null) {
421
+ return 'missing';
422
+ }
423
+ artifactContents.set(artifact, content);
424
+ if (!isValidResumeArtifact(artifact, content, changeId, goal)) {
425
+ hasInvalidArtifact = true;
426
+ }
427
+ }
428
+ const checkpointContent = artifactContents.get(buildArtifactRelativePath(changeId, 'swarm', 'checkpoints', 'checkpoint-1.json'));
429
+ const validationReportContent = artifactContents.get(buildArtifactRelativePath(changeId, 'swarm', 'evidence', 'validation-report.md'));
430
+ if (!checkpointContent || !validationReportContent || !hasMatchingEvidenceRefs(artifactWorkspacePath, changeId, validationReportContent, checkpointContent)) {
431
+ hasInvalidArtifact = true;
432
+ }
433
+ return hasInvalidArtifact ? 'invalid' : 'ready';
434
+ }
435
+ function createResumePlan(changeId, ready) {
436
+ const requiredArtifacts = getResumeRequiredArtifacts(changeId);
437
+ return {
438
+ status: ready ? 'ready' : 'preview',
439
+ checkpoints: ['goal-package-created', 'capabilities-planned', 'rd-swarm-planned', 'validation-evidence-required'],
440
+ requiredArtifacts,
441
+ resumeInstructions: ready
442
+ ? 'Before continuing, verify checkpoint artifacts, pending worker queue state, and validation evidence requirements.'
443
+ : 'Resolve blocked planning reasons before relying on autonomous resume state.'
444
+ };
445
+ }
446
+ function uniqueStrings(values) {
447
+ return [...new Set(values)];
448
+ }
449
+ export function createAutonomousWorkflowPlan(request) {
450
+ validateChangeIdOrThrow(request.changeId);
451
+ const goal = normalizeGoal(request.goal);
452
+ const maxWorkers = request.maxWorkers ?? 40;
453
+ const artifactWorkspacePath = resolveArtifactWorkspacePath(request);
454
+ const memoryBackupPath = artifactWorkspacePath ? join(artifactWorkspacePath, '.peaks', 'memory-backups', 'project-memory-primary') : null;
455
+ const sharedWorkspaceOptions = {
456
+ ...(artifactWorkspacePath ? { artifactWorkspacePath } : {}),
457
+ ...(request.workspace ? { workspace: request.workspace } : {})
458
+ };
459
+ const goalPackage = createGoalPackage(request.changeId, goal);
460
+ const available = hasArtifactWorkspace(request, artifactWorkspacePath);
461
+ const routePlan = createWorkflowRouterPlan({
462
+ mode: request.mode,
463
+ ...(request.soloMode !== undefined ? { soloMode: request.soloMode } : {}),
464
+ changeId: request.changeId,
465
+ goal,
466
+ maxWorkers,
467
+ dryRun: true,
468
+ ...(request.config ? { config: request.config } : {}),
469
+ ...sharedWorkspaceOptions
470
+ });
471
+ const rdPlan = createRdSwarmPlan({
472
+ skill: 'rd',
473
+ changeId: request.changeId,
474
+ goal,
475
+ maxWorkers,
476
+ dryRun: true,
477
+ ...(request.config?.swarmMode !== undefined ? { swarmMode: request.config.swarmMode } : {}),
478
+ executionModelId: routePlan.modeStatus.executionModelId,
479
+ ...sharedWorkspaceOptions
480
+ });
481
+ const requiredArtifacts = getResumeRequiredArtifacts(request.changeId);
482
+ const resumeArtifactsStatus = available && artifactWorkspacePath
483
+ ? getResumeArtifactsStatus(artifactWorkspacePath, requiredArtifacts, request.changeId, goal)
484
+ : 'missing';
485
+ const blockedReasons = uniqueStrings([
486
+ ...routePlan.blockedReasons,
487
+ ...rdPlan.blockedReasons,
488
+ ...(available ? [] : ['artifact-workspace-unavailable']),
489
+ ...(resumeArtifactsStatus === 'missing' ? ['resume-artifacts-missing'] : []),
490
+ ...(resumeArtifactsStatus === 'invalid' ? ['resume-artifacts-invalid'] : [])
491
+ ]);
492
+ const ready = available && blockedReasons.length === 0;
493
+ const capabilityPlan = createCapabilityPlan(request);
494
+ const mvpPackage = createMvpPackage(request, routePlan, rdPlan, capabilityPlan, ready);
495
+ return {
496
+ available: ready,
497
+ behavior: ready ? 'ready' : 'preview',
498
+ changeId: request.changeId,
499
+ goal,
500
+ mode: request.mode,
501
+ dryRun: true,
502
+ goalPackage,
503
+ goalCommand: createGoalCommand(goalPackage),
504
+ capabilityPlan,
505
+ storagePlan: {
506
+ scope: 'user-local',
507
+ artifactWorkspacePath: artifactWorkspacePath ?? null,
508
+ memoryBackupPath: memoryBackupPath ?? null
509
+ },
510
+ routePlan,
511
+ modelAssignments: routePlan.modelAssignments,
512
+ rdPlan,
513
+ resumePlan: createResumePlan(request.changeId, ready),
514
+ mvpPackage,
515
+ constraints: [...AUTONOMOUS_CONSTRAINTS],
516
+ blockedReasons,
517
+ nextActions: available
518
+ ? uniqueStrings([
519
+ ...routePlan.nextActions,
520
+ ...rdPlan.nextActions,
521
+ ...(resumeArtifactsStatus === 'missing' ? RESUME_ARTIFACTS_MISSING_NEXT_ACTIONS : []),
522
+ ...(resumeArtifactsStatus === 'invalid' ? RESUME_ARTIFACTS_INVALID_NEXT_ACTIONS : [])
523
+ ])
524
+ : [...WORKSPACE_UNAVAILABLE_NEXT_ACTIONS]
525
+ };
526
+ }