heyio 0.1.14 → 0.1.16
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/copilot/orchestrator.js +7 -0
- package/dist/copilot/tools.js +147 -1
- package/package.json +1 -1
|
@@ -308,6 +308,13 @@ export async function initOrchestrator(copilotClient) {
|
|
|
308
308
|
catch (err) {
|
|
309
309
|
console.error("[io] Could not validate models:", err instanceof Error ? err.message : err);
|
|
310
310
|
}
|
|
311
|
+
// Log built-in tools for diagnostics
|
|
312
|
+
try {
|
|
313
|
+
const toolsList = await copilotClient.rpc.tools.list({});
|
|
314
|
+
const toolNames = toolsList.tools.map((t) => t.name);
|
|
315
|
+
console.error(`[io] Built-in tools: ${toolNames.join(", ")}`);
|
|
316
|
+
}
|
|
317
|
+
catch { /* non-fatal */ }
|
|
311
318
|
// Start health check timer
|
|
312
319
|
healthCheckTimer = setInterval(() => {
|
|
313
320
|
if (!client || client.getState() !== "connected") {
|
package/dist/copilot/tools.js
CHANGED
|
@@ -263,7 +263,153 @@ export function createTools(deps) {
|
|
|
263
263
|
}
|
|
264
264
|
},
|
|
265
265
|
});
|
|
266
|
-
|
|
266
|
+
// Override built-in view tool
|
|
267
|
+
const viewTool = defineTool("view", {
|
|
268
|
+
description: "View a file's contents or list a directory.",
|
|
269
|
+
skipPermission: true,
|
|
270
|
+
overridesBuiltInTool: true,
|
|
271
|
+
parameters: z.object({
|
|
272
|
+
path: z.string().describe("Path to the file or directory"),
|
|
273
|
+
view_range: z.array(z.number()).optional().describe("Line range [start, end] to view"),
|
|
274
|
+
}),
|
|
275
|
+
handler: async ({ path: filePath, view_range }) => {
|
|
276
|
+
console.error(`[io] view tool called: ${filePath}`);
|
|
277
|
+
try {
|
|
278
|
+
const resolved = resolve(filePath);
|
|
279
|
+
if (!existsSync(resolved))
|
|
280
|
+
return `Not found: ${filePath}`;
|
|
281
|
+
const stat = statSync(resolved);
|
|
282
|
+
if (stat.isDirectory()) {
|
|
283
|
+
const entries = readdirSync(resolved);
|
|
284
|
+
return entries
|
|
285
|
+
.map((e) => {
|
|
286
|
+
const full = join(resolved, e);
|
|
287
|
+
try {
|
|
288
|
+
return statSync(full).isDirectory() ? `${e}/` : e;
|
|
289
|
+
}
|
|
290
|
+
catch {
|
|
291
|
+
return e;
|
|
292
|
+
}
|
|
293
|
+
})
|
|
294
|
+
.join("\n") || "(empty directory)";
|
|
295
|
+
}
|
|
296
|
+
const text = readFileSync(resolved, "utf-8");
|
|
297
|
+
if (view_range && view_range.length === 2) {
|
|
298
|
+
const lines = text.split("\n");
|
|
299
|
+
const start = Math.max(0, view_range[0] - 1);
|
|
300
|
+
const end = view_range[1] === -1 ? lines.length : Math.min(lines.length, view_range[1]);
|
|
301
|
+
return lines.slice(start, end).map((l, i) => `${start + i + 1}. ${l}`).join("\n");
|
|
302
|
+
}
|
|
303
|
+
if (text.length > 8000) {
|
|
304
|
+
return text.slice(0, 8000) + "\n\n[…truncated]";
|
|
305
|
+
}
|
|
306
|
+
return text;
|
|
307
|
+
}
|
|
308
|
+
catch (err) {
|
|
309
|
+
return `Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
310
|
+
}
|
|
311
|
+
},
|
|
312
|
+
});
|
|
313
|
+
// Override built-in grep tool
|
|
314
|
+
const grepTool = defineTool("grep", {
|
|
315
|
+
description: "Search file contents using a pattern.",
|
|
316
|
+
skipPermission: true,
|
|
317
|
+
overridesBuiltInTool: true,
|
|
318
|
+
parameters: z.object({
|
|
319
|
+
pattern: z.string().describe("Search pattern (regex)"),
|
|
320
|
+
path: z.string().optional().describe("Directory or file to search"),
|
|
321
|
+
include: z.string().optional().describe("Glob pattern to filter files (e.g., '*.ts')"),
|
|
322
|
+
}),
|
|
323
|
+
handler: async ({ pattern, path: searchPath, include }) => {
|
|
324
|
+
console.error(`[io] grep tool called: ${pattern} in ${searchPath || "."}`);
|
|
325
|
+
try {
|
|
326
|
+
let cmd = `grep -rn "${pattern.replace(/"/g, '\\"')}"`;
|
|
327
|
+
if (include)
|
|
328
|
+
cmd += ` --include="${include}"`;
|
|
329
|
+
cmd += ` ${searchPath || "."}`;
|
|
330
|
+
const result = execSync(cmd, {
|
|
331
|
+
encoding: "utf-8",
|
|
332
|
+
timeout: 30_000,
|
|
333
|
+
maxBuffer: 1024 * 1024,
|
|
334
|
+
});
|
|
335
|
+
const output = result.trim();
|
|
336
|
+
if (output.length > 8000) {
|
|
337
|
+
return output.slice(0, 8000) + "\n\n[…truncated]";
|
|
338
|
+
}
|
|
339
|
+
return output || "(no matches)";
|
|
340
|
+
}
|
|
341
|
+
catch (err) {
|
|
342
|
+
const execErr = err;
|
|
343
|
+
if (execErr.status === 1)
|
|
344
|
+
return "(no matches)";
|
|
345
|
+
return `Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
346
|
+
}
|
|
347
|
+
},
|
|
348
|
+
});
|
|
349
|
+
// Override built-in str_replace_editor tool
|
|
350
|
+
const strReplaceEditor = defineTool("str_replace_editor", {
|
|
351
|
+
description: "View, create, or edit files using string replacement.",
|
|
352
|
+
skipPermission: true,
|
|
353
|
+
overridesBuiltInTool: true,
|
|
354
|
+
parameters: z.object({
|
|
355
|
+
command: z.enum(["view", "create", "str_replace", "insert"]).describe("Command to execute"),
|
|
356
|
+
path: z.string().describe("File path"),
|
|
357
|
+
old_str: z.string().optional().describe("String to replace (for str_replace)"),
|
|
358
|
+
new_str: z.string().optional().describe("Replacement string"),
|
|
359
|
+
file_text: z.string().optional().describe("Content for create"),
|
|
360
|
+
insert_line: z.number().optional().describe("Line number for insert"),
|
|
361
|
+
view_range: z.array(z.number()).optional().describe("Line range [start, end]"),
|
|
362
|
+
}),
|
|
363
|
+
handler: async ({ command, path: filePath, old_str, new_str, file_text, insert_line, view_range }) => {
|
|
364
|
+
console.error(`[io] str_replace_editor tool called: ${command} ${filePath}`);
|
|
365
|
+
try {
|
|
366
|
+
const resolved = resolve(filePath);
|
|
367
|
+
if (command === "view") {
|
|
368
|
+
if (!existsSync(resolved))
|
|
369
|
+
return `File not found: ${filePath}`;
|
|
370
|
+
const text = readFileSync(resolved, "utf-8");
|
|
371
|
+
if (view_range && view_range.length === 2) {
|
|
372
|
+
const lines = text.split("\n");
|
|
373
|
+
const start = Math.max(0, view_range[0] - 1);
|
|
374
|
+
const end = view_range[1] === -1 ? lines.length : Math.min(lines.length, view_range[1]);
|
|
375
|
+
return lines.slice(start, end).map((l, i) => `${start + i + 1}. ${l}`).join("\n");
|
|
376
|
+
}
|
|
377
|
+
if (text.length > 8000)
|
|
378
|
+
return text.slice(0, 8000) + "\n\n[…truncated]";
|
|
379
|
+
return text;
|
|
380
|
+
}
|
|
381
|
+
if (command === "create") {
|
|
382
|
+
mkdirSync(dirname(resolved), { recursive: true });
|
|
383
|
+
writeFileSync(resolved, file_text || "", "utf-8");
|
|
384
|
+
return `Created: ${filePath}`;
|
|
385
|
+
}
|
|
386
|
+
if (command === "str_replace") {
|
|
387
|
+
if (!existsSync(resolved))
|
|
388
|
+
return `File not found: ${filePath}`;
|
|
389
|
+
const text = readFileSync(resolved, "utf-8");
|
|
390
|
+
if (old_str && !text.includes(old_str))
|
|
391
|
+
return `old_str not found in ${filePath}`;
|
|
392
|
+
const updated = old_str ? text.replace(old_str, new_str || "") : text;
|
|
393
|
+
writeFileSync(resolved, updated, "utf-8");
|
|
394
|
+
return `Updated: ${filePath}`;
|
|
395
|
+
}
|
|
396
|
+
if (command === "insert") {
|
|
397
|
+
if (!existsSync(resolved))
|
|
398
|
+
return `File not found: ${filePath}`;
|
|
399
|
+
const lines = readFileSync(resolved, "utf-8").split("\n");
|
|
400
|
+
const lineNum = insert_line ?? lines.length;
|
|
401
|
+
lines.splice(lineNum, 0, new_str || "");
|
|
402
|
+
writeFileSync(resolved, lines.join("\n"), "utf-8");
|
|
403
|
+
return `Inserted at line ${lineNum} in ${filePath}`;
|
|
404
|
+
}
|
|
405
|
+
return `Unknown command: ${command}`;
|
|
406
|
+
}
|
|
407
|
+
catch (err) {
|
|
408
|
+
return `Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
409
|
+
}
|
|
410
|
+
},
|
|
411
|
+
});
|
|
412
|
+
return [wikiRead, wikiWrite, wikiSearch, squadCreate, squadRecall, squadStatus, squadLogDecision, shell, fileOps, bash, readFile, viewTool, grepTool, strReplaceEditor];
|
|
267
413
|
}
|
|
268
414
|
function walkDirectory(dir, maxDepth = 3, depth = 0) {
|
|
269
415
|
if (depth >= maxDepth)
|