@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,353 @@
1
+ import { defaultKeymap } from "../input/actions.js";
2
+ import { DEFAULT_PREFIX_KEYS, DEFAULT_PREFIX_WINDOW_S } from "../input/keymap.js";
3
+ import { createDeferredNotice } from "../settings-notice.js";
4
+ import { createTheme, forwardEditorTheme, forwardMarkdownTheme } from "../theme.js";
5
+ import { detectColourMode } from "../theme-capability.js";
6
+ import { renderThemeTable } from "../theme-command.js";
7
+ import { DEFAULT_THEME, builtinNames, builtinThemesDir, ensureThemesHome, exportTheme, loadThemes, themesHomeDir, watchThemes } from "../theme-files.js";
8
+ import { defaultSettings, toOverrides } from "../theme-settings.js";
9
+ import { ThemePicker } from "../ui/theme-picker.js";
10
+ import { DEFAULT_VIEW_STATE } from "../ui/view.js";
11
+ import { createAppearancePreferences } from "./appearance-preferences.js";
12
+ /** One second in the unit a chord window is scheduled in. */
13
+ const MS_PER_SECOND = 1000;
14
+ /**
15
+ * The reader's appearance and display preferences, and the theme's lifetime.
16
+ *
17
+ * Every preference is read through a getter rather than captured, and the theme
18
+ * table is replaced behind a delegate the renderers already hold, because the
19
+ * document is hot-reloaded and the shade the reader saves has to reach a session
20
+ * that is already on screen.
21
+ */
22
+ export function createAppearance(ctx, ports) {
23
+ const themeMode = () => (ports.color() ? detectColourMode(process.env) : 'none');
24
+ /**
25
+ * The themes this session can draw.
26
+ *
27
+ * Read from disk rather than compiled in, so a file the reader saves is a theme
28
+ * the moment the save lands. Held beside the settings rather than inside them
29
+ * because the two answer different questions: the section says which name the
30
+ * reader chose, and this says which names exist — including the one they typed
31
+ * into the directory a second ago.
32
+ */
33
+ const themesHome = themesHomeDir();
34
+ let themeLibrary = loadThemes(themesHome, builtinThemesDir());
35
+ /**
36
+ * A refused settings edit, kept until the surface can show it: stderr is
37
+ * behind the alt screen, and the section is read on a schedule of its own.
38
+ */
39
+ const settingsNotice = createDeferredNotice();
40
+ let current = createTheme(themeMode());
41
+ /**
42
+ * The section as it was last read.
43
+ *
44
+ * Held so a preview can rebuild the table without reading the document again:
45
+ * the picker repaints on every arrow key, and a read there would report a
46
+ * refused section once per press.
47
+ */
48
+ let appliedSection;
49
+ /**
50
+ * The theme the picker's cursor is on, while its list is open.
51
+ *
52
+ * A preview is a name and nothing else — the document is not written — so
53
+ * leaving the list is one more rebuild from the section, and a session that
54
+ * ends mid-preview has still persisted only what the reader chose.
55
+ */
56
+ let previewTheme;
57
+ /**
58
+ * The theme in force: the reader's section, then the name the row pins, then
59
+ * whatever file answers to no name at all.
60
+ *
61
+ * One question asked at two scopes. A section belongs to the settings document,
62
+ * so a reader who has one is naming a theme for it; the row belongs to the
63
+ * profile, and a harness that keeps configuration per row has no document left
64
+ * to hold a name — which is why the row is read here, below the section and
65
+ * above the default, rather than as the only answer.
66
+ */
67
+ const themeName = (section) => section.theme ?? (preferences.configBacked() ? undefined : ports.rowTheme);
68
+ const applyTheme = (section) => {
69
+ // The row under the cursor outranks both while a list is open, so a theme is
70
+ // judged on the reader's own transcript before it is taken.
71
+ current = createTheme(themeMode(), toOverrides({ ...section, theme: previewTheme ?? themeName(section) }, themeLibrary));
72
+ };
73
+ /** Repaint the surface: both caches hold rows drawn under the table this replaced. */
74
+ const restyle = () => {
75
+ ports.invalidateMarkdown();
76
+ ports.invalidateView();
77
+ ports.render();
78
+ };
79
+ /**
80
+ * Show a theme without choosing it.
81
+ *
82
+ * The list's cursor is the preview: every row paints the surface and writes
83
+ * nothing, so two themes are compared on the reader's own transcript rather
84
+ * than on a name. Clearing the name puts back what the document says, which is
85
+ * what cancelling the list has to leave behind.
86
+ */
87
+ const showTheme = (name) => {
88
+ previewTheme = name;
89
+ // Nothing to rebuild from before the first read, and nothing to show either.
90
+ if (appliedSection === undefined)
91
+ return;
92
+ applyTheme(appliedSection);
93
+ restyle();
94
+ };
95
+ const theme = {
96
+ get revision() { return current.revision; },
97
+ get color() { return current.color; },
98
+ style: (token, text) => current.style(token, text),
99
+ rich: (raw, options) => current.rich(raw, options),
100
+ cut: (text, width, ellipsis) => current.cut(text, width, ellipsis),
101
+ glyph: token => current.glyph(token),
102
+ visible: token => current.visible(token),
103
+ // Forwarded rather than read, because the editor and the markdown view keep
104
+ // the theme object they were built with: a settings change has to reach them
105
+ // through a stable delegate or they would keep the boot appearance.
106
+ editor: forwardEditorTheme(() => current.editor),
107
+ markdown: forwardMarkdownTheme(() => current.markdown),
108
+ };
109
+ /**
110
+ * Rows the reader has opened by key. The model stays untouched; only the view
111
+ * reads this, and a click on one message overrides it there. A thought starts
112
+ * folded: it is the longest, least scannable row in the transcript, so leaving
113
+ * it open pushes the answer a reader came for off the screen, and a folded row
114
+ * still names itself and its key. Cards start from the reader's own `tools:`
115
+ * settings, and a PTC card's calls start open for the opposite reason: each is
116
+ * one clipped line under a header that already names the program.
117
+ */
118
+ const viewState = { ...DEFAULT_VIEW_STATE };
119
+ const toggleCards = () => {
120
+ viewState.expandCards = !viewState.expandCards;
121
+ };
122
+ const toggleSubCalls = () => {
123
+ viewState.expandSubCalls = !viewState.expandSubCalls;
124
+ };
125
+ const toggleReasoning = () => {
126
+ viewState.expandReasoning = !viewState.expandReasoning;
127
+ };
128
+ /**
129
+ * How a reply's mermaid fences draw, seeded from the reader's section.
130
+ *
131
+ * The transform reads this per render instead of capturing it, because the
132
+ * settings document is hot-reloaded and a session already on screen has to
133
+ * follow the edit.
134
+ */
135
+ let mermaidMode = defaultSettings().mermaid;
136
+ /** How each tool's cards draw; the settings document owns it and the view reads it live. */
137
+ let toolDisplay = defaultSettings().tools;
138
+ /** The keys that start a chord, and how long one waits; the settings document owns all of it. */
139
+ let prefixKeys = DEFAULT_PREFIX_KEYS;
140
+ let prefixWindowMs = DEFAULT_PREFIX_WINDOW_S * MS_PER_SECOND;
141
+ /** Every action's keys in force; the settings document owns it and a press reads it live. */
142
+ let keymap = defaultKeymap();
143
+ /** Whether prompts are recorded and offered, and the cap on how many; the settings document owns all three. */
144
+ let historyEnabled = false;
145
+ let historyGhost = false;
146
+ let historyMaxEntries = defaultSettings().history.maxEntries;
147
+ /**
148
+ * Seed the display the reader configured.
149
+ *
150
+ * The key toggles nested calls for one session, but a settings edit is a
151
+ * deliberate act, so it re-seeds and becomes the new starting point; the
152
+ * mermaid mode and the per-tool card fold have no key of their own and only
153
+ * ever come from the document. Installing the keys, and ending a chord armed
154
+ * under the map this edit replaced, belong to the prompt bar's owner.
155
+ */
156
+ const applyDisplay = (section) => {
157
+ viewState.expandSubCalls = section.subcalls === 'inline';
158
+ mermaidMode = section.mermaid;
159
+ toolDisplay = section.tools;
160
+ prefixKeys = section.prefixes;
161
+ prefixWindowMs = section.prefixWindow * MS_PER_SECOND;
162
+ keymap = section.keymap;
163
+ ports.keybindings().installBindings();
164
+ historyEnabled = section.history.enabled;
165
+ historyGhost = section.history.ghost;
166
+ historyMaxEntries = section.history.maxEntries;
167
+ ports.keybindings().disarmChord();
168
+ };
169
+ /**
170
+ * Read the reader's section once and apply everything it configures.
171
+ *
172
+ * One read per change, because a refused section is reported on the way past:
173
+ * reading it once per field would show the reader the same refusal twice.
174
+ */
175
+ let applyingSettings = false;
176
+ const applySettings = () => {
177
+ // describe() can synchronously announce its first snapshot while it is being read.
178
+ if (applyingSettings)
179
+ return;
180
+ applyingSettings = true;
181
+ try {
182
+ const section = preferences.read();
183
+ previewTheme = undefined;
184
+ reportMissingTheme(section);
185
+ applyTheme(section);
186
+ appliedSection = section;
187
+ applyDisplay(section);
188
+ }
189
+ finally {
190
+ applyingSettings = false;
191
+ }
192
+ };
193
+ /**
194
+ * Say so when the reader named a theme that nothing answers to.
195
+ *
196
+ * The schema cannot refuse the name: a theme is a file, so the set of names is
197
+ * known to the directory rather than to this build, and one can stop answering
198
+ * between two reads. Falling back to the default without a word would leave the
199
+ * reader looking at shades they did not choose, so the refusal lands here
200
+ * instead — beside the read that found it, and alongside the rest of the
201
+ * section, which is still theirs.
202
+ */
203
+ const reportMissingTheme = (section) => {
204
+ const name = themeName(section);
205
+ if (name === undefined || themeLibrary.get(name) !== undefined)
206
+ return;
207
+ settingsNotice.post(`dsh-tui theme "${name}" is not a theme · themes: ${themeLibrary.names().join(' · ')} · the default, ${DEFAULT_THEME}, is drawn instead`);
208
+ };
209
+ /**
210
+ * Choose a theme from a list the screen follows.
211
+ *
212
+ * Enter writes the choice through the settings document, the same path a typed
213
+ * name takes, so what lands is what the reader was looking at. Leaving the list
214
+ * restores the theme in force, because the document never changed while they
215
+ * looked.
216
+ */
217
+ const openThemePicker = async () => {
218
+ const picked = await ports.openPicker(new ThemePicker(() => themeLibrary,
219
+ // What the surface draws right now, so a name pinned in the row is the
220
+ // row the list opens on instead of reading as no choice at all.
221
+ () => appliedSection === undefined ? ports.rowTheme : themeName(appliedSection), () => keymap, theme => showTheme(theme?.name)));
222
+ if (picked === undefined) {
223
+ showTheme(undefined);
224
+ return;
225
+ }
226
+ // The row stays on screen until the document carries it: restoring first
227
+ // would flash the theme the reader just left. The write clears the preview as
228
+ // it lands, and a write that fails says so, leaving a theme that is still one
229
+ // of theirs rather than shades nothing chose.
230
+ preferences.chooseTheme(picked);
231
+ };
232
+ const runThemeCommand = (argument) => {
233
+ // A bare command is the list: a theme is judged by looking at it, so
234
+ // choosing one belongs in a list the screen follows rather than in a name
235
+ // the reader has to already know.
236
+ if (argument === '') {
237
+ void openThemePicker();
238
+ return;
239
+ }
240
+ const [head = '', ...rest] = argument.split(/\s+/u);
241
+ // The table answers the other question a theme raises — which layer drew a
242
+ // shade — and stays reachable by name now that the list has the command.
243
+ if (head === 'tokens') {
244
+ // The table answers for the appearance on screen, not only for the
245
+ // document: a row-pinned theme would otherwise read as every shade
246
+ // untouched, which is the opposite of the question this command answers.
247
+ const section = appliedSection ?? preferences.read();
248
+ for (const line of renderThemeTable(toOverrides({ ...section, theme: previewTheme ?? themeName(section) }, themeLibrary), themeLibrary))
249
+ ports.notice(line);
250
+ ports.render();
251
+ return;
252
+ }
253
+ // The one way a built-in becomes editable. Its file ships inside the
254
+ // package and the next version replaces it, so a reader who wants to
255
+ // change one needs a copy that is theirs — and the copy is a theme the
256
+ // moment it lands, which is why the table is re-read rather than patched.
257
+ if (head === 'export') {
258
+ const chosen = rest.join(' ').trim();
259
+ if (chosen === '') {
260
+ ports.notice(`theme export · which built-in? ${builtinNames(themeLibrary).join(' · ')}`);
261
+ ports.render();
262
+ return;
263
+ }
264
+ const outcome = exportTheme(themeLibrary, chosen);
265
+ if (outcome.ok) {
266
+ themeLibrary = loadThemes(themesHome, builtinThemesDir());
267
+ ports.notice(`theme · exported ${chosen} to ${outcome.path} · /theme ${outcome.select} applies it`);
268
+ }
269
+ else {
270
+ ports.notice(outcome.problem);
271
+ }
272
+ ports.render();
273
+ return;
274
+ }
275
+ // A name nothing answers to is refused by name, like an unknown key
276
+ // layer: the reader asked for something, so the answer lists names.
277
+ if (themeLibrary.get(head) === undefined) {
278
+ ports.notice(`unknown theme "${head}" · themes: ${themeLibrary.names().join(' · ')}`);
279
+ ports.render();
280
+ return;
281
+ }
282
+ preferences.chooseTheme(head);
283
+ };
284
+ const preferences = createAppearancePreferences(ctx, {
285
+ rowSettings: ports.rowSettings,
286
+ rowSettingsLive: ports.rowSettingsLive,
287
+ applied: () => appliedSection,
288
+ apply: applySettings,
289
+ restyle,
290
+ restorePreview: () => showTheme(undefined),
291
+ disableHistory: () => { historyEnabled = false; historyGhost = false; },
292
+ notice: ports.notice,
293
+ problem: message => settingsNotice.post(message),
294
+ });
295
+ let reportedThemes = new Set();
296
+ const reportThemes = () => {
297
+ // Only what is newly wrong: the watcher re-reads the whole directory on every
298
+ // save, so an unfixed file would otherwise repeat its complaint on each one,
299
+ // and a reader who has just been told is not helped by being told again.
300
+ const problems = themeLibrary.problems();
301
+ for (const problem of problems) {
302
+ if (!reportedThemes.has(problem))
303
+ settingsNotice.post(problem);
304
+ }
305
+ reportedThemes = new Set(problems);
306
+ };
307
+ /**
308
+ * The reader's own themes: created, reported, and then watched.
309
+ *
310
+ * Created because a directory that is not there is a command that cannot work —
311
+ * `/theme export` names a path the reader should find where the surface said it
312
+ * would be. Watched because a theme is a file they are editing by hand, so
313
+ * saving one is how they ask for it; a session that needed a restart per shade
314
+ * would make the whole table useless for tuning. Everything unreadable is
315
+ * reported through the deferred notice rather than stderr, which the alternate
316
+ * screen is drawn over.
317
+ */
318
+ const createThemesHome = () => {
319
+ for (const problem of ensureThemesHome(themesHome))
320
+ settingsNotice.post(problem);
321
+ reportThemes();
322
+ };
323
+ const watchThemeFiles = () => watchThemes(themesHome, () => {
324
+ themeLibrary = loadThemes(themesHome, builtinThemesDir());
325
+ reportThemes();
326
+ // The file that was just saved may be the theme already in force, so the
327
+ // table is rebuilt rather than only repainted.
328
+ applySettings();
329
+ restyle();
330
+ });
331
+ return {
332
+ theme,
333
+ viewState: () => viewState,
334
+ toggleCards,
335
+ toggleSubCalls,
336
+ toggleReasoning,
337
+ mermaidMode: () => mermaidMode,
338
+ toolDisplay: () => toolDisplay,
339
+ keymap: () => keymap,
340
+ prefixKeys: () => prefixKeys,
341
+ prefixWindowMs: () => prefixWindowMs,
342
+ historyEnabled: () => preferences.allowsHistory('enabled', historyEnabled),
343
+ historyGhost: () => preferences.allowsHistory('ghost', historyGhost),
344
+ historyMaxEntries: () => historyMaxEntries,
345
+ openNotices: sink => settingsNotice.open(sink),
346
+ registerSection: preferences.register,
347
+ createThemesHome,
348
+ settingsListener: preferences.listen,
349
+ watchThemes: watchThemeFiles,
350
+ runThemeCommand,
351
+ };
352
+ }
353
+ //# sourceMappingURL=appearance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"appearance.js","sourceRoot":"","sources":["../../src/surface/appearance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ import type { SessionId } from '@deepseek-ai/dsh-session';
3
+ import type { TuiAgent } from '../agent/host.ts';
4
+ import { type JobSummary } from '../jobs.ts';
5
+ import { SubagentRoster } from '../subagents.ts';
6
+ /**
7
+ * What the background-work owner needs from the surface that composes it.
8
+ *
9
+ * The agent and the session on screen are read at call time: a command, a
10
+ * listener, or the job watch each has to follow whatever this terminal drives
11
+ * now, and a captured identity would follow the one it drove at construction.
12
+ */
13
+ export interface BackgroundWorkPorts {
14
+ readonly drivingAgent: () => TuiAgent | undefined;
15
+ readonly activeSession: () => SessionId;
16
+ readonly notice: (text: string) => void;
17
+ readonly marker: (text: string) => void;
18
+ readonly render: () => void;
19
+ /** Show the session a child runs in; the viewed-session owner performs it. */
20
+ readonly navigate: (id: string) => void;
21
+ /** Keep the pane claimed while this session's children or jobs are live. */
22
+ readonly backgroundChanged: (running: boolean) => void;
23
+ }
24
+ /** The commands and live reads the composing surface routes to this owner. */
25
+ export interface BackgroundWork {
26
+ readonly roster: SubagentRoster;
27
+ readonly jobs: () => readonly JobSummary[];
28
+ readonly refresh: () => void;
29
+ /** Fold the parent's durable catalog, which is where a child's task name lives. */
30
+ readonly acceptCatalog: (info: unknown) => void;
31
+ readonly resetRoster: () => void;
32
+ readonly runSubagentsCommand: (argument: string) => void;
33
+ readonly runJobsCommand: (argument: string) => void;
34
+ /**
35
+ * Register the two subagent lifecycle listeners.
36
+ *
37
+ * They are returned rather than pushed here so the composition root keeps one
38
+ * ordered list of teardowns, which is unwound in reverse registration order.
39
+ */
40
+ readonly subagentListeners: () => readonly (() => void)[];
41
+ readonly watchJobs: () => () => void;
42
+ }
43
+ /**
44
+ * The work that runs beside the conversation: background jobs and child agents.
45
+ *
46
+ * Neither is folded from the transcript. A job board is live state owned by a
47
+ * service, and a child's name arrives on its own event, so this owner keeps
48
+ * those reads and the two commands that show them in one place.
49
+ */
50
+ export declare function createBackgroundWork(ctx: Context, ports: BackgroundWorkPorts): BackgroundWork;
51
+ //# sourceMappingURL=background-work.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"background-work.d.ts","sourceRoot":"","sources":["../../src/surface/background-work.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAChD,OAAO,EAOL,KAAK,UAAU,EAChB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,cAAc,EAAgF,MAAM,iBAAiB,CAAA;AAO9H;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,QAAQ,GAAG,SAAS,CAAA;IACjD,QAAQ,CAAC,aAAa,EAAE,MAAM,SAAS,CAAA;IACvC,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,IAAI,CAAA;IAC3B,8EAA8E;IAC9E,QAAQ,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,4EAA4E;IAC5E,QAAQ,CAAC,iBAAiB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;CACvD;AAED,8EAA8E;AAC9E,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAA;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,SAAS,UAAU,EAAE,CAAA;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAA;IAC5B,mFAAmF;IACnF,QAAQ,CAAC,aAAa,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IAC/C,QAAQ,CAAC,WAAW,EAAE,MAAM,IAAI,CAAA;IAChC,QAAQ,CAAC,mBAAmB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;IACxD,QAAQ,CAAC,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;IACnD;;;;;OAKG;IACH,QAAQ,CAAC,iBAAiB,EAAE,MAAM,SAAS,CAAC,MAAM,IAAI,CAAC,EAAE,CAAA;IACzD,QAAQ,CAAC,SAAS,EAAE,MAAM,MAAM,IAAI,CAAA;CACrC;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,mBAAmB,GAAG,cAAc,CAiK7F"}
@@ -0,0 +1,172 @@
1
+ import { JOB_READ_LINES, createJobDirectory, describeJobs, isLive, parseJobsArgument, } from "../jobs.js";
2
+ import { SubagentRoster, createSubagentControl, describeSubagents, parseSubagentsArgument, resolveRun } from "../subagents.js";
3
+ /** Decode a lifecycle payload the roster only takes when it carries the shape it expects. */
4
+ function asRecord(value) {
5
+ return typeof value === 'object' && value !== null ? value : undefined;
6
+ }
7
+ /**
8
+ * The work that runs beside the conversation: background jobs and child agents.
9
+ *
10
+ * Neither is folded from the transcript. A job board is live state owned by a
11
+ * service, and a child's name arrives on its own event, so this owner keeps
12
+ * those reads and the two commands that show them in one place.
13
+ */
14
+ export function createBackgroundWork(ctx, ports) {
15
+ const jobDirectory = createJobDirectory(ctx);
16
+ let jobs = [];
17
+ const roster = new SubagentRoster();
18
+ const subagentControl = createSubagentControl(ctx);
19
+ let pendingIdle;
20
+ const reportBackground = () => {
21
+ const live = roster.running().length > 0 || jobs.some(job => isLive(job.status));
22
+ if (live) {
23
+ if (pendingIdle !== undefined)
24
+ clearImmediate(pendingIdle);
25
+ pendingIdle = undefined;
26
+ ports.backgroundChanged(true);
27
+ return;
28
+ }
29
+ if (pendingIdle !== undefined)
30
+ return;
31
+ // The job registry announces settlement before its completion listener
32
+ // wakes the parent; let that handoff finish before claiming the pane idle.
33
+ pendingIdle = setImmediate(() => {
34
+ pendingIdle = undefined;
35
+ ports.backgroundChanged(roster.running().length > 0 || jobs.some(job => isLive(job.status)));
36
+ });
37
+ };
38
+ /** Re-read the job board; it is live state, so nothing else can fold it. */
39
+ const refresh = () => {
40
+ const agent = ports.drivingAgent();
41
+ jobs = agent === undefined || jobDirectory === undefined ? [] : jobDirectory.list(agent.agent);
42
+ reportBackground();
43
+ ports.render();
44
+ };
45
+ /**
46
+ * List or stop the delegations this session started.
47
+ *
48
+ * A child runs in the same process as an ordinary agent, so a stop is the
49
+ * cancel a reader's Ctrl+C sends to the parent; nothing here reaches into the
50
+ * child's own session, which keeps its own transcript either way.
51
+ */
52
+ const runSubagentsCommand = (argument) => {
53
+ const command = parseSubagentsArgument(argument);
54
+ switch (command.kind) {
55
+ case 'list':
56
+ ports.notice(describeSubagents(roster.list(), Date.now()));
57
+ ports.render();
58
+ return;
59
+ case 'open': {
60
+ const run = resolveRun(roster.list(), command.id);
61
+ if (run === undefined) {
62
+ ports.notice(`${command.id}: no single child matches; /subagents lists them`);
63
+ ports.render();
64
+ return;
65
+ }
66
+ ports.navigate(run.id);
67
+ return;
68
+ }
69
+ case 'kill': {
70
+ const stopped = subagentControl?.stop(command.id) ?? false;
71
+ ports.notice(stopped
72
+ ? `${command.id}: stop requested`
73
+ : `${command.id}: no live child with that id`);
74
+ ports.render();
75
+ return;
76
+ }
77
+ case 'invalid':
78
+ ports.notice(`/subagents: ${command.reason}`);
79
+ ports.render();
80
+ return;
81
+ }
82
+ };
83
+ const runJobsCommand = (argument) => {
84
+ const agent = ports.drivingAgent();
85
+ if (jobDirectory === undefined) {
86
+ ports.notice('this profile has no job registry, so there is nothing to list');
87
+ ports.render();
88
+ return;
89
+ }
90
+ if (agent === undefined) {
91
+ ports.notice('the agent is still starting; try again in a moment');
92
+ ports.render();
93
+ return;
94
+ }
95
+ const command = parseJobsArgument(argument);
96
+ switch (command.kind) {
97
+ case 'list':
98
+ refresh();
99
+ ports.notice(describeJobs(jobs, Date.now()));
100
+ ports.render();
101
+ return;
102
+ case 'read': {
103
+ const result = jobDirectory.read(agent.agent, command.id);
104
+ const text = result?.text.trim() ?? '';
105
+ ports.notice(text === ''
106
+ ? `${command.id}: no output yet`
107
+ : `${command.id} output\n${text.split('\n').slice(-JOB_READ_LINES).join('\n')}`);
108
+ refresh();
109
+ return;
110
+ }
111
+ case 'kill': {
112
+ const outcome = jobDirectory.kill(agent.agent, command.id);
113
+ ports.notice(outcome === undefined
114
+ ? `${command.id}: no such job`
115
+ : outcome === 'requested' ? `${command.id}: stop requested` : `${command.id} had already finished`);
116
+ refresh();
117
+ return;
118
+ }
119
+ case 'invalid':
120
+ ports.notice(`/jobs: ${command.reason}`);
121
+ ports.render();
122
+ return;
123
+ }
124
+ };
125
+ /**
126
+ * Subagent lifecycle arrives as a service event rather than a session event,
127
+ * so it is decoration in the transcript: the parent's durable catalog
128
+ * carries the child's task. The name is cast so a rename in the
129
+ * harness cannot break compilation of this surface.
130
+ */
131
+ const listenFor = (name, handler) => ctx.on(name, handler);
132
+ return {
133
+ roster,
134
+ jobs: () => jobs,
135
+ refresh,
136
+ acceptCatalog: info => roster.catalog(info),
137
+ resetRoster: () => {
138
+ roster.reset();
139
+ jobs = [];
140
+ reportBackground();
141
+ },
142
+ runSubagentsCommand,
143
+ runJobsCommand,
144
+ subagentListeners: () => [
145
+ listenFor('subagent/start', info => {
146
+ roster.start(info);
147
+ reportBackground();
148
+ const record = asRecord(info);
149
+ const provider = typeof record?.provider === 'string' ? record.provider : 'subagent';
150
+ const id = typeof record?.id === 'string' ? record.id : '';
151
+ ports.marker(`subagent ${provider} started${id === '' ? '' : ` · ${id}`}`);
152
+ ports.render();
153
+ }),
154
+ listenFor('subagent/end', info => {
155
+ roster.end(info);
156
+ reportBackground();
157
+ const record = asRecord(info);
158
+ const provider = typeof record?.provider === 'string' ? record.provider : 'subagent';
159
+ const stop = typeof record?.stopReason === 'string' ? record.stopReason : undefined;
160
+ ports.marker(`subagent ${provider} finished${stop === undefined ? '' : ` · ${stop}`}`);
161
+ ports.render();
162
+ }),
163
+ ],
164
+ // The board is live state: watch it directly rather than folding events.
165
+ watchJobs: () => jobDirectory?.watch(owner => {
166
+ if (owner !== undefined && owner.id !== ports.activeSession())
167
+ return;
168
+ refresh();
169
+ }) ?? (() => { }),
170
+ };
171
+ }
172
+ //# sourceMappingURL=background-work.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"background-work.js","sourceRoot":"","sources":["../../src/surface/background-work.ts"],"names":[],"mappings":"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"}