@zhijiewang/openharness 2.5.0 → 2.8.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.
@@ -0,0 +1,78 @@
1
+ import * as fs from "node:fs/promises";
2
+ import * as path from "node:path";
3
+ import { z } from "zod";
4
+ const todoSchema = z.object({
5
+ id: z.string(),
6
+ content: z.string(),
7
+ status: z.enum(["pending", "in_progress", "completed"]).default("pending"),
8
+ priority: z.enum(["high", "medium", "low"]).optional(),
9
+ });
10
+ const inputSchema = z.object({
11
+ todos: z.array(todoSchema).describe("List of todo items to write. Existing items with matching IDs are updated."),
12
+ });
13
+ export const TodoWriteTool = {
14
+ name: "TodoWrite",
15
+ description: "Write or update todo items. Creates new items or updates existing ones by ID.",
16
+ inputSchema,
17
+ riskLevel: "low",
18
+ isReadOnly() {
19
+ return false;
20
+ },
21
+ isConcurrencySafe() {
22
+ return false;
23
+ },
24
+ async call(input, context) {
25
+ const dir = path.join(context.workingDir, ".oh");
26
+ const filePath = path.join(dir, "todos.json");
27
+ try {
28
+ await fs.mkdir(dir, { recursive: true });
29
+ let existing = [];
30
+ try {
31
+ const content = await fs.readFile(filePath, "utf-8");
32
+ existing = JSON.parse(content);
33
+ }
34
+ catch {
35
+ // File doesn't exist yet
36
+ }
37
+ const existingMap = new Map(existing.map((t) => [t.id, t]));
38
+ const now = Date.now();
39
+ let created = 0;
40
+ let updated = 0;
41
+ for (const item of input.todos) {
42
+ const prev = existingMap.get(item.id);
43
+ if (prev) {
44
+ existingMap.set(item.id, { ...prev, ...item, updatedAt: now });
45
+ updated++;
46
+ }
47
+ else {
48
+ existingMap.set(item.id, { ...item, createdAt: now, updatedAt: now });
49
+ created++;
50
+ }
51
+ }
52
+ const todos = [...existingMap.values()];
53
+ await fs.writeFile(filePath, JSON.stringify(todos, null, 2), "utf-8");
54
+ const parts = [];
55
+ if (created > 0)
56
+ parts.push(`${created} created`);
57
+ if (updated > 0)
58
+ parts.push(`${updated} updated`);
59
+ const total = todos.filter((t) => t.status !== "completed").length;
60
+ return {
61
+ output: `Todos: ${parts.join(", ")}. ${total} remaining (${todos.length} total).`,
62
+ isError: false,
63
+ };
64
+ }
65
+ catch (err) {
66
+ return { output: `Error writing todos: ${err.message}`, isError: true };
67
+ }
68
+ },
69
+ prompt() {
70
+ return `Write or update todo items in .oh/todos.json. Each item has:
71
+ - id (string, required): Unique identifier for the todo.
72
+ - content (string, required): Description of what needs to be done.
73
+ - status ("pending" | "in_progress" | "completed"): Current status. Default: "pending".
74
+ - priority ("high" | "medium" | "low", optional): Priority level.
75
+ Items with matching IDs are updated; new IDs create new items.`;
76
+ },
77
+ };
78
+ //# sourceMappingURL=index.js.map
package/dist/tools.js CHANGED
@@ -43,6 +43,7 @@ import { TaskListTool } from "./tools/TaskListTool/index.js";
43
43
  import { TaskOutputTool } from "./tools/TaskOutputTool/index.js";
44
44
  import { TaskStopTool } from "./tools/TaskStopTool/index.js";
45
45
  import { TaskUpdateTool } from "./tools/TaskUpdateTool/index.js";
46
+ import { TodoWriteTool } from "./tools/TodoWriteTool/index.js";
46
47
  import { ToolSearchTool } from "./tools/ToolSearchTool/index.js";
47
48
  import { WebFetchTool } from "./tools/WebFetchTool/index.js";
48
49
  import { WebSearchTool } from "./tools/WebSearchTool/index.js";
@@ -104,6 +105,7 @@ export function getAllTools() {
104
105
  MonitorTool,
105
106
  ScheduleWakeupTool,
106
107
  SessionSearchTool,
108
+ TodoWriteTool,
107
109
  ];
108
110
  return [...core, ...extended.map((t) => new DeferredTool(t))];
109
111
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhijiewang/openharness",
3
- "version": "2.5.0",
3
+ "version": "2.8.0",
4
4
  "description": "Open-source terminal coding agent. Works with any LLM.",
5
5
  "type": "module",
6
6
  "bin": {