@vincemakes/kiso-code 0.28.0 → 0.30.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/chat.d.ts CHANGED
@@ -33,6 +33,15 @@ export declare function contextWindowTokens(): number;
33
33
  * the model window. Marked ~ everywhere it is shown; no counting API.
34
34
  */
35
35
  export declare function estimateCtxRatio(session: AgentSession): number;
36
+ /** A1a: the ratio the STATUS LINE and the ctx displays show — the request
37
+ * budget counting the parts (system prompt, tool table, messages with
38
+ * their continuation envelopes, the output reserve when known) over the
39
+ * window. Still ~ (chars/4). The auto-compact policy does NOT read this
40
+ * (see autoCompactRatio) — moving the policy's number is A1b's. */
41
+ export declare function displayCtxRatio(session: AgentSession): number;
42
+ /** A1a: the number the auto-compact decision reads — the pre-A1a estimate,
43
+ * unchanged this round, named so a gate can pin that it did not move. */
44
+ export declare function autoCompactRatio(session: AgentSession): number;
36
45
  /** E2 (1.3.0) — the CLI's usage consumer: one event in, the RunUsage the
37
46
  * status line and recap render plus the miss estimate. `total` is the
38
47
  * carrier for the NEXT turn's miss estimate — the overlap of consecutive
package/dist/chat.js CHANGED
@@ -9,7 +9,7 @@ import { escapeTerminal, cacheHitPct, idleStatus, palette, renderEvent, renderRe
9
9
  import { deletionRiskHint, editFileDiff, writeFileDiff } from "@vincemakes/kiso-tui";
10
10
  import { canonicalTargetPath, shellProgressPath } from "@vincemakes/kiso-tools-node";
11
11
  import { canonicalizeUsage } from "@vincemakes/kiso-runtime";
12
- import { canonicalizeUsageForModel } from "@vincemakes/kiso-runtime/internal";
12
+ import { canonicalizeUsageForModel, requestBudget } from "@vincemakes/kiso-runtime/internal";
13
13
  import { dispatch } from "./dispatch.js";
14
14
  import { agentModel, body, bodyLog, configuredWindow, dock } from "./state.js";
15
15
  import { attachImages } from "./attachments.js";
@@ -62,6 +62,19 @@ export function estimateCtxRatio(session) {
62
62
  const chars = JSON.stringify(projected).length;
63
63
  return chars / 4 / contextWindowTokens();
64
64
  }
65
+ /** A1a: the ratio the STATUS LINE and the ctx displays show — the request
66
+ * budget counting the parts (system prompt, tool table, messages with
67
+ * their continuation envelopes, the output reserve when known) over the
68
+ * window. Still ~ (chars/4). The auto-compact policy does NOT read this
69
+ * (see autoCompactRatio) — moving the policy's number is A1b's. */
70
+ export function displayCtxRatio(session) {
71
+ return requestBudget(session.requestParts(), contextWindowTokens()).ratio;
72
+ }
73
+ /** A1a: the number the auto-compact decision reads — the pre-A1a estimate,
74
+ * unchanged this round, named so a gate can pin that it did not move. */
75
+ export function autoCompactRatio(session) {
76
+ return estimateCtxRatio(session);
77
+ }
65
78
  /** R-C item 4: the per-turn cache miss — the overlap with the previous
66
79
  * prompt that SHOULD have been cached but was re-sent uncached:
67
80
  * missed = min(prevIn, in) − cacheRead. Below the 1024-token floor
@@ -629,7 +642,7 @@ submitTurn) {
629
642
  missed = delta.missed;
630
643
  // TUI2-R1 (E): the request's canonical cost rides the same
631
644
  // callback the usage does — one settled request, one addition.
632
- statusCb?.(usage, estimateCtxRatio(session), delta.costUsd);
645
+ statusCb?.(usage, displayCtxRatio(session), delta.costUsd);
633
646
  break;
634
647
  }
635
648
  case "uncertain_pending":
@@ -736,8 +749,8 @@ submitTurn) {
736
749
  // v3 §02: the run's recap line REPLACES the old "done" label
737
750
  // + status line — one local line, derived from this run's
738
751
  // events (zero tokens). The dock's status bar still paints.
739
- statusCb?.(usage, estimateCtxRatio(session));
740
- const ratio = estimateCtxRatio(session);
752
+ statusCb?.(usage, displayCtxRatio(session));
753
+ const ratio = displayCtxRatio(session);
741
754
  // TV-1B: the settle verdict — the checklist stops lying. When
742
755
  // every item is CLAIMED done, the settled block's tail says
743
756
  // what the projection actually proves ("no passing check yet"
@@ -1053,7 +1066,7 @@ export async function chat(session, faux, input, autoCompact, nav) {
1053
1066
  // stays here; the ROW's text is the tui's status formatter.
1054
1067
  const paintRunning = () => {
1055
1068
  if (dock.active)
1056
- dock.setStatus(runningStatus(runGlyph, runStart, runUsage.out, estimateCtxRatio(session)));
1069
+ dock.setStatus(runningStatus(runGlyph, runStart, runUsage.out, displayCtxRatio(session)));
1057
1070
  };
1058
1071
  // W19: under plan the idle row makes the posture unmistakable — the W4
1059
1072
  // parentheses idiom names the read-only constraint. The tier is the
@@ -1064,7 +1077,7 @@ export async function chat(session, faux, input, autoCompact, nav) {
1064
1077
  // TUI2-R1 (E): the meter rides the idle row — both fields omitted
1065
1078
  // when unknown, so a session that has not called the model paints
1066
1079
  // exactly the pre-round row.
1067
- dock.setStatus(idleStatus(getMode() === "plan" ? "plan (read-only)" : getMode(), agentModel, estimateCtxRatio(session), {
1080
+ dock.setStatus(idleStatus(getMode() === "plan" ? "plan (read-only)" : getMode(), agentModel, displayCtxRatio(session), {
1068
1081
  cacheHitPct: cacheHitPct(runUsage),
1069
1082
  costUsd: spentUsd,
1070
1083
  }));
@@ -1153,7 +1166,7 @@ export async function chat(session, faux, input, autoCompact, nav) {
1153
1166
  isRunning: () => currentRun !== null,
1154
1167
  paintIdle,
1155
1168
  submitTurn,
1156
- estimateCtx: () => estimateCtxRatio(session),
1169
+ estimateCtx: () => displayCtxRatio(session),
1157
1170
  contextWindow: () => contextWindowTokens(),
1158
1171
  // the /resume+/clear mini-spec: the switch directive and the
1159
1172
  // session-navigation seam (absent nav = the commands degrade to
@@ -1177,7 +1190,7 @@ export async function chat(session, faux, input, autoCompact, nav) {
1177
1190
  return;
1178
1191
  if (currentRun !== null)
1179
1192
  return; // dispatch would refuse — skip the noise
1180
- const ratio = estimateCtxRatio(session);
1193
+ const ratio = autoCompactRatio(session); // A1a: the policy keeps the pre-A1a number — A1b decides if it moves
1181
1194
  if (!Number.isFinite(ratio) || ratio < autoCompact.thresholdRatio)
1182
1195
  return;
1183
1196
  dispatch("/compact", dispatchCtx);
package/dist/config.d.ts CHANGED
@@ -59,6 +59,11 @@ export interface KisoConfig {
59
59
  * project file is a LOUD error rather than a silent win. `KISO_THEME`
60
60
  * still outranks it — the environment is the more local answer. */
