@lumenflow/mcp 2.11.0 → 2.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/tools.js CHANGED
@@ -3,14 +3,57 @@
3
3
  * @description MCP tool implementations for LumenFlow operations
4
4
  *
5
5
  * WU-1412: Tools available: context_get, wu_list, wu_status, wu_create, wu_claim, wu_done, gates_run
6
+ * WU-1422: Additional WU tools: wu_block, wu_unblock, wu_edit, wu_release, wu_recover, wu_repair,
7
+ * wu_deps, wu_prep, wu_preflight, wu_prune, wu_delete, wu_cleanup, wu_spawn, wu_validate,
8
+ * wu_infer_lane, wu_unlock_lane
9
+ * WU-1424: Initiative tools: initiative_list, initiative_status, initiative_create, initiative_edit,
10
+ * initiative_add_wu, initiative_remove_wu, initiative_bulk_assign, initiative_plan
11
+ * Memory tools: mem_init, mem_start, mem_ready, mem_checkpoint, mem_cleanup, mem_context,
12
+ * mem_create, mem_delete, mem_export, mem_inbox, mem_signal, mem_summarize, mem_triage
13
+ * WU-1425: Agent tools: agent_session, agent_session_end, agent_log_issue, agent_issues_query
14
+ * Orchestration tools: orchestrate_initiative, orchestrate_init_status, orchestrate_monitor
15
+ * Spawn tools: spawn_list
16
+ * WU-1426: Flow/Metrics tools: flow_bottlenecks, flow_report, metrics_snapshot
17
+ * Validation tools: validate, validate_agent_skills, validate_agent_sync,
18
+ * validate_backlog_sync, validate_skills_spec
19
+ * Setup tools: lumenflow_init, lumenflow_doctor, lumenflow_integrate, lumenflow_upgrade,
20
+ * lumenflow_commands, lumenflow_docs_sync, lumenflow_release, lumenflow_sync_templates
21
+ * WU-1431: Uses shared Zod schemas from @lumenflow/core for CLI/MCP parity
22
+ * WU-1454: All 16 WU lifecycle commands now use shared schemas
23
+ * WU-1456: All 13 memory commands now use shared schemas
24
+ * WU-1457: All remaining commands (flow, validation, setup, agent, orchestration, spawn) use shared schemas
6
25
  *
7
26
  * Architecture:
8
27
  * - Read operations (context_get) use @lumenflow/core directly for context
9
28
  * - All other operations shell out to CLI for consistency and safety
29
+ * - Input schemas are derived from shared schemas in @lumenflow/core (WU-1431, WU-1454)
10
30
  */
11
31
  import { z } from 'zod';
12
32
  import { runCliCommand } from './cli-runner.js';
13
- // Import core functions for context operations only
33
+ // WU-1431: Import shared command schemas for CLI/MCP parity
34
+ // WU-1454: Import WU lifecycle schemas for full coverage
35
+ // WU-1457: Import flow, validation, setup, agent, orchestration, spawn schemas
36
+ // These are the single source of truth for command validation
37
+ import { wuCreateSchema, wuClaimSchema, wuStatusSchema, wuDoneSchema, gatesSchema, wuStatusEnum,
38
+ // WU-1454: Lifecycle command schemas
39
+ wuBlockSchema, wuUnblockSchema, wuEditSchema, wuReleaseSchema, wuRecoverSchema, wuRepairSchema, wuDepsSchema, wuPrepSchema, wuPreflightSchema, wuPruneSchema, wuDeleteSchema, wuCleanupSchema, wuSpawnSchema, wuValidateSchema, wuInferLaneSchema, wuUnlockLaneSchema,
40
+ // WU-1455: Initiative command schemas
41
+ initiativeCreateSchema, initiativeEditSchema, initiativeListSchema, initiativeStatusSchema, initiativeAddWuSchema, initiativeRemoveWuSchema, initiativeBulkAssignSchema, initiativePlanSchema,
42
+ // WU-1456: Memory command schemas
43
+ memInitSchema, memStartSchema, memReadySchema, memCheckpointSchema, memCleanupSchema, memContextSchema, memCreateSchema, memDeleteSchema, memExportSchema, memInboxSchema, memSignalSchema, memSummarizeSchema, memTriageSchema,
44
+ // WU-1457: Flow/Metrics command schemas
45
+ flowBottlenecksSchema, flowReportSchema, metricsSnapshotSchema, metricsSchema,
46
+ // WU-1457: Validation command schemas
47
+ validateSchema, validateAgentSkillsSchema, validateAgentSyncSchema, validateBacklogSyncSchema, validateSkillsSpecSchema,
48
+ // WU-1457: Setup command schemas
49
+ lumenflowInitSchema, lumenflowDoctorSchema, lumenflowIntegrateSchema, lumenflowUpgradeSchema, lumenflowCommandsSchema, docsSyncSchema, releaseSchema, syncTemplatesSchema,
50
+ // WU-1457: Agent command schemas
51
+ agentSessionSchema, agentSessionEndSchema, agentLogIssueSchema, agentIssuesQuerySchema,
52
+ // WU-1457: Orchestration command schemas
53
+ orchestrateInitiativeSchema, orchestrateInitStatusSchema, orchestrateMonitorSchema,
54
+ // WU-1457: Spawn command schemas
55
+ spawnListSchema, } from '@lumenflow/core';
56
+ // Import core functions for context operations only (async to avoid circular deps)
14
57
  let coreModule = null;
