@sagmans/dsh-tui 0.6.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.
Files changed (271) hide show
  1. package/.agents/skills/dsh-tui-dogfood/SKILL.md +83 -0
  2. package/.agents/skills/dsh-tui-dogfood/references/home-state.md +78 -0
  3. package/.agents/skills/dsh-tui-dogfood/scripts/clone-links.mjs +133 -0
  4. package/.agents/skills/dsh-tui-dogfood/scripts/run-plugin-from-worktree.sh +417 -0
  5. package/.agents/skills/dsh-tui-update-models/SKILL.md +199 -0
  6. package/.agents/skills/dsh-tui-update-models/references/model-wiring.md +292 -0
  7. package/.agents/skills/dsh-tui-update-models/scripts/dump-model-catalog.mjs +314 -0
  8. package/README.md +154 -27
  9. package/lib/agent/present.d.ts.map +1 -1
  10. package/lib/agent/present.js +2 -1
  11. package/lib/agent/present.js.map +1 -1
  12. package/lib/cards/composition.d.ts +68 -0
  13. package/lib/cards/composition.d.ts.map +1 -0
  14. package/lib/cards/composition.js +117 -0
  15. package/lib/cards/composition.js.map +1 -0
  16. package/lib/cards/presenter.d.ts +23 -0
  17. package/lib/cards/presenter.d.ts.map +1 -0
  18. package/lib/cards/presenter.js +394 -0
  19. package/lib/cards/presenter.js.map +1 -0
  20. package/lib/cards/preview.d.ts +42 -0
  21. package/lib/cards/preview.d.ts.map +1 -0
  22. package/lib/cards/preview.js +51 -0
  23. package/lib/cards/preview.js.map +1 -0
  24. package/lib/cards.d.ts +12 -120
  25. package/lib/cards.d.ts.map +1 -1
  26. package/lib/cards.js +4 -556
  27. package/lib/cards.js.map +1 -1
  28. package/lib/compat/section.d.ts +29 -0
  29. package/lib/compat/section.d.ts.map +1 -0
  30. package/lib/compat/section.js +82 -0
  31. package/lib/compat/section.js.map +1 -0
  32. package/lib/config.d.ts +27 -2
  33. package/lib/config.d.ts.map +1 -1
  34. package/lib/config.js +61 -1
  35. package/lib/config.js.map +1 -1
  36. package/lib/contracts.d.ts +28 -0
  37. package/lib/contracts.d.ts.map +1 -1
  38. package/lib/fold-cursor.d.ts +8 -0
  39. package/lib/fold-cursor.d.ts.map +1 -1
  40. package/lib/fold-cursor.js +18 -0
  41. package/lib/fold-cursor.js.map +1 -1
  42. package/lib/gates/question-card.d.ts +77 -0
  43. package/lib/gates/question-card.d.ts.map +1 -0
  44. package/lib/gates/question-card.js +113 -0
  45. package/lib/gates/question-card.js.map +1 -0
  46. package/lib/gates/questions.d.ts +127 -0
  47. package/lib/gates/questions.d.ts.map +1 -0
  48. package/lib/gates/questions.js +418 -0
  49. package/lib/gates/questions.js.map +1 -0
  50. package/lib/gates.d.ts +1 -113
  51. package/lib/gates.d.ts.map +1 -1
  52. package/lib/gates.js +1 -484
  53. package/lib/gates.js.map +1 -1
  54. package/lib/herdr/client.d.ts +8 -0
  55. package/lib/herdr/client.d.ts.map +1 -1
  56. package/lib/herdr/client.js +13 -1
  57. package/lib/herdr/client.js.map +1 -1
  58. package/lib/herdr/constants.d.ts +18 -0
  59. package/lib/herdr/constants.d.ts.map +1 -1
  60. package/lib/herdr/constants.js +18 -0
  61. package/lib/herdr/constants.js.map +1 -1
  62. package/lib/herdr/reporter.d.ts +20 -4
  63. package/lib/herdr/reporter.d.ts.map +1 -1
  64. package/lib/herdr/reporter.js +70 -20
  65. package/lib/herdr/reporter.js.map +1 -1
  66. package/lib/herdr/state.d.ts +10 -0
  67. package/lib/herdr/state.d.ts.map +1 -1
  68. package/lib/herdr/state.js +21 -4
  69. package/lib/herdr/state.js.map +1 -1
  70. package/lib/index.d.ts +1 -0
  71. package/lib/index.d.ts.map +1 -1
  72. package/lib/index.js +348 -2602
  73. package/lib/index.js.map +1 -1
  74. package/lib/input/action-catalog.d.ts +74 -0
  75. package/lib/input/action-catalog.d.ts.map +1 -0
  76. package/lib/input/action-catalog.js +137 -0
  77. package/lib/input/action-catalog.js.map +1 -0
  78. package/lib/input/actions.d.ts +5 -81
  79. package/lib/input/actions.d.ts.map +1 -1
  80. package/lib/input/actions.js +4 -625
  81. package/lib/input/actions.js.map +1 -1
  82. package/lib/input/completion.d.ts +1 -1
  83. package/lib/input/completion.d.ts.map +1 -1
  84. package/lib/input/completion.js +2 -1
  85. package/lib/input/completion.js.map +1 -1
  86. package/lib/input/file-index.d.ts +40 -0
  87. package/lib/input/file-index.d.ts.map +1 -0
  88. package/lib/input/file-index.js +141 -0
  89. package/lib/input/file-index.js.map +1 -0
  90. package/lib/input/file-search.d.ts +1 -38
  91. package/lib/input/file-search.d.ts.map +1 -1
  92. package/lib/input/file-search.js +1 -487
  93. package/lib/input/file-search.js.map +1 -1
  94. package/lib/input/key-press.d.ts +57 -0
  95. package/lib/input/key-press.d.ts.map +1 -0
  96. package/lib/input/key-press.js +218 -0
  97. package/lib/input/key-press.js.map +1 -0
  98. package/lib/input/keymap-conflicts.d.ts +59 -0
  99. package/lib/input/keymap-conflicts.d.ts.map +1 -0
  100. package/lib/input/keymap-conflicts.js +292 -0
  101. package/lib/input/keymap-conflicts.js.map +1 -0
  102. package/lib/input/keymap-settings.js +1 -1
  103. package/lib/input/keymap-settings.js.map +1 -1
  104. package/lib/input/keymap.d.ts.map +1 -1
  105. package/lib/input/keymap.js +3 -1
  106. package/lib/input/keymap.js.map +1 -1
  107. package/lib/input/workspace-files.d.ts +10 -0
  108. package/lib/input/workspace-files.d.ts.map +1 -0
  109. package/lib/input/workspace-files.js +359 -0
  110. package/lib/input/workspace-files.js.map +1 -0
  111. package/lib/install-skills.d.ts +39 -0
  112. package/lib/install-skills.d.ts.map +1 -0
  113. package/lib/install-skills.js +273 -0
  114. package/lib/install-skills.js.map +1 -0
  115. package/lib/keys-command.d.ts +2 -1
  116. package/lib/keys-command.d.ts.map +1 -1
  117. package/lib/keys-command.js +2 -1
  118. package/lib/keys-command.js.map +1 -1
  119. package/lib/model-list.d.ts +37 -0
  120. package/lib/model-list.d.ts.map +1 -0
  121. package/lib/model-list.js +60 -0
  122. package/lib/model-list.js.map +1 -0
  123. package/lib/startup.d.ts +8 -0
  124. package/lib/startup.d.ts.map +1 -1
  125. package/lib/startup.js +120 -24
  126. package/lib/startup.js.map +1 -1
  127. package/lib/subagents.d.ts +7 -3
  128. package/lib/subagents.d.ts.map +1 -1
  129. package/lib/subagents.js +28 -4
  130. package/lib/subagents.js.map +1 -1
  131. package/lib/surface/appearance-preferences.d.ts +26 -0
  132. package/lib/surface/appearance-preferences.d.ts.map +1 -0
  133. package/lib/surface/appearance-preferences.js +139 -0
  134. package/lib/surface/appearance-preferences.js.map +1 -0
  135. package/lib/surface/appearance.d.ts +87 -0
  136. package/lib/surface/appearance.d.ts.map +1 -0
  137. package/lib/surface/appearance.js +353 -0
  138. package/lib/surface/appearance.js.map +1 -0
  139. package/lib/surface/background-work.d.ts +51 -0
  140. package/lib/surface/background-work.d.ts.map +1 -0
  141. package/lib/surface/background-work.js +172 -0
  142. package/lib/surface/background-work.js.map +1 -0
  143. package/lib/surface/commands.d.ts +82 -0
  144. package/lib/surface/commands.d.ts.map +1 -0
  145. package/lib/surface/commands.js +370 -0
  146. package/lib/surface/commands.js.map +1 -0
  147. package/lib/surface/modal-input.d.ts +59 -0
  148. package/lib/surface/modal-input.d.ts.map +1 -0
  149. package/lib/surface/modal-input.js +243 -0
  150. package/lib/surface/modal-input.js.map +1 -0
  151. package/lib/surface/model-choice.d.ts +54 -0
  152. package/lib/surface/model-choice.d.ts.map +1 -0
  153. package/lib/surface/model-choice.js +325 -0
  154. package/lib/surface/model-choice.js.map +1 -0
  155. package/lib/surface/preset-choice.d.ts +78 -0
  156. package/lib/surface/preset-choice.d.ts.map +1 -0
  157. package/lib/surface/preset-choice.js +163 -0
  158. package/lib/surface/preset-choice.js.map +1 -0
  159. package/lib/surface/prompt-input.d.ts +97 -0
  160. package/lib/surface/prompt-input.d.ts.map +1 -0
  161. package/lib/surface/prompt-input.js +215 -0
  162. package/lib/surface/prompt-input.js.map +1 -0
  163. package/lib/surface/prompt-memory.d.ts +76 -0
  164. package/lib/surface/prompt-memory.d.ts.map +1 -0
  165. package/lib/surface/prompt-memory.js +167 -0
  166. package/lib/surface/prompt-memory.js.map +1 -0
  167. package/lib/surface/session-lifecycle.d.ts +120 -0
  168. package/lib/surface/session-lifecycle.d.ts.map +1 -0
  169. package/lib/surface/session-lifecycle.js +324 -0
  170. package/lib/surface/session-lifecycle.js.map +1 -0
  171. package/lib/surface/session-picker.d.ts +39 -0
  172. package/lib/surface/session-picker.d.ts.map +1 -0
  173. package/lib/surface/session-picker.js +107 -0
  174. package/lib/surface/session-picker.js.map +1 -0
  175. package/lib/surface/session-view.d.ts +86 -0
  176. package/lib/surface/session-view.d.ts.map +1 -0
  177. package/lib/surface/session-view.js +215 -0
  178. package/lib/surface/session-view.js.map +1 -0
  179. package/lib/surface/staged-turns.d.ts +81 -0
  180. package/lib/surface/staged-turns.d.ts.map +1 -0
  181. package/lib/surface/staged-turns.js +206 -0
  182. package/lib/surface/staged-turns.js.map +1 -0
  183. package/lib/surface/terminal-lifecycle.d.ts +76 -0
  184. package/lib/surface/terminal-lifecycle.d.ts.map +1 -0
  185. package/lib/surface/terminal-lifecycle.js +222 -0
  186. package/lib/surface/terminal-lifecycle.js.map +1 -0
  187. package/lib/terminal-text/scan.d.ts +44 -0
  188. package/lib/terminal-text/scan.d.ts.map +1 -0
  189. package/lib/terminal-text/scan.js +195 -0
  190. package/lib/terminal-text/scan.js.map +1 -0
  191. package/lib/terminal-text/sgr.d.ts +32 -0
  192. package/lib/terminal-text/sgr.d.ts.map +1 -0
  193. package/lib/terminal-text/sgr.js +203 -0
  194. package/lib/terminal-text/sgr.js.map +1 -0
  195. package/lib/terminal-text.d.ts +1 -1
  196. package/lib/terminal-text.d.ts.map +1 -1
  197. package/lib/terminal-text.js +2 -379
  198. package/lib/terminal-text.js.map +1 -1
  199. package/lib/theme-command.js +2 -1
  200. package/lib/theme-command.js.map +1 -1
  201. package/lib/theme-defaults.d.ts +64 -0
  202. package/lib/theme-defaults.d.ts.map +1 -0
  203. package/lib/theme-defaults.js +248 -0
  204. package/lib/theme-defaults.js.map +1 -0
  205. package/lib/theme-files.d.ts +1 -1
  206. package/lib/theme-files.d.ts.map +1 -1
  207. package/lib/theme-files.js +1 -1
  208. package/lib/theme-files.js.map +1 -1
  209. package/lib/theme-resolver.d.ts +36 -0
  210. package/lib/theme-resolver.d.ts.map +1 -0
  211. package/lib/theme-resolver.js +112 -0
  212. package/lib/theme-resolver.js.map +1 -0
  213. package/lib/theme-schema.d.ts.map +1 -1
  214. package/lib/theme-schema.js +3 -2
  215. package/lib/theme-schema.js.map +1 -1
  216. package/lib/theme-settings.d.ts +5 -7
  217. package/lib/theme-settings.d.ts.map +1 -1
  218. package/lib/theme-settings.js +37 -21
  219. package/lib/theme-settings.js.map +1 -1
  220. package/lib/theme-tokens.d.ts +0 -89
  221. package/lib/theme-tokens.d.ts.map +1 -1
  222. package/lib/theme-tokens.js +0 -356
  223. package/lib/theme-tokens.js.map +1 -1
  224. package/lib/theme.d.ts +1 -1
  225. package/lib/theme.d.ts.map +1 -1
  226. package/lib/theme.js +2 -1
  227. package/lib/theme.js.map +1 -1
  228. package/lib/tool-display.d.ts.map +1 -1
  229. package/lib/tool-display.js +2 -1
  230. package/lib/tool-display.js.map +1 -1
  231. package/lib/transcript/message-content.d.ts +21 -0
  232. package/lib/transcript/message-content.d.ts.map +1 -0
  233. package/lib/transcript/message-content.js +61 -0
  234. package/lib/transcript/message-content.js.map +1 -0
  235. package/lib/transcript/tool-calls.d.ts +106 -0
  236. package/lib/transcript/tool-calls.d.ts.map +1 -0
  237. package/lib/transcript/tool-calls.js +254 -0
  238. package/lib/transcript/tool-calls.js.map +1 -0
  239. package/lib/transcript.d.ts +14 -55
  240. package/lib/transcript.d.ts.map +1 -1
  241. package/lib/transcript.js +31 -253
  242. package/lib/transcript.js.map +1 -1
  243. package/lib/ui/dock.d.ts +14 -2
  244. package/lib/ui/dock.d.ts.map +1 -1
  245. package/lib/ui/dock.js +52 -10
  246. package/lib/ui/dock.js.map +1 -1
  247. package/lib/ui/editor.d.ts.map +1 -1
  248. package/lib/ui/editor.js +2 -1
  249. package/lib/ui/editor.js.map +1 -1
  250. package/lib/ui/keymap-picker.d.ts +2 -1
  251. package/lib/ui/keymap-picker.d.ts.map +1 -1
  252. package/lib/ui/keymap-picker.js +1 -0
  253. package/lib/ui/keymap-picker.js.map +1 -1
  254. package/lib/ui/view/gate-card.d.ts +21 -0
  255. package/lib/ui/view/gate-card.d.ts.map +1 -0
  256. package/lib/ui/view/gate-card.js +104 -0
  257. package/lib/ui/view/gate-card.js.map +1 -0
  258. package/lib/ui/view/tool-card.d.ts +149 -0
  259. package/lib/ui/view/tool-card.d.ts.map +1 -0
  260. package/lib/ui/view/tool-card.js +429 -0
  261. package/lib/ui/view/tool-card.js.map +1 -0
  262. package/lib/ui/view/transcript-message.d.ts +62 -0
  263. package/lib/ui/view/transcript-message.d.ts.map +1 -0
  264. package/lib/ui/view/transcript-message.js +158 -0
  265. package/lib/ui/view/transcript-message.js.map +1 -0
  266. package/lib/ui/view.d.ts +105 -223
  267. package/lib/ui/view.d.ts.map +1 -1
  268. package/lib/ui/view.js +132 -679
  269. package/lib/ui/view.js.map +1 -1
  270. package/package.json +3 -1
  271. package/themes/violet-orbit.yaml +7 -5
