duocode 0.1.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 (220) hide show
  1. package/.env.example +36 -0
  2. package/LICENSE +21 -0
  3. package/README.md +52 -0
  4. package/dist/ast/context.d.ts +16 -0
  5. package/dist/ast/context.js +37 -0
  6. package/dist/ast/context.js.map +1 -0
  7. package/dist/ast/diff.d.ts +27 -0
  8. package/dist/ast/diff.js +44 -0
  9. package/dist/ast/diff.js.map +1 -0
  10. package/dist/ast/locks.d.ts +47 -0
  11. package/dist/ast/locks.js +88 -0
  12. package/dist/ast/locks.js.map +1 -0
  13. package/dist/ast/merge.d.ts +22 -0
  14. package/dist/ast/merge.js +120 -0
  15. package/dist/ast/merge.js.map +1 -0
  16. package/dist/ast/ownership.d.ts +31 -0
  17. package/dist/ast/ownership.js +111 -0
  18. package/dist/ast/ownership.js.map +1 -0
  19. package/dist/ast/parser.d.ts +44 -0
  20. package/dist/ast/parser.js +134 -0
  21. package/dist/ast/parser.js.map +1 -0
  22. package/dist/cli.d.ts +2 -0
  23. package/dist/cli.js +423 -0
  24. package/dist/cli.js.map +1 -0
  25. package/dist/commands/doctor.d.ts +5 -0
  26. package/dist/commands/doctor.js +63 -0
  27. package/dist/commands/doctor.js.map +1 -0
  28. package/dist/commands/duo.d.ts +9 -0
  29. package/dist/commands/duo.js +285 -0
  30. package/dist/commands/duo.js.map +1 -0
  31. package/dist/commands/github.d.ts +2 -0
  32. package/dist/commands/github.js +85 -0
  33. package/dist/commands/github.js.map +1 -0
  34. package/dist/commands/init.d.ts +2 -0
  35. package/dist/commands/init.js +33 -0
  36. package/dist/commands/init.js.map +1 -0
  37. package/dist/commands/negotiation.d.ts +2 -0
  38. package/dist/commands/negotiation.js +160 -0
  39. package/dist/commands/negotiation.js.map +1 -0
  40. package/dist/commands/repl_commands.d.ts +26 -0
  41. package/dist/commands/repl_commands.js +226 -0
  42. package/dist/commands/repl_commands.js.map +1 -0
  43. package/dist/commands/shell.d.ts +1 -0
  44. package/dist/commands/shell.js +110 -0
  45. package/dist/commands/shell.js.map +1 -0
  46. package/dist/commands/start.d.ts +2 -0
  47. package/dist/commands/start.js +231 -0
  48. package/dist/commands/start.js.map +1 -0
  49. package/dist/commands/task.d.ts +2 -0
  50. package/dist/commands/task.js +215 -0
  51. package/dist/commands/task.js.map +1 -0
  52. package/dist/config/loader.d.ts +193 -0
  53. package/dist/config/loader.js +106 -0
  54. package/dist/config/loader.js.map +1 -0
  55. package/dist/context/project_context.d.ts +79 -0
  56. package/dist/context/project_context.js +292 -0
  57. package/dist/context/project_context.js.map +1 -0
  58. package/dist/context/token_budget.d.ts +35 -0
  59. package/dist/context/token_budget.js +81 -0
  60. package/dist/context/token_budget.js.map +1 -0
  61. package/dist/db/queries.d.ts +121 -0
  62. package/dist/db/queries.js +109 -0
  63. package/dist/db/queries.js.map +1 -0
  64. package/dist/db/schema.d.ts +110 -0
  65. package/dist/db/schema.js +346 -0
  66. package/dist/db/schema.js.map +1 -0
  67. package/dist/duo/duo_orchestrator.d.ts +50 -0
  68. package/dist/duo/duo_orchestrator.js +510 -0
  69. package/dist/duo/duo_orchestrator.js.map +1 -0
  70. package/dist/duo/duo_session.d.ts +47 -0
  71. package/dist/duo/duo_session.js +127 -0
  72. package/dist/duo/duo_session.js.map +1 -0
  73. package/dist/duo/duo_types.d.ts +168 -0
  74. package/dist/duo/duo_types.js +53 -0
  75. package/dist/duo/duo_types.js.map +1 -0
  76. package/dist/duo/session_store.d.ts +71 -0
  77. package/dist/duo/session_store.js +177 -0
  78. package/dist/duo/session_store.js.map +1 -0
  79. package/dist/git/worktree.d.ts +21 -0
  80. package/dist/git/worktree.js +86 -0
  81. package/dist/git/worktree.js.map +1 -0
  82. package/dist/github/cache.d.ts +23 -0
  83. package/dist/github/cache.js +67 -0
  84. package/dist/github/cache.js.map +1 -0
  85. package/dist/github/issues.d.ts +17 -0
  86. package/dist/github/issues.js +93 -0
  87. package/dist/github/issues.js.map +1 -0
  88. package/dist/github/mcp_client.d.ts +57 -0
  89. package/dist/github/mcp_client.js +214 -0
  90. package/dist/github/mcp_client.js.map +1 -0
  91. package/dist/github/sync.d.ts +11 -0
  92. package/dist/github/sync.js +65 -0
  93. package/dist/github/sync.js.map +1 -0
  94. package/dist/github/webhook.d.ts +25 -0
  95. package/dist/github/webhook.js +197 -0
  96. package/dist/github/webhook.js.map +1 -0
  97. package/dist/negotiation/index.d.ts +1 -0
  98. package/dist/negotiation/index.js +2 -0
  99. package/dist/negotiation/index.js.map +1 -0
  100. package/dist/negotiation/protocol.d.ts +62 -0
  101. package/dist/negotiation/protocol.js +188 -0
  102. package/dist/negotiation/protocol.js.map +1 -0
  103. package/dist/orchestrator/complexity_scorer.d.ts +2 -0
  104. package/dist/orchestrator/complexity_scorer.js +79 -0
  105. package/dist/orchestrator/complexity_scorer.js.map +1 -0
  106. package/dist/orchestrator/dependency_graph.d.ts +7 -0
  107. package/dist/orchestrator/dependency_graph.js +73 -0
  108. package/dist/orchestrator/dependency_graph.js.map +1 -0
  109. package/dist/orchestrator/intent_parser.d.ts +11 -0
  110. package/dist/orchestrator/intent_parser.js +116 -0
  111. package/dist/orchestrator/intent_parser.js.map +1 -0
  112. package/dist/orchestrator/task_runner.d.ts +56 -0
  113. package/dist/orchestrator/task_runner.js +181 -0
  114. package/dist/orchestrator/task_runner.js.map +1 -0
  115. package/dist/orchestrator/types.d.ts +44 -0
  116. package/dist/orchestrator/types.js +21 -0
  117. package/dist/orchestrator/types.js.map +1 -0
  118. package/dist/providers/anthropic.d.ts +12 -0
  119. package/dist/providers/anthropic.js +258 -0
  120. package/dist/providers/anthropic.js.map +1 -0
  121. package/dist/providers/auction.d.ts +42 -0
  122. package/dist/providers/auction.js +190 -0
  123. package/dist/providers/auction.js.map +1 -0
  124. package/dist/providers/base.d.ts +103 -0
  125. package/dist/providers/base.js +2 -0
  126. package/dist/providers/base.js.map +1 -0
  127. package/dist/providers/cost_tracker.d.ts +45 -0
  128. package/dist/providers/cost_tracker.js +111 -0
  129. package/dist/providers/cost_tracker.js.map +1 -0
  130. package/dist/providers/duo_pair_router.d.ts +11 -0
  131. package/dist/providers/duo_pair_router.js +67 -0
  132. package/dist/providers/duo_pair_router.js.map +1 -0
  133. package/dist/providers/factory.d.ts +7 -0
  134. package/dist/providers/factory.js +130 -0
  135. package/dist/providers/factory.js.map +1 -0
  136. package/dist/providers/grading_rubric.d.ts +37 -0
  137. package/dist/providers/grading_rubric.js +238 -0
  138. package/dist/providers/grading_rubric.js.map +1 -0
  139. package/dist/providers/openai.d.ts +12 -0
  140. package/dist/providers/openai.js +229 -0
  141. package/dist/providers/openai.js.map +1 -0
  142. package/dist/providers/openrouter.d.ts +14 -0
  143. package/dist/providers/openrouter.js +178 -0
  144. package/dist/providers/openrouter.js.map +1 -0
  145. package/dist/providers/performance_tracker.d.ts +21 -0
  146. package/dist/providers/performance_tracker.js +63 -0
  147. package/dist/providers/performance_tracker.js.map +1 -0
  148. package/dist/providers/registry_loader.d.ts +6 -0
  149. package/dist/providers/registry_loader.js +54 -0
  150. package/dist/providers/registry_loader.js.map +1 -0
  151. package/dist/providers/retry.d.ts +66 -0
  152. package/dist/providers/retry.js +203 -0
  153. package/dist/providers/retry.js.map +1 -0
  154. package/dist/providers/role_scorer.d.ts +16 -0
  155. package/dist/providers/role_scorer.js +16 -0
  156. package/dist/providers/role_scorer.js.map +1 -0
  157. package/dist/providers/router.d.ts +84 -0
  158. package/dist/providers/router.js +542 -0
  159. package/dist/providers/router.js.map +1 -0
  160. package/dist/security/credentials.d.ts +6 -0
  161. package/dist/security/credentials.js +16 -0
  162. package/dist/security/credentials.js.map +1 -0
  163. package/dist/setup/browser.d.ts +1 -0
  164. package/dist/setup/browser.js +12 -0
  165. package/dist/setup/browser.js.map +1 -0
  166. package/dist/setup/global_config.d.ts +14 -0
  167. package/dist/setup/global_config.js +54 -0
  168. package/dist/setup/global_config.js.map +1 -0
  169. package/dist/setup/wizard.d.ts +2 -0
  170. package/dist/setup/wizard.js +206 -0
  171. package/dist/setup/wizard.js.map +1 -0
  172. package/dist/tools/agent_loop.d.ts +38 -0
  173. package/dist/tools/agent_loop.js +72 -0
  174. package/dist/tools/agent_loop.js.map +1 -0
  175. package/dist/tools/approval.d.ts +64 -0
  176. package/dist/tools/approval.js +172 -0
  177. package/dist/tools/approval.js.map +1 -0
  178. package/dist/tools/checkpoint.d.ts +65 -0
  179. package/dist/tools/checkpoint.js +342 -0
  180. package/dist/tools/checkpoint.js.map +1 -0
  181. package/dist/tools/definitions.d.ts +13 -0
  182. package/dist/tools/definitions.js +103 -0
  183. package/dist/tools/definitions.js.map +1 -0
  184. package/dist/tools/diff_display.d.ts +46 -0
  185. package/dist/tools/diff_display.js +298 -0
  186. package/dist/tools/diff_display.js.map +1 -0
  187. package/dist/tools/executor.d.ts +12 -0
  188. package/dist/tools/executor.js +340 -0
  189. package/dist/tools/executor.js.map +1 -0
  190. package/dist/tools/permissions.d.ts +17 -0
  191. package/dist/tools/permissions.js +139 -0
  192. package/dist/tools/permissions.js.map +1 -0
  193. package/dist/tools/tool_types.d.ts +48 -0
  194. package/dist/tools/tool_types.js +7 -0
  195. package/dist/tools/tool_types.js.map +1 -0
  196. package/dist/ui/banner.d.ts +4 -0
  197. package/dist/ui/banner.js +104 -0
  198. package/dist/ui/banner.js.map +1 -0
  199. package/dist/ui/callbacks.d.ts +30 -0
  200. package/dist/ui/callbacks.js +132 -0
  201. package/dist/ui/callbacks.js.map +1 -0
  202. package/dist/ui/colors.d.ts +14 -0
  203. package/dist/ui/colors.js +28 -0
  204. package/dist/ui/colors.js.map +1 -0
  205. package/dist/ui/dashboard.d.ts +51 -0
  206. package/dist/ui/dashboard.js +181 -0
  207. package/dist/ui/dashboard.js.map +1 -0
  208. package/dist/ui/leaderboard.d.ts +16 -0
  209. package/dist/ui/leaderboard.js +43 -0
  210. package/dist/ui/leaderboard.js.map +1 -0
  211. package/dist/ui/logger.d.ts +28 -0
  212. package/dist/ui/logger.js +117 -0
  213. package/dist/ui/logger.js.map +1 -0
  214. package/dist/ui/progress.d.ts +16 -0
  215. package/dist/ui/progress.js +62 -0
  216. package/dist/ui/progress.js.map +1 -0
  217. package/dist/ui/tokenizer.d.ts +5 -0
  218. package/dist/ui/tokenizer.js +54 -0
  219. package/dist/ui/tokenizer.js.map +1 -0
  220. package/package.json +63 -0
