@lumenflow/mcp 2.18.3 → 2.20.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 (49) hide show
  1. package/dist/tools/agent-tools.d.ts +26 -0
  2. package/dist/tools/agent-tools.d.ts.map +1 -0
  3. package/dist/tools/agent-tools.js +161 -0
  4. package/dist/tools/agent-tools.js.map +1 -0
  5. package/dist/tools/context-tools.d.ts +19 -0
  6. package/dist/tools/context-tools.d.ts.map +1 -0
  7. package/dist/tools/context-tools.js +73 -0
  8. package/dist/tools/context-tools.js.map +1 -0
  9. package/dist/tools/flow-tools.d.ts +30 -0
  10. package/dist/tools/flow-tools.d.ts.map +1 -0
  11. package/dist/tools/flow-tools.js +141 -0
  12. package/dist/tools/flow-tools.js.map +1 -0
  13. package/dist/tools/initiative-tools.d.ts +42 -0
  14. package/dist/tools/initiative-tools.d.ts.map +1 -0
  15. package/dist/tools/initiative-tools.js +304 -0
  16. package/dist/tools/initiative-tools.js.map +1 -0
  17. package/dist/tools/memory-tools.d.ts +66 -0
  18. package/dist/tools/memory-tools.d.ts.map +1 -0
  19. package/dist/tools/memory-tools.js +419 -0
  20. package/dist/tools/memory-tools.js.map +1 -0
  21. package/dist/tools/orchestration-tools.d.ts +26 -0
  22. package/dist/tools/orchestration-tools.d.ts.map +1 -0
  23. package/dist/tools/orchestration-tools.js +158 -0
  24. package/dist/tools/orchestration-tools.js.map +1 -0
  25. package/dist/tools/parity-tools.d.ts +118 -0
  26. package/dist/tools/parity-tools.d.ts.map +1 -0
  27. package/dist/tools/parity-tools.js +897 -0
  28. package/dist/tools/parity-tools.js.map +1 -0
  29. package/dist/tools/setup-tools.d.ts +42 -0
  30. package/dist/tools/setup-tools.d.ts.map +1 -0
  31. package/dist/tools/setup-tools.js +167 -0
  32. package/dist/tools/setup-tools.js.map +1 -0
  33. package/dist/tools/validation-tools.d.ts +34 -0
  34. package/dist/tools/validation-tools.d.ts.map +1 -0
  35. package/dist/tools/validation-tools.js +134 -0
  36. package/dist/tools/validation-tools.js.map +1 -0
  37. package/dist/tools/wu-tools.d.ts +111 -0
  38. package/dist/tools/wu-tools.d.ts.map +1 -0
  39. package/dist/tools/wu-tools.js +768 -0
  40. package/dist/tools/wu-tools.js.map +1 -0
  41. package/dist/tools-shared.d.ts +170 -0
  42. package/dist/tools-shared.d.ts.map +1 -0
  43. package/dist/tools-shared.js +203 -0
  44. package/dist/tools-shared.js.map +1 -0
  45. package/dist/tools.d.ts +34 -466
  46. package/dist/tools.d.ts.map +1 -1
  47. package/dist/tools.js +55 -3323
  48. package/dist/tools.js.map +1 -1
  49. package/package.json +4 -4
