@vincemakes/kiso-tui 0.49.0 → 0.50.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.
@@ -143,6 +143,7 @@ export declare class Body {
143
143
  isError: boolean;
144
144
  reason?: string | null;
145
145
  untimed?: boolean;
146
+ created?: boolean;
146
147
  }): void;
147
148
  textAppend(text: string): void;
148
149
  textEnd(): void;
@@ -189,7 +190,12 @@ export declare class Body {
189
190
  * `off → on` with the new state bold. It is a switch on top of the tier,
190
191
  * not a tier, so it has a row of its own. A pipe keeps #203's words
191
192
  * (`don't ask → on`), byte for byte. */
192
- dontAskNotice(text: string, on: boolean): void;
193
+ dontAskNotice(text: string, on: boolean, unchanged?: boolean): void;
194
+ /** The notices round (owner, 2026-10-14) — a model switch, the MODE row's
195
+ * sibling: `MODEL` gold (the person's choice), `from → to` with the new
196
+ * profile bold, then what the switch carries (the model id and host, the
197
+ * effort) and when it lands. A pipe keeps `text`, byte for byte. */
198
+ modelNotice(text: string, from: string, to: string, tail: string): void;
193
199
  /**
194
200
  * Graphite §7.11 — the turn's SEAL. On the terminal a cell of its own,
195
201
  * drawn at the current width (widest tier that fits); a pipe gets
@@ -567,6 +567,8 @@ export class Body {
567
567
  cell.isError = result.isError;
568
568
  cell.resultText = result.content;
569
569
  cell.reason = result.reason ?? null;
570
+ if (result.created === true)
571
+ cell.created = true;
570
572
  cell.doneAt = result.untimed === true ? null : Date.now();
571
573
  cell.done = true;
572
574
  }
@@ -802,7 +804,7 @@ export class Body {
802
804
  * `off → on` with the new state bold. It is a switch on top of the tier,
803
805
  * not a tier, so it has a row of its own. A pipe keeps #203's words
804
806
  * (`don't ask → on`), byte for byte. */
805
- dontAskNotice(text, on) {
807
+ dontAskNotice(text, on, unchanged = false) {
806
808
  if (!this.#isActive()) {
807
809
  this.#closeOpenThinking();
808
810
  this.#closeOpenText();
@@ -812,7 +814,26 @@ export class Body {
812
814
  this.#closeOpenThinking();
813
815
  this.#closeOpenText();
814
816
  const to = on ? "on" : "off";
815
- this.#cells.push({ kind: "notice", text, done: true, label: "DON'T ASK", sentence: `${on ? "off" : "on"} \u2192 ${to}`, mark: { text: to, tone: "ink" }, stacked: true });
817
+ // the notices round (owner, 2026-10-14): setting it to what it already is
818
+ // is a row too — `already on`, not a bare sentence
819
+ const [sentence, mark] = unchanged ? [`already ${to}`, `already ${to}`] : [`${on ? "off" : "on"} \u2192 ${to}`, to];
820
+ this.#cells.push({ kind: "notice", text, done: true, label: "DON'T ASK", sentence, mark: { text: mark, tone: "ink" }, stacked: true });
821
+ this.#mark();
822
+ }
823
+ /** The notices round (owner, 2026-10-14) — a model switch, the MODE row's
824
+ * sibling: `MODEL` gold (the person's choice), `from → to` with the new
825
+ * profile bold, then what the switch carries (the model id and host, the
826
+ * effort) and when it lands. A pipe keeps `text`, byte for byte. */
827
+ modelNotice(text, from, to, tail) {
828
+ if (!this.#isActive()) {
829
+ this.#closeOpenThinking();
830
+ this.#closeOpenText();
831
+ this.#write(`${text}\n`);
832
+ return;
833
+ }
834
+ this.#closeOpenThinking();
835
+ this.#closeOpenText();
836
+ this.#cells.push({ kind: "notice", text, done: true, label: "MODEL", sentence: `${from} \u2192 ${to}${tail === "" ? "" : ` \u00b7 ${tail}`}`, mark: { text: to, tone: "ink" }, stacked: true });
816
837
  this.#mark();
817
838
  }
818
839
  /**
@@ -9,19 +9,22 @@
9
9
  * The `✦` some notices open with retires on the terminal: `✦` is the
10
10
  * turn's seal (§4), and a label says what the row is.
11
11
  */
12
- /** kiso's session events — the notices that are a KIND of thing, first
13
- * match wins. A command's own confirmation is not one of them: its words
14
- * are read as a whole, and a label would only split them. */
15
12
  const SHAPES = [
16
13
  [/^✦ compacted (.*)$/s, "COMPACTED", (m) => m[1]],
17
14
  // 0.47.1 (finding 0470-F3): one round is singular on the terminal; the
18
15
  // pipe's text (`1 rounds`) is not touched
19
16
  [/^\[\/compact\] ✦ compacted(?: · )?(.*)$/s, "COMPACTED", (m) => m[1].replace(/^1 rounds\b/, "1 round")],
17
+ // the notices round (owner, 2026-10-14): a checkpoint that did not shrink the
18
+ // context is a COMPACTED row, not a bare sentence
19
+ [/^✦ compaction discarded — (.*)$/s, "COMPACTED", (m) => `discarded \u00b7 ${m[1]}`, () => ({ text: "discarded", tone: "fail" })],
20
20
  [/^✦ pruned (.*)$/s, "PRUNED", (m) => m[1]],
21
21
  [/^✦ window learned — (.*)$/s, "WINDOW", (m) => `learned — ${m[1]}`],
22
22
  // the main-sync round: a background task's delivery (ADR-0058, main's
23
23
  // task-notice.ts) is a session event like the others
24
24
  [/^✦ task (.*)$/s, "TASK", (m) => m[1]],
25
+ // the notices round: the chain's budget and a newer install are session events
26
+ [/^✦ chain budget spent — (.*)$/s, "BUDGET", (m) => `chain spent \u00b7 ${m[1]}`],
27
+ [/^✦ (kiso \S+ is installed) — (.*)$/s, "UPDATE", (m) => `${m[1]} \u00b7 ${m[2]}`],
25
28
  [/^run failed — (.*)$/s, "FAILED", (m) => m[1]],
26
29
  [/^(\S+) FAILED — (.*)$/s, "UNCERTAIN", (m) => `${m[1]} — ${m[2]}`],
27
30
  // Graphite P1b (owner, 2026-09-30): dontAsk leaves an interrupted call
@@ -46,14 +49,21 @@ const SHAPES = [
46
49
  // yet]`), or `--- … ---` rules; on the terminal the person has just
47
50
  // typed the command, so the reply is a sentence at the content edge.
48
51
  // A pipe keeps every bracket.
49
- [/^\[reload\] (\d+ extensions?\b.*)$/s, null, (m) => `reloaded ${m[1]}`],
50
- [/^\[reload\] (.*)$/s, null, (m) => `reload failed: ${m[1]}`],
52
+ [/^\[reload\] (\d+ extensions?\b.*)$/s, "RELOAD", (m) => m[1].replace(" \u2014 the conversation", " \u00b7 the conversation")],
53
+ [/^\[reload\] (.*)$/s, "RELOAD", (m) => `failed \u00b7 ${m[1].replace(" \u2014 nothing changed", " \u00b7 nothing changed")}`, () => ({ text: "failed", tone: "fail" })],
54
+ // the notices round: a command that changed what the person set says so
55
+ [/^named "(.*)"$/s, "NAME", (m) => m[1]],
56
+ [/^name cleared — (.*)$/s, "NAME", (m) => `cleared \u00b7 ${m[1]}`],
57
+ [/^name: (.*)$/s, "NAME", (m) => m[1]],
58
+ [/^unnamed — (.*)$/s, "NAME", (m) => `unnamed \u00b7 ${m[1]}`],
59
+ [/^(\S+): stop requested$/s, "TASK", (m) => `${m[1]} \u00b7 stop requested`],
60
+ [/^(\S+): nothing to stop \((.*)\)$/s, "TASK", (m) => `${m[1]} \u00b7 nothing to stop (${m[2]})`],
51
61
  [/^\[\/([a-z-]+)\] failed: (.*)$/s, null, (m) => `/${m[1]} failed: ${m[2]}`],
52
62
  [/^\[\/[a-z-]+\] (.*)$/s, null, (m) => m[1]],
53
63
  [/^\[(turn held — [^\]]+)\] (.*)$/s, null, (m) => `${m[1]} · ${m[2]}`],
54
64
  [/^\[([^[\]\n]+)\]$/s, null, (m) => m[1]],
55
65
  [/^no such mode: (.*)\ntiers: (.*)$/s, null, (m) => `no such mode: ${m[1]} · tiers: ${m[2]}`],
56
- [/^--- (\d+ earlier blocks?) not re-wrapped \(bounded at two screens\) ---$/s, null, (m) => `${m[1]} not re-wrapped — bounded at two screens`],
66
+ [/^--- (\d+ earlier blocks?) not re-wrapped \(bounded at two screens\) ---$/s, "REWRAPPED", (m) => `${m[1]} not re-wrapped \u00b7 bounded at two screens`],
57
67
  ];
58
68
  /** The main sync (0.46.2, Amendment 8) — a task kiso lost track of, said
59
69
  * the moment it is concluded: `✦ lost track of <id> (<what>) — it may
@@ -74,10 +84,12 @@ export function noticeMeta(text) {
74
84
  // verification pass's content): no label of its own
75
85
  if (/^ {2}\S/.test(text))
76
86
  return { label: "", sentence: text.trim() };
77
- for (const [re, label, sentence] of SHAPES) {
87
+ for (const [re, label, sentence, mark] of SHAPES) {
78
88
  const m = re.exec(text);
79
- if (m !== null)
80
- return label === null ? { sentence: sentence(m) } : { label, sentence: sentence(m) };
89
+ if (m === null)
90
+ continue;
91
+ const marked = mark === undefined ? {} : { mark: mark(m) };
92
+ return label === null ? { sentence: sentence(m), ...marked } : { label, sentence: sentence(m), ...marked };
81
93
  }
82
94
  // no kind of its own: the sentence stays whole — only the `✦`, which is
83
95
  // the seal's mark on a terminal (§4), comes off
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vincemakes/kiso-tui",
3
- "version": "0.49.0",
3
+ "version": "0.50.1",
4
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",
@@ -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.49.0"
38
+ "@vincemakes/kiso-tui-cells": "0.50.1"
39
39
  }
40
40
  }