@hasna/coders 0.1.2 → 0.1.4
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/cli.mjs +172 -68
- package/dist/cli.mjs.map +3 -3
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -61872,9 +61872,16 @@ async function runAgentLoop(initialMessages, options2) {
|
|
|
61872
61872
|
throw error;
|
|
61873
61873
|
}
|
|
61874
61874
|
if (aborted) break;
|
|
61875
|
+
const cleanedBlocks = contentBlocks.map((b) => {
|
|
61876
|
+
if (b.type === "tool_use") {
|
|
61877
|
+
const { _inputParseFailed, _rawInputJson, ...clean } = b;
|
|
61878
|
+
return clean;
|
|
61879
|
+
}
|
|
61880
|
+
return b;
|
|
61881
|
+
});
|
|
61875
61882
|
const assistantMessage = {
|
|
61876
61883
|
role: "assistant",
|
|
61877
|
-
content:
|
|
61884
|
+
content: cleanedBlocks
|
|
61878
61885
|
};
|
|
61879
61886
|
messages.push(assistantMessage);
|
|
61880
61887
|
const toolUseBlocks = contentBlocks.filter(
|
|
@@ -70172,21 +70179,18 @@ function useSpinner(active) {
|
|
|
70172
70179
|
}, [active]);
|
|
70173
70180
|
return active ? FRAMES[i] : " ";
|
|
70174
70181
|
}
|
|
70175
|
-
function createToolHandlers(
|
|
70182
|
+
function createToolHandlers() {
|
|
70176
70183
|
const tools = [bashTool, readTool, editTool, writeTool, globTool, grepTool];
|
|
70177
70184
|
const permCtx = createDefaultPermissionContext();
|
|
70178
70185
|
const appState = { toolPermissionContext: permCtx, verbose: false };
|
|
70179
|
-
const alwaysAllowed = /* @__PURE__ */ new Set();
|
|
70180
70186
|
return tools.map((tool) => ({
|
|
70181
70187
|
name: tool.name,
|
|
70182
|
-
description:
|
|
70183
|
-
inputSchema: { type: "object", properties: {} },
|
|
70188
|
+
description: TOOL_DESCRIPTIONS[tool.name] ?? `Tool: ${tool.name}`,
|
|
70189
|
+
inputSchema: TOOL_JSON_SCHEMAS[tool.name] ?? { type: "object", properties: {} },
|
|
70184
70190
|
isReadOnly: tool.isReadOnly(),
|
|
70185
70191
|
isConcurrencySafe: tool.isConcurrencySafe(),
|
|
70186
70192
|
call: async (input, ctx) => {
|
|
70187
70193
|
const summary = toolSummary(tool.name, input);
|
|
70188
|
-
const toolId = `tool-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
|
|
70189
|
-
onToolStart(toolId, tool.name, summary);
|
|
70190
70194
|
const t0 = performance.now();
|
|
70191
70195
|
try {
|
|
70192
70196
|
const toolCtx = {
|
|
@@ -70196,18 +70200,16 @@ function createToolHandlers(onToolStart, onToolEnd, requestPermission) {
|
|
|
70196
70200
|
options: { mainLoopModel: "sonnet", thinkingConfig: { type: "disabled" }, isNonInteractiveSession: false, tools: [], agentDefinitions: { activeAgents: [] } }
|
|
70197
70201
|
};
|
|
70198
70202
|
const result = await tool.call(input, toolCtx);
|
|
70199
|
-
const block2 = tool.mapToolResultToToolResultBlockParam(result.data,
|
|
70203
|
+
const block2 = tool.mapToolResultToToolResultBlockParam(result.data, ctx.toolUseId ?? "");
|
|
70200
70204
|
const dur = performance.now() - t0;
|
|
70201
|
-
onToolEnd(toolId, block2.content.slice(0, 500), block2.is_error ? block2.content : void 0, dur);
|
|
70202
70205
|
try {
|
|
70203
70206
|
dbRun("INSERT INTO audit_log (tool_name, input_summary, result_summary, duration_ms, was_allowed) VALUES (?, ?, ?, ?, 1)", [tool.name, summary, block2.content.slice(0, 200), dur]);
|
|
70204
70207
|
} catch {
|
|
70205
70208
|
}
|
|
70206
|
-
return { data: block2.content };
|
|
70209
|
+
return block2.is_error ? { data: block2.content, error: block2.content, isError: true } : { data: block2.content };
|
|
70207
70210
|
} catch (err) {
|
|
70208
70211
|
const dur = performance.now() - t0;
|
|
70209
70212
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
70210
|
-
onToolEnd(toolId, "", errMsg, dur);
|
|
70211
70213
|
try {
|
|
70212
70214
|
dbRun("INSERT INTO audit_log (tool_name, input_summary, result_summary, duration_ms, was_allowed) VALUES (?, ?, ?, ?, 1)", [tool.name, summary, errMsg.slice(0, 200), dur]);
|
|
70213
70215
|
} catch {
|
|
@@ -70390,11 +70392,23 @@ function App2({ model, mode, initialPrompt }) {
|
|
|
70390
70392
|
setActiveTools((prev) => [...prev, { id, name, summary, status: "running" }]);
|
|
70391
70393
|
}, []);
|
|
70392
70394
|
const onToolEnd = (0, import_react22.useCallback)((id, result, error, durationMs) => {
|
|
70393
|
-
|
|
70394
|
-
|
|
70395
|
-
|
|
70396
|
-
|
|
70397
|
-
|
|
70395
|
+
const tool = activeToolsRef.current.find((t) => t.id === id);
|
|
70396
|
+
if (!tool) return;
|
|
70397
|
+
const completed = {
|
|
70398
|
+
...tool,
|
|
70399
|
+
status: error ? "error" : "done",
|
|
70400
|
+
result,
|
|
70401
|
+
error,
|
|
70402
|
+
durationMs
|
|
70403
|
+
};
|
|
70404
|
+
setMsgs((prev) => [...prev, {
|
|
70405
|
+
id: `td-${id}`,
|
|
70406
|
+
role: "assistant",
|
|
70407
|
+
content: "",
|
|
70408
|
+
timestamp: Date.now(),
|
|
70409
|
+
tools: [completed]
|
|
70410
|
+
}]);
|
|
70411
|
+
setActiveTools((prev) => prev.filter((t) => t.id !== id));
|
|
70398
70412
|
}, []);
|
|
70399
70413
|
const submit = (0, import_react22.useCallback)(async (text) => {
|
|
70400
70414
|
if (!text.trim() || busy) return;
|
|
@@ -70416,8 +70430,9 @@ function App2({ model, mode, initialPrompt }) {
|
|
|
70416
70430
|
setActiveTools([]);
|
|
70417
70431
|
const t0 = performance.now();
|
|
70418
70432
|
try {
|
|
70419
|
-
const toolHandlers = createToolHandlers(
|
|
70433
|
+
const toolHandlers = createToolHandlers();
|
|
70420
70434
|
const permCtx = createDefaultPermissionContext();
|
|
70435
|
+
const toolStartTimes = /* @__PURE__ */ new Map();
|
|
70421
70436
|
const result = await runAgentLoop(
|
|
70422
70437
|
newHistory,
|
|
70423
70438
|
{
|
|
@@ -70434,7 +70449,7 @@ function App2({ model, mode, initialPrompt }) {
|
|
|
70434
70449
|
permissionContext: permCtx,
|
|
70435
70450
|
maxTurns: 10,
|
|
70436
70451
|
onTextDelta: (text2) => {
|
|
70437
|
-
if (activeToolsRef.current.length === 0
|
|
70452
|
+
if (activeToolsRef.current.length === 0) {
|
|
70438
70453
|
setStreaming((prev) => prev + text2);
|
|
70439
70454
|
}
|
|
70440
70455
|
},
|
|
@@ -70442,11 +70457,14 @@ function App2({ model, mode, initialPrompt }) {
|
|
|
70442
70457
|
},
|
|
70443
70458
|
onToolUseStart: (name, id, toolInput) => {
|
|
70444
70459
|
setStreaming("");
|
|
70460
|
+
toolStartTimes.set(id, performance.now());
|
|
70445
70461
|
onToolStart(id, name, toolSummary(name, toolInput));
|
|
70446
70462
|
},
|
|
70447
70463
|
onToolUseEnd: (name, id, toolResult) => {
|
|
70448
70464
|
const isErr = toolResult.isError || !!toolResult.error;
|
|
70449
|
-
|
|
70465
|
+
const startTime = toolStartTimes.get(id);
|
|
70466
|
+
const dur2 = startTime ? performance.now() - startTime : void 0;
|
|
70467
|
+
onToolEnd(id, String(toolResult.data ?? "").slice(0, 500), isErr ? toolResult.error : void 0, dur2);
|
|
70450
70468
|
}
|
|
70451
70469
|
}
|
|
70452
70470
|
);
|
|
@@ -70466,19 +70484,27 @@ function App2({ model, mode, initialPrompt }) {
|
|
|
70466
70484
|
);
|
|
70467
70485
|
setCost((p) => p + c.totalCostUsd);
|
|
70468
70486
|
setTokens((p) => p + result.usage.totalInputTokens + result.usage.totalOutputTokens);
|
|
70469
|
-
const frozenTools = [...activeToolsRef.current].map(
|
|
70470
|
-
(t) => t.status === "running" ? { ...t, status: "done" } : t
|
|
70471
|
-
);
|
|
70472
70487
|
const verb = VERBS[Math.floor(Math.random() * VERBS.length)];
|
|
70473
|
-
|
|
70474
|
-
|
|
70475
|
-
|
|
70476
|
-
|
|
70477
|
-
|
|
70478
|
-
|
|
70479
|
-
|
|
70480
|
-
|
|
70481
|
-
|
|
70488
|
+
const textContent = finalText || streaming || "";
|
|
70489
|
+
if (textContent && textContent !== "(no response)") {
|
|
70490
|
+
setMsgs((p) => [...p, {
|
|
70491
|
+
id: `a${Date.now()}`,
|
|
70492
|
+
role: "assistant",
|
|
70493
|
+
content: textContent,
|
|
70494
|
+
timestamp: Date.now(),
|
|
70495
|
+
durationMs: dur,
|
|
70496
|
+
durationVerb: verb
|
|
70497
|
+
}]);
|
|
70498
|
+
} else if (dur > 1e3) {
|
|
70499
|
+
setMsgs((p) => [...p, {
|
|
70500
|
+
id: `a${Date.now()}`,
|
|
70501
|
+
role: "assistant",
|
|
70502
|
+
content: "",
|
|
70503
|
+
timestamp: Date.now(),
|
|
70504
|
+
durationMs: dur,
|
|
70505
|
+
durationVerb: verb
|
|
70506
|
+
}]);
|
|
70507
|
+
}
|
|
70482
70508
|
setHistory(result.messages.filter((m) => m.role === "user" || m.role === "assistant"));
|
|
70483
70509
|
setStreaming("");
|
|
70484
70510
|
setActiveTools([]);
|
|
@@ -70488,7 +70514,7 @@ function App2({ model, mode, initialPrompt }) {
|
|
|
70488
70514
|
} finally {
|
|
70489
70515
|
setBusy(false);
|
|
70490
70516
|
}
|
|
70491
|
-
}, [busy, history, model, exit, onToolStart, onToolEnd,
|
|
70517
|
+
}, [busy, history, model, exit, onToolStart, onToolEnd, streaming, activeTools]);
|
|
70492
70518
|
(0, import_react22.useEffect)(() => {
|
|
70493
70519
|
if (initialPrompt) submit(initialPrompt);
|
|
70494
70520
|
}, []);
|
|
@@ -70541,47 +70567,49 @@ function App2({ model, mode, initialPrompt }) {
|
|
|
70541
70567
|
} else if (key.escape) setInput("");
|
|
70542
70568
|
else if (!key.ctrl && !key.meta && ch) setInput((p) => p + ch);
|
|
70543
70569
|
});
|
|
70544
|
-
const recentTools = activeTools.slice(-2);
|
|
70545
70570
|
const cols = stdout?.columns ?? 80;
|
|
70546
70571
|
const sep = "\u2500".repeat(Math.min(cols, 120));
|
|
70572
|
+
const hasRunningTools = activeTools.some((t) => t.status === "running");
|
|
70547
70573
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
70548
70574
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Static, { items: msgs, children: (msg) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box_default, { flexDirection: "column", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MessageView, { msg }) }, msg.id) }),
|
|
70549
|
-
busy && recentTools.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box_default, { flexDirection: "column", children: recentTools.map((t) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToolItem, { tool: t }, t.id)) }),
|
|
70550
|
-
busy && streaming && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { children: [
|
|
70551
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "green", children: "\u25CF " }),
|
|
70552
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: streaming.split("\n").filter((l) => l.trim()).slice(-3).join("\n").slice(-200) })
|
|
70553
|
-
] }),
|
|
70554
|
-
busy && !streaming && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { children: [
|
|
70555
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SpinnerDot, {}),
|
|
70556
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { dimColor: true, children: [
|
|
70557
|
-
" ",
|
|
70558
|
-
recentTools.some((t) => t.status === "running") ? "Working" : "Thinking",
|
|
70559
|
-
"..."
|
|
70560
|
-
] })
|
|
70561
|
-
] }),
|
|
70562
70575
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
70563
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
70564
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { children: [
|
|
70565
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
70566
|
-
|
|
70567
|
-
|
|
70568
|
-
|
|
70569
|
-
|
|
70570
|
-
|
|
70576
|
+
busy && activeTools.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box_default, { flexDirection: "column", children: activeTools.map((t) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToolItem, { tool: t }, t.id)) }),
|
|
70577
|
+
busy && streaming && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { children: [
|
|
70578
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "green", children: "\u25CF " }),
|
|
70579
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: streaming.split("\n").filter((l) => l.trim()).slice(-3).join("\n").slice(-200) })
|
|
70580
|
+
] }),
|
|
70581
|
+
busy && !streaming && activeTools.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { children: [
|
|
70582
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SpinnerDot, {}),
|
|
70583
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { dimColor: true, children: " Thinking..." })
|
|
70584
|
+
] }),
|
|
70585
|
+
busy && hasRunningTools && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { children: [
|
|
70586
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SpinnerDot, {}),
|
|
70587
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { dimColor: true, children: " Working..." })
|
|
70571
70588
|
] }),
|
|
70572
|
-
|
|
70573
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
|
|
70574
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
70575
|
-
"
|
|
70576
|
-
|
|
70589
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
70590
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { dimColor: true, children: sep }),
|
|
70591
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { children: [
|
|
70592
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: "cyan", bold: true, children: [
|
|
70593
|
+
PROMPT,
|
|
70594
|
+
" "
|
|
70595
|
+
] }),
|
|
70596
|
+
input.startsWith("/") ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "magenta", children: input }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: input }),
|
|
70597
|
+
!busy && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "gray", children: "\u258E" })
|
|
70577
70598
|
] }),
|
|
70578
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
70579
|
-
" ",
|
|
70580
|
-
|
|
70581
|
-
|
|
70582
|
-
|
|
70583
|
-
|
|
70584
|
-
|
|
70599
|
+
showSlashMenu && filteredCommands.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box_default, { flexDirection: "column", paddingLeft: 2, children: filteredCommands.map((cmd, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { children: [
|
|
70600
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: i === slashSelected ? "cyan" : void 0, bold: i === slashSelected, children: i === slashSelected ? "\u25B8 " : " " }),
|
|
70601
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: i === slashSelected ? "cyan" : "blue", children: [
|
|
70602
|
+
"/",
|
|
70603
|
+
cmd.name.padEnd(16)
|
|
70604
|
+
] }),
|
|
70605
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { dimColor: true, children: [
|
|
70606
|
+
" ",
|
|
70607
|
+
cmd.description
|
|
70608
|
+
] })
|
|
70609
|
+
] }, cmd.name)) }),
|
|
70610
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { dimColor: true, children: sep }),
|
|
70611
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(StatusBar, { model, mode, cost, tokens })
|
|
70612
|
+
] })
|
|
70585
70613
|
] })
|
|
70586
70614
|
] });
|
|
70587
70615
|
}
|
|
@@ -70634,7 +70662,7 @@ function fmtTok(n) {
|
|
|
70634
70662
|
if (n < 1e6) return `${(n / 1e3).toFixed(1)}K`;
|
|
70635
70663
|
return `${(n / 1e6).toFixed(2)}M`;
|
|
70636
70664
|
}
|
|
70637
|
-
var import_react22, import_jsx_runtime, CONN, PROMPT, FRAMES, VERBS;
|
|
70665
|
+
var import_react22, import_jsx_runtime, CONN, PROMPT, FRAMES, VERBS, TOOL_JSON_SCHEMAS, TOOL_DESCRIPTIONS;
|
|
70638
70666
|
var init_app = __esm({
|
|
70639
70667
|
async "src/ui/app.tsx"() {
|
|
70640
70668
|
"use strict";
|
|
@@ -70662,6 +70690,82 @@ var init_app = __esm({
|
|
|
70662
70690
|
PROMPT = "\u276F";
|
|
70663
70691
|
FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
70664
70692
|
VERBS = ["Baked", "Brewed", "Churned", "Cogitated", "Cooked", "Crunched", "Saut\xE9ed", "Worked"];
|
|
70693
|
+
TOOL_JSON_SCHEMAS = {
|
|
70694
|
+
Bash: {
|
|
70695
|
+
type: "object",
|
|
70696
|
+
properties: {
|
|
70697
|
+
command: { type: "string", description: "The command to execute" },
|
|
70698
|
+
description: { type: "string", description: "Clear, concise description of what this command does" },
|
|
70699
|
+
timeout: { type: "number", description: "Optional timeout in milliseconds (max 600000)" },
|
|
70700
|
+
run_in_background: { type: "boolean", description: "Set to true to run in the background" }
|
|
70701
|
+
},
|
|
70702
|
+
required: ["command"]
|
|
70703
|
+
},
|
|
70704
|
+
Read: {
|
|
70705
|
+
type: "object",
|
|
70706
|
+
properties: {
|
|
70707
|
+
file_path: { type: "string", description: "The absolute path to the file to read" },
|
|
70708
|
+
offset: { type: "number", description: "The line number to start reading from" },
|
|
70709
|
+
limit: { type: "number", description: "The number of lines to read" },
|
|
70710
|
+
pages: { type: "string", description: "Page range for PDF files (e.g. '1-5')" }
|
|
70711
|
+
},
|
|
70712
|
+
required: ["file_path"]
|
|
70713
|
+
},
|
|
70714
|
+
Edit: {
|
|
70715
|
+
type: "object",
|
|
70716
|
+
properties: {
|
|
70717
|
+
file_path: { type: "string", description: "The absolute path to the file to modify" },
|
|
70718
|
+
old_string: { type: "string", description: "The text to replace" },
|
|
70719
|
+
new_string: { type: "string", description: "The text to replace it with (must be different from old_string)" },
|
|
70720
|
+
replace_all: { type: "boolean", description: "Replace all occurrences of old_string (default false)", default: false }
|
|
70721
|
+
},
|
|
70722
|
+
required: ["file_path", "old_string", "new_string"]
|
|
70723
|
+
},
|
|
70724
|
+
Write: {
|
|
70725
|
+
type: "object",
|
|
70726
|
+
properties: {
|
|
70727
|
+
file_path: { type: "string", description: "The absolute path to the file to write" },
|
|
70728
|
+
content: { type: "string", description: "The content to write to the file" }
|
|
70729
|
+
},
|
|
70730
|
+
required: ["file_path", "content"]
|
|
70731
|
+
},
|
|
70732
|
+
Glob: {
|
|
70733
|
+
type: "object",
|
|
70734
|
+
properties: {
|
|
70735
|
+
pattern: { type: "string", description: "The glob pattern to match files against" },
|
|
70736
|
+
path: { type: "string", description: "The directory to search in. Defaults to current working directory." }
|
|
70737
|
+
},
|
|
70738
|
+
required: ["pattern"]
|
|
70739
|
+
},
|
|
70740
|
+
Grep: {
|
|
70741
|
+
type: "object",
|
|
70742
|
+
properties: {
|
|
70743
|
+
pattern: { type: "string", description: "The regular expression pattern to search for" },
|
|
70744
|
+
path: { type: "string", description: "File or directory to search in. Defaults to cwd." },
|
|
70745
|
+
glob: { type: "string", description: "Glob pattern to filter files (e.g. '*.js', '*.{ts,tsx}')" },
|
|
70746
|
+
type: { type: "string", description: "File type to search (js, py, rust, go, etc.)" },
|
|
70747
|
+
output_mode: { type: "string", enum: ["content", "files_with_matches", "count"], description: "Output mode. Defaults to 'files_with_matches'." },
|
|
70748
|
+
"-A": { type: "number", description: "Lines to show after each match" },
|
|
70749
|
+
"-B": { type: "number", description: "Lines to show before each match" },
|
|
70750
|
+
"-C": { type: "number", description: "Context lines before and after each match" },
|
|
70751
|
+
context: { type: "number", description: "Alias for -C" },
|
|
70752
|
+
"-i": { type: "boolean", description: "Case insensitive search" },
|
|
70753
|
+
"-n": { type: "boolean", description: "Show line numbers (default true)" },
|
|
70754
|
+
multiline: { type: "boolean", description: "Enable multiline mode" },
|
|
70755
|
+
head_limit: { type: "number", description: "Limit output to first N entries" },
|
|
70756
|
+
offset: { type: "number", description: "Skip first N entries" }
|
|
70757
|
+
},
|
|
70758
|
+
required: ["pattern"]
|
|
70759
|
+
}
|
|
70760
|
+
};
|
|
70761
|
+
TOOL_DESCRIPTIONS = {
|
|
70762
|
+
Bash: "Executes a bash command and returns its output. Use for system commands, builds, and terminal operations.",
|
|
70763
|
+
Read: "Reads a file from the filesystem. Returns contents with line numbers. Supports text, PDF, images, and notebooks.",
|
|
70764
|
+
Edit: "Performs exact string replacements in files. Use old_string/new_string for targeted edits.",
|
|
70765
|
+
Write: "Writes content to a file, creating it if needed or overwriting if it exists.",
|
|
70766
|
+
Glob: "Fast file pattern matching. Returns matching file paths sorted by modification time.",
|
|
70767
|
+
Grep: "Content search powered by ripgrep. Supports regex, file type filters, and multiple output modes."
|
|
70768
|
+
};
|
|
70665
70769
|
}
|
|
70666
70770
|
});
|
|
70667
70771
|
|
|
@@ -70879,7 +70983,7 @@ var VERSION, BUILD_TIME, PACKAGE_NAME2, ISSUES_URL2, startupTimestamps, original
|
|
|
70879
70983
|
var init_index = __esm({
|
|
70880
70984
|
"src/cli/index.ts"() {
|
|
70881
70985
|
VERSION = "0.1.2";
|
|
70882
|
-
BUILD_TIME = "2026-03-
|
|
70986
|
+
BUILD_TIME = "2026-03-20T14:03:23.252Z";
|
|
70883
70987
|
PACKAGE_NAME2 = "@hasna/coders";
|
|
70884
70988
|
ISSUES_URL2 = "https://github.com/hasnaxyz/open-coders/issues";
|
|
70885
70989
|
startupTimestamps = {};
|