@vincemakes/kiso-tui 0.34.0 → 0.37.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/lines.d.ts CHANGED
@@ -132,7 +132,7 @@ export interface RunUsage {
132
132
  }
133
133
  /**
134
134
  * B area/v2a: the one-line status bar after a terminal, e.g.
135
- * [turn 3 · in 12.4k out 1.8k · cache 9.2k · ctx ~14%]
135
+ * [turn 3 · fresh 12.4k out 1.8k · cache 9.2k · ctx ~14%]
136
136
  * Denoising: unknown fields are OMITTED ENTIRELY (show what there is); a fully unknown
137
137
  * usage → null (the caller prints nothing); faux mode → [turn N · faux].
138
138
  * All data comes from usage events; ctx is the approximate estimate
@@ -169,6 +169,16 @@ export interface RecapStats {
169
169
  readonly edits?: number;
170
170
  /** The turn's work BY TOOL, in first-call order (R3d). */
171
171
  readonly byTool?: readonly [string, number][];
172
+ /** W22 (owner, 2026-09-14) — the TURN's usage: the SUM over the turn's
173
+ * model calls, never the last call's alone (the scope this field
174
+ * carried until W22, which made a nine-call turn report its ninth
175
+ * call and read as the turn's). `in` is the canonical FRESH count (E2)
176
+ * and renders as `fresh`, so the number says what it is: the input the
177
+ * turn bought at full price. The rest of its prompt was cache — which
178
+ * is why the field beside it is a ratio, not a raw sum: a sum over
179
+ * calls counts the same prefix once per call. An unmeasured call
180
+ * (`known: false`) makes the whole figure unknown, and the row then
181
+ * says nothing rather than a lower bound dressed as a total. */
172
182
  readonly usage: RunUsage;
173
183
  /** R-C item 4: the per-turn cache miss (min(prevIn, in) − cacheRead),
174
184
  * passed only when above the noise floor — the re-sent-uncached
package/dist/lines.js CHANGED
@@ -141,7 +141,7 @@ function approvalDetail(name, input, resolvePath) {
141
141
  }
142
142
  /**
143
143
  * B area/v2a: the one-line status bar after a terminal, e.g.
144
- * [turn 3 · in 12.4k out 1.8k · cache 9.2k · ctx ~14%]
144
+ * [turn 3 · fresh 12.4k out 1.8k · cache 9.2k · ctx ~14%]
145
145
  * Denoising: unknown fields are OMITTED ENTIRELY (show what there is); a fully unknown
146
146
  * usage → null (the caller prints nothing); faux mode → [turn N · faux].
147
147
  * All data comes from usage events; ctx is the approximate estimate
@@ -154,7 +154,7 @@ export function renderStatusLine(turn, usage, ctxRatio, faux = false) {
154
154
  return null; // everything unknown — nothing worth showing
155
155
  const parts = [];
156
156
  if (usage.in !== null || usage.out !== null) {
157
- const seg = `${usage.in !== null ? `in ${kUnit(usage.in)}` : ""}${usage.in !== null && usage.out !== null ? " " : ""}${usage.out !== null ? `out ${kUnit(usage.out)}` : ""}`;
157
+ const seg = `${usage.in !== null ? `fresh ${kUnit(usage.in)}` : ""}${usage.in !== null && usage.out !== null ? " " : ""}${usage.out !== null ? `out ${kUnit(usage.out)}` : ""}`;
158
158
  parts.push(seg);
159
159
  }
160
160
  if (usage.cache !== null)
@@ -211,7 +211,7 @@ export function renderRecap(s) {
211
211
  : [];
212
212
  const parts = [`took ${s.seconds}s`, ...work];
213
213
  if (s.usage.known) {
214
- const seg = `${s.usage.in !== null ? `in ${kUnit(s.usage.in)}` : ""}${s.usage.in !== null && s.usage.out !== null ? " " : ""}${s.usage.out !== null ? `out ${kUnit(s.usage.out)}` : ""}`;
214
+ const seg = `${s.usage.in !== null ? `fresh ${kUnit(s.usage.in)}` : ""}${s.usage.in !== null && s.usage.out !== null ? " " : ""}${s.usage.out !== null ? `out ${kUnit(s.usage.out)}` : ""}`;
215
215
  if (seg !== "")
216
216
  parts.push(seg);
217
217
  if (s.usage.cache !== null && s.usage.in !== null && (s.usage.in > 0 || s.usage.cache > 0)) {
package/dist/status.js CHANGED
@@ -39,12 +39,24 @@ import { displayWidth } from "@vincemakes/kiso-tui-cells/width";
39
39
  * Glyphs only, no colour: intact under NO_COLOR and on any ground.
40
40
  */
