@sagmans/dsh-tui 0.4.0 → 0.5.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.
Files changed (200) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +270 -68
  3. package/lib/agent/present.js +1 -1
  4. package/lib/agent/present.js.map +1 -1
  5. package/lib/agent/prompt-history.d.ts.map +1 -1
  6. package/lib/agent/prompt-history.js +5 -3
  7. package/lib/agent/prompt-history.js.map +1 -1
  8. package/lib/agent/status.d.ts +1 -1
  9. package/lib/cards.d.ts +83 -13
  10. package/lib/cards.d.ts.map +1 -1
  11. package/lib/cards.js +96 -28
  12. package/lib/cards.js.map +1 -1
  13. package/lib/export.d.ts +3 -3
  14. package/lib/export.d.ts.map +1 -1
  15. package/lib/export.js +23 -13
  16. package/lib/export.js.map +1 -1
  17. package/lib/fold-cursor.d.ts +12 -5
  18. package/lib/fold-cursor.d.ts.map +1 -1
  19. package/lib/fold-cursor.js +16 -5
  20. package/lib/fold-cursor.js.map +1 -1
  21. package/lib/gates.d.ts.map +1 -1
  22. package/lib/gates.js +42 -9
  23. package/lib/gates.js.map +1 -1
  24. package/lib/index.d.ts.map +1 -1
  25. package/lib/index.js +459 -72
  26. package/lib/index.js.map +1 -1
  27. package/lib/injection.d.ts +9 -0
  28. package/lib/injection.d.ts.map +1 -0
  29. package/lib/injection.js +128 -0
  30. package/lib/injection.js.map +1 -0
  31. package/lib/input/actions.d.ts +19 -2
  32. package/lib/input/actions.d.ts.map +1 -1
  33. package/lib/input/actions.js +57 -11
  34. package/lib/input/actions.js.map +1 -1
  35. package/lib/input/cancel.d.ts +55 -0
  36. package/lib/input/cancel.d.ts.map +1 -0
  37. package/lib/input/cancel.js +47 -0
  38. package/lib/input/cancel.js.map +1 -0
  39. package/lib/input/completion.d.ts +5 -2
  40. package/lib/input/completion.d.ts.map +1 -1
  41. package/lib/input/completion.js +79 -4
  42. package/lib/input/completion.js.map +1 -1
  43. package/lib/input/file-search.d.ts +105 -0
  44. package/lib/input/file-search.d.ts.map +1 -0
  45. package/lib/input/file-search.js +665 -0
  46. package/lib/input/file-search.js.map +1 -0
  47. package/lib/input/fuzzy.d.ts +42 -0
  48. package/lib/input/fuzzy.d.ts.map +1 -0
  49. package/lib/input/fuzzy.js +289 -0
  50. package/lib/input/fuzzy.js.map +1 -0
  51. package/lib/input/keymap.d.ts +3 -1
  52. package/lib/input/keymap.d.ts.map +1 -1
  53. package/lib/input/keymap.js +14 -3
  54. package/lib/input/keymap.js.map +1 -1
  55. package/lib/input/match.d.ts +12 -4
  56. package/lib/input/match.d.ts.map +1 -1
  57. package/lib/input/match.js +50 -51
  58. package/lib/input/match.js.map +1 -1
  59. package/lib/input/submission.d.ts +10 -0
  60. package/lib/input/submission.d.ts.map +1 -1
  61. package/lib/input/submission.js +7 -6
  62. package/lib/input/submission.js.map +1 -1
  63. package/lib/keys-command.d.ts +19 -3
  64. package/lib/keys-command.d.ts.map +1 -1
  65. package/lib/keys-command.js +34 -31
  66. package/lib/keys-command.js.map +1 -1
  67. package/lib/settings-notice.d.ts +5 -0
  68. package/lib/settings-notice.d.ts.map +1 -1
  69. package/lib/settings-notice.js +9 -7
  70. package/lib/settings-notice.js.map +1 -1
  71. package/lib/stash/paths.d.ts +8 -8
  72. package/lib/stash/paths.d.ts.map +1 -1
  73. package/lib/stash/paths.js +19 -18
  74. package/lib/stash/paths.js.map +1 -1
  75. package/lib/stash/schema.d.ts +11 -12
  76. package/lib/stash/schema.d.ts.map +1 -1
  77. package/lib/stash/schema.js +10 -29
  78. package/lib/stash/schema.js.map +1 -1
  79. package/lib/stash/store.js +10 -10
  80. package/lib/stash/store.js.map +1 -1
  81. package/lib/stash.d.ts +37 -6
  82. package/lib/stash.d.ts.map +1 -1
  83. package/lib/stash.js +93 -36
  84. package/lib/stash.js.map +1 -1
  85. package/lib/terminal/external-editor.d.ts +93 -0
  86. package/lib/terminal/external-editor.d.ts.map +1 -0
  87. package/lib/terminal/external-editor.js +263 -0
  88. package/lib/terminal/external-editor.js.map +1 -0
  89. package/lib/terminal/host-writes.d.ts +39 -0
  90. package/lib/terminal/host-writes.d.ts.map +1 -0
  91. package/lib/terminal/host-writes.js +136 -0
  92. package/lib/terminal/host-writes.js.map +1 -0
  93. package/lib/terminal/signals.d.ts +25 -0
  94. package/lib/terminal/signals.d.ts.map +1 -0
  95. package/lib/terminal/signals.js +39 -0
  96. package/lib/terminal/signals.js.map +1 -0
  97. package/lib/terminal/warning-screen.d.ts +19 -1
  98. package/lib/terminal/warning-screen.d.ts.map +1 -1
  99. package/lib/terminal/warning-screen.js +37 -1
  100. package/lib/terminal/warning-screen.js.map +1 -1
  101. package/lib/terminal-text.d.ts +72 -0
  102. package/lib/terminal-text.d.ts.map +1 -0
  103. package/lib/terminal-text.js +603 -0
  104. package/lib/terminal-text.js.map +1 -0
  105. package/lib/text.d.ts +45 -6
  106. package/lib/text.d.ts.map +1 -1
  107. package/lib/text.js +106 -46
  108. package/lib/text.js.map +1 -1
  109. package/lib/theme-command.d.ts +7 -4
  110. package/lib/theme-command.d.ts.map +1 -1
  111. package/lib/theme-command.js +32 -12
  112. package/lib/theme-command.js.map +1 -1
  113. package/lib/theme-files.d.ts +110 -0
  114. package/lib/theme-files.d.ts.map +1 -0
  115. package/lib/theme-files.js +352 -0
  116. package/lib/theme-files.js.map +1 -0
  117. package/lib/theme-schema.d.ts +121 -0
  118. package/lib/theme-schema.d.ts.map +1 -0
  119. package/lib/theme-schema.js +87 -0
  120. package/lib/theme-schema.js.map +1 -0
  121. package/lib/theme-settings.d.ts +43 -10
  122. package/lib/theme-settings.d.ts.map +1 -1
  123. package/lib/theme-settings.js +103 -43
  124. package/lib/theme-settings.js.map +1 -1
  125. package/lib/theme-tokens.d.ts +39 -7
  126. package/lib/theme-tokens.d.ts.map +1 -1
  127. package/lib/theme-tokens.js +96 -13
  128. package/lib/theme-tokens.js.map +1 -1
  129. package/lib/theme.d.ts +24 -2
  130. package/lib/theme.d.ts.map +1 -1
  131. package/lib/theme.js +49 -6
  132. package/lib/theme.js.map +1 -1
  133. package/lib/tool-display.d.ts +57 -0
  134. package/lib/tool-display.d.ts.map +1 -0
  135. package/lib/tool-display.js +51 -0
  136. package/lib/tool-display.js.map +1 -0
  137. package/lib/transcript.d.ts +28 -0
  138. package/lib/transcript.d.ts.map +1 -1
  139. package/lib/transcript.js +126 -37
  140. package/lib/transcript.js.map +1 -1
  141. package/lib/ui/diff.d.ts +49 -0
  142. package/lib/ui/diff.d.ts.map +1 -0
  143. package/lib/ui/diff.js +208 -0
  144. package/lib/ui/diff.js.map +1 -0
  145. package/lib/ui/dock.d.ts.map +1 -1
  146. package/lib/ui/dock.js +9 -6
  147. package/lib/ui/dock.js.map +1 -1
  148. package/lib/ui/editor.d.ts.map +1 -1
  149. package/lib/ui/editor.js +4 -2
  150. package/lib/ui/editor.js.map +1 -1
  151. package/lib/ui/frame.d.ts +16 -5
  152. package/lib/ui/frame.d.ts.map +1 -1
  153. package/lib/ui/frame.js +32 -13
  154. package/lib/ui/frame.js.map +1 -1
  155. package/lib/ui/keymap-picker.d.ts +16 -0
  156. package/lib/ui/keymap-picker.d.ts.map +1 -0
  157. package/lib/ui/keymap-picker.js +41 -0
  158. package/lib/ui/keymap-picker.js.map +1 -0
  159. package/lib/ui/layout.d.ts +33 -0
  160. package/lib/ui/layout.d.ts.map +1 -0
  161. package/lib/ui/layout.js +33 -0
  162. package/lib/ui/layout.js.map +1 -0
  163. package/lib/ui/markdown.d.ts +25 -3
  164. package/lib/ui/markdown.d.ts.map +1 -1
  165. package/lib/ui/markdown.js +12 -8
  166. package/lib/ui/markdown.js.map +1 -1
  167. package/lib/ui/picker-card.d.ts +42 -0
  168. package/lib/ui/picker-card.d.ts.map +1 -0
  169. package/lib/ui/picker-card.js +148 -0
  170. package/lib/ui/picker-card.js.map +1 -0
  171. package/lib/ui/picker.d.ts +40 -2
  172. package/lib/ui/picker.d.ts.map +1 -1
  173. package/lib/ui/picker.js +50 -6
  174. package/lib/ui/picker.js.map +1 -1
  175. package/lib/ui/prompt.d.ts +10 -2
  176. package/lib/ui/prompt.d.ts.map +1 -1
  177. package/lib/ui/prompt.js +21 -2
  178. package/lib/ui/prompt.js.map +1 -1
  179. package/lib/ui/rows.d.ts +8 -6
  180. package/lib/ui/rows.d.ts.map +1 -1
  181. package/lib/ui/rows.js +10 -18
  182. package/lib/ui/rows.js.map +1 -1
  183. package/lib/ui/stash-picker.d.ts +2 -2
  184. package/lib/ui/stash-picker.d.ts.map +1 -1
  185. package/lib/ui/stash-picker.js +4 -4
  186. package/lib/ui/stash-picker.js.map +1 -1
  187. package/lib/ui/status.d.ts.map +1 -1
  188. package/lib/ui/status.js +18 -16
  189. package/lib/ui/status.js.map +1 -1
  190. package/lib/ui/theme-picker.d.ts +18 -0
  191. package/lib/ui/theme-picker.d.ts.map +1 -0
  192. package/lib/ui/theme-picker.js +68 -0
  193. package/lib/ui/theme-picker.js.map +1 -0
  194. package/lib/ui/view.d.ts +146 -22
  195. package/lib/ui/view.d.ts.map +1 -1
  196. package/lib/ui/view.js +461 -154
  197. package/lib/ui/view.js.map +1 -1
  198. package/package.json +45 -11
  199. package/themes/deepseek-blue.yaml +183 -0
  200. package/themes/violet-orbit.yaml +178 -0
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Restore the terminal when the process is asked to end from outside.
3
+ *
4
+ * The surface owns the alternate screen and nothing else puts it back: a SIGTERM
5
+ * from a supervisor, a SIGHUP when a window closes, or a SIGQUIT all end a
6
+ * process by default, leaving the reader on a screen no shell prompt is drawn
7
+ * in. These handlers run the same shutdown a quit key runs, then leave with the
8
+ * status a shell reports for the signal.
9
+ */
10
+ /** Signals whose default action ends the process without unwinding the surface. */
11
+ export const TERMINATING_SIGNALS = ['SIGINT', 'SIGTERM', 'SIGHUP', 'SIGQUIT'];
12
+ /** The status a shell reports for a process ended by one of those signals. */
13
+ const SIGNAL_EXIT = { SIGINT: 130, SIGTERM: 143, SIGHUP: 129, SIGQUIT: 131 };
14
+ /**
15
+ * Run a shutdown once for the first terminating signal, then leave.
16
+ *
17
+ * The listener removes itself before the shutdown runs, so a slow shutdown
18
+ * cannot be re-entered by a second signal; the status is the one a shell expects
19
+ * for the signal, so whatever was supervising the process sees an interrupted
20
+ * run rather than a clean one.
21
+ */
22
+ export function installSignalRestore(options) {
23
+ const handlers = new Map();
24
+ const remove = () => {
25
+ for (const [signal, handler] of handlers)
26
+ process.removeListener(signal, handler);
27
+ handlers.clear();
28
+ };
29
+ for (const signal of options.signals ?? TERMINATING_SIGNALS) {
30
+ const handler = () => {
31
+ remove();
32
+ options.shutdown(SIGNAL_EXIT[signal], signal);
33
+ };
34
+ process.on(signal, handler);
35
+ handlers.set(signal, handler);
36
+ }
37
+ return remove;
38
+ }
39
+ //# sourceMappingURL=signals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signals.js","sourceRoot":"","sources":["../../src/terminal/signals.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,mFAAmF;AACnF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,CAAU,CAAA;AAItF,8EAA8E;AAC9E,MAAM,WAAW,GAAsC,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,CAAA;AAE/G;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAGpC;IACC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAiC,CAAA;IACzD,MAAM,MAAM,GAAG,GAAS,EAAE;QACxB,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,QAAQ;YAAE,OAAO,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QACjF,QAAQ,CAAC,KAAK,EAAE,CAAA;IAClB,CAAC,CAAA;IACD,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,OAAO,IAAI,mBAAmB,EAAE,CAAC;QAC5D,MAAM,OAAO,GAAG,GAAS,EAAE;YACzB,MAAM,EAAE,CAAA;YACR,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAA;QAC/C,CAAC,CAAA;QACD,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAC3B,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -1,8 +1,26 @@
1
1
  import { TuiAltScreen, type TuiStopOptions } from '@earendil-works/pi-tui';