@@ -0,0 +1,394 @@
1
+ import { cardRow, bound, boundTail, contentLines } from "../cards.js";
2
+ import {} from '@deepseek-ai/dsh-tools';
3
+ import { countTokens, formatTokens } from "../tokens.js";
4
+ /** A text with the newline that only terminates its last line removed. */
5
+ function withoutTrailingBreaks(text) {
6
+ return text.replace(/\n+$/, '');
7
+ }
8
+ /** How many lines a text holds, ignoring the newline that only terminates the last one. */
9
+ function lineCount(text) {
10
+ const body = withoutTrailingBreaks(text);
11
+ return body === '' ? 0 : body.split('\n').length;
12
+ }
13
+ /**
14
+ * The size of a text a card presents, in lines and in tokens.
15
+ *
16
+ * A reader deciding whether to open a file cares about both: lines say how tall
17
+ * it is, tokens say what it cost to put in the conversation.
18
+ */
19
+ function sizeStats(text) {
20
+ const body = withoutTrailingBreaks(text);
21
+ const lines = lineCount(body);
22
+ const tokens = countTokens(body);
23
+ const stats = [];
24
+ if (lines > 0)
25
+ stats.push({ kind: 'size', text: `${lines} line${lines === 1 ? '' : 's'}` });
26
+ if (tokens > 0)
27
+ stats.push({ kind: 'size', text: `${formatTokens(tokens)} tok` });
28
+ return stats;
29
+ }
30
+ /**
31
+ * A file change's split into added, changed, and removed lines.
32
+ *
33
+ * A replacement is one changed line, not an add plus a remove, so the smaller
34
+ * of the two sides is the changed count and only the excess counts as pure
35
+ * additions or deletions — otherwise every edit reads as twice its size. Each
36
+ * file is netted on its own for the same reason: one file's additions must not
37
+ * cancel another file's deletions, or a change to two files reads as a rewrite
38
+ * of neither.
39
+ */
40
+ function changeStats(diffs) {
41
+ let added = 0;
42
+ let changed = 0;
43
+ let removed = 0;
44
+ for (const diff of diffs) {
45
+ let fileAdded = 0;
46
+ let fileRemoved = 0;
47
+ for (const row of renderFileDiff(diff)) {
48
+ const cls = row.parts[0]?.class;
49
+ if (cls === 'added')
50
+ fileAdded += 1;
51
+ else if (cls === 'removed')
52
+ fileRemoved += 1;
53
+ }
54
+ const fileChanged = Math.min(fileAdded, fileRemoved);
55
+ added += fileAdded - fileChanged;
56
+ changed += fileChanged;
57
+ removed += fileRemoved - fileChanged;
58
+ }
59
+ const stats = [];
60
+ if (added > 0)
61
+ stats.push({ kind: 'added', text: String(added) });
62
+ if (changed > 0)
63
+ stats.push({ kind: 'changed', text: String(changed) });
64
+ if (removed > 0)
65
+ stats.push({ kind: 'removed', text: String(removed) });
66
+ return stats;
67
+ }
68
+ /**
69
+ * The window a read returned: its line range, how many lines, and their token size.
70
+ *
71
+ * An empty window still names the offset it starts at, because the view keeps it
72
+ * for exactly that case, and counts the model-facing content the card falls back
73
+ * to drawing rather than reporting a size of zero.
74
+ */
75
+ function readStats(read) {
76
+ const text = read.lines.length > 0
77
+ ? read.lines.map(line => line.text).join('\n')
78
+ : contentLines(read.content).join('\n');
79
+ const count = read.lines.length > 0 ? read.lines.length : lineCount(text);
80
+ const start = read.offset;
81
+ const stats = [
82
+ { kind: 'size', text: count <= 1 ? `L${start}` : `L${start}–${start + count - 1}` },
83
+ { kind: 'size', text: `${count} line${count === 1 ? '' : 's'}` },
84
+ ];
85
+ const tokens = countTokens(withoutTrailingBreaks(text));
86
+ if (tokens > 0)
87
+ stats.push({ kind: 'size', text: `${formatTokens(tokens)} tok` });
88
+ return stats;
89
+ }
90
+ /**
91
+ * A diff's measured facts: a change with no prior content reports its size,
92
+ * while one that carried prior content reports its line changes.
93
+ *
94
+ * `oldText === null` means the prior content was unavailable at call time — a
95
+ * new file, or a whole-file overwrite — so no diff can be counted and the size
96
+ * is the only honest fact; naming that a *creation* would misread every
97
+ * overwrite as a new file.
98
+ */
99
+ function diffStats(diffs) {
100
+ const withoutPrior = diffs.length > 0 && diffs.every(diff => diff.oldText === null);
101
+ return withoutPrior ? sizeStats(diffs.map(diff => diff.newText).join('\n')) : changeStats(diffs);
102
+ }
103
+ /**
104
+ * Render one file change as a bounded unified hunk.
105
+ *
106
+ * Only the changed middle is shown: a presenter has the prior and next text but
107
+ * no hunk list, so trimming the shared prefix and suffix yields the same region
108
+ * a full diff would highlight without paying for a line-diff computation on
109
+ * every frame.
110
+ */
111
+ export function renderFileDiff(diff) {
112
+ const before = diff.oldText === null ? [] : diff.oldText.split('\n');
113
+ const after = diff.newText.split('\n');
114
+ let head = 0;
115
+ while (head < before.length && head < after.length && before[head] === after[head])
116
+ head += 1;
117
+ let tail = 0;
118
+ while (tail < before.length - head
119
+ && tail < after.length - head
120
+ && before[before.length - 1 - tail] === after[after.length - 1 - tail])
121
+ tail += 1;
122
+ const removed = before.slice(head, before.length - tail);
123
+ const added = after.slice(head, after.length - tail);
124
+ // "new" keys off the absent prior text, not off an empty hunk: an unchanged
125
+ // file has no removals either and must not read as a creation.
126
+ const header = diff.oldText === null ? 'new' : `-${removed.length} +${added.length}`;
127
+ const rows = [cardRow('header', `${diff.path} ${header}`)];
128
+ if (head > 0)
129
+ rows.push(cardRow('hunk', `@@ ${head} unchanged line${head === 1 ? '' : 's'} before`));
130
+ for (const line of removed)
131
+ rows.push(cardRow('removed', `-${line}`));
132
+ for (const line of added)
133
+ rows.push(cardRow('added', `+${line}`));
134
+ if (tail > 0)
135
+ rows.push(cardRow('hunk', `@@ ${tail} unchanged line${tail === 1 ? '' : 's'} after`));
136
+ return rows;
137
+ }
138
+ /**
139
+ * Verbs a presenter may open its title with that only restate the call.
140
+ *
141
+ * The subject a reader scans for is what follows the verb, so the surface draws
142
+ * the card from there: "skill project-skill" rather than "Load skill
143
+ * project-skill". Only a declared title is normalized — a path or a command is
144
+ * the call's own data, and shortening that would misreport what ran — and the
145
+ * list stays literal because inferring a verb could cut a real title short.
146
+ */
147
+ const REDUNDANT_TITLE_LEADS = ['Load '];
148
+ export function title(view, fallback) {
149
+ const declared = view.title?.trim() ?? '';
150
+ const lead = REDUNDANT_TITLE_LEADS.find(prefix => declared.startsWith(prefix));
151
+ const shown = lead === undefined ? declared : declared.slice(lead.length).trim();
152
+ return shown === '' ? fallback : shown;
153
+ }
154
+ /** A read line keeps its number apart from its text, because they read differently. */
155
+ function readLine(number, text) {
156
+ return { parts: [{ class: 'lineNumber', text: `${number}:` }, { class: 'line', text: ` ${text}` }] };
157
+ }
158
+ /** A search hit keeps its location apart from the matching line. */
159
+ function searchHit(path, lineNumber, line) {
160
+ return {
161
+ parts: [
162
+ { class: 'path', text: path },
163
+ { class: 'lineNumber', text: `:${lineNumber}:` },
164
+ { class: 'match', text: ` ${line}` },
165
+ ],
166
+ };
167
+ }
168
+ /** Map a tool's pending-call intent to a card, falling back to the raw call name. */
169
+ export function cardOfCall(view, name) {
170
+ if (view === undefined) {
171
+ return { kind: 'generic', tool: name, title: name, detail: [], failed: false, totalLines: 0 };
172
+ }
173
+ switch (view.card) {
174
+ case 'terminal': {
175
+ const terminal = view;
176
+ const rows = [];
177
+ if (terminal.description !== undefined && terminal.description !== '')
178
+ rows.push(cardRow('output', terminal.description));
179
+ if (terminal.cwd !== undefined && terminal.cwd !== '')
180
+ rows.push(cardRow('cwd', `cwd ${terminal.cwd}`));
181
+ // The header names the tool so the command can sit on its own row: a
182
+ // terminal view's own title IS the command, and a fold must not hide it.
183
+ const command = terminal.title?.trim() ?? '';
184
+ return {
185
+ kind: 'terminal',
186
+ tool: name,
187
+ title: name,
188
+ ...(command === '' ? {} : { argument: command }),
189
+ detail: bound(rows).detail,
190
+ failed: false,
191
+ totalLines: 0,
192
+ };
193
+ }
194
+ case 'diff': {
195
+ const diff = view;
196
+ const bounded = bound(diff.diffs.flatMap(renderFileDiff));
197
+ const path = diff.diffs[0]?.path;
198
+ if (path === undefined || path === '') {
199
+ return { kind: 'diff', tool: name, title: title(diff, name), detail: bounded.detail, failed: false, totalLines: bounded.totalLines };
200
+ }
201
+ return {
202
+ kind: 'diff',
203
+ tool: name,
204
+ title: name,
205
+ argument: path,
206
+ detail: bounded.detail,
207
+ failed: false,
208
+ totalLines: bounded.totalLines,
209
+ };
210
+ }
211
+ default: {
212
+ const generic = view;
213
+ const lines = contentLines(generic.content);
214
+ if (generic.rawInput !== undefined && lines.length === 0) {
215
+ lines.push(typeof generic.rawInput === 'string' ? generic.rawInput : JSON.stringify(generic.rawInput));
216
+ }
217
+ const bounded = bound(lines.map(line => cardRow('detail', line)));
218
+ // A call that names a file has an argument worth its own colour; one that
219
+ // does not keeps its declared title, which is already the label.
220
+ const location = generic.locations?.[0]?.path;
221
+ if (location === undefined || location === '') {
222
+ return { kind: 'generic', tool: name, title: title(generic, name), detail: bounded.detail, failed: false, totalLines: bounded.totalLines };
223
+ }
224
+ return {
225
+ kind: 'generic',
226
+ tool: name,
227
+ title: name,
228
+ argument: location,
229
+ detail: bounded.detail,
230
+ failed: false,
231
+ totalLines: bounded.totalLines,
232
+ };
233
+ }
234
+ }
235
+ }
236
+ /** Map a tool's result intent to a card, falling back to the model-facing text. */
237
+ export function cardOfResult(view, input) {
238
+ const failed = input.failed;
239
+ if (view === undefined) {
240
+ const bounded = bound(input.contentLines.map(line => cardRow('detail', line)));
241
+ return { kind: 'generic', tool: input.name, title: input.name, detail: bounded.detail, failed, totalLines: bounded.totalLines };
242
+ }
243
+ switch (view.card) {
244
+ case 'terminal': {
245
+ const terminal = view;
246
+ // A terminating newline is the shell's, not a row: keeping it would spend
247
+ // one slot of the preview window on a blank line the renderer then drops.
248
+ const raw = (terminal.output ?? '').replace(/\n+$/, '');
249
+ const rows = raw === '' ? [] : raw.split('\n').map(line => cardRow('output', line));
250
+ const status = terminal.signal !== undefined && terminal.signal !== ''
251
+ ? `signal ${terminal.signal}`
252
+ : terminal.exitCode === undefined ? undefined : `exit ${terminal.exitCode}`;
253
+ // A command that exited non-zero, or died on a signal, is a call that
254
+ // failed, whatever the log's own flag said: the harness reports a shell's
255
+ // exit code as its result rather than as an error, so that flag is silent
256
+ // about how the command actually ended.
257
+ const endedBadly = terminal.exitCode === undefined
258
+ ? terminal.signal !== undefined && terminal.signal !== ''
259
+ : terminal.exitCode !== 0;
260
+ // The output is bounded from its END: a command that printed far more
261
+ // than retention keeps must still show how it finished, and the folded
262
+ // preview tails what is retained again.
263
+ const bounded = boundTail(rows);
264
+ // A terminal result mostly omits the title, because the pending call
265
+ // already carried the command; it is only a fallback for a resumed fold
266
+ // that never saw the call.
267
+ const command = terminal.title?.trim() ?? '';
268
+ return {
269
+ kind: 'terminal',
270
+ tool: input.name,
271
+ title: input.name,
272
+ ...(command === '' ? {} : { argument: command }),
273
+ ...(status === undefined ? {} : { status }),
274
+ detail: bounded.detail,
275
+ failed: failed || endedBadly,
276
+ totalLines: bounded.totalLines,
277
+ };
278
+ }
279
+ case 'diff': {
280
+ const diff = view;
281
+ const bounded = bound(diff.diffs.flatMap(renderFileDiff));
282
+ const path = diff.diffs[0]?.path;
283
+ const stats = diffStats(diff.diffs);
284
+ if (path === undefined || path === '') {
285
+ return {
286
+ kind: 'diff',
287
+ tool: input.name,
288
+ title: title(diff, input.name),
289
+ ...(stats.length === 0 ? {} : { stats }),
290
+ detail: bounded.detail,
291
+ failed,
292
+ totalLines: bounded.totalLines,
293
+ };
294
+ }
295
+ return {
296
+ kind: 'diff',
297
+ tool: input.name,
298
+ title: input.name,
299
+ argument: path,
300
+ ...(stats.length === 0 ? {} : { stats }),
301
+ detail: bounded.detail,
302
+ failed,
303
+ totalLines: bounded.totalLines,
304
+ };
305
+ }
306
+ case 'search': {
307
+ const search = view;
308
+ const rows = search.shape === 'paths'
309
+ ? search.paths.map(path => cardRow('path', path))
310
+ : search.files.flatMap(file => file.matches.map(match => searchHit(file.path, match.lineNumber, match.line)));
311
+ if (search.truncated)
312
+ rows.push(cardRow('truncated', `… ${search.total} total`));
313
+ const bounded = bound(rows);
314
+ return {
315
+ kind: 'search',
316
+ tool: input.name,
317
+ title: title(search, input.name),
318
+ detail: bounded.detail,
319
+ failed,
320
+ totalLines: bounded.totalLines,
321
+ };
322
+ }
323
+ case 'read': {
324
+ const read = view;
325
+ // The header now carries the path and the size stats, so the detail rows
326
+ // are only the numbered lines themselves.
327
+ const rows = [];
328
+ if (read.lines.length > 0) {
329
+ for (const line of read.lines)
330
+ rows.push(readLine(line.number, line.text));
331
+ }
332
+ else {
333
+ for (const line of contentLines(read.content))
334
+ rows.push(cardRow('line', line));
335
+ }
336
+ const bounded = bound(rows);
337
+ const stats = readStats(read);
338
+ return {
339
+ kind: 'read',
340
+ tool: input.name,
341
+ title: input.name,
342
+ ...(read.path === '' ? {} : { argument: read.path }),
343
+ ...(stats.length === 0 ? {} : { stats }),
344
+ detail: bounded.detail,
345
+ failed,
346
+ totalLines: bounded.totalLines,
347
+ };
348
+ }
349
+ case 'web': {
350
+ const web = view;
351
+ const rows = [];
352
+ if (web.kind === 'search') {
353
+ if (web.answer !== undefined && web.answer !== '') {
354
+ for (const line of web.answer.split('\n'))
355
+ rows.push(cardRow('detail', line));
356
+ }
357
+ for (const source of web.sources) {
358
+ rows.push(cardRow('source', source.title === undefined ? source.url : `${source.title} — ${source.url}`));
359
+ }
360
+ if (web.truncated)
361
+ rows.push(cardRow('truncated', '… more sources'));
362
+ }
363
+ else {
364
+ rows.push(cardRow('url', `${web.url} → ${web.statusCode}`));
365
+ if (web.truncated)
366
+ rows.push(cardRow('truncated', '… body truncated'));
367
+ }
368
+ const bounded = bound(rows);
369
+ return {
370
+ kind: 'web',
371
+ tool: input.name,
372
+ title: title(web, input.name),
373
+ detail: bounded.detail,
374
+ failed,
375
+ totalLines: bounded.totalLines,
376
+ };
377
+ }
378
+ default: {
379
+ const generic = view;
380
+ const lines = contentLines(generic.content);
381
+ const chosen = lines.length > 0 ? lines : input.contentLines;
382
+ const bounded = bound(chosen.map(line => cardRow('detail', line)));
383
+ return {
384
+ kind: 'generic',
385
+ tool: input.name,
386
+ title: title(generic, input.name),
387
+ detail: bounded.detail,
388
+ failed,
389
+ totalLines: bounded.totalLines,
390
+ };
391
+ }
392
+ }
393
+ }
394
+ //# sourceMappingURL=presenter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presenter.js","sourceRoot":"","sources":["../../src/cards/presenter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import { type CardRow, type ToolCard } from '../cards.ts';
2
+ /**
3
+ * Output rows a folded card keeps on screen when a tool configures a tail.
4
+ *
5
+ * Shipped as the `tail` default for every tool, but drawn only when that tool
6
+ * asks for `output: tail`: the shipped `output: hidden` is what makes a folded
7
+ * card one line. The tail is the part that carries the outcome of a long run,
8
+ * and the retention cap still bounds what ctrl+o can reveal.
9
+ */
10
+ export declare const CARD_SHELL_PREVIEW = 20;
11
+ /**
12
+ * How much of a card the reader has asked for.
13
+ *
14
+ * The folded state names its own treatment because the reader's settings decide
15
+ * whether a folded card shows a tail of its rows or nothing beyond its header;
16
+ * the count travels with the choice so the view never re-reads the policy.
17
+ */
18
+ export type CardPreview = {
19
+ readonly expanded: true;
20
+ } | {
21
+ readonly expanded: false;
22
+ readonly preview: 'title';
23
+ } | {
24
+ readonly expanded: false;
25
+ readonly preview: 'tail';
26
+ readonly rows: number;
27
+ };
28
+ /**
29
+ * The rows a card shows right now, and how many the reader is not seeing.
30
+ *
31
+ * Expansion is a view decision rather than a card field so one key press can
32
+ * change every card at once without rebuilding the transcript.
33
+ */
34
+ export declare function cardDetailRows(card: ToolCard, preview: CardPreview): {
35
+ lines: readonly CardRow[];
36
+ hidden: number;
37
+ };
38
+ /** The hint row for a folded shell card, or undefined when its preview dropped nothing. */
39
+ export declare function shellFoldHint(hidden: number, showMoreKey: string): string | undefined;
40
+ /** The hint row for an opened shell card whose retention dropped the run's earlier rows. */
41
+ export declare function shellRetentionHint(hidden: number): string | undefined;
42
+ //# sourceMappingURL=preview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../src/cards/preview.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAmB,MAAM,aAAa,CAAA;AAG1E;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,KAAK,CAAA;AAqBpC;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GACnB;IAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAA;CAAE,GAC3B;IAAE,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GACvD;IAAE,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAEjF;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,GAAG;IAAE,KAAK,EAAE,SAAS,OAAO,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAOlH;AAED,2FAA2F;AAC3F,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAErF;AAED,4FAA4F;AAC5F,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAErE"}
@@ -0,0 +1,51 @@
1
+ import { CARD_DETAIL_MAX } from "../cards.js";
2
+ import { title } from "./presenter.js";
3
+ /**
4
+ * Output rows a folded card keeps on screen when a tool configures a tail.
5
+ *
6
+ * Shipped as the `tail` default for every tool, but drawn only when that tool
7
+ * asks for `output: tail`: the shipped `output: hidden` is what makes a folded
8
+ * card one line. The tail is the part that carries the outcome of a long run,
9
+ * and the retention cap still bounds what ctrl+o can reveal.
10
+ */
11
+ export const CARD_SHELL_PREVIEW = 20;
12
+ /**
13
+ * The tail of the hint a folded shell card draws when it dropped rows.
14
+ *
15
+ * "more" rather than "them": retention caps detail rows, so a command that
16
+ * printed thousands of lines cannot promise ctrl+o will reveal every dropped
17
+ * one.
18
+ */
19
+ /** The fold hint names the key that opens the card, which the reader owns. */
20
+ const cardHintEarlier = (showMoreKey) => `earlier lines · ${showMoreKey} shows more`;
21
+ /**
22
+ * The tail of the hint an opened shell card draws when retention dropped rows.
23
+ *
24
+ * Retention keeps the tail of a run, so the rows it refused are always the
25
+ * beginning; a hint that only counted them would send the reader looking past
26
+ * the end of the output for rows that are not there.
27
+ */
28
+ const CARD_HINT_UNRETAINED_EARLIER = 'earlier lines not shown';
29
+ /**
30
+ * The rows a card shows right now, and how many the reader is not seeing.
31
+ *
32
+ * Expansion is a view decision rather than a card field so one key press can
33
+ * change every card at once without rebuilding the transcript.
34
+ */
35
+ export function cardDetailRows(card, preview) {
36
+ const lines = preview.expanded
37
+ ? card.detail.slice(0, CARD_DETAIL_MAX)
38
+ : preview.preview === 'tail'
39
+ ? card.detail.slice(Math.max(0, card.detail.length - Math.max(0, preview.rows)))
40
+ : [];
41
+ return { lines, hidden: Math.max(0, card.totalLines - lines.length) };
42
+ }
43
+ /** The hint row for a folded shell card, or undefined when its preview dropped nothing. */
44
+ export function shellFoldHint(hidden, showMoreKey) {
45
+ return hidden <= 0 ? undefined : `… ${hidden} ${cardHintEarlier(showMoreKey)}`;
46
+ }
47
+ /** The hint row for an opened shell card whose retention dropped the run's earlier rows. */
48
+ export function shellRetentionHint(hidden) {
49
+ return hidden <= 0 ? undefined : `… ${hidden} ${CARD_HINT_UNRETAINED_EARLIER}`;
50
+ }
51
+ //# sourceMappingURL=preview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview.js","sourceRoot":"","sources":["../../src/cards/preview.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,eAAe,EAAE,MAAM,aAAa,CAAA;AAC1E,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAEtC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,CAAA;AAEpC;;;;;;GAMG;AACH,8EAA8E;AAC9E,MAAM,eAAe,GAAG,CAAC,WAAmB,EAAU,EAAE,CAAC,mBAAmB,WAAW,aAAa,CAAA;AAEpG;;;;;;GAMG;AACH,MAAM,4BAA4B,GAAG,yBAAyB,CAAA;AAc9D;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,IAAc,EAAE,OAAoB;IACjE,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ;QAC5B,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC;QACvC,CAAC,CAAC,OAAO,CAAC,OAAO,KAAK,MAAM;YAC1B,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YAChF,CAAC,CAAC,EAAE,CAAA;IACR,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,CAAA;AACvE,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,aAAa,CAAC,MAAc,EAAE,WAAmB;IAC/D,OAAO,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,MAAM,IAAI,eAAe,CAAC,WAAW,CAAC,EAAE,CAAA;AAChF,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,OAAO,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,MAAM,IAAI,4BAA4B,EAAE,CAAA;AAChF,CAAC"}