@vincemakes/kiso-code 0.1.46 → 0.1.48
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/index.d.ts +7 -0
- package/dist/index.js +19 -7
- package/package.json +6 -6
- package/dist/diff.d.ts +0 -32
- package/dist/diff.js +0 -122
package/dist/index.d.ts
CHANGED
|
@@ -23,6 +23,13 @@
|
|
|
23
23
|
* makeAgent, and main.
|
|
24
24
|
*/
|
|
25
25
|
export { applyProjectMerges } from "./trust-ui.js";
|
|
26
|
+
/**
|
|
27
|
+
* A area: the coding-agent system prompt — ONE constant, byte-stable for the
|
|
28
|
+
* session's lifetime (D area). Kept under ~80 lines; no template engine.
|
|
29
|
+
*/
|
|
30
|
+
/** The built-in prompt. Exported for scripts/request-surface.mjs — the
|
|
31
|
+
* model-side token-rent counter measures the REAL bytes, never a copy. */
|
|
32
|
+
export declare const SYSTEM_PROMPT = "You are kiso, a coding agent. You work in a workspace\ndirectory and change code with tools. Be concise: answer in a few lines\nunless the task genuinely needs more. Never claim a file was changed\nunless a tool confirmed it.\n\nTool discipline:\n- READ BEFORE YOU EDIT. For any file you are about to change, read it\n first \u2014 never guess its content.\n- Use edit_file for targeted changes and write_file for full rewrites.\n Prefer many small edits over one large write.\n- shell is for commands: builds, tests, git, grep. Be careful \u2014 shell has\n side effects and may take time. Run one command at a time and inspect\n the output before continuing.\n- Batch independent tool calls into one reply \u2014 they run in parallel.\n- search_text and list_dir are cheap \u2014 locate first, then read ranges\n with read_file offset/limit; never read a whole large file in one call.\n- Do not re-read a file you already read unchanged \u2014 rely on the earlier\n result.\n- When a tool fails, read the error and adjust; do not repeat the same\n call blindly.\n\nWorkflow: understand the request, find the relevant code, make the\nsmallest change that works, then verify with a command (tests/build).\nReport what you did in one or two lines per change.";
|
|
26
33
|
/**
|
|
27
34
|
* A area: read the FIRST present instruction file (AGENTS.md preferred) and
|
|
28
35
|
* return it as an injected section, or "" when none exists. Truncated at
|
package/dist/index.js
CHANGED
|
@@ -128,6 +128,12 @@ function editorInput(editor) {
|
|
|
128
128
|
},
|
|
129
129
|
onEot(cb) {
|
|
130
130
|
editor.onEot(cb);
|
|
131
|
+
// E group (the graceful-exit gate ③): a closed pty master is an
|
|
132
|
+
// EOF, not a \x04 byte — the editor's raw key loop never sees it.
|
|
133
|
+
// The stream's 'end' fires the same EOT callback; the chat/resume
|
|
134
|
+
// exit condition (no run, no panel, empty line) decides, so the
|
|
135
|
+
// exit sequence — and with it the lock release — runs.
|
|
136
|
+
process.stdin.on("end", () => cb());
|
|
131
137
|
},
|
|
132
138
|
onEscape(cb) {
|
|
133
139
|
editor.onEscape(cb);
|
|
@@ -243,7 +249,9 @@ function recentSessions(id, agent) {
|
|
|
243
249
|
* A area: the coding-agent system prompt — ONE constant, byte-stable for the
|
|
244
250
|
* session's lifetime (D area). Kept under ~80 lines; no template engine.
|
|
245
251
|
*/
|
|
246
|
-
|
|
252
|
+
/** The built-in prompt. Exported for scripts/request-surface.mjs — the
|
|
253
|
+
* model-side token-rent counter measures the REAL bytes, never a copy. */
|
|
254
|
+
export const SYSTEM_PROMPT = `You are kiso, a coding agent. You work in a workspace
|
|
247
255
|
directory and change code with tools. Be concise: answer in a few lines
|
|
248
256
|
unless the task genuinely needs more. Never claim a file was changed
|
|
249
257
|
unless a tool confirmed it.
|
|
@@ -459,7 +467,7 @@ async function main() {
|
|
|
459
467
|
dock.enter();
|
|
460
468
|
// E area: a resumed session continues the script at its durable
|
|
461
469
|
// position — never restarts it (fauxSkip).
|
|
462
|
-
|
|
470
|
+
agent = await makeAgent(id, input, modelFlag);
|
|
463
471
|
applyConfigMode();
|
|
464
472
|
const session = await agent.session({ id });
|
|
465
473
|
bodyLog(`session ${id}\n`);
|
|
@@ -477,7 +485,7 @@ async function main() {
|
|
|
477
485
|
// (argv = [node, script, resume, id, prompt?]).
|
|
478
486
|
const prompt = process.argv[4];
|
|
479
487
|
dock.enter();
|
|
480
|
-
|
|
488
|
+
agent = await makeAgent(arg, input, modelFlag);
|
|
481
489
|
applyConfigMode();
|
|
482
490
|
const session = await agent.session({ id: arg });
|
|
483
491
|
faux = currentFaux;
|
|
@@ -485,7 +493,7 @@ async function main() {
|
|
|
485
493
|
break;
|
|
486
494
|
}
|
|
487
495
|
case "sessions": {
|
|
488
|
-
|
|
496
|
+
agent = await makeAgent(undefined, undefined, modelFlag);
|
|
489
497
|
for (const meta of agent.sessions()) {
|
|
490
498
|
console.log(renderSessionLine(meta));
|
|
491
499
|
}
|
|
@@ -508,7 +516,7 @@ async function main() {
|
|
|
508
516
|
// chat — the first argument is the session id.
|
|
509
517
|
const id = command ?? new Date().toISOString().replace(/[:.]/g, "-").slice(0, 16);
|
|
510
518
|
dock.enter();
|
|
511
|
-
|
|
519
|
+
agent = await makeAgent(id);
|
|
512
520
|
const session = await agent.session({ id });
|
|
513
521
|
bodyLog(`session ${id}\n`);
|
|
514
522
|
extensionsBanner(recentSessions(id, agent));
|
|
@@ -520,8 +528,12 @@ async function main() {
|
|
|
520
528
|
finally {
|
|
521
529
|
body.close(); // flush the pending frame, stop the heartbeat
|
|
522
530
|
input.close();
|
|
523
|
-
// E group:
|
|
524
|
-
//
|
|
531
|
+
// E group: a NORMAL exit releases the fds and writer locks — the
|
|
532
|
+
// empty released marker is left at the lock path (finding #5: the
|
|
533
|
+
// agent used to be shadowed here; the four branches assign the outer
|
|
534
|
+
// variable now). A signal death skips this and leaves the dead-pid
|
|
535
|
+
// residue — the dead-holder takeover recovers it by design
|
|
536
|
+
// (ADR-0050); the lock never outlives a live writer either way.
|
|
525
537
|
agent?.close();
|
|
526
538
|
// v2b: the dock tears down on EVERY exit path — CSI r resets the
|
|
527
539
|
// scroll region, the cursor lands at the input line, no broken
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vincemakes/kiso-code",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.48",
|
|
4
4
|
"description": "kiso CLI — the coding-agent reference product: kiso chat / kiso resume / kiso sessions.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -20,13 +20,13 @@
|
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@vincemakes/kiso-core": "0.1.35",
|
|
22
22
|
"@vincemakes/kiso-evals": "0.1.36",
|
|
23
|
-
"@vincemakes/kiso-mcp-ext": "0.1.
|
|
23
|
+
"@vincemakes/kiso-mcp-ext": "0.1.48",
|
|
24
24
|
"@vincemakes/kiso-provider-anthropic": "0.1.36",
|
|
25
25
|
"@vincemakes/kiso-provider-openai": "0.1.36",
|
|
26
|
-
"@vincemakes/kiso-runtime": "0.1.
|
|
27
|
-
"@vincemakes/kiso-skills-ext": "0.1.
|
|
28
|
-
"@vincemakes/kiso-subagent-ext": "0.1.
|
|
29
|
-
"@vincemakes/kiso-task-ext": "0.1.
|
|
26
|
+
"@vincemakes/kiso-runtime": "0.1.38",
|
|
27
|
+
"@vincemakes/kiso-skills-ext": "0.1.48",
|
|
28
|
+
"@vincemakes/kiso-subagent-ext": "0.1.48",
|
|
29
|
+
"@vincemakes/kiso-task-ext": "0.1.48",
|
|
30
30
|
"@vincemakes/kiso-tools-node": "0.1.36",
|
|
31
31
|
"@vincemakes/kiso-tui": "0.1.42",
|
|
32
32
|
"@vincemakes/kiso-tui-cells": "0.1.42"
|
package/dist/diff.d.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* v2e — the diff renderer: edit/write changes as inline ± lines, zero
|
|
3
|
-
* dependencies, no syntax highlighting (the spec's scope line). Shown at
|
|
4
|
-
* the approval moment ONLY — the frozen summary stays one line (v2d's
|
|
5
|
-
* anti-leak principle), /last has the full data.
|
|
6
|
-
*
|
|
7
|
-
* edit_file diffs IN PLACE (the search→replace windows are known — no
|
|
8
|
-
* general engine needed); write_file does a row-level LCS over the old
|
|
9
|
-
* file (small files are the target). Context: 2 rows each side. The
|
|
10
|
-
* RENDERER truncates (18 head + 18 tail + "… N lines"); the stats come
|
|
11
|
-
* from the full diff.
|
|
12
|
-
*/
|
|
13
|
-
/** The diff block's per-row kind. */
|
|
14
|
-
export type DiffLine = {
|
|
15
|
-
kind: "-" | "+" | " ";
|
|
16
|
-
text: string;
|
|
17
|
-
};
|
|
18
|
-
export interface DiffResult {
|
|
19
|
-
/** The FULL diff (with context, not truncated) — the display truncates. */
|
|
20
|
-
lines: DiffLine[];
|
|
21
|
-
added: number;
|
|
22
|
-
removed: number;
|
|
23
|
-
}
|
|
24
|
-
/** The RENDERER's truncation: head + "… N lines (/last for full)" + tail. */
|
|
25
|
-
export declare function truncateDiff(diff: DiffLine[]): DiffLine[];
|
|
26
|
-
/** edit_file: the search→replace windows replace in place — the changed
|
|
27
|
-
* region is KNOWN, so the diff is the old window vs the new window,
|
|
28
|
-
* context from the surrounding file. */
|
|
29
|
-
export declare function editFileDiff(oldContent: string, search: string, replace: string): DiffResult;
|
|
30
|
-
/** write_file: a new file is all +; an existing file diffs row-level
|
|
31
|
-
* against its old content. */
|
|
32
|
-
export declare function writeFileDiff(oldContent: string | null, newContent: string): DiffResult;
|
package/dist/diff.js
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* v2e — the diff renderer: edit/write changes as inline ± lines, zero
|
|
3
|
-
* dependencies, no syntax highlighting (the spec's scope line). Shown at
|
|
4
|
-
* the approval moment ONLY — the frozen summary stays one line (v2d's
|
|
5
|
-
* anti-leak principle), /last has the full data.
|
|
6
|
-
*
|
|
7
|
-
* edit_file diffs IN PLACE (the search→replace windows are known — no
|
|
8
|
-
* general engine needed); write_file does a row-level LCS over the old
|
|
9
|
-
* file (small files are the target). Context: 2 rows each side. The
|
|
10
|
-
* RENDERER truncates (18 head + 18 tail + "… N lines"); the stats come
|
|
11
|
-
* from the full diff.
|
|
12
|
-
*/
|
|
13
|
-
/** A line-level LCS diff — the classic two-row DP, ~small inputs. */
|
|
14
|
-
function lcsDiff(oldLines, newLines) {
|
|
15
|
-
const n = oldLines.length;
|
|
16
|
-
const m = newLines.length;
|
|
17
|
-
const dp = Array.from({ length: n + 1 }, () => new Array(m + 1).fill(0));
|
|
18
|
-
for (let i = n - 1; i >= 0; i -= 1) {
|
|
19
|
-
for (let j = m - 1; j >= 0; j -= 1) {
|
|
20
|
-
dp[i][j] = oldLines[i] === newLines[j] ? dp[i + 1][j + 1] + 1 : Math.max(dp[i + 1][j], dp[i][j + 1]);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
const out = [];
|
|
24
|
-
let i = 0;
|
|
25
|
-
let j = 0;
|
|
26
|
-
while (i < n && j < m) {
|
|
27
|
-
if (oldLines[i] === newLines[j]) {
|
|
28
|
-
out.push({ kind: " ", text: oldLines[i] });
|
|
29
|
-
i += 1;
|
|
30
|
-
j += 1;
|
|
31
|
-
}
|
|
32
|
-
else if (dp[i + 1][j] >= dp[i][j + 1]) {
|
|
33
|
-
out.push({ kind: "-", text: oldLines[i] });
|
|
34
|
-
i += 1;
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
out.push({ kind: "+", text: newLines[j] });
|
|
38
|
-
j += 1;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
while (i < n) {
|
|
42
|
-
out.push({ kind: "-", text: oldLines[i] });
|
|
43
|
-
i += 1;
|
|
44
|
-
}
|
|
45
|
-
while (j < m) {
|
|
46
|
-
out.push({ kind: "+", text: newLines[j] });
|
|
47
|
-
j += 1;
|
|
48
|
-
}
|
|
49
|
-
return out;
|
|
50
|
-
}
|
|
51
|
-
/** Keep 2 context rows around each change — the unified-style window. */
|
|
52
|
-
function withContext(diff) {
|
|
53
|
-
const out = [];
|
|
54
|
-
let lastAdded = -10;
|
|
55
|
-
for (let k = 0; k < diff.length; k += 1) {
|
|
56
|
-
if (diff[k].kind === " ")
|
|
57
|
-
continue;
|
|
58
|
-
const from = Math.max(0, k - 2);
|
|
59
|
-
const to = Math.min(diff.length - 1, k + 2);
|
|
60
|
-
for (let c = from; c <= to; c += 1) {
|
|
61
|
-
if (c > lastAdded) {
|
|
62
|
-
out.push(diff[c]);
|
|
63
|
-
lastAdded = c;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
lastAdded = to;
|
|
67
|
-
}
|
|
68
|
-
return out;
|
|
69
|
-
}
|
|
70
|
-
const MAX_DIFF_LINES = 40; // the RENDERED cap
|
|
71
|
-
const TRUNCATE_KEEP = 18;
|
|
72
|
-
/** The RENDERER's truncation: head + "… N lines (/last for full)" + tail. */
|
|
73
|
-
export function truncateDiff(diff) {
|
|
74
|
-
if (diff.length <= MAX_DIFF_LINES)
|
|
75
|
-
return diff;
|
|
76
|
-
const omitted = diff.length - 2 * TRUNCATE_KEEP;
|
|
77
|
-
return [
|
|
78
|
-
...diff.slice(0, TRUNCATE_KEEP),
|
|
79
|
-
{ kind: " ", text: `… ${omitted} lines (/last for full)` },
|
|
80
|
-
...diff.slice(diff.length - TRUNCATE_KEEP),
|
|
81
|
-
];
|
|
82
|
-
}
|
|
83
|
-
function stats(diff) {
|
|
84
|
-
let added = 0;
|
|
85
|
-
let removed = 0;
|
|
86
|
-
for (const d of diff) {
|
|
87
|
-
if (d.kind === "+")
|
|
88
|
-
added += 1;
|
|
89
|
-
else if (d.kind === "-")
|
|
90
|
-
removed += 1;
|
|
91
|
-
}
|
|
92
|
-
return { added, removed };
|
|
93
|
-
}
|
|
94
|
-
/** edit_file: the search→replace windows replace in place — the changed
|
|
95
|
-
* region is KNOWN, so the diff is the old window vs the new window,
|
|
96
|
-
* context from the surrounding file. */
|
|
97
|
-
export function editFileDiff(oldContent, search, replace) {
|
|
98
|
-
const oldLines = oldContent.split("\n");
|
|
99
|
-
const searchLines = search.split("\n");
|
|
100
|
-
const replaceLines = replace.split("\n");
|
|
101
|
-
// Locate the search window (the first occurrence — the edit tool's own
|
|
102
|
-
// semantics); no occurrence → the whole file is the old side.
|
|
103
|
-
let at = -1;
|
|
104
|
-
for (let i = 0; i + searchLines.length <= oldLines.length; i += 1) {
|
|
105
|
-
if (oldLines.slice(i, i + searchLines.length).join("\n") === search) {
|
|
106
|
-
at = i;
|
|
107
|
-
break;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
const lines = at < 0 ? withContext(lcsDiff(oldLines, replaceLines)) : withContext(lcsDiff(oldLines, [...oldLines.slice(0, at), ...replaceLines, ...oldLines.slice(at + searchLines.length)]));
|
|
111
|
-
return { lines, ...stats(lines) };
|
|
112
|
-
}
|
|
113
|
-
/** write_file: a new file is all +; an existing file diffs row-level
|
|
114
|
-
* against its old content. */
|
|
115
|
-
export function writeFileDiff(oldContent, newContent) {
|
|
116
|
-
if (oldContent === null) {
|
|
117
|
-
const lines = newContent.split("\n").map((text) => ({ kind: "+", text }));
|
|
118
|
-
return { lines, added: lines.length, removed: 0 };
|
|
119
|
-
}
|
|
120
|
-
const lines = withContext(lcsDiff(oldContent.split("\n"), newContent.split("\n")));
|
|
121
|
-
return { lines, ...stats(lines) };
|
|
122
|
-
}
|