15
58
  async function getCore() {
16
59
  if (!coreModule) {
@@ -31,6 +74,70 @@ const ErrorCodes = {
31
74
  WU_DONE_ERROR: 'WU_DONE_ERROR',
32
75
  WRONG_LOCATION: 'WRONG_LOCATION',
33
76
  GATES_ERROR: 'GATES_ERROR',
77
+ WU_BLOCK_ERROR: 'WU_BLOCK_ERROR',
78
+ WU_UNBLOCK_ERROR: 'WU_UNBLOCK_ERROR',
79
+ WU_EDIT_ERROR: 'WU_EDIT_ERROR',
80
+ WU_RELEASE_ERROR: 'WU_RELEASE_ERROR',
81
+ WU_RECOVER_ERROR: 'WU_RECOVER_ERROR',
82
+ WU_REPAIR_ERROR: 'WU_REPAIR_ERROR',
83
+ WU_DEPS_ERROR: 'WU_DEPS_ERROR',
84
+ WU_PREP_ERROR: 'WU_PREP_ERROR',
85
+ WU_PREFLIGHT_ERROR: 'WU_PREFLIGHT_ERROR',
86
+ WU_PRUNE_ERROR: 'WU_PRUNE_ERROR',
87
+ WU_DELETE_ERROR: 'WU_DELETE_ERROR',
88
+ WU_CLEANUP_ERROR: 'WU_CLEANUP_ERROR',
89
+ WU_SPAWN_ERROR: 'WU_SPAWN_ERROR',
90
+ WU_VALIDATE_ERROR: 'WU_VALIDATE_ERROR',
91
+ WU_INFER_LANE_ERROR: 'WU_INFER_LANE_ERROR',
92
+ WU_UNLOCK_LANE_ERROR: 'WU_UNLOCK_LANE_ERROR',
93
+ BACKLOG_PRUNE_ERROR: 'BACKLOG_PRUNE_ERROR',
94
+ DOCS_SYNC_ERROR: 'DOCS_SYNC_ERROR',
95
+ GATES_ALIAS_ERROR: 'GATES_ALIAS_ERROR',
96
+ LANE_HEALTH_ERROR: 'LANE_HEALTH_ERROR',
97
+ LANE_SUGGEST_ERROR: 'LANE_SUGGEST_ERROR',
98
+ LUMENFLOW_ALIAS_ERROR: 'LUMENFLOW_ALIAS_ERROR',
99
+ LUMENFLOW_GATES_ERROR: 'LUMENFLOW_GATES_ERROR',
100
+ LUMENFLOW_VALIDATE_ERROR: 'LUMENFLOW_VALIDATE_ERROR',
101
+ LUMENFLOW_METRICS_ERROR: 'LUMENFLOW_METRICS_ERROR',
102
+ METRICS_ERROR: 'METRICS_ERROR',
103
+ STATE_BOOTSTRAP_ERROR: 'STATE_BOOTSTRAP_ERROR',
104
+ STATE_CLEANUP_ERROR: 'STATE_CLEANUP_ERROR',
105
+ STATE_DOCTOR_ERROR: 'STATE_DOCTOR_ERROR',
106
+ SYNC_TEMPLATES_ALIAS_ERROR: 'SYNC_TEMPLATES_ALIAS_ERROR',
107
+ FILE_READ_ERROR: 'FILE_READ_ERROR',
108
+ FILE_WRITE_ERROR: 'FILE_WRITE_ERROR',
109
+ FILE_EDIT_ERROR: 'FILE_EDIT_ERROR',
110
+ FILE_DELETE_ERROR: 'FILE_DELETE_ERROR',
111
+ GIT_STATUS_ERROR: 'GIT_STATUS_ERROR',
112
+ GIT_DIFF_ERROR: 'GIT_DIFF_ERROR',
113
+ GIT_LOG_ERROR: 'GIT_LOG_ERROR',
114
+ GIT_BRANCH_ERROR: 'GIT_BRANCH_ERROR',
115
+ INIT_PLAN_ERROR: 'INIT_PLAN_ERROR',
116
+ PLAN_CREATE_ERROR: 'PLAN_CREATE_ERROR',
117
+ PLAN_EDIT_ERROR: 'PLAN_EDIT_ERROR',
118
+ PLAN_LINK_ERROR: 'PLAN_LINK_ERROR',
119
+ PLAN_PROMOTE_ERROR: 'PLAN_PROMOTE_ERROR',
120
+ SIGNAL_CLEANUP_ERROR: 'SIGNAL_CLEANUP_ERROR',
121
+ WU_PROTO_ERROR: 'WU_PROTO_ERROR',
122
+ // WU-1426: Flow/Metrics error codes
123
+ FLOW_BOTTLENECKS_ERROR: 'FLOW_BOTTLENECKS_ERROR',
124
+ FLOW_REPORT_ERROR: 'FLOW_REPORT_ERROR',
125
+ METRICS_SNAPSHOT_ERROR: 'METRICS_SNAPSHOT_ERROR',
126
+ // WU-1426: Validation error codes
127
+ VALIDATE_ERROR: 'VALIDATE_ERROR',
128
+ VALIDATE_AGENT_SKILLS_ERROR: 'VALIDATE_AGENT_SKILLS_ERROR',
129
+ VALIDATE_AGENT_SYNC_ERROR: 'VALIDATE_AGENT_SYNC_ERROR',
130
+ VALIDATE_BACKLOG_SYNC_ERROR: 'VALIDATE_BACKLOG_SYNC_ERROR',
131
+ VALIDATE_SKILLS_SPEC_ERROR: 'VALIDATE_SKILLS_SPEC_ERROR',
132
+ // WU-1426: Setup error codes
133
+ LUMENFLOW_INIT_ERROR: 'LUMENFLOW_INIT_ERROR',
134
+ LUMENFLOW_DOCTOR_ERROR: 'LUMENFLOW_DOCTOR_ERROR',
135
+ LUMENFLOW_INTEGRATE_ERROR: 'LUMENFLOW_INTEGRATE_ERROR',
136
+ LUMENFLOW_UPGRADE_ERROR: 'LUMENFLOW_UPGRADE_ERROR',
137
+ LUMENFLOW_COMMANDS_ERROR: 'LUMENFLOW_COMMANDS_ERROR',
138
+ LUMENFLOW_DOCS_SYNC_ERROR: 'LUMENFLOW_DOCS_SYNC_ERROR',
139
+ LUMENFLOW_RELEASE_ERROR: 'LUMENFLOW_RELEASE_ERROR',
140
+ LUMENFLOW_SYNC_TEMPLATES_ERROR: 'LUMENFLOW_SYNC_TEMPLATES_ERROR',
34
141
  };
35
142
  /**
36
143
  * Error messages used by tool implementations
@@ -39,7 +146,220 @@ const ErrorMessages = {
39
146
  ID_REQUIRED: 'id is required',
40
147
  LANE_REQUIRED: 'lane is required',
41
148
  TITLE_REQUIRED: 'title is required',
149
+ PATH_REQUIRED: 'path is required',
150
+ CONTENT_REQUIRED: 'content is required',
151
+ OLD_STRING_REQUIRED: 'old_string is required',
152
+ NEW_STRING_REQUIRED: 'new_string is required',
153
+ REASON_REQUIRED: 'reason is required',
154
+ CLIENT_REQUIRED: 'client is required',
155
+ SECTION_REQUIRED: 'section is required',
156
+ PLAN_REQUIRED: 'plan is required',
42
157
  };
158
+ /**
159
+ * CLI argument constants for commonly used flags
160
+ */
161
+ const CliArgs = {
162
+ DESCRIPTION: '--description',
163
+ INITIATIVE: '--initiative',
164
+ PHASE: '--phase',
165
+ JSON: '--json',
166
+ DOCS_ONLY: '--docs-only',
167
+ CODE_PATHS: '--code-paths',
168
+ BASE_DIR: '--base-dir',
169
+ ENCODING: '--encoding',
170
+ // WU-1452: Commands using --format json (initiative:*, flow:*, metrics)
171
+ FORMAT_JSON: ['--format', 'json'],
172
+ DRY_RUN: '--dry-run',
173
+ THRESHOLD: '--threshold',
174
+ RECOVER: '--recover',
175
+ WU: '--wu',
176
+ };
177
+ /**
178
+ * Shared error messages to avoid duplication across different tool categories
179
+ */
180
+ const SharedErrorMessages = {
181
+ WU_REQUIRED: 'wu is required',
182
+ INITIATIVE_REQUIRED: 'initiative is required',
183
+ };
184
+ const SuccessMessages = {
185
+ ALL_GATES_PASSED: 'All gates passed',
186
+ };
187
+ // WU-1482: Schemas for wave-1 parity commands not yet modeled in @lumenflow/core
188
+ const backlogPruneSchema = z.object({
189
+ execute: z.boolean().optional(),
190
+ dry_run: z.boolean().optional(),
191
+ stale_days_in_progress: z.number().optional(),
192
+ stale_days_ready: z.number().optional(),
193
+ archive_days: z.number().optional(),
194
+ });
195
+ const docsSyncMcpSchema = z.object({
196
+ vendor: z.enum(['claude', 'cursor', 'aider', 'all', 'none']).optional(),
197
+ force: z.boolean().optional(),
198
+ });
199
+ const laneHealthSchema = z.object({
200
+ json: z.boolean().optional(),
201
+ verbose: z.boolean().optional(),
202
+ no_coverage: z.boolean().optional(),
203
+ });
204
+ const laneSuggestSchema = z.object({
205
+ dry_run: z.boolean().optional(),
206
+ interactive: z.boolean().optional(),
207
+ output: z.string().optional(),
208
+ json: z.boolean().optional(),
209
+ no_llm: z.boolean().optional(),
210
+ include_git: z.boolean().optional(),
211
+ });
212
+ const stateBootstrapSchema = z.object({
213
+ execute: z.boolean().optional(),
214
+ dry_run: z.boolean().optional(),
215
+ force: z.boolean().optional(),
216
+ wu_dir: z.string().optional(),
217
+ state_dir: z.string().optional(),
218
+ });
219
+ const stateCleanupSchema = z.object({
220
+ dry_run: z.boolean().optional(),
221
+ signals_only: z.boolean().optional(),
222
+ memory_only: z.boolean().optional(),
223
+ events_only: z.boolean().optional(),
224
+ json: z.boolean().optional(),
225
+ quiet: z.boolean().optional(),
226
+ base_dir: z.string().optional(),
227
+ });
228
+ const stateDoctorSchema = z.object({
229
+ fix: z.boolean().optional(),
230
+ dry_run: z.boolean().optional(),
231
+ json: z.boolean().optional(),
232
+ quiet: z.boolean().optional(),
233
+ base_dir: z.string().optional(),
234
+ });
235
+ const syncTemplatesMcpSchema = z.object({
236
+ dry_run: z.boolean().optional(),
237
+ verbose: z.boolean().optional(),
238
+ check_drift: z.boolean().optional(),
239
+ });
240
+ // WU-1483: Schemas for wave-2 parity commands not yet modeled in @lumenflow/core
241
+ const fileReadSchema = z.object({
242
+ path: z.string().optional(),
243
+ encoding: z.string().optional(),
244
+ start_line: z.number().optional(),
245
+ end_line: z.number().optional(),
246
+ max_size: z.number().optional(),
247
+ });
248
+ const fileWriteSchema = z.object({
249
+ path: z.string().optional(),
250
+ content: z.string().optional(),
251
+ encoding: z.string().optional(),
252
+ no_create_dirs: z.boolean().optional(),
253
+ scan_phi: z.boolean().optional(),
254
+ });
255
+ const fileEditSchema = z.object({
256
+ path: z.string().optional(),
257
+ old_string: z.string().optional(),
258
+ new_string: z.string().optional(),
259
+ encoding: z.string().optional(),
260
+ replace_all: z.boolean().optional(),
261
+ });
262
+ const fileDeleteSchema = z.object({
263
+ path: z.string().optional(),
264
+ recursive: z.boolean().optional(),
265
+ force: z.boolean().optional(),
266
+ });
267
+ const gitStatusSchema = z.object({
268
+ base_dir: z.string().optional(),
269
+ path: z.string().optional(),
270
+ porcelain: z.boolean().optional(),
271
+ short: z.boolean().optional(),
272
+ });
273
+ const gitDiffSchema = z.object({
274
+ base_dir: z.string().optional(),
275
+ ref: z.string().optional(),
276
+ staged: z.boolean().optional(),
277
+ name_only: z.boolean().optional(),
278
+ stat: z.boolean().optional(),
279
+ path: z.string().optional(),
280
+ });
281
+ const gitLogSchema = z.object({
282
+ base_dir: z.string().optional(),
283
+ ref: z.string().optional(),
284
+ oneline: z.boolean().optional(),
285
+ max_count: z.number().optional(),
286
+ format: z.string().optional(),
287
+ since: z.string().optional(),
288
+ author: z.string().optional(),
289
+ });
290
+ const gitBranchSchema = z.object({
291
+ base_dir: z.string().optional(),
292
+ list: z.boolean().optional(),
293
+ all: z.boolean().optional(),
294
+ remotes: z.boolean().optional(),
295
+ show_current: z.boolean().optional(),
296
+ contains: z.string().optional(),
297
+ });
298
+ const planCreateSchema = z.object({
299
+ id: z.string().optional(),
300
+ title: z.string().optional(),
301
+ });
302
+ const planEditSchema = z.object({
303
+ id: z.string().optional(),
304
+ section: z.string().optional(),
305
+ content: z.string().optional(),
306
+ append: z.string().optional(),
307
+ });
308
+ const planLinkSchema = z.object({
309
+ id: z.string().optional(),
310
+ plan: z.string().optional(),
311
+ });
312
+ const planPromoteSchema = z.object({
313
+ id: z.string().optional(),
314
+ force: z.boolean().optional(),
315
+ });
316
+ const signalCleanupSchema = z.object({
317
+ dry_run: z.boolean().optional(),
318
+ ttl: z.string().optional(),
319
+ unread_ttl: z.string().optional(),
320
+ max_entries: z.number().optional(),
321
+ json: z.boolean().optional(),
322
+ quiet: z.boolean().optional(),
323
+ base_dir: z.string().optional(),
324
+ });
325
+ const wuProtoSchema = z.object({
326
+ lane: z.string().optional(),
327
+ title: z.string().optional(),
328
+ description: z.string().optional(),
329
+ code_paths: z.array(z.string()).optional(),
330
+ labels: z.array(z.string()).optional(),
331
+ assigned_to: z.string().optional(),
332
+ });
333
+ function buildGatesArgs(input, options = {}) {
334
+ const args = [];
335
+ if (options.forceDocsOnly || input.docs_only)
336
+ args.push(CliArgs.DOCS_ONLY);
337
+ if (input.full_lint)
338
+ args.push('--full-lint');
339
+ if (input.full_tests)
340
+ args.push('--full-tests');
341
+ if (input.full_coverage)
342
+ args.push('--full-coverage');
343
+ if (input.coverage_mode)
344
+ args.push('--coverage-mode', input.coverage_mode);
345
+ if (input.verbose)
346
+ args.push('--verbose');
347
+ return args;
348
+ }
349
+ function buildMetricsArgs(input) {
350
+ const args = [];
351
+ if (input.subcommand)
352
+ args.push(input.subcommand);
353
+ if (input.days !== undefined)
354
+ args.push('--days', String(input.days));
355
+ if (input.format)
356
+ args.push('--format', input.format);
357
+ if (input.output)
358
+ args.push('--output', input.output);
359
+ if (input.dry_run)
360
+ args.push('--dry-run');
361
+ return args;
362
+ }
43
363
  /**
44
364
  * Create a successful tool result
45
365
  */
@@ -78,12 +398,16 @@ export const contextGetTool = {
78
398
  /**
79
399
  * wu_list - List all WUs with optional status filter
80
400
  * Uses CLI shell-out for consistency with other tools
401
+ *
402
+ * WU-1431: Uses shared wuStatusEnum for status filter
81
403
  */
82
404
  export const wuListTool = {
83
405
  name: 'wu_list',
84
406
  description: 'List all Work Units (WUs) with optional status filter',
407
+ // WU-1431: Uses shared wuStatusEnum for status filter
408
+ // (wu_list is MCP-specific, not a shared CLI command, so inline schema is OK)
85
409
  inputSchema: z.object({
86
- status: z.enum(['ready', 'in_progress', 'blocked', 'waiting', 'done']).optional(),
410
+ status: wuStatusEnum.optional(),
87
411
  lane: z.string().optional(),
88
412
  }),
89
413
  async execute(input, options) {
@@ -117,11 +441,16 @@ export const wuListTool = {
117
441
  /**
118
442
  * wu_status - Get status of a specific WU
119
443
  * Uses CLI shell-out for consistency
444
+ *
445
+ * WU-1431: Uses shared wuStatusSchema for parity with CLI
446
+ * Note: CLI allows id to be optional (auto-detect from worktree), but MCP requires it
447
+ * since there's no "current directory" concept for MCP clients
120
448
  */
121
449
  export const wuStatusTool = {
122
450
  name: 'wu_status',
123
451
  description: 'Get detailed status of a specific Work Unit',
124
- inputSchema: z.object({
452
+ // WU-1431: Extend shared schema to require id for MCP (CLI allows optional for auto-detect)
453
+ inputSchema: wuStatusSchema.extend({
125
454
  id: z.string().describe('WU ID (e.g., WU-1412)'),
126
455
  }),
127
456
  async execute(input, options) {
@@ -150,19 +479,14 @@ export const wuStatusTool = {
150
479
  // ============================================================================
151
480
  /**
152
481
  * wu_create - Create a new WU
482
+ *
483
+ * WU-1431: Uses shared wuCreateSchema for CLI/MCP parity
153
484
  */
154
485
  export const wuCreateTool = {
155
486
  name: 'wu_create',
156
487
  description: 'Create a new Work Unit specification',
157
- inputSchema: z.object({
158
- id: z.string().optional().describe('WU ID (auto-generated if omitted)'),
159
- lane: z.string().describe('Lane (e.g., "Framework: CLI")'),
160
- title: z.string().describe('WU title'),
161
- description: z.string().optional().describe('Context: ... Problem: ... Solution: ...'),
162
- acceptance: z.array(z.string()).optional().describe('Acceptance criteria'),
163
- code_paths: z.array(z.string()).optional().describe('Code paths'),
164
- exposure: z.enum(['ui', 'api', 'backend-only', 'documentation']).optional(),
165
- }),
488
+ // WU-1431: Use shared schema - CLI-only aliases are not exposed here
489
+ inputSchema: wuCreateSchema,
166
490
  async execute(input, options) {
167
491
  if (!input.lane) {
168
492
  return error(ErrorMessages.LANE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
@@ -174,7 +498,7 @@ export const wuCreateTool = {
174
498
  if (input.id)
175
499
  args.push('--id', input.id);
176
500
  if (input.description)
177
- args.push('--description', input.description);
501
+ args.push(CliArgs.DESCRIPTION, input.description);
178
502
  if (input.acceptance) {
179
503
  for (const criterion of input.acceptance) {
180
504
  args.push('--acceptance', criterion);
@@ -182,7 +506,7 @@ export const wuCreateTool = {
182
506
  }
183
507
  if (input.code_paths) {
184
508
  for (const p of input.code_paths) {
185
- args.push('--code-paths', p);
509
+ args.push(CliArgs.CODE_PATHS, p);
186
510
  }
187
511
  }
188
512
  if (input.exposure)
@@ -199,14 +523,15 @@ export const wuCreateTool = {
199
523
  };
200
524
  /**
201
525
  * wu_claim - Claim a WU and create worktree
526
+ *
527
+ * WU-1431: Uses shared wuClaimSchema for CLI/MCP parity
528
+ * WU-1491: Supports --cloud, --branch-only, and --pr-mode passthrough
202
529
  */
203
530
  export const wuClaimTool = {
204
531
  name: 'wu_claim',
205
532
  description: 'Claim a Work Unit and create worktree for implementation',
206
- inputSchema: z.object({
207
- id: z.string().describe('WU ID to claim'),
208
- lane: z.string().describe('Lane for the WU'),
209
- }),
533
+ // WU-1431: Use shared schema
534
+ inputSchema: wuClaimSchema,
210
535
  async execute(input, options) {
211
536
  if (!input.id) {
212
537
  return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
@@ -215,6 +540,13 @@ export const wuClaimTool = {
215
540
  return error(ErrorMessages.LANE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
216
541
  }
217
542
  const args = ['--id', input.id, '--lane', input.lane];
543
+ // WU-1491: Pass mode flags through to CLI
544
+ if (input.cloud)
545
+ args.push('--cloud');
546
+ if (input.branch_only)
547
+ args.push('--branch-only');
548
+ if (input.pr_mode)
549
+ args.push('--pr-mode');
218
550
  const cliOptions = { projectRoot: options?.projectRoot };
219
551
  const result = await runCliCommand('wu:claim', args, cliOptions);
220
552
  if (result.success) {
@@ -227,16 +559,14 @@ export const wuClaimTool = {
227
559
  };
228
560
  /**
229
561
  * wu_done - Complete a WU (must be run from main checkout)
562
+ *
563
+ * WU-1431: Uses shared wuDoneSchema for CLI/MCP parity
230
564
  */
231
565
  export const wuDoneTool = {
232
566
  name: 'wu_done',
233
567
  description: 'Complete a Work Unit (merge, stamp, cleanup). MUST be run from main checkout.',
234
- inputSchema: z.object({
235
- id: z.string().describe('WU ID to complete'),
236
- skip_gates: z.boolean().optional().describe('Skip gates (requires reason)'),
237
- reason: z.string().optional().describe('Reason for skipping gates'),
238
- fix_wu: z.string().optional().describe('WU ID that will fix the skipped issue'),
239
- }),
568
+ // WU-1431: Use shared schema
569
+ inputSchema: wuDoneSchema,
240
570
  async execute(input, options) {
241
571
  if (!input.id) {
242
572
  return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
@@ -275,17 +605,18 @@ export const wuDoneTool = {
275
605
  };
276
606
  /**
277
607
  * gates_run - Run quality gates
608
+ *
609
+ * WU-1431: Uses shared gatesSchema for CLI/MCP parity
278
610
  */
279
611
  export const gatesRunTool = {
280
612
  name: 'gates_run',
281
613
  description: 'Run LumenFlow quality gates (lint, typecheck, tests)',
282
- inputSchema: z.object({
283
- docs_only: z.boolean().optional().describe('Run docs-only gates (skip lint/typecheck/tests)'),
284
- }),
614
+ // WU-1431: Use shared schema
615
+ inputSchema: gatesSchema,
285
616
  async execute(input, options) {
286
617
  const args = [];
287
618
  if (input.docs_only) {
288
- args.push('--docs-only');
619
+ args.push(CliArgs.DOCS_ONLY);
289
620
  }
290
621
  const cliOptions = {
291
622
  projectRoot: options?.projectRoot,
@@ -293,13 +624,2665 @@ export const gatesRunTool = {
293
624
  };
294
625
  const result = await runCliCommand('gates', args, cliOptions);
295
626
  if (result.success) {
296
- return success({ message: result.stdout || 'All gates passed' });
627
+ return success({ message: result.stdout || SuccessMessages.ALL_GATES_PASSED });
297
628
  }
298
629
  else {
299
630
  return error(result.stderr || result.error?.message || 'Gates failed', ErrorCodes.GATES_ERROR);
300
631
  }
301
632
  },
302
633
  };
634
+ // ============================================================================
635
+ // Wave-1 Public Parity Operations (WU-1482)
636
+ // ============================================================================
637
+ /**
638
+ * backlog_prune - Clean stale backlog entries
639
+ */
640
+ export const backlogPruneTool = {
641
+ name: 'backlog_prune',
642
+ description: 'Clean stale backlog entries and archive old completed WUs',
643
+ inputSchema: backlogPruneSchema,
644
+ async execute(input, options) {
645
+ const args = [];
646
+ if (input.execute)
647
+ args.push('--execute');
648
+ if (input.dry_run)
649
+ args.push('--dry-run');
650
+ if (input.stale_days_in_progress !== undefined) {
651
+ args.push('--stale-days-in-progress', String(input.stale_days_in_progress));
652
+ }
653
+ if (input.stale_days_ready !== undefined) {
654
+ args.push('--stale-days-ready', String(input.stale_days_ready));
655
+ }
656
+ if (input.archive_days !== undefined) {
657
+ args.push('--archive-days', String(input.archive_days));
658
+ }
659
+ const cliOptions = { projectRoot: options?.projectRoot };
660
+ const result = await runCliCommand('backlog:prune', args, cliOptions);
661
+ if (result.success) {
662
+ return success({ message: result.stdout || 'Backlog prune complete' });
663
+ }
664
+ return error(result.stderr || result.error?.message || 'backlog:prune failed', ErrorCodes.BACKLOG_PRUNE_ERROR);
665
+ },
666
+ };
667
+ /**
668
+ * docs_sync - Sync agent docs to existing project
669
+ */
670
+ export const docsSyncTool = {
671
+ name: 'docs_sync',
672
+ description: 'Sync agent onboarding docs and skills to existing projects',
673
+ inputSchema: docsSyncMcpSchema,
674
+ async execute(input, options) {
675
+ const args = [];
676
+ if (input.vendor)
677
+ args.push('--vendor', input.vendor);
678
+ if (input.force)
679
+ args.push('--force');
680
+ const cliOptions = { projectRoot: options?.projectRoot };
681
+ const result = await runCliCommand('docs:sync', args, cliOptions);
682
+ if (result.success) {
683
+ return success({ message: result.stdout || 'Docs sync complete' });
684
+ }
685
+ return error(result.stderr || result.error?.message || 'docs:sync failed', ErrorCodes.DOCS_SYNC_ERROR);
686
+ },
687
+ };
688
+ /**
689
+ * gates - Public gates command
690
+ */
691
+ export const gatesTool = {
692
+ name: 'gates',
693
+ description: 'Run LumenFlow quality gates',
694
+ inputSchema: gatesSchema,
695
+ async execute(input, options) {
696
+ const args = buildGatesArgs(input);
697
+ const cliOptions = {
698
+ projectRoot: options?.projectRoot,
699
+ timeout: 600000,
700
+ };
701
+ const result = await runCliCommand('gates', args, cliOptions);
702
+ if (result.success) {
703
+ return success({ message: result.stdout || SuccessMessages.ALL_GATES_PASSED });
704
+ }
705
+ return error(result.stderr || result.error?.message || 'gates failed', ErrorCodes.GATES_ALIAS_ERROR);
706
+ },
707
+ };
708
+ /**
709
+ * gates_docs - Public docs-only gates alias
710
+ */
711
+ export const gatesDocsTool = {
712
+ name: 'gates_docs',
713
+ description: 'Run docs-only quality gates',
714
+ inputSchema: gatesSchema,
715
+ async execute(input, options) {
716
+ const args = buildGatesArgs(input, { forceDocsOnly: true });
717
+ const cliOptions = {
718
+ projectRoot: options?.projectRoot,
719
+ timeout: 600000,
720
+ };
721
+ const result = await runCliCommand('gates', args, cliOptions);
722
+ if (result.success) {
723
+ return success({ message: result.stdout || 'Docs-only gates passed' });
724
+ }
725
+ return error(result.stderr || result.error?.message || 'gates:docs failed', ErrorCodes.GATES_ALIAS_ERROR);
726
+ },
727
+ };
728
+ /**
729
+ * lane_health - Diagnose lane configuration issues
730
+ */
731
+ export const laneHealthTool = {
732
+ name: 'lane_health',
733
+ description: 'Check lane configuration health (overlaps and coverage gaps)',
734
+ inputSchema: laneHealthSchema,
735
+ async execute(input, options) {
736
+ const args = [];
737
+ if (input.json)
738
+ args.push('--json');
739
+ if (input.verbose)
740
+ args.push('--verbose');
741
+ if (input.no_coverage)
742
+ args.push('--no-coverage');
743
+ const cliOptions = { projectRoot: options?.projectRoot };
744
+ const result = await runCliCommand('lane:health', args, cliOptions);
745
+ if (result.success) {
746
+ try {
747
+ const data = JSON.parse(result.stdout);
748
+ return success(data);
749
+ }
750
+ catch {
751
+ return success({ message: result.stdout || 'Lane health check complete' });
752
+ }
753
+ }
754
+ return error(result.stderr || result.error?.message || 'lane:health failed', ErrorCodes.LANE_HEALTH_ERROR);
755
+ },
756
+ };
757
+ /**
758
+ * lane_suggest - Suggest lane definitions from project context
759
+ */
760
+ export const laneSuggestTool = {
761
+ name: 'lane_suggest',
762
+ description: 'Generate lane suggestions from codebase context',
763
+ inputSchema: laneSuggestSchema,
764
+ async execute(input, options) {
765
+ const args = [];
766
+ if (input.dry_run)
767
+ args.push('--dry-run');
768
+ if (input.interactive)
769
+ args.push('--interactive');
770
+ if (input.output)
771
+ args.push('--output', input.output);
772
+ if (input.json)
773
+ args.push('--json');
774
+ if (input.no_llm)
775
+ args.push('--no-llm');
776
+ if (input.include_git)
777
+ args.push('--include-git');
778
+ const cliOptions = { projectRoot: options?.projectRoot };
779
+ const result = await runCliCommand('lane:suggest', args, cliOptions);
780
+ if (result.success) {
781
+ try {
782
+ const data = JSON.parse(result.stdout);
783
+ return success(data);
784
+ }
785
+ catch {
786
+ return success({ message: result.stdout || 'Lane suggestions generated' });
787
+ }
788
+ }
789
+ return error(result.stderr || result.error?.message || 'lane:suggest failed', ErrorCodes.LANE_SUGGEST_ERROR);
790
+ },
791
+ };
792
+ /**
793
+ * lumenflow - Public initializer command
794
+ */
795
+ export const lumenflowTool = {
796
+ name: 'lumenflow',
797
+ description: 'Initialize LumenFlow in a project',
798
+ inputSchema: lumenflowInitSchema,
799
+ async execute(input, options) {
800
+ const args = [];
801
+ if (input.client)
802
+ args.push('--client', input.client);
803
+ if (input.merge)
804
+ args.push('--merge');
805
+ if (input.full)
806
+ args.push('--full');
807
+ if (input.minimal)
808
+ args.push('--minimal');
809
+ if (input.framework)
810
+ args.push('--framework', input.framework);
811
+ const cliOptions = { projectRoot: options?.projectRoot };
812
+ const result = await runCliCommand('lumenflow:init', args, cliOptions);
813
+ if (result.success) {
814
+ return success({ message: result.stdout || 'LumenFlow initialized' });
815
+ }
816
+ return error(result.stderr || result.error?.message || 'lumenflow failed', ErrorCodes.LUMENFLOW_ALIAS_ERROR);
817
+ },
818
+ };
819
+ /**
820
+ * lumenflow_gates - Public gates alias
821
+ */
822
+ export const lumenflowGatesTool = {
823
+ name: 'lumenflow_gates',
824
+ description: 'Run quality gates (lumenflow-gates alias)',
825
+ inputSchema: gatesSchema,
826
+ async execute(input, options) {
827
+ const args = buildGatesArgs(input);
828
+ const cliOptions = {
829
+ projectRoot: options?.projectRoot,
830
+ timeout: 600000,
831
+ };
832
+ const result = await runCliCommand('gates', args, cliOptions);
833
+ if (result.success) {
834
+ return success({ message: result.stdout || SuccessMessages.ALL_GATES_PASSED });
835
+ }
836
+ return error(result.stderr || result.error?.message || 'lumenflow-gates failed', ErrorCodes.LUMENFLOW_GATES_ERROR);
837
+ },
838
+ };
839
+ /**
840
+ * lumenflow_validate - Public validate alias
841
+ */
842
+ export const lumenflowValidateTool = {
843
+ name: 'lumenflow_validate',
844
+ description: 'Run validation checks (lumenflow-validate alias)',
845
+ inputSchema: validateSchema,
846
+ async execute(input, options) {
847
+ const args = [];
848
+ if (input.id)
849
+ args.push('--id', input.id);
850
+ if (input.strict)
851
+ args.push('--strict');
852
+ if (input.done_only)
853
+ args.push('--done-only');
854
+ const cliOptions = { projectRoot: options?.projectRoot };
855
+ const result = await runCliCommand('validate', args, cliOptions);
856
+ if (result.success) {
857
+ return success({ message: result.stdout || 'Validation passed' });
858
+ }
859
+ return error(result.stderr || result.error?.message || 'lumenflow-validate failed', ErrorCodes.LUMENFLOW_VALIDATE_ERROR);
860
+ },
861
+ };
862
+ /**
863
+ * lumenflow_metrics - Public metrics alias
864
+ */
865
+ export const lumenflowMetricsTool = {
866
+ name: 'lumenflow_metrics',
867
+ description: 'View workflow metrics (lumenflow:metrics alias)',
868
+ inputSchema: metricsSchema,
869
+ async execute(input, options) {
870
+ const args = buildMetricsArgs(input);
871
+ const cliOptions = { projectRoot: options?.projectRoot };
872
+ const result = await runCliCommand('metrics', args, cliOptions);
873
+ if (result.success) {
874
+ return success({ message: result.stdout || 'Metrics generated' });
875
+ }
876
+ return error(result.stderr || result.error?.message || 'lumenflow:metrics failed', ErrorCodes.LUMENFLOW_METRICS_ERROR);
877
+ },
878
+ };
879
+ /**
880
+ * metrics - Unified workflow metrics command
881
+ */
882
+ export const metricsTool = {
883
+ name: 'metrics',
884
+ description: 'View workflow metrics (lanes, dora, flow, all)',
885
+ inputSchema: metricsSchema,
886
+ async execute(input, options) {
887
+ const args = buildMetricsArgs(input);
888
+ const cliOptions = { projectRoot: options?.projectRoot };
889
+ const result = await runCliCommand('metrics', args, cliOptions);
890
+ if (result.success) {
891
+ return success({ message: result.stdout || 'Metrics generated' });
892
+ }
893
+ return error(result.stderr || result.error?.message || 'metrics failed', ErrorCodes.METRICS_ERROR);
894
+ },
895
+ };
896
+ /**
897
+ * state_bootstrap - Bootstrap event store from WU YAMLs
898
+ */
899
+ export const stateBootstrapTool = {
900
+ name: 'state_bootstrap',
901
+ description: 'Bootstrap state store from existing WU YAML files',
902
+ inputSchema: stateBootstrapSchema,
903
+ async execute(input, options) {
904
+ const args = [];
905
+ if (input.execute)
906
+ args.push('--execute');
907
+ if (input.dry_run)
908
+ args.push('--dry-run');
909
+ if (input.force)
910
+ args.push('--force');
911
+ if (input.wu_dir)
912
+ args.push('--wu-dir', input.wu_dir);
913
+ if (input.state_dir)
914
+ args.push('--state-dir', input.state_dir);
915
+ const cliOptions = { projectRoot: options?.projectRoot };
916
+ const result = await runCliCommand('state:bootstrap', args, cliOptions);
917
+ if (result.success) {
918
+ return success({ message: result.stdout || 'State bootstrap complete' });
919
+ }
920
+ return error(result.stderr || result.error?.message || 'state:bootstrap failed', ErrorCodes.STATE_BOOTSTRAP_ERROR);
921
+ },
922
+ };
923
+ /**
924
+ * state_cleanup - Run unified state cleanup
925
+ */
926
+ export const stateCleanupTool = {
927
+ name: 'state_cleanup',
928
+ description: 'Clean stale state, memory, and signal data',
929
+ inputSchema: stateCleanupSchema,
930
+ async execute(input, options) {
931
+ const args = [];
932
+ if (input.dry_run)
933
+ args.push('--dry-run');
934
+ if (input.signals_only)
935
+ args.push('--signals-only');
936
+ if (input.memory_only)
937
+ args.push('--memory-only');
938
+ if (input.events_only)
939
+ args.push('--events-only');
940
+ if (input.json)
941
+ args.push('--json');
942
+ if (input.quiet)
943
+ args.push('--quiet');
944
+ if (input.base_dir)
945
+ args.push(CliArgs.BASE_DIR, input.base_dir);
946
+ const cliOptions = { projectRoot: options?.projectRoot };
947
+ const result = await runCliCommand('state:cleanup', args, cliOptions);
948
+ if (result.success) {
949
+ return success({ message: result.stdout || 'State cleanup complete' });
950
+ }
951
+ return error(result.stderr || result.error?.message || 'state:cleanup failed', ErrorCodes.STATE_CLEANUP_ERROR);
952
+ },
953
+ };
954
+ /**
955
+ * state_doctor - Diagnose and repair state issues
956
+ */
957
+ export const stateDoctorTool = {
958
+ name: 'state_doctor',
959
+ description: 'Diagnose state store integrity issues',
960
+ inputSchema: stateDoctorSchema,
961
+ async execute(input, options) {
962
+ const args = [];
963
+ if (input.fix)
964
+ args.push('--fix');
965
+ if (input.dry_run)
966
+ args.push('--dry-run');
967
+ if (input.json)
968
+ args.push('--json');
969
+ if (input.quiet)
970
+ args.push('--quiet');
971
+ if (input.base_dir)
972
+ args.push(CliArgs.BASE_DIR, input.base_dir);
973
+ const cliOptions = { projectRoot: options?.projectRoot };
974
+ const result = await runCliCommand('state:doctor', args, cliOptions);
975
+ if (result.success) {
976
+ return success({ message: result.stdout || 'State doctor complete' });
977
+ }
978
+ return error(result.stderr || result.error?.message || 'state:doctor failed', ErrorCodes.STATE_DOCTOR_ERROR);
979
+ },
980
+ };
981
+ /**
982
+ * sync_templates - Sync templates from source docs
983
+ */
984
+ export const syncTemplatesTool = {
985
+ name: 'sync_templates',
986
+ description: 'Sync internal docs to CLI templates',
987
+ inputSchema: syncTemplatesMcpSchema,
988
+ async execute(input, options) {
989
+ const args = [];
990
+ if (input.dry_run)
991
+ args.push('--dry-run');
992
+ if (input.verbose)
993
+ args.push('--verbose');
994
+ if (input.check_drift)
995
+ args.push('--check-drift');
996
+ const cliOptions = { projectRoot: options?.projectRoot };
997
+ const result = await runCliCommand('sync:templates', args, cliOptions);
998
+ if (result.success) {
999
+ return success({ message: result.stdout || 'Template sync complete' });
1000
+ }
1001
+ return error(result.stderr || result.error?.message || 'sync:templates failed', ErrorCodes.SYNC_TEMPLATES_ALIAS_ERROR);
1002
+ },
1003
+ };
1004
+ // ============================================================================
1005
+ // Wave-2 Public Parity Operations (WU-1483)
1006
+ // ============================================================================
1007
+ /**
1008
+ * file_read - Read file content with audit trail
1009
+ */
1010
+ export const fileReadTool = {
1011
+ name: 'file_read',
1012
+ description: 'Read a file with optional line ranges and encoding',
1013
+ inputSchema: fileReadSchema,
1014
+ async execute(input, options) {
1015
+ if (!input.path) {
1016
+ return error(ErrorMessages.PATH_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1017
+ }
1018
+ const args = ['--path', input.path];
1019
+ if (input.encoding)
1020
+ args.push(CliArgs.ENCODING, input.encoding);
1021
+ if (input.start_line !== undefined)
1022
+ args.push('--start-line', String(input.start_line));
1023
+ if (input.end_line !== undefined)
1024
+ args.push('--end-line', String(input.end_line));
1025
+ if (input.max_size !== undefined)
1026
+ args.push('--max-size', String(input.max_size));
1027
+ const cliOptions = { projectRoot: options?.projectRoot };
1028
+ const result = await runCliCommand('file:read', args, cliOptions);
1029
+ if (result.success) {
1030
+ return success({ content: result.stdout });
1031
+ }
1032
+ return error(result.stderr || result.error?.message || 'file:read failed', ErrorCodes.FILE_READ_ERROR);
1033
+ },
1034
+ };
1035
+ /**
1036
+ * file_write - Write file content with audit trail
1037
+ */
1038
+ export const fileWriteTool = {
1039
+ name: 'file_write',
1040
+ description: 'Write content to a file with optional PHI scan',
1041
+ inputSchema: fileWriteSchema,
1042
+ async execute(input, options) {
1043
+ if (!input.path) {
1044
+ return error(ErrorMessages.PATH_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1045
+ }
1046
+ if (input.content === undefined) {
1047
+ return error(ErrorMessages.CONTENT_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1048
+ }
1049
+ const args = ['--path', input.path, '--content', input.content];
1050
+ if (input.encoding)
1051
+ args.push(CliArgs.ENCODING, input.encoding);
1052
+ if (input.no_create_dirs)
1053
+ args.push('--no-create-dirs');
1054
+ if (input.scan_phi)
1055
+ args.push('--scan-phi');
1056
+ const cliOptions = { projectRoot: options?.projectRoot };
1057
+ const result = await runCliCommand('file:write', args, cliOptions);
1058
+ if (result.success) {
1059
+ return success({ message: result.stdout || 'File written' });
1060
+ }
1061
+ return error(result.stderr || result.error?.message || 'file:write failed', ErrorCodes.FILE_WRITE_ERROR);
1062
+ },
1063
+ };
1064
+ /**
1065
+ * file_edit - Replace exact string matches in a file
1066
+ */
1067
+ export const fileEditTool = {
1068
+ name: 'file_edit',
1069
+ description: 'Edit a file via exact string replacement',
1070
+ inputSchema: fileEditSchema,
1071
+ async execute(input, options) {
1072
+ if (!input.path) {
1073
+ return error(ErrorMessages.PATH_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1074
+ }
1075
+ if (!input.old_string) {
1076
+ return error(ErrorMessages.OLD_STRING_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1077
+ }
1078
+ if (input.new_string === undefined) {
1079
+ return error(ErrorMessages.NEW_STRING_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1080
+ }
1081
+ const args = [
1082
+ '--path',
1083
+ input.path,
1084
+ '--old-string',
1085
+ input.old_string,
1086
+ '--new-string',
1087
+ input.new_string,
1088
+ ];
1089
+ if (input.encoding)
1090
+ args.push(CliArgs.ENCODING, input.encoding);
1091
+ if (input.replace_all)
1092
+ args.push('--replace-all');
1093
+ const cliOptions = { projectRoot: options?.projectRoot };
1094
+ const result = await runCliCommand('file:edit', args, cliOptions);
1095
+ if (result.success) {
1096
+ return success({ message: result.stdout || 'File edited' });
1097
+ }
1098
+ return error(result.stderr || result.error?.message || 'file:edit failed', ErrorCodes.FILE_EDIT_ERROR);
1099
+ },
1100
+ };
1101
+ /**
1102
+ * file_delete - Delete file or directory with audit trail
1103
+ */
1104
+ export const fileDeleteTool = {
1105
+ name: 'file_delete',
1106
+ description: 'Delete files or directories with safety flags',
1107
+ inputSchema: fileDeleteSchema,
1108
+ async execute(input, options) {
1109
+ if (!input.path) {
1110
+ return error(ErrorMessages.PATH_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1111
+ }
1112
+ const args = ['--path', input.path];
1113
+ if (input.recursive)
1114
+ args.push('--recursive');
1115
+ if (input.force)
1116
+ args.push('--force');
1117
+ const cliOptions = { projectRoot: options?.projectRoot };
1118
+ const result = await runCliCommand('file:delete', args, cliOptions);
1119
+ if (result.success) {
1120
+ return success({ message: result.stdout || 'Delete complete' });
1121
+ }
1122
+ return error(result.stderr || result.error?.message || 'file:delete failed', ErrorCodes.FILE_DELETE_ERROR);
1123
+ },
1124
+ };
1125
+ /**
1126
+ * git_status - Show git status
1127
+ */
1128
+ export const gitStatusTool = {
1129
+ name: 'git_status',
1130
+ description: 'Show git status with optional porcelain/short modes',
1131
+ inputSchema: gitStatusSchema,
1132
+ async execute(input, options) {
1133
+ const args = [];
1134
+ if (input.base_dir)
1135
+ args.push(CliArgs.BASE_DIR, input.base_dir);
1136
+ if (input.porcelain)
1137
+ args.push('--porcelain');
1138
+ if (input.short)
1139
+ args.push('--short');
1140
+ if (input.path)
1141
+ args.push(input.path);
1142
+ const cliOptions = { projectRoot: options?.projectRoot };
1143
+ const result = await runCliCommand('git:status', args, cliOptions);
1144
+ if (result.success) {
1145
+ return success({ output: result.stdout });
1146
+ }
1147
+ return error(result.stderr || result.error?.message || 'git:status failed', ErrorCodes.GIT_STATUS_ERROR);
1148
+ },
1149
+ };
1150
+ /**
1151
+ * git_diff - Show git diff
1152
+ */
1153
+ export const gitDiffTool = {
1154
+ name: 'git_diff',
1155
+ description: 'Show git diff with staged/name-only/stat modes',
1156
+ inputSchema: gitDiffSchema,
1157
+ async execute(input, options) {
1158
+ const args = [];
1159
+ if (input.base_dir)
1160
+ args.push(CliArgs.BASE_DIR, input.base_dir);
1161
+ if (input.staged)
1162
+ args.push('--staged');
1163
+ if (input.name_only)
1164
+ args.push('--name-only');
1165
+ if (input.stat)
1166
+ args.push('--stat');
1167
+ if (input.ref)
1168
+ args.push(input.ref);
1169
+ if (input.path)
1170
+ args.push('--', input.path);
1171
+ const cliOptions = { projectRoot: options?.projectRoot };
1172
+ const result = await runCliCommand('git:diff', args, cliOptions);
1173
+ if (result.success) {
1174
+ return success({ output: result.stdout });
1175
+ }
1176
+ return error(result.stderr || result.error?.message || 'git:diff failed', ErrorCodes.GIT_DIFF_ERROR);
1177
+ },
1178
+ };
1179
+ /**
1180
+ * git_log - Show commit history
1181
+ */
1182
+ export const gitLogTool = {
1183
+ name: 'git_log',
1184
+ description: 'Show git commit log with filters',
1185
+ inputSchema: gitLogSchema,
1186
+ async execute(input, options) {
1187
+ const args = [];
1188
+ if (input.base_dir)
1189
+ args.push(CliArgs.BASE_DIR, input.base_dir);
1190
+ if (input.oneline)
1191
+ args.push('--oneline');
1192
+ if (input.max_count !== undefined)
1193
+ args.push('-n', String(input.max_count));
1194
+ if (input.format)
1195
+ args.push('--format', input.format);
1196
+ if (input.since)
1197
+ args.push('--since', input.since);
1198
+ if (input.author)
1199
+ args.push('--author', input.author);
1200
+ if (input.ref)
1201
+ args.push(input.ref);
1202
+ const cliOptions = { projectRoot: options?.projectRoot };
1203
+ const result = await runCliCommand('git:log', args, cliOptions);
1204
+ if (result.success) {
1205
+ return success({ output: result.stdout });
1206
+ }
1207
+ return error(result.stderr || result.error?.message || 'git:log failed', ErrorCodes.GIT_LOG_ERROR);
1208
+ },
1209
+ };
1210
+ /**
1211
+ * git_branch - Show branch information
1212
+ */
1213
+ export const gitBranchTool = {
1214
+ name: 'git_branch',
1215
+ description: 'Show git branch listing and current branch',
1216
+ inputSchema: gitBranchSchema,
1217
+ async execute(input, options) {
1218
+ const args = [];
1219
+ if (input.base_dir)
1220
+ args.push(CliArgs.BASE_DIR, input.base_dir);
1221
+ if (input.list)
1222
+ args.push('--list');
1223
+ if (input.all)
1224
+ args.push('--all');
1225
+ if (input.remotes)
1226
+ args.push('--remotes');
1227
+ if (input.show_current)
1228
+ args.push('--show-current');
1229
+ if (input.contains)
1230
+ args.push('--contains', input.contains);
1231
+ const cliOptions = { projectRoot: options?.projectRoot };
1232
+ const result = await runCliCommand('git:branch', args, cliOptions);
1233
+ if (result.success) {
1234
+ return success({ output: result.stdout });
1235
+ }
1236
+ return error(result.stderr || result.error?.message || 'git:branch failed', ErrorCodes.GIT_BRANCH_ERROR);
1237
+ },
1238
+ };
1239
+ /**
1240
+ * init_plan - Link plan to initiative (alias)
1241
+ */
1242
+ export const initPlanTool = {
1243
+ name: 'init_plan',
1244
+ description: 'Link or create a plan for an initiative',
1245
+ inputSchema: initiativePlanSchema,
1246
+ async execute(input, options) {
1247
+ if (!input.initiative) {
1248
+ return error(SharedErrorMessages.INITIATIVE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1249
+ }
1250
+ if (!input.plan && !input.create) {
1251
+ return error(ErrorMessages.PLAN_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1252
+ }
1253
+ const args = ['--initiative', input.initiative];
1254
+ if (input.plan)
1255
+ args.push('--plan', input.plan);
1256
+ if (input.create)
1257
+ args.push('--create');
1258
+ const cliOptions = { projectRoot: options?.projectRoot };
1259
+ const result = await runCliCommand('init:plan', args, cliOptions);
1260
+ if (result.success) {
1261
+ return success({ message: result.stdout || 'Plan linked' });
1262
+ }
1263
+ return error(result.stderr || result.error?.message || 'init:plan failed', ErrorCodes.INIT_PLAN_ERROR);
1264
+ },
1265
+ };
1266
+ /**
1267
+ * plan_create - Create a plan file
1268
+ */
1269
+ export const planCreateTool = {
1270
+ name: 'plan_create',
1271
+ description: 'Create a new plan for a WU or initiative',
1272
+ inputSchema: planCreateSchema,
1273
+ async execute(input, options) {
1274
+ if (!input.id) {
1275
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1276
+ }
1277
+ if (!input.title) {
1278
+ return error(ErrorMessages.TITLE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1279
+ }
1280
+ const args = ['--id', input.id, '--title', input.title];
1281
+ const cliOptions = { projectRoot: options?.projectRoot };
1282
+ const result = await runCliCommand('plan:create', args, cliOptions);
1283
+ if (result.success) {
1284
+ return success({ message: result.stdout || 'Plan created' });
1285
+ }
1286
+ return error(result.stderr || result.error?.message || 'plan:create failed', ErrorCodes.PLAN_CREATE_ERROR);
1287
+ },
1288
+ };
1289
+ /**
1290
+ * plan_edit - Edit an existing plan section
1291
+ */
1292
+ export const planEditTool = {
1293
+ name: 'plan_edit',
1294
+ description: 'Edit or append content to a plan section',
1295
+ inputSchema: planEditSchema,
1296
+ async execute(input, options) {
1297
+ if (!input.id) {
1298
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1299
+ }
1300
+ if (!input.section) {
1301
+ return error(ErrorMessages.SECTION_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1302
+ }
1303
+ if (!input.content && !input.append) {
1304
+ return error(ErrorMessages.CONTENT_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1305
+ }
1306
+ const args = ['--id', input.id, '--section', input.section];
1307
+ if (input.content)
1308
+ args.push('--content', input.content);
1309
+ if (input.append)
1310
+ args.push('--append', input.append);
1311
+ const cliOptions = { projectRoot: options?.projectRoot };
1312
+ const result = await runCliCommand('plan:edit', args, cliOptions);
1313
+ if (result.success) {
1314
+ return success({ message: result.stdout || 'Plan edited' });
1315
+ }
1316
+ return error(result.stderr || result.error?.message || 'plan:edit failed', ErrorCodes.PLAN_EDIT_ERROR);
1317
+ },
1318
+ };
1319
+ /**
1320
+ * plan_link - Link plan URI to WU/initiative
1321
+ */
1322
+ export const planLinkTool = {
1323
+ name: 'plan_link',
1324
+ description: 'Link an existing plan URI to a WU or initiative',
1325
+ inputSchema: planLinkSchema,
1326
+ async execute(input, options) {
1327
+ if (!input.id) {
1328
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1329
+ }
1330
+ if (!input.plan) {
1331
+ return error(ErrorMessages.PLAN_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1332
+ }
1333
+ const args = ['--id', input.id, '--plan', input.plan];
1334
+ const cliOptions = { projectRoot: options?.projectRoot };
1335
+ const result = await runCliCommand('plan:link', args, cliOptions);
1336
+ if (result.success) {
1337
+ return success({ message: result.stdout || 'Plan linked' });
1338
+ }
1339
+ return error(result.stderr || result.error?.message || 'plan:link failed', ErrorCodes.PLAN_LINK_ERROR);
1340
+ },
1341
+ };
1342
+ /**
1343
+ * plan_promote - Promote plan to approved status
1344
+ */
1345
+ export const planPromoteTool = {
1346
+ name: 'plan_promote',
1347
+ description: 'Promote plan from draft to approved status',
1348
+ inputSchema: planPromoteSchema,
1349
+ async execute(input, options) {
1350
+ if (!input.id) {
1351
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1352
+ }
1353
+ const args = ['--id', input.id];
1354
+ if (input.force)
1355
+ args.push('--force');
1356
+ const cliOptions = { projectRoot: options?.projectRoot };
1357
+ const result = await runCliCommand('plan:promote', args, cliOptions);
1358
+ if (result.success) {
1359
+ return success({ message: result.stdout || 'Plan promoted' });
1360
+ }
1361
+ return error(result.stderr || result.error?.message || 'plan:promote failed', ErrorCodes.PLAN_PROMOTE_ERROR);
1362
+ },
1363
+ };
1364
+ /**
1365
+ * signal_cleanup - Clean stale signals
1366
+ */
1367
+ export const signalCleanupTool = {
1368
+ name: 'signal_cleanup',
1369
+ description: 'Cleanup stale signals using TTL policy',
1370
+ inputSchema: signalCleanupSchema,
1371
+ async execute(input, options) {
1372
+ const args = [];
1373
+ if (input.dry_run)
1374
+ args.push('--dry-run');
1375
+ if (input.ttl)
1376
+ args.push('--ttl', input.ttl);
1377
+ if (input.unread_ttl)
1378
+ args.push('--unread-ttl', input.unread_ttl);
1379
+ if (input.max_entries !== undefined)
1380
+ args.push('--max-entries', String(input.max_entries));
1381
+ if (input.json)
1382
+ args.push('--json');
1383
+ if (input.quiet)
1384
+ args.push('--quiet');
1385
+ if (input.base_dir)
1386
+ args.push(CliArgs.BASE_DIR, input.base_dir);
1387
+ const cliOptions = { projectRoot: options?.projectRoot };
1388
+ const result = await runCliCommand('signal:cleanup', args, cliOptions);
1389
+ if (result.success) {
1390
+ return success({ message: result.stdout || 'Signal cleanup complete' });
1391
+ }
1392
+ return error(result.stderr || result.error?.message || 'signal:cleanup failed', ErrorCodes.SIGNAL_CLEANUP_ERROR);
1393
+ },
1394
+ };
1395
+ /**
1396
+ * wu_proto - Create and claim a prototype WU
1397
+ */
1398
+ export const wuProtoTool = {
1399
+ name: 'wu_proto',
1400
+ description: 'Create and claim a prototype WU with relaxed validation',
1401
+ inputSchema: wuProtoSchema,
1402
+ async execute(input, options) {
1403
+ if (!input.lane) {
1404
+ return error(ErrorMessages.LANE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1405
+ }
1406
+ if (!input.title) {
1407
+ return error(ErrorMessages.TITLE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1408
+ }
1409
+ const args = ['--lane', input.lane, '--title', input.title];
1410
+ if (input.description)
1411
+ args.push(CliArgs.DESCRIPTION, input.description);
1412
+ if (Array.isArray(input.code_paths)) {
1413
+ for (const codePath of input.code_paths) {
1414
+ args.push(CliArgs.CODE_PATHS, String(codePath));
1415
+ }
1416
+ }
1417
+ if (Array.isArray(input.labels) && input.labels.length > 0) {
1418
+ args.push('--labels', input.labels.join(','));
1419
+ }
1420
+ if (input.assigned_to)
1421
+ args.push('--assigned-to', input.assigned_to);
1422
+ const cliOptions = { projectRoot: options?.projectRoot };
1423
+ const result = await runCliCommand('wu:proto', args, cliOptions);
1424
+ if (result.success) {
1425
+ return success({ message: result.stdout || 'Prototype WU created' });
1426
+ }
1427
+ return error(result.stderr || result.error?.message || 'wu:proto failed', ErrorCodes.WU_PROTO_ERROR);
1428
+ },
1429
+ };
1430
+ // ============================================================================
1431
+ // Additional WU Operations (WU-1422)
1432
+ // ============================================================================
1433
+ /**
1434
+ * wu_block - Block a WU and move it to blocked status
1435
+ */
1436
+ export const wuBlockTool = {
1437
+ name: 'wu_block',
1438
+ description: 'Block a Work Unit and move it from in_progress to blocked status',
1439
+ // WU-1454: Use shared schema
1440
+ inputSchema: wuBlockSchema,
1441
+ async execute(input, options) {
1442
+ if (!input.id) {
1443
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1444
+ }
1445
+ if (!input.reason) {
1446
+ return error(ErrorMessages.REASON_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1447
+ }
1448
+ const args = ['--id', input.id, '--reason', input.reason];
1449
+ if (input.remove_worktree) {
1450
+ args.push('--remove-worktree');
1451
+ }
1452
+ const cliOptions = { projectRoot: options?.projectRoot };
1453
+ const result = await runCliCommand('wu:block', args, cliOptions);
1454
+ if (result.success) {
1455
+ return success({ message: result.stdout || 'WU blocked successfully' });
1456
+ }
1457
+ else {
1458
+ return error(result.stderr || result.error?.message || 'wu:block failed', ErrorCodes.WU_BLOCK_ERROR);
1459
+ }
1460
+ },
1461
+ };
1462
+ /**
1463
+ * wu_unblock - Unblock a WU and move it back to in_progress status
1464
+ */
1465
+ export const wuUnblockTool = {
1466
+ name: 'wu_unblock',
1467
+ description: 'Unblock a Work Unit and move it from blocked to in_progress status',
1468
+ // WU-1454: Use shared schema
1469
+ inputSchema: wuUnblockSchema,
1470
+ async execute(input, options) {
1471
+ if (!input.id) {
1472
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1473
+ }
1474
+ const args = ['--id', input.id];
1475
+ if (input.reason)
1476
+ args.push('--reason', input.reason);
1477
+ if (input.create_worktree)
1478
+ args.push('--create-worktree');
1479
+ const cliOptions = { projectRoot: options?.projectRoot };
1480
+ const result = await runCliCommand('wu:unblock', args, cliOptions);
1481
+ if (result.success) {
1482
+ return success({ message: result.stdout || 'WU unblocked successfully' });
1483
+ }
1484
+ else {
1485
+ return error(result.stderr || result.error?.message || 'wu:unblock failed', ErrorCodes.WU_UNBLOCK_ERROR);
1486
+ }
1487
+ },
1488
+ };
1489
+ /**
1490
+ * wu_edit - Edit WU spec fields
1491
+ */
1492
+ export const wuEditTool = {
1493
+ name: 'wu_edit',
1494
+ description: 'Edit Work Unit spec fields with micro-worktree isolation',
1495
+ // WU-1454: Use shared schema
1496
+ inputSchema: wuEditSchema,
1497
+ async execute(input, options) {
1498
+ if (!input.id) {
1499
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1500
+ }
1501
+ const args = ['--id', input.id];
1502
+ if (input.description)
1503
+ args.push(CliArgs.DESCRIPTION, input.description);
1504
+ if (input.acceptance) {
1505
+ for (const criterion of input.acceptance) {
1506
+ args.push('--acceptance', criterion);
1507
+ }
1508
+ }
1509
+ if (input.notes)
1510
+ args.push('--notes', input.notes);
1511
+ if (input.code_paths) {
1512
+ for (const p of input.code_paths) {
1513
+ args.push(CliArgs.CODE_PATHS, p);
1514
+ }
1515
+ }
1516
+ if (input.lane)
1517
+ args.push('--lane', input.lane);
1518
+ if (input.priority)
1519
+ args.push('--priority', input.priority);
1520
+ if (input.initiative)
1521
+ args.push(CliArgs.INITIATIVE, input.initiative);
1522
+ if (input.phase)
1523
+ args.push(CliArgs.PHASE, String(input.phase));
1524
+ if (input.no_strict)
1525
+ args.push('--no-strict');
1526
+ const cliOptions = { projectRoot: options?.projectRoot };
1527
+ const result = await runCliCommand('wu:edit', args, cliOptions);
1528
+ if (result.success) {
1529
+ return success({ message: result.stdout || 'WU edited successfully' });
1530
+ }
1531
+ else {
1532
+ return error(result.stderr || result.error?.message || 'wu:edit failed', ErrorCodes.WU_EDIT_ERROR);
1533
+ }
1534
+ },
1535
+ };
1536
+ /**
1537
+ * wu_release - Release an orphaned WU from in_progress to ready status
1538
+ */
1539
+ export const wuReleaseTool = {
1540
+ name: 'wu_release',
1541
+ description: 'Release an orphaned WU from in_progress back to ready state for reclaiming',
1542
+ // WU-1454: Use shared schema
1543
+ inputSchema: wuReleaseSchema,
1544
+ async execute(input, options) {
1545
+ if (!input.id) {
1546
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1547
+ }
1548
+ const args = ['--id', input.id];
1549
+ if (input.reason)
1550
+ args.push('--reason', input.reason);
1551
+ const cliOptions = { projectRoot: options?.projectRoot };
1552
+ const result = await runCliCommand('wu:release', args, cliOptions);
1553
+ if (result.success) {
1554
+ return success({ message: result.stdout || 'WU released successfully' });
1555
+ }
1556
+ else {
1557
+ return error(result.stderr || result.error?.message || 'wu:release failed', ErrorCodes.WU_RELEASE_ERROR);
1558
+ }
1559
+ },
1560
+ };
1561
+ /**
1562
+ * wu_recover - Analyze and fix WU state inconsistencies
1563
+ */
1564
+ export const wuRecoverTool = {
1565
+ name: 'wu_recover',
1566
+ description: 'Analyze and fix WU state inconsistencies',
1567
+ // WU-1454: Use shared schema
1568
+ inputSchema: wuRecoverSchema,
1569
+ async execute(input, options) {
1570
+ if (!input.id) {
1571
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1572
+ }
1573
+ const args = ['--id', input.id];
1574
+ if (input.action)
1575
+ args.push('--action', input.action);
1576
+ if (input.force)
1577
+ args.push('--force');
1578
+ if (input.json)
1579
+ args.push(CliArgs.JSON);
1580
+ const cliOptions = { projectRoot: options?.projectRoot };
1581
+ const result = await runCliCommand('wu:recover', args, cliOptions);
1582
+ if (result.success) {
1583
+ try {
1584
+ const data = JSON.parse(result.stdout);
1585
+ return success(data);
1586
+ }
1587
+ catch {
1588
+ return success({ message: result.stdout || 'WU recovered successfully' });
1589
+ }
1590
+ }
1591
+ else {
1592
+ return error(result.stderr || result.error?.message || 'wu:recover failed', ErrorCodes.WU_RECOVER_ERROR);
1593
+ }
1594
+ },
1595
+ };
1596
+ /**
1597
+ * wu_repair - Unified WU repair tool for state issues
1598
+ */
1599
+ export const wuRepairTool = {
1600
+ name: 'wu_repair',
1601
+ description: 'Unified WU repair tool - detect and fix WU state issues',
1602
+ // WU-1454: Use shared schema
1603
+ inputSchema: wuRepairSchema,
1604
+ async execute(input, options) {
1605
+ const args = [];
1606
+ if (input.id)
1607
+ args.push('--id', input.id);
1608
+ if (input.check)
1609
+ args.push('--check');
1610
+ if (input.all)
1611
+ args.push('--all');
1612
+ if (input.claim)
1613
+ args.push('--claim');
1614
+ if (input.admin)
1615
+ args.push('--admin');
1616
+ if (input.repair_state)
1617
+ args.push('--repair-state');
1618
+ const cliOptions = { projectRoot: options?.projectRoot };
1619
+ const result = await runCliCommand('wu:repair', args, cliOptions);
1620
+ if (result.success) {
1621
+ return success({ message: result.stdout || 'WU repair completed' });
1622
+ }
1623
+ else {
1624
+ return error(result.stderr || result.error?.message || 'wu:repair failed', ErrorCodes.WU_REPAIR_ERROR);
1625
+ }
1626
+ },
1627
+ };
1628
+ /**
1629
+ * wu_deps - Visualize WU dependency graph
1630
+ */
1631
+ export const wuDepsTool = {
1632
+ name: 'wu_deps',
1633
+ description: 'Visualize WU dependency graph',
1634
+ // WU-1454: Use shared schema
1635
+ inputSchema: wuDepsSchema,
1636
+ async execute(input, options) {
1637
+ if (!input.id) {
1638
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1639
+ }
1640
+ const args = ['--id', input.id];
1641
+ if (input.format)
1642
+ args.push('--format', input.format);
1643
+ if (input.depth)
1644
+ args.push('--depth', String(input.depth));
1645
+ if (input.direction)
1646
+ args.push('--direction', input.direction);
1647
+ const cliOptions = { projectRoot: options?.projectRoot };
1648
+ const result = await runCliCommand('wu:deps', args, cliOptions);
1649
+ if (result.success) {
1650
+ try {
1651
+ const data = JSON.parse(result.stdout);
1652
+ return success(data);
1653
+ }
1654
+ catch {
1655
+ return success({ message: result.stdout });
1656
+ }
1657
+ }
1658
+ else {
1659
+ return error(result.stderr || result.error?.message || 'wu:deps failed', ErrorCodes.WU_DEPS_ERROR);
1660
+ }
1661
+ },
1662
+ };
1663
+ /**
1664
+ * wu_prep - Prepare WU for completion (run gates in worktree)
1665
+ */
1666
+ export const wuPrepTool = {
1667
+ name: 'wu_prep',
1668
+ description: 'Prepare WU for completion by running gates in worktree',
1669
+ // WU-1454: Use shared schema
1670
+ inputSchema: wuPrepSchema,
1671
+ async execute(input, options) {
1672
+ if (!input.id) {
1673
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1674
+ }
1675
+ const args = ['--id', input.id];
1676
+ if (input.docs_only)
1677
+ args.push(CliArgs.DOCS_ONLY);
1678
+ const cliOptions = {
1679
+ projectRoot: options?.projectRoot,
1680
+ timeout: 600000, // 10 minutes for gates
1681
+ };
1682
+ const result = await runCliCommand('wu:prep', args, cliOptions);
1683
+ if (result.success) {
1684
+ return success({ message: result.stdout || 'WU prep completed' });
1685
+ }
1686
+ else {
1687
+ return error(result.stderr || result.error?.message || 'wu:prep failed', ErrorCodes.WU_PREP_ERROR);
1688
+ }
1689
+ },
1690
+ };
1691
+ /**
1692
+ * wu_preflight - Fast validation before gates run
1693
+ */
1694
+ export const wuPreflightTool = {
1695
+ name: 'wu_preflight',
1696
+ description: 'Fast validation of code_paths and test paths before gates run (under 5 seconds vs 2+ minutes)',
1697
+ // WU-1454: Use shared schema
1698
+ inputSchema: wuPreflightSchema,
1699
+ async execute(input, options) {
1700
+ if (!input.id) {
1701
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1702
+ }
1703
+ const args = ['--id', input.id];
1704
+ if (input.worktree)
1705
+ args.push('--worktree', input.worktree);
1706
+ const cliOptions = { projectRoot: options?.projectRoot };
1707
+ const result = await runCliCommand('wu:preflight', args, cliOptions);
1708
+ if (result.success) {
1709
+ return success({ message: result.stdout || 'Preflight checks passed' });
1710
+ }
1711
+ else {
1712
+ return error(result.stderr || result.error?.message || 'wu:preflight failed', ErrorCodes.WU_PREFLIGHT_ERROR);
1713
+ }
1714
+ },
1715
+ };
1716
+ /**
1717
+ * wu_prune - Clean stale worktrees
1718
+ */
1719
+ export const wuPruneTool = {
1720
+ name: 'wu_prune',
1721
+ description: 'Clean stale worktrees (dry-run by default)',
1722
+ // WU-1454: Use shared schema
1723
+ inputSchema: wuPruneSchema,
1724
+ async execute(input, options) {
1725
+ const args = [];
1726
+ if (input.execute)
1727
+ args.push('--execute');
1728
+ const cliOptions = { projectRoot: options?.projectRoot };
1729
+ const result = await runCliCommand('wu:prune', args, cliOptions);
1730
+ if (result.success) {
1731
+ return success({ message: result.stdout || 'Prune completed' });
1732
+ }
1733
+ else {
1734
+ return error(result.stderr || result.error?.message || 'wu:prune failed', ErrorCodes.WU_PRUNE_ERROR);
1735
+ }
1736
+ },
1737
+ };
1738
+ /**
1739
+ * wu_delete - Safely delete WU YAML files
1740
+ */
1741
+ export const wuDeleteTool = {
1742
+ name: 'wu_delete',
1743
+ description: 'Safely delete WU YAML files with micro-worktree isolation',
1744
+ // WU-1454: Use shared schema
1745
+ inputSchema: wuDeleteSchema,
1746
+ async execute(input, options) {
1747
+ if (!input.id && !input.batch) {
1748
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1749
+ }
1750
+ const args = [];
1751
+ if (input.id)
1752
+ args.push('--id', input.id);
1753
+ if (input.dry_run)
1754
+ args.push(CliArgs.DRY_RUN);
1755
+ if (input.batch)
1756
+ args.push('--batch', input.batch);
1757
+ const cliOptions = { projectRoot: options?.projectRoot };
1758
+ const result = await runCliCommand('wu:delete', args, cliOptions);
1759
+ if (result.success) {
1760
+ return success({ message: result.stdout || 'WU deleted' });
1761
+ }
1762
+ else {
1763
+ return error(result.stderr || result.error?.message || 'wu:delete failed', ErrorCodes.WU_DELETE_ERROR);
1764
+ }
1765
+ },
1766
+ };
1767
+ /**
1768
+ * wu_cleanup - Clean up worktree and branch after PR merge
1769
+ */
1770
+ export const wuCleanupTool = {
1771
+ name: 'wu_cleanup',
1772
+ description: 'Clean up worktree and branch after PR merge (PR-based completion workflow)',
1773
+ // WU-1454: Use shared schema
1774
+ inputSchema: wuCleanupSchema,
1775
+ async execute(input, options) {
1776
+ if (!input.id) {
1777
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1778
+ }
1779
+ const args = ['--id', input.id];
1780
+ if (input.artifacts)
1781
+ args.push('--artifacts');
1782
+ const cliOptions = { projectRoot: options?.projectRoot };
1783
+ const result = await runCliCommand('wu:cleanup', args, cliOptions);
1784
+ if (result.success) {
1785
+ return success({ message: result.stdout || 'Cleanup complete' });
1786
+ }
1787
+ else {
1788
+ return error(result.stderr || result.error?.message || 'wu:cleanup failed', ErrorCodes.WU_CLEANUP_ERROR);
1789
+ }
1790
+ },
1791
+ };
1792
+ /**
1793
+ * wu_spawn - Generate Task tool invocation for sub-agent WU execution
1794
+ */
1795
+ export const wuSpawnTool = {
1796
+ name: 'wu_spawn',
1797
+ description: 'Generate sub-agent spawn prompt for WU execution',
1798
+ // WU-1454: Use shared schema
1799
+ inputSchema: wuSpawnSchema,
1800
+ async execute(input, options) {
1801
+ if (!input.id) {
1802
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1803
+ }
1804
+ const args = ['--id', input.id];
1805
+ if (input.client)
1806
+ args.push('--client', input.client);
1807
+ if (input.thinking)
1808
+ args.push('--thinking');
1809
+ if (input.budget)
1810
+ args.push('--budget', String(input.budget));
1811
+ if (input.parent_wu)
1812
+ args.push('--parent-wu', input.parent_wu);
1813
+ if (input.no_context)
1814
+ args.push('--no-context');
1815
+ const cliOptions = { projectRoot: options?.projectRoot };
1816
+ const result = await runCliCommand('wu:spawn', args, cliOptions);
1817
+ if (result.success) {
1818
+ return success({ message: result.stdout || 'Spawn prompt generated' });
1819
+ }
1820
+ else {
1821
+ return error(result.stderr || result.error?.message || 'wu:spawn failed', ErrorCodes.WU_SPAWN_ERROR);
1822
+ }
1823
+ },
1824
+ };
1825
+ /**
1826
+ * wu_validate - Validate WU YAML files
1827
+ */
1828
+ export const wuValidateTool = {
1829
+ name: 'wu_validate',
1830
+ description: 'Validate WU YAML files against schema (strict mode by default)',
1831
+ // WU-1454: Use shared schema
1832
+ inputSchema: wuValidateSchema,
1833
+ async execute(input, options) {
1834
+ if (!input.id) {
1835
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1836
+ }
1837
+ const args = ['--id', input.id];
1838
+ if (input.no_strict)
1839
+ args.push('--no-strict');
1840
+ const cliOptions = { projectRoot: options?.projectRoot };
1841
+ const result = await runCliCommand('wu:validate', args, cliOptions);
1842
+ if (result.success) {
1843
+ return success({ message: result.stdout || 'WU is valid' });
1844
+ }
1845
+ else {
1846
+ return error(result.stderr || result.error?.message || 'wu:validate failed', ErrorCodes.WU_VALIDATE_ERROR);
1847
+ }
1848
+ },
1849
+ };
1850
+ /**
1851
+ * wu_infer_lane - Suggest lane for a WU based on code paths and description
1852
+ */
1853
+ export const wuInferLaneTool = {
1854
+ name: 'wu_infer_lane',
1855
+ description: 'Suggest lane for a WU based on code paths and description',
1856
+ // WU-1454: Use shared schema
1857
+ inputSchema: wuInferLaneSchema,
1858
+ async execute(input, options) {
1859
+ const args = [];
1860
+ if (input.id)
1861
+ args.push('--id', input.id);
1862
+ if (input.paths) {
1863
+ for (const p of input.paths) {
1864
+ args.push('--paths', p);
1865
+ }
1866
+ }
1867
+ if (input.desc)
1868
+ args.push('--desc', input.desc);
1869
+ const cliOptions = { projectRoot: options?.projectRoot };
1870
+ const result = await runCliCommand('wu:infer-lane', args, cliOptions);
1871
+ if (result.success) {
1872
+ return success({ lane: result.stdout?.trim() || 'Unknown' });
1873
+ }
1874
+ else {
1875
+ return error(result.stderr || result.error?.message || 'wu:infer-lane failed', ErrorCodes.WU_INFER_LANE_ERROR);
1876
+ }
1877
+ },
1878
+ };
1879
+ /**
1880
+ * wu_unlock_lane - Safely unlock a lane lock with audit logging
1881
+ */
1882
+ export const wuUnlockLaneTool = {
1883
+ name: 'wu_unlock_lane',
1884
+ description: 'Safely unlock a lane lock with audit logging',
1885
+ // WU-1454: Use shared schema
1886
+ inputSchema: wuUnlockLaneSchema,
1887
+ async execute(input, options) {
1888
+ // If list mode, no lane required
1889
+ if (!input.list && !input.lane) {
1890
+ return error(ErrorMessages.LANE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1891
+ }
1892
+ const args = [];
1893
+ if (input.lane)
1894
+ args.push('--lane', input.lane);
1895
+ if (input.reason)
1896
+ args.push('--reason', input.reason);
1897
+ if (input.force)
1898
+ args.push('--force');
1899
+ if (input.list)
1900
+ args.push('--list');
1901
+ if (input.status)
1902
+ args.push('--status');
1903
+ const cliOptions = { projectRoot: options?.projectRoot };
1904
+ const result = await runCliCommand('wu:unlock-lane', args, cliOptions);
1905
+ if (result.success) {
1906
+ try {
1907
+ const data = JSON.parse(result.stdout);
1908
+ return success(data);
1909
+ }
1910
+ catch {
1911
+ return success({ message: result.stdout || 'Lane unlocked' });
1912
+ }
1913
+ }
1914
+ else {
1915
+ return error(result.stderr || result.error?.message || 'wu:unlock-lane failed', ErrorCodes.WU_UNLOCK_LANE_ERROR);
1916
+ }
1917
+ },
1918
+ };
1919
+ // ============================================================================
1920
+ // Initiative Operations (WU-1424)
1921
+ // ============================================================================
1922
+ /**
1923
+ * Error codes for initiative tools
1924
+ */
1925
+ const InitiativeErrorCodes = {
1926
+ INITIATIVE_LIST_ERROR: 'INITIATIVE_LIST_ERROR',
1927
+ INITIATIVE_STATUS_ERROR: 'INITIATIVE_STATUS_ERROR',
1928
+ INITIATIVE_CREATE_ERROR: 'INITIATIVE_CREATE_ERROR',
1929
+ INITIATIVE_EDIT_ERROR: 'INITIATIVE_EDIT_ERROR',
1930
+ INITIATIVE_ADD_WU_ERROR: 'INITIATIVE_ADD_WU_ERROR',
1931
+ INITIATIVE_REMOVE_WU_ERROR: 'INITIATIVE_REMOVE_WU_ERROR',
1932
+ INITIATIVE_BULK_ASSIGN_ERROR: 'INITIATIVE_BULK_ASSIGN_ERROR',
1933
+ INITIATIVE_PLAN_ERROR: 'INITIATIVE_PLAN_ERROR',
1934
+ };
1935
+ /**
1936
+ * Error messages for initiative tools (uses shared messages to avoid duplication)
1937
+ */
1938
+ const InitiativeErrorMessages = {
1939
+ INITIATIVE_REQUIRED: SharedErrorMessages.INITIATIVE_REQUIRED,
1940
+ WU_REQUIRED: SharedErrorMessages.WU_REQUIRED,
1941
+ };
1942
+ /**
1943
+ * initiative_list - List all initiatives
1944
+ */
1945
+ export const initiativeListTool = {
1946
+ name: 'initiative_list',
1947
+ description: 'List all initiatives with optional status filter',
1948
+ // WU-1455: Use shared schema from @lumenflow/core
1949
+ inputSchema: initiativeListSchema,
1950
+ async execute(input, options) {
1951
+ const args = [];
1952
+ if (input.status)
1953
+ args.push('--status', input.status);
1954
+ // WU-1455: Use format field from shared schema
1955
+ if (input.format)
1956
+ args.push('--format', input.format);
1957
+ const cliOptions = { projectRoot: options?.projectRoot };
1958
+ const result = await runCliCommand('initiative:list', args, cliOptions);
1959
+ if (result.success) {
1960
+ try {
1961
+ const data = JSON.parse(result.stdout);
1962
+ return success(data);
1963
+ }
1964
+ catch {
1965
+ return success({ message: result.stdout });
1966
+ }
1967
+ }
1968
+ else {
1969
+ return error(result.stderr || result.error?.message || 'initiative:list failed', InitiativeErrorCodes.INITIATIVE_LIST_ERROR);
1970
+ }
1971
+ },
1972
+ };
1973
+ /**
1974
+ * initiative_status - Get status of a specific initiative
1975
+ */
1976
+ export const initiativeStatusTool = {
1977
+ name: 'initiative_status',
1978
+ description: 'Get detailed status of a specific initiative including WUs and progress',
1979
+ // WU-1455: Use shared schema from @lumenflow/core
1980
+ inputSchema: initiativeStatusSchema,
1981
+ async execute(input, options) {
1982
+ if (!input.id) {
1983
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
1984
+ }
1985
+ const args = ['--id', input.id];
1986
+ // WU-1455: Use format field from shared schema
1987
+ if (input.format)
1988
+ args.push('--format', input.format);
1989
+ const cliOptions = { projectRoot: options?.projectRoot };
1990
+ const result = await runCliCommand('initiative:status', args, cliOptions);
1991
+ if (result.success) {
1992
+ try {
1993
+ const data = JSON.parse(result.stdout);
1994
+ return success(data);
1995
+ }
1996
+ catch {
1997
+ return success({ message: result.stdout });
1998
+ }
1999
+ }
2000
+ else {
2001
+ return error(result.stderr || result.error?.message || 'initiative:status failed', InitiativeErrorCodes.INITIATIVE_STATUS_ERROR);
2002
+ }
2003
+ },
2004
+ };
2005
+ /**
2006
+ * initiative_create - Create a new initiative
2007
+ */
2008
+ export const initiativeCreateTool = {
2009
+ name: 'initiative_create',
2010
+ description: 'Create a new initiative for multi-phase project orchestration',
2011
+ // WU-1455: Use shared schema from @lumenflow/core
2012
+ inputSchema: initiativeCreateSchema,
2013
+ async execute(input, options) {
2014
+ if (!input.id) {
2015
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2016
+ }
2017
+ if (!input.title) {
2018
+ return error(ErrorMessages.TITLE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2019
+ }
2020
+ // WU-1455: Map shared schema fields to CLI flags
2021
+ const args = [
2022
+ '--id',
2023
+ input.id,
2024
+ '--slug',
2025
+ input.slug,
2026
+ '--title',
2027
+ input.title,
2028
+ ];
2029
+ if (input.priority)
2030
+ args.push('--priority', input.priority);
2031
+ if (input.owner)
2032
+ args.push('--owner', input.owner);
2033
+ if (input.target_date)
2034
+ args.push('--target-date', input.target_date);
2035
+ const cliOptions = { projectRoot: options?.projectRoot };
2036
+ const result = await runCliCommand('initiative:create', args, cliOptions);
2037
+ if (result.success) {
2038
+ return success({ message: result.stdout || 'Initiative created successfully' });
2039
+ }
2040
+ else {
2041
+ return error(result.stderr || result.error?.message || 'initiative:create failed', InitiativeErrorCodes.INITIATIVE_CREATE_ERROR);
2042
+ }
2043
+ },
2044
+ };
2045
+ /**
2046
+ * initiative_edit - Edit initiative fields
2047
+ */
2048
+ export const initiativeEditTool = {
2049
+ name: 'initiative_edit',
2050
+ description: 'Edit initiative fields',
2051
+ // WU-1455: Use shared schema from @lumenflow/core
2052
+ inputSchema: initiativeEditSchema,
2053
+ async execute(input, options) {
2054
+ if (!input.id) {
2055
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2056
+ }
2057
+ // WU-1455: Map shared schema fields to CLI flags
2058
+ const args = ['--id', input.id];
2059
+ if (input.description)
2060
+ args.push(CliArgs.DESCRIPTION, input.description);
2061
+ if (input.status)
2062
+ args.push('--status', input.status);
2063
+ if (input.blocked_by)
2064
+ args.push('--blocked-by', input.blocked_by);
2065
+ if (input.blocked_reason)
2066
+ args.push('--blocked-reason', input.blocked_reason);
2067
+ if (input.unblock)
2068
+ args.push('--unblock');
2069
+ if (input.notes)
2070
+ args.push('--notes', input.notes);
2071
+ if (input.phase_id)
2072
+ args.push('--phase-id', input.phase_id);
2073
+ if (input.phase_status)
2074
+ args.push('--phase-status', input.phase_status);
2075
+ if (input.created)
2076
+ args.push('--created', input.created);
2077
+ if (input.add_lane) {
2078
+ for (const lane of input.add_lane) {
2079
+ args.push('--add-lane', lane);
2080
+ }
2081
+ }
2082
+ if (input.remove_lane) {
2083
+ for (const lane of input.remove_lane) {
2084
+ args.push('--remove-lane', lane);
2085
+ }
2086
+ }
2087
+ if (input.add_phase) {
2088
+ for (const phase of input.add_phase) {
2089
+ args.push('--add-phase', phase);
2090
+ }
2091
+ }
2092
+ if (input.add_success_metric) {
2093
+ for (const metric of input.add_success_metric) {
2094
+ args.push('--add-success-metric', metric);
2095
+ }
2096
+ }
2097
+ const cliOptions = { projectRoot: options?.projectRoot };
2098
+ const result = await runCliCommand('initiative:edit', args, cliOptions);
2099
+ if (result.success) {
2100
+ return success({ message: result.stdout || 'Initiative edited successfully' });
2101
+ }
2102
+ else {
2103
+ return error(result.stderr || result.error?.message || 'initiative:edit failed', InitiativeErrorCodes.INITIATIVE_EDIT_ERROR);
2104
+ }
2105
+ },
2106
+ };
2107
+ /**
2108
+ * initiative_add_wu - Add a WU to an initiative
2109
+ */
2110
+ export const initiativeAddWuTool = {
2111
+ name: 'initiative_add_wu',
2112
+ description: 'Add a Work Unit to an initiative, optionally assigning to a phase',
2113
+ // WU-1455: Use shared schema from @lumenflow/core
2114
+ inputSchema: initiativeAddWuSchema,
2115
+ async execute(input, options) {
2116
+ if (!input.initiative) {
2117
+ return error(InitiativeErrorMessages.INITIATIVE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2118
+ }
2119
+ if (!input.wu) {
2120
+ return error(InitiativeErrorMessages.WU_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2121
+ }
2122
+ const args = [CliArgs.INITIATIVE, input.initiative, '--wu', input.wu];
2123
+ if (input.phase !== undefined)
2124
+ args.push(CliArgs.PHASE, String(input.phase));
2125
+ const cliOptions = { projectRoot: options?.projectRoot };
2126
+ const result = await runCliCommand('initiative:add-wu', args, cliOptions);
2127
+ if (result.success) {
2128
+ return success({ message: result.stdout || 'WU added to initiative' });
2129
+ }
2130
+ else {
2131
+ return error(result.stderr || result.error?.message || 'initiative:add-wu failed', InitiativeErrorCodes.INITIATIVE_ADD_WU_ERROR);
2132
+ }
2133
+ },
2134
+ };
2135
+ /**
2136
+ * initiative_remove_wu - Remove a WU from an initiative
2137
+ */
2138
+ export const initiativeRemoveWuTool = {
2139
+ name: 'initiative_remove_wu',
2140
+ description: 'Remove a Work Unit from an initiative',
2141
+ // WU-1455: Use shared schema from @lumenflow/core
2142
+ inputSchema: initiativeRemoveWuSchema,
2143
+ async execute(input, options) {
2144
+ if (!input.initiative) {
2145
+ return error(InitiativeErrorMessages.INITIATIVE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2146
+ }
2147
+ if (!input.wu) {
2148
+ return error(InitiativeErrorMessages.WU_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2149
+ }
2150
+ const args = [CliArgs.INITIATIVE, input.initiative, '--wu', input.wu];
2151
+ const cliOptions = { projectRoot: options?.projectRoot };
2152
+ const result = await runCliCommand('initiative:remove-wu', args, cliOptions);
2153
+ if (result.success) {
2154
+ return success({ message: result.stdout || 'WU removed from initiative' });
2155
+ }
2156
+ else {
2157
+ return error(result.stderr || result.error?.message || 'initiative:remove-wu failed', InitiativeErrorCodes.INITIATIVE_REMOVE_WU_ERROR);
2158
+ }
2159
+ },
2160
+ };
2161
+ /**
2162
+ * initiative_bulk_assign - Bulk assign WUs to an initiative
2163
+ */
2164
+ export const initiatiBulkAssignTool = {
2165
+ name: 'initiative_bulk_assign',
2166
+ description: 'Bulk assign WUs to an initiative based on lane prefix rules',
2167
+ // WU-1455: Use shared schema from @lumenflow/core
2168
+ inputSchema: initiativeBulkAssignSchema,
2169
+ async execute(input, options) {
2170
+ // WU-1455: Map shared schema fields to CLI flags
2171
+ const args = [];
2172
+ if (input.config)
2173
+ args.push('--config', input.config);
2174
+ if (input.apply)
2175
+ args.push('--apply');
2176
+ if (input.sync_from_initiative)
2177
+ args.push('--reconcile-initiative', input.sync_from_initiative);
2178
+ const cliOptions = { projectRoot: options?.projectRoot };
2179
+ const result = await runCliCommand('initiative:bulk-assign', args, cliOptions);
2180
+ if (result.success) {
2181
+ return success({ message: result.stdout || 'Bulk assignment completed' });
2182
+ }
2183
+ else {
2184
+ return error(result.stderr || result.error?.message || 'initiative:bulk-assign failed', InitiativeErrorCodes.INITIATIVE_BULK_ASSIGN_ERROR);
2185
+ }
2186
+ },
2187
+ };
2188
+ /**
2189
+ * initiative_plan - Link or create a plan for an initiative
2190
+ */
2191
+ export const initiativePlanTool = {
2192
+ name: 'initiative_plan',
2193
+ description: 'Link an existing plan or create a new plan template for an initiative',
2194
+ // WU-1455: Use shared schema from @lumenflow/core
2195
+ inputSchema: initiativePlanSchema,
2196
+ async execute(input, options) {
2197
+ if (!input.initiative) {
2198
+ return error(InitiativeErrorMessages.INITIATIVE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2199
+ }
2200
+ const args = [CliArgs.INITIATIVE, input.initiative];
2201
+ if (input.plan)
2202
+ args.push('--plan', input.plan);
2203
+ if (input.create)
2204
+ args.push('--create');
2205
+ const cliOptions = { projectRoot: options?.projectRoot };
2206
+ const result = await runCliCommand('initiative:plan', args, cliOptions);
2207
+ if (result.success) {
2208
+ return success({ message: result.stdout || 'Plan linked to initiative' });
2209
+ }
2210
+ else {
2211
+ return error(result.stderr || result.error?.message || 'initiative:plan failed', InitiativeErrorCodes.INITIATIVE_PLAN_ERROR);
2212
+ }
2213
+ },
2214
+ };
2215
+ // ============================================================================
2216
+ // Memory Operations (WU-1424)
2217
+ // ============================================================================
2218
+ /**
2219
+ * Error codes for memory tools
2220
+ */
2221
+ const MemoryErrorCodes = {
2222
+ MEM_INIT_ERROR: 'MEM_INIT_ERROR',
2223
+ MEM_START_ERROR: 'MEM_START_ERROR',
2224
+ MEM_READY_ERROR: 'MEM_READY_ERROR',
2225
+ MEM_CHECKPOINT_ERROR: 'MEM_CHECKPOINT_ERROR',
2226
+ MEM_CLEANUP_ERROR: 'MEM_CLEANUP_ERROR',
2227
+ MEM_CONTEXT_ERROR: 'MEM_CONTEXT_ERROR',
2228
+ MEM_CREATE_ERROR: 'MEM_CREATE_ERROR',
2229
+ MEM_DELETE_ERROR: 'MEM_DELETE_ERROR',
2230
+ MEM_EXPORT_ERROR: 'MEM_EXPORT_ERROR',
2231
+ MEM_INBOX_ERROR: 'MEM_INBOX_ERROR',
2232
+ MEM_SIGNAL_ERROR: 'MEM_SIGNAL_ERROR',
2233
+ MEM_SUMMARIZE_ERROR: 'MEM_SUMMARIZE_ERROR',
2234
+ MEM_TRIAGE_ERROR: 'MEM_TRIAGE_ERROR',
2235
+ };
2236
+ /**
2237
+ * Error messages for memory tools (uses shared messages to avoid duplication)
2238
+ */
2239
+ const MemoryErrorMessages = {
2240
+ WU_REQUIRED: SharedErrorMessages.WU_REQUIRED,
2241
+ MESSAGE_REQUIRED: 'message is required',
2242
+ };
2243
+ /**
2244
+ * mem_init - Initialize memory for a WU
2245
+ */
2246
+ export const memInitTool = {
2247
+ name: 'mem_init',
2248
+ description: 'Initialize memory layer for a Work Unit',
2249
+ inputSchema: memInitSchema,
2250
+ async execute(input, options) {
2251
+ if (!input.wu) {
2252
+ return error(MemoryErrorMessages.WU_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2253
+ }
2254
+ const args = ['--wu', input.wu];
2255
+ const cliOptions = { projectRoot: options?.projectRoot };
2256
+ const result = await runCliCommand('mem:init', args, cliOptions);
2257
+ if (result.success) {
2258
+ return success({ message: result.stdout || 'Memory initialized' });
2259
+ }
2260
+ else {
2261
+ return error(result.stderr || result.error?.message || 'mem:init failed', MemoryErrorCodes.MEM_INIT_ERROR);
2262
+ }
2263
+ },
2264
+ };
2265
+ /**
2266
+ * mem_start - Start a memory session
2267
+ */
2268
+ export const memStartTool = {
2269
+ name: 'mem_start',
2270
+ description: 'Start a memory session for a Work Unit',
2271
+ inputSchema: memStartSchema,
2272
+ async execute(input, options) {
2273
+ if (!input.wu) {
2274
+ return error(MemoryErrorMessages.WU_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2275
+ }
2276
+ const args = ['--wu', input.wu];
2277
+ if (input.lane)
2278
+ args.push('--lane', input.lane);
2279
+ const cliOptions = { projectRoot: options?.projectRoot };
2280
+ const result = await runCliCommand('mem:start', args, cliOptions);
2281
+ if (result.success) {
2282
+ return success({ message: result.stdout || 'Session started' });
2283
+ }
2284
+ else {
2285
+ return error(result.stderr || result.error?.message || 'mem:start failed', MemoryErrorCodes.MEM_START_ERROR);
2286
+ }
2287
+ },
2288
+ };
2289
+ /**
2290
+ * mem_ready - Check pending nodes
2291
+ */
2292
+ export const memReadyTool = {
2293
+ name: 'mem_ready',
2294
+ description: 'Check pending memory nodes for a Work Unit',
2295
+ inputSchema: memReadySchema,
2296
+ async execute(input, options) {
2297
+ if (!input.wu) {
2298
+ return error(MemoryErrorMessages.WU_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2299
+ }
2300
+ const args = ['--wu', input.wu];
2301
+ const cliOptions = { projectRoot: options?.projectRoot };
2302
+ const result = await runCliCommand('mem:ready', args, cliOptions);
2303
+ if (result.success) {
2304
+ try {
2305
+ const data = JSON.parse(result.stdout);
2306
+ return success(data);
2307
+ }
2308
+ catch {
2309
+ return success({ message: result.stdout });
2310
+ }
2311
+ }
2312
+ else {
2313
+ return error(result.stderr || result.error?.message || 'mem:ready failed', MemoryErrorCodes.MEM_READY_ERROR);
2314
+ }
2315
+ },
2316
+ };
2317
+ /**
2318
+ * mem_checkpoint - Save progress checkpoint
2319
+ */
2320
+ export const memCheckpointTool = {
2321
+ name: 'mem_checkpoint',
2322
+ description: 'Save a progress checkpoint for a Work Unit',
2323
+ inputSchema: memCheckpointSchema,
2324
+ async execute(input, options) {
2325
+ if (!input.wu) {
2326
+ return error(MemoryErrorMessages.WU_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2327
+ }
2328
+ const args = ['--wu', input.wu];
2329
+ if (input.message)
2330
+ args.push('--message', input.message);
2331
+ const cliOptions = { projectRoot: options?.projectRoot };
2332
+ const result = await runCliCommand('mem:checkpoint', args, cliOptions);
2333
+ if (result.success) {
2334
+ return success({ message: result.stdout || 'Checkpoint saved' });
2335
+ }
2336
+ else {
2337
+ return error(result.stderr || result.error?.message || 'mem:checkpoint failed', MemoryErrorCodes.MEM_CHECKPOINT_ERROR);
2338
+ }
2339
+ },
2340
+ };
2341
+ /**
2342
+ * mem_cleanup - Clean up stale memory data
2343
+ */
2344
+ export const memCleanupTool = {
2345
+ name: 'mem_cleanup',
2346
+ description: 'Clean up stale memory data',
2347
+ inputSchema: memCleanupSchema,
2348
+ async execute(input, options) {
2349
+ const args = [];
2350
+ if (input.dry_run)
2351
+ args.push(CliArgs.DRY_RUN);
2352
+ const cliOptions = { projectRoot: options?.projectRoot };
2353
+ const result = await runCliCommand('mem:cleanup', args, cliOptions);
2354
+ if (result.success) {
2355
+ return success({ message: result.stdout || 'Cleanup completed' });
2356
+ }
2357
+ else {
2358
+ return error(result.stderr || result.error?.message || 'mem:cleanup failed', MemoryErrorCodes.MEM_CLEANUP_ERROR);
2359
+ }
2360
+ },
2361
+ };
2362
+ /**
2363
+ * mem_context - Get context for current lane/WU
2364
+ */
2365
+ export const memContextTool = {
2366
+ name: 'mem_context',
2367
+ description: 'Get memory context for a Work Unit, optionally filtered by lane',
2368
+ inputSchema: memContextSchema,
2369
+ async execute(input, options) {
2370
+ if (!input.wu) {
2371
+ return error(MemoryErrorMessages.WU_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2372
+ }
2373
+ const args = ['--wu', input.wu];
2374
+ if (input.lane)
2375
+ args.push('--lane', input.lane);
2376
+ const cliOptions = { projectRoot: options?.projectRoot };
2377
+ const result = await runCliCommand('mem:context', args, cliOptions);
2378
+ if (result.success) {
2379
+ try {
2380
+ const data = JSON.parse(result.stdout);
2381
+ return success(data);
2382
+ }
2383
+ catch {
2384
+ return success({ message: result.stdout });
2385
+ }
2386
+ }
2387
+ else {
2388
+ return error(result.stderr || result.error?.message || 'mem:context failed', MemoryErrorCodes.MEM_CONTEXT_ERROR);
2389
+ }
2390
+ },
2391
+ };
2392
+ /**
2393
+ * mem_create - Create a memory node
2394
+ */
2395
+ export const memCreateTool = {
2396
+ name: 'mem_create',
2397
+ description: 'Create a memory node (e.g., for bug discovery)',
2398
+ inputSchema: memCreateSchema,
2399
+ async execute(input, options) {
2400
+ if (!input.message) {
2401
+ return error(MemoryErrorMessages.MESSAGE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2402
+ }
2403
+ if (!input.wu) {
2404
+ return error(MemoryErrorMessages.WU_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2405
+ }
2406
+ const args = [input.message, '--wu', input.wu];
2407
+ if (input.type)
2408
+ args.push('--type', input.type);
2409
+ if (input.tags)
2410
+ args.push('--tags', input.tags.join(','));
2411
+ const cliOptions = { projectRoot: options?.projectRoot };
2412
+ const result = await runCliCommand('mem:create', args, cliOptions);
2413
+ if (result.success) {
2414
+ return success({ message: result.stdout || 'Memory node created' });
2415
+ }
2416
+ else {
2417
+ return error(result.stderr || result.error?.message || 'mem:create failed', MemoryErrorCodes.MEM_CREATE_ERROR);
2418
+ }
2419
+ },
2420
+ };
2421
+ /**
2422
+ * mem_delete - Delete/archive a memory node
2423
+ */
2424
+ export const memDeleteTool = {
2425
+ name: 'mem_delete',
2426
+ description: 'Delete or archive a memory node',
2427
+ inputSchema: memDeleteSchema,
2428
+ async execute(input, options) {
2429
+ if (!input.id) {
2430
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2431
+ }
2432
+ const args = ['--id', input.id];
2433
+ const cliOptions = { projectRoot: options?.projectRoot };
2434
+ const result = await runCliCommand('mem:delete', args, cliOptions);
2435
+ if (result.success) {
2436
+ return success({ message: result.stdout || 'Memory node deleted' });
2437
+ }
2438
+ else {
2439
+ return error(result.stderr || result.error?.message || 'mem:delete failed', MemoryErrorCodes.MEM_DELETE_ERROR);
2440
+ }
2441
+ },
2442
+ };
2443
+ /**
2444
+ * mem_export - Export memory as markdown
2445
+ */
2446
+ export const memExportTool = {
2447
+ name: 'mem_export',
2448
+ description: 'Export memory for a Work Unit as markdown or JSON',
2449
+ inputSchema: memExportSchema,
2450
+ async execute(input, options) {
2451
+ if (!input.wu) {
2452
+ return error(MemoryErrorMessages.WU_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2453
+ }
2454
+ const args = ['--wu', input.wu];
2455
+ if (input.format)
2456
+ args.push('--format', input.format);
2457
+ const cliOptions = { projectRoot: options?.projectRoot };
2458
+ const result = await runCliCommand('mem:export', args, cliOptions);
2459
+ if (result.success) {
2460
+ return success({ message: result.stdout });
2461
+ }
2462
+ else {
2463
+ return error(result.stderr || result.error?.message || 'mem:export failed', MemoryErrorCodes.MEM_EXPORT_ERROR);
2464
+ }
2465
+ },
2466
+ };
2467
+ /**
2468
+ * mem_inbox - Check coordination signals
2469
+ */
2470
+ export const memInboxTool = {
2471
+ name: 'mem_inbox',
2472
+ description: 'Check coordination signals from other agents',
2473
+ inputSchema: memInboxSchema,
2474
+ async execute(input, options) {
2475
+ const args = [];
2476
+ if (input.since)
2477
+ args.push('--since', input.since);
2478
+ if (input.wu)
2479
+ args.push(CliArgs.WU, input.wu);
2480
+ if (input.lane)
2481
+ args.push('--lane', input.lane);
2482
+ const cliOptions = { projectRoot: options?.projectRoot };
2483
+ const result = await runCliCommand('mem:inbox', args, cliOptions);
2484
+ if (result.success) {
2485
+ try {
2486
+ const data = JSON.parse(result.stdout);
2487
+ return success(data);
2488
+ }
2489
+ catch {
2490
+ return success({ message: result.stdout });
2491
+ }
2492
+ }
2493
+ else {
2494
+ return error(result.stderr || result.error?.message || 'mem:inbox failed', MemoryErrorCodes.MEM_INBOX_ERROR);
2495
+ }
2496
+ },
2497
+ };
2498
+ /**
2499
+ * mem_signal - Broadcast coordination signal
2500
+ */
2501
+ export const memSignalTool = {
2502
+ name: 'mem_signal',
2503
+ description: 'Broadcast a coordination signal to other agents',
2504
+ inputSchema: memSignalSchema,
2505
+ async execute(input, options) {
2506
+ if (!input.message) {
2507
+ return error(MemoryErrorMessages.MESSAGE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2508
+ }
2509
+ if (!input.wu) {
2510
+ return error(MemoryErrorMessages.WU_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2511
+ }
2512
+ const args = [input.message, '--wu', input.wu];
2513
+ const cliOptions = { projectRoot: options?.projectRoot };
2514
+ const result = await runCliCommand('mem:signal', args, cliOptions);
2515
+ if (result.success) {
2516
+ return success({ message: result.stdout || 'Signal broadcast' });
2517
+ }
2518
+ else {
2519
+ return error(result.stderr || result.error?.message || 'mem:signal failed', MemoryErrorCodes.MEM_SIGNAL_ERROR);
2520
+ }
2521
+ },
2522
+ };
2523
+ /**
2524
+ * mem_summarize - Summarize memory context
2525
+ */
2526
+ export const memSummarizeTool = {
2527
+ name: 'mem_summarize',
2528
+ description: 'Summarize memory context for a Work Unit',
2529
+ inputSchema: memSummarizeSchema,
2530
+ async execute(input, options) {
2531
+ if (!input.wu) {
2532
+ return error(MemoryErrorMessages.WU_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2533
+ }
2534
+ const args = ['--wu', input.wu];
2535
+ const cliOptions = { projectRoot: options?.projectRoot };
2536
+ const result = await runCliCommand('mem:summarize', args, cliOptions);
2537
+ if (result.success) {
2538
+ return success({ message: result.stdout });
2539
+ }
2540
+ else {
2541
+ return error(result.stderr || result.error?.message || 'mem:summarize failed', MemoryErrorCodes.MEM_SUMMARIZE_ERROR);
2542
+ }
2543
+ },
2544
+ };
2545
+ /**
2546
+ * mem_triage - Triage discovered bugs
2547
+ */
2548
+ export const memTriageTool = {
2549
+ name: 'mem_triage',
2550
+ description: 'Triage discovered bugs for a Work Unit, optionally promoting to WU',
2551
+ inputSchema: memTriageSchema,
2552
+ async execute(input, options) {
2553
+ if (!input.wu) {
2554
+ return error(MemoryErrorMessages.WU_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2555
+ }
2556
+ const args = ['--wu', input.wu];
2557
+ if (input.promote)
2558
+ args.push('--promote', input.promote);
2559
+ if (input.lane)
2560
+ args.push('--lane', input.lane);
2561
+ const cliOptions = { projectRoot: options?.projectRoot };
2562
+ const result = await runCliCommand('mem:triage', args, cliOptions);
2563
+ if (result.success) {
2564
+ try {
2565
+ const data = JSON.parse(result.stdout);
2566
+ return success(data);
2567
+ }
2568
+ catch {
2569
+ return success({ message: result.stdout });
2570
+ }
2571
+ }
2572
+ else {
2573
+ return error(result.stderr || result.error?.message || 'mem:triage failed', MemoryErrorCodes.MEM_TRIAGE_ERROR);
2574
+ }
2575
+ },
2576
+ };
2577
+ // ============================================================================
2578
+ // Agent Operations (WU-1425)
2579
+ // ============================================================================
2580
+ /**
2581
+ * Error codes for agent tools
2582
+ */
2583
+ const AgentErrorCodes = {
2584
+ AGENT_SESSION_ERROR: 'AGENT_SESSION_ERROR',
2585
+ AGENT_SESSION_END_ERROR: 'AGENT_SESSION_END_ERROR',
2586
+ AGENT_LOG_ISSUE_ERROR: 'AGENT_LOG_ISSUE_ERROR',
2587
+ AGENT_ISSUES_QUERY_ERROR: 'AGENT_ISSUES_QUERY_ERROR',
2588
+ };
2589
+ /**
2590
+ * Error messages for agent tools
2591
+ */
2592
+ const AgentErrorMessages = {
2593
+ WU_REQUIRED: SharedErrorMessages.WU_REQUIRED,
2594
+ TIER_REQUIRED: 'tier is required',
2595
+ CATEGORY_REQUIRED: 'category is required',
2596
+ SEVERITY_REQUIRED: 'severity is required',
2597
+ TITLE_REQUIRED: 'title is required',
2598
+ DESCRIPTION_REQUIRED: 'description is required',
2599
+ };
2600
+ /**
2601
+ * agent_session - Start an agent session for tracking WU execution
2602
+ */
2603
+ export const agentSessionTool = {
2604
+ name: 'agent_session',
2605
+ description: 'Start an agent session for tracking WU execution',
2606
+ inputSchema: agentSessionSchema,
2607
+ async execute(input, options) {
2608
+ if (!input.wu) {
2609
+ return error(AgentErrorMessages.WU_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2610
+ }
2611
+ if (input.tier === undefined || input.tier === null) {
2612
+ return error(AgentErrorMessages.TIER_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2613
+ }
2614
+ const args = ['--wu', input.wu, '--tier', String(input.tier)];
2615
+ if (input.agent_type)
2616
+ args.push('--agent-type', input.agent_type);
2617
+ const cliOptions = { projectRoot: options?.projectRoot };
2618
+ const result = await runCliCommand('agent:session', args, cliOptions);
2619
+ if (result.success) {
2620
+ return success({ message: result.stdout || 'Session started' });
2621
+ }
2622
+ else {
2623
+ return error(result.stderr || result.error?.message || 'agent:session failed', AgentErrorCodes.AGENT_SESSION_ERROR);
2624
+ }
2625
+ },
2626
+ };
2627
+ /**
2628
+ * agent_session_end - End the current agent session
2629
+ */
2630
+ export const agentSessionEndTool = {
2631
+ name: 'agent_session_end',
2632
+ description: 'End the current agent session and return summary',
2633
+ inputSchema: agentSessionEndSchema,
2634
+ async execute(_input, options) {
2635
+ const cliOptions = { projectRoot: options?.projectRoot };
2636
+ const result = await runCliCommand('agent:session:end', [], cliOptions);
2637
+ if (result.success) {
2638
+ try {
2639
+ const data = JSON.parse(result.stdout);
2640
+ return success(data);
2641
+ }
2642
+ catch {
2643
+ return success({ message: result.stdout || 'Session ended' });
2644
+ }
2645
+ }
2646
+ else {
2647
+ return error(result.stderr || result.error?.message || 'agent:session:end failed', AgentErrorCodes.AGENT_SESSION_END_ERROR);
2648
+ }
2649
+ },
2650
+ };
2651
+ /**
2652
+ * agent_log_issue - Log a workflow issue or incident during agent execution
2653
+ */
2654
+ export const agentLogIssueTool = {
2655
+ name: 'agent_log_issue',
2656
+ description: 'Log a workflow issue or incident during agent execution',
2657
+ inputSchema: agentLogIssueSchema,
2658
+ async execute(input, options) {
2659
+ if (!input.category) {
2660
+ return error(AgentErrorMessages.CATEGORY_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2661
+ }
2662
+ if (!input.severity) {
2663
+ return error(AgentErrorMessages.SEVERITY_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2664
+ }
2665
+ if (!input.title) {
2666
+ return error(AgentErrorMessages.TITLE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2667
+ }
2668
+ if (!input.description) {
2669
+ return error(AgentErrorMessages.DESCRIPTION_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2670
+ }
2671
+ const args = [
2672
+ '--category',
2673
+ input.category,
2674
+ '--severity',
2675
+ input.severity,
2676
+ '--title',
2677
+ input.title,
2678
+ CliArgs.DESCRIPTION,
2679
+ input.description,
2680
+ ];
2681
+ if (input.resolution)
2682
+ args.push('--resolution', input.resolution);
2683
+ if (input.tags) {
2684
+ for (const tag of input.tags) {
2685
+ args.push('--tag', tag);
2686
+ }
2687
+ }
2688
+ if (input.step)
2689
+ args.push('--step', input.step);
2690
+ if (input.files) {
2691
+ for (const file of input.files) {
2692
+ args.push('--file', file);
2693
+ }
2694
+ }
2695
+ const cliOptions = { projectRoot: options?.projectRoot };
2696
+ const result = await runCliCommand('agent:log-issue', args, cliOptions);
2697
+ if (result.success) {
2698
+ return success({ message: result.stdout || 'Issue logged' });
2699
+ }
2700
+ else {
2701
+ return error(result.stderr || result.error?.message || 'agent:log-issue failed', AgentErrorCodes.AGENT_LOG_ISSUE_ERROR);
2702
+ }
2703
+ },
2704
+ };
2705
+ /**
2706
+ * agent_issues_query - Query and display logged agent incidents
2707
+ */
2708
+ export const agentIssuesQueryTool = {
2709
+ name: 'agent_issues_query',
2710
+ description: 'Query and display logged agent incidents/issues summary',
2711
+ inputSchema: agentIssuesQuerySchema,
2712
+ async execute(input, options) {
2713
+ const args = ['summary'];
2714
+ if (input.since)
2715
+ args.push('--since', String(input.since));
2716
+ if (input.category)
2717
+ args.push('--category', input.category);
2718
+ if (input.severity)
2719
+ args.push('--severity', input.severity);
2720
+ const cliOptions = { projectRoot: options?.projectRoot };
2721
+ const result = await runCliCommand('agent:issues-query', args, cliOptions);
2722
+ if (result.success) {
2723
+ return success({ message: result.stdout || 'Query complete' });
2724
+ }
2725
+ else {
2726
+ return error(result.stderr || result.error?.message || 'agent:issues-query failed', AgentErrorCodes.AGENT_ISSUES_QUERY_ERROR);
2727
+ }
2728
+ },
2729
+ };
2730
+ // ============================================================================
2731
+ // Orchestration Operations (WU-1425)
2732
+ // ============================================================================
2733
+ /**
2734
+ * Error codes for orchestration tools
2735
+ */
2736
+ const OrchestrationErrorCodes = {
2737
+ ORCHESTRATE_INITIATIVE_ERROR: 'ORCHESTRATE_INITIATIVE_ERROR',
2738
+ ORCHESTRATE_INIT_STATUS_ERROR: 'ORCHESTRATE_INIT_STATUS_ERROR',
2739
+ ORCHESTRATE_MONITOR_ERROR: 'ORCHESTRATE_MONITOR_ERROR',
2740
+ };
2741
+ /**
2742
+ * Error messages for orchestration tools
2743
+ */
2744
+ const OrchestrationErrorMessages = {
2745
+ INITIATIVE_REQUIRED: SharedErrorMessages.INITIATIVE_REQUIRED,
2746
+ };
2747
+ /**
2748
+ * orchestrate_initiative - Orchestrate initiative execution with parallel agent spawning
2749
+ */
2750
+ export const orchestrateInitiativeTool = {
2751
+ name: 'orchestrate_initiative',
2752
+ description: 'Orchestrate initiative execution with parallel agent spawning',
2753
+ inputSchema: orchestrateInitiativeSchema,
2754
+ async execute(input, options) {
2755
+ if (!input.initiative) {
2756
+ return error(OrchestrationErrorMessages.INITIATIVE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2757
+ }
2758
+ const args = [CliArgs.INITIATIVE, input.initiative];
2759
+ if (input.dry_run)
2760
+ args.push(CliArgs.DRY_RUN);
2761
+ if (input.progress)
2762
+ args.push('--progress');
2763
+ if (input.checkpoint_per_wave)
2764
+ args.push('--checkpoint-per-wave');
2765
+ const cliOptions = {
2766
+ projectRoot: options?.projectRoot,
2767
+ timeout: 300000, // 5 minutes for orchestration
2768
+ };
2769
+ const result = await runCliCommand('orchestrate:initiative', args, cliOptions);
2770
+ if (result.success) {
2771
+ return success({ message: result.stdout || 'Orchestration complete' });
2772
+ }
2773
+ else {
2774
+ return error(result.stderr || result.error?.message || 'orchestrate:initiative failed', OrchestrationErrorCodes.ORCHESTRATE_INITIATIVE_ERROR);
2775
+ }
2776
+ },
2777
+ };
2778
+ /**
2779
+ * orchestrate_init_status - Show initiative progress status
2780
+ */
2781
+ export const orchestrateInitStatusTool = {
2782
+ name: 'orchestrate_init_status',
2783
+ description: 'Show compact initiative progress status including WUs and lane availability',
2784
+ inputSchema: orchestrateInitStatusSchema,
2785
+ async execute(input, options) {
2786
+ if (!input.initiative) {
2787
+ return error(OrchestrationErrorMessages.INITIATIVE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2788
+ }
2789
+ const args = [CliArgs.INITIATIVE, input.initiative];
2790
+ const cliOptions = { projectRoot: options?.projectRoot };
2791
+ const result = await runCliCommand('orchestrate:init-status', args, cliOptions);
2792
+ if (result.success) {
2793
+ return success({ message: result.stdout || 'Status displayed' });
2794
+ }
2795
+ else {
2796
+ return error(result.stderr || result.error?.message || 'orchestrate:init-status failed', OrchestrationErrorCodes.ORCHESTRATE_INIT_STATUS_ERROR);
2797
+ }
2798
+ },
2799
+ };
2800
+ /**
2801
+ * orchestrate_monitor - Monitor spawned agent progress and spawn health
2802
+ */
2803
+ export const orchestrateMonitorTool = {
2804
+ name: 'orchestrate_monitor',
2805
+ description: 'Monitor spawned agent progress and spawn health (stuck detection, zombie locks)',
2806
+ inputSchema: orchestrateMonitorSchema,
2807
+ async execute(input, options) {
2808
+ const args = [];
2809
+ if (input.threshold)
2810
+ args.push(CliArgs.THRESHOLD, String(input.threshold));
2811
+ if (input.recover)
2812
+ args.push(CliArgs.RECOVER);
2813
+ if (input.dry_run)
2814
+ args.push(CliArgs.DRY_RUN);
2815
+ if (input.since)
2816
+ args.push('--since', input.since);
2817
+ if (input.wu)
2818
+ args.push(CliArgs.WU, input.wu);
2819
+ if (input.signals_only)
2820
+ args.push('--signals-only');
2821
+ const cliOptions = {
2822
+ projectRoot: options?.projectRoot,
2823
+ timeout: 180000, // 3 minutes for monitoring
2824
+ };
2825
+ const result = await runCliCommand('orchestrate:monitor', args, cliOptions);
2826
+ if (result.success) {
2827
+ return success({ message: result.stdout || 'Monitor complete' });
2828
+ }
2829
+ else {
2830
+ return error(result.stderr || result.error?.message || 'orchestrate:monitor failed', OrchestrationErrorCodes.ORCHESTRATE_MONITOR_ERROR);
2831
+ }
2832
+ },
2833
+ };
2834
+ // ============================================================================
2835
+ // Spawn Operations (WU-1425)
2836
+ // ============================================================================
2837
+ /**
2838
+ * Error codes for spawn tools
2839
+ */
2840
+ const SpawnErrorCodes = {
2841
+ SPAWN_LIST_ERROR: 'SPAWN_LIST_ERROR',
2842
+ };
2843
+ /**
2844
+ * Error messages for spawn tools
2845
+ */
2846
+ const SpawnErrorMessages = {
2847
+ WU_OR_INITIATIVE_REQUIRED: 'Either wu or initiative is required',
2848
+ };
2849
+ /**
2850
+ * spawn_list - Display spawn trees for WUs or initiatives
2851
+ */
2852
+ export const spawnListTool = {
2853
+ name: 'spawn_list',
2854
+ description: 'Display spawn trees for WUs or initiatives',
2855
+ inputSchema: spawnListSchema,
2856
+ async execute(input, options) {
2857
+ if (!input.wu && !input.initiative) {
2858
+ return error(SpawnErrorMessages.WU_OR_INITIATIVE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
2859
+ }
2860
+ const args = [];
2861
+ if (input.wu)
2862
+ args.push(CliArgs.WU, input.wu);
2863
+ if (input.initiative)
2864
+ args.push(CliArgs.INITIATIVE, input.initiative);
2865
+ if (input.json)
2866
+ args.push('--json');
2867
+ const cliOptions = { projectRoot: options?.projectRoot };
2868
+ const result = await runCliCommand('spawn:list', args, cliOptions);
2869
+ if (result.success) {
2870
+ try {
2871
+ const data = JSON.parse(result.stdout);
2872
+ return success(data);
2873
+ }
2874
+ catch {
2875
+ return success({ message: result.stdout || 'Spawn list displayed' });
2876
+ }
2877
+ }
2878
+ else {
2879
+ return error(result.stderr || result.error?.message || 'spawn:list failed', SpawnErrorCodes.SPAWN_LIST_ERROR);
2880
+ }
2881
+ },
2882
+ };
2883
+ // ============================================================================
2884
+ // Flow/Metrics Operations (WU-1426)
2885
+ // ============================================================================
2886
+ /**
2887
+ * flow_bottlenecks - Identify flow bottlenecks
2888
+ */
2889
+ export const flowBottlenecksTool = {
2890
+ name: 'flow_bottlenecks',
2891
+ description: 'Identify flow bottlenecks in the workflow (WIP violations, stuck WUs, etc.)',
2892
+ inputSchema: flowBottlenecksSchema,
2893
+ async execute(input, options) {
2894
+ const args = [];
2895
+ // WU-1457: Use shared schema fields (limit, format match CLI flags)
2896
+ if (input.limit)
2897
+ args.push('--limit', String(input.limit));
2898
+ if (input.format)
2899
+ args.push('--format', input.format);
2900
+ // WU-1452: flow:bottlenecks uses --format json, not --json
2901
+ if (input.json)
2902
+ args.push(...CliArgs.FORMAT_JSON);
2903
+ const cliOptions = { projectRoot: options?.projectRoot };
2904
+ const result = await runCliCommand('flow:bottlenecks', args, cliOptions);
2905
+ if (result.success) {
2906
+ try {
2907
+ const data = JSON.parse(result.stdout);
2908
+ return success(data);
2909
+ }
2910
+ catch {
2911
+ return success({ message: result.stdout || 'Bottleneck analysis complete' });
2912
+ }
2913
+ }
2914
+ else {
2915
+ return error(result.stderr || result.error?.message || 'flow:bottlenecks failed', ErrorCodes.FLOW_BOTTLENECKS_ERROR);
2916
+ }
2917
+ },
2918
+ };
2919
+ /**
2920
+ * flow_report - Generate flow metrics report
2921
+ */
2922
+ export const flowReportTool = {
2923
+ name: 'flow_report',
2924
+ description: 'Generate flow metrics report with cycle time, throughput, and other DORA metrics',
2925
+ inputSchema: flowReportSchema,
2926
+ async execute(input, options) {
2927
+ const args = [];
2928
+ // WU-1457: Use shared schema field names (start/end match CLI flags)
2929
+ if (input.start)
2930
+ args.push('--start', input.start);
2931
+ if (input.end)
2932
+ args.push('--end', input.end);
2933
+ if (input.days)
2934
+ args.push('--days', String(input.days));
2935
+ // WU-1452: flow:report uses --format, not --json
2936
+ if (input.format)
2937
+ args.push('--format', input.format);
2938
+ if (input.json)
2939
+ args.push(...CliArgs.FORMAT_JSON);
2940
+ const cliOptions = { projectRoot: options?.projectRoot };
2941
+ const result = await runCliCommand('flow:report', args, cliOptions);
2942
+ if (result.success) {
2943
+ try {
2944
+ const data = JSON.parse(result.stdout);
2945
+ return success(data);
2946
+ }
2947
+ catch {
2948
+ return success({ message: result.stdout || 'Flow report generated' });
2949
+ }
2950
+ }
2951
+ else {
2952
+ return error(result.stderr || result.error?.message || 'flow:report failed', ErrorCodes.FLOW_REPORT_ERROR);
2953
+ }
2954
+ },
2955
+ };
2956
+ /**
2957
+ * metrics_snapshot - Capture metrics snapshot
2958
+ */
2959
+ export const metricsSnapshotTool = {
2960
+ name: 'metrics_snapshot',
2961
+ description: 'Capture a snapshot of current LumenFlow metrics',
2962
+ inputSchema: metricsSnapshotSchema,
2963
+ async execute(input, options) {
2964
+ // WU-1452: metrics:snapshot always outputs JSON (writes to file); no --json flag exists
2965
+ const args = [];
2966
+ const cliOptions = { projectRoot: options?.projectRoot };
2967
+ const result = await runCliCommand('metrics:snapshot', args, cliOptions);
2968
+ if (result.success) {
2969
+ try {
2970
+ const data = JSON.parse(result.stdout);
2971
+ return success(data);
2972
+ }
2973
+ catch {
2974
+ return success({ message: result.stdout || 'Metrics snapshot captured' });
2975
+ }
2976
+ }
2977
+ else {
2978
+ return error(result.stderr || result.error?.message || 'metrics:snapshot failed', ErrorCodes.METRICS_SNAPSHOT_ERROR);
2979
+ }
2980
+ },
2981
+ };
2982
+ // ============================================================================
2983
+ // Validation Operations (WU-1426)
2984
+ // ============================================================================
2985
+ /**
2986
+ * validate - Validate WU YAML files
2987
+ */
2988
+ export const validateTool = {
2989
+ name: 'validate',
2990
+ description: 'Validate WU YAML files and status consistency',
2991
+ inputSchema: validateSchema,
2992
+ async execute(input, options) {
2993
+ const args = [];
2994
+ if (input.id)
2995
+ args.push('--id', input.id);
2996
+ if (input.strict)
2997
+ args.push('--strict');
2998
+ if (input.done_only)
2999
+ args.push('--done-only');
3000
+ const cliOptions = { projectRoot: options?.projectRoot };
3001
+ const result = await runCliCommand('validate', args, cliOptions);
3002
+ if (result.success) {
3003
+ return success({ message: result.stdout || 'Validation passed' });
3004
+ }
3005
+ else {
3006
+ return error(result.stderr || result.error?.message || 'Validation failed', ErrorCodes.VALIDATE_ERROR);
3007
+ }
3008
+ },
3009
+ };
3010
+ /**
3011
+ * validate_agent_skills - Validate agent skill definitions
3012
+ */
3013
+ export const validateAgentSkillsTool = {
3014
+ name: 'validate_agent_skills',
3015
+ description: 'Validate agent skill definitions in .claude/skills/',
3016
+ inputSchema: validateAgentSkillsSchema,
3017
+ async execute(input, options) {
3018
+ const args = [];
3019
+ if (input.skill)
3020
+ args.push('--skill', input.skill);
3021
+ const cliOptions = { projectRoot: options?.projectRoot };
3022
+ const result = await runCliCommand('validate:agent-skills', args, cliOptions);
3023
+ if (result.success) {
3024
+ return success({ message: result.stdout || 'All skills valid' });
3025
+ }
3026
+ else {
3027
+ return error(result.stderr || result.error?.message || 'validate:agent-skills failed', ErrorCodes.VALIDATE_AGENT_SKILLS_ERROR);
3028
+ }
3029
+ },
3030
+ };
3031
+ /**
3032
+ * validate_agent_sync - Validate agent sync state
3033
+ */
3034
+ export const validateAgentSyncTool = {
3035
+ name: 'validate_agent_sync',
3036
+ description: 'Validate agent synchronization state',
3037
+ inputSchema: validateAgentSyncSchema,
3038
+ async execute(_input, options) {
3039
+ const cliOptions = { projectRoot: options?.projectRoot };
3040
+ const result = await runCliCommand('validate:agent-sync', [], cliOptions);
3041
+ if (result.success) {
3042
+ return success({ message: result.stdout || 'Agent sync valid' });
3043
+ }
3044
+ else {
3045
+ return error(result.stderr || result.error?.message || 'validate:agent-sync failed', ErrorCodes.VALIDATE_AGENT_SYNC_ERROR);
3046
+ }
3047
+ },
3048
+ };
3049
+ /**
3050
+ * validate_backlog_sync - Validate backlog synchronization
3051
+ */
3052
+ export const validateBacklogSyncTool = {
3053
+ name: 'validate_backlog_sync',
3054
+ description: 'Validate backlog synchronization between WU YAMLs and backlog.md',
3055
+ inputSchema: validateBacklogSyncSchema,
3056
+ async execute(_input, options) {
3057
+ const cliOptions = { projectRoot: options?.projectRoot };
3058
+ const result = await runCliCommand('validate:backlog-sync', [], cliOptions);
3059
+ if (result.success) {
3060
+ return success({ message: result.stdout || 'Backlog sync valid' });
3061
+ }
3062
+ else {
3063
+ return error(result.stderr || result.error?.message || 'validate:backlog-sync failed', ErrorCodes.VALIDATE_BACKLOG_SYNC_ERROR);
3064
+ }
3065
+ },
3066
+ };
3067
+ /**
3068
+ * validate_skills_spec - Validate skills specification
3069
+ */
3070
+ export const validateSkillsSpecTool = {
3071
+ name: 'validate_skills_spec',
3072
+ description: 'Validate skills specification files',
3073
+ inputSchema: validateSkillsSpecSchema,
3074
+ async execute(_input, options) {
3075
+ const cliOptions = { projectRoot: options?.projectRoot };
3076
+ const result = await runCliCommand('validate:skills-spec', [], cliOptions);
3077
+ if (result.success) {
3078
+ return success({ message: result.stdout || 'Skills spec valid' });
3079
+ }
3080
+ else {
3081
+ return error(result.stderr || result.error?.message || 'validate:skills-spec failed', ErrorCodes.VALIDATE_SKILLS_SPEC_ERROR);
3082
+ }
3083
+ },
3084
+ };
3085
+ // ============================================================================
3086
+ // Setup/LumenFlow Operations (WU-1426)
3087
+ // ============================================================================
3088
+ /**
3089
+ * lumenflow_init - Initialize LumenFlow in a project
3090
+ */
3091
+ export const lumenflowInitTool = {
3092
+ name: 'lumenflow_init',
3093
+ description: 'Initialize LumenFlow workflow framework in a project',
3094
+ inputSchema: lumenflowInitSchema,
3095
+ async execute(input, options) {
3096
+ const args = [];
3097
+ if (input.client)
3098
+ args.push('--client', input.client);
3099
+ if (input.merge)
3100
+ args.push('--merge');
3101
+ const cliOptions = { projectRoot: options?.projectRoot };
3102
+ const result = await runCliCommand('lumenflow:init', args, cliOptions);
3103
+ if (result.success) {
3104
+ return success({ message: result.stdout || 'LumenFlow initialized' });
3105
+ }
3106
+ else {
3107
+ return error(result.stderr || result.error?.message || 'lumenflow:init failed', ErrorCodes.LUMENFLOW_INIT_ERROR);
3108
+ }
3109
+ },
3110
+ };
3111
+ /**
3112
+ * lumenflow_doctor - Diagnose LumenFlow configuration
3113
+ */
3114
+ export const lumenflowDoctorTool = {
3115
+ name: 'lumenflow_doctor',
3116
+ description: 'Diagnose LumenFlow configuration and safety components',
3117
+ inputSchema: lumenflowDoctorSchema,
3118
+ async execute(_input, options) {
3119
+ const cliOptions = { projectRoot: options?.projectRoot };
3120
+ const result = await runCliCommand('lumenflow:doctor', [], cliOptions);
3121
+ if (result.success) {
3122
+ return success({ message: result.stdout || 'LumenFlow safety: ACTIVE' });
3123
+ }
3124
+ else {
3125
+ return error(result.stderr || result.error?.message || 'Doctor found issues', ErrorCodes.LUMENFLOW_DOCTOR_ERROR);
3126
+ }
3127
+ },
3128
+ };
3129
+ /**
3130
+ * lumenflow_integrate - Generate enforcement hooks for a client
3131
+ */
3132
+ export const lumenflowIntegrateTool = {
3133
+ name: 'lumenflow_integrate',
3134
+ description: 'Generate enforcement hooks for a specific client (e.g., claude-code)',
3135
+ inputSchema: lumenflowIntegrateSchema,
3136
+ async execute(input, options) {
3137
+ if (!input.client) {
3138
+ return error(ErrorMessages.CLIENT_REQUIRED, ErrorCodes.MISSING_PARAMETER);
3139
+ }
3140
+ const args = ['--client', input.client];
3141
+ const cliOptions = { projectRoot: options?.projectRoot };
3142
+ const result = await runCliCommand('lumenflow:integrate', args, cliOptions);
3143
+ if (result.success) {
3144
+ return success({ message: result.stdout || 'Hooks generated' });
3145
+ }
3146
+ else {
3147
+ return error(result.stderr || result.error?.message || 'lumenflow:integrate failed', ErrorCodes.LUMENFLOW_INTEGRATE_ERROR);
3148
+ }
3149
+ },
3150
+ };
3151
+ /**
3152
+ * lumenflow_upgrade - Upgrade LumenFlow packages
3153
+ */
3154
+ export const lumenflowUpgradeTool = {
3155
+ name: 'lumenflow_upgrade',
3156
+ description: 'Upgrade LumenFlow packages to latest versions',
3157
+ inputSchema: lumenflowUpgradeSchema,
3158
+ async execute(_input, options) {
3159
+ const cliOptions = { projectRoot: options?.projectRoot };
3160
+ const result = await runCliCommand('lumenflow:upgrade', [], cliOptions);
3161
+ if (result.success) {
3162
+ return success({ message: result.stdout || 'LumenFlow upgraded' });
3163
+ }
3164
+ else {
3165
+ return error(result.stderr || result.error?.message || 'lumenflow:upgrade failed', ErrorCodes.LUMENFLOW_UPGRADE_ERROR);
3166
+ }
3167
+ },
3168
+ };
3169
+ /**
3170
+ * lumenflow_commands - List all available CLI commands
3171
+ */
3172
+ export const lumenflowCommandsTool = {
3173
+ name: 'lumenflow_commands',
3174
+ description: 'List all available LumenFlow CLI commands',
3175
+ inputSchema: lumenflowCommandsSchema,
3176
+ async execute(_input, options) {
3177
+ const cliOptions = { projectRoot: options?.projectRoot };
3178
+ const result = await runCliCommand('lumenflow', ['commands'], cliOptions);
3179
+ if (result.success) {
3180
+ return success({ message: result.stdout || 'Commands listed' });
3181
+ }
3182
+ else {
3183
+ return error(result.stderr || result.error?.message || 'lumenflow commands failed', ErrorCodes.LUMENFLOW_COMMANDS_ERROR);
3184
+ }
3185
+ },
3186
+ };
3187
+ /**
3188
+ * lumenflow_docs_sync - Sync agent documentation
3189
+ */
3190
+ export const lumenflowDocsSyncTool = {
3191
+ name: 'lumenflow_docs_sync',
3192
+ description: 'Sync agent documentation after upgrading LumenFlow packages',
3193
+ inputSchema: docsSyncSchema,
3194
+ async execute(_input, options) {
3195
+ const cliOptions = { projectRoot: options?.projectRoot };
3196
+ const result = await runCliCommand('docs:sync', [], cliOptions);
3197
+ if (result.success) {
3198
+ return success({ message: result.stdout || 'Docs synced' });
3199
+ }
3200
+ else {
3201
+ return error(result.stderr || result.error?.message || 'docs:sync failed', ErrorCodes.LUMENFLOW_DOCS_SYNC_ERROR);
3202
+ }
3203
+ },
3204
+ };
3205
+ /**
3206
+ * lumenflow_release - Run release workflow
3207
+ */
3208
+ export const lumenflowReleaseTool = {
3209
+ name: 'lumenflow_release',
3210
+ description: 'Run LumenFlow release workflow (versioning, npm publish)',
3211
+ inputSchema: releaseSchema,
3212
+ async execute(input, options) {
3213
+ const args = [];
3214
+ if (input.dry_run)
3215
+ args.push(CliArgs.DRY_RUN);
3216
+ const cliOptions = { projectRoot: options?.projectRoot };
3217
+ const result = await runCliCommand('release', args, cliOptions);
3218
+ if (result.success) {
3219
+ return success({ message: result.stdout || 'Release complete' });
3220
+ }
3221
+ else {
3222
+ return error(result.stderr || result.error?.message || 'release failed', ErrorCodes.LUMENFLOW_RELEASE_ERROR);
3223
+ }
3224
+ },
3225
+ };
3226
+ /**
3227
+ * lumenflow_sync_templates - Sync templates to project
3228
+ */
3229
+ export const lumenflowSyncTemplatesTool = {
3230
+ name: 'lumenflow_sync_templates',
3231
+ description: 'Sync LumenFlow templates to the project',
3232
+ inputSchema: syncTemplatesSchema,
3233
+ async execute(_input, options) {
3234
+ const cliOptions = { projectRoot: options?.projectRoot };
3235
+ const result = await runCliCommand('sync:templates', [], cliOptions);
3236
+ if (result.success) {
3237
+ return success({ message: result.stdout || 'Templates synced' });
3238
+ }
3239
+ else {
3240
+ return error(result.stderr || result.error?.message || 'sync:templates failed', ErrorCodes.LUMENFLOW_SYNC_TEMPLATES_ERROR);
3241
+ }
3242
+ },
3243
+ };
3244
+ /**
3245
+ * MCP parity exclusions for tools that are intentionally MCP-only or maintainer-only.
3246
+ *
3247
+ * These names are excluded from strict public CLI parity comparison because
3248
+ * they have no public command in packages/@lumenflow/cli/src/public-manifest.ts.
3249
+ */
3250
+ export const MCP_PUBLIC_PARITY_ALLOWED_EXTRA_TOOLS = [
3251
+ 'context_get',
3252
+ 'gates_run',
3253
+ 'initiative_remove_wu',
3254
+ 'validate_agent_skills',
3255
+ 'validate_agent_sync',
3256
+ 'validate_backlog_sync',
3257
+ 'validate_skills_spec',
3258
+ 'wu_list',
3259
+ ];
3260
+ /**
3261
+ * Normalize public CLI command names to MCP tool naming.
3262
+ *
3263
+ * Example:
3264
+ * - "wu:create" -> "wu_create"
3265
+ * - "plan:promote" -> "plan_promote"
3266
+ */
3267
+ export function normalizePublicManifestCommandName(commandName) {
3268
+ return commandName.replace(/[:-]/g, '_');
3269
+ }
3270
+ /**
3271
+ * Compare public CLI manifest command names against MCP tool names.
3272
+ */
3273
+ export function buildMcpManifestParityReport(manifestCommandNames, mcpToolNames) {
3274
+ const normalizedManifest = new Set(manifestCommandNames.map((commandName) => normalizePublicManifestCommandName(commandName)));
3275
+ const mcpToolSet = new Set(mcpToolNames);
3276
+ const allowedExtraSet = new Set(MCP_PUBLIC_PARITY_ALLOWED_EXTRA_TOOLS);
3277
+ const missing = [...normalizedManifest].filter((name) => !mcpToolSet.has(name)).sort();
3278
+ const allowedExtra = [...mcpToolSet]
3279
+ .filter((name) => !normalizedManifest.has(name) && allowedExtraSet.has(name))
3280
+ .sort();
3281
+ const unexpectedExtra = [...mcpToolSet]
3282
+ .filter((name) => !normalizedManifest.has(name) && !allowedExtraSet.has(name))
3283
+ .sort();
3284
+ return { missing, allowedExtra, unexpectedExtra };
3285
+ }
303
3286
  /**
304
3287
  * All available tools
305
3288
  */
@@ -311,4 +3294,107 @@ export const allTools = [
311
3294
  wuClaimTool,
312
3295
  wuDoneTool,
313
3296
  gatesRunTool,
3297
+ // WU-1482: Wave-1 public parity tools
3298
+ backlogPruneTool,
3299
+ docsSyncTool,
3300
+ gatesTool,
3301
+ gatesDocsTool,
3302
+ laneHealthTool,
3303
+ laneSuggestTool,
3304
+ lumenflowTool,
3305
+ lumenflowGatesTool,
3306
+ lumenflowValidateTool,
3307
+ lumenflowMetricsTool,
3308
+ metricsTool,
3309
+ stateBootstrapTool,
3310
+ stateCleanupTool,
3311
+ stateDoctorTool,
3312
+ syncTemplatesTool,
3313
+ // WU-1483: Wave-2 public parity tools
3314
+ fileReadTool,
3315
+ fileWriteTool,
3316
+ fileEditTool,
3317
+ fileDeleteTool,
3318
+ gitStatusTool,
3319
+ gitDiffTool,
3320
+ gitLogTool,
3321
+ gitBranchTool,
3322
+ initPlanTool,
3323
+ planCreateTool,
3324
+ planEditTool,
3325
+ planLinkTool,
3326
+ planPromoteTool,
3327
+ signalCleanupTool,
3328
+ wuProtoTool,
3329
+ // WU-1422: Additional WU tools
3330
+ wuBlockTool,
3331
+ wuUnblockTool,
3332
+ wuEditTool,
3333
+ wuReleaseTool,
3334
+ wuRecoverTool,
3335
+ wuRepairTool,
3336
+ wuDepsTool,
3337
+ wuPrepTool,
3338
+ wuPreflightTool,
3339
+ wuPruneTool,
3340
+ wuDeleteTool,
3341
+ wuCleanupTool,
3342
+ wuSpawnTool,
3343
+ wuValidateTool,
3344
+ wuInferLaneTool,
3345
+ wuUnlockLaneTool,
3346
+ // WU-1424: Initiative tools
3347
+ initiativeListTool,
3348
+ initiativeStatusTool,
3349
+ initiativeCreateTool,
3350
+ initiativeEditTool,
3351
+ initiativeAddWuTool,
3352
+ initiativeRemoveWuTool,
3353
+ initiatiBulkAssignTool,
3354
+ initiativePlanTool,
3355
+ // WU-1424: Memory tools
3356
+ memInitTool,
3357
+ memStartTool,
3358
+ memReadyTool,
3359
+ memCheckpointTool,
3360
+ memCleanupTool,
3361
+ memContextTool,
3362
+ memCreateTool,
3363
+ memDeleteTool,
3364
+ memExportTool,
3365
+ memInboxTool,
3366
+ memSignalTool,
3367
+ memSummarizeTool,
3368
+ memTriageTool,
3369
+ // WU-1425: Agent tools
3370
+ agentSessionTool,
3371
+ agentSessionEndTool,
3372
+ agentLogIssueTool,
3373
+ agentIssuesQueryTool,
3374
+ // WU-1425: Orchestration tools
3375
+ orchestrateInitiativeTool,
3376
+ orchestrateInitStatusTool,
3377
+ orchestrateMonitorTool,
3378
+ // WU-1425: Spawn tools
3379
+ spawnListTool,
3380
+ // WU-1426: Flow/Metrics tools
3381
+ flowBottlenecksTool,
3382
+ flowReportTool,
3383
+ metricsSnapshotTool,
3384
+ // WU-1426: Validation tools
3385
+ validateTool,
3386
+ validateAgentSkillsTool,
3387
+ validateAgentSyncTool,
3388
+ validateBacklogSyncTool,
3389
+ validateSkillsSpecTool,
3390
+ // WU-1426: Setup tools
3391
+ lumenflowInitTool,
3392
+ lumenflowDoctorTool,
3393
+ lumenflowIntegrateTool,
3394
+ lumenflowUpgradeTool,
3395
+ lumenflowCommandsTool,
3396
+ lumenflowDocsSyncTool,
3397
+ lumenflowReleaseTool,
3398
+ lumenflowSyncTemplatesTool,
314
3399
  ];
3400
+ //# sourceMappingURL=tools.js.map