@hasna/coders 0.1.3 → 0.1.5
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 +62 -18
- package/dist/cli.mjs.map +3 -3
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -61852,12 +61852,15 @@ async function runAgentLoop(initialMessages, options2) {
|
|
|
61852
61852
|
options2.onThinkingDelta?.(event.delta.thinking);
|
|
61853
61853
|
}
|
|
61854
61854
|
}
|
|
61855
|
-
if (event.type === "
|
|
61855
|
+
if (event.type === "message_delta") {
|
|
61856
|
+
stopReason = accumulated.stopReason ?? stopReason;
|
|
61857
|
+
}
|
|
61858
|
+
if (event.type === "message_stop") {
|
|
61856
61859
|
if (accumulated.content) {
|
|
61857
61860
|
contentBlocks.length = 0;
|
|
61858
61861
|
contentBlocks.push(...accumulated.content);
|
|
61859
61862
|
}
|
|
61860
|
-
stopReason = accumulated.stopReason ??
|
|
61863
|
+
stopReason = accumulated.stopReason ?? stopReason;
|
|
61861
61864
|
if (accumulated.usage) {
|
|
61862
61865
|
totalInputTokens += accumulated.usage.inputTokens;
|
|
61863
61866
|
totalOutputTokens += accumulated.usage.outputTokens;
|
|
@@ -61872,9 +61875,16 @@ async function runAgentLoop(initialMessages, options2) {
|
|
|
61872
61875
|
throw error;
|
|
61873
61876
|
}
|
|
61874
61877
|
if (aborted) break;
|
|
61878
|
+
const cleanedBlocks = contentBlocks.map((b) => {
|
|
61879
|
+
if (b.type === "tool_use") {
|
|
61880
|
+
const { _inputParseFailed, _rawInputJson, ...clean } = b;
|
|
61881
|
+
return clean;
|
|
61882
|
+
}
|
|
61883
|
+
return b;
|
|
61884
|
+
});
|
|
61875
61885
|
const assistantMessage = {
|
|
61876
61886
|
role: "assistant",
|
|
61877
|
-
content:
|
|
61887
|
+
content: cleanedBlocks
|
|
61878
61888
|
};
|
|
61879
61889
|
messages.push(assistantMessage);
|
|
61880
61890
|
const toolUseBlocks = contentBlocks.filter(
|
|
@@ -62346,8 +62356,9 @@ var init_bash = __esm({
|
|
|
62346
62356
|
{ pattern: /\b:(){ :\|:& };:/, reason: "Fork bomb" },
|
|
62347
62357
|
{ pattern: /\bchmod\s+-R\s+777\s+\//, reason: "Recursive chmod 777 on root" },
|
|
62348
62358
|
{ pattern: /\bchown\s+-R\s+.*\s+\//, reason: "Recursive chown on root" },
|
|
62349
|
-
{ pattern: /\
|
|
62350
|
-
{ pattern: /\
|
|
62359
|
+
{ pattern: /\b(curl|wget)\s.*\|\s*(sh|bash|zsh|ksh)\b/, reason: "Pipe remote script to shell" },
|
|
62360
|
+
{ pattern: /\bdd\s+if=/, reason: "Direct disk copy" },
|
|
62361
|
+
{ pattern: /\bsudo\s+rm\s+-rf\b/, reason: "Recursive delete as root" },
|
|
62351
62362
|
{ pattern: /\b\/etc\/passwd\b/, reason: "Access to passwd file" },
|
|
62352
62363
|
{ pattern: /\b\/etc\/shadow\b/, reason: "Access to shadow file" }
|
|
62353
62364
|
];
|
|
@@ -62638,8 +62649,7 @@ var init_bash = __esm({
|
|
|
62638
62649
|
shell: getShell(),
|
|
62639
62650
|
cwd: process.cwd(),
|
|
62640
62651
|
env: { ...process.env },
|
|
62641
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
62642
|
-
timeout: timeoutMs
|
|
62652
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
62643
62653
|
});
|
|
62644
62654
|
child.stdout?.on("data", (data) => {
|
|
62645
62655
|
stdout += data.toString();
|
|
@@ -62647,6 +62657,11 @@ var init_bash = __esm({
|
|
|
62647
62657
|
child.stderr?.on("data", (data) => {
|
|
62648
62658
|
stderr += data.toString();
|
|
62649
62659
|
});
|
|
62660
|
+
const timeoutTimer = setTimeout(() => {
|
|
62661
|
+
interrupted = true;
|
|
62662
|
+
child.kill("SIGTERM");
|
|
62663
|
+
setTimeout(() => child.kill("SIGKILL"), 3e3);
|
|
62664
|
+
}, timeoutMs);
|
|
62650
62665
|
const onAbort = () => {
|
|
62651
62666
|
interrupted = true;
|
|
62652
62667
|
child.kill("SIGTERM");
|
|
@@ -62654,6 +62669,7 @@ var init_bash = __esm({
|
|
|
62654
62669
|
};
|
|
62655
62670
|
context.abortController?.signal.addEventListener("abort", onAbort, { once: true });
|
|
62656
62671
|
child.on("close", (code, signal) => {
|
|
62672
|
+
clearTimeout(timeoutTimer);
|
|
62657
62673
|
context.abortController?.signal.removeEventListener("abort", onAbort);
|
|
62658
62674
|
const durationMs = performance.now() - startTime;
|
|
62659
62675
|
if (signal === "SIGTERM" || signal === "SIGKILL") {
|
|
@@ -62967,7 +62983,7 @@ Usage:
|
|
|
62967
62983
|
});
|
|
62968
62984
|
|
|
62969
62985
|
// src/tools/builtin/edit.ts
|
|
62970
|
-
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as existsSync7 } from "fs";
|
|
62986
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as existsSync7, statSync as statSync2 } from "fs";
|
|
62971
62987
|
import { resolve as resolve3, isAbsolute as isAbsolute2 } from "path";
|
|
62972
62988
|
import { randomUUID } from "crypto";
|
|
62973
62989
|
function resolvePath2(filePath) {
|
|
@@ -63146,6 +63162,23 @@ var init_edit = __esm({
|
|
|
63146
63162
|
return { data: { filePath: input.file_path, oldString: "", newString: "", replacements: 0, originalFile: "" } };
|
|
63147
63163
|
}
|
|
63148
63164
|
const resolved = resolvePath2(input.file_path);
|
|
63165
|
+
const MAX_FILE_SIZE = 50 * 1024 * 1024;
|
|
63166
|
+
try {
|
|
63167
|
+
const fileSize = statSync2(resolved).size;
|
|
63168
|
+
if (fileSize > MAX_FILE_SIZE) {
|
|
63169
|
+
return {
|
|
63170
|
+
data: {
|
|
63171
|
+
filePath: resolved,
|
|
63172
|
+
oldString: input.old_string,
|
|
63173
|
+
newString: input.new_string,
|
|
63174
|
+
replacements: 0,
|
|
63175
|
+
originalFile: "",
|
|
63176
|
+
gitDiff: void 0
|
|
63177
|
+
}
|
|
63178
|
+
};
|
|
63179
|
+
}
|
|
63180
|
+
} catch {
|
|
63181
|
+
}
|
|
63149
63182
|
const originalContent = readFileSync6(resolved, "utf-8");
|
|
63150
63183
|
let newContent;
|
|
63151
63184
|
let replacements;
|
|
@@ -66958,11 +66991,11 @@ var require_out = __commonJS({
|
|
|
66958
66991
|
async.read(path, getSettings2(optionsOrSettingsOrCallback), callback);
|
|
66959
66992
|
}
|
|
66960
66993
|
exports.stat = stat;
|
|
66961
|
-
function
|
|
66994
|
+
function statSync4(path, optionsOrSettings) {
|
|
66962
66995
|
const settings = getSettings2(optionsOrSettings);
|
|
66963
66996
|
return sync.read(path, settings);
|
|
66964
66997
|
}
|
|
66965
|
-
exports.statSync =
|
|
66998
|
+
exports.statSync = statSync4;
|
|
66966
66999
|
function getSettings2(settingsOrOptions = {}) {
|
|
66967
67000
|
if (settingsOrOptions instanceof settings_1.default) {
|
|
66968
67001
|
return settingsOrOptions;
|
|
@@ -68847,7 +68880,7 @@ var require_out4 = __commonJS({
|
|
|
68847
68880
|
});
|
|
68848
68881
|
|
|
68849
68882
|
// src/tools/builtin/glob.ts
|
|
68850
|
-
import { statSync as
|
|
68883
|
+
import { statSync as statSync3, existsSync as existsSync9 } from "fs";
|
|
68851
68884
|
import { resolve as resolve5, isAbsolute as isAbsolute4 } from "path";
|
|
68852
68885
|
function resolvePath4(p) {
|
|
68853
68886
|
if (isAbsolute4(p)) return p;
|
|
@@ -68913,6 +68946,15 @@ var init_glob = __esm({
|
|
|
68913
68946
|
},
|
|
68914
68947
|
async call(input, context) {
|
|
68915
68948
|
const cwd2 = input.path ? resolvePath4(input.path) : process.cwd();
|
|
68949
|
+
if (input.path && !existsSync9(cwd2)) {
|
|
68950
|
+
return {
|
|
68951
|
+
data: {
|
|
68952
|
+
files: [],
|
|
68953
|
+
totalMatches: 0,
|
|
68954
|
+
truncated: false
|
|
68955
|
+
}
|
|
68956
|
+
};
|
|
68957
|
+
}
|
|
68916
68958
|
try {
|
|
68917
68959
|
const allFiles = await (0, import_fast_glob.default)(input.pattern, {
|
|
68918
68960
|
cwd: cwd2,
|
|
@@ -68935,7 +68977,7 @@ var init_glob = __esm({
|
|
|
68935
68977
|
});
|
|
68936
68978
|
const withStats = allFiles.map((f) => {
|
|
68937
68979
|
try {
|
|
68938
|
-
const stat =
|
|
68980
|
+
const stat = statSync3(f);
|
|
68939
68981
|
return { path: f, mtime: stat.mtimeMs };
|
|
68940
68982
|
} catch {
|
|
68941
68983
|
return { path: f, mtime: 0 };
|
|
@@ -69184,7 +69226,7 @@ var init_grep = __esm({
|
|
|
69184
69226
|
return processOutput(result, input);
|
|
69185
69227
|
} catch (error) {
|
|
69186
69228
|
const err = error;
|
|
69187
|
-
if (err.status === 1) {
|
|
69229
|
+
if (err.status === 1 && (!err.stderr || err.stderr.trim() === "")) {
|
|
69188
69230
|
return {
|
|
69189
69231
|
data: { content: "No matches found.", matchCount: 0, fileCount: 0, truncated: false }
|
|
69190
69232
|
};
|
|
@@ -70426,6 +70468,10 @@ function App2({ model, mode, initialPrompt }) {
|
|
|
70426
70468
|
const toolHandlers = createToolHandlers();
|
|
70427
70469
|
const permCtx = createDefaultPermissionContext();
|
|
70428
70470
|
const toolStartTimes = /* @__PURE__ */ new Map();
|
|
70471
|
+
const builtinTools = [bashTool, readTool, editTool, writeTool, globTool, grepTool];
|
|
70472
|
+
const toolPrompts = await Promise.all(
|
|
70473
|
+
builtinTools.map(async (t) => ({ name: t.name, prompt: await t.prompt() }))
|
|
70474
|
+
);
|
|
70429
70475
|
const result = await runAgentLoop(
|
|
70430
70476
|
newHistory,
|
|
70431
70477
|
{
|
|
@@ -70434,7 +70480,7 @@ function App2({ model, mode, initialPrompt }) {
|
|
|
70434
70480
|
projectDir: process.cwd(),
|
|
70435
70481
|
model,
|
|
70436
70482
|
permissionMode: mode,
|
|
70437
|
-
tools:
|
|
70483
|
+
tools: toolPrompts
|
|
70438
70484
|
}),
|
|
70439
70485
|
tools: toolHandlers,
|
|
70440
70486
|
model,
|
|
@@ -70565,7 +70611,7 @@ function App2({ model, mode, initialPrompt }) {
|
|
|
70565
70611
|
const hasRunningTools = activeTools.some((t) => t.status === "running");
|
|
70566
70612
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
70567
70613
|
/* @__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) }),
|
|
70568
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column",
|
|
70614
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
70569
70615
|
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)) }),
|
|
70570
70616
|
busy && streaming && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { children: [
|
|
70571
70617
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "green", children: "\u25CF " }),
|
|
@@ -70623,8 +70669,6 @@ function launchInkApp(opts = {}) {
|
|
|
70623
70669
|
};
|
|
70624
70670
|
console.error = () => {
|
|
70625
70671
|
};
|
|
70626
|
-
const termRows = process.stdout.rows ?? 24;
|
|
70627
|
-
process.stdout.write("\n".repeat(Math.max(termRows - 5, 0)));
|
|
70628
70672
|
const { waitUntilExit } = render_default(
|
|
70629
70673
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(App2, { model, mode, initialPrompt: opts.initialPrompt }),
|
|
70630
70674
|
{ exitOnCtrlC: false }
|
|
@@ -70978,7 +71022,7 @@ var VERSION, BUILD_TIME, PACKAGE_NAME2, ISSUES_URL2, startupTimestamps, original
|
|
|
70978
71022
|
var init_index = __esm({
|
|
70979
71023
|
"src/cli/index.ts"() {
|
|
70980
71024
|
VERSION = "0.1.2";
|
|
70981
|
-
BUILD_TIME = "2026-03-
|
|
71025
|
+
BUILD_TIME = "2026-03-20T17:30:01.515Z";
|
|
70982
71026
|
PACKAGE_NAME2 = "@hasna/coders";
|
|
70983
71027
|
ISSUES_URL2 = "https://github.com/hasnaxyz/open-coders/issues";
|
|
70984
71028
|
startupTimestamps = {};
|