@wrongstack/tools 0.89.3 → 0.104.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/builtin.js +143 -1
- package/dist/builtin.js.map +1 -1
- package/dist/index.js +143 -1
- package/dist/index.js.map +1 -1
- package/dist/pack.js +143 -1
- package/dist/pack.js.map +1 -1
- package/package.json +2 -2
package/dist/pack.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as Core from '@wrongstack/core';
|
|
2
|
-
import { buildChildEnv, expectDefined, detectNewlineStyle, normalizeToLf, toStyle, atomicWrite, unifiedDiff, compileGlob, loadPlan, emptyPlan, clearPlan, savePlan, getPlanTemplate, addPlanItem, deriveTodosFromPlanItem, removePlanItem, setPlanItemStatus, formatPlan, resolveWstackPaths } from '@wrongstack/core';
|
|
2
|
+
import { buildChildEnv, expectDefined, detectNewlineStyle, normalizeToLf, toStyle, atomicWrite, unifiedDiff, compileGlob, loadPlan, emptyPlan, clearPlan, savePlan, getPlanTemplate, addPlanItem, deriveTodosFromPlanItem, removePlanItem, setPlanItemStatus, formatPlan, loadTasks, emptyTaskFile, saveTasks, computeTaskItemProgress, formatTaskList, resolveWstackPaths } from '@wrongstack/core';
|
|
3
3
|
import { spawn, execFileSync, spawnSync } from 'node:child_process';
|
|
4
4
|
import * as fs12 from 'node:fs/promises';
|
|
5
5
|
import * as path from 'node:path';
|
|
@@ -6550,6 +6550,147 @@ function anySignal(...signals) {
|
|
|
6550
6550
|
function stripTags2(html) {
|
|
6551
6551
|
return html.replace(/<[^>]+>/g, "").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'").trim();
|
|
6552
6552
|
}
|
|
6553
|
+
var taskTool = {
|
|
6554
|
+
name: "task",
|
|
6555
|
+
category: "Session",
|
|
6556
|
+
description: "Manage structured work items with dependencies, types, and priorities. Use this for complex, multi-step work where tasks have ordering constraints. Unlike `todo` (flat, tactical), `task` supports typed work (feature/bugfix/refactor/etc.), dependencies between items, priority ranking, and agent assignment. The task list persists across session resumes.",
|
|
6557
|
+
usageHint: 'USE FOR STRUCTURED WORK:\n- `action: "replace"` \u2014 set the complete task list (tasks ordered by priority)\n- `action: "add"` \u2014 append a single task\n- `action: "status"` \u2014 update a task\'s status (e.g. pending\u2192in_progress, in_progress\u2192completed)\n- `action: "show"` \u2014 view current tasks without changing them\n\nTask fields:\n- `dependsOn`: list of task IDs this one waits for\n- `type`: "feature" | "bugfix" | "refactor" | "docs" | "test" | "chore"\n- `priority`: "critical" | "high" | "medium" | "low"\n- `assignee`: agent/subagent name (e.g. "bug-hunter", "refactor-planner")\n- `estimateHours`: rough time estimate',
|
|
6558
|
+
permission: "auto",
|
|
6559
|
+
mutating: false,
|
|
6560
|
+
timeoutMs: 2e3,
|
|
6561
|
+
inputSchema: {
|
|
6562
|
+
type: "object",
|
|
6563
|
+
properties: {
|
|
6564
|
+
action: {
|
|
6565
|
+
type: "string",
|
|
6566
|
+
enum: ["replace", "add", "status", "show"],
|
|
6567
|
+
description: "replace = set full list, add = append, status = update task status, show = view only."
|
|
6568
|
+
},
|
|
6569
|
+
tasks: {
|
|
6570
|
+
type: "array",
|
|
6571
|
+
items: {
|
|
6572
|
+
type: "object",
|
|
6573
|
+
properties: {
|
|
6574
|
+
id: { type: "string", description: 'Unique id (e.g. "t1", "auth-flow").' },
|
|
6575
|
+
title: { type: "string", description: "Short title." },
|
|
6576
|
+
description: { type: "string", description: "Optional details." },
|
|
6577
|
+
type: { type: "string", enum: ["feature", "bugfix", "refactor", "docs", "test", "chore"] },
|
|
6578
|
+
priority: { type: "string", enum: ["critical", "high", "medium", "low"] },
|
|
6579
|
+
status: { type: "string", enum: ["pending", "in_progress", "blocked", "failed", "review", "completed"] },
|
|
6580
|
+
dependsOn: {
|
|
6581
|
+
type: "array",
|
|
6582
|
+
items: { type: "string" },
|
|
6583
|
+
description: "IDs of tasks this one depends on."
|
|
6584
|
+
},
|
|
6585
|
+
assignee: { type: "string", description: "Agent/subagent assigned." },
|
|
6586
|
+
estimateHours: { type: "number", description: "Estimated hours." },
|
|
6587
|
+
tags: { type: "array", items: { type: "string" }, description: "Optional tags." },
|
|
6588
|
+
createdAt: { type: "string" },
|
|
6589
|
+
updatedAt: { type: "string" }
|
|
6590
|
+
},
|
|
6591
|
+
required: ["id", "title", "type", "priority", "status"]
|
|
6592
|
+
},
|
|
6593
|
+
description: "Complete task list. Replaces previous list entirely."
|
|
6594
|
+
},
|
|
6595
|
+
task: {
|
|
6596
|
+
type: "object",
|
|
6597
|
+
properties: {
|
|
6598
|
+
title: { type: "string" },
|
|
6599
|
+
description: { type: "string" },
|
|
6600
|
+
type: { type: "string", enum: ["feature", "bugfix", "refactor", "docs", "test", "chore"] },
|
|
6601
|
+
priority: { type: "string", enum: ["critical", "high", "medium", "low"] },
|
|
6602
|
+
status: { type: "string", enum: ["pending", "in_progress", "blocked", "failed", "review", "completed"] },
|
|
6603
|
+
dependsOn: { type: "array", items: { type: "string" } },
|
|
6604
|
+
assignee: { type: "string" },
|
|
6605
|
+
estimateHours: { type: "number" },
|
|
6606
|
+
tags: { type: "array", items: { type: "string" } }
|
|
6607
|
+
},
|
|
6608
|
+
required: ["title", "type", "priority"],
|
|
6609
|
+
description: "Single task to append (id/createdAt/updatedAt auto-generated)."
|
|
6610
|
+
},
|
|
6611
|
+
id: { type: "string", description: "Task id for action=status." },
|
|
6612
|
+
status: {
|
|
6613
|
+
type: "string",
|
|
6614
|
+
enum: ["pending", "in_progress", "blocked", "failed", "review", "completed"],
|
|
6615
|
+
description: "New status for action=status."
|
|
6616
|
+
}
|
|
6617
|
+
},
|
|
6618
|
+
required: ["action"]
|
|
6619
|
+
},
|
|
6620
|
+
async execute(input, ctx) {
|
|
6621
|
+
const taskPath = ctx.meta["task.path"];
|
|
6622
|
+
if (typeof taskPath !== "string" || !taskPath) {
|
|
6623
|
+
return { ok: false, message: "Task storage path not configured.", count: 0, completed: 0, inProgress: 0 };
|
|
6624
|
+
}
|
|
6625
|
+
const sessionId = ctx.session?.id ?? "unknown";
|
|
6626
|
+
let file = await loadTasks(taskPath) ?? emptyTaskFile(sessionId);
|
|
6627
|
+
switch (input.action) {
|
|
6628
|
+
case "show":
|
|
6629
|
+
break;
|
|
6630
|
+
case "replace": {
|
|
6631
|
+
if (!Array.isArray(input.tasks)) {
|
|
6632
|
+
return { ok: false, message: "action=replace requires `tasks` array.", count: 0, completed: 0, inProgress: 0 };
|
|
6633
|
+
}
|
|
6634
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
6635
|
+
file.tasks = input.tasks.map((t) => ({
|
|
6636
|
+
...t,
|
|
6637
|
+
createdAt: t.createdAt || now,
|
|
6638
|
+
updatedAt: now
|
|
6639
|
+
}));
|
|
6640
|
+
await saveTasks(taskPath, file);
|
|
6641
|
+
break;
|
|
6642
|
+
}
|
|
6643
|
+
case "add": {
|
|
6644
|
+
const t = input.task;
|
|
6645
|
+
if (!t || !t.title) {
|
|
6646
|
+
return { ok: false, message: "action=add requires `task` with at least `title`.", count: 0, completed: 0, inProgress: 0 };
|
|
6647
|
+
}
|
|
6648
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
6649
|
+
const newTask = {
|
|
6650
|
+
id: `task_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
|
|
6651
|
+
title: t.title,
|
|
6652
|
+
description: t.description,
|
|
6653
|
+
type: t.type || "feature",
|
|
6654
|
+
priority: t.priority || "medium",
|
|
6655
|
+
status: t.status || "pending",
|
|
6656
|
+
dependsOn: t.dependsOn,
|
|
6657
|
+
assignee: t.assignee,
|
|
6658
|
+
estimateHours: t.estimateHours,
|
|
6659
|
+
tags: t.tags,
|
|
6660
|
+
createdAt: now,
|
|
6661
|
+
updatedAt: now
|
|
6662
|
+
};
|
|
6663
|
+
file.tasks.push(newTask);
|
|
6664
|
+
await saveTasks(taskPath, file);
|
|
6665
|
+
break;
|
|
6666
|
+
}
|
|
6667
|
+
case "status": {
|
|
6668
|
+
if (!input.id || !input.status) {
|
|
6669
|
+
return { ok: false, message: "action=status requires `id` and `status`.", count: 0, completed: 0, inProgress: 0 };
|
|
6670
|
+
}
|
|
6671
|
+
const task = file.tasks.find((t) => t.id === input.id);
|
|
6672
|
+
if (!task) {
|
|
6673
|
+
return { ok: false, message: `Task "${input.id}" not found.`, count: 0, completed: 0, inProgress: 0 };
|
|
6674
|
+
}
|
|
6675
|
+
task.status = input.status;
|
|
6676
|
+
task.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
6677
|
+
await saveTasks(taskPath, file);
|
|
6678
|
+
break;
|
|
6679
|
+
}
|
|
6680
|
+
default:
|
|
6681
|
+
return { ok: false, message: `Unknown action "${input.action}". Use replace | add | status | show.`, count: 0, completed: 0, inProgress: 0 };
|
|
6682
|
+
}
|
|
6683
|
+
const p = computeTaskItemProgress(file.tasks);
|
|
6684
|
+
const summary = file.tasks.length > 0 ? formatTaskList(file.tasks) : "No tasks.";
|
|
6685
|
+
return {
|
|
6686
|
+
ok: true,
|
|
6687
|
+
message: summary,
|
|
6688
|
+
count: file.tasks.length,
|
|
6689
|
+
completed: p.completed,
|
|
6690
|
+
inProgress: p.inProgress
|
|
6691
|
+
};
|
|
6692
|
+
}
|
|
6693
|
+
};
|
|
6553
6694
|
var testTool = {
|
|
6554
6695
|
name: "test",
|
|
6555
6696
|
category: "Code Quality",
|
|
@@ -7371,6 +7512,7 @@ var builtinTools = [
|
|
|
7371
7512
|
searchTool,
|
|
7372
7513
|
todoTool,
|
|
7373
7514
|
planTool,
|
|
7515
|
+
taskTool,
|
|
7374
7516
|
gitTool,
|
|
7375
7517
|
patchTool,
|
|
7376
7518
|
jsonTool,
|