41
41
  export const STATUS_GLYPHS = TWINKLE;
42
- /** The ~ctx estimate as the whole-percent LEFT. A non-finite ratio (no
43
- * window, no estimate) yields null and the row prints "~null%" — the
44
- * long-standing shape, kept on purpose: an honest null beats an
45
- * invented percentage. */
46
- function ctxLeft(ratio) {
47
- return Number.isFinite(ratio) ? Math.round((1 - ratio) * 100) : null;
42
+ /**
43
+ * The ~ctx estimate as the whole-percent LEFT, or `ctx ?` when there is no
44
+ * window to divide by.
45
+ *
46
+ * A percentage needs a denominator. When the model's context window is not
47
+ * KNOWN — the registry records null for it, nobody set one in the profile,
48
+ * no env — there is no denominator, and this row's rule is the same as
49
+ * every other number on it: a measurement, or nothing. It used to print
50
+ * `ctx left ~null%`, which at least did not invent a figure; `ctx ?` says
51
+ * the same thing to a reader.
52
+ *
53
+ * The failure this replaces is worse than either: the window fell back to
54
+ * a hardcoded 200,000 and the row printed a confident `ctx left ~82%`
55
+ * against a number nobody had measured. A reader had no way to tell that
56
+ * percentage from one computed against a real window.
57
+ */
58
+ function ctxSegment(ratio) {
59
+ return Number.isFinite(ratio) ? `ctx left ~${Math.round((1 - ratio) * 100)}%` : "ctx ?";
48
60
  }
49
61
  /**
50
62
  * TPS-1 — the settled DECODE rate of one model call: its output tokens
@@ -90,7 +102,7 @@ export function runningStatus(glyph, since, outTokens, ctxRatio, tokPerSec = nul
90
102
  // state, so its row says nothing rather than guessing.
91
103
  const rate = tokPerSec !== null ? ` · ${tokPerSec} tok/s` : "";
92
104
  const seconds = Math.max(1, Math.round((Date.now() - since) / 1000));
93
- return `${glyph} working ${seconds}s${out}${rate} · esc stop · alt+⏎ redirect · ctx left ~${ctxLeft(ctxRatio)}%`;
105
+ return `${glyph} working ${seconds}s${out}${rate} · esc stop · alt+⏎ redirect · ${ctxSegment(ctxRatio)}`;
94
106
  }
95
107
  /** DF-0330-F1 — how far the model id may be squeezed on the ROW. Twenty
96
108
  * visible columns keeps a head and a tail: `deepseek-v…s-on-0910` still
@@ -165,7 +177,7 @@ export function idleStatus(tier, model, ctxRatio, meter, W) {
165
177
  if (meter?.cacheHitPct != null)
166
178
  parts.push(`CH ${Math.round(meter.cacheHitPct)}%`);
167
179
  // costUsd deliberately NOT rendered — see StatusMeter.costUsd.
168
- parts.push(`ctx left ~${ctxLeft(ctxRatio)}%`);
180
+ parts.push(ctxSegment(ctxRatio));
169
181
  if (meter?.tokPerSec != null)
170
182
  parts.push(`${meter.tokPerSec} tok/s`); // TPS-1: last, after the ctx estimate
171
183
  return parts.join(" · ");
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vincemakes/kiso-tui",
3
- "version": "0.34.0",
4
- "description": "kiso tui — the pure terminal layer (cell renderer, dock, raw editor, diff, palette). Zero runtime dependencies: input is data, output is bytes.",
3
+ "version": "0.37.0",
4
+ "description": "kiso tui \u2014 the pure terminal layer (cell renderer, dock, raw editor, diff, palette). Zero runtime dependencies: input is data, output is bytes.",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "exports": {
@@ -35,6 +35,6 @@
35
35
  },
36
36
  "homepage": "https://github.com/vincemakes/kiso/tree/main/packages/tui#readme",
37
37
  "dependencies": {
38
- "@vincemakes/kiso-tui-cells": "0.34.0"
38
+ "@vincemakes/kiso-tui-cells": "0.37.0"
39
39
  }
40
40
  }