@zhijiewang/openharness 0.1.2 → 0.2.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.
Files changed (113) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +27 -0
  2. package/.github/ISSUE_TEMPLATE/feature_request.md +17 -0
  3. package/.github/pull_request_template.md +24 -0
  4. package/CODE_OF_CONDUCT.md +43 -0
  5. package/README.md +160 -156
  6. package/SECURITY.md +21 -0
  7. package/dist/commands/index.d.ts +37 -0
  8. package/dist/commands/index.d.ts.map +1 -0
  9. package/dist/commands/index.js +189 -0
  10. package/dist/commands/index.js.map +1 -0
  11. package/dist/components/App.d.ts.map +1 -1
  12. package/dist/components/App.js +3 -2
  13. package/dist/components/App.js.map +1 -1
  14. package/dist/components/ErrorBoundary.d.ts +17 -0
  15. package/dist/components/ErrorBoundary.d.ts.map +1 -0
  16. package/dist/components/ErrorBoundary.js +19 -0
  17. package/dist/components/ErrorBoundary.js.map +1 -0
  18. package/dist/components/Markdown.d.ts.map +1 -1
  19. package/dist/components/Markdown.js +70 -18
  20. package/dist/components/Markdown.js.map +1 -1
  21. package/dist/components/Messages.d.ts.map +1 -1
  22. package/dist/components/Messages.js +10 -4
  23. package/dist/components/Messages.js.map +1 -1
  24. package/dist/components/PermissionPrompt.d.ts.map +1 -1
  25. package/dist/components/PermissionPrompt.js +25 -7
  26. package/dist/components/PermissionPrompt.js.map +1 -1
  27. package/dist/components/REPL.d.ts.map +1 -1
  28. package/dist/components/REPL.js +60 -6
  29. package/dist/components/REPL.js.map +1 -1
  30. package/dist/components/Spinner.d.ts +3 -2
  31. package/dist/components/Spinner.d.ts.map +1 -1
  32. package/dist/components/Spinner.js +22 -4
  33. package/dist/components/Spinner.js.map +1 -1
  34. package/dist/components/TextInput.d.ts.map +1 -1
  35. package/dist/components/TextInput.js +4 -1
  36. package/dist/components/TextInput.js.map +1 -1
  37. package/dist/git/index.d.ts +47 -0
  38. package/dist/git/index.d.ts.map +1 -0
  39. package/dist/git/index.js +151 -0
  40. package/dist/git/index.js.map +1 -0
  41. package/dist/harness/session.d.ts.map +1 -1
  42. package/dist/harness/session.js +2 -1
  43. package/dist/harness/session.js.map +1 -1
  44. package/dist/main.js +88 -2
  45. package/dist/main.js.map +1 -1
  46. package/dist/providers/openai.js +11 -1
  47. package/dist/providers/openai.js.map +1 -1
  48. package/dist/providers/openrouter.js +11 -1
  49. package/dist/providers/openrouter.js.map +1 -1
  50. package/dist/query.d.ts +15 -11
  51. package/dist/query.d.ts.map +1 -1
  52. package/dist/query.js +196 -80
  53. package/dist/query.js.map +1 -1
  54. package/dist/services/StreamingToolExecutor.d.ts +25 -0
  55. package/dist/services/StreamingToolExecutor.d.ts.map +1 -0
  56. package/dist/services/StreamingToolExecutor.js +107 -0
  57. package/dist/services/StreamingToolExecutor.js.map +1 -0
  58. package/dist/tools/AgentTool/index.d.ts +15 -0
  59. package/dist/tools/AgentTool/index.d.ts.map +1 -0
  60. package/dist/tools/AgentTool/index.js +30 -0
  61. package/dist/tools/AgentTool/index.js.map +1 -0
  62. package/dist/tools/AskUserTool/index.d.ts +15 -0
  63. package/dist/tools/AskUserTool/index.d.ts.map +1 -0
  64. package/dist/tools/AskUserTool/index.js +30 -0
  65. package/dist/tools/AskUserTool/index.js.map +1 -0
  66. package/dist/tools/EnterPlanModeTool/index.d.ts +6 -0
  67. package/dist/tools/EnterPlanModeTool/index.d.ts.map +1 -0
  68. package/dist/tools/EnterPlanModeTool/index.js +37 -0
  69. package/dist/tools/EnterPlanModeTool/index.js.map +1 -0
  70. package/dist/tools/ExitPlanModeTool/index.d.ts +6 -0
  71. package/dist/tools/ExitPlanModeTool/index.d.ts.map +1 -0
  72. package/dist/tools/ExitPlanModeTool/index.js +21 -0
  73. package/dist/tools/ExitPlanModeTool/index.js.map +1 -0
  74. package/dist/tools/NotebookEditTool/index.d.ts +18 -0
  75. package/dist/tools/NotebookEditTool/index.d.ts.map +1 -0
  76. package/dist/tools/NotebookEditTool/index.js +61 -0
  77. package/dist/tools/NotebookEditTool/index.js.map +1 -0
  78. package/dist/tools/SkillTool/index.d.ts +15 -0
  79. package/dist/tools/SkillTool/index.d.ts.map +1 -0
  80. package/dist/tools/SkillTool/index.js +49 -0
  81. package/dist/tools/SkillTool/index.js.map +1 -0
  82. package/dist/tools/TaskCreateTool/index.d.ts +15 -0
  83. package/dist/tools/TaskCreateTool/index.d.ts.map +1 -0
  84. package/dist/tools/TaskCreateTool/index.js +54 -0
  85. package/dist/tools/TaskCreateTool/index.js.map +1 -0
  86. package/dist/tools/TaskListTool/index.d.ts +6 -0
  87. package/dist/tools/TaskListTool/index.d.ts.map +1 -0
  88. package/dist/tools/TaskListTool/index.js +40 -0
  89. package/dist/tools/TaskListTool/index.js.map +1 -0
  90. package/dist/tools/TaskUpdateTool/index.d.ts +18 -0
  91. package/dist/tools/TaskUpdateTool/index.d.ts.map +1 -0
  92. package/dist/tools/TaskUpdateTool/index.js +50 -0
  93. package/dist/tools/TaskUpdateTool/index.js.map +1 -0
  94. package/dist/tools/WebSearchTool/index.d.ts +15 -0
  95. package/dist/tools/WebSearchTool/index.d.ts.map +1 -0
  96. package/dist/tools/WebSearchTool/index.js +76 -0
  97. package/dist/tools/WebSearchTool/index.js.map +1 -0
  98. package/dist/tools.d.ts.map +1 -1
  99. package/dist/tools.js +27 -0
  100. package/dist/tools.js.map +1 -1
  101. package/dist/utils/retry.d.ts +10 -0
  102. package/dist/utils/retry.d.ts.map +1 -0
  103. package/dist/utils/retry.js +23 -0
  104. package/dist/utils/retry.js.map +1 -0
  105. package/dist/utils/theme.d.ts +27 -0
  106. package/dist/utils/theme.d.ts.map +1 -0
  107. package/dist/utils/theme.js +45 -0
  108. package/dist/utils/theme.js.map +1 -0
  109. package/dist/utils/tokens.d.ts +18 -0
  110. package/dist/utils/tokens.d.ts.map +1 -0
  111. package/dist/utils/tokens.js +57 -0
  112. package/dist/utils/tokens.js.map +1 -0
  113. package/package.json +61 -57
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Tool execution during LLM streaming — mirrors Claude Code's concurrent
3
+ * tool execution pattern with permission checks and queue management.
4
+ */
5
+ import type { ToolCall } from "../types/message.js";
6
+ import type { ToolResult, ToolContext, Tools } from "../Tool.js";
7
+ import type { PermissionMode, AskUserFn } from "../types/permissions.js";
8
+ export declare class StreamingToolExecutor {
9
+ private tools;
10
+ private context;
11
+ private permissionMode;
12
+ private askUser?;
13
+ private tracked;
14
+ constructor(tools: Tools, context: ToolContext, permissionMode: PermissionMode, askUser?: AskUserFn | undefined);
15
+ addTool(toolCall: ToolCall): void;
16
+ private processQueue;
17
+ private executeTool;
18
+ getCompletedResults(): Generator<{
19
+ toolCall: ToolCall;
20
+ result: ToolResult;
21
+ }>;
22
+ waitForAll(): Promise<void>;
23
+ get pendingCount(): number;
24
+ }
25
+ //# sourceMappingURL=StreamingToolExecutor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StreamingToolExecutor.d.ts","sourceRoot":"","sources":["../../src/services/StreamingToolExecutor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAQ,UAAU,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEvE,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAgBzE,qBAAa,qBAAqB;IAI9B,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,OAAO,CAAC;IANlB,OAAO,CAAC,OAAO,CAAqB;gBAG1B,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,WAAW,EACpB,cAAc,EAAE,cAAc,EAC9B,OAAO,CAAC,EAAE,SAAS,YAAA;IAG7B,OAAO,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAYjC,OAAO,CAAC,YAAY;YAeN,WAAW;IAoDxB,mBAAmB,IAAI,SAAS,CAAC;QAAE,QAAQ,EAAE,QAAQ,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE,CAAC;IAWvE,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjC,IAAI,YAAY,IAAI,MAAM,CAEzB;CACF"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Tool execution during LLM streaming — mirrors Claude Code's concurrent
3
+ * tool execution pattern with permission checks and queue management.
4
+ */
5
+ import { findToolByName } from "../Tool.js";
6
+ import { checkPermission } from "../types/permissions.js";
7
+ const MAX_CONCURRENCY = 10;
8
+ export class StreamingToolExecutor {
9
+ tools;
10
+ context;
11
+ permissionMode;
12
+ askUser;
13
+ tracked = [];
14
+ constructor(tools, context, permissionMode, askUser) {
15
+ this.tools = tools;
16
+ this.context = context;
17
+ this.permissionMode = permissionMode;
18
+ this.askUser = askUser;
19
+ }
20
+ addTool(toolCall) {
21
+ const tool = findToolByName(this.tools, toolCall.toolName);
22
+ const isSafe = tool ? tool.isConcurrencySafe(toolCall.arguments) : false;
23
+ this.tracked.push({
24
+ id: toolCall.id,
25
+ toolCall,
26
+ status: "queued",
27
+ isConcurrencySafe: isSafe,
28
+ });
29
+ this.processQueue();
30
+ }
31
+ processQueue() {
32
+ const executing = this.tracked.filter((t) => t.status === "executing");
33
+ for (const tool of this.tracked) {
34
+ if (tool.status !== "queued")
35
+ continue;
36
+ if (executing.length >= MAX_CONCURRENCY)
37
+ break;
38
+ if (executing.length > 0 && !tool.isConcurrencySafe)
39
+ break;
40
+ if (executing.length > 0 && executing.some((e) => !e.isConcurrencySafe))
41
+ break;
42
+ tool.status = "executing";
43
+ tool.promise = this.executeTool(tool);
44
+ executing.push(tool);
45
+ }
46
+ }
47
+ async executeTool(tracked) {
48
+ const tool = findToolByName(this.tools, tracked.toolCall.toolName);
49
+ if (!tool) {
50
+ tracked.result = { output: `Unknown tool: ${tracked.toolCall.toolName}`, isError: true };
51
+ tracked.status = "completed";
52
+ return;
53
+ }
54
+ // Permission check
55
+ const perm = checkPermission(this.permissionMode, tool.riskLevel, tool.isReadOnly(tracked.toolCall.arguments));
56
+ if (!perm.allowed && perm.reason === "needs-approval" && this.askUser) {
57
+ const allowed = await this.askUser(tool.name, JSON.stringify(tracked.toolCall.arguments).slice(0, 200));
58
+ if (!allowed) {
59
+ tracked.result = { output: "Permission denied.", isError: true };
60
+ tracked.status = "completed";
61
+ return;
62
+ }
63
+ }
64
+ else if (!perm.allowed) {
65
+ tracked.result = { output: `Denied: ${perm.reason}`, isError: true };
66
+ tracked.status = "completed";
67
+ return;
68
+ }
69
+ // Validate input
70
+ const parsed = tool.inputSchema.safeParse(tracked.toolCall.arguments);
71
+ if (!parsed.success) {
72
+ tracked.result = { output: `Validation: ${parsed.error.message}`, isError: true };
73
+ tracked.status = "completed";
74
+ return;
75
+ }
76
+ // Execute
77
+ try {
78
+ tracked.result = await tool.call(parsed.data, this.context);
79
+ }
80
+ catch (err) {
81
+ tracked.result = {
82
+ output: `Error: ${err instanceof Error ? err.message : String(err)}`,
83
+ isError: true,
84
+ };
85
+ }
86
+ tracked.status = "completed";
87
+ this.processQueue(); // Process next queued tools
88
+ }
89
+ *getCompletedResults() {
90
+ for (const t of this.tracked) {
91
+ if (t.status === "completed" && t.result) {
92
+ t.status = "yielded";
93
+ yield { toolCall: t.toolCall, result: t.result };
94
+ }
95
+ else if (t.status === "executing" && !t.isConcurrencySafe) {
96
+ break; // Don't skip past non-concurrent executing tools
97
+ }
98
+ }
99
+ }
100
+ async waitForAll() {
101
+ await Promise.all(this.tracked.filter((t) => t.promise).map((t) => t.promise));
102
+ }
103
+ get pendingCount() {
104
+ return this.tracked.filter((t) => t.status === "queued" || t.status === "executing").length;
105
+ }
106
+ }
107
+ //# sourceMappingURL=StreamingToolExecutor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StreamingToolExecutor.js","sourceRoot":"","sources":["../../src/services/StreamingToolExecutor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { z } from "zod";
2
+ import type { Tool } from "../../Tool.js";
3
+ declare const inputSchema: z.ZodObject<{
4
+ prompt: z.ZodString;
5
+ description: z.ZodOptional<z.ZodString>;
6
+ }, "strip", z.ZodTypeAny, {
7
+ prompt: string;
8
+ description?: string | undefined;
9
+ }, {
10
+ prompt: string;
11
+ description?: string | undefined;
12
+ }>;
13
+ export declare const AgentTool: Tool<typeof inputSchema>;
14
+ export {};
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/AgentTool/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,eAAe,CAAC;AAEnE,QAAA,MAAM,WAAW;;;;;;;;;EAGf,CAAC;AAEH,eAAO,MAAM,SAAS,EAAE,IAAI,CAAC,OAAO,WAAW,CA2B9C,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { z } from "zod";
2
+ const inputSchema = z.object({
3
+ prompt: z.string(),
4
+ description: z.string().optional(),
5
+ });
6
+ export const AgentTool = {
7
+ name: "Agent",
8
+ description: "Spawn a sub-agent to handle a task (stub).",
9
+ inputSchema,
10
+ riskLevel: "medium",
11
+ isReadOnly() {
12
+ return false;
13
+ },
14
+ isConcurrencySafe() {
15
+ return false;
16
+ },
17
+ async call(input, _context) {
18
+ return {
19
+ output: `Sub-agent spawning not yet implemented. Handle this task directly instead of delegating. Prompt was: ${input.prompt}`,
20
+ isError: true,
21
+ };
22
+ },
23
+ prompt() {
24
+ return `Spawn a sub-agent to handle a delegated task. Parameters:
25
+ - prompt (string, required): The prompt/instructions for the sub-agent.
26
+ - description (string, optional): A short description of what the sub-agent should do.
27
+ Note: This is currently a stub and will be implemented later.`;
28
+ },
29
+ };
30
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/AgentTool/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACnC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,SAAS,GAA6B;IACjD,IAAI,EAAE,OAAO;IACb,WAAW,EAAE,4CAA4C;IACzD,WAAW;IACX,SAAS,EAAE,QAAQ;IAEnB,UAAU;QACR,OAAO,KAAK,CAAC;IACf,CAAC;IAED,iBAAiB;QACf,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ;QACxB,OAAO;YACL,MAAM,EAAE,wGAAwG,KAAK,CAAC,MAAM,EAAE;YAC9H,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IAED,MAAM;QACJ,OAAO;;;8DAGmD,CAAC;IAC7D,CAAC;CACF,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { z } from "zod";
2
+ import type { Tool } from "../../Tool.js";
3
+ declare const inputSchema: z.ZodObject<{
4
+ question: z.ZodString;
5
+ options: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
6
+ }, "strip", z.ZodTypeAny, {
7
+ question: string;
8
+ options?: string[] | undefined;
9
+ }, {
10
+ question: string;
11
+ options?: string[] | undefined;
12
+ }>;
13
+ export declare const AskUserTool: Tool<typeof inputSchema>;
14
+ export {};
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/AskUserTool/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,eAAe,CAAC;AAEnE,QAAA,MAAM,WAAW;;;;;;;;;EAGf,CAAC;AAEH,eAAO,MAAM,WAAW,EAAE,IAAI,CAAC,OAAO,WAAW,CA2BhD,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { z } from "zod";
2
+ const inputSchema = z.object({
3
+ question: z.string(),
4
+ options: z.array(z.string()).optional(),
5
+ });
6
+ export const AskUserTool = {
7
+ name: "AskUser",
8
+ description: "Ask the user a question. The REPL will display it as a prompt.",
9
+ inputSchema,
10
+ riskLevel: "low",
11
+ isReadOnly() {
12
+ return true;
13
+ },
14
+ isConcurrencySafe() {
15
+ return false;
16
+ },
17
+ async call(input, _context) {
18
+ let output = `[Question] ${input.question}`;
19
+ if (input.options && input.options.length > 0) {
20
+ output += "\nOptions:\n" + input.options.map((o, i) => ` ${i + 1}. ${o}`).join("\n");
21
+ }
22
+ return { output, isError: false };
23
+ },
24
+ prompt() {
25
+ return `Ask the user a question. This is a signal to the UI to prompt the user. Parameters:
26
+ - question (string, required): The question to ask.
27
+ - options (string[], optional): List of options to present.`;
28
+ },
29
+ };
30
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/AskUserTool/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;CACxC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,WAAW,GAA6B;IACnD,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,gEAAgE;IAC7E,WAAW;IACX,SAAS,EAAE,KAAK;IAEhB,UAAU;QACR,OAAO,IAAI,CAAC;IACd,CAAC;IAED,iBAAiB;QACf,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ;QACxB,IAAI,MAAM,GAAG,cAAc,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC5C,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9C,MAAM,IAAI,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxF,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IACpC,CAAC;IAED,MAAM;QACJ,OAAO;;4DAEiD,CAAC;IAC3D,CAAC;CACF,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { z } from "zod";
2
+ import type { Tool } from "../../Tool.js";
3
+ declare const inputSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
4
+ export declare const EnterPlanModeTool: Tool<typeof inputSchema>;
5
+ export {};
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/EnterPlanModeTool/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,eAAe,CAAC;AAEnE,QAAA,MAAM,WAAW,gDAAe,CAAC;AAEjC,eAAO,MAAM,iBAAiB,EAAE,IAAI,CAAC,OAAO,WAAW,CAoCtD,CAAC"}
@@ -0,0 +1,37 @@
1
+ import { z } from "zod";
2
+ import * as fs from "fs/promises";
3
+ import * as path from "path";
4
+ const inputSchema = z.object({});
5
+ export const EnterPlanModeTool = {
6
+ name: "EnterPlanMode",
7
+ description: "Enter plan mode, creating .oh/plan.md if it does not exist.",
8
+ inputSchema,
9
+ riskLevel: "low",
10
+ isReadOnly() {
11
+ return false;
12
+ },
13
+ isConcurrencySafe() {
14
+ return false;
15
+ },
16
+ async call(_input, context) {
17
+ const dir = path.join(context.workingDir, ".oh");
18
+ const filePath = path.join(dir, "plan.md");
19
+ try {
20
+ await fs.mkdir(dir, { recursive: true });
21
+ try {
22
+ await fs.access(filePath);
23
+ }
24
+ catch {
25
+ await fs.writeFile(filePath, "# Plan\n\n", "utf-8");
26
+ }
27
+ return { output: "Plan mode entered.", isError: false };
28
+ }
29
+ catch (err) {
30
+ return { output: `Error entering plan mode: ${err.message}`, isError: true };
31
+ }
32
+ },
33
+ prompt() {
34
+ return `Enter plan mode. Creates .oh/plan.md if it does not already exist. No parameters required.`;
35
+ },
36
+ };
37
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/EnterPlanModeTool/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAG7B,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAEjC,MAAM,CAAC,MAAM,iBAAiB,GAA6B;IACzD,IAAI,EAAE,eAAe;IACrB,WAAW,EAAE,6DAA6D;IAC1E,WAAW;IACX,SAAS,EAAE,KAAK;IAEhB,UAAU;QACR,OAAO,KAAK,CAAC;IACf,CAAC;IAED,iBAAiB;QACf,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO;QACxB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAE3C,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAEzC,IAAI,CAAC;gBACH,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC5B,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;YACtD,CAAC;YAED,OAAO,EAAE,MAAM,EAAE,oBAAoB,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC1D,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,OAAO,EAAE,MAAM,EAAE,6BAA6B,GAAG,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC/E,CAAC;IACH,CAAC;IAED,MAAM;QACJ,OAAO,4FAA4F,CAAC;IACtG,CAAC;CACF,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { z } from "zod";
2
+ import type { Tool } from "../../Tool.js";
3
+ declare const inputSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
4
+ export declare const ExitPlanModeTool: Tool<typeof inputSchema>;
5
+ export {};
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/ExitPlanModeTool/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,eAAe,CAAC;AAEnE,QAAA,MAAM,WAAW,gDAAe,CAAC;AAEjC,eAAO,MAAM,gBAAgB,EAAE,IAAI,CAAC,OAAO,WAAW,CAqBrD,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { z } from "zod";
2
+ const inputSchema = z.object({});
3
+ export const ExitPlanModeTool = {
4
+ name: "ExitPlanMode",
5
+ description: "Exit plan mode.",
6
+ inputSchema,
7
+ riskLevel: "low",
8
+ isReadOnly() {
9
+ return false;
10
+ },
11
+ isConcurrencySafe() {
12
+ return false;
13
+ },
14
+ async call(_input, _context) {
15
+ return { output: "Plan mode exited.", isError: false };
16
+ },
17
+ prompt() {
18
+ return `Exit plan mode. No parameters required.`;
19
+ },
20
+ };
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/ExitPlanModeTool/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAEjC,MAAM,CAAC,MAAM,gBAAgB,GAA6B;IACxD,IAAI,EAAE,cAAc;IACpB,WAAW,EAAE,iBAAiB;IAC9B,WAAW;IACX,SAAS,EAAE,KAAK;IAEhB,UAAU;QACR,OAAO,KAAK,CAAC;IACf,CAAC;IAED,iBAAiB;QACf,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ;QACzB,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IACzD,CAAC;IAED,MAAM;QACJ,OAAO,yCAAyC,CAAC;IACnD,CAAC;CACF,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { z } from "zod";
2
+ import type { Tool } from "../../Tool.js";
3
+ declare const inputSchema: z.ZodObject<{
4
+ notebook_path: z.ZodString;
5
+ cell_index: z.ZodNumber;
6
+ new_source: z.ZodString;
7
+ }, "strip", z.ZodTypeAny, {
8
+ notebook_path: string;
9
+ cell_index: number;
10
+ new_source: string;
11
+ }, {
12
+ notebook_path: string;
13
+ cell_index: number;
14
+ new_source: string;
15
+ }>;
16
+ export declare const NotebookEditTool: Tool<typeof inputSchema>;
17
+ export {};
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/NotebookEditTool/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,eAAe,CAAC;AAEnE,QAAA,MAAM,WAAW;;;;;;;;;;;;EAIf,CAAC;AAEH,eAAO,MAAM,gBAAgB,EAAE,IAAI,CAAC,OAAO,WAAW,CA8DrD,CAAC"}
@@ -0,0 +1,61 @@
1
+ import { z } from "zod";
2
+ import * as fs from "fs/promises";
3
+ import * as path from "path";
4
+ const inputSchema = z.object({
5
+ notebook_path: z.string(),
6
+ cell_index: z.number(),
7
+ new_source: z.string(),
8
+ });
9
+ export const NotebookEditTool = {
10
+ name: "NotebookEdit",
11
+ description: "Edit a cell in a Jupyter notebook (.ipynb) file.",
12
+ inputSchema,
13
+ riskLevel: "medium",
14
+ isReadOnly() {
15
+ return false;
16
+ },
17
+ isConcurrencySafe() {
18
+ return false;
19
+ },
20
+ async call(input, context) {
21
+ const filePath = path.resolve(context.workingDir, input.notebook_path);
22
+ // Path containment — must stay within working directory
23
+ if (!filePath.startsWith(path.resolve(context.workingDir))) {
24
+ return { output: "Error: Path must be within the working directory.", isError: true };
25
+ }
26
+ try {
27
+ const content = await fs.readFile(filePath, "utf-8");
28
+ const notebook = JSON.parse(content);
29
+ if (!notebook.cells || !Array.isArray(notebook.cells)) {
30
+ return { output: "Error: Invalid notebook format — no cells array.", isError: true };
31
+ }
32
+ if (input.cell_index < 0 || input.cell_index >= notebook.cells.length) {
33
+ return {
34
+ output: `Error: Cell index ${input.cell_index} out of range (0-${notebook.cells.length - 1}).`,
35
+ isError: true,
36
+ };
37
+ }
38
+ // Notebook cell source is an array of lines
39
+ const lines = input.new_source.split("\n").map((line, i, arr) => i < arr.length - 1 ? line + "\n" : line);
40
+ notebook.cells[input.cell_index].source = lines;
41
+ await fs.writeFile(filePath, JSON.stringify(notebook, null, 1), "utf-8");
42
+ return {
43
+ output: `Cell ${input.cell_index} updated in ${filePath}.`,
44
+ isError: false,
45
+ };
46
+ }
47
+ catch (err) {
48
+ if (err.code === "ENOENT") {
49
+ return { output: `Error: Notebook not found: ${filePath}`, isError: true };
50
+ }
51
+ return { output: `Error editing notebook: ${err.message}`, isError: true };
52
+ }
53
+ },
54
+ prompt() {
55
+ return `Edit a cell in a Jupyter notebook (.ipynb). Parameters:
56
+ - notebook_path (string, required): Path to the .ipynb file.
57
+ - cell_index (number, required): Zero-based index of the cell to edit.
58
+ - new_source (string, required): The new source code for the cell.`;
59
+ },
60
+ };
61
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/NotebookEditTool/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { z } from "zod";
2
+ import type { Tool } from "../../Tool.js";
3
+ declare const inputSchema: z.ZodObject<{
4
+ skill: z.ZodString;
5
+ args: z.ZodOptional<z.ZodString>;
6
+ }, "strip", z.ZodTypeAny, {
7
+ skill: string;
8
+ args?: string | undefined;
9
+ }, {
10
+ skill: string;
11
+ args?: string | undefined;
12
+ }>;
13
+ export declare const SkillTool: Tool<typeof inputSchema>;
14
+ export {};
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/SkillTool/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,eAAe,CAAC;AAEnE,QAAA,MAAM,WAAW;;;;;;;;;EAGf,CAAC;AAEH,eAAO,MAAM,SAAS,EAAE,IAAI,CAAC,OAAO,WAAW,CA4C9C,CAAC"}
@@ -0,0 +1,49 @@
1
+ import { z } from "zod";
2
+ import * as fs from "fs/promises";
3
+ import * as path from "path";
4
+ const inputSchema = z.object({
5
+ skill: z.string(),
6
+ args: z.string().optional(),
7
+ });
8
+ export const SkillTool = {
9
+ name: "Skill",
10
+ description: "Execute a skill by reading its definition from .oh/skills/.",
11
+ inputSchema,
12
+ riskLevel: "low",
13
+ isReadOnly() {
14
+ return true;
15
+ },
16
+ isConcurrencySafe() {
17
+ return false;
18
+ },
19
+ async call(input, context) {
20
+ // Path traversal protection
21
+ if (input.skill.includes("..") || input.skill.includes("/") || input.skill.includes("\\")) {
22
+ return { output: "Error: Invalid skill name.", isError: true };
23
+ }
24
+ const baseDir = path.join(context.workingDir, ".oh", "skills");
25
+ const filePath = path.join(baseDir, `${input.skill}.md`);
26
+ if (!filePath.startsWith(baseDir)) {
27
+ return { output: "Error: Invalid skill path.", isError: true };
28
+ }
29
+ try {
30
+ const content = await fs.readFile(filePath, "utf-8");
31
+ return { output: content, isError: false };
32
+ }
33
+ catch (err) {
34
+ if (err.code === "ENOENT") {
35
+ return {
36
+ output: `Error: Skill "${input.skill}" not found at ${filePath}`,
37
+ isError: true,
38
+ };
39
+ }
40
+ return { output: `Error reading skill: ${err.message}`, isError: true };
41
+ }
42
+ },
43
+ prompt() {
44
+ return `Execute a skill by loading its definition from .oh/skills/{skill}.md. Parameters:
45
+ - skill (string, required): The skill name (maps to a .md file).
46
+ - args (string, optional): Arguments to pass to the skill.`;
47
+ },
48
+ };
49
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/SkillTool/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAG7B,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC5B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,SAAS,GAA6B;IACjD,IAAI,EAAE,OAAO;IACb,WAAW,EAAE,6DAA6D;IAC1E,WAAW;IACX,SAAS,EAAE,KAAK;IAEhB,UAAU;QACR,OAAO,IAAI,CAAC;IACd,CAAC;IAED,iBAAiB;QACf,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO;QACvB,4BAA4B;QAC5B,IAAI,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1F,OAAO,EAAE,MAAM,EAAE,4BAA4B,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QACjE,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC/D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,KAAK,KAAK,CAAC,CAAC;QACzD,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAClC,OAAO,EAAE,MAAM,EAAE,4BAA4B,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QACjE,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACrD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC7C,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC1B,OAAO;oBACL,MAAM,EAAE,iBAAiB,KAAK,CAAC,KAAK,kBAAkB,QAAQ,EAAE;oBAChE,OAAO,EAAE,IAAI;iBACd,CAAC;YACJ,CAAC;YACD,OAAO,EAAE,MAAM,EAAE,wBAAwB,GAAG,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC1E,CAAC;IACH,CAAC;IAED,MAAM;QACJ,OAAO;;2DAEgD,CAAC;IAC1D,CAAC;CACF,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { z } from "zod";
2
+ import type { Tool } from "../../Tool.js";
3
+ declare const inputSchema: z.ZodObject<{
4
+ subject: z.ZodString;
5
+ description: z.ZodString;
6
+ }, "strip", z.ZodTypeAny, {
7
+ description: string;
8
+ subject: string;
9
+ }, {
10
+ description: string;
11
+ subject: string;
12
+ }>;
13
+ export declare const TaskCreateTool: Tool<typeof inputSchema>;
14
+ export {};
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/TaskCreateTool/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,eAAe,CAAC;AAEnE,QAAA,MAAM,WAAW;;;;;;;;;EAGf,CAAC;AASH,eAAO,MAAM,cAAc,EAAE,IAAI,CAAC,OAAO,WAAW,CAoDnD,CAAC"}
@@ -0,0 +1,54 @@
1
+ import { z } from "zod";
2
+ import * as fs from "fs/promises";
3
+ import * as path from "path";
4
+ const inputSchema = z.object({
5
+ subject: z.string(),
6
+ description: z.string(),
7
+ });
8
+ export const TaskCreateTool = {
9
+ name: "TaskCreate",
10
+ description: "Create a new task and append it to .oh/tasks.json.",
11
+ inputSchema,
12
+ riskLevel: "low",
13
+ isReadOnly() {
14
+ return false;
15
+ },
16
+ isConcurrencySafe() {
17
+ return false; // Mutates shared tasks.json
18
+ },
19
+ async call(input, context) {
20
+ const dir = path.join(context.workingDir, ".oh");
21
+ const filePath = path.join(dir, "tasks.json");
22
+ try {
23
+ await fs.mkdir(dir, { recursive: true });
24
+ let tasks = [];
25
+ try {
26
+ const content = await fs.readFile(filePath, "utf-8");
27
+ tasks = JSON.parse(content);
28
+ }
29
+ catch {
30
+ // File doesn't exist yet
31
+ }
32
+ const maxId = tasks.reduce((max, t) => Math.max(max, t.id), 0);
33
+ const newTask = {
34
+ id: maxId + 1,
35
+ subject: input.subject,
36
+ description: input.description,
37
+ status: "pending",
38
+ };
39
+ tasks.push(newTask);
40
+ await fs.writeFile(filePath, JSON.stringify(tasks, null, 2), "utf-8");
41
+ return { output: `Task #${newTask.id} created: ${newTask.subject}`, isError: false };
42
+ }
43
+ catch (err) {
44
+ return { output: `Error creating task: ${err.message}`, isError: true };
45
+ }
46
+ },
47
+ prompt() {
48
+ return `Create a new task in .oh/tasks.json. Parameters:
49
+ - subject (string, required): Short title for the task.
50
+ - description (string, required): Detailed description of the task.
51
+ Each task gets an auto-incremented ID and starts with status "pending".`;
52
+ },
53
+ };
54
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/TaskCreateTool/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAG7B,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;CACxB,CAAC,CAAC;AASH,MAAM,CAAC,MAAM,cAAc,GAA6B;IACtD,IAAI,EAAE,YAAY;IAClB,WAAW,EAAE,oDAAoD;IACjE,WAAW;IACX,SAAS,EAAE,KAAK;IAEhB,UAAU;QACR,OAAO,KAAK,CAAC;IACf,CAAC;IAED,iBAAiB;QACf,OAAO,KAAK,CAAC,CAAC,4BAA4B;IAC5C,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO;QACvB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;QAE9C,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAEzC,IAAI,KAAK,GAAW,EAAE,CAAC;YACvB,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBACrD,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC9B,CAAC;YAAC,MAAM,CAAC;gBACP,yBAAyB;YAC3B,CAAC;YAED,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YAC/D,MAAM,OAAO,GAAS;gBACpB,EAAE,EAAE,KAAK,GAAG,CAAC;gBACb,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,MAAM,EAAE,SAAS;aAClB,CAAC;YAEF,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACpB,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YAEtE,OAAO,EAAE,MAAM,EAAE,SAAS,OAAO,CAAC,EAAE,aAAa,OAAO,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QACvF,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,OAAO,EAAE,MAAM,EAAE,wBAAwB,GAAG,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC1E,CAAC;IACH,CAAC;IAED,MAAM;QACJ,OAAO;;;wEAG6D,CAAC;IACvE,CAAC;CACF,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { z } from "zod";
2
+ import type { Tool } from "../../Tool.js";
3
+ declare const inputSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
4
+ export declare const TaskListTool: Tool<typeof inputSchema>;
5
+ export {};
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/TaskListTool/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,eAAe,CAAC;AAEnE,QAAA,MAAM,WAAW,gDAAe,CAAC;AASjC,eAAO,MAAM,YAAY,EAAE,IAAI,CAAC,OAAO,WAAW,CAyCjD,CAAC"}