maskweaver 0.8.16 → 0.9.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 (34) hide show
  1. package/README.ko.md +640 -657
  2. package/README.md +672 -689
  3. package/assets/commands/meta/commands.json +254 -0
  4. package/assets/commands/weave-agents.md +62 -0
  5. package/assets/commands/weave-approve.md +61 -0
  6. package/assets/commands/weave-build.md +99 -0
  7. package/assets/commands/weave-help.md +112 -158
  8. package/assets/commands/weave-interview.md +121 -0
  9. package/assets/commands/weave-map.md +109 -0
  10. package/assets/commands/weave-troubleshoot.md +57 -0
  11. package/dist/plugin/index.d.ts +5 -1
  12. package/dist/plugin/index.d.ts.map +1 -1
  13. package/dist/plugin/index.js +20 -17
  14. package/dist/plugin/index.js.map +1 -1
  15. package/dist/plugin/tools/command-registry.d.ts +51 -0
  16. package/dist/plugin/tools/command-registry.d.ts.map +1 -0
  17. package/dist/plugin/tools/command-registry.js +348 -0
  18. package/dist/plugin/tools/command-registry.js.map +1 -0
  19. package/dist/plugin/tools/slashcommand.d.ts +1 -1
  20. package/dist/plugin/tools/slashcommand.d.ts.map +1 -1
  21. package/dist/plugin/tools/slashcommand.js +47 -193
  22. package/dist/plugin/tools/slashcommand.js.map +1 -1
  23. package/dist/plugin/tools/weave.d.ts +14 -35
  24. package/dist/plugin/tools/weave.d.ts.map +1 -1
  25. package/dist/plugin/tools/weave.js +247 -213
  26. package/dist/plugin/tools/weave.js.map +1 -1
  27. package/package.json +142 -142
  28. package/assets/commands/weave-approve-plan.md +0 -57
  29. package/assets/commands/weave-design.md +0 -296
  30. package/assets/commands/weave-flow.md +0 -48
  31. package/assets/commands/weave-plan.md +0 -15
  32. package/assets/commands/weave-research.md +0 -51
  33. package/assets/commands/weave-spec.md +0 -227
  34. package/assets/commands/weave-switch.md +0 -170
@@ -38,67 +38,43 @@ import { analyzeParallelOpportunities, executionPlanToSquadTasks } from '../../w
38
38
  import { acquireLoopOperatorLock, appendLoopEvent, createLoopRun, ensureLoopContract, listLoopRuns, readLoopRun, releaseLoopOperatorLock, refreshLoopOperatorLock, requestLoopStop, toLoopOperatorStatePath, resolveLoopId, toLoopRunPath, updateLoopRun, writeLoopOperatorState, writeLoopAttemptControllerNotes, writeLoopAttemptTaskBundle, writeLoopAttemptWorkerBrief, writeLoopAttemptVerificationReport, } from '../../weave/loop.js';
39
39
  import { getEffectiveGdcConfig, runGdcMachineCommand, countGdcCheckIssues, getStatsNodeSummary, } from '../../weave/gdc.js';
40
40
  import { generatePoolAgentFilesFromConfig, writeDefaultRuntimeConfig, writeDefaultPluginConfig, } from '../../shared/generate-agents.js';
41
+ import { resolveCommand, loadCommandsJson } from './command-registry.js';
41
42
  // ============================================================================
42
43
  // Tool Factory
43
44
  // ============================================================================
