@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,222 @@
1
+ import { ProcessTerminal } from '@earendil-works/pi-tui';
2
+ import { createHerdrReporter } from "../herdr/reporter.js";
3
+ import { PROFILE_NAME, resumeHint } from "../identity.js";
4
+ import { clipboardSequence } from "../terminal/clipboard.js";
5
+ import { ExternalEditor } from "../terminal/external-editor.js";
6
+ import { createRestoreRegistry } from "../terminal/restore.js";
7
+ import { installSignalRestore } from "../terminal/signals.js";
8
+ import { CLEAR_TITLE, windowTitle } from "../terminal/title.js";
9
+ import { WarningSafeTui } from "../terminal/warning-screen.js";
10
+ import { cleanCopied } from "../ui/copy.js";
11
+ /**
12
+ * The terminal's lifetime: the screen this surface owns, the way out of it, and
13
+ * the child that borrows it.
14
+ *
15
+ * Ownership is the whole subject: the alternate screen, the hooks that put the
16
+ * shell back, and the exit are one mechanism, and a second writer would not
17
+ * know that the reader's own editor holds the tty. The composer keeps the
18
+ * widgets; this owner keeps every byte written to the terminal.
19
+ */
20
+ export function createTerminalLifecycle(ctx, ports) {
21
+ const restore = createRestoreRegistry();
22
+ const terminal = new ProcessTerminal();
23
+ const tui = new WarningSafeTui(terminal, { copySelection });
24
+ // A frame that cannot be drawn leaves the last good screen up, so the failure
25
+ // has to reach the transcript: otherwise the surface looks frozen and nothing
26
+ // on screen can say why.
27
+ tui.onFrameError = error => ports.reportFrameError(error);
28
+ /** Whether a child process owns the terminal, which is when nothing here may write to it. */
29
+ let handedOver = false;
30
+ /** Whether the host has unloaded this surface, after which nothing may start it again. */
31
+ let disposed = false;
32
+ /** An exit asked for while a child owned the terminal, run once the screen is ours again. */
33
+ let deferredExit;
34
+ /** Whether the exit has begun, which is when nothing may start another. */
35
+ let exited = false;
36
+ /**
37
+ * Write to the tty, but only while this surface owns it.
38
+ *
39
+ * An editor the reader opened draws its own screen on the same terminal, so a
40
+ * title or a bell from here would land on top of it and, for a bell, sound as
41
+ * if the editor had failed. The title is written again when the screen comes
42
+ * back; a bell that fell in the gap is dropped rather than rung late.
43
+ */
44
+ const writeTerminal = (text) => {
45
+ if (!handedOver)
46
+ terminal.write(text);
47
+ };
48
+ /**
49
+ * Put a copied selection on the clipboard as the words it selected.
50
+ *
51
+ * A terminal copies the screen, so a drag across a message takes the box the
52
+ * message was drawn in along with it. The rows the last frame drew are the
53
+ * account of that frame, so the copy is read back through them: the shape the
54
+ * surface added comes off, and nothing the reader wrote does.
55
+ */
56
+ function copySelection(text) {
57
+ if (handedOver)
58
+ return Promise.resolve(false);
59
+ terminal.write(clipboardSequence(cleanCopied(text, ports.copyRows())));
60
+ return Promise.resolve(true);
61
+ }
62
+ const disposers = [];
63
+ // A containing Herdr is told what this pane is doing; away from one the
64
+ // reporter is inert, so the surface never depends on being multiplexed.
65
+ const herdr = createHerdrReporter();
66
+ // Kept out of the disposal list on purpose: the row is handed back before
67
+ // this stops guarding it, so a host that leaves during the release still
68
+ // releases synchronously.
69
+ const unregisterExit = herdr.registerExitRelease();
70
+ restore.add(() => tui.stop());
71
+ ctx.effect(() => () => {
72
+ // A surface the host unloads owns no screen and keeps no listeners, so a
73
+ // child still running in another process must not be handed a start().
74
+ disposed = true;
75
+ // The pane stops being an agent before the process that claimed it unwinds:
76
+ // a release that ran after the reports were unregistered would race them,
77
+ // and one that never ran would leave a row that reads as a live agent. The
78
+ // reports already on the wire are settled first, because Herdr ignores a
79
+ // release for a pane nothing has claimed yet — the report that followed it
80
+ // would otherwise claim the row back. The promise is returned so a host that
81
+ // waits for teardown waits for the row too, and the exit listener outlives
82
+ // the wait, so one that does not still hands the row back synchronously.
83
+ const released = herdr.release().catch(() => undefined);
84
+ restore.restore();
85
+ for (const dispose of disposers.reverse())
86
+ dispose();
87
+ return released.finally(unregisterExit);
88
+ });
89
+ const requestExit = (code, reason) => {
90
+ if (exited)
91
+ return;
92
+ // A child owns the terminal: restoring it here would leave the reader a
93
+ // shell behind an editor that is still running, and would put its tty back
94
+ // into cooked mode under it. The exit waits for the screen to come back.
95
+ if (handedOver) {
96
+ deferredExit = { code, reason };
97
+ return;
98
+ }
99
+ exited = true;
100
+ ports.stopClock();
101
+ // The screen goes back at once, so leaving feels like leaving; the row goes
102
+ // back behind it. Reports already on the wire are settled first, because
103
+ // Herdr ignores the release of a pane nothing has claimed yet — the report
104
+ // that followed it would otherwise claim the row back during shutdown.
105
+ terminal.write(CLEAR_TITLE);
106
+ restore.restore();
107
+ void herdr
108
+ .release()
109
+ // Nobody is left to report a release that failed on the way out, and a
110
+ // row that could not be cleared is not a reason to keep the process.
111
+ .catch(() => undefined)
112
+ .finally(() => {
113
+ // Everything below is written after the release: a failure nobody can
114
+ // read is not a failure that was reported.
115
+ if (reason !== undefined)
116
+ terminal.write(`\ndsh-tui: ${reason}\n`);
117
+ // The hint is computed here rather than read from the context because
118
+ // only the surface knows which session it is leaving: a fork or a
119
+ // switch moves it. A run that opened nothing has nothing to offer back:
120
+ // the identity it was launched with names no log, so pointing at it
121
+ // would send the reader to a conversation that does not exist.
122
+ if (ports.sessionOpened())
123
+ terminal.write(`\n${resumeHint(String(ports.activeSession()), PROFILE_NAME)}\n`);
124
+ ports.exit(code);
125
+ });
126
+ };
127
+ /**
128
+ * Take the signals a supervisor sends into the same shutdown a quit key runs.
129
+ *
130
+ * A signal ends the process from outside the surface, and the default action
131
+ * would leave the reader on a screen no shell prompt is drawn in. Returned
132
+ * rather than pushed here: the composer owns the one ordered teardown list, so
133
+ * this registration keeps the position that list already gave it.
134
+ */
135
+ const signalShutdown = () => installSignalRestore({ shutdown: code => requestExit(code, 'interrupted') });
136
+ /**
137
+ * The reader's own editor, opened over the draft the bar holds.
138
+ *
139
+ * The screen is handed over rather than drawn beside: an editor needs the
140
+ * terminal, so this is the one moment the surface is not the process painting
141
+ * on it. Every failure is reported as a notice and leaves the bar as it was,
142
+ * because the caller is a key press with nowhere to put an error.
143
+ */
144
+ const externalEditor = new ExternalEditor({
145
+ suspend: () => {
146
+ handedOver = true;
147
+ try {
148
+ // The frame is left in place rather than repainted into the normal
149
+ // buffer: the editor is about to paint over that same screen.
150
+ tui.stop({ preserveScreen: true });
151
+ }
152
+ catch (error) {
153
+ // A stop that failed leaves the screen ours; leaving the flag up would
154
+ // suppress every later title and defer every exit for good.
155
+ handedOver = false;
156
+ throw error;
157
+ }
158
+ },
159
+ resume: () => {
160
+ // Whatever the host unloaded is not coming back: starting it again would
161
+ // paint on a terminal this process is done with, into listeners that are gone.
162
+ if (disposed)
163
+ return;
164
+ try {
165
+ tui.start();
166
+ }
167
+ finally {
168
+ handedOver = false;
169
+ }
170
+ // Entering the alternate screen clears it, and any render asked for while
171
+ // the child owned the terminal was dropped after setting the very flag that
172
+ // makes the next ordinary request a no-op: without a forced one the reader
173
+ // would get a blank screen with a working keyboard under it.
174
+ tui.requestRender(true);
175
+ // The title is state this surface owns and the handoff swallowed any change
176
+ // to it, so a turn that ended while the editor was open would leave
177
+ // "working" up until the next turn.
178
+ writeTerminal(windowTitle(process.cwd(), ports.turnRunning() ? 'working' : 'ready'));
179
+ },
180
+ notice: message => ports.notice(message),
181
+ });
182
+ /**
183
+ * Hand the draft to the reader's editor and take back whatever it saved.
184
+ *
185
+ * An exit that was asked for during the handoff runs here rather than in the
186
+ * key that asked: the child owned the screen then, and the screen is this
187
+ * surface's again only once the editor has returned.
188
+ *
189
+ * A gate can open while the child owns the screen, and the bar then holds
190
+ * somebody's answer: the edited draft waits behind it instead of being written
191
+ * into a question the reader never answered.
192
+ */
193
+ const editDraft = () => {
194
+ void externalEditor.edit(ports.draftText()).then(text => {
195
+ if (text !== undefined) {
196
+ if (ports.draftBorrowed())
197
+ ports.holdDraft(text);
198
+ else
199
+ ports.writeDraft(text);
200
+ tui.requestRender();
201
+ }
202
+ const pendingExit = deferredExit;
203
+ deferredExit = undefined;
204
+ if (pendingExit !== undefined)
205
+ requestExit(pendingExit.code, pendingExit.reason);
206
+ });
207
+ };
208
+ return {
209
+ terminal,
210
+ tui,
211
+ herdr,
212
+ disposers,
213
+ writeTerminal,
214
+ handedOver: () => handedOver,
215
+ disposed: () => disposed,
216
+ exited: () => exited,
217
+ requestExit,
218
+ editDraft,
219
+ signalShutdown,
220
+ };
221
+ }
222
+ //# sourceMappingURL=terminal-lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-lifecycle.js","sourceRoot":"","sources":["../../src/surface/terminal-lifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * The escape grammar the surface recognises, and the visible spelling of the
3
+ * controls it must not execute.
4
+ *
5
+ * Kept apart from the renderer because recognition is the trust boundary: what
6
+ * this module accepts is what every drawing path is handed, and its rules
7
+ * follow the terminal's grammar rather than a row's layout.
8
+ */
9
+ export declare const ESC = "\u001B";
10
+ /** The bytes a text fragment cannot be drawn with: they are either sequences to read or marks to spell. */
11
+ export declare const NEEDS_READING: RegExp;
12
+ export declare const RESET = 0;
13
+ export type Token = {
14
+ readonly kind: 'text';
15
+ } | {
16
+ readonly kind: 'lineFeed';
17
+ } | {
18
+ readonly kind: 'tab';
19
+ } | {
20
+ readonly kind: 'carriageReturn';
21
+ } | {
22
+ readonly kind: 'backspace';
23
+ } | {
24
+ readonly kind: 'sgr';
25
+ readonly params: readonly number[];
26
+ } | {
27
+ readonly kind: 'consumed';
28
+ } | {
29
+ readonly kind: 'control';
30
+ } | {
31
+ readonly kind: 'incomplete';
32
+ };
33
+ /** One recognised piece of the input, with the source text it was read from. */
34
+ export interface Piece {
35
+ readonly token: Token;
36
+ readonly raw: string;
37
+ }
38
+ /** Every character of a sequence that is a control, spelled; the rest of it is printable. */
39
+ export declare function spellControls(raw: string): string;
40
+ /** The parameters of an SGR sequence, or nothing when it uses a form this module does not model. */
41
+ export declare function parseSgrParams(body: string): readonly number[] | undefined;
42
+ /** Split a text fragment into the pieces a policy draws or spells. */
43
+ export declare function scan(raw: string): Piece[];
44
+ //# sourceMappingURL=scan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/terminal-text/scan.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,eAAO,MAAM,GAAG,WAAW,CAAA;AAgC3B,2GAA2G;AAC3G,eAAO,MAAM,aAAa,QAAoH,CAAA;AAoC9I,eAAO,MAAM,KAAK,IAAI,CAAA;AAEtB,MAAM,MAAM,KAAK,GACb;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GAC7B;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAA;CAAE,GACxB;IAAE,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAA;CAAE,GACnC;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;CAAE,GAC9B;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAC5D;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GAC7B;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GAC5B;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;CAAE,CAAA;AAEnC,gFAAgF;AAChF,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB;AAkBD,6FAA6F;AAC7F,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAOjD;AAuDD,oGAAoG;AACpG,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS,CAQ1E;AAED,sEAAsE;AACtE,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,EAAE,CA8CzC"}
@@ -0,0 +1,195 @@
1
+ /**
2
+ * The escape grammar the surface recognises, and the visible spelling of the
3
+ * controls it must not execute.
4
+ *
5
+ * Kept apart from the renderer because recognition is the trust boundary: what
6
+ * this module accepts is what every drawing path is handed, and its rules
7
+ * follow the terminal's grammar rather than a row's layout.
8
+ */
9
+ export const ESC = '\u001b';
10
+ const REPLACEMENT = '\uFFFD';
11
+ const C0_PREFIX = '\\x';
12
+ const UNICODE_PREFIX = '\\u';
13
+ const HEX2 = 2;
14
+ const HEX4 = 4;
15
+ const LAST_C0 = 0x1f;
16
+ const TAB = 0x09;
17
+ const LINE_FEED = 0x0a;
18
+ const CARRIAGE_RETURN = 0x0d;
19
+ const BACKSPACE = 0x08;
20
+ const DELETE = 0x7f;
21
+ const FIRST_C1 = 0x80;
22
+ const LAST_C1 = 0x9f;
23
+ const FIRST_SURROGATE = 0xd800;
24
+ const LAST_SURROGATE = 0xdfff;
25
+ /** The bytes a text fragment cannot be drawn with: they are either sequences to read or marks to spell. */
26
+ export const NEEDS_READING = /[\u0000-\u0009\u000B-\u001F\u007F-\u009F\u061C\u200E\u200F\u2028\u2029\u202A-\u202E\u2066-\u2069\uD800-\uDFFF]/u;
27
+ /** Directional overrides and isolates, which reorder a row without drawing anything. */
28
+ const BIDI_CONTROLS = new Set([0x202a, 0x202b, 0x202c, 0x202d, 0x202e, 0x2066, 0x2067, 0x2068, 0x2069]);
29
+ const LINE_SEPARATOR = 0x2028;
30
+ const PARAGRAPH_SEPARATOR = 0x2029;
31
+ const ARABIC_LETTER_MARK = 0x061c;
32
+ const LEFT_TO_RIGHT_MARK = 0x200e;
33
+ const RIGHT_TO_LEFT_MARK = 0x200f;
34
+ /** The SGR final byte, and the parameter bytes a sequence may carry before it. */
35
+ const SGR_FINAL = 'm';
36
+ const CSI_PARAMETER_LAST = 0x3f;
37
+ const CSI_INTERMEDIATE_FIRST = 0x20;
38
+ const CSI_INTERMEDIATE_LAST = 0x2f;
39
+ const CSI_FINAL_FIRST = 0x40;
40
+ const CSI_FINAL_LAST = 0x7e;
41
+ const ESCAPE_FINAL_FIRST = 0x30;
42
+ const OSC_INTRODUCER = ']';
43
+ const STRING_INTRODUCERS = new Set(['P', 'X', '^', '_']);
44
+ const STRING_END = '\u0007';
45
+ export const RESET = 0;
46
+ function escapeCode(prefix, code, digits) {
47
+ return prefix + code.toString(16).toUpperCase().padStart(digits, '0');
48
+ }
49
+ /** Whether a code point is a mark this module spells instead of drawing. */
50
+ function isSpelledControl(code) {
51
+ if (code <= LAST_C0 || code === DELETE)
52
+ return true;
53
+ if (code >= FIRST_C1 && code <= LAST_C1)
54
+ return true;
55
+ return BIDI_CONTROLS.has(code) || code === LINE_SEPARATOR || code === PARAGRAPH_SEPARATOR || code === ARABIC_LETTER_MARK || code === LEFT_TO_RIGHT_MARK || code === RIGHT_TO_LEFT_MARK;
56
+ }
57
+ function spelled(code) {
58
+ if (code <= 0xff)
59
+ return escapeCode(C0_PREFIX, code, HEX2);
60
+ return escapeCode(UNICODE_PREFIX, code, HEX4);
61
+ }
62
+ /** Every character of a sequence that is a control, spelled; the rest of it is printable. */
63
+ export function spellControls(raw) {
64
+ let out = '';
65
+ for (const character of raw) {
66
+ const code = character.codePointAt(0) ?? 0;
67
+ out += isSpelledControl(code) ? spelled(code) : character;
68
+ }
69
+ return out;
70
+ }
71
+ function isCsiFinal(code) {
72
+ return code >= CSI_FINAL_FIRST && code <= CSI_FINAL_LAST;
73
+ }
74
+ /**
75
+ * Read one escape sequence at `at`.
76
+ *
77
+ * A string sequence (OSC, DCS, and their siblings) runs to BEL or ST; when its
78
+ * terminator never arrives the sequence is reported incomplete rather than
79
+ * swallowed to the end of the row, because the renderer and the editor want
80
+ * different answers for a truncated sequence and only the scanner knows where
81
+ * it stopped.
82
+ */
83
+ function readEscape(raw, at) {
84
+ const introducer = raw[at + 1];
85
+ if (introducer === undefined)
86
+ return undefined;
87
+ if (introducer === '[') {
88
+ let end = at + 2;
89
+ while (end < raw.length) {
90
+ const code = raw.charCodeAt(end);
91
+ if (isCsiFinal(code)) {
92
+ const source = raw.slice(at, end + 1);
93
+ if (raw[end] === SGR_FINAL) {
94
+ const params = parseSgrParams(source.slice(2, -1));
95
+ if (params !== undefined)
96
+ return { token: { kind: 'sgr', params }, raw: source };
97
+ }
98
+ return { token: { kind: 'consumed' }, raw: source };
99
+ }
100
+ if (code > CSI_PARAMETER_LAST && (code < CSI_INTERMEDIATE_FIRST || code > CSI_INTERMEDIATE_LAST)) {
101
+ // A byte outside the CSI grammar ends the sequence as malformed; the
102
+ // sequence is consumed so its bytes cannot be drawn as text.
103
+ return { token: { kind: 'consumed' }, raw: raw.slice(at, end) };
104
+ }
105
+ end += 1;
106
+ }
107
+ return { token: { kind: 'incomplete' }, raw: raw.slice(at) };
108
+ }
109
+ if (introducer === OSC_INTRODUCER || STRING_INTRODUCERS.has(introducer)) {
110
+ let end = at + 2;
111
+ while (end < raw.length) {
112
+ if (raw[end] === STRING_END)
113
+ return { token: { kind: 'consumed' }, raw: raw.slice(at, end + 1) };
114
+ if (raw[end] === ESC && raw[end + 1] === '\\')
115
+ return { token: { kind: 'consumed' }, raw: raw.slice(at, end + 2) };
116
+ end += 1;
117
+ }
118
+ return { token: { kind: 'incomplete' }, raw: raw.slice(at) };
119
+ }
120
+ const code = raw.charCodeAt(at + 1);
121
+ if (code >= ESCAPE_FINAL_FIRST && code <= CSI_FINAL_LAST) {
122
+ return { token: { kind: 'consumed' }, raw: raw.slice(at, at + 2) };
123
+ }
124
+ return undefined;
125
+ }
126
+ /** The parameters of an SGR sequence, or nothing when it uses a form this module does not model. */
127
+ export function parseSgrParams(body) {
128
+ if (body === '')
129
+ return [RESET];
130
+ const params = [];
131
+ for (const part of body.split(';')) {
132
+ if (!/^[0-9]*$/.test(part))
133
+ return undefined;
134
+ params.push(part === '' ? RESET : Number(part));
135
+ }
136
+ return params;
137
+ }
138
+ /** Split a text fragment into the pieces a policy draws or spells. */
139
+ export function scan(raw) {
140
+ const pieces = [];
141
+ let text = '';
142
+ const flush = () => {
143
+ if (text === '')
144
+ return;
145
+ pieces.push({ token: { kind: 'text' }, raw: text });
146
+ text = '';
147
+ };
148
+ let at = 0;
149
+ while (at < raw.length) {
150
+ const code = raw.codePointAt(at) ?? 0;
151
+ const character = String.fromCodePoint(code);
152
+ if (code === LINE_FEED) {
153
+ flush();
154
+ pieces.push({ token: { kind: 'lineFeed' }, raw: character });
155
+ }
156
+ else if (code === TAB) {
157
+ flush();
158
+ pieces.push({ token: { kind: 'tab' }, raw: character });
159
+ }
160
+ else if (code === CARRIAGE_RETURN) {
161
+ flush();
162
+ pieces.push({ token: { kind: 'carriageReturn' }, raw: character });
163
+ }
164
+ else if (code === BACKSPACE) {
165
+ flush();
166
+ pieces.push({ token: { kind: 'backspace' }, raw: character });
167
+ }
168
+ else if (code === 0x1b) {
169
+ flush();
170
+ const sequence = readEscape(raw, at);
171
+ if (sequence === undefined) {
172
+ pieces.push({ token: { kind: 'control' }, raw: character });
173
+ }
174
+ else {
175
+ pieces.push(sequence);
176
+ at += sequence.raw.length;
177
+ continue;
178
+ }
179
+ }
180
+ else if (code >= FIRST_SURROGATE && code <= LAST_SURROGATE) {
181
+ text += REPLACEMENT;
182
+ }
183
+ else if (isSpelledControl(code)) {
184
+ flush();
185
+ pieces.push({ token: { kind: 'control' }, raw: character });
186
+ }
187
+ else {
188
+ text += character;
189
+ }
190
+ at += character.length;
191
+ }
192
+ flush();
193
+ return pieces;
194
+ }
195
+ //# sourceMappingURL=scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/terminal-text/scan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * The style state a renderer models: which attributes are on, which colour each
3
+ * names, and the sequences that move one state to the next.
4
+ *
5
+ * Apart from the grammar that reads those sequences and the renderer that emits
6
+ * rows, because which attributes and colours a terminal may set is a policy
7
+ * this surface owns, not a property of either.
8
+ */
9
+ import { type ColourMode } from '../theme-capability.ts';
10
+ export declare const CSI = "\u001B[";
11
+ export interface TextStyle {
12
+ readonly fg?: string | undefined;
13
+ readonly bg?: string | undefined;
14
+ /** Attribute bits, so two styles compare by value without walking a set. */
15
+ readonly attributes: number;
16
+ }
17
+ export declare const GROUND: TextStyle;
18
+ export interface Encoder {
19
+ /** The codes that move from one style to the next. */
20
+ between(previous: TextStyle, next: TextStyle): string;
21
+ }
22
+ /**
23
+ * Build the encoder for one colour budget.
24
+ *
25
+ * The element's own colour is the ground state rather than a reset, because a
26
+ * tool that ends a coloured run must not clear the colour the card drew it in;
27
+ * a full reset is never emitted, so nothing outside the run is disturbed.
28
+ */
29
+ export declare function encoder(color: ColourMode, base: string): Encoder;
30
+ /** Apply an SGR sequence to the state a cell is written with. */
31
+ export declare function applySgr(style: TextStyle, params: readonly number[], color: ColourMode): TextStyle;
32
+ //# sourceMappingURL=sgr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sgr.d.ts","sourceRoot":"","sources":["../../src/terminal-text/sgr.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAkC,KAAK,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAGxF,eAAO,MAAM,GAAG,YAAY,CAAA;AA8E5B,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,4EAA4E;IAC5E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AAED,eAAO,MAAM,MAAM,EAAE,SAA6B,CAAA;AAalD,MAAM,WAAW,OAAO;IACtB,sDAAsD;IACtD,OAAO,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,CAAA;CACtD;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAwBhE;AAsBD,iEAAiE;AACjE,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,UAAU,GAAG,SAAS,CA+ClG"}