@sagmans/dsh-tui 0.6.0 → 0.7.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 (250) 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 +121 -0
  6. package/.agents/skills/dsh-tui-update-models/references/model-wiring.md +162 -0
  7. package/.agents/skills/dsh-tui-update-models/scripts/dump-model-catalog.mjs +178 -0
  8. package/README.md +99 -5
  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/index.d.ts +1 -0
  55. package/lib/index.d.ts.map +1 -1
  56. package/lib/index.js +343 -2602
  57. package/lib/index.js.map +1 -1
  58. package/lib/input/action-catalog.d.ts +74 -0
  59. package/lib/input/action-catalog.d.ts.map +1 -0
  60. package/lib/input/action-catalog.js +137 -0
  61. package/lib/input/action-catalog.js.map +1 -0
  62. package/lib/input/actions.d.ts +5 -81
  63. package/lib/input/actions.d.ts.map +1 -1
  64. package/lib/input/actions.js +4 -625
  65. package/lib/input/actions.js.map +1 -1
  66. package/lib/input/completion.d.ts +1 -1
  67. package/lib/input/completion.d.ts.map +1 -1
  68. package/lib/input/completion.js +2 -1
  69. package/lib/input/completion.js.map +1 -1
  70. package/lib/input/file-index.d.ts +40 -0
  71. package/lib/input/file-index.d.ts.map +1 -0
  72. package/lib/input/file-index.js +141 -0
  73. package/lib/input/file-index.js.map +1 -0
  74. package/lib/input/file-search.d.ts +1 -38
  75. package/lib/input/file-search.d.ts.map +1 -1
  76. package/lib/input/file-search.js +1 -487
  77. package/lib/input/file-search.js.map +1 -1
  78. package/lib/input/key-press.d.ts +57 -0
  79. package/lib/input/key-press.d.ts.map +1 -0
  80. package/lib/input/key-press.js +218 -0
  81. package/lib/input/key-press.js.map +1 -0
  82. package/lib/input/keymap-conflicts.d.ts +59 -0
  83. package/lib/input/keymap-conflicts.d.ts.map +1 -0
  84. package/lib/input/keymap-conflicts.js +292 -0
  85. package/lib/input/keymap-conflicts.js.map +1 -0
  86. package/lib/input/keymap-settings.js +1 -1
  87. package/lib/input/keymap-settings.js.map +1 -1
  88. package/lib/input/keymap.d.ts.map +1 -1
  89. package/lib/input/keymap.js +3 -1
  90. package/lib/input/keymap.js.map +1 -1
  91. package/lib/input/workspace-files.d.ts +10 -0
  92. package/lib/input/workspace-files.d.ts.map +1 -0
  93. package/lib/input/workspace-files.js +359 -0
  94. package/lib/input/workspace-files.js.map +1 -0
  95. package/lib/install-skills.d.ts +20 -0
  96. package/lib/install-skills.d.ts.map +1 -0
  97. package/lib/install-skills.js +198 -0
  98. package/lib/install-skills.js.map +1 -0
  99. package/lib/keys-command.d.ts +2 -1
  100. package/lib/keys-command.d.ts.map +1 -1
  101. package/lib/keys-command.js +2 -1
  102. package/lib/keys-command.js.map +1 -1
  103. package/lib/model-list.d.ts +37 -0
  104. package/lib/model-list.d.ts.map +1 -0
  105. package/lib/model-list.js +60 -0
  106. package/lib/model-list.js.map +1 -0
  107. package/lib/startup.d.ts +8 -0
  108. package/lib/startup.d.ts.map +1 -1
  109. package/lib/startup.js +120 -24
  110. package/lib/startup.js.map +1 -1
  111. package/lib/subagents.d.ts +7 -3
  112. package/lib/subagents.d.ts.map +1 -1
  113. package/lib/subagents.js +28 -4
  114. package/lib/subagents.js.map +1 -1
  115. package/lib/surface/appearance-preferences.d.ts +26 -0
  116. package/lib/surface/appearance-preferences.d.ts.map +1 -0
  117. package/lib/surface/appearance-preferences.js +139 -0
  118. package/lib/surface/appearance-preferences.js.map +1 -0
  119. package/lib/surface/appearance.d.ts +87 -0
  120. package/lib/surface/appearance.d.ts.map +1 -0
  121. package/lib/surface/appearance.js +353 -0
  122. package/lib/surface/appearance.js.map +1 -0
  123. package/lib/surface/background-work.d.ts +49 -0
  124. package/lib/surface/background-work.d.ts.map +1 -0
  125. package/lib/surface/background-work.js +146 -0
  126. package/lib/surface/background-work.js.map +1 -0
  127. package/lib/surface/commands.d.ts +80 -0
  128. package/lib/surface/commands.d.ts.map +1 -0
  129. package/lib/surface/commands.js +364 -0
  130. package/lib/surface/commands.js.map +1 -0
  131. package/lib/surface/modal-input.d.ts +58 -0
  132. package/lib/surface/modal-input.d.ts.map +1 -0
  133. package/lib/surface/modal-input.js +237 -0
  134. package/lib/surface/modal-input.js.map +1 -0
  135. package/lib/surface/model-choice.d.ts +54 -0
  136. package/lib/surface/model-choice.d.ts.map +1 -0
  137. package/lib/surface/model-choice.js +325 -0
  138. package/lib/surface/model-choice.js.map +1 -0
  139. package/lib/surface/preset-choice.d.ts +78 -0
  140. package/lib/surface/preset-choice.d.ts.map +1 -0
  141. package/lib/surface/preset-choice.js +163 -0
  142. package/lib/surface/preset-choice.js.map +1 -0
  143. package/lib/surface/prompt-input.d.ts +97 -0
  144. package/lib/surface/prompt-input.d.ts.map +1 -0
  145. package/lib/surface/prompt-input.js +215 -0
  146. package/lib/surface/prompt-input.js.map +1 -0
  147. package/lib/surface/prompt-memory.d.ts +76 -0
  148. package/lib/surface/prompt-memory.d.ts.map +1 -0
  149. package/lib/surface/prompt-memory.js +167 -0
  150. package/lib/surface/prompt-memory.js.map +1 -0
  151. package/lib/surface/session-lifecycle.d.ts +120 -0
  152. package/lib/surface/session-lifecycle.d.ts.map +1 -0
  153. package/lib/surface/session-lifecycle.js +321 -0
  154. package/lib/surface/session-lifecycle.js.map +1 -0
  155. package/lib/surface/session-picker.d.ts +39 -0
  156. package/lib/surface/session-picker.d.ts.map +1 -0
  157. package/lib/surface/session-picker.js +107 -0
  158. package/lib/surface/session-picker.js.map +1 -0
  159. package/lib/surface/session-view.d.ts +86 -0
  160. package/lib/surface/session-view.d.ts.map +1 -0
  161. package/lib/surface/session-view.js +215 -0
  162. package/lib/surface/session-view.js.map +1 -0
  163. package/lib/surface/staged-turns.d.ts +81 -0
  164. package/lib/surface/staged-turns.d.ts.map +1 -0
  165. package/lib/surface/staged-turns.js +206 -0
  166. package/lib/surface/staged-turns.js.map +1 -0
  167. package/lib/surface/terminal-lifecycle.d.ts +76 -0
  168. package/lib/surface/terminal-lifecycle.d.ts.map +1 -0
  169. package/lib/surface/terminal-lifecycle.js +222 -0
  170. package/lib/surface/terminal-lifecycle.js.map +1 -0
  171. package/lib/terminal-text/scan.d.ts +44 -0
  172. package/lib/terminal-text/scan.d.ts.map +1 -0
  173. package/lib/terminal-text/scan.js +195 -0
  174. package/lib/terminal-text/scan.js.map +1 -0
  175. package/lib/terminal-text/sgr.d.ts +32 -0
  176. package/lib/terminal-text/sgr.d.ts.map +1 -0
  177. package/lib/terminal-text/sgr.js +203 -0
  178. package/lib/terminal-text/sgr.js.map +1 -0
  179. package/lib/terminal-text.d.ts +1 -1
  180. package/lib/terminal-text.d.ts.map +1 -1
  181. package/lib/terminal-text.js +2 -379
  182. package/lib/terminal-text.js.map +1 -1
  183. package/lib/theme-command.js +2 -1
  184. package/lib/theme-command.js.map +1 -1
  185. package/lib/theme-defaults.d.ts +64 -0
  186. package/lib/theme-defaults.d.ts.map +1 -0
  187. package/lib/theme-defaults.js +248 -0
  188. package/lib/theme-defaults.js.map +1 -0
  189. package/lib/theme-resolver.d.ts +36 -0
  190. package/lib/theme-resolver.d.ts.map +1 -0
  191. package/lib/theme-resolver.js +112 -0
  192. package/lib/theme-resolver.js.map +1 -0
  193. package/lib/theme-schema.d.ts.map +1 -1
  194. package/lib/theme-schema.js +3 -2
  195. package/lib/theme-schema.js.map +1 -1
  196. package/lib/theme-settings.d.ts +5 -7
  197. package/lib/theme-settings.d.ts.map +1 -1
  198. package/lib/theme-settings.js +27 -19
  199. package/lib/theme-settings.js.map +1 -1
  200. package/lib/theme-tokens.d.ts +0 -89
  201. package/lib/theme-tokens.d.ts.map +1 -1
  202. package/lib/theme-tokens.js +0 -356
  203. package/lib/theme-tokens.js.map +1 -1
  204. package/lib/theme.d.ts +1 -1
  205. package/lib/theme.d.ts.map +1 -1
  206. package/lib/theme.js +2 -1
  207. package/lib/theme.js.map +1 -1
  208. package/lib/tool-display.d.ts.map +1 -1
  209. package/lib/tool-display.js +2 -1
  210. package/lib/tool-display.js.map +1 -1
  211. package/lib/transcript/message-content.d.ts +21 -0
  212. package/lib/transcript/message-content.d.ts.map +1 -0
  213. package/lib/transcript/message-content.js +61 -0
  214. package/lib/transcript/message-content.js.map +1 -0
  215. package/lib/transcript/tool-calls.d.ts +106 -0
  216. package/lib/transcript/tool-calls.d.ts.map +1 -0
  217. package/lib/transcript/tool-calls.js +254 -0
  218. package/lib/transcript/tool-calls.js.map +1 -0
  219. package/lib/transcript.d.ts +14 -55
  220. package/lib/transcript.d.ts.map +1 -1
  221. package/lib/transcript.js +31 -253
  222. package/lib/transcript.js.map +1 -1
  223. package/lib/ui/dock.d.ts +14 -2
  224. package/lib/ui/dock.d.ts.map +1 -1
  225. package/lib/ui/dock.js +52 -10
  226. package/lib/ui/dock.js.map +1 -1
  227. package/lib/ui/editor.d.ts.map +1 -1
  228. package/lib/ui/editor.js +2 -1
  229. package/lib/ui/editor.js.map +1 -1
  230. package/lib/ui/keymap-picker.d.ts +2 -1
  231. package/lib/ui/keymap-picker.d.ts.map +1 -1
  232. package/lib/ui/keymap-picker.js +1 -0
  233. package/lib/ui/keymap-picker.js.map +1 -1
  234. package/lib/ui/view/gate-card.d.ts +21 -0
  235. package/lib/ui/view/gate-card.d.ts.map +1 -0
  236. package/lib/ui/view/gate-card.js +104 -0
  237. package/lib/ui/view/gate-card.js.map +1 -0
  238. package/lib/ui/view/tool-card.d.ts +138 -0
  239. package/lib/ui/view/tool-card.d.ts.map +1 -0
  240. package/lib/ui/view/tool-card.js +413 -0
  241. package/lib/ui/view/tool-card.js.map +1 -0
  242. package/lib/ui/view/transcript-message.d.ts +62 -0
  243. package/lib/ui/view/transcript-message.d.ts.map +1 -0
  244. package/lib/ui/view/transcript-message.js +158 -0
  245. package/lib/ui/view/transcript-message.js.map +1 -0
  246. package/lib/ui/view.d.ts +80 -220
  247. package/lib/ui/view.d.ts.map +1 -1
  248. package/lib/ui/view.js +81 -675
  249. package/lib/ui/view.js.map +1 -1
  250. package/package.json +3 -1