@@ -0,0 +1,768 @@
1
+ /**
2
+ * @file wu-tools.ts
3
+ * @description WU lifecycle tool implementations (create, claim, done, block, edit, etc.)
4
+ *
5
+ * WU-1642: Extracted from tools.ts during domain decomposition.
6
+ * WU-1412: Core WU tools: wu_status, wu_create, wu_claim, wu_done, gates_run
7
+ * WU-1422: Additional WU tools
8
+ * WU-1431: Uses shared Zod schemas from @lumenflow/core for CLI/MCP parity
9
+ * WU-1454: All 16 WU lifecycle commands now use shared schemas
10
+ */
11
+ import { z } from 'zod';
12
+ import { wuCreateSchema, wuClaimSchema, wuStatusSchema, wuDoneSchema, gatesSchema,
13
+ // WU-1454: Lifecycle command schemas
14
+ wuBlockSchema, wuUnblockSchema, wuEditSchema, wuReleaseSchema, wuRecoverSchema, wuRepairSchema, wuDepsSchema, wuPrepSchema, wuPreflightSchema, wuPruneSchema, wuDeleteSchema, wuCleanupSchema, wuSpawnSchema, wuValidateSchema, wuInferLaneSchema, wuUnlockLaneSchema, } from '@lumenflow/core';
15
+ import { ErrorCodes, ErrorMessages, CliArgs, SuccessMessages, getCore, success, error, buildWuPromptArgs, runCliCommand, } from '../tools-shared.js';
16
+ /**
17
+ * wu_status - Get status of a specific WU
18
+ * Uses CLI shell-out for consistency
19
+ *
20
+ * WU-1431: Uses shared wuStatusSchema for parity with CLI
21
+ * Note: CLI allows id to be optional (auto-detect from worktree), but MCP requires it
22
+ * since there's no "current directory" concept for MCP clients
23
+ */
24
+ export const wuStatusTool = {
25
+ name: 'wu_status',
26
+ description: 'Get detailed status of a specific Work Unit',
27
+ // WU-1431: Extend shared schema to require id for MCP (CLI allows optional for auto-detect)
28
+ inputSchema: wuStatusSchema.extend({
29
+ id: z.string().describe('WU ID (e.g., WU-1412)'),
30
+ }),
31
+ async execute(input, options) {
32
+ if (!input.id) {
33
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
34
+ }
35
+ const args = ['--id', input.id, '--json'];
36
+ const cliOptions = { projectRoot: options?.projectRoot };
37
+ const result = await runCliCommand('wu:status', args, cliOptions);
38
+ if (result.success) {
39
+ try {
40
+ const data = JSON.parse(result.stdout);
41
+ return success(data);
42
+ }
43
+ catch {
44
+ return success({ message: result.stdout });
45
+ }
46
+ }
47
+ else {
48
+ return error(result.stderr || result.error?.message || 'wu:status failed', ErrorCodes.WU_STATUS_ERROR);
49
+ }
50
+ },
51
+ };
52
+ /**
53
+ * wu_create - Create a new WU
54
+ *
55
+ * WU-1431: Uses shared wuCreateSchema for CLI/MCP parity
56
+ */
57
+ export const wuCreateTool = {
58
+ name: 'wu_create',
59
+ description: 'Create a new Work Unit specification',
60
+ // WU-1431: Use shared schema - CLI-only aliases are not exposed here
61
+ inputSchema: wuCreateSchema,
62
+ async execute(input, options) {
63
+ if (!input.lane) {
64
+ return error(ErrorMessages.LANE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
65
+ }
66
+ if (!input.title) {
67
+ return error(ErrorMessages.TITLE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
68
+ }
69
+ const args = ['--lane', input.lane, '--title', input.title];
70
+ if (input.id)
71
+ args.push('--id', input.id);
72
+ if (input.description)
73
+ args.push(CliArgs.DESCRIPTION, input.description);
74
+ if (input.acceptance) {
75
+ for (const criterion of input.acceptance) {
76
+ args.push('--acceptance', criterion);
77
+ }
78
+ }
79
+ if (input.code_paths) {
80
+ for (const p of input.code_paths) {
81
+ args.push(CliArgs.CODE_PATHS, p);
82
+ }
83
+ }
84
+ if (input.exposure)
85
+ args.push('--exposure', input.exposure);
86
+ const cliOptions = { projectRoot: options?.projectRoot };
87
+ const result = await runCliCommand('wu:create', args, cliOptions);
88
+ if (result.success) {
89
+ return success({ message: result.stdout || 'WU created successfully' });
90
+ }
91
+ else {
92
+ return error(result.stderr || result.error?.message || 'wu:create failed', ErrorCodes.WU_CREATE_ERROR);
93
+ }
94
+ },
95
+ };
96
+ /**
97
+ * wu_claim - Claim a WU and create worktree
98
+ *
99
+ * WU-1431: Uses shared wuClaimSchema for CLI/MCP parity
100
+ * WU-1491: Supports --cloud, --branch-only, and --pr-mode passthrough
101
+ */
102
+ const wuClaimToolSchema = wuClaimSchema.extend({
103
+ sandbox: z
104
+ .boolean()
105
+ .optional()
106
+ .describe('Launch post-claim session through wu:sandbox (requires sandbox_command in MCP)'),
107
+ sandbox_command: z
108
+ .array(z.string())
109
+ .optional()
110
+ .describe('Command argv to run with --sandbox (e.g., ["node", "-v"])'),
111
+ });
112
+ export const wuClaimTool = {
113
+ name: 'wu_claim',
114
+ description: 'Claim a Work Unit and create worktree for implementation',
115
+ // WU-1431: Extend shared schema with MCP-safe sandbox launch controls
116
+ inputSchema: wuClaimToolSchema,
117
+ async execute(input, options) {
118
+ if (!input.id) {
119
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
120
+ }
121
+ if (!input.lane) {
122
+ return error(ErrorMessages.LANE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
123
+ }
124
+ const args = ['--id', input.id, '--lane', input.lane];
125
+ // WU-1491: Pass mode flags through to CLI
126
+ if (input.cloud)
127
+ args.push('--cloud');
128
+ if (input.branch_only)
129
+ args.push('--branch-only');
130
+ if (input.pr_mode)
131
+ args.push('--pr-mode');
132
+ if (input.sandbox) {
133
+ const sandboxCommand = Array.isArray(input.sandbox_command)
134
+ ? input.sandbox_command
135
+ : [];
136
+ if (sandboxCommand.length === 0) {
137
+ return error('sandbox_command is required when sandbox=true for MCP execution', ErrorCodes.MISSING_PARAMETER);
138
+ }
139
+ args.push('--sandbox', '--', ...sandboxCommand);
140
+ }
141
+ const cliOptions = { projectRoot: options?.projectRoot };
142
+ const result = await runCliCommand('wu:claim', args, cliOptions);
143
+ if (result.success) {
144
+ return success({ message: result.stdout || 'WU claimed successfully' });
145
+ }
146
+ else {
147
+ return error(result.stderr || result.error?.message || 'wu:claim failed', ErrorCodes.WU_CLAIM_ERROR);
148
+ }
149
+ },
150
+ };
151
+ /**
152
+ * wu_sandbox - Execute a command through the sandbox backend for this platform
153
+ */
154
+ const wuSandboxSchema = z.object({
155
+ id: z.string().describe('WU ID (e.g., WU-1687)'),
156
+ worktree: z.string().optional().describe('Optional worktree path override'),
157
+ command: z
158
+ .array(z.string())
159
+ .min(1)
160
+ .describe('Command argv to execute (e.g., ["node", "-e", "process.exit(0)"])'),
161
+ });
162
+ export const wuSandboxTool = {
163
+ name: 'wu_sandbox',
164
+ description: 'Run a command through the hardened WU sandbox backend',
165
+ inputSchema: wuSandboxSchema,
166
+ async execute(input, options) {
167
+ if (!input.id) {
168
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
169
+ }
170
+ const command = Array.isArray(input.command) ? input.command : [];
171
+ if (command.length === 0) {
172
+ return error('command is required', ErrorCodes.MISSING_PARAMETER);
173
+ }
174
+ const args = ['--id', input.id];
175
+ if (input.worktree) {
176
+ args.push('--worktree', input.worktree);
177
+ }
178
+ args.push('--', ...command);
179
+ const cliOptions = { projectRoot: options?.projectRoot };
180
+ const result = await runCliCommand('wu:sandbox', args, cliOptions);
181
+ if (result.success) {
182
+ return success({ message: result.stdout || 'WU sandbox command completed successfully' });
183
+ }
184
+ else {
185
+ return error(result.stderr || result.error?.message || 'wu:sandbox failed', ErrorCodes.WU_CLAIM_ERROR);
186
+ }
187
+ },
188
+ };
189
+ /**
190
+ * wu_done - Complete a WU (must be run from main checkout)
191
+ *
192
+ * WU-1431: Uses shared wuDoneSchema for CLI/MCP parity
193
+ */
194
+ export const wuDoneTool = {
195
+ name: 'wu_done',
196
+ description: 'Complete a Work Unit (merge, stamp, cleanup). MUST be run from main checkout.',
197
+ // WU-1431: Use shared schema
198
+ inputSchema: wuDoneSchema,
199
+ async execute(input, options) {
200
+ if (!input.id) {
201
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
202
+ }
203
+ // Fail fast if not on main checkout (AC: wu_done fails fast if not on main checkout)
204
+ try {
205
+ const core = await getCore();
206
+ const context = await core.computeWuContext({
207
+ cwd: options?.projectRoot,
208
+ });
209
+ if (context.location.type === 'worktree') {
210
+ return error('wu_done must be run from main checkout, not from a worktree. ' +
211
+ 'Run "pnpm wu:prep" first from the worktree, then cd to main and run wu:done.', ErrorCodes.WRONG_LOCATION);
212
+ }
213
+ }
214
+ catch {
215
+ // If we can't determine context, proceed anyway - CLI will validate
216
+ }
217
+ const args = ['--id', input.id];
218
+ if (input.skip_gates) {
219
+ args.push('--skip-gates');
220
+ if (input.reason)
221
+ args.push('--reason', input.reason);
222
+ if (input.fix_wu)
223
+ args.push('--fix-wu', input.fix_wu);
224
+ }
225
+ const cliOptions = { projectRoot: options?.projectRoot };
226
+ const result = await runCliCommand('wu:done', args, cliOptions);
227
+ if (result.success) {
228
+ return success({ message: result.stdout || 'WU completed successfully' });
229
+ }
230
+ else {
231
+ return error(result.stderr || result.error?.message || 'wu:done failed', ErrorCodes.WU_DONE_ERROR);
232
+ }
233
+ },
234
+ };
235
+ /**
236
+ * gates_run - Run quality gates
237
+ *
238
+ * WU-1431: Uses shared gatesSchema for CLI/MCP parity
239
+ */
240
+ export const gatesRunTool = {
241
+ name: 'gates_run',
242
+ description: 'Run LumenFlow quality gates (lint, typecheck, tests)',
243
+ // WU-1431: Use shared schema
244
+ inputSchema: gatesSchema,
245
+ async execute(input, options) {
246
+ const args = [];
247
+ if (input.docs_only) {
248
+ args.push(CliArgs.DOCS_ONLY);
249
+ }
250
+ const cliOptions = {
251
+ projectRoot: options?.projectRoot,
252
+ timeout: 600000, // 10 minutes for gates
253
+ };
254
+ const result = await runCliCommand('gates', args, cliOptions);
255
+ if (result.success) {
256
+ return success({ message: result.stdout || SuccessMessages.ALL_GATES_PASSED });
257
+ }
258
+ else {
259
+ return error(result.stderr || result.error?.message || 'Gates failed', ErrorCodes.GATES_ERROR);
260
+ }
261
+ },
262
+ };
263
+ /**
264
+ * wu_block - Block a WU and move it to blocked status
265
+ */
266
+ export const wuBlockTool = {
267
+ name: 'wu_block',
268
+ description: 'Block a Work Unit and move it from in_progress to blocked status',
269
+ // WU-1454: Use shared schema
270
+ inputSchema: wuBlockSchema,
271
+ async execute(input, options) {
272
+ if (!input.id) {
273
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
274
+ }
275
+ if (!input.reason) {
276
+ return error(ErrorMessages.REASON_REQUIRED, ErrorCodes.MISSING_PARAMETER);
277
+ }
278
+ const args = ['--id', input.id, '--reason', input.reason];
279
+ if (input.remove_worktree) {
280
+ args.push('--remove-worktree');
281
+ }
282
+ const cliOptions = { projectRoot: options?.projectRoot };
283
+ const result = await runCliCommand('wu:block', args, cliOptions);
284
+ if (result.success) {
285
+ return success({ message: result.stdout || 'WU blocked successfully' });
286
+ }
287
+ else {
288
+ return error(result.stderr || result.error?.message || 'wu:block failed', ErrorCodes.WU_BLOCK_ERROR);
289
+ }
290
+ },
291
+ };
292
+ /**
293
+ * wu_unblock - Unblock a WU and move it back to in_progress status
294
+ */
295
+ export const wuUnblockTool = {
296
+ name: 'wu_unblock',
297
+ description: 'Unblock a Work Unit and move it from blocked to in_progress status',
298
+ // WU-1454: Use shared schema
299
+ inputSchema: wuUnblockSchema,
300
+ async execute(input, options) {
301
+ if (!input.id) {
302
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
303
+ }
304
+ const args = ['--id', input.id];
305
+ if (input.reason)
306
+ args.push('--reason', input.reason);
307
+ if (input.create_worktree)
308
+ args.push('--create-worktree');
309
+ const cliOptions = { projectRoot: options?.projectRoot };
310
+ const result = await runCliCommand('wu:unblock', args, cliOptions);
311
+ if (result.success) {
312
+ return success({ message: result.stdout || 'WU unblocked successfully' });
313
+ }
314
+ else {
315
+ return error(result.stderr || result.error?.message || 'wu:unblock failed', ErrorCodes.WU_UNBLOCK_ERROR);
316
+ }
317
+ },
318
+ };
319
+ /**
320
+ * wu_edit - Edit WU spec fields
321
+ */
322
+ export const wuEditTool = {
323
+ name: 'wu_edit',
324
+ description: 'Edit Work Unit spec fields with micro-worktree isolation',
325
+ // WU-1454: Use shared schema
326
+ inputSchema: wuEditSchema,
327
+ async execute(input, options) {
328
+ if (!input.id) {
329
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
330
+ }
331
+ const args = ['--id', input.id];
332
+ if (input.description)
333
+ args.push(CliArgs.DESCRIPTION, input.description);
334
+ if (input.acceptance) {
335
+ for (const criterion of input.acceptance) {
336
+ args.push('--acceptance', criterion);
337
+ }
338
+ }
339
+ if (input.notes)
340
+ args.push('--notes', input.notes);
341
+ if (input.code_paths) {
342
+ for (const p of input.code_paths) {
343
+ args.push(CliArgs.CODE_PATHS, p);
344
+ }
345
+ }
346
+ if (input.lane)
347
+ args.push('--lane', input.lane);
348
+ if (input.priority)
349
+ args.push('--priority', input.priority);
350
+ if (input.initiative)
351
+ args.push(CliArgs.INITIATIVE, input.initiative);
352
+ if (input.phase)
353
+ args.push(CliArgs.PHASE, String(input.phase));
354
+ if (input.no_strict)
355
+ args.push('--no-strict');
356
+ const cliOptions = { projectRoot: options?.projectRoot };
357
+ const result = await runCliCommand('wu:edit', args, cliOptions);
358
+ if (result.success) {
359
+ return success({ message: result.stdout || 'WU edited successfully' });
360
+ }
361
+ else {
362
+ return error(result.stderr || result.error?.message || 'wu:edit failed', ErrorCodes.WU_EDIT_ERROR);
363
+ }
364
+ },
365
+ };
366
+ /**
367
+ * wu_release - Release an orphaned WU from in_progress to ready status
368
+ */
369
+ export const wuReleaseTool = {
370
+ name: 'wu_release',
371
+ description: 'Release an orphaned WU from in_progress back to ready state for reclaiming',
372
+ // WU-1454: Use shared schema
373
+ inputSchema: wuReleaseSchema,
374
+ async execute(input, options) {
375
+ if (!input.id) {
376
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
377
+ }
378
+ const args = ['--id', input.id];
379
+ if (input.reason)
380
+ args.push('--reason', input.reason);
381
+ const cliOptions = { projectRoot: options?.projectRoot };
382
+ const result = await runCliCommand('wu:release', args, cliOptions);
383
+ if (result.success) {
384
+ return success({ message: result.stdout || 'WU released successfully' });
385
+ }
386
+ else {
387
+ return error(result.stderr || result.error?.message || 'wu:release failed', ErrorCodes.WU_RELEASE_ERROR);
388
+ }
389
+ },
390
+ };
391
+ /**
392
+ * wu_recover - Analyze and fix WU state inconsistencies
393
+ */
394
+ export const wuRecoverTool = {
395
+ name: 'wu_recover',
396
+ description: 'Analyze and fix WU state inconsistencies',
397
+ // WU-1454: Use shared schema
398
+ inputSchema: wuRecoverSchema,
399
+ async execute(input, options) {
400
+ if (!input.id) {
401
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
402
+ }
403
+ const args = ['--id', input.id];
404
+ if (input.action)
405
+ args.push('--action', input.action);
406
+ if (input.force)
407
+ args.push('--force');
408
+ if (input.json)
409
+ args.push(CliArgs.JSON);
410
+ const cliOptions = { projectRoot: options?.projectRoot };
411
+ const result = await runCliCommand('wu:recover', args, cliOptions);
412
+ if (result.success) {
413
+ try {
414
+ const data = JSON.parse(result.stdout);
415
+ return success(data);
416
+ }
417
+ catch {
418
+ return success({ message: result.stdout || 'WU recovered successfully' });
419
+ }
420
+ }
421
+ else {
422
+ return error(result.stderr || result.error?.message || 'wu:recover failed', ErrorCodes.WU_RECOVER_ERROR);
423
+ }
424
+ },
425
+ };
426
+ /**
427
+ * wu_repair - Unified WU repair tool for state issues
428
+ */
429
+ export const wuRepairTool = {
430
+ name: 'wu_repair',
431
+ description: 'Unified WU repair tool - detect and fix WU state issues',
432
+ // WU-1454: Use shared schema
433
+ inputSchema: wuRepairSchema,
434
+ async execute(input, options) {
435
+ const args = [];
436
+ if (input.id)
437
+ args.push('--id', input.id);
438
+ if (input.check)
439
+ args.push('--check');
440
+ if (input.all)
441
+ args.push('--all');
442
+ if (input.claim)
443
+ args.push('--claim');
444
+ if (input.admin)
445
+ args.push('--admin');
446
+ if (input.repair_state)
447
+ args.push('--repair-state');
448
+ const cliOptions = { projectRoot: options?.projectRoot };
449
+ const result = await runCliCommand('wu:repair', args, cliOptions);
450
+ if (result.success) {
451
+ return success({ message: result.stdout || 'WU repair completed' });
452
+ }
453
+ else {
454
+ return error(result.stderr || result.error?.message || 'wu:repair failed', ErrorCodes.WU_REPAIR_ERROR);
455
+ }
456
+ },
457
+ };
458
+ /**
459
+ * wu_deps - Visualize WU dependency graph
460
+ */
461
+ export const wuDepsTool = {
462
+ name: 'wu_deps',
463
+ description: 'Visualize WU dependency graph',
464
+ // WU-1454: Use shared schema
465
+ inputSchema: wuDepsSchema,
466
+ async execute(input, options) {
467
+ if (!input.id) {
468
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
469
+ }
470
+ const args = ['--id', input.id];
471
+ if (input.format)
472
+ args.push('--format', input.format);
473
+ if (input.depth)
474
+ args.push('--depth', String(input.depth));
475
+ if (input.direction)
476
+ args.push('--direction', input.direction);
477
+ const cliOptions = { projectRoot: options?.projectRoot };
478
+ const result = await runCliCommand('wu:deps', args, cliOptions);
479
+ if (result.success) {
480
+ try {
481
+ const data = JSON.parse(result.stdout);
482
+ return success(data);
483
+ }
484
+ catch {
485
+ return success({ message: result.stdout });
486
+ }
487
+ }
488
+ else {
489
+ return error(result.stderr || result.error?.message || 'wu:deps failed', ErrorCodes.WU_DEPS_ERROR);
490
+ }
491
+ },
492
+ };
493
+ /**
494
+ * wu_prep - Prepare WU for completion (run gates in worktree)
495
+ */
496
+ export const wuPrepTool = {
497
+ name: 'wu_prep',
498
+ description: 'Prepare WU for completion by running gates in worktree',
499
+ // WU-1454: Use shared schema
500
+ inputSchema: wuPrepSchema,
501
+ async execute(input, options) {
502
+ if (!input.id) {
503
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
504
+ }
505
+ const args = ['--id', input.id];
506
+ if (input.docs_only)
507
+ args.push(CliArgs.DOCS_ONLY);
508
+ if (input.full_tests)
509
+ args.push('--full-tests');
510
+ const cliOptions = {
511
+ projectRoot: options?.projectRoot,
512
+ timeout: 600000, // 10 minutes for gates
513
+ };
514
+ const result = await runCliCommand('wu:prep', args, cliOptions);
515
+ if (result.success) {
516
+ return success({ message: result.stdout || 'WU prep completed' });
517
+ }
518
+ else {
519
+ return error(result.stderr || result.error?.message || 'wu:prep failed', ErrorCodes.WU_PREP_ERROR);
520
+ }
521
+ },
522
+ };
523
+ /**
524
+ * wu_preflight - Fast validation before gates run
525
+ */
526
+ export const wuPreflightTool = {
527
+ name: 'wu_preflight',
528
+ description: 'Fast validation of code_paths and test paths before gates run (under 5 seconds vs 2+ minutes)',
529
+ // WU-1454: Use shared schema
530
+ inputSchema: wuPreflightSchema,
531
+ async execute(input, options) {
532
+ if (!input.id) {
533
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
534
+ }
535
+ const args = ['--id', input.id];
536
+ if (input.worktree)
537
+ args.push('--worktree', input.worktree);
538
+ const cliOptions = { projectRoot: options?.projectRoot };
539
+ const result = await runCliCommand('wu:preflight', args, cliOptions);
540
+ if (result.success) {
541
+ return success({ message: result.stdout || 'Preflight checks passed' });
542
+ }
543
+ else {
544
+ return error(result.stderr || result.error?.message || 'wu:preflight failed', ErrorCodes.WU_PREFLIGHT_ERROR);
545
+ }
546
+ },
547
+ };
548
+ /**
549
+ * wu_prune - Clean stale worktrees
550
+ */
551
+ export const wuPruneTool = {
552
+ name: 'wu_prune',
553
+ description: 'Clean stale worktrees (dry-run by default)',
554
+ // WU-1454: Use shared schema
555
+ inputSchema: wuPruneSchema,
556
+ async execute(input, options) {
557
+ const args = [];
558
+ if (input.execute)
559
+ args.push('--execute');
560
+ const cliOptions = { projectRoot: options?.projectRoot };
561
+ const result = await runCliCommand('wu:prune', args, cliOptions);
562
+ if (result.success) {
563
+ return success({ message: result.stdout || 'Prune completed' });
564
+ }
565
+ else {
566
+ return error(result.stderr || result.error?.message || 'wu:prune failed', ErrorCodes.WU_PRUNE_ERROR);
567
+ }
568
+ },
569
+ };
570
+ /**
571
+ * wu_delete - Safely delete WU YAML files
572
+ */
573
+ export const wuDeleteTool = {
574
+ name: 'wu_delete',
575
+ description: 'Safely delete WU YAML files with micro-worktree isolation',
576
+ // WU-1454: Use shared schema
577
+ inputSchema: wuDeleteSchema,
578
+ async execute(input, options) {
579
+ if (!input.id && !input.batch) {
580
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
581
+ }
582
+ const args = [];
583
+ if (input.id)
584
+ args.push('--id', input.id);
585
+ if (input.dry_run)
586
+ args.push(CliArgs.DRY_RUN);
587
+ if (input.batch)
588
+ args.push('--batch', input.batch);
589
+ const cliOptions = { projectRoot: options?.projectRoot };
590
+ const result = await runCliCommand('wu:delete', args, cliOptions);
591
+ if (result.success) {
592
+ return success({ message: result.stdout || 'WU deleted' });
593
+ }
594
+ else {
595
+ return error(result.stderr || result.error?.message || 'wu:delete failed', ErrorCodes.WU_DELETE_ERROR);
596
+ }
597
+ },
598
+ };
599
+ /**
600
+ * wu_cleanup - Clean up worktree and branch after PR merge
601
+ */
602
+ export const wuCleanupTool = {
603
+ name: 'wu_cleanup',
604
+ description: 'Clean up worktree and branch after PR merge (PR-based completion workflow)',
605
+ // WU-1454: Use shared schema
606
+ inputSchema: wuCleanupSchema,
607
+ async execute(input, options) {
608
+ if (!input.id) {
609
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
610
+ }
611
+ const args = ['--id', input.id];
612
+ if (input.artifacts)
613
+ args.push('--artifacts');
614
+ const cliOptions = { projectRoot: options?.projectRoot };
615
+ const result = await runCliCommand('wu:cleanup', args, cliOptions);
616
+ if (result.success) {
617
+ return success({ message: result.stdout || 'Cleanup complete' });
618
+ }
619
+ else {
620
+ return error(result.stderr || result.error?.message || 'wu:cleanup failed', ErrorCodes.WU_CLEANUP_ERROR);
621
+ }
622
+ },
623
+ };
624
+ /**
625
+ * wu_brief - Generate handoff prompt for sub-agent WU execution (WU-1603)
626
+ *
627
+ * This is the canonical prompt-generation tool.
628
+ */
629
+ export const wuBriefTool = {
630
+ name: 'wu_brief',
631
+ description: 'Generate handoff prompt for sub-agent WU execution',
632
+ // WU-1454: Use shared schema (same parameters as wu:delegate)
633
+ inputSchema: wuSpawnSchema,
634
+ async execute(input, options) {
635
+ if (!input.id) {
636
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
637
+ }
638
+ const args = buildWuPromptArgs(input);
639
+ const cliOptions = { projectRoot: options?.projectRoot };
640
+ const result = await runCliCommand('wu:brief', args, cliOptions);
641
+ if (result.success) {
642
+ return success({ message: result.stdout || 'Brief prompt generated' });
643
+ }
644
+ else {
645
+ return error(result.stderr || result.error?.message || 'wu:brief failed', ErrorCodes.WU_BRIEF_ERROR);
646
+ }
647
+ },
648
+ };
649
+ /**
650
+ * wu_delegate - Generate prompt and explicitly record delegation lineage intent
651
+ */
652
+ export const wuDelegateTool = {
653
+ name: 'wu_delegate',
654
+ description: 'Generate delegation prompt and record explicit lineage intent',
655
+ inputSchema: wuSpawnSchema,
656
+ async execute(input, options) {
657
+ if (!input.id) {
658
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
659
+ }
660
+ if (!input.parent_wu) {
661
+ return error(ErrorMessages.PARENT_WU_REQUIRED, ErrorCodes.MISSING_PARAMETER);
662
+ }
663
+ const args = buildWuPromptArgs(input);
664
+ const cliOptions = { projectRoot: options?.projectRoot };
665
+ const result = await runCliCommand('wu:delegate', args, cliOptions);
666
+ if (result.success) {
667
+ return success({ message: result.stdout || 'Delegation prompt generated' });
668
+ }
669
+ else {
670
+ return error(result.stderr || result.error?.message || 'wu:delegate failed', ErrorCodes.WU_DELEGATE_ERROR);
671
+ }
672
+ },
673
+ };
674
+ /**
675
+ * wu_validate - Validate WU YAML files
676
+ */
677
+ export const wuValidateTool = {
678
+ name: 'wu_validate',
679
+ description: 'Validate WU YAML files against schema (strict mode by default)',
680
+ // WU-1454: Use shared schema
681
+ inputSchema: wuValidateSchema,
682
+ async execute(input, options) {
683
+ if (!input.id) {
684
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
685
+ }
686
+ const args = ['--id', input.id];
687
+ if (input.no_strict)
688
+ args.push('--no-strict');
689
+ const cliOptions = { projectRoot: options?.projectRoot };
690
+ const result = await runCliCommand('wu:validate', args, cliOptions);
691
+ if (result.success) {
692
+ return success({ message: result.stdout || 'WU is valid' });
693
+ }
694
+ else {
695
+ return error(result.stderr || result.error?.message || 'wu:validate failed', ErrorCodes.WU_VALIDATE_ERROR);
696
+ }
697
+ },
698
+ };
699
+ /**
700
+ * wu_infer_lane - Suggest lane for a WU based on code paths and description
701
+ */
702
+ export const wuInferLaneTool = {
703
+ name: 'wu_infer_lane',
704
+ description: 'Suggest lane for a WU based on code paths and description',
705
+ // WU-1454: Use shared schema
706
+ inputSchema: wuInferLaneSchema,
707
+ async execute(input, options) {
708
+ const args = [];
709
+ if (input.id)
710
+ args.push('--id', input.id);
711
+ if (input.paths) {
712
+ for (const p of input.paths) {
713
+ args.push('--paths', p);
714
+ }
715
+ }
716
+ if (input.desc)
717
+ args.push('--desc', input.desc);
718
+ const cliOptions = { projectRoot: options?.projectRoot };
719
+ const result = await runCliCommand('wu:infer-lane', args, cliOptions);
720
+ if (result.success) {
721
+ return success({ lane: result.stdout?.trim() || 'Unknown' });
722
+ }
723
+ else {
724
+ return error(result.stderr || result.error?.message || 'wu:infer-lane failed', ErrorCodes.WU_INFER_LANE_ERROR);
725
+ }
726
+ },
727
+ };
728
+ /**
729
+ * wu_unlock_lane - Safely unlock a lane lock with audit logging
730
+ */
731
+ export const wuUnlockLaneTool = {
732
+ name: 'wu_unlock_lane',
733
+ description: 'Safely unlock a lane lock with audit logging',
734
+ // WU-1454: Use shared schema
735
+ inputSchema: wuUnlockLaneSchema,
736
+ async execute(input, options) {
737
+ // If list mode, no lane required
738
+ if (!input.list && !input.lane) {
739
+ return error(ErrorMessages.LANE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
740
+ }
741
+ const args = [];
742
+ if (input.lane)
743
+ args.push('--lane', input.lane);
744
+ if (input.reason)
745
+ args.push('--reason', input.reason);
746
+ if (input.force)
747
+ args.push('--force');
748
+ if (input.list)
749
+ args.push('--list');
750
+ if (input.status)
751
+ args.push('--status');
752
+ const cliOptions = { projectRoot: options?.projectRoot };
753
+ const result = await runCliCommand('wu:unlock-lane', args, cliOptions);
754
+ if (result.success) {
755
+ try {
756
+ const data = JSON.parse(result.stdout);
757
+ return success(data);
758
+ }
759
+ catch {
760
+ return success({ message: result.stdout || 'Lane unlocked' });
761
+ }
762
+ }
763
+ else {
764
+ return error(result.stderr || result.error?.message || 'wu:unlock-lane failed', ErrorCodes.WU_UNLOCK_LANE_ERROR);
765
+ }
766
+ },
767
+ };
768
+ //# sourceMappingURL=wu-tools.js.map