@vincemakes/kiso-code 0.7.0 → 0.8.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.d.ts +7 -1
- package/dist/builtin.js +8 -2
- package/dist/dispatch.js +10 -18
- package/dist/index.js +12 -17
- package/dist/trust-ui.d.ts +19 -0
- package/dist/trust-ui.js +32 -2
- package/package.json +14 -13
package/dist/builtin.d.ts
CHANGED
|
@@ -1,2 +1,8 @@
|
|
|
1
|
+
import { type AskUI } from "@vincemakes/kiso-ask-ext";
|
|
1
2
|
import type { KisoExtension } from "@vincemakes/kiso-runtime";
|
|
2
|
-
export declare function builtInLayer(user: readonly KisoExtension[], project: readonly KisoExtension[]
|
|
3
|
+
export declare function builtInLayer(user: readonly KisoExtension[], project: readonly KisoExtension[],
|
|
4
|
+
/** KC3.5: built-in #4 — the ask extension, loaded ONLY when a panel
|
|
5
|
+
* bridge exists (an interactive TTY). No bridge, no fourth built-in:
|
|
6
|
+
* a headless session never pays the rent for a question nobody could
|
|
7
|
+
* answer, and its tool table cannot mention ask_user. */
|
|
8
|
+
ask?: AskUI): Promise<readonly KisoExtension[]>;
|
package/dist/builtin.js
CHANGED
|
@@ -24,8 +24,14 @@
|
|
|
24
24
|
import createMcp from "@vincemakes/kiso-mcp-ext";
|
|
25
25
|
import createSkills from "@vincemakes/kiso-skills-ext";
|
|
26
26
|
import createSubagent from "@vincemakes/kiso-subagent-ext";
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
import createAsk, {} from "@vincemakes/kiso-ask-ext";
|
|
28
|
+
export async function builtInLayer(user, project,
|
|
29
|
+
/** KC3.5: built-in #4 — the ask extension, loaded ONLY when a panel
|
|
30
|
+
* bridge exists (an interactive TTY). No bridge, no fourth built-in:
|
|
31
|
+
* a headless session never pays the rent for a question nobody could
|
|
32
|
+
* answer, and its tool table cannot mention ask_user. */
|
|
33
|
+
ask) {
|
|
34
|
+
const all = await Promise.all([createMcp(), createSkills(), createSubagent(), ...(ask === undefined ? [] : [createAsk(ask)])]);
|
|
29
35
|
const shadowed = all.filter((b) => user.some((u) => u.name === b.name));
|
|
30
36
|
for (const s of shadowed) {
|
|
31
37
|
console.error(`[extensions] user extension "${s.name}" shadows the built-in — the built-in is not loaded`);
|
package/dist/dispatch.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* turns. The bodies moved verbatim from chat()'s closure; chat provides
|
|
4
4
|
* the context (the chain, the run state, the prompt arming).
|
|
5
5
|
*/
|
|
6
|
-
import { escapeTerminal, kUnit, palette } from "@vincemakes/kiso-tui";
|
|
6
|
+
import { escapeTerminal, helpRows, kUnit, palette } from "@vincemakes/kiso-tui";
|
|
7
7
|
import { buildAdapter } from "@vincemakes/kiso-runtime/internal";
|
|
8
8
|
import { MODES, getMode, setMode } from "./mode.js";
|
|
9
9
|
import { agentModel, body, bodyLog, configModels, dock, setAgentModel, setCurrentModelName } from "./state.js";
|
|
@@ -15,24 +15,16 @@ import { directWriteProfile, profileAvailable } from "./config.js";
|
|
|
15
15
|
export function dispatch(line, ctx) {
|
|
16
16
|
const trimmed = line.trim();
|
|
17
17
|
if (trimmed === "/help") {
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
// KC3.5 slice ⓪ (the extraction): the ROWS moved to the terminal
|
|
19
|
+
// layer's strings module (helpRows — the KC3 §1 pattern: what the
|
|
20
|
+
// human reads is presentation). The FLOW is what stays here, and
|
|
21
|
+
// it is unchanged: print on the chain, then re-prompt. The rows
|
|
22
|
+
// are byte-identical to the eight bodyLog calls they replace —
|
|
23
|
+
// the last one still carries its own \n, so `exit` and `keys`
|
|
24
|
+
// land as two rows from one call (bodyLog splits on \n).
|
|
22
25
|
ctx.chainRef.current = ctx.chainRef.current.then(async () => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
bodyLog(cmd("/last", "show the most recent tool call's input and output"));
|
|
26
|
-
bodyLog(cmd("/status", "show session id, event count, and context estimate"));
|
|
27
|
-
bodyLog(cmd("/mode", "show the approval tier; /mode <name> switches (manual/default/accept-edits/plan/bypass)"));
|
|
28
|
-
bodyLog(cmd("/model", "list model profiles; /model <name|provider/model> switches"));
|
|
29
|
-
bodyLog(cmd("/compact", "summarize the older conversation to free context"));
|
|
30
|
-
// KC1: the composer's keys ride the SAME bodyLog call (it splits
|
|
31
|
-
// on \n) — the help gains a row, the cli source does not.
|
|
32
|
-
// KC2: the redirect joins the same row for the same reason.
|
|
33
|
-
// KC3: and so does the @ picker — the row is where a gesture is
|
|
34
|
-
// taught, and the row costs nothing.
|
|
35
|
-
bodyLog(`${cmd("exit", "leave the session")}\n${cmd("keys", "enter sends · ctrl+J newline (shift+enter where encoded) · esc stops the run · alt+⏎ stops it and sends this instead · @ files")}`);
|
|
26
|
+
for (const row of helpRows())
|
|
27
|
+
bodyLog(row);
|
|
36
28
|
ctx.input.prompt();
|
|
37
29
|
});
|
|
38
30
|
return;
|
package/dist/index.js
CHANGED
|
@@ -26,14 +26,14 @@ 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, escapeTerminal, interactivePrompt, palette, renderSessionLine } from "@vincemakes/kiso-tui";
|
|
29
|
+
import { Body, Editor, bannerLines, escapeTerminal, extensionsBannerText, interactivePrompt, palette, renderSessionLine } from "@vincemakes/kiso-tui";
|
|
30
30
|
import { createAgent, disposeExtensions, loadExtensions, loadProjectExtensions, SessionStore, } from "@vincemakes/kiso-runtime";
|
|
31
31
|
import { createFauxProvider } from "@vincemakes/kiso-evals";
|
|
32
32
|
import { createCodingTools } from "@vincemakes/kiso-tools-node";
|
|
33
33
|
import { MODES, modeExtensions, modeFromEnv, modeSystemPrompt, setMode } from "./mode.js";
|
|
34
34
|
import { builtInLayer } from "./builtin.js";
|
|
35
35
|
import { atFiles, body, bodyLog, builtInExtensions, currentFaux, dock, extensionsDir, loadedExtensions, mergedConfig, mergedTempPaths, projectExtensions, sessionsDir, setAgentModel, setBody, setConfigModels, setConfiguredWindow, setCurrentAgentExtensions, setCurrentFaux, setCurrentModelName, setExtensionLists, setMergedConfig, userExtensions, VERSION } from "./state.js";
|
|
36
|
-
import { resolveProjectTrust } from "./trust-ui.js";
|
|
36
|
+
import { askUi, resolveProjectTrust } from "./trust-ui.js";
|
|
37
37
|
import { isFirstRun, scaffoldFirstRun } from "./first-run.js";
|
|
38
38
|
import { fauxSkip, readFauxScript } from "./faux-glue.js";
|
|
39
39
|
import { autoCompactFromEnv, chat, contextWindowTokens } from "./chat.js";
|
|
@@ -209,20 +209,11 @@ function makeLineInput() {
|
|
|
209
209
|
* a fresh install reads `[3 extensions: built-in: mcp, skills, subagent]`
|
|
210
210
|
* with zero disk setup (E5: the task extension is opt-in). */
|
|
211
211
|
function bannerExtensionText() {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
// its in-flight state in the banner — "mcp (connecting…)".
|
|
218
|
-
const label = (e) => e.connecting === true ? `${e.name} (connecting…)` : e.name;
|
|
219
|
-
if (builtInExtensions.length > 0)
|
|
220
|
-
parts.push(`built-in: ${builtInExtensions.map(label).join(", ")}`);
|
|
221
|
-
if (userExtensions.length > 0)
|
|
222
|
-
parts.push(userExtensions.map(label).join(", "));
|
|
223
|
-
if (projectExtensions.length > 0)
|
|
224
|
-
parts.push(`project: ${projectExtensions.map(label).join(", ")}`);
|
|
225
|
-
return ` · [${total} extension${total === 1 ? "" : "s"}: ${parts.join(" · ")}]`;
|
|
212
|
+
// KC3.5 slice ⓪ (the extraction): the composition moved to the
|
|
213
|
+
// terminal layer (extensionsBannerText — a pure function of the three
|
|
214
|
+
// name lists, including the "(connecting…)" in-flight label). Which
|
|
215
|
+
// lists exist is the CLI's fact and stays here.
|
|
216
|
+
return extensionsBannerText(builtInExtensions, userExtensions, projectExtensions);
|
|
226
217
|
}
|
|
227
218
|
/** E1: the startup banner line(s) — TTY: logo + merged extensions + the
|
|
228
219
|
* W5 resume list as a LIVE banner cell (W1: the tier re-derives on
|
|
@@ -374,7 +365,11 @@ async function makeAgent(sessionId, input, modelFlag) {
|
|
|
374
365
|
const proj = project !== null ? await loadProjectExtensions(process.cwd(), user) : [];
|
|
375
366
|
// R-D 0.1.45: the built-in layer registers by module import (builtin.ts)
|
|
376
367
|
// — a user extension may shadow a built-in, a project one may not.
|
|
377
|
-
|
|
368
|
+
// KC3.5: built-in #4 (ask) registers ONLY where a human can answer —
|
|
369
|
+
// the panel bridge is the argument, and a non-TTY session has none to
|
|
370
|
+
// give. A piped run's composed tool table therefore cannot contain
|
|
371
|
+
// ask_user (T-Q3: the bench's structural byte-identity proof).
|
|
372
|
+
const builtIn = await builtInLayer(user, proj, input !== undefined && process.stdin.isTTY ? askUi(input) : undefined);
|
|
378
373
|
setExtensionLists(builtIn, user, proj, [...builtIn, ...user, ...proj]);
|
|
379
374
|
// merge round B — the config surface: user config + (trusted) project config,
|
|
380
375
|
// resolved with flags > env > project > user > default. The CLI never
|
package/dist/trust-ui.d.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* decisions. All bodies moved verbatim from index.ts.
|
|
7
7
|
*/
|
|
8
8
|
import { type PanelVerdict, type PanelView } from "@vincemakes/kiso-tui";
|
|
9
|
+
import type { AskUI } from "@vincemakes/kiso-ask-ext";
|
|
9
10
|
import { type ProjectArtifacts } from "@vincemakes/kiso-runtime";
|
|
10
11
|
import type { AgentSession } from "@vincemakes/kiso-runtime";
|
|
11
12
|
import { type LineInput } from "./state.js";
|
|
@@ -34,6 +35,24 @@ import { type LineInput } from "./state.js";
|
|
|
34
35
|
*/
|
|
35
36
|
export declare let pendingAsk: (() => void) | null;
|
|
36
37
|
export declare function askPanel(input: LineInput, view: PanelView): Promise<PanelVerdict>;
|
|
38
|
+
/**
|
|
39
|
+
* KC3.5 — the AskUI bridge: the panel the ask extension asks through.
|
|
40
|
+
*
|
|
41
|
+
* It is deliberately three lines of GLUE. Everything an ask needs was
|
|
42
|
+
* already built for W21 and is reused whole: askPanel owns the
|
|
43
|
+
* abortable ask (the SIGINT/esc path resolves it), the non-interactive
|
|
44
|
+
* refusal (printed loudly, never hung) and the dock-less fallback; the
|
|
45
|
+
* editor owns the keys and the buffer stash; the tui owns the rows and
|
|
46
|
+
* the walk. What is left here is the mapping — the panel's `answers`
|
|
47
|
+
* verdict IS the tool's result, and EVERY other verdict is the decline,
|
|
48
|
+
* which is an honest recorded outcome naming what went unanswered.
|
|
49
|
+
*
|
|
50
|
+
* (A cancel, a non-interactive deny and a dock-less y/n all land in the
|
|
51
|
+
* same place on purpose: none of them is an answer to a multiple-choice
|
|
52
|
+
* question, and inventing one would be the dishonesty the whole round
|
|
53
|
+
* is built to avoid.)
|
|
54
|
+
*/
|
|
55
|
+
export declare function askUi(input: LineInput): AskUI;
|
|
37
56
|
/**
|
|
38
57
|
* W21/R3 — the "2 Yes, don't ask again for <tool>" rule: a GENERATED
|
|
39
58
|
* extension, ALLOW-ONLY by construction (it never emits deny or ask —
|
package/dist/trust-ui.js
CHANGED
|
@@ -9,7 +9,7 @@ import { existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, symlinkS
|
|
|
9
9
|
import { homedir, tmpdir } from "node:os";
|
|
10
10
|
import { join } from "node:path";
|
|
11
11
|
import { pathToFileURL } from "node:url";
|
|
12
|
-
import { projectTrustRows, projectTrustView, projectUntrustedNote, uncertainView } from "@vincemakes/kiso-tui";
|
|
12
|
+
import { askDeclineAll, askView, projectTrustRows, projectTrustView, projectUntrustedNote, uncertainView, unansweredAskView } from "@vincemakes/kiso-tui";
|
|
13
13
|
import { projectArtifacts, recordTrust, trustFor } from "@vincemakes/kiso-runtime";
|
|
14
14
|
import { bodyLog, currentAgentExtensions, dock, extensionsDir, kisoHome, mergedTempPaths } from "./state.js";
|
|
15
15
|
import { loadUserConfig, resolveProjectTrustPolicy } from "./config.js";
|
|
@@ -83,6 +83,31 @@ export function askPanel(input, view) {
|
|
|
83
83
|
}
|
|
84
84
|
});
|
|
85
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* KC3.5 — the AskUI bridge: the panel the ask extension asks through.
|
|
88
|
+
*
|
|
89
|
+
* It is deliberately three lines of GLUE. Everything an ask needs was
|
|
90
|
+
* already built for W21 and is reused whole: askPanel owns the
|
|
91
|
+
* abortable ask (the SIGINT/esc path resolves it), the non-interactive
|
|
92
|
+
* refusal (printed loudly, never hung) and the dock-less fallback; the
|
|
93
|
+
* editor owns the keys and the buffer stash; the tui owns the rows and
|
|
94
|
+
* the walk. What is left here is the mapping — the panel's `answers`
|
|
95
|
+
* verdict IS the tool's result, and EVERY other verdict is the decline,
|
|
96
|
+
* which is an honest recorded outcome naming what went unanswered.
|
|
97
|
+
*
|
|
98
|
+
* (A cancel, a non-interactive deny and a dock-less y/n all land in the
|
|
99
|
+
* same place on purpose: none of them is an answer to a multiple-choice
|
|
100
|
+
* question, and inventing one would be the dishonesty the whole round
|
|
101
|
+
* is built to avoid.)
|
|
102
|
+
*/
|
|
103
|
+
export function askUi(input) {
|
|
104
|
+
return {
|
|
105
|
+
ask: async (spec) => {
|
|
106
|
+
const verdict = await askPanel(input, askView(spec));
|
|
107
|
+
return verdict.action === "answers" ? verdict.result : askDeclineAll(spec);
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
}
|
|
86
111
|
/**
|
|
87
112
|
* W21/R3 — the "2 Yes, don't ask again for <tool>" rule: a GENERATED
|
|
88
113
|
* extension, ALLOW-ONLY by construction (it never emits deny or ask —
|
|
@@ -299,7 +324,12 @@ function readdirSyncSafe(dir) {
|
|
|
299
324
|
* the body is the single stdout writer, never a stray console.log. */
|
|
300
325
|
export async function resolveUncertains(session, input, isCancelled) {
|
|
301
326
|
for (const uncertain of session.uncertainExecutions()) {
|
|
302
|
-
|
|
327
|
+
// KC3.5 §4: an interrupted ask_user is not a side effect that may
|
|
328
|
+
// have applied — it is a question nobody answered. The COPY says
|
|
329
|
+
// so; the mechanism is untouched (allow → the runtime's own rerun
|
|
330
|
+
// resolution, whose error-fill text this round never edits).
|
|
331
|
+
const view = uncertain.name === "ask_user" ? unansweredAskView(uncertain.executionId) : uncertainView(uncertain.name, uncertain.executionId);
|
|
332
|
+
const verdict = await askPanel(input, view);
|
|
303
333
|
if (isCancelled() || verdict.action === "cancel") {
|
|
304
334
|
// round 10: a cancellation NEVER records a verdict — the execution
|
|
305
335
|
// stays uncertain and durable; no rerun/abandoned is fabricated.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vincemakes/kiso-code",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
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",
|
|
@@ -18,18 +18,19 @@
|
|
|
18
18
|
"test": "vitest run"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@vincemakes/kiso-
|
|
22
|
-
"@vincemakes/kiso-
|
|
23
|
-
"@vincemakes/kiso-
|
|
24
|
-
"@vincemakes/kiso-
|
|
25
|
-
"@vincemakes/kiso-provider-
|
|
26
|
-
"@vincemakes/kiso-
|
|
27
|
-
"@vincemakes/kiso-
|
|
28
|
-
"@vincemakes/kiso-
|
|
29
|
-
"@vincemakes/kiso-
|
|
30
|
-
"@vincemakes/kiso-
|
|
31
|
-
"@vincemakes/kiso-
|
|
32
|
-
"@vincemakes/kiso-tui
|
|
21
|
+
"@vincemakes/kiso-ask-ext": "0.8.0",
|
|
22
|
+
"@vincemakes/kiso-core": "0.8.0",
|
|
23
|
+
"@vincemakes/kiso-evals": "0.8.0",
|
|
24
|
+
"@vincemakes/kiso-mcp-ext": "0.8.0",
|
|
25
|
+
"@vincemakes/kiso-provider-anthropic": "0.8.0",
|
|
26
|
+
"@vincemakes/kiso-provider-openai": "0.8.0",
|
|
27
|
+
"@vincemakes/kiso-runtime": "0.8.0",
|
|
28
|
+
"@vincemakes/kiso-skills-ext": "0.8.0",
|
|
29
|
+
"@vincemakes/kiso-subagent-ext": "0.8.0",
|
|
30
|
+
"@vincemakes/kiso-task-ext": "0.8.0",
|
|
31
|
+
"@vincemakes/kiso-tools-node": "0.8.0",
|
|
32
|
+
"@vincemakes/kiso-tui": "0.8.0",
|
|
33
|
+
"@vincemakes/kiso-tui-cells": "0.8.0"
|
|
33
34
|
},
|
|
34
35
|
"devDependencies": {
|
|
35
36
|
"@types/node": "^26.1.2",
|