@@ -0,0 +1,340 @@
1
+ /**
2
+ * Tool execution engine.
3
+ * Receives a ToolCall from a model, executes it against the local filesystem
4
+ * or shell, and returns a ToolResult.
5
+ */
6
+ import fs from "node:fs";
7
+ import path from "node:path";
8
+ import { execSync } from "node:child_process";
9
+ import { resolvePermission } from "./permissions.js";
10
+ // ── Path safety ──────────────────────────────────────────────────
11
+ function safePath(projectRoot, inputPath) {
12
+ const resolved = path.isAbsolute(inputPath)
13
+ ? path.resolve(inputPath)
14
+ : path.resolve(projectRoot, inputPath);
15
+ return path.normalize(resolved);
16
+ }
17
+ function safeWritePath(projectRoot, inputPath) {
18
+ const resolved = safePath(projectRoot, inputPath);
19
+ if (!resolved.startsWith(projectRoot)) {
20
+ throw new Error(`Write outside project root blocked: ${inputPath}`);
21
+ }
22
+ return resolved;
23
+ }
24
+ // ── Classification ───────────────────────────────────────────────
25
+ function toToolAction(call) {
26
+ const categoryMap = {
27
+ read_file: "read",
28
+ list_directory: "read",
29
+ search_files: "search",
30
+ write_file: "write",
31
+ edit_file: "write",
32
+ run_command: "execute",
33
+ };
34
+ return {
35
+ tool: call.name,
36
+ category: categoryMap[call.name] ?? "read",
37
+ summary: buildSummary(call),
38
+ input: call.input,
39
+ };
40
+ }
41
+ function buildSummary(call) {
42
+ switch (call.name) {
43
+ case "read_file":
44
+ return `Read ${call.input.path}`;
45
+ case "write_file":
46
+ return `Write ${call.input.path}`;
47
+ case "edit_file":
48
+ return `Edit ${call.input.path}`;
49
+ case "list_directory":
50
+ return `List ${call.input.path}`;
51
+ case "search_files":
52
+ return `Search for "${call.input.pattern}" in ${call.input.path}`;
53
+ case "run_command":
54
+ return `Run: ${String(call.input.command).slice(0, 80)}`;
55
+ default:
56
+ return call.name;
57
+ }
58
+ }
59
+ // ── Individual tool handlers ─────────────────────────────────────
60
+ function executeReadFile(ctx, input) {
61
+ const filePath = safePath(ctx.projectRoot, String(input.path));
62
+ if (!fs.existsSync(filePath)) {
63
+ return `Error: File not found: ${filePath}`;
64
+ }
65
+ const stat = fs.statSync(filePath);
66
+ if (stat.isDirectory()) {
67
+ return `Error: ${filePath} is a directory. Use list_directory instead.`;
68
+ }
69
+ const maxBytes = ctx.maxFileReadBytes ?? 256 * 1024;
70
+ if (stat.size > maxBytes) {
71
+ return `Error: File too large (${stat.size} bytes). Use offset/limit.`;
72
+ }
73
+ const content = fs.readFileSync(filePath, "utf-8");
74
+ const lines = content.split("\n");
75
+ const offset = Math.max(1, Number(input.offset) || 1);
76
+ const limit = Number(input.limit) || lines.length;
77
+ const slice = lines.slice(offset - 1, offset - 1 + limit);
78
+ return slice
79
+ .map((line, i) => `${String(offset + i).padStart(5)} ${line}`)
80
+ .join("\n");
81
+ }
82
+ function executeWriteFile(ctx, input) {
83
+ const filePath = safeWritePath(ctx.projectRoot, String(input.path));
84
+ const content = String(input.content);
85
+ const existed = fs.existsSync(filePath);
86
+ const oldContent = existed ? fs.readFileSync(filePath, "utf-8") : null;
87
+ const dir = path.dirname(filePath);
88
+ if (!fs.existsSync(dir)) {
89
+ fs.mkdirSync(dir, { recursive: true });
90
+ }
91
+ fs.writeFileSync(filePath, content, "utf-8");
92
+ ctx.fileChanges.push({
93
+ filePath: path.relative(ctx.projectRoot, filePath),
94
+ type: existed ? "edit" : "create",
95
+ oldContent,
96
+ newContent: content,
97
+ });
98
+ const lineCount = content.split("\n").length;
99
+ const relPath = path.relative(ctx.projectRoot, filePath);
100
+ return existed
101
+ ? `Updated ${relPath} (${lineCount} lines)`
102
+ : `Created ${relPath} (${lineCount} lines)`;
103
+ }
104
+ function executeEditFile(ctx, input) {
105
+ const filePath = safeWritePath(ctx.projectRoot, String(input.path));
106
+ if (!fs.existsSync(filePath)) {
107
+ return `Error: File not found: ${filePath}`;
108
+ }
109
+ const oldContent = fs.readFileSync(filePath, "utf-8");
110
+ const oldString = String(input.old_string);
111
+ const newString = String(input.new_string);
112
+ const occurrences = oldContent.split(oldString).length - 1;
113
+ if (occurrences === 0) {
114
+ return (`Error: old_string not found in ` +
115
+ `${path.relative(ctx.projectRoot, filePath)}. ` +
116
+ `Verify the exact text including whitespace.`);
117
+ }
118
+ if (occurrences > 1) {
119
+ return (`Error: old_string found ${occurrences} times in ` +
120
+ `${path.relative(ctx.projectRoot, filePath)}. ` +
121
+ `Provide more surrounding context to make it unique.`);
122
+ }
123
+ const newContent = oldContent.replace(oldString, newString);
124
+ fs.writeFileSync(filePath, newContent, "utf-8");
125
+ ctx.fileChanges.push({
126
+ filePath: path.relative(ctx.projectRoot, filePath),
127
+ type: "edit",
128
+ oldContent,
129
+ newContent,
130
+ editDescription: `Replaced ${oldString.split("\n").length} line(s)`,
131
+ });
132
+ return `Edited ${path.relative(ctx.projectRoot, filePath)}`;
133
+ }
134
+ function executeListDirectory(ctx, input) {
135
+ const dirPath = safePath(ctx.projectRoot, String(input.path));
136
+ if (!fs.existsSync(dirPath)) {
137
+ return `Error: Directory not found: ${dirPath}`;
138
+ }
139
+ if (!fs.statSync(dirPath).isDirectory()) {
140
+ return `Error: ${dirPath} is a file, not a directory.`;
141
+ }
142
+ const recursive = Boolean(input.recursive);
143
+ const maxDepth = recursive ? 3 : 1;
144
+ const entries = [];
145
+ const skip = new Set([
146
+ "node_modules", ".git", "dist", ".next", "__pycache__", ".venv",
147
+ ]);
148
+ function walk(dir, depth, prefix) {
149
+ if (depth > maxDepth || entries.length >= 500)
150
+ return;
151
+ let items;
152
+ try {
153
+ items = fs.readdirSync(dir, { withFileTypes: true });
154
+ }
155
+ catch {
156
+ return;
157
+ }
158
+ for (const item of items.sort((a, b) => a.name.localeCompare(b.name))) {
159
+ if (skip.has(item.name) && depth > 0)
160
+ continue;
161
+ const isDir = item.isDirectory();
162
+ entries.push(`${prefix}${item.name}${isDir ? "/" : ""}`);
163
+ if (isDir && depth < maxDepth) {
164
+ walk(path.join(dir, item.name), depth + 1, prefix + " ");
165
+ }
166
+ }
167
+ }
168
+ walk(dirPath, 0, "");
169
+ if (entries.length >= 500)
170
+ entries.push("... (truncated at 500 entries)");
171
+ return entries.join("\n") || "(empty directory)";
172
+ }
173
+ function executeSearchFiles(ctx, input) {
174
+ const dirPath = safePath(ctx.projectRoot, String(input.path));
175
+ const patternStr = String(input.pattern);
176
+ const glob = input.glob ? String(input.glob) : undefined;
177
+ if (!fs.existsSync(dirPath)) {
178
+ return `Error: Directory not found: ${dirPath}`;
179
+ }
180
+ let regex;
181
+ try {
182
+ regex = new RegExp(patternStr, "gi");
183
+ }
184
+ catch {
185
+ return `Error: Invalid regex: ${patternStr}`;
186
+ }
187
+ const results = [];
188
+ const maxResults = 50;
189
+ const binaryExts = new Set([
190
+ ".png", ".jpg", ".gif", ".ico", ".woff", ".woff2",
191
+ ".ttf", ".eot", ".zip", ".tar", ".gz", ".db", ".sqlite",
192
+ ]);
193
+ const skip = new Set([
194
+ "node_modules", ".git", "dist", ".next", "__pycache__", ".venv",
195
+ ]);
196
+ function matchGlob(filename, pattern) {
197
+ const ext = pattern.replace("*", "");
198
+ return filename.endsWith(ext);
199
+ }
200
+ function search(dir, depth) {
201
+ if (depth > 5 || results.length >= maxResults)
202
+ return;
203
+ let items;
204
+ try {
205
+ items = fs.readdirSync(dir, { withFileTypes: true });
206
+ }
207
+ catch {
208
+ return;
209
+ }
210
+ for (const item of items) {
211
+ if (skip.has(item.name))
212
+ continue;
213
+ const fullPath = path.join(dir, item.name);
214
+ if (item.isDirectory()) {
215
+ search(fullPath, depth + 1);
216
+ continue;
217
+ }
218
+ if (glob && !matchGlob(item.name, glob))
219
+ continue;
220
+ if (binaryExts.has(path.extname(item.name).toLowerCase()))
221
+ continue;
222
+ try {
223
+ const stat = fs.statSync(fullPath);
224
+ if (stat.size > 512 * 1024)
225
+ continue;
226
+ const content = fs.readFileSync(fullPath, "utf-8");
227
+ const lines = content.split("\n");
228
+ for (let i = 0; i < lines.length; i++) {
229
+ regex.lastIndex = 0;
230
+ if (regex.test(lines[i])) {
231
+ const relPath = path.relative(ctx.projectRoot, fullPath);
232
+ results.push(`${relPath}:${i + 1}: ${lines[i].trim()}`);
233
+ if (results.length >= maxResults)
234
+ return;
235
+ }
236
+ }
237
+ }
238
+ catch {
239
+ /* skip unreadable files */
240
+ }
241
+ }
242
+ }
243
+ search(dirPath, 0);
244
+ if (results.length === 0) {
245
+ const rel = path.relative(ctx.projectRoot, dirPath) || ".";
246
+ return `No matches found for "${patternStr}" in ${rel}`;
247
+ }
248
+ let output = results.join("\n");
249
+ if (results.length >= maxResults) {
250
+ output += `\n... (truncated at ${maxResults} results)`;
251
+ }
252
+ return output;
253
+ }
254
+ function executeRunCommand(ctx, input) {
255
+ const command = String(input.command);
256
+ const cwd = input.cwd
257
+ ? safePath(ctx.projectRoot, String(input.cwd))
258
+ : ctx.projectRoot;
259
+ const timeoutMs = Math.min(Number(input.timeout) || 30000, 120000);
260
+ const maxOutput = ctx.maxCommandOutputBytes ?? 64 * 1024;
261
+ try {
262
+ const output = execSync(command, {
263
+ cwd,
264
+ timeout: timeoutMs,
265
+ maxBuffer: maxOutput,
266
+ encoding: "utf-8",
267
+ stdio: ["pipe", "pipe", "pipe"],
268
+ env: { ...process.env, FORCE_COLOR: "0" },
269
+ });
270
+ return output || "(no output)";
271
+ }
272
+ catch (error) {
273
+ const exec = error;
274
+ if (exec.killed)
275
+ return `Command timed out after ${timeoutMs}ms`;
276
+ const parts = [];
277
+ if (exec.status !== undefined)
278
+ parts.push(`Exit code: ${exec.status}`);
279
+ if (exec.stdout)
280
+ parts.push(`stdout:\n${exec.stdout}`);
281
+ if (exec.stderr)
282
+ parts.push(`stderr:\n${exec.stderr}`);
283
+ return parts.length > 0
284
+ ? parts.join("\n")
285
+ : `Error: ${error instanceof Error ? error.message : String(error)}`;
286
+ }
287
+ }
288
+ // ── Main dispatcher ──────────────────────────────────────────────
289
+ const HANDLERS = {
290
+ read_file: executeReadFile,
291
+ write_file: executeWriteFile,
292
+ edit_file: executeEditFile,
293
+ list_directory: executeListDirectory,
294
+ search_files: executeSearchFiles,
295
+ run_command: executeRunCommand,
296
+ };
297
+ export async function executeTool(ctx, call) {
298
+ const start = Date.now();
299
+ const action = toToolAction(call);
300
+ const allowed = await resolvePermission(action, ctx.permissions);
301
+ if (!allowed) {
302
+ return {
303
+ tool: call.name,
304
+ success: false,
305
+ output: `Permission denied: ${action.summary}`,
306
+ durationMs: Date.now() - start,
307
+ requiredApproval: true,
308
+ };
309
+ }
310
+ const handler = HANDLERS[call.name];
311
+ if (!handler) {
312
+ return {
313
+ tool: call.name,
314
+ success: false,
315
+ output: `Unknown tool: ${call.name}`,
316
+ durationMs: Date.now() - start,
317
+ requiredApproval: false,
318
+ };
319
+ }
320
+ try {
321
+ const output = handler(ctx, call.input);
322
+ return {
323
+ tool: call.name,
324
+ success: !output.startsWith("Error:"),
325
+ output,
326
+ durationMs: Date.now() - start,
327
+ requiredApproval: action.category === "write" || action.category === "execute",
328
+ };
329
+ }
330
+ catch (error) {
331
+ return {
332
+ tool: call.name,
333
+ success: false,
334
+ output: `Error: ${error instanceof Error ? error.message : String(error)}`,
335
+ durationMs: Date.now() - start,
336
+ requiredApproval: false,
337
+ };
338
+ }
339
+ }
340
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/tools/executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Permission model for tool execution.
3
+ * Controls which tools can run automatically vs requiring user confirmation.
4
+ */
5
+ import type { ToolAction } from "./tool_types.js";
6
+ export type PermissionLevel = "auto" | "confirm-writes" | "confirm-all" | "read-only";
7
+ export type ConfirmToolCallback = (action: ToolAction) => Promise<boolean>;
8
+ export interface PermissionConfig {
9
+ level: PermissionLevel;
10
+ confirmCallback?: ConfirmToolCallback;
11
+ /** Regex patterns for commands that are always allowed */
12
+ allowedCommandPatterns?: string[];
13
+ /** Regex patterns for commands that are always denied */
14
+ deniedCommandPatterns?: string[];
15
+ }
16
+ export declare function checkPermission(action: ToolAction, config: PermissionConfig): "allow" | "deny" | "confirm";
17
+ export declare function resolvePermission(action: ToolAction, config: PermissionConfig): Promise<boolean>;
@@ -0,0 +1,139 @@
1
+ /** Binaries that are always denied regardless of arguments. */
2
+ const BLOCKED_BINARIES = new Set([
3
+ "mkfs", "mkfs.ext4", "mkfs.xfs", "mkfs.btrfs",
4
+ "fdisk", "parted", "wipefs",
5
+ "shutdown", "reboot", "halt", "poweroff",
6
+ "iptables", "ip6tables", "nft",
7
+ "passwd", "useradd", "userdel", "usermod",
8
+ "mount", "umount",
9
+ ]);
10
+ /** Binaries that are denied when used with dangerous argument patterns. */
11
+ const DANGEROUS_COMBOS = [
12
+ { binary: "rm", test: (args) => args.some((a) => /^-.*r/i.test(a)) && args.some((a) => a === "/" || a === "/*") },
13
+ { binary: "rm", test: (args) => args.some((a) => /^-.*f.*r|^-.*r.*f/i.test(a)) && args.some((a) => a.startsWith("/") && a.split("/").length <= 2) },
14
+ { binary: "dd", test: (args) => args.some((a) => a.startsWith("if=") || a.startsWith("of=/dev/")) },
15
+ { binary: "chmod", test: (args) => args.some((a) => a === "777") && args.some((a) => a === "/" || a === "-R") },
16
+ { binary: "chown", test: (args) => args.some((a) => a === "-R") && args.some((a) => a === "/") },
17
+ ];
18
+ /**
19
+ * Extract individual command segments from a shell command line.
20
+ * Splits on pipes, semicolons, &&, ||, $(), backticks.
21
+ * Returns the binary name for each segment.
22
+ */
23
+ function extractCommandBinaries(command) {
24
+ // Split on shell operators to get individual commands
25
+ const segments = command
26
+ .replace(/`[^`]*`/g, " __backtick__ ") // flag backtick substitutions
27
+ .replace(/\$\([^)]*\)/g, " __subshell__ ") // flag $() substitutions
28
+ .split(/\s*(?:&&|\|\||[;|])\s*/);
29
+ const binaries = [];
30
+ for (const seg of segments) {
31
+ const trimmed = seg.trim();
32
+ if (!trimmed)
33
+ continue;
34
+ // Skip env var prefixes like FOO=bar
35
+ const tokens = trimmed.split(/\s+/).filter((t) => !t.includes("=") || t.startsWith("-"));
36
+ const bin = tokens[0];
37
+ if (bin) {
38
+ // Extract basename (handle /usr/bin/rm → rm)
39
+ const basename = bin.split("/").pop() ?? bin;
40
+ // Strip any quoting tricks: "r"m → rm, r''m → rm
41
+ const cleaned = basename.replace(/["']/g, "");
42
+ binaries.push(cleaned);
43
+ }
44
+ // Flag if backtick or subshell substitution is present (potential evasion)
45
+ if (trimmed.includes("__backtick__") || trimmed.includes("__subshell__")) {
46
+ binaries.push("__shell_substitution__");
47
+ }
48
+ }
49
+ return binaries;
50
+ }
51
+ function extractArgs(command, binary) {
52
+ const idx = command.indexOf(binary);
53
+ if (idx < 0)
54
+ return [];
55
+ const rest = command.slice(idx + binary.length).trim();
56
+ return rest.split(/\s+/).filter(Boolean);
57
+ }
58
+ /** Regex patterns that indicate fork bombs or redirect attacks. */
59
+ const STRUCTURAL_DENY_PATTERNS = [
60
+ /:\s*\(\)\s*\{/, // fork bomb: :() { ... }
61
+ />\s*\/dev\/[sh]d/, // redirect to block device
62
+ />\s*\/proc\//, // redirect to /proc
63
+ />\s*\/sys\//, // redirect to /sys
64
+ /\beval\b.*\$\{?[A-Z]/, // eval with env var expansion
65
+ ];
66
+ function isCommandDenied(command) {
67
+ // Check structural patterns (fork bombs, device redirects)
68
+ for (const pattern of STRUCTURAL_DENY_PATTERNS) {
69
+ if (pattern.test(command))
70
+ return true;
71
+ }
72
+ const binaries = extractCommandBinaries(command);
73
+ // Block shell substitution in non-auto modes (evasion vector)
74
+ if (binaries.includes("__shell_substitution__"))
75
+ return true;
76
+ for (const bin of binaries) {
77
+ if (BLOCKED_BINARIES.has(bin))
78
+ return true;
79
+ for (const combo of DANGEROUS_COMBOS) {
80
+ if (combo.binary === bin) {
81
+ const args = extractArgs(command, bin);
82
+ if (combo.test(args))
83
+ return true;
84
+ }
85
+ }
86
+ }
87
+ return false;
88
+ }
89
+ export function checkPermission(action, config) {
90
+ if (config.level === "read-only") {
91
+ return action.category === "write" || action.category === "execute"
92
+ ? "deny"
93
+ : "allow";
94
+ }
95
+ // Check denied patterns for commands
96
+ if (action.category === "execute") {
97
+ const command = String(action.input.command ?? "");
98
+ // Built-in binary/structural checks
99
+ if (isCommandDenied(command))
100
+ return "deny";
101
+ // User-configured deny patterns
102
+ for (const raw of config.deniedCommandPatterns ?? []) {
103
+ if (new RegExp(raw).test(command))
104
+ return "deny";
105
+ }
106
+ // User-configured allow patterns
107
+ for (const raw of config.allowedCommandPatterns ?? []) {
108
+ if (new RegExp(raw).test(command))
109
+ return "allow";
110
+ }
111
+ }
112
+ if (config.level === "auto")
113
+ return "allow";
114
+ // Reads and searches never need confirmation
115
+ if (action.category === "read" || action.category === "search") {
116
+ return "allow";
117
+ }
118
+ if (config.level === "confirm-writes") {
119
+ return action.category === "write" || action.category === "execute"
120
+ ? "confirm"
121
+ : "allow";
122
+ }
123
+ // confirm-all
124
+ return "confirm";
125
+ }
126
+ export async function resolvePermission(action, config) {
127
+ const decision = checkPermission(action, config);
128
+ if (decision === "allow")
129
+ return true;
130
+ if (decision === "deny")
131
+ return false;
132
+ // Confirm — delegate to callback
133
+ if (config.confirmCallback) {
134
+ return config.confirmCallback(action);
135
+ }
136
+ // No callback available — default deny for safety
137
+ return false;
138
+ }
139
+ //# sourceMappingURL=permissions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/tools/permissions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Shared type definitions for the tool execution system.
3
+ * Phase 1 implements the tool loop; Phase 2 provides diff display,
4
+ * approval, context, and retry modules that the loop consumes.
5
+ */
6
+ export type ToolCategory = "read" | "write" | "execute" | "search" | "ask";
7
+ export interface ToolAction {
8
+ /** Tool name (e.g. "read_file", "edit_file", "run_command") */
9
+ tool: string;
10
+ /** Category for approval routing */
11
+ category: ToolCategory;
12
+ /** Human-readable summary of what this action does */
13
+ summary: string;
14
+ /** Tool input parameters */
15
+ input: Record<string, unknown>;
16
+ }
17
+ export interface ToolResult {
18
+ tool: string;
19
+ success: boolean;
20
+ output: string;
21
+ /** Milliseconds elapsed */
22
+ durationMs: number;
23
+ /** Whether the user was prompted for approval */
24
+ requiredApproval: boolean;
25
+ }
26
+ export interface FileChange {
27
+ filePath: string;
28
+ type: "create" | "edit" | "delete";
29
+ oldContent: string | null;
30
+ newContent: string | null;
31
+ /** For edit_file: the search/replace pair */
32
+ editDescription?: string;
33
+ }
34
+ export interface CommandRequest {
35
+ command: string;
36
+ args: string[];
37
+ cwd?: string;
38
+ timeoutMs?: number;
39
+ /** If true, stdout/stderr is streamed to the terminal live */
40
+ inheritStdio?: boolean;
41
+ }
42
+ export interface CommandResult {
43
+ exitCode: number;
44
+ stdout: string;
45
+ stderr: string;
46
+ timedOut: boolean;
47
+ durationMs: number;
48
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Shared type definitions for the tool execution system.
3
+ * Phase 1 implements the tool loop; Phase 2 provides diff display,
4
+ * approval, context, and retry modules that the loop consumes.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=tool_types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool_types.js","sourceRoot":"","sources":["../../src/tools/tool_types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,4 @@
1
+ export declare function banner(): string;
2
+ export declare function printManPage(): void;
3
+ export declare function printModels(): void;
4
+ export declare function checkPromptClarity(input: string): string | null;