44
45
  export function createWeaveTool() {
45
46
  return {
46
- description: `Weave: Phase-driven development workflow with expert mask auto-selection and cross-project knowledge sharing.
47
-
48
- Commands:
49
- - init: Initialize weave workspace files and probe GDC integration
50
- - map [deep]: Analyze codebase structure via GDC + Graphify (knowledge graph)
51
- - interview [docsPath]: Multi-step question asking until clarity, with structural change detection
52
- - research [docsPath]: Deep-read docs + workspace context and write persistent research.md
53
- - spec [docsPath]: Generate baseline spec (requirements + AC)
54
- - design [docsPath]: Analyze requirements and create phase-based plan (auto-splits oversized plans)
55
- - prepare [docsPath]: Create research + spec + plan with defaults (auto-splits oversized plans)
56
- - refine-plan: Apply annotation notes to active plan
57
- - approve-plan: Approve the plan, or finalize a crafted phase when phaseId is provided
58
- - flow [docsPath]: One-command path (prepare -> auto-approve -> craft -> verify -> finalize)
59
- - craft [phaseId]: Prepare execution context for a phase (phase auto-select if omitted)
60
- - build [phaseIds]: Ralph-loop autonomous execution — runs approved plan until all tasks complete (no user intervention)
61
- - build-resume [buildId]: Resume a previously blocked build
62
- - status: View overall progress
63
- - worktree: Manage git worktrees for parallel work
64
- - verify: Run build/test verification for current worktree
65
- - archive: Archive the verified active change artifact
66
- - loop-run: Run a bounded loop for the active change until verify passes or the run blocks
67
- - loop-start: Create a loop run without executing it
68
- - loop-status: Inspect a loop run by loopId
69
- - loop-stop: Request a semantic stop for a loop run
70
- - loop-list: List known loop runs
71
- - loop-sync: Sync delegated squad results back into a loop run
72
- - loop-watchdog: Poll loop delegation sessions and auto-sync completed runs
73
- - loop-poll: Bounded wait loop that watches delegated work and resumes automatically
74
- - loop-operator: Recurring operator run for delegated loops (automation-friendly)
75
- - troubleshoot [error]: Search global knowledge for solutions
76
- - record [solution]: Record a troubleshooting solution
77
- - repair: Scan and auto-repair corrupted plan YAML files
78
- - sync-agents: Force regenerate dummy-human agent .md files from maskweaver.config.json pool (reads project config first, falls back to ~/.config/opencode/maskweaver.config.json)
79
- - init-config: Create default maskweaver.config.json with pool template (does not overwrite existing)
80
-
81
- Examples:
82
- - weave init
83
- - weave research docs/
84
- - weave design docs/
85
- - weave refine-plan
86
- - weave approve-plan
87
- - weave craft P1
88
- - weave loop-run
89
- - weave loop-status loopId="docs-p1-loop-r1"
90
- - weave status
91
- - weave repair
92
- - weave sync-agents
93
- - weave init-config
94
- - weave troubleshoot "Cannot find module 'xyz'"`,
47
+ description: (() => {
48
+ const registry = loadCommandsJson();
49
+ const lines = [
50
+ 'Weave: Phase-driven development workflow with expert mask auto-selection and cross-project knowledge sharing.',
51
+ '',
52
+ 'Commands:',
53
+ ];
54
+ for (const cmd of registry.commands) {
55
+ const aliasText = cmd.aliases.length > 0 ? ` (aliases: ${cmd.aliases.join(', ')})` : '';
56
+ lines.push(`- ${cmd.name}${aliasText}: ${cmd.description}`);
57
+ }
58
+ lines.push('');
59
+ lines.push('Examples:');
60
+ for (const ex of registry.commands.flatMap((c) => c.examples).slice(0, 12)) {
61
+ lines.push(`- ${ex}`);
62
+ }
63
+ return lines.join('\n');
64
+ })(),
95
65
  args: {
96
- command: z.enum(['init', 'map', 'interview', 'research', 'spec', 'design', 'prepare', 'refine-plan', 'approve-plan', 'flow', 'craft', 'build', 'build-resume', 'status', 'worktree', 'verify', 'archive', 'loop-run', 'loop-start', 'loop-step', 'loop-status', 'loop-stop', 'loop-list', 'loop-sync', 'loop-watchdog', 'loop-poll', 'loop-operator', 'troubleshoot', 'record', 'help', 'repair', 'sync-agents', 'init-config'])
97
- .describe('Weave command to execute'),
66
+ command: z.string()
67
+ .describe('Weave command to execute. Run "help" for full list.'),
68
+ action: z.enum(['run', 'status', 'stop', 'list', 'resume', 'sync']).optional()
69
+ .describe('Build sub-action (for build command)'),
70
+ sync: z.boolean().optional()
71
+ .describe('Force regenerate agent .md files from config pool (for agents command)'),
72
+ init: z.boolean().optional()
73
+ .describe('Create default maskweaver.config.json with pool template (for agents command)'),
98
74
  docsPath: z.string().optional()
99
75
  .describe('Path to requirements documents (for design command)'),
100
76
  phaseId: z.string().optional()
101
- .describe('Phase ID (used by craft and approve-plan finalize flow)'),
77
+ .describe('Phase ID (used by craft and approve finalize flow)'),
102
78
  projectName: z.string().optional()
103
79
  .describe('Project name (for design command)'),
104
80
  planName: z.string().optional()
@@ -110,11 +86,11 @@ Examples:
110
86
  splitMaxHours: z.number().int().min(4).max(40).optional()
111
87
  .describe('Max estimated hours per shard when splitPlans is enabled (default: 10)'),
112
88
  planReview: z.string().optional()
113
- .describe('Plan review summary text (for approve-plan command)'),
89
+ .describe('Plan review summary text (for approve command)'),
114
90
  notesPath: z.string().optional()
115
91
  .describe('Path to structured plan notes (default: tasks/plan-notes.md)'),
116
92
  applyNotes: z.boolean().optional()
117
- .describe('Auto-apply plan notes during approve-plan (default: true)'),
93
+ .describe('Auto-apply plan notes during approve (default: true)'),
118
94
  worktreeAction: z.enum(['create', 'list', 'open', 'remove', 'merge']).optional()
119
95
  .describe('Worktree action (for worktree command)'),
120
96
  name: z.string().optional()
@@ -169,77 +145,68 @@ Examples:
169
145
  execute: async (args, context) => {
170
146
  const { command } = args;
171
147
  const basePath = context.worktree;
148
+ // Resolve command aliases and deprecation
149
+ const resolved = resolveCommand(command);
150
+ if ('error' in resolved) {
151
+ return `Error: ${resolved.error}`;
152
+ }
153
+ const { command: resolvedCmd, warning: deprecationWarning } = resolved;
154
+ const prefixWarning = deprecationWarning ? `${deprecationWarning}\n\n` : '';
172
155
  try {
173
- switch (command) {
156
+ let result;
157
+ switch (resolvedCmd) {
174
158
  case 'init':
175
- return await handleInit(basePath);
159
+ result = await handleInit(basePath);
160
+ break;
176
161
  case 'map':
177
- return await handleMap(args, basePath);
162
+ result = await handleMap(args, basePath);
163
+ break;
178
164
  case 'interview':
179
- return await handleInterview(args, basePath);
180
- case 'build':
181
- return await handleBuild(args, basePath);
182
- case 'build-resume':
183
- return await handleBuildResume(args, basePath);
184
- case 'research':
185
- return await handleResearch(args, basePath);
186
- case 'spec':
187
- return await handleSpec(args, basePath);
188
- case 'design':
189
- return await handleDesign(args, basePath);
165
+ result = await handleInterview(args, basePath);
166
+ break;
190
167
  case 'prepare':
191
- return await handlePrepare(args, basePath);
168
+ result = await handlePrepare(args, basePath);
169
+ break;
192
170
  case 'refine-plan':
193
- return await handleRefinePlan(args, basePath);
194
- case 'approve-plan':
195
- return await handleApprovePlan(args, basePath);
196
- case 'flow':
197
- return await handleFlow(args, basePath);
171
+ result = await handleRefinePlan(args, basePath);
172
+ break;
173
+ case 'approve':
174
+ result = await handleApprovePlan(args, basePath);
175
+ break;
198
176
  case 'craft':
199
- return await handleCraft(args, basePath);
177
+ result = await handleCraft(args, basePath);
178
+ break;
179
+ case 'build':
180
+ result = await handleBuildUnified(args, basePath);
181
+ break;
200
182
  case 'status':
201
- return await handleStatus(basePath);
183
+ result = await handleStatus(basePath);
184
+ break;
202
185
  case 'worktree':
203
- return await handleWorktree(args, basePath);
186
+ result = await handleWorktree(args, basePath);
187
+ break;
204
188
  case 'verify':
205
- return await handleVerify(args, basePath);
189
+ result = await handleVerify(args, basePath);
190
+ break;
206
191
  case 'archive':
207
- return await handleArchive(basePath);
208
- case 'loop-run':
209
- return await handleLoopRun(args, basePath);
210
- case 'loop-start':
211
- return await handleLoopStart(args, basePath);
212
- case 'loop-step':
213
- return await handleLoopStep(args, basePath);
214
- case 'loop-status':
215
- return await handleLoopStatus(args, basePath);
216
- case 'loop-stop':
217
- return await handleLoopStop(args, basePath);
218
- case 'loop-list':
219
- return await handleLoopList(basePath);
220
- case 'loop-sync':
221
- return await handleLoopSync(args, basePath);
222
- case 'loop-watchdog':
223
- return await handleLoopWatchdog(args, basePath);
224
- case 'loop-poll':
225
- return await handleLoopPoll(args, basePath);
226
- case 'loop-operator':
227
- return await handleLoopOperator(args, basePath);
192
+ result = await handleArchive(basePath);
193
+ break;
228
194
  case 'troubleshoot':
229
- return await handleTroubleshoot(args);
230
- case 'record':
231
- return await handleRecord(args);
195
+ result = await handleTroubleshoot(args);
196
+ break;
232
197
  case 'repair':
233
- return await handleRepair(basePath);
234
- case 'sync-agents':
235
- return await handleSyncAgents(basePath);
236
- case 'init-config':
237
- return await handleInitConfig(basePath);
198
+ result = await handleRepair(basePath);
199
+ break;
200
+ case 'agents':
201
+ result = await handleAgents(args, basePath);
202
+ break;
238
203
  case 'help':
239
- return getHelpMessage();
204
+ result = getHelpMessage();
205
+ break;
240
206
  default:
241
- return `Error: Unknown command: ${command}. Use 'help' for available commands.`;
207
+ result = `Error: Unknown command: ${command}. Use 'help' for available commands.`;
242
208
  }
209
+ return prefixWarning + result;
243
210
  }
244
211
  catch (e) {
245
212
  const error = e instanceof Error ? e.message : String(e);
@@ -742,7 +709,7 @@ function formatPlanApprovalRequired(basePath, plan) {
742
709
  `- Review research: \`${researchPath}\``,
743
710
  `- Review plan: \`${planPath}\``,
744
711
  '- (Optional) Apply note directives: `weave command=refine-plan`',
745
- '- Then run: `weave command=approve-plan`',
712
+ '- Then run: `weave command=approve`',
746
713
  ].join('\n');
747
714
  }
748
715
  const DEFAULT_PLAN_NOTES_PATH = path.join('tasks', 'plan-notes.md');
@@ -1361,7 +1328,7 @@ async function handleRefinePlan(args, basePath) {
1361
1328
  return [
1362
1329
  formatRefinePlanResult('## 📝 Plan Refined From Notes', outcome),
1363
1330
  '',
1364
- 'Review the updated plan, then run: `weave command=approve-plan`',
1331
+ 'Review the updated plan, then run: `weave command=approve`',
1365
1332
  ].join('\n');
1366
1333
  }
1367
1334
  async function handleApprovePlan(args, basePath) {
@@ -1408,7 +1375,7 @@ async function handleApprovePlan(args, basePath) {
1408
1375
  formatRefinePlanResult('## 📝 Plan Refined During Approve', outcome),
1409
1376
  '',
1410
1377
  'Approval paused after applying note directives.',
1411
- 'Review the updated plan and rerun: `weave command=approve-plan`',
1378
+ 'Review the updated plan and rerun: `weave command=approve`',
1412
1379
  ].join('\n');
1413
1380
  }
1414
1381
  }
@@ -1506,7 +1473,7 @@ async function handleDesign(args, basePath) {
1506
1473
  '',
1507
1474
  '---',
1508
1475
  '계획을 검토하고 구현 전에 승인하세요:',
1509
- '- `weave command=approve-plan`',
1476
+ '- `weave command=approve`',
1510
1477
  ].join('\n');
1511
1478
  }
1512
1479
  async function handleSpec(args, basePath) {
@@ -1540,30 +1507,61 @@ async function handlePrepare(args, basePath) {
1540
1507
  const resolvedDocsPath = resolveUnderBase(basePath, docsPath);
1541
1508
  const intakeResult = await intake({ docsPath: resolvedDocsPath });
1542
1509
  const gdcPrepareSync = await runGdcPrepareSync(basePath);
1543
- const researchResult = await writeResearchReport({
1544
- docsPath: resolvedDocsPath,
1545
- intake: intakeResult,
1546
- basePath,
1547
- projectName: projectName || 'My Project',
1548
- });
1549
1510
  const normalizedPlanName = normalizePlanName(args.planName, projectName, resolvedDocsPath);
1511
+ // Cache-aware skip: skip steps if artifacts already exist
1512
+ const researchPath = path.join(basePath, 'tasks', 'research.md');
1513
+ const specsDir = path.join(basePath, '.opencode', 'weave', 'specs');
1514
+ const plansDir = path.join(basePath, '.opencode', 'weave', 'plans');
1515
+ const hasResearch = fs.existsSync(researchPath);
1516
+ const hasSpec = (() => {
1517
+ try {
1518
+ return fs.readdirSync(specsDir).some(f => f.endsWith('.yaml') || f.endsWith('.yml'));
1519
+ }
1520
+ catch {
1521
+ return false;
1522
+ }
1523
+ })();
1524
+ const hasPlan = (() => {
1525
+ try {
1526
+ return fs.readdirSync(plansDir).some(f => f.endsWith('.yaml') || f.endsWith('.yml'));
1527
+ }
1528
+ catch {
1529
+ return false;
1530
+ }
1531
+ })();
1532
+ // Step 1: Research
1533
+ const researchResult = hasResearch
1534
+ ? {
1535
+ summary: `> ⏭️ Research skipped: \`${toWorkspaceRelative(basePath, researchPath)}\` already exists.`,
1536
+ reportPath: researchPath,
1537
+ }
1538
+ : await writeResearchReport({
1539
+ docsPath: resolvedDocsPath,
1540
+ intake: intakeResult,
1541
+ basePath,
1542
+ projectName: projectName || 'My Project',
1543
+ });
1550
1544
  // Step 2: Spec (baseline)
1551
- const specResult = await createSpec({
1552
- intake: intakeResult,
1553
- projectName: projectName || 'My Project',
1554
- specName: normalizedPlanName,
1555
- basePath,
1556
- });
1557
- // Prepare is the default "happy path": proceed with reasonable defaults.
1558
- const planResult = await plan({
1559
- intake: intakeResult,
1560
- projectName: projectName || 'My Project',
1561
- planName: normalizedPlanName,
1562
- basePath,
1563
- splitPlans: args.splitPlans,
1564
- splitMaxPhases: args.splitMaxPhases,
1565
- splitMaxHours: args.splitMaxHours,
1566
- });
1545
+ const specResult = hasSpec
1546
+ ? { summary: `> ⏭️ Spec skipped: existing artifact found in \`${toWorkspaceRelative(basePath, specsDir)}\`.` }
1547
+ : await createSpec({
1548
+ intake: intakeResult,
1549
+ projectName: projectName || 'My Project',
1550
+ specName: normalizedPlanName,
1551
+ basePath,
1552
+ });
1553
+ // Step 3: Plan
1554
+ const planResult = hasPlan
1555
+ ? { summary: `> ⏭️ Plan skipped: existing artifact found in \`${toWorkspaceRelative(basePath, plansDir)}\`.` }
1556
+ : await plan({
1557
+ intake: intakeResult,
1558
+ projectName: projectName || 'My Project',
1559
+ planName: normalizedPlanName,
1560
+ basePath,
1561
+ splitPlans: args.splitPlans,
1562
+ splitMaxPhases: args.splitMaxPhases,
1563
+ splitMaxHours: args.splitMaxHours,
1564
+ });
1567
1565
  await updateActivePlanReviewMetadata(basePath, {
1568
1566
  researchPath: researchResult.reportPath,
1569
1567
  resetApproval: true,
@@ -1594,7 +1592,7 @@ async function handlePrepare(args, basePath) {
1594
1592
  }
1595
1593
  lines.push('\n---\n');
1596
1594
  lines.push('다음 단계 (구현 전 승인 필수):');
1597
- lines.push('`weave command=approve-plan`');
1595
+ lines.push('`weave command=approve`');
1598
1596
  lines.push('그 다음 `weave craft P1` 또는 `weave flow`');
1599
1597
  return lines.join('\n');
1600
1598
  }
@@ -1847,7 +1845,7 @@ async function handleInterview(args, basePath) {
1847
1845
  lines.push(` - Status: ${sc.agreed ? '✅ Agreed' : '⏳ Pending approval'}`);
1848
1846
  }
1849
1847
  lines.push('');
1850
- lines.push('To proceed, agree to structural changes via `weave command=approve-plan`.');
1848
+ lines.push('To proceed, agree to structural changes via `weave command=approve`.');
1851
1849
  lines.push('');
1852
1850
  }
1853
1851
  lines.push('### Questions');
@@ -1873,7 +1871,7 @@ async function handleBuild(args, basePath) {
1873
1871
  return 'Error: No active plan found. Run `weave command=design docsPath="docs/"` first.';
1874
1872
  }
1875
1873
  if (!plan.planApproved) {
1876
- return 'Error: Plan not approved. Run `weave command=approve-plan` first.';
1874
+ return 'Error: Plan not approved. Run `weave command=approve` first.';
1877
1875
  }
1878
1876
  lines.push(`Plan: **${plan.projectName}** (approved at ${plan.planApprovedAt || 'N/A'})`);
1879
1877
  lines.push('');
@@ -2034,7 +2032,7 @@ async function handleCraft(args, basePath) {
2034
2032
  lines.push('');
2035
2033
  lines.push('- Implement/delegate the phase work using the execution plan above.');
2036
2034
  lines.push('- Run verification: `weave command=verify` (or your project test/build commands).');
2037
- lines.push(`- Finalize the phase when ready: \`weave command=approve-plan phaseId="${resolvedPhaseId}"\``);
2035
+ lines.push(`- Finalize the phase when ready: \`weave command=approve phaseId="${resolvedPhaseId}"\``);
2038
2036
  lines.push('- Check overall progress anytime: `weave command=status`.');
2039
2037
  await syncWorkflowArtifacts(basePath, manager, {
2040
2038
  phaseId: resolvedPhaseId,
@@ -2249,13 +2247,20 @@ async function handleVerify(args, basePath) {
2249
2247
  return verification.report;
2250
2248
  }
2251
2249
  async function handleTroubleshoot(args) {
2250
+ // Unified: record mode (absorbs old 'record' command)
2251
+ if (args.record) {
2252
+ if (!args.error || !args.solution) {
2253
+ return 'Error: error and solution are required when record=true. Example: weave command=troubleshoot record=true error="..." solution="..."';
2254
+ }
2255
+ return handleRecord(args);
2256
+ }
2252
2257
  const { error, projectType } = args;
2253
2258
  if (!error) {
2254
- return 'Error: error is required for troubleshoot command';
2259
+ return 'Error: error is required for troubleshoot command. Example: weave command=troubleshoot error="Cannot find module \'xyz\'"';
2255
2260
  }
2256
2261
  const solutions = await searchTroubleshooting(error, { projectType, limit: 5 });
2257
2262
  if (solutions.length === 0) {
2258
- return '유사한 해결책을 찾지 못했습니다.\n\n문제를 해결하신 후, `weave record`로 해결책을 기록해주세요.';
2263
+ return '유사한 해결책을 찾지 못했습니다.\n\n문제를 해결하신 후, `weave command=troubleshoot record=true solution="..."`로 해결책을 기록해주세요.';
2259
2264
  }
2260
2265
  const lines = ['## 💡 유사한 해결책 발견\n'];
2261
2266
  for (let i = 0; i < solutions.length; i++) {
@@ -2374,6 +2379,56 @@ async function handleInitConfig(basePath) {
2374
2379
  lines.push('> with your model pool, then run `weave sync-agents` in any project to apply it.');
2375
2380
  return lines.join('\n');
2376
2381
  }
2382
+ // ============================================================================
2383
+ // Unified Build Handler (absorbs build, build-resume, loop-*)
2384
+ // ============================================================================
2385
+ async function handleBuildUnified(args, basePath) {
2386
+ const action = args.action || 'run';
2387
+ switch (action) {
2388
+ case 'run':
2389
+ return handleBuild(args, basePath);
2390
+ case 'resume':
2391
+ return handleBuildResume(args, basePath);
2392
+ case 'status': {
2393
+ const loopId = args.buildId || args.loopId;
2394
+ if (!loopId)
2395
+ return 'Error: buildId or loopId is required for status action. Example: weave command=build action=status buildId="build-20250428-a1b2"';
2396
+ return handleLoopStatus({ loopId }, basePath);
2397
+ }
2398
+ case 'stop': {
2399
+ const loopId = args.buildId || args.loopId;
2400
+ if (!loopId)
2401
+ return 'Error: buildId or loopId is required for stop action. Example: weave command=build action=stop buildId="build-20250428-a1b2"';
2402
+ return handleLoopStop({ loopId, context: undefined }, basePath);
2403
+ }
2404
+ case 'list':
2405
+ return handleLoopList(basePath);
2406
+ case 'sync': {
2407
+ const loopId = args.buildId || args.loopId;
2408
+ if (!loopId)
2409
+ return 'Error: buildId or loopId is required for sync action. Example: weave command=build action=sync buildId="build-20250428-a1b2"';
2410
+ return handleLoopSync({ loopId }, basePath);
2411
+ }
2412
+ default:
2413
+ return `Error: Unknown build action: ${action}. Available: run, status, stop, list, resume, sync.`;
2414
+ }
2415
+ }
2416
+ // ============================================================================
2417
+ // Agents Handler (absorbs sync-agents, init-config)
2418
+ // ============================================================================
2419
+ async function handleAgents(args, basePath) {
2420
+ if (!args.sync && !args.init) {
2421
+ return 'Error: agents requires an action. Use `sync=true` to regenerate agent files, or `init=true` to create default config.';
2422
+ }
2423
+ const sections = [];
2424
+ if (args.sync) {
2425
+ sections.push(await handleSyncAgents(basePath));
2426
+ }
2427
+ if (args.init) {
2428
+ sections.push(await handleInitConfig(basePath));
2429
+ }
2430
+ return sections.join('\n\n---\n\n');
2431
+ }
2377
2432
  async function handleArchive(basePath) {
2378
2433
  const manager = getPhaseManager(basePath);
2379
2434
  const activePlan = await manager.loadPlan();
@@ -2945,7 +3000,7 @@ async function maybeAdvanceToNextShard(phaseManager, basePath) {
2945
3000
  return [
2946
3001
  `Auto-switched to shard plan: \`${nextPlan.planName}\` (${shardLabel}).`,
2947
3002
  'Review/approve this shard before implementation:',
2948
- '- `weave command=approve-plan`',
3003
+ '- `weave command=approve`',
2949
3004
  '- `weave command=craft`',
2950
3005
  ].join('\n');
2951
3006
  }
@@ -3130,77 +3185,56 @@ async function handleApprove(args, basePath) {
3130
3185
  ].filter(Boolean));
3131
3186
  }
3132
3187
  function getHelpMessage() {
3133
- return `## Weave Workflow Help (Maskweaver v${VERSION})
3134
-
3135
- **Weave** is Maskweaver's Phase-Driven Development workflow.
3136
- "AI verifies, User confirms"
3137
-
3138
- ### Version
3139
-
3140
- \`Maskweaver v${VERSION}\`
3141
-
3142
- To check installed version:
3143
- - CLI: \`maskweaver --version\`
3144
- - In chat: use \`maskweaver_status\` tool
3145
- - npm: \`npm list maskweaver\`
3146
-
3147
- ### Commands
3148
-
3149
- | Command | Description |
3150
- |---------|-------------|
3151
- | \`weave init\` | Initialize weave workspace (.ignore + state/plans) and probe GDC |
3152
- | \`weave research [docs]\` | Deep-read docs + workspace context and write persistent research.md |
3153
- | \`weave spec [docs]\` | Generate baseline spec (requirements + AC) |
3154
- | \`weave prepare [docs]\` | Create spec + phase plan (auto-splits oversized plans) |
3155
- | \`weave refine-plan\` | Apply structured plan-note directives to active plan |
3156
- | \`weave approve-plan\` | Approve plan, or finalize a phase with \`phaseId\` |
3157
- | \`weave flow [docs]\` | One-command path (prepare -> auto-approve -> craft -> verify -> finalize) |
3158
- | \`weave design [docs]\` | Analyze requirements and create phase plan (auto-splits oversized plans) |
3159
- | \`weave craft [id]\` | Prepare execution context for a phase |
3160
- | \`weave status\` | View progress |
3161
- | \`weave worktree ...\` | Manage git worktrees for parallel work |
3162
- | \`weave verify\` | Run build/test verification for current worktree |
3163
- | \`weave archive\` | Archive the verified active change artifact |
3164
- | \`weave loop-run\` | Create and execute a bounded loop for the active change |
3165
- | \`weave loop-start\` | Create a loop run without executing it |
3166
- | \`weave loop-step\` | Execute one loop iteration for an existing loopId |
3167
- | \`weave loop-status\` | Inspect a loop run by loopId |
3168
- | \`weave loop-stop\` | Request a semantic stop for a loop run |
3169
- | \`weave loop-list\` | List known loop runs |
3170
- | \`weave loop-sync\` | Pull delegated squad results back into a loop run |
3171
- | \`weave loop-watchdog\` | Scan delegated loops and auto-sync completed runs |
3172
- | \`weave loop-poll\` | Bounded wait loop for delegated completion |
3173
- | \`weave loop-operator\` | Recurring operator run with state + lock artifacts |
3174
- | \`weave repair\` | Scan and auto-repair corrupted plan YAML files |
3175
- | \`weave troubleshoot [error]\` | Search global knowledge for solutions |
3176
- | \`weave record [solution]\` | Record a new solution |
3177
- | \`weave help\` | Show this help |
3178
-
3179
- ### Key Features
3180
-
3181
- - **Mask Auto-Selection**: Automatically applies expert masks for phase execution
3182
- - **Global Knowledge Sharing**: Cross-project troubleshooting experience
3183
- - **Auto-Verification**: Build + Self-Verify Loop
3184
- - **YAML Auto-Repair**: Automatically detects and fixes corrupted plan files
3185
-
3186
- ### Quick Start
3187
-
3188
- \`\`\`
3189
- weave init # Initialize weave + probe GDC
3190
- weave prepare docs/ # Research + spec + plan
3191
- weave refine-plan # Apply plan-notes directives (optional)
3192
- weave approve-plan # Explicit approval gate
3193
- weave approve-plan phaseId="P1" # Finalize crafted phase P1
3194
- weave flow # One-shot: prepare/approve/craft/verify/finalize
3195
- weave craft # Prepare current phase execution context
3196
- weave loop-run # Run bounded loop for the active change
3197
- weave loop-status loopId="docs-p1-loop-r1" # Inspect a specific loop run
3198
- weave loop-sync loopId="docs-p1-loop-r1" # Resume after delegated workers finish
3199
- weave loop-watchdog # Scan all delegated loops once
3200
- weave loop-poll loopId="docs-p1-loop-r1" # Wait for delegated completion and resume automatically
3201
- weave loop-operator # Automation-friendly recurring operator pass
3202
- weave archive # Archive verified active change
3203
- \`\`\`
3188
+ const registry = loadCommandsJson();
3189
+ const commandRows = registry.commands
3190
+ .map(cmd => {
3191
+ const aliasText = cmd.aliases.length > 0 ? ` (${cmd.aliases.join(', ')})` : '';
3192
+ return `| \`weave ${cmd.name}\`${aliasText} | ${cmd.description} |`;
3193
+ })
3194
+ .join('\n ');
3195
+ return `## Weave Workflow Help (Maskweaver v${VERSION})
3196
+
3197
+ **Weave** is Maskweaver's Phase-Driven Development workflow.
3198
+ "AI verifies, User confirms"
3199
+
3200
+ ### Version
3201
+
3202
+ \`Maskweaver v${VERSION}\`
3203
+
3204
+ To check installed version:
3205
+ - CLI: \`maskweaver --version\`
3206
+ - In chat: use \`maskweaver_status\` tool
3207
+ - npm: \`npm list maskweaver\`
3208
+
3209
+ ### Commands
3210
+
3211
+ | Command | Description |
3212
+ |---------|-------------|
3213
+ ${commandRows}
3214
+
3215
+ ### Key Features
3216
+
3217
+ - **Mask Auto-Selection**: Automatically applies expert masks for phase execution
3218
+ - **Global Knowledge Sharing**: Cross-project troubleshooting experience
3219
+ - **Auto-Verification**: Build + Self-Verify Loop
3220
+ - **YAML Auto-Repair**: Automatically detects and fixes corrupted plan files
3221
+
3222
+ ### Quick Start
3223
+
3224
+ \`\`\`
3225
+ weave init # Initialize weave + probe GDC
3226
+ weave prepare docs/ # Research + spec + plan
3227
+ weave refine-plan # Apply plan-notes directives (optional)
3228
+ weave approve # Explicit approval gate
3229
+ weave approve phaseId="P1" # Finalize crafted phase P1
3230
+ weave craft # Prepare current phase execution context
3231
+ weave build # Ralph-loop autonomous execution
3232
+ weave build action=status buildId="..." # Inspect a specific build
3233
+ weave build action=resume buildId="..." # Resume a blocked build
3234
+ weave status # View overall progress
3235
+ weave verify # Run build/test verification
3236
+ weave archive # Archive verified active change
3237
+ \`\`\`
3204
3238
  `;
3205
3239
  }
3206
3240
  function evaluatePlanGate(phase) {