@kolisachint/hoocode-agent 0.4.110 → 0.4.111
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/CHANGELOG.md +61 -0
- package/dist/core/format-duration.d.ts +7 -0
- package/dist/core/format-duration.d.ts.map +1 -0
- package/dist/core/format-duration.js +16 -0
- package/dist/core/format-duration.js.map +1 -0
- package/dist/core/keybindings.d.ts +10 -0
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +10 -0
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/lifeguard.d.ts +15 -0
- package/dist/core/lifeguard.d.ts.map +1 -1
- package/dist/core/lifeguard.js +48 -18
- package/dist/core/lifeguard.js.map +1 -1
- package/dist/core/subagent-inbox.d.ts +1 -1
- package/dist/core/subagent-inbox.d.ts.map +1 -1
- package/dist/core/subagent-inbox.js +2 -0
- package/dist/core/subagent-inbox.js.map +1 -1
- package/dist/core/subagent-pool-instance.d.ts.map +1 -1
- package/dist/core/subagent-pool-instance.js +18 -11
- package/dist/core/subagent-pool-instance.js.map +1 -1
- package/dist/core/subagent-pool.d.ts +25 -3
- package/dist/core/subagent-pool.d.ts.map +1 -1
- package/dist/core/subagent-pool.js +120 -25
- package/dist/core/subagent-pool.js.map +1 -1
- package/dist/core/subagent-result.d.ts.map +1 -1
- package/dist/core/subagent-result.js +6 -4
- package/dist/core/subagent-result.js.map +1 -1
- package/dist/core/task-store.d.ts +45 -3
- package/dist/core/task-store.d.ts.map +1 -1
- package/dist/core/task-store.js +51 -5
- package/dist/core/task-store.js.map +1 -1
- package/dist/core/team-view.d.ts.map +1 -1
- package/dist/core/team-view.js +2 -0
- package/dist/core/team-view.js.map +1 -1
- package/dist/core/token-budget.d.ts +13 -1
- package/dist/core/token-budget.d.ts.map +1 -1
- package/dist/core/token-budget.js +18 -1
- package/dist/core/token-budget.js.map +1 -1
- package/dist/core/tools/subagent.d.ts +1 -1
- package/dist/core/tools/subagent.d.ts.map +1 -1
- package/dist/core/tools/subagent.js +184 -53
- package/dist/core/tools/subagent.js.map +1 -1
- package/dist/core/tools/todo.d.ts.map +1 -1
- package/dist/core/tools/todo.js +39 -7
- package/dist/core/tools/todo.js.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts +10 -0
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.js +27 -1
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
- package/dist/modes/interactive/components/task-panel.d.ts +22 -1
- package/dist/modes/interactive/components/task-panel.d.ts.map +1 -1
- package/dist/modes/interactive/components/task-panel.js +302 -80
- package/dist/modes/interactive/components/task-panel.js.map +1 -1
- package/dist/modes/interactive/components/team-attach-panel.d.ts.map +1 -1
- package/dist/modes/interactive/components/team-attach-panel.js +15 -5
- package/dist/modes/interactive/components/team-attach-panel.js.map +1 -1
- package/dist/modes/interactive/theme/dark.json +8 -1
- package/dist/modes/interactive/theme/light.json +8 -1
- package/dist/modes/interactive/theme/theme-schema.json +28 -1
- package/dist/modes/interactive/theme/theme.d.ts +12 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +52 -0
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/interactive/voice/voice-panel.d.ts.map +1 -1
- package/dist/modes/interactive/voice/voice-panel.js +5 -2
- package/dist/modes/interactive/voice/voice-panel.js.map +1 -1
- package/dist/modes/rpc/jsonl.d.ts +16 -1
- package/dist/modes/rpc/jsonl.d.ts.map +1 -1
- package/dist/modes/rpc/jsonl.js +53 -8
- package/dist/modes/rpc/jsonl.js.map +1 -1
- package/dist/utils/atomic-file.d.ts +13 -0
- package/dist/utils/atomic-file.d.ts.map +1 -0
- package/dist/utils/atomic-file.js +26 -0
- package/dist/utils/atomic-file.js.map +1 -0
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +4 -4
package/dist/modes/rpc/jsonl.js
CHANGED
|
@@ -14,10 +14,20 @@ export function serializeJsonLine(value) {
|
|
|
14
14
|
* This intentionally does not use Node readline. Readline splits on additional
|
|
15
15
|
* Unicode separators that are valid inside JSON strings and therefore does not
|
|
16
16
|
* implement strict JSONL framing.
|
|
17
|
+
*
|
|
18
|
+
* The reader detaches itself on stream `error` (which would otherwise crash the
|
|
19
|
+
* process as an unhandled 'error' event) and flushes + detaches on `close`, so
|
|
20
|
+
* a child that dies mid-line cannot leak listeners or buffered data. The
|
|
21
|
+
* returned function detaches manually.
|
|
17
22
|
*/
|
|
18
|
-
export function attachJsonlLineReader(stream, onLine) {
|
|
23
|
+
export function attachJsonlLineReader(stream, onLine, options = {}) {
|
|
19
24
|
const decoder = new StringDecoder("utf8");
|
|
25
|
+
const maxBuffer = options.maxBuffer;
|
|
20
26
|
let buffer = "";
|
|
27
|
+
/** True while skipping the remainder of a line that overflowed maxBuffer. */
|
|
28
|
+
let discarding = false;
|
|
29
|
+
let flushed = false;
|
|
30
|
+
let detached = false;
|
|
21
31
|
const emitLine = (line) => {
|
|
22
32
|
onLine(line.endsWith("\r") ? line.slice(0, -1) : line);
|
|
23
33
|
};
|
|
@@ -26,24 +36,59 @@ export function attachJsonlLineReader(stream, onLine) {
|
|
|
26
36
|
while (true) {
|
|
27
37
|
const newlineIndex = buffer.indexOf("\n");
|
|
28
38
|
if (newlineIndex === -1) {
|
|
39
|
+
if (maxBuffer !== undefined && buffer.length > maxBuffer) {
|
|
40
|
+
buffer = "";
|
|
41
|
+
discarding = true;
|
|
42
|
+
}
|
|
29
43
|
return;
|
|
30
44
|
}
|
|
31
|
-
|
|
45
|
+
const line = buffer.slice(0, newlineIndex);
|
|
32
46
|
buffer = buffer.slice(newlineIndex + 1);
|
|
47
|
+
if (discarding) {
|
|
48
|
+
// The extracted piece is the tail of an oversized, already-dropped line.
|
|
49
|
+
discarding = false;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
emitLine(line);
|
|
33
53
|
}
|
|
34
54
|
};
|
|
35
|
-
const
|
|
55
|
+
const flush = () => {
|
|
56
|
+
if (flushed)
|
|
57
|
+
return;
|
|
58
|
+
flushed = true;
|
|
36
59
|
buffer += decoder.end();
|
|
37
|
-
if (buffer.length > 0) {
|
|
60
|
+
if (buffer.length > 0 && !discarding) {
|
|
38
61
|
emitLine(buffer);
|
|
39
|
-
buffer = "";
|
|
40
62
|
}
|
|
63
|
+
buffer = "";
|
|
41
64
|
};
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
65
|
+
const detach = () => {
|
|
66
|
+
if (detached)
|
|
67
|
+
return;
|
|
68
|
+
detached = true;
|
|
45
69
|
stream.off("data", onData);
|
|
46
70
|
stream.off("end", onEnd);
|
|
71
|
+
stream.off("close", onClose);
|
|
72
|
+
stream.off("error", onError);
|
|
73
|
+
buffer = "";
|
|
47
74
|
};
|
|
75
|
+
const onEnd = () => {
|
|
76
|
+
flush();
|
|
77
|
+
};
|
|
78
|
+
const onClose = () => {
|
|
79
|
+
flush();
|
|
80
|
+
detach();
|
|
81
|
+
};
|
|
82
|
+
const onError = () => {
|
|
83
|
+
// The stream is dead; drop partial data and release the listeners. Having
|
|
84
|
+
// this handler also keeps a stream 'error' from becoming an uncaught
|
|
85
|
+
// exception in the parent.
|
|
86
|
+
detach();
|
|
87
|
+
};
|
|
88
|
+
stream.on("data", onData);
|
|
89
|
+
stream.on("end", onEnd);
|
|
90
|
+
stream.on("close", onClose);
|
|
91
|
+
stream.on("error", onError);
|
|
92
|
+
return detach;
|
|
48
93
|
}
|
|
49
94
|
//# sourceMappingURL=jsonl.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsonl.js","sourceRoot":"","sources":["../../../src/modes/rpc/jsonl.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAc,EAAU;IACzD,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC;AAAA,CACpC;
|
|
1
|
+
{"version":3,"file":"jsonl.js","sourceRoot":"","sources":["../../../src/modes/rpc/jsonl.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Readable } from \"node:stream\";\nimport { StringDecoder } from \"node:string_decoder\";\n\n/**\n * Serialize a single strict JSONL record.\n *\n * Framing is LF-only. Payload strings may contain other Unicode separators such as\n * U+2028 and U+2029. Clients must split records on `\\n` only.\n */\nexport function serializeJsonLine(value: unknown): string {\n\treturn `${JSON.stringify(value)}\\n`;\n}\n\nexport interface JsonlLineReaderOptions {\n\t/**\n\t * Cap (in UTF-16 code units) on the un-terminated line buffer. A line that\n\t * grows past this without a newline is dropped in its entirety (the rest of\n\t * it is skipped up to the next newline) instead of being buffered without\n\t * bound — a misbehaving writer must not be able to OOM the reader. Omit for\n\t * an unbounded buffer (trusted peers, e.g. the RPC channel).\n\t */\n\tmaxBuffer?: number;\n}\n\n/**\n * Attach an LF-only JSONL reader to a stream.\n *\n * This intentionally does not use Node readline. Readline splits on additional\n * Unicode separators that are valid inside JSON strings and therefore does not\n * implement strict JSONL framing.\n *\n * The reader detaches itself on stream `error` (which would otherwise crash the\n * process as an unhandled 'error' event) and flushes + detaches on `close`, so\n * a child that dies mid-line cannot leak listeners or buffered data. The\n * returned function detaches manually.\n */\nexport function attachJsonlLineReader(\n\tstream: Readable,\n\tonLine: (line: string) => void,\n\toptions: JsonlLineReaderOptions = {},\n): () => void {\n\tconst decoder = new StringDecoder(\"utf8\");\n\tconst maxBuffer = options.maxBuffer;\n\tlet buffer = \"\";\n\t/** True while skipping the remainder of a line that overflowed maxBuffer. */\n\tlet discarding = false;\n\tlet flushed = false;\n\tlet detached = false;\n\n\tconst emitLine = (line: string) => {\n\t\tonLine(line.endsWith(\"\\r\") ? line.slice(0, -1) : line);\n\t};\n\n\tconst onData = (chunk: string | Buffer) => {\n\t\tbuffer += typeof chunk === \"string\" ? chunk : decoder.write(chunk);\n\n\t\twhile (true) {\n\t\t\tconst newlineIndex = buffer.indexOf(\"\\n\");\n\t\t\tif (newlineIndex === -1) {\n\t\t\t\tif (maxBuffer !== undefined && buffer.length > maxBuffer) {\n\t\t\t\t\tbuffer = \"\";\n\t\t\t\t\tdiscarding = true;\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst line = buffer.slice(0, newlineIndex);\n\t\t\tbuffer = buffer.slice(newlineIndex + 1);\n\t\t\tif (discarding) {\n\t\t\t\t// The extracted piece is the tail of an oversized, already-dropped line.\n\t\t\t\tdiscarding = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\temitLine(line);\n\t\t}\n\t};\n\n\tconst flush = () => {\n\t\tif (flushed) return;\n\t\tflushed = true;\n\t\tbuffer += decoder.end();\n\t\tif (buffer.length > 0 && !discarding) {\n\t\t\temitLine(buffer);\n\t\t}\n\t\tbuffer = \"\";\n\t};\n\n\tconst detach = () => {\n\t\tif (detached) return;\n\t\tdetached = true;\n\t\tstream.off(\"data\", onData);\n\t\tstream.off(\"end\", onEnd);\n\t\tstream.off(\"close\", onClose);\n\t\tstream.off(\"error\", onError);\n\t\tbuffer = \"\";\n\t};\n\n\tconst onEnd = () => {\n\t\tflush();\n\t};\n\n\tconst onClose = () => {\n\t\tflush();\n\t\tdetach();\n\t};\n\n\tconst onError = () => {\n\t\t// The stream is dead; drop partial data and release the listeners. Having\n\t\t// this handler also keeps a stream 'error' from becoming an uncaught\n\t\t// exception in the parent.\n\t\tdetach();\n\t};\n\n\tstream.on(\"data\", onData);\n\tstream.on(\"end\", onEnd);\n\tstream.on(\"close\", onClose);\n\tstream.on(\"error\", onError);\n\n\treturn detach;\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Write a file atomically: write to a unique temp file in the same directory,
|
|
3
|
+
* then rename over the target. The same-directory temp keeps the rename on one
|
|
4
|
+
* filesystem (rename across mounts is a non-atomic copy), so a reader can never
|
|
5
|
+
* observe a torn, half-written file — it sees either the old content or the
|
|
6
|
+
* new. Used for handshake files like a subagent's result.json, where a reader
|
|
7
|
+
* (the parent pool) may race a writer that gets SIGKILLed mid-write.
|
|
8
|
+
*
|
|
9
|
+
* Throws on failure like writeFileSync; callers that treat persistence as
|
|
10
|
+
* best-effort keep their own try/catch.
|
|
11
|
+
*/
|
|
12
|
+
export declare function writeFileAtomicSync(path: string, data: string): void;
|
|
13
|
+
//# sourceMappingURL=atomic-file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atomic-file.d.ts","sourceRoot":"","sources":["../../src/utils/atomic-file.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAUpE","sourcesContent":["import { mkdirSync, renameSync, rmSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\n\n/**\n * Write a file atomically: write to a unique temp file in the same directory,\n * then rename over the target. The same-directory temp keeps the rename on one\n * filesystem (rename across mounts is a non-atomic copy), so a reader can never\n * observe a torn, half-written file — it sees either the old content or the\n * new. Used for handshake files like a subagent's result.json, where a reader\n * (the parent pool) may race a writer that gets SIGKILLed mid-write.\n *\n * Throws on failure like writeFileSync; callers that treat persistence as\n * best-effort keep their own try/catch.\n */\nexport function writeFileAtomicSync(path: string, data: string): void {\n\tmkdirSync(dirname(path), { recursive: true });\n\tconst tempPath = join(dirname(path), `.${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}.tmp`);\n\ttry {\n\t\twriteFileSync(tempPath, data);\n\t\trenameSync(tempPath, path);\n\t} catch (error) {\n\t\trmSync(tempPath, { force: true });\n\t\tthrow error;\n\t}\n}\n"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { mkdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Write a file atomically: write to a unique temp file in the same directory,
|
|
5
|
+
* then rename over the target. The same-directory temp keeps the rename on one
|
|
6
|
+
* filesystem (rename across mounts is a non-atomic copy), so a reader can never
|
|
7
|
+
* observe a torn, half-written file — it sees either the old content or the
|
|
8
|
+
* new. Used for handshake files like a subagent's result.json, where a reader
|
|
9
|
+
* (the parent pool) may race a writer that gets SIGKILLed mid-write.
|
|
10
|
+
*
|
|
11
|
+
* Throws on failure like writeFileSync; callers that treat persistence as
|
|
12
|
+
* best-effort keep their own try/catch.
|
|
13
|
+
*/
|
|
14
|
+
export function writeFileAtomicSync(path, data) {
|
|
15
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
16
|
+
const tempPath = join(dirname(path), `.${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}.tmp`);
|
|
17
|
+
try {
|
|
18
|
+
writeFileSync(tempPath, data);
|
|
19
|
+
renameSync(tempPath, path);
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
rmSync(tempPath, { force: true });
|
|
23
|
+
throw error;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=atomic-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atomic-file.js","sourceRoot":"","sources":["../../src/utils/atomic-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACvE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C;;;;;;;;;;GAUG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY,EAAE,IAAY,EAAQ;IACrE,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IAClH,IAAI,CAAC;QACJ,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC9B,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAClC,MAAM,KAAK,CAAC;IACb,CAAC;AAAA,CACD","sourcesContent":["import { mkdirSync, renameSync, rmSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\n\n/**\n * Write a file atomically: write to a unique temp file in the same directory,\n * then rename over the target. The same-directory temp keeps the rename on one\n * filesystem (rename across mounts is a non-atomic copy), so a reader can never\n * observe a torn, half-written file — it sees either the old content or the\n * new. Used for handshake files like a subagent's result.json, where a reader\n * (the parent pool) may race a writer that gets SIGKILLed mid-write.\n *\n * Throws on failure like writeFileSync; callers that treat persistence as\n * best-effort keep their own try/catch.\n */\nexport function writeFileAtomicSync(path: string, data: string): void {\n\tmkdirSync(dirname(path), { recursive: true });\n\tconst tempPath = join(dirname(path), `.${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}.tmp`);\n\ttry {\n\t\twriteFileSync(tempPath, data);\n\t\trenameSync(tempPath, path);\n\t} catch (error) {\n\t\trmSync(tempPath, { force: true });\n\t\tthrow error;\n\t}\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kolisachint/hoocode-agent",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.111",
|
|
4
4
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"hoocodeConfig": {
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
"prepublishOnly": "npm run clean && npm run build"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@kolisachint/hoocode-agent-core": "^0.4.
|
|
49
|
-
"@kolisachint/hoocode-ai": "^0.4.
|
|
50
|
-
"@kolisachint/hoocode-tui": "^0.4.
|
|
48
|
+
"@kolisachint/hoocode-agent-core": "^0.4.111",
|
|
49
|
+
"@kolisachint/hoocode-ai": "^0.4.111",
|
|
50
|
+
"@kolisachint/hoocode-tui": "^0.4.111",
|
|
51
51
|
"@silvia-odwyer/photon-node": "^0.3.4",
|
|
52
52
|
"chalk": "^5.5.0",
|
|
53
53
|
"cli-highlight": "^2.1.11",
|