2
- /** Warning ownership follows screen ownership, including partial startup and repeated disposal. */
2
+ /**
3
+ * Terminal safety follows screen ownership, including partial startup and
4
+ * repeated disposal: warnings wait for the shell, the host's own writing waits
5
+ * with them, and a frame that cannot be drawn keeps the last good screen.
6
+ */
3
7
  export declare class WarningSafeTui extends TuiAltScreen {
4
8
  private releaseWarnings;
9
+ private hostWrites;
10
+ private frameFailed;
11
+ /** Told once when a frame could not be drawn, so the surface can report it. */
12
+ onFrameError: ((error: unknown) => void) | undefined;
5
13
  start(): void;
14
+ /**
15
+ * Draw a frame, keeping the last good one when drawing fails.
16
+ *
17
+ * A frame is composed before it is written, so a component that throws leaves
18
+ * the previous screen intact; without this the throw would reach the timer that
19
+ * asked for the frame, end the process, and take the terminal down with it.
20
+ * The first failure is reported and later ones stay silent: a repaint a broken
21
+ * component fails again is the same news, and repeating it would only loop.
22
+ */
23
+ doRender(): void;
6
24
  stop(options?: TuiStopOptions): void;
7
25
  }
8
26
  //# sourceMappingURL=warning-screen.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"warning-screen.d.ts","sourceRoot":"","sources":["../../src/terminal/warning-screen.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAmC1E,mGAAmG;AACnG,qBAAa,cAAe,SAAQ,YAAY;IAC9C,OAAO,CAAC,eAAe,CAA0B;IAExC,KAAK,IAAI,IAAI;IAUb,IAAI,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,IAAI;CAa9C"}