@@ -0,0 +1,139 @@
1
+ import { openSection } from "../compat/section.js";
2
+ import { asRecord } from "../theme-schema.js";
3
+ import { TUI_SETTINGS_NAMESPACE, TuiSettingsSchema, readScope, settingsProblemMessage } from "../theme-settings.js";
4
+ const WRITE_UNSUPPORTED = 'the settings service cannot write the section; the patch was not applied';
5
+ /** Keep attachment, persistence, and notifications on the same checked settings source. */
6
+ export function createAppearancePreferences(ctx, ports) {
7
+ let configBacked = false;
8
+ let activeScope;
9
+ let privacyRevision;
10
+ let hadUser = false;
11
+ let blocked = { enabled: false, ghost: false };
12
+ const observePrivacy = () => {
13
+ try {
14
+ const user = activeScope?.readUser();
15
+ if (user === undefined)
16
+ return;
17
+ if (user.revision !== privacyRevision) {
18
+ privacyRevision = user.revision;
19
+ hadUser = false;
20
+ blocked = { enabled: false, ghost: false };
21
+ }
22
+ // An invalid root is omitted by describe(); valid removal advances the revision.
23
+ if (user.value === undefined && hadUser)
24
+ blocked = { enabled: true, ghost: true };
25
+ hadUser ||= user.value !== undefined;
26
+ const section = asRecord(user.value);
27
+ const history = asRecord(section?.history);
28
+ if ((user.value !== undefined && section === undefined) || (section?.history !== undefined && history === undefined)) {
29
+ blocked = { enabled: true, ghost: true };
30
+ }
31
+ else {
32
+ if (history?.enabled !== undefined && history.enabled !== true)
33
+ blocked.enabled = true;
34
+ if (history?.ghost !== undefined && history.ghost !== true)
35
+ blocked.ghost = true;
36
+ }
37
+ }
38
+ catch {
39
+ blocked = { enabled: true, ghost: true };
40
+ }
41
+ };
42
+ let readSection = () => {
43
+ const row = readScope({ get: ports.rowSettings }, ports.problem);
44
+ // Until a supported owner can read preferences, absence cannot authorize recording.
45
+ return { ...row, history: { ...row.history, enabled: false, ghost: false } };
46
+ };
47
+ let chooseTheme = (_name) => {
48
+ ports.restorePreview();
49
+ ports.problem(WRITE_UNSUPPORTED);
50
+ };
51
+ // Profile settings address local row IDs, not the Loader's qualified entry paths.
52
+ const configNamespace = ctx.fiber.entry?.options.id;
53
+ const register = () => {
54
+ // Row appearance must exist before prompt memory, even when Cordis defers attachment.
55
+ ports.apply();
56
+ ctx.inject(['settings'], settingsCtx => {
57
+ let scope;
58
+ try {
59
+ scope = openSection(settingsCtx.settings, {
60
+ owner: settingsCtx,
61
+ ns: TUI_SETTINGS_NAMESPACE,
62
+ schema: TuiSettingsSchema,
63
+ entry: ports.rowSettings(),
64
+ config: { ns: configNamespace, get: ports.rowSettings, live: ports.rowSettingsLive },
65
+ onChange: () => {
66
+ ports.apply();
67
+ ports.restyle();
68
+ },
69
+ });
70
+ }
71
+ catch (error) {
72
+ ports.disableHistory();
73
+ ports.problem(settingsProblemMessage(error) + ' · prompt history stays off until the section parses');
74
+ return;
75
+ }
76
+ activeScope = scope;
77
+ privacyRevision = undefined;
78
+ hadUser = false;
79
+ blocked = { enabled: false, ghost: false };
80
+ configBacked = scope.kind === 'config';
81
+ readSection = () => readScope({ get: () => {
82
+ const raw = scope.get();
83
+ if (scope.kind !== 'config')
84
+ return raw;
85
+ const record = asRecord(raw);
86
+ if (record === undefined)
87
+ return raw;
88
+ const history = asRecord(record.history);
89
+ // Legacy import follows Loader activation. Missing switches cannot opt in first.
90
+ if (record.history !== undefined && history === undefined)
91
+ return raw;
92
+ return { ...record, history: {
93
+ ...history,
94
+ enabled: history?.enabled === undefined ? false : history.enabled,
95
+ ghost: history?.ghost === undefined ? false : history.ghost,
96
+ } };
97
+ } }, ports.problem, ports.applied());
98
+ chooseTheme = name => {
99
+ void scope.update({ theme: name }).then(() => {
100
+ ports.apply();
101
+ ports.restyle();
102
+ ports.notice(`theme · ${name} · written to the settings document`);
103
+ }, (error) => {
104
+ ports.restorePreview();
105
+ ports.problem(settingsProblemMessage(error));
106
+ });
107
+ };
108
+ ports.apply();
109
+ });
110
+ };
111
+ const listen = () => {
112
+ const changed = (ns) => {
113
+ if (String(ns) !== TUI_SETTINGS_NAMESPACE && String(ns) !== configNamespace)
114
+ return;
115
+ ports.apply();
116
+ ports.restyle();
117
+ };
118
+ const section = ctx.on('settings/updated', changed);
119
+ const config = ctx.on('settings/document-updated', changed);
120
+ return () => { section(); config(); };
121
+ };
122
+ return {
123
+ read: () => {
124
+ const section = readSection();
125
+ // Attachment and commits must establish raw-layer presence before the first history use.
126
+ observePrivacy();
127
+ return section;
128
+ },
129
+ configBacked: () => configBacked,
130
+ chooseTheme: name => chooseTheme(name),
131
+ allowsHistory: (field, applied) => {
132
+ observePrivacy();
133
+ return applied && !blocked[field];
134
+ },
135
+ register,
136
+ listen,
137
+ };
138
+ }
139
+ //# sourceMappingURL=appearance-preferences.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"appearance-preferences.js","sourceRoot":"","sources":["../../src/surface/appearance-preferences.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ import type { KeyId } from '@earendil-works/pi-tui';
2
+ import type { Context } from '@deepseek-ai/cordis';
3
+ import { type Keymap } from '../input/actions.ts';
4
+ import { type NoticeSink } from '../settings-notice.ts';
5
+ import { type TuiTheme } from '../theme.ts';
6
+ import { type MermaidMode } from '../theme-settings.ts';
7
+ import type { ToolDisplayTable } from '../tool-display.ts';
8
+ import { type ViewState } from '../ui/view.ts';
9
+ import type { Picker } from './modal-input.ts';
10
+ import type { PromptInput } from './prompt-input.ts';
11
+ /**
12
+ * What the appearance owner needs from the surface that composes it.
13
+ *
14
+ * The sinks are ports because the caches they clear belong to the markdown view and
15
+ * the transcript view. The keyboard is a reader because the settings scope applies
16
+ * before the prompt bar's own owner exists, and the chord an edit has to end is
17
+ * armed at that moment.
18
+ */
19
+ export interface AppearancePorts {
20
+ /** Whether colour was asked for at launch; the flag outranks anything configured. */
21
+ readonly color: () => boolean;
22
+ /**
23
+ * The theme the row's own configuration pins, or nothing when it pins none.
24
+ *
25
+ * Read from the row rather than taken from the section, because a harness that
26
+ * keeps configuration per row has no `dsh-tui:` section to write a name into:
27
+ * the row is then the only layer a profile patch can carry a theme in.
28
+ */
29
+ readonly rowTheme: string | undefined;
30
+ /** Keep source Config references live rather than capturing their startup values. */
31
+ readonly rowSettings: () => unknown;
32
+ /** Source Loader can apply live edits only when its schema runtime created native references. */
33
+ readonly rowSettingsLive: boolean;
34
+ readonly notice: (message: string) => void;
35
+ readonly render: () => void;
36
+ readonly invalidateMarkdown: () => void;
37
+ readonly invalidateView: () => void;
38
+ /** The keys an edit re-installs, and the chord it has to end. */
39
+ readonly keybindings: () => Pick<PromptInput, 'installBindings' | 'disarmChord'>;
40
+ /** Run a list the surface answers for; the modal owner drives every gate and picker. */
41
+ readonly openPicker: (picker: Picker) => Promise<string | undefined>;
42
+ }
43
+ /**
44
+ * The surface's appearance, rebuilt whenever the reader's settings change.
45
+ *
46
+ * Renderers hold this object for the life of the session, so the current theme
47
+ * is swapped *behind* a stable delegate rather than reassigned: every row then
48
+ * reads one whole table, and a repaint can never observe a half-applied one.
49
+ * `--no-color` still outranks anything configured.
50
+ */
51
+ export interface Appearance {
52
+ readonly theme: TuiTheme;
53
+ /** The folds the transcript is drawn with, and the keys that flip them. */
54
+ readonly viewState: () => ViewState;
55
+ readonly toggleCards: () => void;
56
+ readonly toggleSubCalls: () => void;
57
+ readonly toggleReasoning: () => void;
58
+ readonly mermaidMode: () => MermaidMode;
59
+ readonly toolDisplay: () => ToolDisplayTable;
60
+ readonly keymap: () => Keymap;
61
+ readonly prefixKeys: () => readonly KeyId[];
62
+ readonly prefixWindowMs: () => number;
63
+ /** Whether prompts are recorded and offered, and the cap on how many. */
64
+ readonly historyEnabled: () => boolean;
65
+ readonly historyGhost: () => boolean;
66
+ readonly historyMaxEntries: () => number;
67
+ /** Print whatever the settings scope held back, where the reader can read it. */
68
+ readonly openNotices: (sink: NoticeSink) => void;
69
+ readonly registerSection: () => void;
70
+ readonly createThemesHome: () => void;
71
+ /** Register the settings listener; the answer takes it back off. */
72
+ readonly settingsListener: () => () => void;
73
+ /** Watch the reader's own themes; the answer stops the watch. */
74
+ readonly watchThemes: () => () => void;
75
+ /** Carry out one `theme` command line. */
76
+ readonly runThemeCommand: (argument: string) => void;
77
+ }
78
+ /**
79
+ * The reader's appearance and display preferences, and the theme's lifetime.
80
+ *
81
+ * Every preference is read through a getter rather than captured, and the theme
82
+ * table is replaced behind a delegate the renderers already hold, because the
83
+ * document is hot-reloaded and the shade the reader saves has to reach a session
84
+ * that is already on screen.
85
+ */
86
+ export declare function createAppearance(ctx: Context, ports: AppearancePorts): Appearance;
87
+ //# sourceMappingURL=appearance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"appearance.d.ts","sourceRoot":"","sources":["../../src/surface/appearance.ts"],"names":[],"mappings":"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"}
@@ -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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"}