@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/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as fs4 from 'node:fs/promises';
2
2
  import * as Core from '@wrongstack/core';
3
- import { atomicWrite, unifiedDiff, detectNewlineStyle, normalizeToLf, toStyle, compileGlob, expectDefined, buildChildEnv, loadPlan, emptyPlan, clearPlan, savePlan, getPlanTemplate, addPlanItem, deriveTodosFromPlanItem, removePlanItem, setPlanItemStatus, formatPlan, resolveWstackPaths } from '@wrongstack/core';
3
+ import { atomicWrite, unifiedDiff, detectNewlineStyle, normalizeToLf, toStyle, compileGlob, expectDefined, buildChildEnv, loadPlan, emptyPlan, clearPlan, savePlan, getPlanTemplate, addPlanItem, deriveTodosFromPlanItem, removePlanItem, setPlanItemStatus, formatPlan, loadTasks, emptyTaskFile, saveTasks, computeTaskItemProgress, formatTaskList, resolveWstackPaths } from '@wrongstack/core';
4
4
  import * as path from 'node:path';
5
5
  import { resolve, sep, dirname } from 'node:path';
6
6
  import { spawn, execFileSync, spawnSync } from 'node:child_process';
@@ -7713,6 +7713,147 @@ var codebaseStatsTool = {
7713
7713
  }
7714
7714
  }
7715
7715
  };
