@lumenflow/mcp 3.2.0 → 3.2.2
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 +16 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js.map +1 -0
- package/dist/cli-runner.d.ts +58 -0
- package/dist/cli-runner.d.ts.map +1 -0
- package/dist/cli-runner.js +164 -0
- package/dist/cli-runner.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-constants.d.ts +177 -0
- package/dist/mcp-constants.d.ts.map +1 -0
- package/dist/mcp-constants.js +197 -0
- package/dist/mcp-constants.js.map +1 -0
- package/dist/resources.d.ts +53 -0
- package/dist/resources.d.ts.map +1 -0
- package/dist/resources.js +131 -0
- package/dist/resources.js.map +1 -0
- package/dist/runtime-cache.d.ts +7 -0
- package/dist/runtime-cache.d.ts.map +1 -0
- package/dist/runtime-cache.js +28 -0
- package/dist/runtime-cache.js.map +1 -0
- package/dist/runtime-tool-resolver.constants.d.ts +26 -0
- package/dist/runtime-tool-resolver.constants.d.ts.map +1 -0
- package/dist/runtime-tool-resolver.constants.js +36 -0
- package/dist/runtime-tool-resolver.constants.js.map +1 -0
- package/dist/runtime-tool-resolver.d.ts +5 -0
- package/dist/runtime-tool-resolver.d.ts.map +1 -0
- package/dist/runtime-tool-resolver.js +2030 -0
- package/dist/runtime-tool-resolver.js.map +1 -0
- package/dist/server.d.ts +58 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +212 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/agent-tools.d.ts +18 -0
- package/dist/tools/agent-tools.d.ts.map +1 -0
- package/dist/tools/agent-tools.js +235 -0
- package/dist/tools/agent-tools.js.map +1 -0
- package/dist/tools/context-tools.d.ts +13 -0
- package/dist/tools/context-tools.d.ts.map +1 -0
- package/dist/tools/context-tools.js +58 -0
- package/dist/tools/context-tools.js.map +1 -0
- package/dist/tools/flow-tools.d.ts +22 -0
- package/dist/tools/flow-tools.d.ts.map +1 -0
- package/dist/tools/flow-tools.js +130 -0
- package/dist/tools/flow-tools.js.map +1 -0
- package/dist/tools/initiative-tools.d.ts +34 -0
- package/dist/tools/initiative-tools.d.ts.map +1 -0
- package/dist/tools/initiative-tools.js +420 -0
- package/dist/tools/initiative-tools.js.map +1 -0
- package/dist/tools/memory-tools.d.ts +58 -0
- package/dist/tools/memory-tools.d.ts.map +1 -0
- package/dist/tools/memory-tools.js +523 -0
- package/dist/tools/memory-tools.js.map +1 -0
- package/dist/tools/orchestration-tools.d.ts +18 -0
- package/dist/tools/orchestration-tools.d.ts.map +1 -0
- package/dist/tools/orchestration-tools.js +202 -0
- package/dist/tools/orchestration-tools.js.map +1 -0
- package/dist/tools/parity-tools.d.ts +138 -0
- package/dist/tools/parity-tools.d.ts.map +1 -0
- package/dist/tools/parity-tools.js +1690 -0
- package/dist/tools/parity-tools.js.map +1 -0
- package/dist/tools/runtime-task-constants.d.ts +19 -0
- package/dist/tools/runtime-task-constants.d.ts.map +1 -0
- package/dist/tools/runtime-task-constants.js +21 -0
- package/dist/tools/runtime-task-constants.js.map +1 -0
- package/dist/tools/runtime-task-tools.d.ts +10 -0
- package/dist/tools/runtime-task-tools.d.ts.map +1 -0
- package/dist/tools/runtime-task-tools.js +116 -0
- package/dist/tools/runtime-task-tools.js.map +1 -0
- package/dist/tools/setup-tools.d.ts +34 -0
- package/dist/tools/setup-tools.d.ts.map +1 -0
- package/dist/tools/setup-tools.js +254 -0
- package/dist/tools/setup-tools.js.map +1 -0
- package/dist/tools/validation-tools.d.ts +26 -0
- package/dist/tools/validation-tools.d.ts.map +1 -0
- package/dist/tools/validation-tools.js +180 -0
- package/dist/tools/validation-tools.js.map +1 -0
- package/dist/tools/wu-tools.d.ts +101 -0
- package/dist/tools/wu-tools.d.ts.map +1 -0
- package/dist/tools/wu-tools.js +964 -0
- package/dist/tools/wu-tools.js.map +1 -0
- package/dist/tools-shared.d.ts +257 -0
- package/dist/tools-shared.d.ts.map +1 -0
- package/dist/tools-shared.js +410 -0
- package/dist/tools-shared.js.map +1 -0
- package/dist/tools.d.ts +99 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +253 -0
- package/dist/tools.js.map +1 -0
- package/dist/worktree-enforcement.d.ts +32 -0
- package/dist/worktree-enforcement.d.ts.map +1 -0
- package/dist/worktree-enforcement.js +154 -0
- package/dist/worktree-enforcement.js.map +1 -0
- package/package.json +5 -5
|
@@ -0,0 +1,964 @@
|
|
|
1
|
+
// Copyright (c) 2026 Hellmai Ltd
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* @file wu-tools.ts
|
|
5
|
+
* @description WU lifecycle tool implementations (create, claim, done, block, edit, etc.)
|
|
6
|
+
*
|
|
7
|
+
* WU-1642: Extracted from tools.ts during modular decomposition.
|
|
8
|
+
* WU-1412: Core WU tools: wu_status, wu_create, wu_claim, wu_done, gates_run
|
|
9
|
+
* WU-1422: Additional WU tools
|
|
10
|
+
* WU-1431: Uses shared Zod schemas from @lumenflow/core for CLI/MCP parity
|
|
11
|
+
* WU-1454: All 16 WU lifecycle commands now use shared schemas
|
|
12
|
+
*/
|
|
13
|
+
import { z } from 'zod';
|
|
14
|
+
import { wuCreateSchema, wuClaimSchema, wuStatusSchema, wuDoneSchema, gatesSchema,
|
|
15
|
+
// WU-1454: Lifecycle command schemas
|
|
16
|
+
wuBlockSchema, wuUnblockSchema, wuEditSchema, wuReleaseSchema, wuRecoverSchema, wuRepairSchema, wuDepsSchema, wuPrepSchema, wuPreflightSchema, wuPruneSchema, wuDeleteSchema, wuCleanupSchema, wuSpawnSchema, wuValidateSchema, wuInferLaneSchema, wuUnlockLaneSchema, } from '@lumenflow/core';
|
|
17
|
+
import { ErrorCodes, ErrorMessages, CliArgs, SuccessMessages, getCore, success, error, buildWuPromptArgs, executeViaPack, } from '../tools-shared.js';
|
|
18
|
+
import { CliCommands, MetadataKeys } from '../mcp-constants.js';
|
|
19
|
+
/**
|
|
20
|
+
* WU-1805: Fallback messages for WU query tools when executeViaPack
|
|
21
|
+
* returns no structured data.
|
|
22
|
+
*/
|
|
23
|
+
const WuQueryMessages = {
|
|
24
|
+
STATUS_FAILED: 'wu:status failed',
|
|
25
|
+
CREATE_PASSED: 'WU created successfully',
|
|
26
|
+
CREATE_FAILED: 'wu:create failed',
|
|
27
|
+
CLAIM_PASSED: 'WU claimed successfully',
|
|
28
|
+
CLAIM_FAILED: 'wu:claim failed',
|
|
29
|
+
DEPS_FAILED: 'wu:deps failed',
|
|
30
|
+
PREFLIGHT_PASSED: 'Preflight checks passed',
|
|
31
|
+
PREFLIGHT_FAILED: 'wu:preflight failed',
|
|
32
|
+
VALIDATE_PASSED: 'WU is valid',
|
|
33
|
+
VALIDATE_FAILED: 'wu:validate failed',
|
|
34
|
+
INFER_LANE_FAILED: 'wu:infer-lane failed',
|
|
35
|
+
};
|
|
36
|
+
const WuStateTransitionMessages = {
|
|
37
|
+
BLOCK_PASSED: 'WU blocked successfully',
|
|
38
|
+
BLOCK_FAILED: 'wu:block failed',
|
|
39
|
+
UNBLOCK_PASSED: 'WU unblocked successfully',
|
|
40
|
+
UNBLOCK_FAILED: 'wu:unblock failed',
|
|
41
|
+
EDIT_PASSED: 'WU edited successfully',
|
|
42
|
+
EDIT_FAILED: 'wu:edit failed',
|
|
43
|
+
RELEASE_PASSED: 'WU released successfully',
|
|
44
|
+
RELEASE_FAILED: 'wu:release failed',
|
|
45
|
+
};
|
|
46
|
+
const WuCompletionLifecycleMessages = {
|
|
47
|
+
SANDBOX_PASSED: 'WU sandbox command completed successfully',
|
|
48
|
+
SANDBOX_FAILED: 'wu:sandbox failed',
|
|
49
|
+
DONE_PASSED: 'WU completed successfully',
|
|
50
|
+
DONE_FAILED: 'wu:done failed',
|
|
51
|
+
PREP_PASSED: 'WU prep completed',
|
|
52
|
+
PREP_FAILED: 'wu:prep failed',
|
|
53
|
+
PRUNE_PASSED: 'Prune completed',
|
|
54
|
+
PRUNE_FAILED: 'wu:prune failed',
|
|
55
|
+
DELETE_PASSED: 'WU deleted',
|
|
56
|
+
DELETE_FAILED: 'wu:delete failed',
|
|
57
|
+
CLEANUP_PASSED: 'Cleanup complete',
|
|
58
|
+
CLEANUP_FAILED: 'wu:cleanup failed',
|
|
59
|
+
};
|
|
60
|
+
const WuDelegationAndGatesMessages = {
|
|
61
|
+
GATES_FAILED: 'Gates failed',
|
|
62
|
+
BRIEF_PASSED: 'Brief prompt generated',
|
|
63
|
+
BRIEF_FAILED: 'wu:brief failed',
|
|
64
|
+
DELEGATE_PASSED: 'Delegation prompt generated',
|
|
65
|
+
DELEGATE_FAILED: 'wu:delegate failed',
|
|
66
|
+
UNLOCK_PASSED: 'Lane unlocked',
|
|
67
|
+
UNLOCK_FAILED: 'wu:unlock-lane failed',
|
|
68
|
+
};
|
|
69
|
+
const GatesRuntimeConstants = {
|
|
70
|
+
FALLBACK_TIMEOUT_MS: 600000,
|
|
71
|
+
};
|
|
72
|
+
const WuQueryFlags = {
|
|
73
|
+
NO_STRICT: '--no-strict',
|
|
74
|
+
WORKTREE: '--worktree',
|
|
75
|
+
DEPTH: '--depth',
|
|
76
|
+
DIRECTION: '--direction',
|
|
77
|
+
PATHS: '--paths',
|
|
78
|
+
DESC: '--desc',
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* wu_status - Get status of a specific WU
|
|
82
|
+
*
|
|
83
|
+
* WU-1431: Uses shared wuStatusSchema for parity with CLI
|
|
84
|
+
* WU-1805: Migrated from CLI shell-out to executeViaPack (runtime-first)
|
|
85
|
+
* Note: CLI allows id to be optional (auto-detect from worktree), but MCP requires it
|
|
86
|
+
* since there's no "current directory" concept for MCP clients
|
|
87
|
+
*/
|
|
88
|
+
export const wuStatusTool = {
|
|
89
|
+
name: 'wu_status',
|
|
90
|
+
description: 'Get detailed status of a specific Work Unit',
|
|
91
|
+
// WU-1431: Extend shared schema to require id for MCP (CLI allows optional for auto-detect)
|
|
92
|
+
inputSchema: wuStatusSchema.extend({
|
|
93
|
+
id: z.string().describe('WU ID (e.g., WU-1412)'),
|
|
94
|
+
}),
|
|
95
|
+
async execute(input, options) {
|
|
96
|
+
if (!input.id) {
|
|
97
|
+
return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
|
|
98
|
+
}
|
|
99
|
+
const args = [CliArgs.ID, input.id, CliArgs.JSON];
|
|
100
|
+
const result = await executeViaPack(CliCommands.WU_STATUS, input, {
|
|
101
|
+
projectRoot: options?.projectRoot,
|
|
102
|
+
fallback: {
|
|
103
|
+
command: CliCommands.WU_STATUS,
|
|
104
|
+
args,
|
|
105
|
+
errorCode: ErrorCodes.WU_STATUS_ERROR,
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
return result.success
|
|
109
|
+
? success(result.data ?? { message: result.data })
|
|
110
|
+
: error(result.error?.message ?? WuQueryMessages.STATUS_FAILED, ErrorCodes.WU_STATUS_ERROR);
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
/**
|
|
114
|
+
* wu_create - Create a new WU
|
|
115
|
+
*
|
|
116
|
+
* WU-1431: Uses shared wuCreateSchema for CLI/MCP parity
|
|
117
|
+
*/
|
|
118
|
+
export const wuCreateTool = {
|
|
119
|
+
name: 'wu_create',
|
|
120
|
+
description: 'Create a new Work Unit specification',
|
|
121
|
+
// WU-1431: Use shared schema - CLI-only aliases are not exposed here
|
|
122
|
+
inputSchema: wuCreateSchema,
|
|
123
|
+
async execute(input, options) {
|
|
124
|
+
if (!input.lane) {
|
|
125
|
+
return error(ErrorMessages.LANE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
|
|
126
|
+
}
|
|
127
|
+
if (!input.title) {
|
|
128
|
+
return error(ErrorMessages.TITLE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
|
|
129
|
+
}
|
|
130
|
+
const args = [CliArgs.LANE, input.lane, '--title', input.title];
|
|
131
|
+
if (input.id)
|
|
132
|
+
args.push(CliArgs.ID, input.id);
|
|
133
|
+
if (input.description)
|
|
134
|
+
args.push(CliArgs.DESCRIPTION, input.description);
|
|
135
|
+
if (input.acceptance) {
|
|
136
|
+
for (const criterion of input.acceptance) {
|
|
137
|
+
args.push('--acceptance', criterion);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (input.code_paths) {
|
|
141
|
+
for (const p of input.code_paths) {
|
|
142
|
+
args.push(CliArgs.CODE_PATHS, p);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
if (input.exposure)
|
|
146
|
+
args.push('--exposure', input.exposure);
|
|
147
|
+
const result = await executeViaPack(CliCommands.WU_CREATE, input, {
|
|
148
|
+
projectRoot: options?.projectRoot,
|
|
149
|
+
contextInput: {
|
|
150
|
+
metadata: {
|
|
151
|
+
[MetadataKeys.PROJECT_ROOT]: options?.projectRoot,
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
fallback: {
|
|
155
|
+
command: CliCommands.WU_CREATE,
|
|
156
|
+
args,
|
|
157
|
+
errorCode: ErrorCodes.WU_CREATE_ERROR,
|
|
158
|
+
},
|
|
159
|
+
});
|
|
160
|
+
return result.success
|
|
161
|
+
? success(result.data ?? { message: WuQueryMessages.CREATE_PASSED })
|
|
162
|
+
: error(result.error?.message ?? WuQueryMessages.CREATE_FAILED, ErrorCodes.WU_CREATE_ERROR);
|
|
163
|
+
},
|
|
164
|
+
};
|
|
165
|
+
/**
|
|
166
|
+
* wu_claim - Claim a WU and create worktree
|
|
167
|
+
*
|
|
168
|
+
* WU-1431: Uses shared wuClaimSchema for CLI/MCP parity
|
|
169
|
+
* WU-1491: Supports --cloud, --branch-only, and --pr-mode passthrough
|
|
170
|
+
*/
|
|
171
|
+
const wuClaimToolSchema = wuClaimSchema.extend({
|
|
172
|
+
sandbox: z
|
|
173
|
+
.boolean()
|
|
174
|
+
.optional()
|
|
175
|
+
.describe('Launch post-claim session through wu:sandbox (requires sandbox_command in MCP)'),
|
|
176
|
+
sandbox_command: z
|
|
177
|
+
.array(z.string())
|
|
178
|
+
.optional()
|
|
179
|
+
.describe('Command argv to run with --sandbox (e.g., ["node", "-v"])'),
|
|
180
|
+
});
|
|
181
|
+
export const wuClaimTool = {
|
|
182
|
+
name: 'wu_claim',
|
|
183
|
+
description: 'Claim a Work Unit and create worktree for implementation',
|
|
184
|
+
// WU-1431: Extend shared schema with MCP-safe sandbox launch controls
|
|
185
|
+
inputSchema: wuClaimToolSchema,
|
|
186
|
+
async execute(input, options) {
|
|
187
|
+
if (!input.id) {
|
|
188
|
+
return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
|
|
189
|
+
}
|
|
190
|
+
if (!input.lane) {
|
|
191
|
+
return error(ErrorMessages.LANE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
|
|
192
|
+
}
|
|
193
|
+
const args = [CliArgs.ID, input.id, CliArgs.LANE, input.lane];
|
|
194
|
+
// WU-1491: Pass mode flags through to CLI
|
|
195
|
+
if (input.cloud)
|
|
196
|
+
args.push('--cloud');
|
|
197
|
+
if (input.branch_only)
|
|
198
|
+
args.push('--branch-only');
|
|
199
|
+
if (input.pr_mode)
|
|
200
|
+
args.push('--pr-mode');
|
|
201
|
+
if (input.sandbox) {
|
|
202
|
+
const sandboxCommand = Array.isArray(input.sandbox_command)
|
|
203
|
+
? input.sandbox_command
|
|
204
|
+
: [];
|
|
205
|
+
if (sandboxCommand.length === 0) {
|
|
206
|
+
return error('sandbox_command is required when sandbox=true for MCP execution', ErrorCodes.MISSING_PARAMETER);
|
|
207
|
+
}
|
|
208
|
+
args.push('--sandbox', '--', ...sandboxCommand);
|
|
209
|
+
}
|
|
210
|
+
const result = await executeViaPack(CliCommands.WU_CLAIM, input, {
|
|
211
|
+
projectRoot: options?.projectRoot,
|
|
212
|
+
contextInput: {
|
|
213
|
+
metadata: {
|
|
214
|
+
[MetadataKeys.PROJECT_ROOT]: options?.projectRoot,
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
fallback: {
|
|
218
|
+
command: CliCommands.WU_CLAIM,
|
|
219
|
+
args,
|
|
220
|
+
errorCode: ErrorCodes.WU_CLAIM_ERROR,
|
|
221
|
+
},
|
|
222
|
+
});
|
|
223
|
+
return result.success
|
|
224
|
+
? success(result.data ?? { message: WuQueryMessages.CLAIM_PASSED })
|
|
225
|
+
: error(result.error?.message ?? WuQueryMessages.CLAIM_FAILED, ErrorCodes.WU_CLAIM_ERROR);
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
/**
|
|
229
|
+
* wu_sandbox - Execute a command through the sandbox backend for this platform
|
|
230
|
+
*/
|
|
231
|
+
const wuSandboxSchema = z.object({
|
|
232
|
+
id: z.string().describe('WU ID (e.g., WU-1687)'),
|
|
233
|
+
worktree: z.string().optional().describe('Optional worktree path override'),
|
|
234
|
+
command: z
|
|
235
|
+
.array(z.string())
|
|
236
|
+
.min(1)
|
|
237
|
+
.describe('Command argv to execute (e.g., ["node", "-e", "process.exit(0)"])'),
|
|
238
|
+
});
|
|
239
|
+
export const wuSandboxTool = {
|
|
240
|
+
name: 'wu_sandbox',
|
|
241
|
+
description: 'Run a command through the hardened WU sandbox backend',
|
|
242
|
+
inputSchema: wuSandboxSchema,
|
|
243
|
+
async execute(input, options) {
|
|
244
|
+
if (!input.id) {
|
|
245
|
+
return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
|
|
246
|
+
}
|
|
247
|
+
const command = Array.isArray(input.command) ? input.command : [];
|
|
248
|
+
if (command.length === 0) {
|
|
249
|
+
return error('command is required', ErrorCodes.MISSING_PARAMETER);
|
|
250
|
+
}
|
|
251
|
+
const args = [CliArgs.ID, input.id];
|
|
252
|
+
if (input.worktree) {
|
|
253
|
+
args.push('--worktree', input.worktree);
|
|
254
|
+
}
|
|
255
|
+
args.push('--', ...command);
|
|
256
|
+
const result = await executeViaPack(CliCommands.WU_SANDBOX, input, {
|
|
257
|
+
projectRoot: options?.projectRoot,
|
|
258
|
+
contextInput: {
|
|
259
|
+
metadata: {
|
|
260
|
+
[MetadataKeys.PROJECT_ROOT]: options?.projectRoot,
|
|
261
|
+
},
|
|
262
|
+
},
|
|
263
|
+
fallback: {
|
|
264
|
+
command: CliCommands.WU_SANDBOX,
|
|
265
|
+
args,
|
|
266
|
+
errorCode: ErrorCodes.WU_CLAIM_ERROR,
|
|
267
|
+
},
|
|
268
|
+
});
|
|
269
|
+
return result.success
|
|
270
|
+
? success(result.data ?? { message: WuCompletionLifecycleMessages.SANDBOX_PASSED })
|
|
271
|
+
: error(result.error?.message ?? WuCompletionLifecycleMessages.SANDBOX_FAILED, ErrorCodes.WU_CLAIM_ERROR);
|
|
272
|
+
},
|
|
273
|
+
};
|
|
274
|
+
/**
|
|
275
|
+
* wu_done - Complete a WU (must be run from main checkout)
|
|
276
|
+
*
|
|
277
|
+
* WU-1431: Uses shared wuDoneSchema for CLI/MCP parity
|
|
278
|
+
*/
|
|
279
|
+
export const wuDoneTool = {
|
|
280
|
+
name: 'wu_done',
|
|
281
|
+
description: 'Complete a Work Unit (merge, stamp, cleanup). MUST be run from main checkout.',
|
|
282
|
+
// WU-1431: Use shared schema
|
|
283
|
+
inputSchema: wuDoneSchema,
|
|
284
|
+
async execute(input, options) {
|
|
285
|
+
if (!input.id) {
|
|
286
|
+
return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
|
|
287
|
+
}
|
|
288
|
+
// Fail fast if not on main checkout (AC: wu_done fails fast if not on main checkout)
|
|
289
|
+
try {
|
|
290
|
+
const core = await getCore();
|
|
291
|
+
const context = await core.computeWuContext({
|
|
292
|
+
cwd: options?.projectRoot,
|
|
293
|
+
});
|
|
294
|
+
if (context.location.type === 'worktree') {
|
|
295
|
+
return error('wu_done must be run from main checkout, not from a worktree. ' +
|
|
296
|
+
'Run "pnpm wu:prep" first from the worktree, then cd to main and run wu:done.', ErrorCodes.WRONG_LOCATION);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
catch {
|
|
300
|
+
// If we can't determine context, proceed anyway - CLI will validate
|
|
301
|
+
}
|
|
302
|
+
const args = [CliArgs.ID, input.id];
|
|
303
|
+
if (input.skip_gates) {
|
|
304
|
+
args.push('--skip-gates');
|
|
305
|
+
if (input.reason)
|
|
306
|
+
args.push(CliArgs.REASON, input.reason);
|
|
307
|
+
if (input.fix_wu)
|
|
308
|
+
args.push('--fix-wu', input.fix_wu);
|
|
309
|
+
}
|
|
310
|
+
const result = await executeViaPack(CliCommands.WU_DONE, input, {
|
|
311
|
+
projectRoot: options?.projectRoot,
|
|
312
|
+
contextInput: {
|
|
313
|
+
metadata: {
|
|
314
|
+
[MetadataKeys.PROJECT_ROOT]: options?.projectRoot,
|
|
315
|
+
},
|
|
316
|
+
},
|
|
317
|
+
fallback: {
|
|
318
|
+
command: CliCommands.WU_DONE,
|
|
319
|
+
args,
|
|
320
|
+
errorCode: ErrorCodes.WU_DONE_ERROR,
|
|
321
|
+
},
|
|
322
|
+
});
|
|
323
|
+
return result.success
|
|
324
|
+
? success(result.data ?? { message: WuCompletionLifecycleMessages.DONE_PASSED })
|
|
325
|
+
: error(result.error?.message ?? WuCompletionLifecycleMessages.DONE_FAILED, ErrorCodes.WU_DONE_ERROR);
|
|
326
|
+
},
|
|
327
|
+
};
|
|
328
|
+
/**
|
|
329
|
+
* gates_run - Run quality gates
|
|
330
|
+
*
|
|
331
|
+
* WU-1431: Uses shared gatesSchema for CLI/MCP parity
|
|
332
|
+
*/
|
|
333
|
+
export const gatesRunTool = {
|
|
334
|
+
name: 'gates_run',
|
|
335
|
+
description: 'Run LumenFlow quality gates (lint, typecheck, tests)',
|
|
336
|
+
// WU-1431: Use shared schema
|
|
337
|
+
inputSchema: gatesSchema,
|
|
338
|
+
async execute(input, options) {
|
|
339
|
+
const args = [];
|
|
340
|
+
if (input.docs_only) {
|
|
341
|
+
args.push(CliArgs.DOCS_ONLY);
|
|
342
|
+
}
|
|
343
|
+
const result = await executeViaPack(CliCommands.GATES, input, {
|
|
344
|
+
projectRoot: options?.projectRoot,
|
|
345
|
+
contextInput: {
|
|
346
|
+
metadata: {
|
|
347
|
+
[MetadataKeys.PROJECT_ROOT]: options?.projectRoot,
|
|
348
|
+
},
|
|
349
|
+
},
|
|
350
|
+
fallback: {
|
|
351
|
+
command: CliCommands.GATES,
|
|
352
|
+
args,
|
|
353
|
+
errorCode: ErrorCodes.GATES_ERROR,
|
|
354
|
+
},
|
|
355
|
+
fallbackCliOptions: {
|
|
356
|
+
timeout: GatesRuntimeConstants.FALLBACK_TIMEOUT_MS,
|
|
357
|
+
},
|
|
358
|
+
});
|
|
359
|
+
return result.success
|
|
360
|
+
? success(result.data ?? { message: SuccessMessages.ALL_GATES_PASSED })
|
|
361
|
+
: error(result.error?.message ?? WuDelegationAndGatesMessages.GATES_FAILED, ErrorCodes.GATES_ERROR);
|
|
362
|
+
},
|
|
363
|
+
};
|
|
364
|
+
/**
|
|
365
|
+
* wu_block - Block a WU and move it to blocked status
|
|
366
|
+
*/
|
|
367
|
+
export const wuBlockTool = {
|
|
368
|
+
name: 'wu_block',
|
|
369
|
+
description: 'Block a Work Unit and move it from in_progress to blocked status',
|
|
370
|
+
// WU-1454: Use shared schema
|
|
371
|
+
inputSchema: wuBlockSchema,
|
|
372
|
+
async execute(input, options) {
|
|
373
|
+
if (!input.id) {
|
|
374
|
+
return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
|
|
375
|
+
}
|
|
376
|
+
if (!input.reason) {
|
|
377
|
+
return error(ErrorMessages.REASON_REQUIRED, ErrorCodes.MISSING_PARAMETER);
|
|
378
|
+
}
|
|
379
|
+
const args = [CliArgs.ID, input.id, CliArgs.REASON, input.reason];
|
|
380
|
+
if (input.remove_worktree) {
|
|
381
|
+
args.push('--remove-worktree');
|
|
382
|
+
}
|
|
383
|
+
const result = await executeViaPack(CliCommands.WU_BLOCK, input, {
|
|
384
|
+
projectRoot: options?.projectRoot,
|
|
385
|
+
contextInput: {
|
|
386
|
+
metadata: {
|
|
387
|
+
[MetadataKeys.PROJECT_ROOT]: options?.projectRoot,
|
|
388
|
+
},
|
|
389
|
+
},
|
|
390
|
+
fallback: {
|
|
391
|
+
command: CliCommands.WU_BLOCK,
|
|
392
|
+
args,
|
|
393
|
+
errorCode: ErrorCodes.WU_BLOCK_ERROR,
|
|
394
|
+
},
|
|
395
|
+
});
|
|
396
|
+
return result.success
|
|
397
|
+
? success(result.data ?? { message: WuStateTransitionMessages.BLOCK_PASSED })
|
|
398
|
+
: error(result.error?.message ?? WuStateTransitionMessages.BLOCK_FAILED, ErrorCodes.WU_BLOCK_ERROR);
|
|
399
|
+
},
|
|
400
|
+
};
|
|
401
|
+
/**
|
|
402
|
+
* wu_unblock - Unblock a WU and move it back to in_progress status
|
|
403
|
+
*/
|
|
404
|
+
export const wuUnblockTool = {
|
|
405
|
+
name: 'wu_unblock',
|
|
406
|
+
description: 'Unblock a Work Unit and move it from blocked to in_progress status',
|
|
407
|
+
// WU-1454: Use shared schema
|
|
408
|
+
inputSchema: wuUnblockSchema,
|
|
409
|
+
async execute(input, options) {
|
|
410
|
+
if (!input.id) {
|
|
411
|
+
return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
|
|
412
|
+
}
|
|
413
|
+
const args = [CliArgs.ID, input.id];
|
|
414
|
+
if (input.reason)
|
|
415
|
+
args.push(CliArgs.REASON, input.reason);
|
|
416
|
+
if (input.create_worktree)
|
|
417
|
+
args.push('--create-worktree');
|
|
418
|
+
const result = await executeViaPack(CliCommands.WU_UNBLOCK, input, {
|
|
419
|
+
projectRoot: options?.projectRoot,
|
|
420
|
+
contextInput: {
|
|
421
|
+
metadata: {
|
|
422
|
+
[MetadataKeys.PROJECT_ROOT]: options?.projectRoot,
|
|
423
|
+
},
|
|
424
|
+
},
|
|
425
|
+
fallback: {
|
|
426
|
+
command: CliCommands.WU_UNBLOCK,
|
|
427
|
+
args,
|
|
428
|
+
errorCode: ErrorCodes.WU_UNBLOCK_ERROR,
|
|
429
|
+
},
|
|
430
|
+
});
|
|
431
|
+
return result.success
|
|
432
|
+
? success(result.data ?? { message: WuStateTransitionMessages.UNBLOCK_PASSED })
|
|
433
|
+
: error(result.error?.message ?? WuStateTransitionMessages.UNBLOCK_FAILED, ErrorCodes.WU_UNBLOCK_ERROR);
|
|
434
|
+
},
|
|
435
|
+
};
|
|
436
|
+
/**
|
|
437
|
+
* wu_edit - Edit WU spec fields
|
|
438
|
+
*/
|
|
439
|
+
export const wuEditTool = {
|
|
440
|
+
name: 'wu_edit',
|
|
441
|
+
description: 'Edit Work Unit spec fields with micro-worktree isolation',
|
|
442
|
+
// WU-1454: Use shared schema
|
|
443
|
+
inputSchema: wuEditSchema,
|
|
444
|
+
async execute(input, options) {
|
|
445
|
+
if (!input.id) {
|
|
446
|
+
return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
|
|
447
|
+
}
|
|
448
|
+
const args = [CliArgs.ID, input.id];
|
|
449
|
+
if (input.description)
|
|
450
|
+
args.push(CliArgs.DESCRIPTION, input.description);
|
|
451
|
+
if (input.acceptance) {
|
|
452
|
+
for (const criterion of input.acceptance) {
|
|
453
|
+
args.push('--acceptance', criterion);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
if (input.notes)
|
|
457
|
+
args.push('--notes', input.notes);
|
|
458
|
+
if (input.code_paths) {
|
|
459
|
+
for (const p of input.code_paths) {
|
|
460
|
+
args.push(CliArgs.CODE_PATHS, p);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
if (input.lane)
|
|
464
|
+
args.push(CliArgs.LANE, input.lane);
|
|
465
|
+
if (input.priority)
|
|
466
|
+
args.push('--priority', input.priority);
|
|
467
|
+
if (input.initiative)
|
|
468
|
+
args.push(CliArgs.INITIATIVE, input.initiative);
|
|
469
|
+
if (input.phase)
|
|
470
|
+
args.push(CliArgs.PHASE, String(input.phase));
|
|
471
|
+
if (input.no_strict)
|
|
472
|
+
args.push('--no-strict');
|
|
473
|
+
const result = await executeViaPack(CliCommands.WU_EDIT, input, {
|
|
474
|
+
projectRoot: options?.projectRoot,
|
|
475
|
+
contextInput: {
|
|
476
|
+
metadata: {
|
|
477
|
+
[MetadataKeys.PROJECT_ROOT]: options?.projectRoot,
|
|
478
|
+
},
|
|
479
|
+
},
|
|
480
|
+
fallback: {
|
|
481
|
+
command: CliCommands.WU_EDIT,
|
|
482
|
+
args,
|
|
483
|
+
errorCode: ErrorCodes.WU_EDIT_ERROR,
|
|
484
|
+
},
|
|
485
|
+
});
|
|
486
|
+
return result.success
|
|
487
|
+
? success(result.data ?? { message: WuStateTransitionMessages.EDIT_PASSED })
|
|
488
|
+
: error(result.error?.message ?? WuStateTransitionMessages.EDIT_FAILED, ErrorCodes.WU_EDIT_ERROR);
|
|
489
|
+
},
|
|
490
|
+
};
|
|
491
|
+
/**
|
|
492
|
+
* wu_release - Release an orphaned WU from in_progress to ready status
|
|
493
|
+
*/
|
|
494
|
+
export const wuReleaseTool = {
|
|
495
|
+
name: 'wu_release',
|
|
496
|
+
description: 'Release an orphaned WU from in_progress back to ready state for reclaiming',
|
|
497
|
+
// WU-1454: Use shared schema
|
|
498
|
+
inputSchema: wuReleaseSchema,
|
|
499
|
+
async execute(input, options) {
|
|
500
|
+
if (!input.id) {
|
|
501
|
+
return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
|
|
502
|
+
}
|
|
503
|
+
const args = [CliArgs.ID, input.id];
|
|
504
|
+
if (input.reason)
|
|
505
|
+
args.push(CliArgs.REASON, input.reason);
|
|
506
|
+
const result = await executeViaPack(CliCommands.WU_RELEASE, input, {
|
|
507
|
+
projectRoot: options?.projectRoot,
|
|
508
|
+
contextInput: {
|
|
509
|
+
metadata: {
|
|
510
|
+
[MetadataKeys.PROJECT_ROOT]: options?.projectRoot,
|
|
511
|
+
},
|
|
512
|
+
},
|
|
513
|
+
fallback: {
|
|
514
|
+
command: CliCommands.WU_RELEASE,
|
|
515
|
+
args,
|
|
516
|
+
errorCode: ErrorCodes.WU_RELEASE_ERROR,
|
|
517
|
+
},
|
|
518
|
+
});
|
|
519
|
+
return result.success
|
|
520
|
+
? success(result.data ?? { message: WuStateTransitionMessages.RELEASE_PASSED })
|
|
521
|
+
: error(result.error?.message ?? WuStateTransitionMessages.RELEASE_FAILED, ErrorCodes.WU_RELEASE_ERROR);
|
|
522
|
+
},
|
|
523
|
+
};
|
|
524
|
+
/**
|
|
525
|
+
* wu_recover - Analyze and fix WU state inconsistencies
|
|
526
|
+
*/
|
|
527
|
+
export const wuRecoverTool = {
|
|
528
|
+
name: 'wu_recover',
|
|
529
|
+
description: 'Analyze and fix WU state inconsistencies',
|
|
530
|
+
// WU-1454: Use shared schema
|
|
531
|
+
inputSchema: wuRecoverSchema,
|
|
532
|
+
async execute(input, options) {
|
|
533
|
+
if (!input.id) {
|
|
534
|
+
return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
|
|
535
|
+
}
|
|
536
|
+
const args = [CliArgs.ID, input.id];
|
|
537
|
+
if (input.action)
|
|
538
|
+
args.push('--action', input.action);
|
|
539
|
+
if (input.force)
|
|
540
|
+
args.push(CliArgs.FORCE);
|
|
541
|
+
if (input.json)
|
|
542
|
+
args.push(CliArgs.JSON);
|
|
543
|
+
const result = await executeViaPack(CliCommands.WU_RECOVER, input, {
|
|
544
|
+
projectRoot: options?.projectRoot,
|
|
545
|
+
contextInput: {
|
|
546
|
+
metadata: {
|
|
547
|
+
[MetadataKeys.PROJECT_ROOT]: options?.projectRoot,
|
|
548
|
+
},
|
|
549
|
+
},
|
|
550
|
+
fallback: {
|
|
551
|
+
command: CliCommands.WU_RECOVER,
|
|
552
|
+
args,
|
|
553
|
+
errorCode: ErrorCodes.WU_RECOVER_ERROR,
|
|
554
|
+
},
|
|
555
|
+
});
|
|
556
|
+
return result.success
|
|
557
|
+
? success(result.data ?? { message: 'WU recovered successfully' })
|
|
558
|
+
: error(result.error?.message ?? 'wu:recover failed', ErrorCodes.WU_RECOVER_ERROR);
|
|
559
|
+
},
|
|
560
|
+
};
|
|
561
|
+
/**
|
|
562
|
+
* wu_repair - Unified WU repair tool for state issues
|
|
563
|
+
*/
|
|
564
|
+
export const wuRepairTool = {
|
|
565
|
+
name: 'wu_repair',
|
|
566
|
+
description: 'Unified WU repair tool - detect and fix WU state issues',
|
|
567
|
+
// WU-1454: Use shared schema
|
|
568
|
+
inputSchema: wuRepairSchema,
|
|
569
|
+
async execute(input, options) {
|
|
570
|
+
const args = [];
|
|
571
|
+
if (input.id)
|
|
572
|
+
args.push(CliArgs.ID, input.id);
|
|
573
|
+
if (input.check)
|
|
574
|
+
args.push('--check');
|
|
575
|
+
if (input.all)
|
|
576
|
+
args.push('--all');
|
|
577
|
+
if (input.claim)
|
|
578
|
+
args.push('--claim');
|
|
579
|
+
if (input.admin)
|
|
580
|
+
args.push('--admin');
|
|
581
|
+
if (input.repair_state)
|
|
582
|
+
args.push('--repair-state');
|
|
583
|
+
const result = await executeViaPack(CliCommands.WU_REPAIR, input, {
|
|
584
|
+
projectRoot: options?.projectRoot,
|
|
585
|
+
contextInput: {
|
|
586
|
+
metadata: {
|
|
587
|
+
[MetadataKeys.PROJECT_ROOT]: options?.projectRoot,
|
|
588
|
+
},
|
|
589
|
+
},
|
|
590
|
+
fallback: {
|
|
591
|
+
command: CliCommands.WU_REPAIR,
|
|
592
|
+
args,
|
|
593
|
+
errorCode: ErrorCodes.WU_REPAIR_ERROR,
|
|
594
|
+
},
|
|
595
|
+
});
|
|
596
|
+
return result.success
|
|
597
|
+
? success(result.data ?? { message: 'WU repair completed' })
|
|
598
|
+
: error(result.error?.message ?? 'wu:repair failed', ErrorCodes.WU_REPAIR_ERROR);
|
|
599
|
+
},
|
|
600
|
+
};
|
|
601
|
+
/**
|
|
602
|
+
* wu_deps - Visualize WU dependency graph
|
|
603
|
+
*/
|
|
604
|
+
export const wuDepsTool = {
|
|
605
|
+
name: 'wu_deps',
|
|
606
|
+
description: 'Visualize WU dependency graph',
|
|
607
|
+
// WU-1454: Use shared schema
|
|
608
|
+
inputSchema: wuDepsSchema,
|
|
609
|
+
async execute(input, options) {
|
|
610
|
+
if (!input.id) {
|
|
611
|
+
return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
|
|
612
|
+
}
|
|
613
|
+
const args = [CliArgs.ID, input.id];
|
|
614
|
+
if (input.format)
|
|
615
|
+
args.push(CliArgs.FORMAT, input.format);
|
|
616
|
+
if (input.depth)
|
|
617
|
+
args.push(WuQueryFlags.DEPTH, String(input.depth));
|
|
618
|
+
if (input.direction)
|
|
619
|
+
args.push(WuQueryFlags.DIRECTION, input.direction);
|
|
620
|
+
const result = await executeViaPack(CliCommands.WU_DEPS, input, {
|
|
621
|
+
projectRoot: options?.projectRoot,
|
|
622
|
+
fallback: {
|
|
623
|
+
command: CliCommands.WU_DEPS,
|
|
624
|
+
args,
|
|
625
|
+
errorCode: ErrorCodes.WU_DEPS_ERROR,
|
|
626
|
+
},
|
|
627
|
+
});
|
|
628
|
+
return result.success
|
|
629
|
+
? success(result.data ?? { message: result.data })
|
|
630
|
+
: error(result.error?.message ?? WuQueryMessages.DEPS_FAILED, ErrorCodes.WU_DEPS_ERROR);
|
|
631
|
+
},
|
|
632
|
+
};
|
|
633
|
+
/**
|
|
634
|
+
* wu_prep - Prepare WU for completion (run gates in worktree)
|
|
635
|
+
*/
|
|
636
|
+
export const wuPrepTool = {
|
|
637
|
+
name: 'wu_prep',
|
|
638
|
+
description: 'Prepare WU for completion by running gates in worktree',
|
|
639
|
+
// WU-1454: Use shared schema
|
|
640
|
+
inputSchema: wuPrepSchema,
|
|
641
|
+
async execute(input, options) {
|
|
642
|
+
if (!input.id) {
|
|
643
|
+
return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
|
|
644
|
+
}
|
|
645
|
+
const args = [CliArgs.ID, input.id];
|
|
646
|
+
if (input.docs_only)
|
|
647
|
+
args.push(CliArgs.DOCS_ONLY);
|
|
648
|
+
if (input.full_tests)
|
|
649
|
+
args.push('--full-tests');
|
|
650
|
+
const result = await executeViaPack(CliCommands.WU_PREP, input, {
|
|
651
|
+
projectRoot: options?.projectRoot,
|
|
652
|
+
contextInput: {
|
|
653
|
+
metadata: {
|
|
654
|
+
[MetadataKeys.PROJECT_ROOT]: options?.projectRoot,
|
|
655
|
+
},
|
|
656
|
+
},
|
|
657
|
+
fallback: {
|
|
658
|
+
command: CliCommands.WU_PREP,
|
|
659
|
+
args,
|
|
660
|
+
errorCode: ErrorCodes.WU_PREP_ERROR,
|
|
661
|
+
},
|
|
662
|
+
});
|
|
663
|
+
return result.success
|
|
664
|
+
? success(result.data ?? { message: WuCompletionLifecycleMessages.PREP_PASSED })
|
|
665
|
+
: error(result.error?.message ?? WuCompletionLifecycleMessages.PREP_FAILED, ErrorCodes.WU_PREP_ERROR);
|
|
666
|
+
},
|
|
667
|
+
};
|
|
668
|
+
/**
|
|
669
|
+
* wu_preflight - Fast validation before gates run
|
|
670
|
+
*/
|
|
671
|
+
export const wuPreflightTool = {
|
|
672
|
+
name: 'wu_preflight',
|
|
673
|
+
description: 'Fast validation of code_paths and test paths before gates run (under 5 seconds vs 2+ minutes)',
|
|
674
|
+
// WU-1454: Use shared schema
|
|
675
|
+
inputSchema: wuPreflightSchema,
|
|
676
|
+
async execute(input, options) {
|
|
677
|
+
if (!input.id) {
|
|
678
|
+
return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
|
|
679
|
+
}
|
|
680
|
+
const args = [CliArgs.ID, input.id];
|
|
681
|
+
if (input.worktree)
|
|
682
|
+
args.push(WuQueryFlags.WORKTREE, input.worktree);
|
|
683
|
+
const result = await executeViaPack(CliCommands.WU_PREFLIGHT, input, {
|
|
684
|
+
projectRoot: options?.projectRoot,
|
|
685
|
+
fallback: {
|
|
686
|
+
command: CliCommands.WU_PREFLIGHT,
|
|
687
|
+
args,
|
|
688
|
+
errorCode: ErrorCodes.WU_PREFLIGHT_ERROR,
|
|
689
|
+
},
|
|
690
|
+
});
|
|
691
|
+
return result.success
|
|
692
|
+
? success(result.data ?? { message: WuQueryMessages.PREFLIGHT_PASSED })
|
|
693
|
+
: error(result.error?.message ?? WuQueryMessages.PREFLIGHT_FAILED, ErrorCodes.WU_PREFLIGHT_ERROR);
|
|
694
|
+
},
|
|
695
|
+
};
|
|
696
|
+
/**
|
|
697
|
+
* wu_prune - Clean stale worktrees
|
|
698
|
+
*/
|
|
699
|
+
export const wuPruneTool = {
|
|
700
|
+
name: 'wu_prune',
|
|
701
|
+
description: 'Clean stale worktrees (dry-run by default)',
|
|
702
|
+
// WU-1454: Use shared schema
|
|
703
|
+
inputSchema: wuPruneSchema,
|
|
704
|
+
async execute(input, options) {
|
|
705
|
+
const args = [];
|
|
706
|
+
if (input.execute)
|
|
707
|
+
args.push(CliArgs.EXECUTE);
|
|
708
|
+
const result = await executeViaPack(CliCommands.WU_PRUNE, input, {
|
|
709
|
+
projectRoot: options?.projectRoot,
|
|
710
|
+
contextInput: {
|
|
711
|
+
metadata: {
|
|
712
|
+
[MetadataKeys.PROJECT_ROOT]: options?.projectRoot,
|
|
713
|
+
},
|
|
714
|
+
},
|
|
715
|
+
fallback: {
|
|
716
|
+
command: CliCommands.WU_PRUNE,
|
|
717
|
+
args,
|
|
718
|
+
errorCode: ErrorCodes.WU_PRUNE_ERROR,
|
|
719
|
+
},
|
|
720
|
+
});
|
|
721
|
+
return result.success
|
|
722
|
+
? success(result.data ?? { message: WuCompletionLifecycleMessages.PRUNE_PASSED })
|
|
723
|
+
: error(result.error?.message ?? WuCompletionLifecycleMessages.PRUNE_FAILED, ErrorCodes.WU_PRUNE_ERROR);
|
|
724
|
+
},
|
|
725
|
+
};
|
|
726
|
+
/**
|
|
727
|
+
* wu_delete - Safely delete WU YAML files
|
|
728
|
+
*/
|
|
729
|
+
export const wuDeleteTool = {
|
|
730
|
+
name: 'wu_delete',
|
|
731
|
+
description: 'Safely delete WU YAML files with micro-worktree isolation',
|
|
732
|
+
// WU-1454: Use shared schema
|
|
733
|
+
inputSchema: wuDeleteSchema,
|
|
734
|
+
async execute(input, options) {
|
|
735
|
+
if (!input.id && !input.batch) {
|
|
736
|
+
return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
|
|
737
|
+
}
|
|
738
|
+
const args = [];
|
|
739
|
+
if (input.id)
|
|
740
|
+
args.push(CliArgs.ID, input.id);
|
|
741
|
+
if (input.dry_run)
|
|
742
|
+
args.push(CliArgs.DRY_RUN);
|
|
743
|
+
if (input.batch)
|
|
744
|
+
args.push('--batch', input.batch);
|
|
745
|
+
const result = await executeViaPack(CliCommands.WU_DELETE, input, {
|
|
746
|
+
projectRoot: options?.projectRoot,
|
|
747
|
+
contextInput: {
|
|
748
|
+
metadata: {
|
|
749
|
+
[MetadataKeys.PROJECT_ROOT]: options?.projectRoot,
|
|
750
|
+
},
|
|
751
|
+
},
|
|
752
|
+
fallback: {
|
|
753
|
+
command: CliCommands.WU_DELETE,
|
|
754
|
+
args,
|
|
755
|
+
errorCode: ErrorCodes.WU_DELETE_ERROR,
|
|
756
|
+
},
|
|
757
|
+
});
|
|
758
|
+
return result.success
|
|
759
|
+
? success(result.data ?? { message: WuCompletionLifecycleMessages.DELETE_PASSED })
|
|
760
|
+
: error(result.error?.message ?? WuCompletionLifecycleMessages.DELETE_FAILED, ErrorCodes.WU_DELETE_ERROR);
|
|
761
|
+
},
|
|
762
|
+
};
|
|
763
|
+
/**
|
|
764
|
+
* wu_cleanup - Clean up worktree and branch after PR merge
|
|
765
|
+
*/
|
|
766
|
+
export const wuCleanupTool = {
|
|
767
|
+
name: 'wu_cleanup',
|
|
768
|
+
description: 'Clean up worktree and branch after PR merge (PR-based completion workflow)',
|
|
769
|
+
// WU-1454: Use shared schema
|
|
770
|
+
inputSchema: wuCleanupSchema,
|
|
771
|
+
async execute(input, options) {
|
|
772
|
+
if (!input.id) {
|
|
773
|
+
return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
|
|
774
|
+
}
|
|
775
|
+
const args = [CliArgs.ID, input.id];
|
|
776
|
+
if (input.artifacts)
|
|
777
|
+
args.push('--artifacts');
|
|
778
|
+
const result = await executeViaPack(CliCommands.WU_CLEANUP, input, {
|
|
779
|
+
projectRoot: options?.projectRoot,
|
|
780
|
+
contextInput: {
|
|
781
|
+
metadata: {
|
|
782
|
+
[MetadataKeys.PROJECT_ROOT]: options?.projectRoot,
|
|
783
|
+
},
|
|
784
|
+
},
|
|
785
|
+
fallback: {
|
|
786
|
+
command: CliCommands.WU_CLEANUP,
|
|
787
|
+
args,
|
|
788
|
+
errorCode: ErrorCodes.WU_CLEANUP_ERROR,
|
|
789
|
+
},
|
|
790
|
+
});
|
|
791
|
+
return result.success
|
|
792
|
+
? success(result.data ?? { message: WuCompletionLifecycleMessages.CLEANUP_PASSED })
|
|
793
|
+
: error(result.error?.message ?? WuCompletionLifecycleMessages.CLEANUP_FAILED, ErrorCodes.WU_CLEANUP_ERROR);
|
|
794
|
+
},
|
|
795
|
+
};
|
|
796
|
+
/**
|
|
797
|
+
* wu_brief - Generate handoff prompt for sub-agent WU execution (WU-1603)
|
|
798
|
+
*
|
|
799
|
+
* This is the canonical prompt-generation tool.
|
|
800
|
+
*/
|
|
801
|
+
export const wuBriefTool = {
|
|
802
|
+
name: 'wu_brief',
|
|
803
|
+
description: 'Generate handoff prompt for sub-agent WU execution',
|
|
804
|
+
// WU-1454: Use shared schema (same parameters as wu:delegate)
|
|
805
|
+
inputSchema: wuSpawnSchema,
|
|
806
|
+
async execute(input, options) {
|
|
807
|
+
if (!input.id) {
|
|
808
|
+
return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
|
|
809
|
+
}
|
|
810
|
+
const args = buildWuPromptArgs(input);
|
|
811
|
+
const result = await executeViaPack(CliCommands.WU_BRIEF, input, {
|
|
812
|
+
projectRoot: options?.projectRoot,
|
|
813
|
+
contextInput: {
|
|
814
|
+
metadata: {
|
|
815
|
+
[MetadataKeys.PROJECT_ROOT]: options?.projectRoot,
|
|
816
|
+
},
|
|
817
|
+
},
|
|
818
|
+
fallback: {
|
|
819
|
+
command: CliCommands.WU_BRIEF,
|
|
820
|
+
args,
|
|
821
|
+
errorCode: ErrorCodes.WU_BRIEF_ERROR,
|
|
822
|
+
},
|
|
823
|
+
});
|
|
824
|
+
return result.success
|
|
825
|
+
? success(result.data ?? { message: WuDelegationAndGatesMessages.BRIEF_PASSED })
|
|
826
|
+
: error(result.error?.message ?? WuDelegationAndGatesMessages.BRIEF_FAILED, ErrorCodes.WU_BRIEF_ERROR);
|
|
827
|
+
},
|
|
828
|
+
};
|
|
829
|
+
/**
|
|
830
|
+
* wu_delegate - Generate prompt and explicitly record delegation lineage intent
|
|
831
|
+
*/
|
|
832
|
+
export const wuDelegateTool = {
|
|
833
|
+
name: 'wu_delegate',
|
|
834
|
+
description: 'Generate delegation prompt and record explicit lineage intent',
|
|
835
|
+
inputSchema: wuSpawnSchema,
|
|
836
|
+
async execute(input, options) {
|
|
837
|
+
if (!input.id) {
|
|
838
|
+
return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
|
|
839
|
+
}
|
|
840
|
+
if (!input.parent_wu) {
|
|
841
|
+
return error(ErrorMessages.PARENT_WU_REQUIRED, ErrorCodes.MISSING_PARAMETER);
|
|
842
|
+
}
|
|
843
|
+
const args = buildWuPromptArgs(input);
|
|
844
|
+
const result = await executeViaPack(CliCommands.WU_DELEGATE, input, {
|
|
845
|
+
projectRoot: options?.projectRoot,
|
|
846
|
+
contextInput: {
|
|
847
|
+
metadata: {
|
|
848
|
+
[MetadataKeys.PROJECT_ROOT]: options?.projectRoot,
|
|
849
|
+
},
|
|
850
|
+
},
|
|
851
|
+
fallback: {
|
|
852
|
+
command: CliCommands.WU_DELEGATE,
|
|
853
|
+
args,
|
|
854
|
+
errorCode: ErrorCodes.WU_DELEGATE_ERROR,
|
|
855
|
+
},
|
|
856
|
+
});
|
|
857
|
+
return result.success
|
|
858
|
+
? success(result.data ?? { message: WuDelegationAndGatesMessages.DELEGATE_PASSED })
|
|
859
|
+
: error(result.error?.message ?? WuDelegationAndGatesMessages.DELEGATE_FAILED, ErrorCodes.WU_DELEGATE_ERROR);
|
|
860
|
+
},
|
|
861
|
+
};
|
|
862
|
+
/**
|
|
863
|
+
* wu_validate - Validate WU YAML files
|
|
864
|
+
*/
|
|
865
|
+
export const wuValidateTool = {
|
|
866
|
+
name: 'wu_validate',
|
|
867
|
+
description: 'Validate WU YAML files against schema (strict mode by default)',
|
|
868
|
+
// WU-1454: Use shared schema
|
|
869
|
+
inputSchema: wuValidateSchema,
|
|
870
|
+
async execute(input, options) {
|
|
871
|
+
if (!input.id) {
|
|
872
|
+
return error(ErrorMessages.ID_REQUIRED, ErrorCodes.MISSING_PARAMETER);
|
|
873
|
+
}
|
|
874
|
+
const args = [CliArgs.ID, input.id];
|
|
875
|
+
if (input.no_strict)
|
|
876
|
+
args.push(WuQueryFlags.NO_STRICT);
|
|
877
|
+
const result = await executeViaPack(CliCommands.WU_VALIDATE, input, {
|
|
878
|
+
projectRoot: options?.projectRoot,
|
|
879
|
+
fallback: {
|
|
880
|
+
command: CliCommands.WU_VALIDATE,
|
|
881
|
+
args,
|
|
882
|
+
errorCode: ErrorCodes.WU_VALIDATE_ERROR,
|
|
883
|
+
},
|
|
884
|
+
});
|
|
885
|
+
return result.success
|
|
886
|
+
? success(result.data ?? { message: WuQueryMessages.VALIDATE_PASSED })
|
|
887
|
+
: error(result.error?.message ?? WuQueryMessages.VALIDATE_FAILED, ErrorCodes.WU_VALIDATE_ERROR);
|
|
888
|
+
},
|
|
889
|
+
};
|
|
890
|
+
/**
|
|
891
|
+
* wu_infer_lane - Suggest lane for a WU based on code paths and description
|
|
892
|
+
*/
|
|
893
|
+
export const wuInferLaneTool = {
|
|
894
|
+
name: 'wu_infer_lane',
|
|
895
|
+
description: 'Suggest lane for a WU based on code paths and description',
|
|
896
|
+
// WU-1454: Use shared schema
|
|
897
|
+
inputSchema: wuInferLaneSchema,
|
|
898
|
+
async execute(input, options) {
|
|
899
|
+
const args = [];
|
|
900
|
+
if (input.id)
|
|
901
|
+
args.push(CliArgs.ID, input.id);
|
|
902
|
+
if (input.paths) {
|
|
903
|
+
for (const p of input.paths) {
|
|
904
|
+
args.push(WuQueryFlags.PATHS, p);
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
if (input.desc)
|
|
908
|
+
args.push(WuQueryFlags.DESC, input.desc);
|
|
909
|
+
const result = await executeViaPack(CliCommands.WU_INFER_LANE, input, {
|
|
910
|
+
projectRoot: options?.projectRoot,
|
|
911
|
+
fallback: {
|
|
912
|
+
command: CliCommands.WU_INFER_LANE,
|
|
913
|
+
args,
|
|
914
|
+
errorCode: ErrorCodes.WU_INFER_LANE_ERROR,
|
|
915
|
+
},
|
|
916
|
+
});
|
|
917
|
+
return result.success
|
|
918
|
+
? success(result.data ?? { lane: 'Unknown' })
|
|
919
|
+
: error(result.error?.message ?? WuQueryMessages.INFER_LANE_FAILED, ErrorCodes.WU_INFER_LANE_ERROR);
|
|
920
|
+
},
|
|
921
|
+
};
|
|
922
|
+
/**
|
|
923
|
+
* wu_unlock_lane - Safely unlock a lane lock with audit logging
|
|
924
|
+
*/
|
|
925
|
+
export const wuUnlockLaneTool = {
|
|
926
|
+
name: 'wu_unlock_lane',
|
|
927
|
+
description: 'Safely unlock a lane lock with audit logging',
|
|
928
|
+
// WU-1454: Use shared schema
|
|
929
|
+
inputSchema: wuUnlockLaneSchema,
|
|
930
|
+
async execute(input, options) {
|
|
931
|
+
// If list mode, no lane required
|
|
932
|
+
if (!input.list && !input.lane) {
|
|
933
|
+
return error(ErrorMessages.LANE_REQUIRED, ErrorCodes.MISSING_PARAMETER);
|
|
934
|
+
}
|
|
935
|
+
const args = [];
|
|
936
|
+
if (input.lane)
|
|
937
|
+
args.push(CliArgs.LANE, input.lane);
|
|
938
|
+
if (input.reason)
|
|
939
|
+
args.push(CliArgs.REASON, input.reason);
|
|
940
|
+
if (input.force)
|
|
941
|
+
args.push(CliArgs.FORCE);
|
|
942
|
+
if (input.list)
|
|
943
|
+
args.push('--list');
|
|
944
|
+
if (input.status)
|
|
945
|
+
args.push(CliArgs.STATUS);
|
|
946
|
+
const result = await executeViaPack(CliCommands.WU_UNLOCK_LANE, input, {
|
|
947
|
+
projectRoot: options?.projectRoot,
|
|
948
|
+
contextInput: {
|
|
949
|
+
metadata: {
|
|
950
|
+
[MetadataKeys.PROJECT_ROOT]: options?.projectRoot,
|
|
951
|
+
},
|
|
952
|
+
},
|
|
953
|
+
fallback: {
|
|
954
|
+
command: CliCommands.WU_UNLOCK_LANE,
|
|
955
|
+
args,
|
|
956
|
+
errorCode: ErrorCodes.WU_UNLOCK_LANE_ERROR,
|
|
957
|
+
},
|
|
958
|
+
});
|
|
959
|
+
return result.success
|
|
960
|
+
? success(result.data ?? { message: WuDelegationAndGatesMessages.UNLOCK_PASSED })
|
|
961
|
+
: error(result.error?.message ?? WuDelegationAndGatesMessages.UNLOCK_FAILED, ErrorCodes.WU_UNLOCK_LANE_ERROR);
|
|
962
|
+
},
|
|
963
|
+
};
|
|
964
|
+
//# sourceMappingURL=wu-tools.js.map
|