@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.
- package/dist/tools/agent-tools.d.ts +26 -0
- package/dist/tools/agent-tools.d.ts.map +1 -0
- package/dist/tools/agent-tools.js +161 -0
- package/dist/tools/agent-tools.js.map +1 -0
- package/dist/tools/context-tools.d.ts +19 -0
- package/dist/tools/context-tools.d.ts.map +1 -0
- package/dist/tools/context-tools.js +73 -0
- package/dist/tools/context-tools.js.map +1 -0
- package/dist/tools/flow-tools.d.ts +30 -0
- package/dist/tools/flow-tools.d.ts.map +1 -0
- package/dist/tools/flow-tools.js +141 -0
- package/dist/tools/flow-tools.js.map +1 -0
- package/dist/tools/initiative-tools.d.ts +42 -0
- package/dist/tools/initiative-tools.d.ts.map +1 -0
- package/dist/tools/initiative-tools.js +304 -0
- package/dist/tools/initiative-tools.js.map +1 -0
- package/dist/tools/memory-tools.d.ts +66 -0
- package/dist/tools/memory-tools.d.ts.map +1 -0
- package/dist/tools/memory-tools.js +419 -0
- package/dist/tools/memory-tools.js.map +1 -0
- package/dist/tools/orchestration-tools.d.ts +26 -0
- package/dist/tools/orchestration-tools.d.ts.map +1 -0
- package/dist/tools/orchestration-tools.js +158 -0
- package/dist/tools/orchestration-tools.js.map +1 -0
- package/dist/tools/parity-tools.d.ts +118 -0
- package/dist/tools/parity-tools.d.ts.map +1 -0
- package/dist/tools/parity-tools.js +897 -0
- package/dist/tools/parity-tools.js.map +1 -0
- package/dist/tools/setup-tools.d.ts +42 -0
- package/dist/tools/setup-tools.d.ts.map +1 -0
- package/dist/tools/setup-tools.js +167 -0
- package/dist/tools/setup-tools.js.map +1 -0
- package/dist/tools/validation-tools.d.ts +34 -0
- package/dist/tools/validation-tools.d.ts.map +1 -0
- package/dist/tools/validation-tools.js +134 -0
- package/dist/tools/validation-tools.js.map +1 -0
- package/dist/tools/wu-tools.d.ts +116 -0
- package/dist/tools/wu-tools.d.ts.map +1 -0
- package/dist/tools/wu-tools.js +711 -0
- package/dist/tools/wu-tools.js.map +1 -0
- package/dist/tools-shared.d.ts +170 -0
- package/dist/tools-shared.d.ts.map +1 -0
- package/dist/tools-shared.js +203 -0
- package/dist/tools-shared.js.map +1 -0
- package/dist/tools.d.ts +34 -466
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +54 -3323
- package/dist/tools.js.map +1 -1
- 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
|