@lumenflow/mcp 2.18.2 → 2.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/tools/agent-tools.d.ts +26 -0
  2. package/dist/tools/agent-tools.d.ts.map +1 -0
  3. package/dist/tools/agent-tools.js +161 -0
  4. package/dist/tools/agent-tools.js.map +1 -0
  5. package/dist/tools/context-tools.d.ts +19 -0
  6. package/dist/tools/context-tools.d.ts.map +1 -0
  7. package/dist/tools/context-tools.js +73 -0
  8. package/dist/tools/context-tools.js.map +1 -0
  9. package/dist/tools/flow-tools.d.ts +30 -0
  10. package/dist/tools/flow-tools.d.ts.map +1 -0
  11. package/dist/tools/flow-tools.js +141 -0
  12. package/dist/tools/flow-tools.js.map +1 -0
  13. package/dist/tools/initiative-tools.d.ts +42 -0
  14. package/dist/tools/initiative-tools.d.ts.map +1 -0
  15. package/dist/tools/initiative-tools.js +304 -0
  16. package/dist/tools/initiative-tools.js.map +1 -0
  17. package/dist/tools/memory-tools.d.ts +66 -0
  18. package/dist/tools/memory-tools.d.ts.map +1 -0
  19. package/dist/tools/memory-tools.js +419 -0
  20. package/dist/tools/memory-tools.js.map +1 -0
  21. package/dist/tools/orchestration-tools.d.ts +26 -0
  22. package/dist/tools/orchestration-tools.d.ts.map +1 -0
  23. package/dist/tools/orchestration-tools.js +158 -0
  24. package/dist/tools/orchestration-tools.js.map +1 -0
  25. package/dist/tools/parity-tools.d.ts +118 -0
  26. package/dist/tools/parity-tools.d.ts.map +1 -0
  27. package/dist/tools/parity-tools.js +897 -0
  28. package/dist/tools/parity-tools.js.map +1 -0
  29. package/dist/tools/setup-tools.d.ts +42 -0
  30. package/dist/tools/setup-tools.d.ts.map +1 -0
  31. package/dist/tools/setup-tools.js +167 -0
  32. package/dist/tools/setup-tools.js.map +1 -0
  33. package/dist/tools/validation-tools.d.ts +34 -0
  34. package/dist/tools/validation-tools.d.ts.map +1 -0
  35. package/dist/tools/validation-tools.js +134 -0
  36. package/dist/tools/validation-tools.js.map +1 -0
  37. package/dist/tools/wu-tools.d.ts +116 -0
  38. package/dist/tools/wu-tools.d.ts.map +1 -0
  39. package/dist/tools/wu-tools.js +711 -0
  40. package/dist/tools/wu-tools.js.map +1 -0
  41. package/dist/tools-shared.d.ts +170 -0
  42. package/dist/tools-shared.d.ts.map +1 -0
  43. package/dist/tools-shared.js +203 -0
  44. package/dist/tools-shared.js.map +1 -0
  45. package/dist/tools.d.ts +34 -466
  46. package/dist/tools.d.ts.map +1 -1
  47. package/dist/tools.js +54 -3323
  48. package/dist/tools.js.map +1 -1
  49. package/package.json +2 -2
