@wrongstack/tools 1.0.8 → 1.0.10
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/_win32-resolve.d.ts +5 -0
- package/dist/audit.js +5 -5
- package/dist/bash-kill-guard.d.ts +6 -4
- package/dist/bash.js +2 -2
- package/dist/browser/index.js +1 -1
- package/dist/builtin.js +41 -41
- package/dist/{chunk-N3OTTQNC.js → chunk-2OCAAFAT.js} +44 -25
- package/dist/{chunk-5MP76C72.js → chunk-2UVAIS5O.js} +24 -29
- package/dist/{chunk-SIIOHBNY.js → chunk-3RRK33YM.js} +2 -2
- package/dist/{chunk-M2W36JT7.js → chunk-4CE3RKEP.js} +6 -3
- package/dist/{chunk-QJARSK2G.js → chunk-4SUGLJLO.js} +11 -3
- package/dist/{chunk-AH7J5HWL.js → chunk-5RBUYFRV.js} +15 -7
- package/dist/{chunk-GNLHBDFO.js → chunk-6I6RXQFG.js} +127 -196
- package/dist/{chunk-WKLUOXR4.js → chunk-7GOE2ZTZ.js} +2 -2
- package/dist/{chunk-O6AGFJBO.js → chunk-7V33PHT6.js} +49 -77
- package/dist/{chunk-CAF4L6KN.js → chunk-C3WP6ZOT.js} +36 -48
- package/dist/{chunk-KMXPP32M.js → chunk-C6ZOXNXV.js} +13 -3
- package/dist/{chunk-EGT5QLCB.js → chunk-D6RQZMZS.js} +123 -255
- package/dist/{chunk-S6CGSFLX.js → chunk-DBG7UQGK.js} +10 -3
- package/dist/{chunk-FI6SOIVE.js → chunk-DLZCOEVG.js} +21 -3
- package/dist/{chunk-NL45OWEO.js → chunk-DOAHONOS.js} +7 -12
- package/dist/{chunk-3LQJXJDM.js → chunk-E7A4SLKR.js} +2 -2
- package/dist/{chunk-JB5JLY7V.js → chunk-ENE22I5W.js} +387 -394
- package/dist/{chunk-5KRKL3WD.js → chunk-FCSUBTUJ.js} +112 -119
- package/dist/{chunk-YUK3WLHJ.js → chunk-FVSMTEO3.js} +2 -2
- package/dist/{chunk-SEONDNLN.js → chunk-G7CYW5EP.js} +2 -2
- package/dist/{chunk-TU6UVATU.js → chunk-HYHE4VNA.js} +3 -3
- package/dist/{chunk-HIRVCXLP.js → chunk-IE4KDAOB.js} +3 -3
- package/dist/{chunk-YA2ZYCJY.js → chunk-JPK2HHBK.js} +1 -1
- package/dist/{chunk-7E55DAFW.js → chunk-KHUCKLOR.js} +12 -7
- package/dist/{chunk-R3HIZVFS.js → chunk-KPDCKSN5.js} +23 -3
- package/dist/{chunk-B3MGJBFI.js → chunk-KS2OEZWV.js} +23 -47
- package/dist/{chunk-UI3ZJIG3.js → chunk-LKLIQUCW.js} +14 -8
- package/dist/{chunk-62OAECEQ.js → chunk-LLSFOUZF.js} +8 -8
- package/dist/{chunk-YZQSUL5G.js → chunk-M4ZHHCCW.js} +14 -6
- package/dist/{chunk-IXIS7RSG.js → chunk-MRXWOOOR.js} +29 -47
- package/dist/{chunk-C4DSQBTT.js → chunk-NEYUPZL6.js} +3 -3
- package/dist/{chunk-6XYFYLN7.js → chunk-O2MHULBO.js} +13 -8
- package/dist/{chunk-B62LKMWQ.js → chunk-OKZJJDOG.js} +86 -188
- package/dist/{chunk-HOFVYIPI.js → chunk-ON6ET5ER.js} +16 -1
- package/dist/{chunk-KF7GMVNU.js → chunk-OUERRFEM.js} +32 -11
- package/dist/{chunk-GF4JHLCO.js → chunk-PWZUHZP7.js} +2 -2
- package/dist/{chunk-OGQMPX3J.js → chunk-QAWI3RSK.js} +37 -81
- package/dist/{chunk-ZMCV3XOV.js → chunk-SPNXDTCJ.js} +29 -63
- package/dist/{chunk-H2VB7GCR.js → chunk-ULI2J6TX.js} +27 -14
- package/dist/{chunk-EMA2XENR.js → chunk-UVYRQKPZ.js} +4 -3
- package/dist/{chunk-MF6ZUBI7.js → chunk-V25Q6TQ7.js} +3 -3
- package/dist/{chunk-2NTHMZV3.js → chunk-VMJY6FYJ.js} +693 -276
- package/dist/{chunk-ZOUG3KKS.js → chunk-XPVYZ2S6.js} +2 -2
- package/dist/{chunk-5U5ULQX2.js → chunk-XZLVJD56.js} +5 -1
- package/dist/{chunk-HCPSVK7J.js → chunk-YKSOSI2N.js} +47 -31
- package/dist/codebase-index/codebase-ast-replace-tool.d.ts +5 -6
- package/dist/codebase-index/codebase-context-tool.d.ts +4 -6
- package/dist/codebase-index/codebase-impact-analysis-tool.d.ts +1 -2
- package/dist/codebase-index/codebase-incoming-calls-tool.d.ts +0 -2
- package/dist/codebase-index/codebase-index-tool.d.ts +0 -2
- package/dist/codebase-index/codebase-invariant-check-tool.d.ts +1 -2
- package/dist/codebase-index/codebase-outgoing-calls-tool.d.ts +0 -2
- package/dist/codebase-index/codebase-repo-map-tool.d.ts +1 -2
- package/dist/codebase-index/codebase-search-tool.d.ts +1 -1
- package/dist/codebase-index/codebase-targeted-test-tool.d.ts +1 -2
- package/dist/codebase-index/index.js +8 -8
- package/dist/codebase-index/parser-worker-script.js +3 -3
- package/dist/codebase-index/project-server.js +5 -5
- package/dist/codebase-index/worker.js +4 -4
- package/dist/design.js +1 -1
- package/dist/diff.js +1 -1
- package/dist/edit.js +7 -7
- package/dist/exec.d.ts +7 -7
- package/dist/exec.js +2 -2
- package/dist/format.js +5 -5
- package/dist/git.js +1 -1
- package/dist/glob.js +1 -1
- package/dist/{go-parser-VDPRQEGM.js → go-parser-Z4H6SR3R.js} +6 -3
- package/dist/grep.js +1 -1
- package/dist/index.js +45 -45
- package/dist/install.js +5 -5
- package/dist/json.d.ts +0 -1
- package/dist/json.js +1 -1
- package/dist/kanban-presence.d.ts +6 -0
- package/dist/kanban-serializer.d.ts +9 -1
- package/dist/kanban-split-task-handler.d.ts +1 -1
- package/dist/kanban-tool-results.d.ts +57 -2
- package/dist/kanban-tool-types.d.ts +16 -5
- package/dist/kanban.d.ts +14 -0
- package/dist/kanban.js +9 -1
- package/dist/languages/index.js +3 -3
- package/dist/{legacy-bridge-4T4OTSQP.js → legacy-bridge-BPT2S2F4.js} +5 -5
- package/dist/lint.js +5 -5
- package/dist/logs.js +1 -1
- package/dist/mode.d.ts +3 -2
- package/dist/mode.js +1 -1
- package/dist/outdated.js +2 -2
- package/dist/pack.js +42 -42
- package/dist/{parser-dispatch-4E2SDQUO.js → parser-dispatch-WG4DNBHH.js} +4 -4
- package/dist/patch.js +7 -7
- package/dist/plan.d.ts +2 -1
- package/dist/plan.js +3 -3
- package/dist/{py-parser-MAW6DHFE.js → py-parser-4PFZYAJ7.js} +3 -3
- package/dist/read.js +7 -7
- package/dist/replace.js +7 -7
- package/dist/search.d.ts +0 -6
- package/dist/search.js +1 -1
- package/dist/security-ast-scan-tool.d.ts +1 -2
- package/dist/session-shell.js +2 -2
- package/dist/task.d.ts +2 -1
- package/dist/task.js +3 -3
- package/dist/test.d.ts +8 -1
- package/dist/test.js +5 -5
- package/dist/todo.js +2 -2
- package/dist/tool-search.d.ts +2 -0
- package/dist/tool-search.js +1 -1
- package/dist/tool-tier.js +43 -43
- package/dist/tool-use.d.ts +2 -2
- package/dist/tool-use.js +1 -1
- package/dist/tree.js +1 -1
- package/dist/typecheck.js +5 -5
- package/dist/wasm/bash/tree-sitter-bash.wasm +0 -0
- package/dist/wasm/c/tree-sitter-c.wasm +0 -0
- package/dist/wasm/c_sharp/tree-sitter-c_sharp.wasm +0 -0
- package/dist/wasm/checksums.json +16 -0
- package/dist/wasm/cpp/tree-sitter-cpp.wasm +0 -0
- package/dist/wasm/elixir/tree-sitter-elixir.wasm +0 -0
- package/dist/wasm/go/tree-sitter-go.wasm +0 -0
- package/dist/wasm/java/tree-sitter-java.wasm +0 -0
- package/dist/wasm/kotlin/tree-sitter-kotlin.wasm +0 -0
- package/dist/wasm/php/tree-sitter-php.wasm +0 -0
- package/dist/wasm/python/tree-sitter-python.wasm +0 -0
- package/dist/wasm/ruby/tree-sitter-ruby.wasm +0 -0
- package/dist/wasm/rust/tree-sitter-rust.wasm +0 -0
- package/dist/wasm/swift/tree-sitter-swift.wasm +0 -0
- package/dist/wasm/tree-sitter-runtime.wasm +0 -0
- package/dist/win32.d.ts +1 -1
- package/dist/win32.js +3 -1
- package/dist/write.js +7 -7
- package/package.json +10 -10
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
todoTool
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-DBG7UQGK.js";
|
|
4
4
|
import {
|
|
5
5
|
mirrorSessionTasksToKanban
|
|
6
6
|
} from "./chunk-YZECCW3F.js";
|
|
@@ -138,13 +138,10 @@ var taskTool = {
|
|
|
138
138
|
"planify"
|
|
139
139
|
]);
|
|
140
140
|
if (!input?.action || !VALID_ACTIONS.has(input.action)) {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
completed: 0,
|
|
146
|
-
inProgress: 0
|
|
147
|
-
};
|
|
141
|
+
throw new ToolValidationError({
|
|
142
|
+
message: `task: Unknown action "${input?.action}". Use replace | add | status | show | promote | planify.`,
|
|
143
|
+
field: "action"
|
|
144
|
+
});
|
|
148
145
|
}
|
|
149
146
|
if (input.scope !== void 0 && input.scope !== "session" && input.scope !== "project") {
|
|
150
147
|
throw new ToolValidationError({
|
|
@@ -167,13 +164,7 @@ var taskTool = {
|
|
|
167
164
|
taskPath = sessionTaskPath;
|
|
168
165
|
}
|
|
169
166
|
if (typeof taskPath !== "string" || !taskPath) {
|
|
170
|
-
|
|
171
|
-
ok: false,
|
|
172
|
-
message: "Task storage path not configured.",
|
|
173
|
-
count: 0,
|
|
174
|
-
completed: 0,
|
|
175
|
-
inProgress: 0
|
|
176
|
-
};
|
|
167
|
+
throw new Error("task: Task storage path not configured.");
|
|
177
168
|
}
|
|
178
169
|
const sessionId = ctx.session?.id ?? "unknown";
|
|
179
170
|
if (input.action === "show") {
|
|
@@ -189,7 +180,10 @@ var taskTool = {
|
|
|
189
180
|
inProgress: p2.inProgress
|
|
190
181
|
};
|
|
191
182
|
}
|
|
192
|
-
let
|
|
183
|
+
let failure;
|
|
184
|
+
const refuse = (message, field) => {
|
|
185
|
+
failure = field ? new ToolValidationError({ message: `task: ${message}`, field }) : new Error(`task: ${message}`);
|
|
186
|
+
};
|
|
193
187
|
const promoteMeta = { count: 0, title: "" };
|
|
194
188
|
const planifyMeta = { title: "", details: "" };
|
|
195
189
|
let didPlanify = false;
|
|
@@ -202,13 +196,7 @@ var taskTool = {
|
|
|
202
196
|
break;
|
|
203
197
|
case "replace": {
|
|
204
198
|
if (!Array.isArray(input.tasks)) {
|
|
205
|
-
|
|
206
|
-
ok: false,
|
|
207
|
-
message: "action=replace requires `tasks` array.",
|
|
208
|
-
count: 0,
|
|
209
|
-
completed: 0,
|
|
210
|
-
inProgress: 0
|
|
211
|
-
};
|
|
199
|
+
refuse("action=replace requires `tasks` array.", "tasks");
|
|
212
200
|
return f;
|
|
213
201
|
}
|
|
214
202
|
const newIds = new Set(input.tasks.map((t) => t.id));
|
|
@@ -223,25 +211,20 @@ var taskTool = {
|
|
|
223
211
|
})
|
|
224
212
|
)
|
|
225
213
|
];
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
completed: 0,
|
|
231
|
-
inProgress: 0
|
|
232
|
-
};
|
|
214
|
+
refuse(
|
|
215
|
+
`action=replace has duplicate task IDs: ${dupes.join(", ")}. Each task id must be unique.`,
|
|
216
|
+
"tasks"
|
|
217
|
+
);
|
|
233
218
|
return f;
|
|
234
219
|
}
|
|
235
220
|
const omittedUnfinished = f.tasks.filter(
|
|
236
221
|
(task) => task.status !== "completed" && !newIds.has(task.id)
|
|
237
222
|
);
|
|
238
223
|
if (omittedUnfinished.length > 0) {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
...computeTaskItemProgress(f.tasks)
|
|
244
|
-
};
|
|
224
|
+
refuse(
|
|
225
|
+
`action=replace cannot omit unfinished tasks: ${omittedUnfinished.map((task) => task.id).join(", ")}. Complete them first.`,
|
|
226
|
+
"tasks"
|
|
227
|
+
);
|
|
245
228
|
return f;
|
|
246
229
|
}
|
|
247
230
|
const taskStatusById = new Map(input.tasks.map((t) => [t.id, t.status]));
|
|
@@ -249,13 +232,10 @@ var taskTool = {
|
|
|
249
232
|
if (t.dependsOn && t.dependsOn.length > 0) {
|
|
250
233
|
const missing = t.dependsOn.filter((d) => !newIds.has(d));
|
|
251
234
|
if (missing.length > 0) {
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
completed: 0,
|
|
257
|
-
inProgress: 0
|
|
258
|
-
};
|
|
235
|
+
refuse(
|
|
236
|
+
`dependsOn validation failed: task "${t.id}" references unknown IDs: ${missing.join(", ")}`,
|
|
237
|
+
"tasks"
|
|
238
|
+
);
|
|
259
239
|
return f;
|
|
260
240
|
}
|
|
261
241
|
}
|
|
@@ -264,12 +244,9 @@ var taskTool = {
|
|
|
264
244
|
(dependencyId) => taskStatusById.get(dependencyId) !== "completed"
|
|
265
245
|
);
|
|
266
246
|
if (unmet.length > 0) {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
count: f.tasks.length,
|
|
271
|
-
...computeTaskItemProgress(f.tasks)
|
|
272
|
-
};
|
|
247
|
+
refuse(
|
|
248
|
+
`dependency status validation failed: task "${t.id}" cannot be ${t.status} before completion of ${unmet.join(", ")}.`
|
|
249
|
+
);
|
|
273
250
|
return f;
|
|
274
251
|
}
|
|
275
252
|
}
|
|
@@ -285,26 +262,17 @@ var taskTool = {
|
|
|
285
262
|
case "add": {
|
|
286
263
|
const t = input.task;
|
|
287
264
|
if (!t?.title) {
|
|
288
|
-
|
|
289
|
-
ok: false,
|
|
290
|
-
message: "action=add requires `task` with at least `title`.",
|
|
291
|
-
count: 0,
|
|
292
|
-
completed: 0,
|
|
293
|
-
inProgress: 0
|
|
294
|
-
};
|
|
265
|
+
refuse("action=add requires `task` with at least `title`.", "task");
|
|
295
266
|
return f;
|
|
296
267
|
}
|
|
297
268
|
if (t.dependsOn && t.dependsOn.length > 0) {
|
|
298
269
|
const existingIds = new Set(f.tasks.map((e) => e.id));
|
|
299
270
|
const missing = t.dependsOn.filter((d) => !existingIds.has(d));
|
|
300
271
|
if (missing.length > 0) {
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
completed: 0,
|
|
306
|
-
inProgress: 0
|
|
307
|
-
};
|
|
272
|
+
refuse(
|
|
273
|
+
`dependsOn validation failed: unknown task IDs: ${missing.join(", ")}`,
|
|
274
|
+
"task"
|
|
275
|
+
);
|
|
308
276
|
return f;
|
|
309
277
|
}
|
|
310
278
|
}
|
|
@@ -336,33 +304,19 @@ var taskTool = {
|
|
|
336
304
|
"completed"
|
|
337
305
|
]);
|
|
338
306
|
if (!input.id || !input.status) {
|
|
339
|
-
|
|
340
|
-
ok: false,
|
|
341
|
-
message: "action=status requires `id` and `status`.",
|
|
342
|
-
count: 0,
|
|
343
|
-
completed: 0,
|
|
344
|
-
inProgress: 0
|
|
345
|
-
};
|
|
307
|
+
refuse("action=status requires `id` and `status`.", input.id ? "status" : "id");
|
|
346
308
|
return f;
|
|
347
309
|
}
|
|
348
310
|
if (!VALID_TASK_STATUSES.has(input.status)) {
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
...computeTaskItemProgress(f.tasks)
|
|
354
|
-
};
|
|
311
|
+
refuse(
|
|
312
|
+
`action=status requires valid status ('pending' | 'in_progress' | 'blocked' | 'failed' | 'review' | 'completed'), got "${input.status}".`,
|
|
313
|
+
"status"
|
|
314
|
+
);
|
|
355
315
|
return f;
|
|
356
316
|
}
|
|
357
317
|
const task = f.tasks.find((t) => t.id === input.id);
|
|
358
318
|
if (!task) {
|
|
359
|
-
|
|
360
|
-
ok: false,
|
|
361
|
-
message: `Task "${input.id}" not found.`,
|
|
362
|
-
count: 0,
|
|
363
|
-
completed: 0,
|
|
364
|
-
inProgress: 0
|
|
365
|
-
};
|
|
319
|
+
refuse(`Task "${input.id}" not found.`, "id");
|
|
366
320
|
return f;
|
|
367
321
|
}
|
|
368
322
|
if (input.status === "in_progress" || input.status === "completed") {
|
|
@@ -370,12 +324,9 @@ var taskTool = {
|
|
|
370
324
|
(dependencyId) => f.tasks.find((candidate) => candidate.id === dependencyId)?.status !== "completed"
|
|
371
325
|
);
|
|
372
326
|
if (unmet.length > 0) {
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
count: f.tasks.length,
|
|
377
|
-
...computeTaskItemProgress(f.tasks)
|
|
378
|
-
};
|
|
327
|
+
refuse(
|
|
328
|
+
`Task "${task.id}" cannot be ${input.status} before dependencies complete: ${unmet.join(", ")}.`
|
|
329
|
+
);
|
|
379
330
|
return f;
|
|
380
331
|
}
|
|
381
332
|
}
|
|
@@ -386,35 +337,16 @@ var taskTool = {
|
|
|
386
337
|
case "promote": {
|
|
387
338
|
const target = (input.target ?? input.id)?.trim();
|
|
388
339
|
if (!target) {
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
completed: 0,
|
|
394
|
-
inProgress: 0
|
|
395
|
-
};
|
|
340
|
+
refuse(
|
|
341
|
+
"action=promote requires `target` (task id, index, or title substring).",
|
|
342
|
+
"target"
|
|
343
|
+
);
|
|
396
344
|
return f;
|
|
397
345
|
}
|
|
398
346
|
const idx = findTaskIndex(f.tasks, target);
|
|
399
|
-
|
|
400
|
-
early = {
|
|
401
|
-
ok: false,
|
|
402
|
-
message: `No task matched "${target}".`,
|
|
403
|
-
count: 0,
|
|
404
|
-
completed: 0,
|
|
405
|
-
inProgress: 0
|
|
406
|
-
};
|
|
407
|
-
return f;
|
|
408
|
-
}
|
|
409
|
-
const match = f.tasks[idx];
|
|
347
|
+
const match = idx === -1 ? void 0 : f.tasks[idx];
|
|
410
348
|
if (!match) {
|
|
411
|
-
|
|
412
|
-
ok: false,
|
|
413
|
-
message: `No task matched "${target}".`,
|
|
414
|
-
count: 0,
|
|
415
|
-
completed: 0,
|
|
416
|
-
inProgress: 0
|
|
417
|
-
};
|
|
349
|
+
refuse(`No task matched "${target}".`, "target");
|
|
418
350
|
return f;
|
|
419
351
|
}
|
|
420
352
|
if (match.status !== "completed" && match.status !== "failed") {
|
|
@@ -457,35 +389,16 @@ var taskTool = {
|
|
|
457
389
|
case "planify": {
|
|
458
390
|
const target = (input.target ?? input.id)?.trim();
|
|
459
391
|
if (!target) {
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
completed: 0,
|
|
465
|
-
inProgress: 0
|
|
466
|
-
};
|
|
392
|
+
refuse(
|
|
393
|
+
"action=planify requires `target` (task id, index, or title substring).",
|
|
394
|
+
"target"
|
|
395
|
+
);
|
|
467
396
|
return f;
|
|
468
397
|
}
|
|
469
398
|
const idx = findTaskIndex(f.tasks, target);
|
|
470
|
-
|
|
471
|
-
early = {
|
|
472
|
-
ok: false,
|
|
473
|
-
message: `No task matched "${target}".`,
|
|
474
|
-
count: 0,
|
|
475
|
-
completed: 0,
|
|
476
|
-
inProgress: 0
|
|
477
|
-
};
|
|
478
|
-
return f;
|
|
479
|
-
}
|
|
480
|
-
const match = f.tasks[idx];
|
|
399
|
+
const match = idx === -1 ? void 0 : f.tasks[idx];
|
|
481
400
|
if (!match) {
|
|
482
|
-
|
|
483
|
-
ok: false,
|
|
484
|
-
message: `No task matched "${target}".`,
|
|
485
|
-
count: 0,
|
|
486
|
-
completed: 0,
|
|
487
|
-
inProgress: 0
|
|
488
|
-
};
|
|
401
|
+
refuse(`No task matched "${target}".`, "target");
|
|
489
402
|
return f;
|
|
490
403
|
}
|
|
491
404
|
planifyMeta.title = match.title;
|
|
@@ -494,26 +407,21 @@ var taskTool = {
|
|
|
494
407
|
break;
|
|
495
408
|
}
|
|
496
409
|
default:
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
completed: 0,
|
|
502
|
-
inProgress: 0
|
|
503
|
-
};
|
|
410
|
+
refuse(
|
|
411
|
+
`Unknown action "${input.action}". Use replace | add | status | show | promote | planify.`,
|
|
412
|
+
"action"
|
|
413
|
+
);
|
|
504
414
|
return f;
|
|
505
415
|
}
|
|
506
416
|
return f;
|
|
507
417
|
});
|
|
508
418
|
} catch (err) {
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
completed: 0,
|
|
514
|
-
inProgress: 0
|
|
515
|
-
};
|
|
419
|
+
throw new Error(
|
|
420
|
+
`task: change not saved \u2014 ${err instanceof Error ? err.message : String(err)}`,
|
|
421
|
+
{ cause: err }
|
|
422
|
+
);
|
|
516
423
|
}
|
|
424
|
+
if (failure) throw failure;
|
|
517
425
|
ctx.meta["task.path.resolved"] = taskPath;
|
|
518
426
|
if (todosToReplace) {
|
|
519
427
|
await todoTool.execute({ todos: todosToReplace }, ctx, {
|
|
@@ -521,46 +429,36 @@ var taskTool = {
|
|
|
521
429
|
});
|
|
522
430
|
}
|
|
523
431
|
mirrorSessionTasksToKanban(ctx.projectRoot, file.tasks, sessionId);
|
|
524
|
-
if (early) return early;
|
|
525
432
|
if (didPlanify) {
|
|
526
433
|
const { title, details } = planifyMeta;
|
|
527
434
|
const planPathRaw = ctx.meta["plan.path"];
|
|
528
435
|
const prog = computeTaskItemProgress(file.tasks);
|
|
529
|
-
if (typeof planPathRaw
|
|
530
|
-
|
|
531
|
-
if (input.scope === "project") {
|
|
532
|
-
const lastSep = Math.max(planPath.lastIndexOf("/"), planPath.lastIndexOf("\\"));
|
|
533
|
-
planPath = lastSep >= 0 ? planPath.slice(0, lastSep + 1) + "backlog.plan.json" : "backlog.plan.json";
|
|
534
|
-
}
|
|
535
|
-
let formatted = "";
|
|
536
|
-
try {
|
|
537
|
-
await mutatePlan(planPath, sessionId, (pf) => {
|
|
538
|
-
const { plan: updated } = addPlanItem(pf, title, details || void 0);
|
|
539
|
-
formatted = formatPlan(updated);
|
|
540
|
-
return updated;
|
|
541
|
-
});
|
|
542
|
-
ctx.meta["plan.path.resolved"] = planPath;
|
|
543
|
-
} catch (err) {
|
|
544
|
-
return {
|
|
545
|
-
ok: false,
|
|
546
|
-
message: `planify: plan not saved \u2014 ${err instanceof Error ? err.message : String(err)}`,
|
|
547
|
-
count: file.tasks.length,
|
|
548
|
-
completed: prog.completed,
|
|
549
|
-
inProgress: prog.inProgress
|
|
550
|
-
};
|
|
551
|
-
}
|
|
552
|
-
return {
|
|
553
|
-
ok: true,
|
|
554
|
-
message: `planify ok \u2014 added "${title}" to plan.
|
|
555
|
-
${formatted}`,
|
|
556
|
-
count: file.tasks.length,
|
|
557
|
-
completed: prog.completed,
|
|
558
|
-
inProgress: prog.inProgress
|
|
559
|
-
};
|
|
436
|
+
if (typeof planPathRaw !== "string" || !planPathRaw) {
|
|
437
|
+
throw new Error("task: Plan storage path not configured \u2014 cannot planify.");
|
|
560
438
|
}
|
|
439
|
+
let planPath = planPathRaw;
|
|
440
|
+
if (input.scope === "project") {
|
|
441
|
+
const lastSep = Math.max(planPath.lastIndexOf("/"), planPath.lastIndexOf("\\"));
|
|
442
|
+
planPath = lastSep >= 0 ? planPath.slice(0, lastSep + 1) + "backlog.plan.json" : "backlog.plan.json";
|
|
443
|
+
}
|
|
444
|
+
let formatted = "";
|
|
445
|
+
try {
|
|
446
|
+
await mutatePlan(planPath, sessionId, (pf) => {
|
|
447
|
+
const { plan: updated } = addPlanItem(pf, title, details || void 0);
|
|
448
|
+
formatted = formatPlan(updated);
|
|
449
|
+
return updated;
|
|
450
|
+
});
|
|
451
|
+
} catch (err) {
|
|
452
|
+
throw new Error(
|
|
453
|
+
`task: planify: plan not saved \u2014 ${err instanceof Error ? err.message : String(err)}`,
|
|
454
|
+
{ cause: err }
|
|
455
|
+
);
|
|
456
|
+
}
|
|
457
|
+
ctx.meta["plan.path.resolved"] = planPath;
|
|
561
458
|
return {
|
|
562
|
-
ok:
|
|
563
|
-
message:
|
|
459
|
+
ok: true,
|
|
460
|
+
message: `planify ok \u2014 added "${title}" to plan.
|
|
461
|
+
${formatted}`,
|
|
564
462
|
count: file.tasks.length,
|
|
565
463
|
completed: prog.completed,
|
|
566
464
|
inProgress: prog.inProgress
|
|
@@ -582,4 +480,4 @@ ${formatTaskList(file.tasks)}` : file.tasks.length > 0 ? formatTaskList(file.tas
|
|
|
582
480
|
export {
|
|
583
481
|
taskTool
|
|
584
482
|
};
|
|
585
|
-
//# sourceMappingURL=chunk-
|
|
483
|
+
//# sourceMappingURL=chunk-OKZJJDOG.js.map
|
|
@@ -64,6 +64,21 @@ var globTool = {
|
|
|
64
64
|
return { files: [], truncated: true };
|
|
65
65
|
}
|
|
66
66
|
const base = input.path ? await safeResolveReal(input.path, ctx) : ctx.cwd;
|
|
67
|
+
if (input.path) {
|
|
68
|
+
const baseStat = await fs.stat(base).catch(() => null);
|
|
69
|
+
if (!baseStat) {
|
|
70
|
+
throw new ToolValidationError({
|
|
71
|
+
message: `glob: path "${input.path}" does not exist`,
|
|
72
|
+
field: "path"
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
if (!baseStat.isDirectory()) {
|
|
76
|
+
throw new ToolValidationError({
|
|
77
|
+
message: `glob: path "${input.path}" is not a directory`,
|
|
78
|
+
field: "path"
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
67
82
|
const rawLimit = typeof input.limit === "number" && !Number.isNaN(input.limit) ? input.limit : 1e3;
|
|
68
83
|
const limit = Math.max(1, Math.min(Math.floor(rawLimit), 5e3));
|
|
69
84
|
const isGitIgnored = await loadGitignoreMatcher(base);
|
|
@@ -188,4 +203,4 @@ var globTool = {
|
|
|
188
203
|
export {
|
|
189
204
|
globTool
|
|
190
205
|
};
|
|
191
|
-
//# sourceMappingURL=chunk-
|
|
206
|
+
//# sourceMappingURL=chunk-ON6ET5ER.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
tryLegacyCodeOperation
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-E7A4SLKR.js";
|
|
4
4
|
import {
|
|
5
5
|
spawnStream
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-UVYRQKPZ.js";
|
|
7
7
|
import {
|
|
8
8
|
normalizeCommandOutput,
|
|
9
9
|
safeResolveReal
|
|
@@ -16,7 +16,7 @@ var testTool = {
|
|
|
16
16
|
name: "test",
|
|
17
17
|
category: "Code Quality",
|
|
18
18
|
description: "Execute the project's test suite. This is one of the most critical tools for validating that your changes are correct.",
|
|
19
|
-
usageHint: "ESSENTIAL BEFORE CONSIDERING WORK DONE:\n\n- Use `files` or `grep` to run only relevant tests during development.\n- `coverage: true` is useful when working on critical paths.\nRun tests frequently. A clean test run is usually required before the task can be considered complete.",
|
|
19
|
+
usageHint: "ESSENTIAL BEFORE CONSIDERING WORK DONE:\n\n- Use `files` or `grep` to run only relevant tests during development.\n- `coverage: true` is useful when working on critical paths.\n- Check `status`: `passed`, `failed`, or `no_tests` (no runner configured / no test files matched). `no_tests` is NOT a pass.\nRun tests frequently. A clean test run is usually required before the task can be considered complete.",
|
|
20
20
|
permission: "confirm",
|
|
21
21
|
mutating: false,
|
|
22
22
|
icon: "test",
|
|
@@ -75,16 +75,26 @@ var testTool = {
|
|
|
75
75
|
});
|
|
76
76
|
if (bridge?.run) {
|
|
77
77
|
const run = bridge.run;
|
|
78
|
+
if (run.status === "unavailable") {
|
|
79
|
+
throw new Error(
|
|
80
|
+
`test: ${bridge.language} test runner unavailable: ${run.error || run.output || "no detail"}`
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
const passed = run.summary.passed ?? 0;
|
|
84
|
+
const failed = run.summary.failed ?? 0;
|
|
85
|
+
const exitCode = run.exitCode ?? 0;
|
|
86
|
+
const rawOutput = run.output || run.error || "";
|
|
78
87
|
yield {
|
|
79
88
|
type: "final",
|
|
80
89
|
output: {
|
|
81
90
|
runner: bridge.language,
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
91
|
+
status: resolveStatus(exitCode, passed + failed, rawOutput),
|
|
92
|
+
exit_code: exitCode,
|
|
93
|
+
tests_run: passed + failed,
|
|
94
|
+
passed,
|
|
95
|
+
failed,
|
|
86
96
|
duration_ms: run.durationMs,
|
|
87
|
-
output: normalizeCommandOutput(
|
|
97
|
+
output: normalizeCommandOutput(rawOutput),
|
|
88
98
|
truncated: run.truncated
|
|
89
99
|
}
|
|
90
100
|
};
|
|
@@ -97,12 +107,14 @@ var testTool = {
|
|
|
97
107
|
type: "final",
|
|
98
108
|
output: {
|
|
99
109
|
runner: "none",
|
|
100
|
-
|
|
110
|
+
// Nothing ran: not a pass, and no exit code to report.
|
|
111
|
+
status: "no_tests",
|
|
112
|
+
exit_code: null,
|
|
101
113
|
tests_run: 0,
|
|
102
114
|
passed: 0,
|
|
103
115
|
failed: 0,
|
|
104
116
|
duration_ms: 0,
|
|
105
|
-
output: "No test runner
|
|
117
|
+
output: "No tests: no test runner configured (looked for vitest.config.*, jest.config.*, .mocharc.*).",
|
|
106
118
|
truncated: false
|
|
107
119
|
}
|
|
108
120
|
};
|
|
@@ -119,6 +131,9 @@ var testTool = {
|
|
|
119
131
|
maxBytes: 2e5
|
|
120
132
|
});
|
|
121
133
|
const duration = Date.now() - start;
|
|
134
|
+
if (result.error) {
|
|
135
|
+
throw new Error(`test: failed to start ${detected}: ${result.error}`);
|
|
136
|
+
}
|
|
122
137
|
yield { type: "final", output: parseResult(detected, result, duration) };
|
|
123
138
|
}
|
|
124
139
|
};
|
|
@@ -183,6 +198,11 @@ function buildArgs(runner, input) {
|
|
|
183
198
|
}
|
|
184
199
|
return args;
|
|
185
200
|
}
|
|
201
|
+
var NO_TESTS_PATTERN = /No test files found|No tests found|no test files|running 0 tests|^\s*0 passing/im;
|
|
202
|
+
function resolveStatus(exitCode, testsRun, output) {
|
|
203
|
+
if (testsRun === 0 && NO_TESTS_PATTERN.test(output)) return "no_tests";
|
|
204
|
+
return exitCode === 0 ? "passed" : "failed";
|
|
205
|
+
}
|
|
186
206
|
function parseResult(runner, result, duration) {
|
|
187
207
|
const out = result.stdout + result.stderr;
|
|
188
208
|
let tests_run = 0;
|
|
@@ -212,6 +232,7 @@ function parseResult(runner, result, duration) {
|
|
|
212
232
|
${result.stderr}` : result.stdout || result.stderr || result.error || "";
|
|
213
233
|
return {
|
|
214
234
|
runner,
|
|
235
|
+
status: resolveStatus(result.exitCode, tests_run, out),
|
|
215
236
|
exit_code: result.exitCode,
|
|
216
237
|
tests_run,
|
|
217
238
|
passed,
|
|
@@ -231,4 +252,4 @@ ${result.stderr}` : result.stdout || result.stderr || result.error || "";
|
|
|
231
252
|
export {
|
|
232
253
|
testTool
|
|
233
254
|
};
|
|
234
|
-
//# sourceMappingURL=chunk-
|
|
255
|
+
//# sourceMappingURL=chunk-OUERRFEM.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-MSOAX3GC.js";
|
|
4
4
|
import {
|
|
5
5
|
enqueueReindex
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-HYHE4VNA.js";
|
|
7
7
|
import {
|
|
8
8
|
safeResolveReal,
|
|
9
9
|
sha256hex,
|
|
@@ -179,4 +179,4 @@ async function finishWrite(input, ctx, prepared, signal) {
|
|
|
179
179
|
export {
|
|
180
180
|
writeTool
|
|
181
181
|
};
|
|
182
|
-
//# sourceMappingURL=chunk-
|
|
182
|
+
//# sourceMappingURL=chunk-PWZUHZP7.js.map
|