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