@vincemakes/kiso-code 0.38.0 → 0.39.1

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.js CHANGED
@@ -12,6 +12,7 @@ import { echoText } from "@vincemakes/kiso-tui-cells/render";
12
12
  import { canonicalizeUsage } from "@vincemakes/kiso-runtime";
13
13
  import { canonicalizeUsageForModel, requestBudget } from "@vincemakes/kiso-runtime/internal";
14
14
  import { dispatch, abortBangCommand } from "./dispatch.js";
15
+ import { paintWindowTitle } from "./window-title.js";
15
16
  import { agentBaseUrl, agentModel, body, bodyLog, configuredWindow, dock } from "./state.js";
16
17
  import { attachImages } from "./attachments.js";
17
18
  import { lookupModelMetadata } from "@vincemakes/kiso-runtime/internal";
@@ -781,6 +782,13 @@ submitTurn) {
781
782
  // construction (ADR-0040).
782
783
  switch (ev.type) {
783
784
  case "user_input":
785
+ // The window title is re-derived here because THIS is when a
786
+ // session stops being nameless: the tab opened as `kiso —
787
+ // <workspace>` and the first substantive prompt is what gives
788
+ // it a name. Re-derived rather than set, so the opener rule is
789
+ // `sessionTitle`'s and a greeting-first session upgrades when
790
+ // the real prompt lands instead of keeping "hi" forever.
791
+ paintWindowTitle(session.log.all);
784
792
  // TV-1B: a system-sourced input is PRODUCT MACHINERY — visible
785
793
  // (every durable input renders) but never painted as the
786
794
  // user's words. Provenance is honest on screen, not only in
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 { contextRows, contextUnavailableRows, displayVerb, escapeTerminal, helpRows, kUnit, modePickView, modelPickView, palette } from "@vincemakes/kiso-tui";
6
+ import { contextRows, contextUnavailableRows, displayVerb, escapeTerminal, helpRows, kUnit, modePickView, modelPickView, palette, renderEvent, settledLabel, slashCommandNames } from "@vincemakes/kiso-tui";
7
7
  import { newSessionId } from "./session-id.js";
8
8
  import { buildAdapter, lookupModelMetadata, resolveContinuationScope, resolveReasoning } from "@vincemakes/kiso-runtime/internal";
9
9
  import { MODES, MODE_NOTE, getMode, setMode } from "./mode.js";
@@ -761,10 +761,28 @@ export function dispatch(line, ctx) {
761
761
  // (the estimate BEFORE vs AFTER — the same chars/4
762
762
  // proxy the status bar shows, marked ~), and the time.
763
763
  const ctxAfter = Math.round(ctx.estimateCtx() * 100);
764
- const elapsed = compactStart > 0 ? ((Date.now() - compactStart) / 1000).toFixed(1) : "?";
764
+ const elapsed = compactStart > 0 ? settledLabel((Date.now() - compactStart) / 1000) : "?s";
765
765
  // a non-null result implies onStart ran — the "?" is
766
766
  // reachable only at the type level
767
- body.notice(`[/compact] ✦ compacted · ${compactInfo?.rounds ?? "?"} rounds → 1 summary · saved ~${kUnit(result.savedTokens)} · ctx ${ctxBefore ?? "?"}% → ${ctxAfter}% · ${elapsed}s`);
767
+ body.notice(`[/compact] ✦ compacted · ${compactInfo?.rounds ?? "?"} rounds → 1 summary · saved ~${kUnit(result.savedTokens)} · ctx ${ctxBefore ?? "?"}% → ${ctxAfter}% · ${elapsed}`);
768
+ // 0.39.1 — the boundary row, under the recap.
769
+ //
770
+ // `summarized` is appended OFF-LOOP: session.summarize()
771
+ // writes it to the log and persists it, and no hook
772
+ // carries it to a renderer. So the row that marks where
773
+ // the transcript was cut had exactly one producer — a
774
+ // `case "summarized"` in lines.ts whose own comment says
775
+ // it is there "for the switch's completeness only" — and
776
+ // zero callers. The durable log said a compaction
777
+ // happened at seq N; no screen ever did.
778
+ //
779
+ // Rendered THROUGH that case rather than written again
780
+ // here: the line a resumed or replayed view would draw is
781
+ // the line drawn now, by construction, and the row cannot
782
+ // drift into two spellings of one fact.
783
+ const boundary = renderEvent({ type: "summarized", coversToSeq: result.coversToSeq });
784
+ if (boundary.text !== "")
785
+ body.raw(boundary.text.replace(/\n$/, "").split("\n"));
768
786
  }
769
787
  }
770
788
  catch (err) {
@@ -774,7 +792,22 @@ export function dispatch(line, ctx) {
774
792
  body.notice("[/compact] cancelled — nothing was persisted");
775
793
  }
776
794
  else {
777
- body.notice(`[/compact] failed: ${err instanceof Error ? err.message : String(err)}`);
795
+ // 0.39.1 — two repairs on one line. A failure the ADAPTER
796
+ // classified is a plain object, not an Error: `String(err)`
797
+ // rendered it `[object Object]`, which became reachable the
798
+ // moment the adapters started THROWING the
799
+ // transport-failure class instead of stopping with it. And
800
+ // a transport failure is worth saying so about: summarize
801
+ // already retried it once (it has no kernel behind it to do
802
+ // that), so a second failure means the gateway is still
803
+ // dropping the stream — the run is fine and the gesture is
804
+ // worth repeating. A permanent failure is not, and must not
805
+ // be dressed up as one that is.
806
+ const e = err;
807
+ const classified = typeof e.code === "string" && typeof e.message === "string";
808
+ const detail = classified ? String(e.message) : err instanceof Error ? err.message : String(err);
809
+ const again = classified && e.retryable === true ? " — the connection dropped again; /compact is worth another try" : "";
810
+ body.notice(`[/compact] failed: ${escapeTerminal(detail)}${again}`);
778
811
  }
779
812
  }
780
813
  finally {
@@ -902,7 +935,21 @@ export function dispatch(line, ctx) {
902
935
  // still submits.
903
936
  if (trimmed.startsWith("/") && !trimmed.includes("\n")) {
904
937
  ctx.chainRef.current = ctx.chainRef.current.then(async () => {
905
- bodyLog(`unknown command: ${escapeTerminal(trimmed.split(" ")[0] ?? trimmed)} — /help lists the commands`);
938
+ // The word, not the line: a command that EXISTS but was handed an
939
+ // argument it does not take reaches here too, and calling it
940
+ // unknown is a lie the user cannot get past — `/help` lists it,
941
+ // they typed what `/help` said, and kiso answers that there is no
942
+ // such command. (Reported on `/reload extensions`, 0.39.1.) The
943
+ // commands that DO take an argument matched on their own prefix
944
+ // far above, so a known word arriving here means exactly one
945
+ // thing: it takes none. `slashCommandNames` is the help sheet's
946
+ // own table, so this line cannot drift from the list the user was
947
+ // reading when they typed it.
948
+ const word = trimmed.split(/\s+/)[0] ?? trimmed;
949
+ const known = slashCommandNames().includes(word);
950
+ bodyLog(known
951
+ ? `${escapeTerminal(word)} takes no arguments — /help says what it does`
952
+ : `unknown command: ${escapeTerminal(word)} — /help lists the commands`);
906
953
  ctx.input.prompt();
907
954
  });
908
955
  return;
package/dist/index.d.ts CHANGED
@@ -31,7 +31,7 @@ export { applyProjectMerges } from "./trust-ui.js";
31
31
  */
32
32
  /** The built-in prompt. Exported for scripts/request-surface.mjs — the
33
33
  * model-side token-rent counter measures the REAL bytes, never a copy. */
34
- 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\nWhat you can reach:\n- The workspace: read_file, list_dir, search_text, write_file, edit_file.\n- This machine and the network: shell \u2014 builds, tests, git, package\n managers, curl for HTTP, system queries. A request one command can\n answer is answered by running it.\n- The human: ask_user, for a decision that is theirs.\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, or one you changed\n yourself through a confirmed edit \u2014 rely on the earlier result and\n on the change you just made.\n- When a tool fails, read the error and adjust; do not repeat the same\n call blindly.\n\nAn authorization covers what it NAMES: when the scope is not named \u2014\nwhich files, which branches, whether to push \u2014 ask before acting.\nDelivering, sharing or handing over changes means committing locally and\nstopping; pushing, publishing or sending happens only when the human\nnames it.\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
+ 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\nWhat you can reach:\n- The workspace: read_file, list_dir, search_text, write_file, edit_file.\n- This machine and the network: shell \u2014 builds, tests, git, package\n managers, curl for HTTP, system queries. A request one command can\n answer is answered by running it.\n- The human: ask_user, for a decision that is theirs.\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- Be careful \u2014 shell has side effects and may take time.\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, or one you changed\n yourself through a confirmed edit \u2014 rely on the earlier result and\n on the change you just made.\n- When a tool fails, read the error and adjust; do not repeat the same\n call blindly.\n\nAn authorization covers what it NAMES: when the scope is not named \u2014\nwhich files, which branches, whether to push \u2014 ask before acting.\nDelivering, sharing or handing over changes means committing locally and\nstopping; pushing, publishing or sending happens only when the human\nnames it.\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.";
35
35
  /** Hard cap for injected instructions — truncate and say so. */
36
36
  /**
37
37
  * A area: read the FIRST present instruction file (AGENTS.md preferred) and
package/dist/index.js CHANGED
@@ -47,6 +47,7 @@ import { loadProjectConfig, loadUserConfig, mergeConfigs, resolveAutoCompact, re
47
47
  import { checkForUpdate, knownUpdate, updateCardLines } from "./update-check.js";
48
48
  import { tmuxMouseHint } from "./tmux-hint.js";
49
49
  import { resume } from "./resume.js";
50
+ import { paintWindowTitle } from "./window-title.js";
50
51
  import { resumeTail } from "./resume-tail.js";
51
52
  import { armByteTrace } from "./byte-trace.js";
52
53
  import { tmpdir, homedir } from "node:os";
@@ -592,10 +593,7 @@ Tool discipline:
592
593
  first — never guess its content.
593
594
  - Use edit_file for targeted changes and write_file for full rewrites.
594
595
  Prefer many small edits over one large write.
595
- - shell is for commands: builds, tests, git, grep. Be careful — shell has
596
- side effects and may take time. Run one command at a time and inspect
597
- the output before continuing.
598
- - Batch independent tool calls into one reply — they run in parallel.
596
+ - Be careful — shell has side effects and may take time.
599
597
  - search_text and list_dir are cheap — locate first, then read ranges
600
598
  with read_file offset/limit; never read a whole large file in one call.
601
599
  - Do not re-read a file you already read unchanged, or one you changed
@@ -1128,6 +1126,11 @@ async function chatLoop(first, firstId, input, autoCompact) {
1128
1126
  bindRestoredSession(session);
1129
1127
  setCurrentModelName(session.model);
1130
1128
  paintBootStatus(session);
1129
+ // The terminal's window title, HERE for the same reason the three
1130
+ // lines above are here: this is the one step all three entry points
1131
+ // share (first start, `/resume <id>`, a switch), so a tab can never
1132
+ // be left naming the session the user just left.
1133
+ paintWindowTitle(session.log.all);
1131
1134
  const nav = {
1132
1135
  sessions: () => agent.sessions().map((m) => m.id),
1133
1136
  ...(process.stdin.isTTY ? { pick: () => pickSession(agent, input) } : {}),
@@ -0,0 +1,76 @@
1
+ /**
2
+ * The terminal's window title (0.39.1, the owner's call).
3
+ *
4
+ * kiso set none, so a tab read whatever the shell left there — the
5
+ * directory the shell happened to be in and the absolute path of a node
6
+ * binary, identically for every kiso in every tab. The title is the one
7
+ * place a terminal shows which session a tab holds without the user
8
+ * switching to it, and it was the only screen kiso never wrote to.
9
+ *
10
+ * `kiso — <workspace>` at the start, `kiso — <session title> —
11
+ * <workspace>` once the session has one. The session's title is
12
+ * `sessionTitle`'s — the SAME projection the resume picker and `kiso
13
+ * sessions` print, so a tab and the picker can never disagree about what
14
+ * a session is called. That is also why an opener does not become the
15
+ * title: the rule for "substantive" lives in one place and this is a
16
+ * consumer of it, not a second opinion.
17
+ *
18
+ * WHAT IT WRITES. OSC 0, BEL-terminated — icon name and window title in
19
+ * one sequence, the form every terminal that supports either accepts. It
20
+ * goes STRAIGHT to stdout, deliberately outside the compositor: a title
21
+ * occupies no cell and no column, so it is not in the width accounting
22
+ * and must not be a cell that the repaint could move, cut, or scroll.
23
+ *
24
+ * WHAT IT NEVER WRITES. Anything at all when stdout is not a TTY. An OSC
25
+ * into a pipe is bytes in someone's output, and the pipe-identity gates
26
+ * exist because that has been a real defect before.
27
+ *
28
+ * NO RESTORE ON EXIT. Putting back what was there first requires reading
29
+ * it, which no terminal reliably answers; the shell repaints its own
30
+ * title on the next prompt anyway. A guess written on the way out would
31
+ * be a title kiso invented, which is worse than one it left.
32
+ *
33
+ * AND NO `process.title`. The reference implementation sets one; kiso
34
+ * does not, because two gates in this repo said no and the benefit was
35
+ * that `ps` would print `kiso` instead of a node path.
36
+ *
37
+ * - It overwrites the process's ARGV memory, so a renamed process shows
38
+ * as `kiso` with its arguments simply gone. The subagent's
39
+ * concurrency probe counts live children by matching `chat
40
+ * sub-parent-` in the command column; six renamed children were
41
+ * indistinguishable from each other and from nothing.
42
+ * - Setting it is not free on this platform: 14 ms measured for the
43
+ * first assignment on the machine this was written on, 7 ms for the
44
+ * second. A synchronous stall of that size on the main thread while a
45
+ * 3,000-line paste is arriving wedges the PTY in both directions —
46
+ * the UD-1 byte-exact paste gate deadlocked reproducibly and passed
47
+ * the moment the assignment was removed.
48
+ *
49
+ * The window title is what was asked for; the process name was a detail
50
+ * that came with it, and it costs more than it is worth.
51
+ */
52
+ import type { Event } from "@vincemakes/kiso-core";
53
+ /** OSC 0 — "set icon name and window title". */
54
+ export declare const OSC_TITLE_PREFIX = "\u001B]0;";
55
+ /** BEL, the terminator the reference form uses (ST works too; BEL is the
56
+ * one older terminals accept without argument). */
57
+ export declare const OSC_TITLE_SUFFIX = "\u0007";
58
+ /**
59
+ * The text of the title, with no IO — the whole rule, testable.
60
+ *
61
+ * Every part is passed through `escapeTerminal` before it can reach the
62
+ * sequence. A title is whatever a human typed or PASTED: a BEL in it
63
+ * would end the sequence early and an ESC would begin another one, and
64
+ * the title would stop being a title and start being commands to the
65
+ * terminal. The same stripper the rendered surfaces use — one definition
66
+ * of "what is safe to put on a terminal", not a second.
67
+ */
68
+ export declare function windowTitleText(events: readonly Event[], workspace: string): string;
69
+ /**
70
+ * Write the title for this session's state. Called where the session is
71
+ * BOUND (which is one place for all three entry points — first start,
72
+ * `/resume <id>`, and a switch) and again as the session's own title
73
+ * becomes knowable, so a tab named before the first prompt is renamed by
74
+ * it rather than keeping a name that was only ever a placeholder.
75
+ */
76
+ export declare function paintWindowTitle(events: readonly Event[], cwd?: string): void;
@@ -0,0 +1,114 @@
1
+ /**
2
+ * The terminal's window title (0.39.1, the owner's call).
3
+ *
4
+ * kiso set none, so a tab read whatever the shell left there — the
5
+ * directory the shell happened to be in and the absolute path of a node
6
+ * binary, identically for every kiso in every tab. The title is the one
7
+ * place a terminal shows which session a tab holds without the user
8
+ * switching to it, and it was the only screen kiso never wrote to.
9
+ *
10
+ * `kiso — <workspace>` at the start, `kiso — <session title> —
11
+ * <workspace>` once the session has one. The session's title is
12
+ * `sessionTitle`'s — the SAME projection the resume picker and `kiso
13
+ * sessions` print, so a tab and the picker can never disagree about what
14
+ * a session is called. That is also why an opener does not become the
15
+ * title: the rule for "substantive" lives in one place and this is a
16
+ * consumer of it, not a second opinion.
17
+ *
18
+ * WHAT IT WRITES. OSC 0, BEL-terminated — icon name and window title in
19
+ * one sequence, the form every terminal that supports either accepts. It
20
+ * goes STRAIGHT to stdout, deliberately outside the compositor: a title
21
+ * occupies no cell and no column, so it is not in the width accounting
22
+ * and must not be a cell that the repaint could move, cut, or scroll.
23
+ *
24
+ * WHAT IT NEVER WRITES. Anything at all when stdout is not a TTY. An OSC
25
+ * into a pipe is bytes in someone's output, and the pipe-identity gates
26
+ * exist because that has been a real defect before.
27
+ *
28
+ * NO RESTORE ON EXIT. Putting back what was there first requires reading
29
+ * it, which no terminal reliably answers; the shell repaints its own
30
+ * title on the next prompt anyway. A guess written on the way out would
31
+ * be a title kiso invented, which is worse than one it left.
32
+ *
33
+ * AND NO `process.title`. The reference implementation sets one; kiso
34
+ * does not, because two gates in this repo said no and the benefit was
35
+ * that `ps` would print `kiso` instead of a node path.
36
+ *
37
+ * - It overwrites the process's ARGV memory, so a renamed process shows
38
+ * as `kiso` with its arguments simply gone. The subagent's
39
+ * concurrency probe counts live children by matching `chat
40
+ * sub-parent-` in the command column; six renamed children were
41
+ * indistinguishable from each other and from nothing.
42
+ * - Setting it is not free on this platform: 14 ms measured for the
43
+ * first assignment on the machine this was written on, 7 ms for the
44
+ * second. A synchronous stall of that size on the main thread while a
45
+ * 3,000-line paste is arriving wedges the PTY in both directions —
46
+ * the UD-1 byte-exact paste gate deadlocked reproducibly and passed
47
+ * the moment the assignment was removed.
48
+ *
49
+ * The window title is what was asked for; the process name was a detail
50
+ * that came with it, and it costs more than it is worth.
51
+ */
52
+ import { basename } from "node:path";
53
+ import { sessionTitle } from "@vincemakes/kiso-runtime/internal";
54
+ import { displayWidth, widthCut } from "@vincemakes/kiso-tui-cells/width";
55
+ import { escapeTerminal } from "@vincemakes/kiso-tui-cells/render";
56
+ /** OSC 0 — "set icon name and window title". */
57
+ export const OSC_TITLE_PREFIX = "\u001b]0;";
58
+ /** BEL, the terminator the reference form uses (ST works too; BEL is the
59
+ * one older terminals accept without argument). */
60
+ export const OSC_TITLE_SUFFIX = "\u0007";
61
+ /** The session title's share of the tab, in CELLS. A tab strip gives a
62
+ * title far less than a row, and the workspace — which says WHERE, the
63
+ * thing a human scanning tabs is usually after — must survive the cut. */
64
+ const TITLE_CELLS = 40;
65
+ /** The title a session with no title yet has. `sessionTitle` returns this
66
+ * when nothing has been asked; it is not a label, so it is not shown. */
67
+ const NO_TITLE = "(no prompt)";
68
+ /**
69
+ * The text of the title, with no IO — the whole rule, testable.
70
+ *
71
+ * Every part is passed through `escapeTerminal` before it can reach the
72
+ * sequence. A title is whatever a human typed or PASTED: a BEL in it
73
+ * would end the sequence early and an ESC would begin another one, and
74
+ * the title would stop being a title and start being commands to the
75
+ * terminal. The same stripper the rendered surfaces use — one definition
76
+ * of "what is safe to put on a terminal", not a second.
77
+ */
78
+ export function windowTitleText(events, workspace) {
79
+ const place = escapeTerminal(workspace);
80
+ // Filtered BEFORE the wrap, so the cost is one object per user turn
81
+ // rather than one per event — this is re-derived on every turn of a
82
+ // session whose log may hold thousands. `sessionTitle` filters again;
83
+ // it is the authority on what counts and this is not a second opinion.
84
+ const inputs = events.filter((e) => e.type === "user_input");
85
+ const raw = sessionTitle(inputs.map((event) => ({ runId: "", ts: 0, event })));
86
+ if (raw === NO_TITLE)
87
+ return `kiso — ${place}`;
88
+ const safe = escapeTerminal(raw);
89
+ // Cut by CELLS, not code points: a title of wide characters counts
90
+ // two columns each, and a count of characters would overflow the tab
91
+ // by as much again. The mark is inside the budget, never added to it.
92
+ const shown = displayWidth(safe) > TITLE_CELLS ? `${widthCut(safe, TITLE_CELLS - 1)}…` : safe;
93
+ return `kiso — ${shown} — ${place}`;
94
+ }
95
+ /** What was last written, so a repaint of the same title writes nothing.
96
+ * The title is re-derived on every bind and every user turn; most of
97
+ * those derive what is already on screen. */
98
+ let shown = null;
99
+ /**
100
+ * Write the title for this session's state. Called where the session is
101
+ * BOUND (which is one place for all three entry points — first start,
102
+ * `/resume <id>`, and a switch) and again as the session's own title
103
+ * becomes knowable, so a tab named before the first prompt is renamed by
104
+ * it rather than keeping a name that was only ever a placeholder.
105
+ */
106
+ export function paintWindowTitle(events, cwd = process.cwd()) {
107
+ if (process.stdout.isTTY !== true)
108
+ return;
109
+ const text = windowTitleText(events, basename(cwd) || cwd);
110
+ if (text === shown)
111
+ return;
112
+ shown = text;
113
+ process.stdout.write(`${OSC_TITLE_PREFIX}${text}${OSC_TITLE_SUFFIX}`);
114
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vincemakes/kiso-code",
3
- "version": "0.38.0",
3
+ "version": "0.39.1",
4
4
  "description": "kiso-code \u2014 the coding agent on kiso, the durable runtime for AI agents: kiso chat / kiso resume / kiso sessions.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -18,20 +18,20 @@
18
18
  "test": "vitest run"
19
19
  },
20
20
  "dependencies": {
21
- "@vincemakes/kiso-ask-ext": "0.38.0",
22
- "@vincemakes/kiso-core": "0.38.0",
23
- "@vincemakes/kiso-evals": "0.38.0",
24
- "@vincemakes/kiso-mcp-ext": "0.38.0",
25
- "@vincemakes/kiso-provider-anthropic": "0.38.0",
26
- "@vincemakes/kiso-provider-openai": "0.38.0",
27
- "@vincemakes/kiso-provider-openai-responses": "0.38.0",
28
- "@vincemakes/kiso-runtime": "0.38.0",
29
- "@vincemakes/kiso-skills-ext": "0.38.0",
30
- "@vincemakes/kiso-subagent-ext": "0.38.0",
31
- "@vincemakes/kiso-task-ext": "0.38.0",
32
- "@vincemakes/kiso-tools-node": "0.38.0",
33
- "@vincemakes/kiso-tui": "0.38.0",
34
- "@vincemakes/kiso-tui-cells": "0.38.0"
21
+ "@vincemakes/kiso-ask-ext": "0.39.1",
22
+ "@vincemakes/kiso-core": "0.39.1",
23
+ "@vincemakes/kiso-evals": "0.39.1",
24
+ "@vincemakes/kiso-mcp-ext": "0.39.1",
25
+ "@vincemakes/kiso-provider-anthropic": "0.39.1",
26
+ "@vincemakes/kiso-provider-openai": "0.39.1",
27
+ "@vincemakes/kiso-provider-openai-responses": "0.39.1",
28
+ "@vincemakes/kiso-runtime": "0.39.1",
29
+ "@vincemakes/kiso-skills-ext": "0.39.1",
30
+ "@vincemakes/kiso-subagent-ext": "0.39.1",
31
+ "@vincemakes/kiso-task-ext": "0.39.1",
32
+ "@vincemakes/kiso-tools-node": "0.39.1",
33
+ "@vincemakes/kiso-tui": "0.39.1",
34
+ "@vincemakes/kiso-tui-cells": "0.39.1"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@types/node": "^26.1.2",