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