61
61
  readonly theme?: "dark" | "light";
62
+ /** DT-1a: named acceptance checks a delegated task may reference —
63
+ * user-authored (or trust-gated project) commands, run by the PARENT
64
+ * in the child's worktree. A model never supplies a command; it names
65
+ * one of these. `{ "test": "npm test", "lint": "npm run lint" }`. */
66
+ readonly checks?: Readonly<Record<string, string>>;
62
67
  }
63
68
  /** The resolved, merged config — project wins over user, both validated. */
64
69
  export interface ResolvedConfig {
package/dist/config.js CHANGED
@@ -63,6 +63,17 @@ export function parseConfig(text, source) {
63
63
  fail("theme", "belongs in the USER config — a terminal is a property of the person at it, not of the project");
64
64
  out.theme = obj.theme;
65
65
  }
66
+ if (obj.checks !== undefined) {
67
+ if (obj.checks === null || typeof obj.checks !== "object" || Array.isArray(obj.checks))
68
+ fail("checks", "expected an object of name → command");
69
+ for (const [name, cmd] of Object.entries(obj.checks)) {
70
+ if (!/^[A-Za-z0-9_-]+$/.test(name))
71
+ fail(`checks.${name}`, "a check name is letters, digits, _ or -");
72
+ if (typeof cmd !== "string" || cmd.trim() === "")
73
+ fail(`checks.${name}`, "expected a non-empty command string");
74
+ }
75
+ out.checks = obj.checks;
76
+ }
66
77
  if (obj.model !== undefined) {
67
78
  if (typeof obj.model !== "string" || obj.model === "")
68
79
  fail("model", "expected a profile name or provider/model string");
@@ -162,6 +173,8 @@ export function mergeConfigs(user, project) {
162
173
  ...(p.autoCompact !== undefined ? { autoCompact: p.autoCompact } : {}),
163
174
  ...(u.projectTrust !== undefined ? { projectTrust: u.projectTrust } : {}),
164
175
  ...(p.projectTrust !== undefined ? { projectTrust: p.projectTrust } : {}),
176
+ // DT-1a: checks merge per name — a (trusted) project's check wins over the user's
177
+ ...(u.checks !== undefined || p.checks !== undefined ? { checks: { ...(u.checks ?? {}), ...(p.checks ?? {}) } } : {}),
165
178
  };
166
179
  }
167
180
  /** A profile is available when its apiKeyEnv var is set (the key exists). */
package/dist/index.js CHANGED
@@ -39,7 +39,7 @@ import { agentModel, atFiles, body, bodyLog, kisoHome, builtInExtensions, curren
39
39
  import { askUi, resolveProjectTrust } from "./trust-ui.js";
40
40
  import { isFirstRun, scaffoldFirstRun } from "./first-run.js";
41
41
  import { fauxSkip, readFauxScript } from "./faux-glue.js";
42
- import { chat, contextWindowTokens, estimateCtxRatio } from "./chat.js";
42
+ import { chat, contextWindowTokens, displayCtxRatio } from "./chat.js";
43
43
  import { loadProjectConfig, loadUserConfig, mergeConfigs, resolveAutoCompact, resolveContextWindow, resolveModel } from "./config.js";
44
44
  import { checkForUpdate } from "./update-check.js";
45
45
  import { resume } from "./resume.js";
@@ -590,6 +590,10 @@ async function makeAgent(sessionId, input, modelFlag) {
590
590
  const projectCfg = loadProjectConfig(process.cwd(), project !== null);
591
591
  const merged = mergeConfigs(userCfg, projectCfg);
592
592
  setMergedConfig(merged);
593
+ // DT-1a: what a delegated task may NAME — the configured checks and the
594
+ // model profiles — handed to the (in-process) subagent extension through
595
+ // the environment. A model never supplies a command; it names a check.
596
+ process.env.KISO_DELEGATION_CONFIG_JSON = JSON.stringify({ checks: merged.checks ?? {}, profiles: Object.keys(merged.models ?? {}) });
593
597
  setConfigModels(merged.models ?? {});
594
598
  setConfiguredWindow(resolveContextWindow(merged));
595
599
  const resolved = resolveModel(modelFlag, merged);
@@ -726,7 +730,7 @@ async function pickSession(agent, input) {
726
730
  function paintBootStatus(session) {
727
731
  if (!dock.active)
728
732
  return;
729
- dock.setStatus(idleStatus(getMode() === "plan" ? "plan (read-only)" : getMode(), agentModel, estimateCtxRatio(session)));
733
+ dock.setStatus(idleStatus(getMode() === "plan" ? "plan (read-only)" : getMode(), agentModel, displayCtxRatio(session)));
730
734
  }
731
735
  /** PH-1a (finding PH-F12): a usage error raised from inside the TUI —
732
736
  * main's finally still runs (dock teardown, agent close, temp cleanup)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vincemakes/kiso-code",
3
- "version": "0.28.0",
3
+ "version": "0.30.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,19 +18,19 @@
18
18
  "test": "vitest run"
19
19
  },
20
20
  "dependencies": {
21
- "@vincemakes/kiso-ask-ext": "0.28.0",
22
- "@vincemakes/kiso-core": "0.28.0",
23
- "@vincemakes/kiso-evals": "0.28.0",
24
- "@vincemakes/kiso-mcp-ext": "0.28.0",
25
- "@vincemakes/kiso-provider-anthropic": "0.28.0",
26
- "@vincemakes/kiso-provider-openai": "0.28.0",
27
- "@vincemakes/kiso-runtime": "0.28.0",
28
- "@vincemakes/kiso-skills-ext": "0.28.0",
29
- "@vincemakes/kiso-subagent-ext": "0.28.0",
30
- "@vincemakes/kiso-task-ext": "0.28.0",
31
- "@vincemakes/kiso-tools-node": "0.28.0",
32
- "@vincemakes/kiso-tui": "0.28.0",
33
- "@vincemakes/kiso-tui-cells": "0.28.0"
21
+ "@vincemakes/kiso-ask-ext": "0.30.0",
22
+ "@vincemakes/kiso-core": "0.30.0",
23
+ "@vincemakes/kiso-evals": "0.30.0",
24
+ "@vincemakes/kiso-mcp-ext": "0.30.0",
25
+ "@vincemakes/kiso-provider-anthropic": "0.30.0",
26
+ "@vincemakes/kiso-provider-openai": "0.30.0",
27
+ "@vincemakes/kiso-runtime": "0.30.0",
28
+ "@vincemakes/kiso-skills-ext": "0.30.0",
29
+ "@vincemakes/kiso-subagent-ext": "0.30.0",
30
+ "@vincemakes/kiso-task-ext": "0.30.0",
31
+ "@vincemakes/kiso-tools-node": "0.30.0",
32
+ "@vincemakes/kiso-tui": "0.30.0",
33
+ "@vincemakes/kiso-tui-cells": "0.30.0"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@types/node": "^26.1.2",