7716
+ var taskTool = {
7717
+ name: "task",
7718
+ category: "Session",
7719
+ 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.",
7720
+ 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',
7721
+ permission: "auto",
7722
+ mutating: false,
7723
+ timeoutMs: 2e3,
7724
+ inputSchema: {
7725
+ type: "object",
7726
+ properties: {
7727
+ action: {
7728
+ type: "string",
7729
+ enum: ["replace", "add", "status", "show"],
7730
+ description: "replace = set full list, add = append, status = update task status, show = view only."
7731
+ },
7732
+ tasks: {
7733
+ type: "array",
7734
+ items: {
7735
+ type: "object",
7736
+ properties: {
7737
+ id: { type: "string", description: 'Unique id (e.g. "t1", "auth-flow").' },
7738
+ title: { type: "string", description: "Short title." },
7739
+ description: { type: "string", description: "Optional details." },
7740
+ type: { type: "string", enum: ["feature", "bugfix", "refactor", "docs", "test", "chore"] },
7741
+ priority: { type: "string", enum: ["critical", "high", "medium", "low"] },
7742
+ status: { type: "string", enum: ["pending", "in_progress", "blocked", "failed", "review", "completed"] },
7743
+ dependsOn: {
7744
+ type: "array",
7745
+ items: { type: "string" },
7746
+ description: "IDs of tasks this one depends on."
7747
+ },
7748
+ assignee: { type: "string", description: "Agent/subagent assigned." },
7749
+ estimateHours: { type: "number", description: "Estimated hours." },
7750
+ tags: { type: "array", items: { type: "string" }, description: "Optional tags." },
7751
+ createdAt: { type: "string" },
7752
+ updatedAt: { type: "string" }
7753
+ },
7754
+ required: ["id", "title", "type", "priority", "status"]
7755
+ },
7756
+ description: "Complete task list. Replaces previous list entirely."
7757
+ },
7758
+ task: {
7759
+ type: "object",
7760
+ properties: {
7761
+ title: { type: "string" },
7762
+ description: { type: "string" },
7763
+ type: { type: "string", enum: ["feature", "bugfix", "refactor", "docs", "test", "chore"] },
7764
+ priority: { type: "string", enum: ["critical", "high", "medium", "low"] },
7765
+ status: { type: "string", enum: ["pending", "in_progress", "blocked", "failed", "review", "completed"] },
7766
+ dependsOn: { type: "array", items: { type: "string" } },
7767
+ assignee: { type: "string" },
7768
+ estimateHours: { type: "number" },
7769
+ tags: { type: "array", items: { type: "string" } }
7770
+ },
7771
+ required: ["title", "type", "priority"],
7772
+ description: "Single task to append (id/createdAt/updatedAt auto-generated)."
7773
+ },
7774
+ id: { type: "string", description: "Task id for action=status." },
7775
+ status: {
7776
+ type: "string",
7777
+ enum: ["pending", "in_progress", "blocked", "failed", "review", "completed"],
7778
+ description: "New status for action=status."
7779
+ }
7780
+ },
7781
+ required: ["action"]
7782
+ },
7783
+ async execute(input, ctx) {
7784
+ const taskPath = ctx.meta["task.path"];
7785
+ if (typeof taskPath !== "string" || !taskPath) {
7786
+ return { ok: false, message: "Task storage path not configured.", count: 0, completed: 0, inProgress: 0 };
7787
+ }
7788
+ const sessionId = ctx.session?.id ?? "unknown";
7789
+ let file = await loadTasks(taskPath) ?? emptyTaskFile(sessionId);
7790
+ switch (input.action) {
7791
+ case "show":
7792
+ break;
7793
+ case "replace": {
7794
+ if (!Array.isArray(input.tasks)) {
7795
+ return { ok: false, message: "action=replace requires `tasks` array.", count: 0, completed: 0, inProgress: 0 };
7796
+ }
7797
+ const now = (/* @__PURE__ */ new Date()).toISOString();
7798
+ file.tasks = input.tasks.map((t) => ({
7799
+ ...t,
7800
+ createdAt: t.createdAt || now,
7801
+ updatedAt: now
7802
+ }));
7803
+ await saveTasks(taskPath, file);
7804
+ break;
7805
+ }
7806
+ case "add": {
7807
+ const t = input.task;
7808
+ if (!t || !t.title) {
7809
+ return { ok: false, message: "action=add requires `task` with at least `title`.", count: 0, completed: 0, inProgress: 0 };
7810
+ }
7811
+ const now = (/* @__PURE__ */ new Date()).toISOString();
7812
+ const newTask = {
7813
+ id: `task_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
7814
+ title: t.title,
7815
+ description: t.description,
7816
+ type: t.type || "feature",
7817
+ priority: t.priority || "medium",
7818
+ status: t.status || "pending",
7819
+ dependsOn: t.dependsOn,
7820
+ assignee: t.assignee,
7821
+ estimateHours: t.estimateHours,
7822
+ tags: t.tags,
7823
+ createdAt: now,
7824
+ updatedAt: now
7825
+ };
7826
+ file.tasks.push(newTask);
7827
+ await saveTasks(taskPath, file);
7828
+ break;
7829
+ }
7830
+ case "status": {
7831
+ if (!input.id || !input.status) {
7832
+ return { ok: false, message: "action=status requires `id` and `status`.", count: 0, completed: 0, inProgress: 0 };
7833
+ }
7834
+ const task = file.tasks.find((t) => t.id === input.id);
7835
+ if (!task) {
7836
+ return { ok: false, message: `Task "${input.id}" not found.`, count: 0, completed: 0, inProgress: 0 };
7837
+ }
7838
+ task.status = input.status;
7839
+ task.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
7840
+ await saveTasks(taskPath, file);
7841
+ break;
7842
+ }
7843
+ default:
7844
+ return { ok: false, message: `Unknown action "${input.action}". Use replace | add | status | show.`, count: 0, completed: 0, inProgress: 0 };
7845
+ }
7846
+ const p = computeTaskItemProgress(file.tasks);
7847
+ const summary = file.tasks.length > 0 ? formatTaskList(file.tasks) : "No tasks.";
7848
+ return {
7849
+ ok: true,
7850
+ message: summary,
7851
+ count: file.tasks.length,
7852
+ completed: p.completed,
7853
+ inProgress: p.inProgress
7854
+ };
7855
+ }
7856
+ };
7716
7857
 
7717
7858
  // src/builtin.ts
7718
7859
  var builtinTools = [
@@ -7728,6 +7869,7 @@ var builtinTools = [
7728
7869
  searchTool,
7729
7870
  todoTool,
7730
7871
  planTool,
7872
+ taskTool,
7731
7873
  gitTool,
7732
7874
  patchTool,
7733
7875
  jsonTool,