1
+ {"version":3,"file":"warning-screen.d.ts","sourceRoot":"","sources":["../../src/terminal/warning-screen.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAoC1E;;;;GAIG;AACH,qBAAa,cAAe,SAAQ,YAAY;IAC9C,OAAO,CAAC,eAAe,CAA0B;IACjD,OAAO,CAAC,UAAU,CAA4B;IAC9C,OAAO,CAAC,WAAW,CAAQ;IAE3B,+EAA+E;IAC/E,YAAY,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IAE3C,KAAK,IAAI,IAAI;IAWtB;;;;;;;;OAQG;IACM,QAAQ,IAAI,IAAI;IAUhB,IAAI,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,IAAI;CAmB9C"}
@@ -1,4 +1,5 @@
1
1
  import { TuiAltScreen } from '@earendil-works/pi-tui';
2
+ import { holdHostWrites, HOST_WRITE_TARGETS } from "./host-writes.js";
2
3
  const WARNING_EVENT = 'warning';
3
4
  const RESTORE_SHELL = '\x1b[?1049l\x1b[0m\x1b[?7h\x1b[?25h';
4
5
  /** Node's default warning listener writes outside the renderer, so delivery must wait for the shell. */
@@ -34,11 +35,20 @@ function deferWarnings() {
34
35
  throw failures[0];
35
36
  };
36
37
  }