@@ -0,0 +1,897 @@
1
+ /**
2
+ * @file parity-tools.ts
3
+ * @description Wave-1 and Wave-2 public parity tool implementations
4
+ *
5
+ * WU-1642: Extracted from tools.ts during domain decomposition.
6
+ * WU-1482: Wave-1 public parity tools
7
+ * WU-1483: Wave-2 public parity tools (file, git, plan, signal, wu:proto)
8
+ */
9
+ import { z } from 'zod';
10
+ import { gatesSchema, lumenflowInitSchema, initiativePlanSchema } from '@lumenflow/core';
11
+ import { ErrorCodes, ErrorMessages, CliArgs, SharedErrorMessages, SuccessMessages, success, error, buildGatesArgs, runCliCommand, } from '../tools-shared.js';
12
+ // WU-1482: Schemas for wave-1 parity commands not yet modeled in @lumenflow/core
13
+ const backlogPruneSchema = z.object({
14
+ execute: z.boolean().optional(),
15
+ dry_run: z.boolean().optional(),
16
+ stale_days_in_progress: z.number().optional(),
17
+ stale_days_ready: z.number().optional(),
18
+ archive_days: z.number().optional(),
19
+ });
20
+ const docsSyncMcpSchema = z.object({
21
+ vendor: z.enum(['claude', 'cursor', 'aider', 'all', 'none']).optional(),
22
+ force: z.boolean().optional(),
23
+ });
24
+ const laneHealthSchema = z.object({
25
+ json: z.boolean().optional(),
26
+ verbose: z.boolean().optional(),
27
+ no_coverage: z.boolean().optional(),
28
+ });
29
+ const laneSuggestSchema = z.object({
30
+ dry_run: z.boolean().optional(),
31
+ interactive: z.boolean().optional(),
32
+ output: z.string().optional(),
33
+ json: z.boolean().optional(),
34
+ no_llm: z.boolean().optional(),
35
+ include_git: z.boolean().optional(),
36
+ });
37
+ const stateBootstrapSchema = z.object({
38
+ execute: z.boolean().optional(),
39
+ dry_run: z.boolean().optional(),
40
+ force: z.boolean().optional(),
41
+ wu_dir: z.string().optional(),
42
+ state_dir: z.string().optional(),
43
+ });
44
+ const stateCleanupSchema = z.object({
45
+ dry_run: z.boolean().optional(),
46
+ signals_only: z.boolean().optional(),
47
+ memory_only: z.boolean().optional(),
48
+ events_only: z.boolean().optional(),
49
+ json: z.boolean().optional(),
50
+ quiet: z.boolean().optional(),
51
+ base_dir: z.string().optional(),
52
+ });
53
+ const stateDoctorSchema = z.object({
54
+ fix: z.boolean().optional(),
55
+ dry_run: z.boolean().optional(),
56
+ json: z.boolean().optional(),
57
+ quiet: z.boolean().optional(),
58
+ base_dir: z.string().optional(),
59
+ });
60
+ const syncTemplatesMcpSchema = z.object({
61
+ dry_run: z.boolean().optional(),
62
+ verbose: z.boolean().optional(),
63
+ check_drift: z.boolean().optional(),
64
+ });
65
+ // WU-1483: Schemas for wave-2 parity commands not yet modeled in @lumenflow/core
66
+ const fileReadSchema = z.object({
67
+ path: z.string().optional(),
68
+ encoding: z.string().optional(),
69
+ start_line: z.number().optional(),
70
+ end_line: z.number().optional(),
71
+ max_size: z.number().optional(),
72
+ });
73
+ const fileWriteSchema = z.object({
74
+ path: z.string().optional(),
75
+ content: z.string().optional(),
76
+ encoding: z.string().optional(),
77
+ no_create_dirs: z.boolean().optional(),
78
+ scan_phi: z.boolean().optional(),
79
+ });
80
+ const fileEditSchema = z.object({
81
+ path: z.string().optional(),
82
+ old_string: z.string().optional(),
83
+ new_string: z.string().optional(),
84
+ encoding: z.string().optional(),
85
+ replace_all: z.boolean().optional(),
86
+ });
87
+ const fileDeleteSchema = z.object({
88
+ path: z.string().optional(),
89
+ recursive: z.boolean().optional(),
90
+ force: z.boolean().optional(),
91
+ });
92
+ const gitStatusSchema = z.object({
93
+ base_dir: z.string().optional(),
94
+ path: z.string().optional(),
95
+ porcelain: z.boolean().optional(),
96
+ short: z.boolean().optional(),
97
+ });
98
+ const gitDiffSchema = z.object({
99
+ base_dir: z.string().optional(),
100
+ ref: z.string().optional(),
101
+ staged: z.boolean().optional(),
102
+ name_only: z.boolean().optional(),
103
+ stat: z.boolean().optional(),
104
+ path: z.string().optional(),
105
+ });
106
+ const gitLogSchema = z.object({
107
+ base_dir: z.string().optional(),
108
+ ref: z.string().optional(),
109
+ oneline: z.boolean().optional(),
110
+ max_count: z.number().optional(),
111
+ format: z.string().optional(),
112
+ since: z.string().optional(),
113
+ author: z.string().optional(),
114
+ });
115
+ const gitBranchSchema = z.object({
116
+ base_dir: z.string().optional(),
117
+ list: z.boolean().optional(),
118
+ all: z.boolean().optional(),
119
+ remotes: z.boolean().optional(),
120
+ show_current: z.boolean().optional(),
121
+ contains: z.string().optional(),
122
+ });
123
+ const planCreateSchema = z.object({
124
+ id: z.string().optional(),
125
+ title: z.string().optional(),
126
+ });
127
+ const planEditSchema = z.object({
128
+ id: z.string().optional(),
129
+ section: z.string().optional(),
130
+ content: z.string().optional(),
131
+ append: z.string().optional(),
132
+ });
133
+ const planLinkSchema = z.object({
134
+ id: z.string().optional(),
135
+ plan: z.string().optional(),
136
+ });
137
+ const planPromoteSchema = z.object({
138
+ id: z.string().optional(),
139
+ force: z.boolean().optional(),
140
+ });
141
+ const signalCleanupSchema = z.object({
142
+ dry_run: z.boolean().optional(),
143
+ ttl: z.string().optional(),
144
+ unread_ttl: z.string().optional(),
145
+ max_entries: z.number().optional(),
146
+ json: z.boolean().optional(),
147
+ quiet: z.boolean().optional(),
148
+ base_dir: z.string().optional(),
149
+ });
150
+ const wuProtoSchema = z.object({
151
+ lane: z.string().optional(),
152
+ title: z.string().optional(),
153
+ description: z.string().optional(),
154
+ code_paths: z.array(z.string()).optional(),
155
+ labels: z.array(z.string()).optional(),
156
+ assigned_to: z.string().optional(),
157
+ });
158
+ // ============================================================================
159
+ // Wave-1 Public Parity Operations (WU-1482)
160
+ // ============================================================================
161
+ /**
162
+ * backlog_prune - Clean stale backlog entries
163
+ */
164
+ export const backlogPruneTool = {
165
+ name: 'backlog_prune',
166
+ description: 'Clean stale backlog entries and archive old completed WUs',
167
+ inputSchema: backlogPruneSchema,
168
+ async execute(input, options) {
169
+ const args = [];
170
+ if (input.execute)
171
+ args.push('--execute');
172
+ if (input.dry_run)
173
+ args.push('--dry-run');
174
+ if (input.stale_days_in_progress !== undefined) {
175
+ args.push('--stale-days-in-progress', String(input.stale_days_in_progress));
176
+ }
177
+ if (input.stale_days_ready !== undefined) {
178
+ args.push('--stale-days-ready', String(input.stale_days_ready));
179
+ }
180
+ if (input.archive_days !== undefined) {
181
+ args.push('--archive-days', String(input.archive_days));
182
+ }
183
+ const cliOptions = { projectRoot: options?.projectRoot };
184
+ const result = await runCliCommand('backlog:prune', args, cliOptions);
185
+ if (result.success) {
186
+ return success({ message: result.stdout || 'Backlog prune complete' });
187
+ }
188
+ return error(result.stderr || result.error?.message || 'backlog:prune failed', ErrorCodes.BACKLOG_PRUNE_ERROR);
189
+ },
190
+ };
191
+ /**
192
+ * docs_sync - Sync agent docs to existing project
193
+ */
194
+ export const docsSyncTool = {
195
+ name: 'docs_sync',
196
+ description: 'Sync agent onboarding docs and skills to existing projects',
197
+ inputSchema: docsSyncMcpSchema,
198
+ async execute(input, options) {
199
+ const args = [];
200
+ if (input.vendor)
201
+ args.push('--vendor', input.vendor);
202
+ if (input.force)
203
+ args.push('--force');
204
+ const cliOptions = { projectRoot: options?.projectRoot };
205
+ const result = await runCliCommand('docs:sync', args, cliOptions);
206
+ if (result.success) {
207
+ return success({ message: result.stdout || 'Docs sync complete' });
208
+ }
209
+ return error(result.stderr || result.error?.message || 'docs:sync failed', ErrorCodes.DOCS_SYNC_ERROR);
210
+ },
211
+ };
212
+ /**
213
+ * gates - Public gates command
214
+ */
215
+ export const gatesTool = {
216
+ name: 'gates',
217
+ description: 'Run LumenFlow quality gates',
218
+ inputSchema: gatesSchema,
219
+ async execute(input, options) {
220
+ const args = buildGatesArgs(input);
221
+ const cliOptions = {
222
+ projectRoot: options?.projectRoot,
223
+ timeout: 600000,
224
+ };
225
+ const result = await runCliCommand('gates', args, cliOptions);
226
+ if (result.success) {
227
+ return success({ message: result.stdout || SuccessMessages.ALL_GATES_PASSED });
228
+ }
229
+ return error(result.stderr || result.error?.message || 'gates failed', ErrorCodes.GATES_ALIAS_ERROR);
230
+ },
231
+ };
232
+ /**
233
+ * gates_docs - Public docs-only gates alias
234
+ */
235
+ export const gatesDocsTool = {
236
+ name: 'gates_docs',
237
+ description: 'Run docs-only quality gates',
238
+ inputSchema: gatesSchema,
239
+ async execute(input, options) {
240
+ const args = buildGatesArgs(input, { forceDocsOnly: true });
241
+ const cliOptions = {
242
+ projectRoot: options?.projectRoot,
243
+ timeout: 600000,
244
+ };
245
+ const result = await runCliCommand('gates', args, cliOptions);
246
+ if (result.success) {
247
+ return success({ message: result.stdout || 'Docs-only gates passed' });
248
+ }
249
+ return error(result.stderr || result.error?.message || 'gates:docs failed', ErrorCodes.GATES_ALIAS_ERROR);
250
+ },
251
+ };
252
+ /**
253
+ * lane_health - Diagnose lane configuration issues
254
+ */
255
+ export const laneHealthTool = {
256
+ name: 'lane_health',
257
+ description: 'Check lane configuration health (overlaps and coverage gaps)',
258
+ inputSchema: laneHealthSchema,
259
+ async execute(input, options) {
260
+ const args = [];
261
+ if (input.json)
262
+ args.push('--json');
263
+ if (input.verbose)
264
+ args.push('--verbose');
265
+ if (input.no_coverage)
266
+ args.push('--no-coverage');
267
+ const cliOptions = { projectRoot: options?.projectRoot };
268
+ const result = await runCliCommand('lane:health', args, cliOptions);
269
+ if (result.success) {
270
+ try {
271
+ const data = JSON.parse(result.stdout);
272
+ return success(data);
273
+ }
274
+ catch {
275
+ return success({ message: result.stdout || 'Lane health check complete' });
276
+ }
277
+ }
278
+ return error(result.stderr || result.error?.message || 'lane:health failed', ErrorCodes.LANE_HEALTH_ERROR);
279
+ },
280
+ };
281
+ /**
282
+ * lane_suggest - Suggest lane definitions from project context
283
+ */
284
+ export const laneSuggestTool = {
285
+ name: 'lane_suggest',
286
+ description: 'Generate lane suggestions from codebase context',
287
+ inputSchema: laneSuggestSchema,
288
+ async execute(input, options) {
289
+ const args = [];
290
+ if (input.dry_run)
291
+ args.push('--dry-run');
292
+ if (input.interactive)
293
+ args.push('--interactive');
294
+ if (input.output)
295
+ args.push('--output', input.output);
296
+ if (input.json)
297
+ args.push('--json');
298
+ if (input.no_llm)
299
+ args.push('--no-llm');
300
+ if (input.include_git)
301
+ args.push('--include-git');
302
+ const cliOptions = { projectRoot: options?.projectRoot };
303
+ const result = await runCliCommand('lane:suggest', args, cliOptions);
304
+ if (result.success) {
305
+ try {
306
+ const data = JSON.parse(result.stdout);
307
+ return success(data);
308
+ }
309
+ catch {
310
+ return success({ message: result.stdout || 'Lane suggestions generated' });
311
+ }
312
+ }
313
+ return error(result.stderr || result.error?.message || 'lane:suggest failed', ErrorCodes.LANE_SUGGEST_ERROR);
314
+ },
315
+ };
316
+ /**
317
+ * lumenflow - Public initializer command
318
+ */
319
+ export const lumenflowTool = {
320
+ name: 'lumenflow',
321
+ description: 'Initialize LumenFlow in a project',
322
+ inputSchema: lumenflowInitSchema,
323
+ async execute(input, options) {
324
+ const args = [];
325
+ if (input.client)
326
+ args.push('--client', input.client);
327
+ if (input.merge)
328
+ args.push('--merge');
329
+ if (input.full)
330
+ args.push('--full');
331
+ if (input.minimal)
332
+ args.push('--minimal');
333
+ if (input.framework)
334
+ args.push('--framework', input.framework);
335
+ const cliOptions = { projectRoot: options?.projectRoot };
336
+ const result = await runCliCommand('lumenflow', args, cliOptions);
337
+ if (result.success) {
338
+ return success({ message: result.stdout || 'LumenFlow initialized' });
339
+ }
340
+ return error(result.stderr || result.error?.message || 'lumenflow failed', ErrorCodes.LUMENFLOW_ALIAS_ERROR);
341
+ },
342
+ };
343
+ /**
344
+ * lumenflow_gates - Public gates alias
345
+ */
346
+ export const lumenflowGatesTool = {
347
+ name: 'lumenflow_gates',
348
+ description: 'Run quality gates (lumenflow-gates alias)',
349
+ inputSchema: gatesSchema,
350
+ async execute(input, options) {
351
+ const args = buildGatesArgs(input);
352
+ const cliOptions = {
353
+ projectRoot: options?.projectRoot,
354
+ timeout: 600000,
355
+ };
356
+ const result = await runCliCommand('gates', args, cliOptions);
357
+ if (result.success) {
358
+ return success({ message: result.stdout || SuccessMessages.ALL_GATES_PASSED });
359
+ }
360
+ return error(result.stderr || result.error?.message || 'lumenflow-gates failed', ErrorCodes.LUMENFLOW_GATES_ERROR);
361
+ },
362
+ };
363
+ /**
364
+ * state_bootstrap - Bootstrap event store from WU YAMLs
365
+ */
366
+ export const stateBootstrapTool = {
367
+ name: 'state_bootstrap',
368
+ description: 'Bootstrap state store from existing WU YAML files',
369
+ inputSchema: stateBootstrapSchema,
370
+ async execute(input, options) {
371
+ const args = [];
372
+ if (input.execute)
373
+ args.push('--execute');
374
+ if (input.dry_run)
375
+ args.push('--dry-run');
376
+ if (input.force)
377
+ args.push('--force');
378
+ if (input.wu_dir)
379
+ args.push('--wu-dir', input.wu_dir);
380
+ if (input.state_dir)
381
+ args.push('--state-dir', input.state_dir);
382
+ const cliOptions = { projectRoot: options?.projectRoot };
383
+ const result = await runCliCommand('state:bootstrap', args, cliOptions);
384
+ if (result.success) {
385
+ return success({ message: result.stdout || 'State bootstrap complete' });
386
+ }
387
+ return error(result.stderr || result.error?.message || 'state:bootstrap failed', ErrorCodes.STATE_BOOTSTRAP_ERROR);
388
+ },
389
+ };
390
+ /**
391
+ * state_cleanup - Run unified state cleanup
392
+ */
393
+ export const stateCleanupTool = {
394
+ name: 'state_cleanup',
395
+ description: 'Clean stale state, memory, and signal data',
396
+ inputSchema: stateCleanupSchema,
397
+ async execute(input, options) {
398
+ const args = [];
399
+ if (input.dry_run)
400
+ args.push('--dry-run');
401
+ if (input.signals_only)
402
+ args.push('--signals-only');
403
+ if (input.memory_only)
404
+ args.push('--memory-only');
405
+ if (input.events_only)
406
+ args.push('--events-only');
407
+ if (input.json)
408
+ args.push('--json');
409
+ if (input.quiet)
410
+ args.push('--quiet');
411
+ if (input.base_dir)
412
+ args.push(CliArgs.BASE_DIR, input.base_dir);
413
+ const cliOptions = { projectRoot: options?.projectRoot };
414
+ const result = await runCliCommand('state:cleanup', args, cliOptions);
415
+ if (result.success) {
416
+ return success({ message: result.stdout || 'State cleanup complete' });
417
+ }
418
+ return error(result.stderr || result.error?.message || 'state:cleanup failed', ErrorCodes.STATE_CLEANUP_ERROR);
419
+ },
420
+ };
421
+ /**
422
+ * state_doctor - Diagnose and repair state issues
423
+ */
424
+ export const stateDoctorTool = {
425
+ name: 'state_doctor',
426
+ description: 'Diagnose state store integrity issues',
427
+ inputSchema: stateDoctorSchema,
428
+ async execute(input, options) {
429
+ const args = [];
430
+ if (input.fix)
431
+ args.push('--fix');
432
+ if (input.dry_run)
433
+ args.push('--dry-run');
434
+ if (input.json)
435
+ args.push('--json');
436
+ if (input.quiet)
437
+ args.push('--quiet');
438
+ if (input.base_dir)
439
+ args.push(CliArgs.BASE_DIR, input.base_dir);
440
+ const cliOptions = { projectRoot: options?.projectRoot };
441
+ const result = await runCliCommand('state:doctor', args, cliOptions);
442
+ if (result.success) {
443
+ return success({ message: result.stdout || 'State doctor complete' });
444
+ }
445
+ return error(result.stderr || result.error?.message || 'state:doctor failed', ErrorCodes.STATE_DOCTOR_ERROR);
446
+ },
447
+ };
448
+ /**
449
+ * sync_templates - Sync templates from source docs
450
+ */
451
+ export const syncTemplatesTool = {
452
+ name: 'sync_templates',
453
+ description: 'Sync internal docs to CLI templates',
454
+ inputSchema: syncTemplatesMcpSchema,
455
+ async execute(input, options) {
456
+ const args = [];
457
+ if (input.dry_run)
458
+ args.push('--dry-run');
459
+ if (input.verbose)
460
+ args.push('--verbose');
461
+ if (input.check_drift)
462
+ args.push('--check-drift');
463
+ const cliOptions = { projectRoot: options?.projectRoot };
464
+ const result = await runCliCommand('sync:templates', args, cliOptions);
465
+ if (result.success) {
466
+ return success({ message: result.stdout || 'Template sync complete' });
467
+ }
468
+ return error(result.stderr || result.error?.message || 'sync:templates failed', ErrorCodes.SYNC_TEMPLATES_ALIAS_ERROR);
469
+ },
470
+ };
471
+ // ============================================================================
472
+ // Wave-2 Public Parity Operations (WU-1483)
473
+ // ============================================================================
474
+ /**
475
+ * file_read - Read file content with audit trail
476
+ */
477
+ export const fileReadTool = {
478
+ name: 'file_read',
479
+ description: 'Read a file with optional line ranges and encoding',
480
+ inputSchema: fileReadSchema,
481
+ async execute(input, options) {
482
+ if (!input.path) {
483
+ return error(ErrorMessages.PATH_REQUIRED, ErrorCodes.MISSING_PARAMETER);
484
+ }
485
+ const args = ['--path', input.path];
486
+ if (input.encoding)
487
+ args.push(CliArgs.ENCODING, input.encoding);
488
+ if (input.start_line !== undefined)
489
+ args.push('--start-line', String(input.start_line));
490
+ if (input.end_line !== undefined)
491
+ args.push('--end-line', String(input.end_line));
492
+ if (input.max_size !== undefined)
493
+ args.push('--max-size', String(input.max_size));
494
+ const cliOptions = { projectRoot: options?.projectRoot };
495
+ const result = await runCliCommand('file:read', args, cliOptions);
496
+ if (result.success) {
497
+ return success({ content: result.stdout });
498
+ }
499
+ return error(result.stderr || result.error?.message || 'file:read failed', ErrorCodes.FILE_READ_ERROR);
500
+ },
501
+ };
502
+ /**
503
+ * file_write - Write file content with audit trail
504
+ */
505
+ export const fileWriteTool = {
506
+ name: 'file_write',
507
+ description: 'Write content to a file with optional PHI scan',
508
+ inputSchema: fileWriteSchema,
509
+ async execute(input, options) {
510
+ if (!input.path) {
511
+ return error(ErrorMessages.PATH_REQUIRED, ErrorCodes.MISSING_PARAMETER);
512
+ }
513
+ if (input.content === undefined) {
514
+ return error(ErrorMessages.CONTENT_REQUIRED, ErrorCodes.MISSING_PARAMETER);
515
+ }
516
+ const args = ['--path', input.path, '--content', input.content];
517
+ if (input.encoding)
518
+ args.push(CliArgs.ENCODING, input.encoding);
519
+ if (input.no_create_dirs)
520
+ args.push('--no-create-dirs');
521
+ if (input.scan_phi)
522
+ args.push('--scan-phi');
523
+ const cliOptions = { projectRoot: options?.projectRoot };
524
+ const result = await runCliCommand('file:write', args, cliOptions);
525
+ if (result.success) {
526
+ return success({ message: result.stdout || 'File written' });
527
+ }
528
+ return error(result.stderr || result.error?.message || 'file:write failed', ErrorCodes.FILE_WRITE_ERROR);
529
+ },
530
+ };
531
+ /**
532
+ * file_edit - Replace exact string matches in a file
533
+ */
534
+ export const fileEditTool = {
535
+ name: 'file_edit',
536
+ description: 'Edit a file via exact string replacement',
537
+ inputSchema: fileEditSchema,
538
+ async execute(input, options) {
539
+ if (!input.path) {
540
+ return error(ErrorMessages.PATH_REQUIRED, ErrorCodes.MISSING_PARAMETER);
541
+ }
542
+ if (!input.old_string) {
543
+ return error(ErrorMessages.OLD_STRING_REQUIRED, ErrorCodes.MISSING_PARAMETER);
544
+ }
545
+ if (input.new_string === undefined) {
546
+ return error(ErrorMessages.NEW_STRING_REQUIRED, ErrorCodes.MISSING_PARAMETER);
547
+ }
548
+ const args = [
549
+ '--path',
550
+ input.path,
551
+ '--old-string',
552
+ input.old_string,
553
+ '--new-string',
554
+ input.new_string,
555
+ ];
556
+ if (input.encoding)
557
+ args.push(CliArgs.ENCODING, input.encoding);
558
+ if (input.replace_all)
559
+ args.push('--replace-all');
560
+ const cliOptions = { projectRoot: options?.projectRoot };
561
+ const result = await runCliCommand('file:edit', args, cliOptions);
562
+ if (result.success) {
563
+ return success({ message: result.stdout || 'File edited' });
564
+ }
565
+ return error(result.stderr || result.error?.message || 'file:edit failed', ErrorCodes.FILE_EDIT_ERROR);
566
+ },
567
+ };
568
+ /**
569
+ * file_delete - Delete file or directory with audit trail
570
+ */
571
+ export const fileDeleteTool = {
572
+ name: 'file_delete',
573
+ description: 'Delete files or directories with safety flags',
574
+ inputSchema: fileDeleteSchema,
575
+ async execute(input, options) {
576
+ if (!input.path) {
577
+ return error(ErrorMessages.PATH_REQUIRED, ErrorCodes.MISSING_PARAMETER);
578
+ }
579
+ const args = ['--path', input.path];
580
+ if (input.recursive)
581
+ args.push('--recursive');
582
+ if (input.force)
583
+ args.push('--force');
584
+ const cliOptions = { projectRoot: options?.projectRoot };
585
+ const result = await runCliCommand('file:delete', args, cliOptions);
586
+ if (result.success) {
587
+ return success({ message: result.stdout || 'Delete complete' });
588
+ }
589
+ return error(result.stderr || result.error?.message || 'file:delete failed', ErrorCodes.FILE_DELETE_ERROR);
590
+ },
591
+ };
592
+ /**
593
+ * git_status - Show git status
594
+ */
595
+ export const gitStatusTool = {
596
+ name: 'git_status',
597
+ description: 'Show git status with optional porcelain/short modes',
598
+ inputSchema: gitStatusSchema,
599
+ async execute(input, options) {
600
+ const args = [];
601
+ if (input.base_dir)
602
+ args.push(CliArgs.BASE_DIR, input.base_dir);
603
+ if (input.porcelain)
604
+ args.push('--porcelain');
605
+ if (input.short)
606
+ args.push('--short');
607
+ if (input.path)
608
+ args.push(input.path);
609
+ const cliOptions = { projectRoot: options?.projectRoot };
610
+ const result = await runCliCommand('git:status', args, cliOptions);
611
+ if (result.success) {
612
+ return success({ output: result.stdout });
613
+ }
614
+ return error(result.stderr || result.error?.message || 'git:status failed', ErrorCodes.GIT_STATUS_ERROR);
615
+ },
616
+ };
617
+ /**
618
+ * git_diff - Show git diff
619
+ */
620
+ export const gitDiffTool = {
621
+ name: 'git_diff',
622
+ description: 'Show git diff with staged/name-only/stat modes',
623
+ inputSchema: gitDiffSchema,
624
+ async execute(input, options) {
625
+ const args = [];
626
+ if (input.base_dir)
627
+ args.push(CliArgs.BASE_DIR, input.base_dir);
628
+ if (input.staged)
629
+ args.push('--staged');
630
+ if (input.name_only)
631
+ args.push('--name-only');
632
+ if (input.stat)
633
+ args.push('--stat');
634
+ if (input.ref)
635
+ args.push(input.ref);
636
+ if (input.path)
637
+ args.push('--', input.path);
638
+ const cliOptions = { projectRoot: options?.projectRoot };
639
+ const result = await runCliCommand('git:diff', args, cliOptions);
640
+ if (result.success) {
641
+ return success({ output: result.stdout });
642
+ }
643
+ return error(result.stderr || result.error?.message || 'git:diff failed', ErrorCodes.GIT_DIFF_ERROR);
644
+ },
645
+ };
646
+ /**
647
+ * git_log - Show commit history
648
+ */
649
+ export const gitLogTool = {
650
+ name: 'git_log',
651
+ description: 'Show git commit log with filters',
652
+ inputSchema: gitLogSchema,
653
+ async execute(input, options) {
654
+ const args = [];
655
+ if (input.base_dir)
656
+ args.push(CliArgs.BASE_DIR, input.base_dir);
657
+ if (input.oneline)
658
+ args.push('--oneline');
659
+ if (input.max_count !== undefined)
660
+ args.push('-n', String(input.max_count));
661
+ if (input.format)
662
+ args.push('--format', input.format);
663
+ if (input.since)
664
+ args.push('--since', input.since);
665
+ if (input.author)
666
+ args.push('--author', input.author);
667
+ if (input.ref)
668
+ args.push(input.ref);
669
+ const cliOptions = { projectRoot: options?.projectRoot };
670
+ const result = await runCliCommand('git:log', args, cliOptions);
671
+ if (result.success) {
672
+ return success({ output: result.stdout });
673
+ }
674
+ return error(result.stderr || result.error?.message || 'git:log failed', ErrorCodes.GIT_LOG_ERROR);
675
+ },
676
+ };
677
+ /**
678
+ * git_branch - Show branch information
679
+ */
680
+ export const gitBranchTool = {
681
+ name: 'git_branch',
682
+ description: 'Show git branch listing and current branch',
683
+ inputSchema: gitBranchSchema,
684
+ async execute(input, options) {
685
+ const args = [];
686
+ if (input.base_dir)
687
+ args.push(CliArgs.BASE_DIR, input.base_dir);
688
+ if (input.list)
689
+ args.push('--list');
690
+ if (input.all)
691
+ args.push('--all');
692
+ if (input.remotes)
693
+ args.push('--remotes');
694
+ if (input.show_current)
695
+ args.push('--show-current');
696
+ if (input.contains)
697
+ args.push('--contains', input.contains);
698
+ const cliOptions = { projectRoot: options?.projectRoot };
699
+ const result = await runCliCommand('git:branch', args, cliOptions);
700
+ if (result.success) {
701
+ return success({ output: result.stdout });
702
+ }
703
+ return error(result.stderr || result.error?.message || 'git:branch failed', ErrorCodes.GIT_BRANCH_ERROR);
704
+ },
705
+ };
706
+ /**
707
+ * init_plan - Link plan to initiative (alias)
708
+ */
709
+ export const initPlanTool = {
710
+ name: 'init_plan',
711
+ description: 'Link or create a plan for an initiative',
712
+ inputSchema: initiativePlanSchema,
713
+ async execute(input, options) {
714
+ if (!input.initiative) {
715
+ return error(SharedErrorMessages.INITIATIVE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
716
+ }
717
+ if (!input.plan && !input.create) {
718
+ return error(ErrorMessages.PLAN_REQUIRED, ErrorCodes.MISSING_PARAMETER);
719
+ }
720
+ const args = ['--initiative', input.initiative];
721
+ if (input.plan)
722
+ args.push('--plan', input.plan);
723
+ if (input.create)
724
+ args.push('--create');
725
+ const cliOptions = { projectRoot: options?.projectRoot };
726
+ const result = await runCliCommand('init:plan', args, cliOptions);
727
+ if (result.success) {
728
+ return success({ message: result.stdout || 'Plan linked' });
729
+ }
730
+ return error(result.stderr || result.error?.message || 'init:plan failed', ErrorCodes.INIT_PLAN_ERROR);
731
+ },
732
+ };
733
+ /**
734
+ * plan_create - Create a plan file
735
+ */
736
+ export const planCreateTool = {
737
+ name: 'plan_create',
738
+ description: 'Create a new plan for a WU or initiative',
739
+ inputSchema: planCreateSchema,
740
+ async execute(input, options) {
741
+ if (!input.id) {
742
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
743
+ }
744
+ if (!input.title) {
745
+ return error(ErrorMessages.TITLE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
746
+ }
747
+ const args = ['--id', input.id, '--title', input.title];
748
+ const cliOptions = { projectRoot: options?.projectRoot };
749
+ const result = await runCliCommand('plan:create', args, cliOptions);
750
+ if (result.success) {
751
+ return success({ message: result.stdout || 'Plan created' });
752
+ }
753
+ return error(result.stderr || result.error?.message || 'plan:create failed', ErrorCodes.PLAN_CREATE_ERROR);
754
+ },
755
+ };
756
+ /**
757
+ * plan_edit - Edit an existing plan section
758
+ */
759
+ export const planEditTool = {
760
+ name: 'plan_edit',
761
+ description: 'Edit or append content to a plan section',
762
+ inputSchema: planEditSchema,
763
+ async execute(input, options) {
764
+ if (!input.id) {
765
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
766
+ }
767
+ if (!input.section) {
768
+ return error(ErrorMessages.SECTION_REQUIRED, ErrorCodes.MISSING_PARAMETER);
769
+ }
770
+ if (!input.content && !input.append) {
771
+ return error(ErrorMessages.CONTENT_REQUIRED, ErrorCodes.MISSING_PARAMETER);
772
+ }
773
+ const args = ['--id', input.id, '--section', input.section];
774
+ if (input.content)
775
+ args.push('--content', input.content);
776
+ if (input.append)
777
+ args.push('--append', input.append);
778
+ const cliOptions = { projectRoot: options?.projectRoot };
779
+ const result = await runCliCommand('plan:edit', args, cliOptions);
780
+ if (result.success) {
781
+ return success({ message: result.stdout || 'Plan edited' });
782
+ }
783
+ return error(result.stderr || result.error?.message || 'plan:edit failed', ErrorCodes.PLAN_EDIT_ERROR);
784
+ },
785
+ };
786
+ /**
787
+ * plan_link - Link plan URI to WU/initiative
788
+ */
789
+ export const planLinkTool = {
790
+ name: 'plan_link',
791
+ description: 'Link an existing plan URI to a WU or initiative',
792
+ inputSchema: planLinkSchema,
793
+ async execute(input, options) {
794
+ if (!input.id) {
795
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
796
+ }
797
+ if (!input.plan) {
798
+ return error(ErrorMessages.PLAN_REQUIRED, ErrorCodes.MISSING_PARAMETER);
799
+ }
800
+ const args = ['--id', input.id, '--plan', input.plan];
801
+ const cliOptions = { projectRoot: options?.projectRoot };
802
+ const result = await runCliCommand('plan:link', args, cliOptions);
803
+ if (result.success) {
804
+ return success({ message: result.stdout || 'Plan linked' });
805
+ }
806
+ return error(result.stderr || result.error?.message || 'plan:link failed', ErrorCodes.PLAN_LINK_ERROR);
807
+ },
808
+ };
809
+ /**
810
+ * plan_promote - Promote plan to approved status
811
+ */
812
+ export const planPromoteTool = {
813
+ name: 'plan_promote',
814
+ description: 'Promote plan from draft to approved status',
815
+ inputSchema: planPromoteSchema,
816
+ async execute(input, options) {
817
+ if (!input.id) {
818
+ return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
819
+ }
820
+ const args = ['--id', input.id];
821
+ if (input.force)
822
+ args.push('--force');
823
+ const cliOptions = { projectRoot: options?.projectRoot };
824
+ const result = await runCliCommand('plan:promote', args, cliOptions);
825
+ if (result.success) {
826
+ return success({ message: result.stdout || 'Plan promoted' });
827
+ }
828
+ return error(result.stderr || result.error?.message || 'plan:promote failed', ErrorCodes.PLAN_PROMOTE_ERROR);
829
+ },
830
+ };
831
+ /**
832
+ * signal_cleanup - Clean stale signals
833
+ */
834
+ export const signalCleanupTool = {
835
+ name: 'signal_cleanup',
836
+ description: 'Cleanup stale signals using TTL policy',
837
+ inputSchema: signalCleanupSchema,
838
+ async execute(input, options) {
839
+ const args = [];
840
+ if (input.dry_run)
841
+ args.push('--dry-run');
842
+ if (input.ttl)
843
+ args.push('--ttl', input.ttl);
844
+ if (input.unread_ttl)
845
+ args.push('--unread-ttl', input.unread_ttl);
846
+ if (input.max_entries !== undefined)
847
+ args.push('--max-entries', String(input.max_entries));
848
+ if (input.json)
849
+ args.push('--json');
850
+ if (input.quiet)
851
+ args.push('--quiet');
852
+ if (input.base_dir)
853
+ args.push(CliArgs.BASE_DIR, input.base_dir);
854
+ const cliOptions = { projectRoot: options?.projectRoot };
855
+ const result = await runCliCommand('signal:cleanup', args, cliOptions);
856
+ if (result.success) {
857
+ return success({ message: result.stdout || 'Signal cleanup complete' });
858
+ }
859
+ return error(result.stderr || result.error?.message || 'signal:cleanup failed', ErrorCodes.SIGNAL_CLEANUP_ERROR);
860
+ },
861
+ };
862
+ /**
863
+ * wu_proto - Create and claim a prototype WU
864
+ */
865
+ export const wuProtoTool = {
866
+ name: 'wu_proto',
867
+ description: 'Create and claim a prototype WU with relaxed validation',
868
+ inputSchema: wuProtoSchema,
869
+ async execute(input, options) {
870
+ if (!input.lane) {
871
+ return error(ErrorMessages.LANE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
872
+ }
873
+ if (!input.title) {
874
+ return error(ErrorMessages.TITLE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
875
+ }
876
+ const args = ['--lane', input.lane, '--title', input.title];
877
+ if (input.description)
878
+ args.push(CliArgs.DESCRIPTION, input.description);
879
+ if (Array.isArray(input.code_paths)) {
880
+ for (const codePath of input.code_paths) {
881
+ args.push(CliArgs.CODE_PATHS, String(codePath));
882
+ }
883
+ }
884
+ if (Array.isArray(input.labels) && input.labels.length > 0) {
885
+ args.push('--labels', input.labels.join(','));
886
+ }
887
+ if (input.assigned_to)
888
+ args.push('--assigned-to', input.assigned_to);
889
+ const cliOptions = { projectRoot: options?.projectRoot };
890
+ const result = await runCliCommand('wu:proto', args, cliOptions);
891
+ if (result.success) {
892
+ return success({ message: result.stdout || 'Prototype WU created' });
893
+ }
894
+ return error(result.stderr || result.error?.message || 'wu:proto failed', ErrorCodes.WU_PROTO_ERROR);
895
+ },
896
+ };
897
+ //# sourceMappingURL=parity-tools.js.map