@vincemakes/kiso-code 0.2.2 → 0.4.0
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/builtin.js +12 -4
- package/dist/index.d.ts +20 -0
- package/dist/index.js +60 -18
- package/dist/state.d.ts +4 -3
- package/dist/state.js +4 -3
- package/package.json +3 -3
package/dist/builtin.js
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* R-D 0.1.45 — the built-in layer: the
|
|
3
|
-
* skills, subagent
|
|
2
|
+
* R-D 0.1.45 — the built-in layer: the three official extensions (mcp,
|
|
3
|
+
* skills, subagent), shipped in the cli package and registered by
|
|
4
4
|
* MODULE IMPORT — never a disk scan (the user layer's loadExtensions stays
|
|
5
5
|
* word-for-word untouched). The cascade, base → top: built-in → user
|
|
6
6
|
* (~/.kiso/extensions) → project (.kiso/extensions, trust-gated).
|
|
7
7
|
*
|
|
8
|
+
* E5 (the composition round, finding E5-F1/F2): the task extension left
|
|
9
|
+
* the default composition — on 13 consecutive real-provider sessions it
|
|
10
|
+
* paid its rent (system:ext:task + tool:task_set on every request) and
|
|
11
|
+
* was never called, not even on the guidance's own designed trigger. It
|
|
12
|
+
* stays an official extension, OPT-IN via the user layer: copy
|
|
13
|
+
* extensions/task/src/kiso-task.mjs into ~/.kiso/extensions/ (a user or
|
|
14
|
+
* project extension named "task" is now a plain extension — no built-in
|
|
15
|
+
* to shadow or collide with).
|
|
16
|
+
*
|
|
8
17
|
* - a user extension may SHADOW a built-in by name — the user's deliberate
|
|
9
18
|
* install wins (a built-in cannot be uninstalled), loudly, and the
|
|
10
19
|
* shadowed built-in leaves the loaded set and the banner;
|
|
@@ -15,9 +24,8 @@
|
|
|
15
24
|
import createMcp from "@vincemakes/kiso-mcp-ext";
|
|
16
25
|
import createSkills from "@vincemakes/kiso-skills-ext";
|
|
17
26
|
import createSubagent from "@vincemakes/kiso-subagent-ext";
|
|
18
|
-
import createTask from "@vincemakes/kiso-task-ext";
|
|
19
27
|
export async function builtInLayer(user, project) {
|
|
20
|
-
const all = await Promise.all([createMcp(), createSkills(), createSubagent()
|
|
28
|
+
const all = await Promise.all([createMcp(), createSkills(), createSubagent()]);
|
|
21
29
|
const shadowed = all.filter((b) => user.some((u) => u.name === b.name));
|
|
22
30
|
for (const s of shadowed) {
|
|
23
31
|
console.error(`[extensions] user extension "${s.name}" shadows the built-in — the built-in is not loaded`);
|
package/dist/index.d.ts
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
* index.ts keeps the entry: banner, input sources, the A area prompt,
|
|
23
23
|
* makeAgent, and main.
|
|
24
24
|
*/
|
|
25
|
+
import { type ContextPolicy } from "@vincemakes/kiso-runtime";
|
|
25
26
|
export { applyProjectMerges } from "./trust-ui.js";
|
|
26
27
|
/**
|
|
27
28
|
* A area: the coding-agent system prompt — ONE constant, byte-stable for the
|
|
@@ -30,6 +31,7 @@ export { applyProjectMerges } from "./trust-ui.js";
|
|
|
30
31
|
/** The built-in prompt. Exported for scripts/request-surface.mjs — the
|
|
31
32
|
* model-side token-rent counter measures the REAL bytes, never a copy. */
|
|
32
33
|
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.";
|
|
34
|
+
/** Hard cap for injected instructions — truncate and say so. */
|
|
33
35
|
/**
|
|
34
36
|
* A area: read the FIRST present instruction file (AGENTS.md preferred) and
|
|
35
37
|
* return it as an injected section, or "" when none exists. Truncated at
|
|
@@ -40,3 +42,21 @@ export declare function readProjectInstructions(cwd: string): string;
|
|
|
40
42
|
/** A area: the session's system prompt — the constant plus any project
|
|
41
43
|
* instructions found in the workspace. Deterministic per cwd. */
|
|
42
44
|
export declare function composeSystemPrompt(cwd: string): string;
|
|
45
|
+
/**
|
|
46
|
+
* E6: the run-start context policy, OFF unless env-armed (invalid values
|
|
47
|
+
* are ABSENT, never a crash — the autoCompactFromEnv convention).
|
|
48
|
+
* The product arming is KISO_CONTEXT_WINDOW → window − POLICY_RESERVE
|
|
49
|
+
* (the window rides the config as windowTokens; the runtime owns the
|
|
50
|
+
* arithmetic — never a fixed low absolute). KISO_POLICY_SUMMARY_TRIGGER
|
|
51
|
+
* survives ONLY as the legacy absolute override when no window is set
|
|
52
|
+
* (bench back-compat); the window wins when both are set.
|
|
53
|
+
* KISO_POLICY_SUMMARY_KEEP (rounds) and KISO_POLICY_SUMMARY_KEEP_TOKENS
|
|
54
|
+
* override the runtime defaults (KEEP_RECENT_ROUNDS = 4,
|
|
55
|
+
* KEEP_TOKENS_DEFAULT = 20,000) — emitted only when set.
|
|
56
|
+
* KISO_POLICY_SUMMARY_MAX_FAILURES overrides the (h) circuit-breaker
|
|
57
|
+
* default (MAX_SUMMARY_FAILURES = 3).
|
|
58
|
+
* KISO_POLICY_DROP=1 switches the armed mode to the crux C arm
|
|
59
|
+
* (mechanical drop — same trigger/keep envs); KISO_POLICY_MICROCOMPACT
|
|
60
|
+
* arms the session-aware override (MIN_TURNS = the no-fire guard).
|
|
61
|
+
*/
|
|
62
|
+
export declare function contextPolicyFromEnv(): ContextPolicy | undefined;
|
package/dist/index.js
CHANGED
|
@@ -26,8 +26,7 @@ import { readFileSync, realpathSync, rmSync } from "node:fs";
|
|
|
26
26
|
import { createInterface } from "node:readline";
|
|
27
27
|
import { fileURLToPath } from "node:url";
|
|
28
28
|
import { join } from "node:path";
|
|
29
|
-
import { Body, Editor, bannerLines, palette, renderSessionLine } from "@vincemakes/kiso-tui";
|
|
30
|
-
import { escapeTerminal } from "@vincemakes/kiso-tui";
|
|
29
|
+
import { Body, Editor, bannerLines, escapeTerminal, palette, renderSessionLine } from "@vincemakes/kiso-tui";
|
|
31
30
|
import { createAgent, disposeExtensions, loadExtensions, loadProjectExtensions, SessionStore, } from "@vincemakes/kiso-runtime";
|
|
32
31
|
import { createFauxProvider } from "@vincemakes/kiso-evals";
|
|
33
32
|
import { createCodingTools } from "@vincemakes/kiso-tools-node";
|
|
@@ -200,8 +199,8 @@ function makeLineInput() {
|
|
|
200
199
|
/** R-D 0.1.45: the `[N extensions: ...]` text — the built-in column, then
|
|
201
200
|
* the user-level names, then the project-level ones marked `project:`.
|
|
202
201
|
* The built-in column is the banner's truthful face of the built-in layer:
|
|
203
|
-
* a fresh install reads `[
|
|
204
|
-
*
|
|
202
|
+
* a fresh install reads `[3 extensions: built-in: mcp, skills, subagent]`
|
|
203
|
+
* with zero disk setup (E5: the task extension is opt-in). */
|
|
205
204
|
function bannerExtensionText() {
|
|
206
205
|
const total = builtInExtensions.length + userExtensions.length + projectExtensions.length;
|
|
207
206
|
if (total === 0)
|
|
@@ -223,14 +222,13 @@ function bannerExtensionText() {
|
|
|
223
222
|
* resize; the resume list re-gates with the tier); off-TTY: the
|
|
224
223
|
* historical `[N extensions: ...]` standalone line (zero change). */
|
|
225
224
|
function extensionsBanner(resume = []) {
|
|
226
|
-
if (process.stdout.isTTY) {
|
|
227
|
-
body.banner(VERSION, bannerExtensionText().replace(/^ · /, ""), resume);
|
|
228
|
-
return;
|
|
229
|
-
}
|
|
230
225
|
const text = bannerExtensionText();
|
|
231
|
-
if (
|
|
226
|
+
if (!process.stdout.isTTY) {
|
|
227
|
+
if (text !== "")
|
|
228
|
+
bodyLog(`${text}\n`);
|
|
232
229
|
return;
|
|
233
|
-
|
|
230
|
+
}
|
|
231
|
+
body.banner(VERSION, text.replace(/^ · /, ""), resume);
|
|
234
232
|
}
|
|
235
233
|
/** W5: the opening-screen resume list — up to 3 recent sessions, newest
|
|
236
234
|
* first, the CURRENT session excluded (it is not something to pick back
|
|
@@ -278,7 +276,6 @@ Report what you did in one or two lines per change.`;
|
|
|
278
276
|
/** The project-instructions file names, in priority order (A area). */
|
|
279
277
|
const INSTRUCTION_FILES = ["AGENTS.md", "CLAUDE.md"];
|
|
280
278
|
/** Hard cap for injected instructions — truncate and say so. */
|
|
281
|
-
const INSTRUCTION_MAX = 8 * 1024;
|
|
282
279
|
/**
|
|
283
280
|
* A area: read the FIRST present instruction file (AGENTS.md preferred) and
|
|
284
281
|
* return it as an injected section, or "" when none exists. Truncated at
|
|
@@ -294,8 +291,7 @@ export function readProjectInstructions(cwd) {
|
|
|
294
291
|
catch {
|
|
295
292
|
continue; // not present — try the next
|
|
296
293
|
}
|
|
297
|
-
|
|
298
|
-
return `\n\n=== Project instructions (${name}) ===\n${body}`;
|
|
294
|
+
return `\n\n=== Project instructions (${name}) ===\n${text.length > 8 * 1024 ? text.slice(0, 8 * 1024) + `\n\n[truncated at ${8 * 1024} chars]` : text}`;
|
|
299
295
|
}
|
|
300
296
|
return "";
|
|
301
297
|
}
|
|
@@ -305,6 +301,51 @@ export function composeSystemPrompt(cwd) {
|
|
|
305
301
|
const injected = readProjectInstructions(cwd);
|
|
306
302
|
return injected === "" ? SYSTEM_PROMPT : `${SYSTEM_PROMPT}\n${injected}`;
|
|
307
303
|
}
|
|
304
|
+
/**
|
|
305
|
+
* E6: the run-start context policy, OFF unless env-armed (invalid values
|
|
306
|
+
* are ABSENT, never a crash — the autoCompactFromEnv convention).
|
|
307
|
+
* The product arming is KISO_CONTEXT_WINDOW → window − POLICY_RESERVE
|
|
308
|
+
* (the window rides the config as windowTokens; the runtime owns the
|
|
309
|
+
* arithmetic — never a fixed low absolute). KISO_POLICY_SUMMARY_TRIGGER
|
|
310
|
+
* survives ONLY as the legacy absolute override when no window is set
|
|
311
|
+
* (bench back-compat); the window wins when both are set.
|
|
312
|
+
* KISO_POLICY_SUMMARY_KEEP (rounds) and KISO_POLICY_SUMMARY_KEEP_TOKENS
|
|
313
|
+
* override the runtime defaults (KEEP_RECENT_ROUNDS = 4,
|
|
314
|
+
* KEEP_TOKENS_DEFAULT = 20,000) — emitted only when set.
|
|
315
|
+
* KISO_POLICY_SUMMARY_MAX_FAILURES overrides the (h) circuit-breaker
|
|
316
|
+
* default (MAX_SUMMARY_FAILURES = 3).
|
|
317
|
+
* KISO_POLICY_DROP=1 switches the armed mode to the crux C arm
|
|
318
|
+
* (mechanical drop — same trigger/keep envs); KISO_POLICY_MICROCOMPACT
|
|
319
|
+
* arms the session-aware override (MIN_TURNS = the no-fire guard).
|
|
320
|
+
*/
|
|
321
|
+
export function contextPolicyFromEnv() {
|
|
322
|
+
const summaryTrigger = positiveIntEnv("KISO_POLICY_SUMMARY_TRIGGER");
|
|
323
|
+
const contextWindow = positiveIntEnv("KISO_CONTEXT_WINDOW");
|
|
324
|
+
const microcompactTrigger = positiveIntEnv("KISO_POLICY_MICROCOMPACT");
|
|
325
|
+
if (summaryTrigger === undefined && contextWindow === undefined && microcompactTrigger === undefined)
|
|
326
|
+
return undefined;
|
|
327
|
+
return {
|
|
328
|
+
...(summaryTrigger === undefined && contextWindow === undefined ? {} : {
|
|
329
|
+
[(process.env.KISO_POLICY_DROP === "1" ? "drop" : "summary")]: {
|
|
330
|
+
...(contextWindow !== undefined ? { windowTokens: contextWindow } : summaryTrigger !== undefined ? { triggerTokens: summaryTrigger } : {}),
|
|
331
|
+
...kv("keepRounds", "KISO_POLICY_SUMMARY_KEEP"),
|
|
332
|
+
...kv("keepTokens", "KISO_POLICY_SUMMARY_KEEP_TOKENS"),
|
|
333
|
+
...kv("maxFailures", "KISO_POLICY_SUMMARY_MAX_FAILURES"),
|
|
334
|
+
},
|
|
335
|
+
}),
|
|
336
|
+
...(microcompactTrigger !== undefined ? { microcompact: { thresholdTokens: microcompactTrigger, ...kv("keepResults", "KISO_POLICY_MICROCOMPACT_KEEP"), ...kv("minTurns", "KISO_POLICY_MICROCOMPACT_MIN_TURNS") } } : {}),
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
/** { [key]: value } when the env int is set — the spread-friendly optional field. */
|
|
340
|
+
function kv(key, env) {
|
|
341
|
+
const v = positiveIntEnv(env);
|
|
342
|
+
return v !== undefined ? { [key]: v } : {};
|
|
343
|
+
}
|
|
344
|
+
/** Parse a positive-int env var — absent or invalid is undefined (no crash). */
|
|
345
|
+
function positiveIntEnv(name) {
|
|
346
|
+
const n = Number.parseInt(process.env[name] ?? "", 10);
|
|
347
|
+
return Number.isFinite(n) && n > 0 ? n : undefined;
|
|
348
|
+
}
|
|
308
349
|
async function makeAgent(sessionId, input, modelFlag) {
|
|
309
350
|
// E3: the project-level trust gate runs BEFORE any extension load (the
|
|
310
351
|
// mcp/skills merges must be in the env when the user-level extensions
|
|
@@ -358,6 +399,8 @@ async function makeAgent(sessionId, input, modelFlag) {
|
|
|
358
399
|
// re-reads the config's extensions array per run).
|
|
359
400
|
const extensions = [...modeExtensions(), ...loadedExtensions];
|
|
360
401
|
setCurrentAgentExtensions(extensions);
|
|
402
|
+
// E6: the run-start context policy (captured once — exactOptionalPropertyTypes).
|
|
403
|
+
const contextPolicy = contextPolicyFromEnv();
|
|
361
404
|
const definition = {
|
|
362
405
|
model,
|
|
363
406
|
store,
|
|
@@ -379,6 +422,8 @@ async function makeAgent(sessionId, input, modelFlag) {
|
|
|
379
422
|
// 200k window → 100k tokens). Long sessions compact old read/list/
|
|
380
423
|
// search/shell outputs instead of silently growing past the window.
|
|
381
424
|
microcompact: { thresholdTokens: contextWindowTokens() / 2 },
|
|
425
|
+
// E6: the run-start context policy — OFF unless env-armed (beats the microcompact default when both fire).
|
|
426
|
+
...(contextPolicy !== undefined ? { contextPolicy } : {}),
|
|
382
427
|
maxTurns: 20,
|
|
383
428
|
// Modes: the five tiers join at the CHAIN HEAD, before the user/
|
|
384
429
|
// project extensions (the deny>ask>allow composition keeps a user
|
|
@@ -462,11 +507,8 @@ async function main() {
|
|
|
462
507
|
// (its verdict decides whether the project config exists at all) —
|
|
463
508
|
// unless a higher layer (--mode flag / KISO_MODE) already decided.
|
|
464
509
|
const applyConfigMode = () => {
|
|
465
|
-
if (modeFlag
|
|
466
|
-
|
|
467
|
-
const m = mergedConfig.mode;
|
|
468
|
-
if (m !== undefined)
|
|
469
|
-
setMode(m);
|
|
510
|
+
if (modeFlag === -1 && process.env.KISO_MODE === undefined && mergedConfig.mode !== undefined)
|
|
511
|
+
setMode(mergedConfig.mode);
|
|
470
512
|
};
|
|
471
513
|
switch (command) {
|
|
472
514
|
case "chat": {
|
package/dist/state.d.ts
CHANGED
|
@@ -87,9 +87,10 @@ export declare let currentModelName: string;
|
|
|
87
87
|
export declare function setCurrentModelName(value: string): void;
|
|
88
88
|
/** E1: the extensions loaded by makeAgent — their names feed the banner. */
|
|
89
89
|
export declare let loadedExtensions: readonly KisoExtension[];
|
|
90
|
-
/** R-D 0.1.45: the BUILT-IN layer — the
|
|
91
|
-
* with the cli (module imports, never a disk scan; builtin.ts).
|
|
92
|
-
*
|
|
90
|
+
/** R-D 0.1.45: the BUILT-IN layer — the three default official extensions,
|
|
91
|
+
* shipped with the cli (module imports, never a disk scan; builtin.ts).
|
|
92
|
+
* E5: the task extension is opt-in, not built-in. The banner's marked
|
|
93
|
+
* column; a user extension may shadow a built-in. */
|
|
93
94
|
export declare let builtInExtensions: readonly KisoExtension[];
|
|
94
95
|
/** E1: the USER-level extensions alone — the banner's unmarked part (E3:
|
|
95
96
|
* loadedExtensions later includes the project-level ones too). */
|
package/dist/state.js
CHANGED
|
@@ -78,9 +78,10 @@ export function setCurrentModelName(value) {
|
|
|
78
78
|
}
|
|
79
79
|
/** E1: the extensions loaded by makeAgent — their names feed the banner. */
|
|
80
80
|
export let loadedExtensions = [];
|
|
81
|
-
/** R-D 0.1.45: the BUILT-IN layer — the
|
|
82
|
-
* with the cli (module imports, never a disk scan; builtin.ts).
|
|
83
|
-
*
|
|
81
|
+
/** R-D 0.1.45: the BUILT-IN layer — the three default official extensions,
|
|
82
|
+
* shipped with the cli (module imports, never a disk scan; builtin.ts).
|
|
83
|
+
* E5: the task extension is opt-in, not built-in. The banner's marked
|
|
84
|
+
* column; a user extension may shadow a built-in. */
|
|
84
85
|
export let builtInExtensions = [];
|
|
85
86
|
/** E1: the USER-level extensions alone — the banner's unmarked part (E3:
|
|
86
87
|
* loadedExtensions later includes the project-level ones too). */
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vincemakes/kiso-code",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "kiso CLI
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "kiso CLI — the durable coding agent that survives kill -9: kiso chat / kiso resume / kiso sessions.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"bin": {
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"@vincemakes/kiso-mcp-ext": "0.2.0",
|
|
24
24
|
"@vincemakes/kiso-provider-anthropic": "0.2.0",
|
|
25
25
|
"@vincemakes/kiso-provider-openai": "0.2.0",
|
|
26
|
-
"@vincemakes/kiso-runtime": "0.
|
|
26
|
+
"@vincemakes/kiso-runtime": "0.3.0",
|
|
27
27
|
"@vincemakes/kiso-skills-ext": "0.2.0",
|
|
28
28
|
"@vincemakes/kiso-subagent-ext": "0.2.0",
|
|
29
29
|
"@vincemakes/kiso-task-ext": "0.2.0",
|