37
- /** Warning ownership follows screen ownership, including partial startup and repeated disposal. */
38
+ /**
39
+ * Terminal safety follows screen ownership, including partial startup and
40
+ * repeated disposal: warnings wait for the shell, the host's own writing waits
41
+ * with them, and a frame that cannot be drawn keeps the last good screen.
42
+ */
38
43
  export class WarningSafeTui extends TuiAltScreen {
39
44
  releaseWarnings;
45
+ hostWrites;
46
+ frameFailed = false;
47
+ /** Told once when a frame could not be drawn, so the surface can report it. */
48
+ onFrameError;
40
49
  start() {
41
50
  this.releaseWarnings ??= deferWarnings();
51
+ this.hostWrites ??= holdHostWrites({ terminal: this.terminal, targets: HOST_WRITE_TARGETS });
42
52
  try {
43
53
  super.start();
44
54
  }
@@ -47,6 +57,26 @@ export class WarningSafeTui extends TuiAltScreen {
47
57
  throw error;
48
58
  }
49
59
  }
60
+ /**
61
+ * Draw a frame, keeping the last good one when drawing fails.
62
+ *
63
+ * A frame is composed before it is written, so a component that throws leaves
64
+ * the previous screen intact; without this the throw would reach the timer that
65
+ * asked for the frame, end the process, and take the terminal down with it.
66
+ * The first failure is reported and later ones stay silent: a repaint a broken
67
+ * component fails again is the same news, and repeating it would only loop.
68
+ */
69
+ doRender() {
70
+ try {
71
+ super.doRender();
72
+ }
73
+ catch (error) {
74
+ if (this.frameFailed)
75
+ return;
76
+ this.frameFailed = true;
77
+ this.onFrameError?.(error);
78
+ }
79
+ }
50
80
  stop(options) {
51
81
  try {
52
82
  super.stop(options);
@@ -57,9 +87,15 @@ export class WarningSafeTui extends TuiAltScreen {
57
87
  throw error;
58
88
  }
59
89
  finally {
90
+ // Warnings go first, while the hold is still in place, so what they print
91
+ // joins the host text in the order it arrived; the release then writes it
92
+ // all out behind the exit sequence this call already wrote.
60
93
  const release = this.releaseWarnings;
61
94
  this.releaseWarnings = undefined;
62
95
  release?.();
96
+ const writes = this.hostWrites;
97
+ this.hostWrites = undefined;
98
+ writes?.release();
63
99
  }
64
100
  }
65
101
  }
@@ -1 +1 @@
1
- {"version":3,"file":"warning-screen.js","sourceRoot":"","sources":["../../src/terminal/warning-screen.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAuB,MAAM,wBAAwB,CAAA;AAE1E,MAAM,aAAa,GAAG,SAAS,CAAA;AAC/B,MAAM,aAAa,GAAG,qCAAqC,CAAA;AAE3D,wGAAwG;AACxG,SAAS,aAAa;IACpB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;IACzB,MAAM,OAAO,GAAgB,EAAE,CAAA;IAC/B,IAAI,MAAM,GAAG,IAAI,CAAA;IACjB,MAAM,YAAY,GAAG,UAAgC,KAAsB,EAAE,GAAG,IAAe;QAC7F,IAAI,MAAM,IAAI,IAAI,KAAK,OAAO,IAAI,KAAK,KAAK,aAAa,EAAE,CAAC;YAC1D,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAClB,OAAO,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;QACjD,CAAC;QACD,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,CAAY,CAAA;IAC/D,CAAwB,CAAA;IACxB,OAAO,CAAC,IAAI,GAAG,YAAY,CAAA;IAC3B,OAAO,GAAG,EAAE;QACV,IAAI,CAAC,MAAM;YAAE,OAAM;QACnB,MAAM,GAAG,KAAK,CAAA;QACd,+FAA+F;QAC/F,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY;YAAE,OAAO,CAAC,IAAI,GAAG,IAAI,CAAA;QACtD,MAAM,QAAQ,GAAc,EAAE,CAAA;QAC9B,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC;gBACH,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,aAAa,EAAE,GAAG,IAAI,CAAC,CAAC,CAAA;YACxD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACtB,CAAC;QACH,CAAC;QACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM,QAAQ,CAAC,CAAC,CAAC,CAAA;IAC5C,CAAC,CAAA;AACH,CAAC;AAED,mGAAmG;AACnG,MAAM,OAAO,cAAe,SAAQ,YAAY;IACtC,eAAe,CAA0B;IAExC,KAAK;QACZ,IAAI,CAAC,eAAe,KAAK,aAAa,EAAE,CAAA;QACxC,IAAI,CAAC;YACH,KAAK,CAAC,KAAK,EAAE,CAAA;QACf,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,IAAI,CAAC,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAA;YACnC,MAAM,KAAK,CAAA;QACb,CAAC;IACH,CAAC;IAEQ,IAAI,CAAC,OAAwB;QACpC,IAAI,CAAC;YACH,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACrB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,0FAA0F;YAC1F,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA;YAClC,MAAM,KAAK,CAAA;QACb,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAA;YACpC,IAAI,CAAC,eAAe,GAAG,SAAS,CAAA;YAChC,OAAO,EAAE,EAAE,CAAA;QACb,CAAC;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"warning-screen.js","sourceRoot":"","sources":["../../src/terminal/warning-screen.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAuB,MAAM,wBAAwB,CAAA;AAC1E,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAuB,MAAM,kBAAkB,CAAA;AAE1F,MAAM,aAAa,GAAG,SAAS,CAAA;AAC/B,MAAM,aAAa,GAAG,qCAAqC,CAAA;AAE3D,wGAAwG;AACxG,SAAS,aAAa;IACpB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;IACzB,MAAM,OAAO,GAAgB,EAAE,CAAA;IAC/B,IAAI,MAAM,GAAG,IAAI,CAAA;IACjB,MAAM,YAAY,GAAG,UAAgC,KAAsB,EAAE,GAAG,IAAe;QAC7F,IAAI,MAAM,IAAI,IAAI,KAAK,OAAO,IAAI,KAAK,KAAK,aAAa,EAAE,CAAC;YAC1D,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAClB,OAAO,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;QACjD,CAAC;QACD,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,CAAY,CAAA;IAC/D,CAAwB,CAAA;IACxB,OAAO,CAAC,IAAI,GAAG,YAAY,CAAA;IAC3B,OAAO,GAAG,EAAE;QACV,IAAI,CAAC,MAAM;YAAE,OAAM;QACnB,MAAM,GAAG,KAAK,CAAA;QACd,+FAA+F;QAC/F,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY;YAAE,OAAO,CAAC,IAAI,GAAG,IAAI,CAAA;QACtD,MAAM,QAAQ,GAAc,EAAE,CAAA;QAC9B,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC;gBACH,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,aAAa,EAAE,GAAG,IAAI,CAAC,CAAC,CAAA;YACxD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACtB,CAAC;QACH,CAAC;QACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM,QAAQ,CAAC,CAAC,CAAC,CAAA;IAC5C,CAAC,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,OAAO,cAAe,SAAQ,YAAY;IACtC,eAAe,CAA0B;IACzC,UAAU,CAA4B;IACtC,WAAW,GAAG,KAAK,CAAA;IAE3B,+EAA+E;IAC/E,YAAY,CAAwC;IAE3C,KAAK;QACZ,IAAI,CAAC,eAAe,KAAK,aAAa,EAAE,CAAA;QACxC,IAAI,CAAC,UAAU,KAAK,cAAc,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAA;QAC5F,IAAI,CAAC;YACH,KAAK,CAAC,KAAK,EAAE,CAAA;QACf,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,IAAI,CAAC,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAA;YACnC,MAAM,KAAK,CAAA;QACb,CAAC;IACH,CAAC;IAED;;;;;;;;OAQG;IACM,QAAQ;QACf,IAAI,CAAC;YACH,KAAK,CAAC,QAAQ,EAAE,CAAA;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,IAAI,CAAC,WAAW;gBAAE,OAAM;YAC5B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAA;YACvB,IAAI,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,CAAA;QAC5B,CAAC;IACH,CAAC;IAEQ,IAAI,CAAC,OAAwB;QACpC,IAAI,CAAC;YACH,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACrB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,0FAA0F;YAC1F,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA;YAClC,MAAM,KAAK,CAAA;QACb,CAAC;gBAAS,CAAC;YACT,0EAA0E;YAC1E,0EAA0E;YAC1E,4DAA4D;YAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAA;YACpC,IAAI,CAAC,eAAe,GAAG,SAAS,CAAA;YAChC,OAAO,EAAE,EAAE,CAAA;YACX,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAA;YAC9B,IAAI,CAAC,UAAU,GAAG,SAAS,CAAA;YAC3B,MAAM,EAAE,OAAO,EAAE,CAAA;QACnB,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Terminal text, read the way a terminal would read it.
3
+ *
4
+ * Tool output, file content, and model text all reach the screen, and this
5
+ * module is the only place that decides what a control byte means. It offers
6
+ * two policies over one token stream, so they can never disagree about where a
7
+ * sequence ends:
8
+ *
9
+ * - {@link renderTerminalText} draws what the terminal would have drawn: a
10
+ * whitelisted SGR subset becomes real colour at the session's colour budget,
11
+ * a tab lands on its stop, a carriage return repaints the row it sits on, and
12
+ * every sequence a terminal would *act* on is consumed, so it acts on
13
+ * nothing. Bytes that are not a sequence are still spelled out rather than
14
+ * dropped, because silently swallowing text would hide what a tool said.
15
+ * - {@link escapeTerminalText} is for text a buffer or a file will hold: every
16
+ * control character is spelled out, because an editor cannot draw an escape
17
+ * and must not execute one.
18
+ *
19
+ * Sharing one scanner matters for more than agreement: pi-tui's own escape
20
+ * scanner recognises less than a terminal does (a `\x1b[?25l` left in a drawn
21
+ * string would make its width arithmetic swallow the text after it), so a
22
+ * sequence that is not SGR must be gone before any width is measured.
23
+ */
24
+ import { type ColourMode } from './theme-capability.ts';
25
+ /** Columns between tab stops: the POSIX default, and what every terminal still uses. */
26
+ export declare const TAB_STOP = 8;
27
+ /** Whether a tab is drawn on its stop, or kept for a buffer that will hold it. */
28
+ export type TabPolicy = 'expand' | 'keep';
29
+ export interface EscapeTextOptions {
30
+ /** The column the text starts at, so its first tab lands on the terminal's next stop. */
31
+ readonly column?: number | undefined;
32
+ readonly tab?: TabPolicy | undefined;
33
+ }
34
+ export interface RenderTextOptions {
35
+ /** The colour budget the session has; `none` drops tool styling entirely. */
36
+ readonly color: ColourMode;
37
+ /** SGR already in effect — an element's own colour, which a foreign reset returns to. */
38
+ readonly base?: string | undefined;
39
+ readonly column?: number | undefined;
40
+ }
41
+ /**
42
+ * Spell every control character, expanding a tab to the stop the terminal would
43
+ * have used.
44
+ *
45
+ * The column is what makes a tab land where it landed for the tool that wrote
46
+ * it: a row indented by four columns reaches its stop four columns later than
47
+ * the same row at the left edge.
48
+ */
49
+ export declare function escapeTerminalText(raw: string, options?: EscapeTextOptions): string;
50
+ /**
51
+ * Draw text as the terminal that produced it would have drawn it.
52
+ *
53
+ * A carriage return repaints the row from the column the fragment starts at
54
+ * and a backspace moves one column left, so a progress bar collapses to the
55
+ * state it settled on instead of showing every repaint in a row. That starting
56
+ * column is also a left margin: a row indented by the layout cannot be repainted
57
+ * by the text it holds, which is the one thing a carriage return could
58
+ * otherwise do to the frame. Styling is kept per cell, so what survives a
59
+ * repaint keeps the colour it was written with.
60
+ */
61
+ export declare function renderTerminalText(raw: string, options: RenderTextOptions): string;
62
+ /**
63
+ * Cut text to a budget of the characters a reader sees.
64
+ *
65
+ * Sequences are not content: counting them would let a coloured row lose its
66
+ * words sooner than a plain one, and cutting through one would leave a half
67
+ * sequence for a renderer to guess at. The cut falls between grapheme clusters
68
+ * for the same reason every other cut in the surface does — half a joined emoji
69
+ * is the same glitch as half a colour code.
70
+ */
71
+ export declare function clipVisibleGraphemes(raw: string, limit: number): string;
72
+ //# sourceMappingURL=terminal-text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-text.d.ts","sourceRoot":"","sources":["../src/terminal-text.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAAkC,KAAK,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAEvF,wFAAwF;AACxF,eAAO,MAAM,QAAQ,IAAI,CAAA;AAEzB,kFAAkF;AAClF,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEzC,MAAM,WAAW,iBAAiB;IAChC,yFAAyF;IACzF,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC,QAAQ,CAAC,GAAG,CAAC,EAAE,SAAS,GAAG,SAAS,CAAA;CACrC;AAED,MAAM,WAAW,iBAAiB;IAChC,6EAA6E;IAC7E,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;IAC1B,yFAAyF;IACzF,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACrC;AAuRD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,MAAM,CAkCvF;AAsJD;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,MAAM,CA2ElF;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAwBvE"}