@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,29 @@
1
+ /** Keep released section ownership and Config-backed profile edits behind one checked seam. */
2
+ import type { Context } from '@deepseek-ai/cordis';
3
+ /** Appearance must not report success until its durable owner accepts the patch. */
4
+ export interface SectionScope {
5
+ readonly kind: 'installSection' | 'register' | 'config' | 'unsupported';
6
+ get(): unknown;
7
+ update(patch: object): Promise<void>;
8
+ /** Raw opt-outs can precede a valid commit and therefore never reach get() or notifications. */
9
+ readUser(): {
10
+ readonly value: unknown;
11
+ readonly revision: number;
12
+ } | undefined;
13
+ }
14
+ /** The row reader is needed before the Loader marks the calling fiber active. */
15
+ export interface SectionRequest<T> {
16
+ readonly owner: Context;
17
+ readonly ns: string;
18
+ readonly schema: unknown;
19
+ readonly entry: T;
20
+ readonly onChange: () => void;
21
+ readonly config?: {
22
+ readonly ns: string | undefined;
23
+ readonly get: () => unknown;
24
+ readonly live: boolean;
25
+ };
26
+ }
27
+ /** Never manufacture a successful write when no supported owner can persist it. */
28
+ export declare function openSection<T>(service: unknown, request: SectionRequest<T>): SectionScope;
29
+ //# sourceMappingURL=section.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"section.d.ts","sourceRoot":"","sources":["../../src/compat/section.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAC/F,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAMlD,oFAAoF;AACpF,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,gBAAgB,GAAG,UAAU,GAAG,QAAQ,GAAG,aAAa,CAAA;IACvE,GAAG,IAAI,OAAO,CAAA;IACd,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACpC,gGAAgG;IAChG,QAAQ,IAAI;QAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAA;CAC/E;AAyBD,iFAAiF;AACjF,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;IACjB,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAA;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,OAAO,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAA;CAC3G;AAED,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,YAAY,CAsEzF"}
@@ -0,0 +1,82 @@
1
+ const READ_UNSUPPORTED = 'the settings service cannot read the section; prompt history stays off';
2
+ const WRITE_UNSUPPORTED = 'the settings service cannot write the section; the patch was not applied';
3
+ const CONFIG_NOT_LIVE = 'the settings service cannot write live Config with this schema runtime; the patch was not applied';
4
+ /** Never manufacture a successful write when no supported owner can persist it. */
5
+ export function openSection(service, request) {
6
+ const settings = (service ?? {});
7
+ const refuseWrite = () => Promise.reject(new Error(WRITE_UNSUPPORTED));
8
+ const readUser = (ns) => {
9
+ if (typeof settings.describe !== 'function')
10
+ return undefined;
11
+ const descriptor = settings.describe().find(row => row.ns === ns);
12
+ if (descriptor === undefined || !Number.isSafeInteger(descriptor.revision) || descriptor.revision < 0) {
13
+ throw new Error(READ_UNSUPPORTED);
14
+ }
15
+ return { value: descriptor.user, revision: descriptor.revision };
16
+ };
17
+ if (typeof settings.installSection === 'function') {
18
+ let source = () => request.entry;
19
+ // An attach notification precedes the caller receiving its scope.
20
+ let attached = false;
21
+ settings.installSection(request.owner, request.ns, request.schema, request.entry, {
22
+ setSource: current => { source = current; },
23
+ onChange: () => { if (attached)
24
+ request.onChange(); },
25
+ });
26
+ attached = true;
27
+ return {
28
+ kind: 'installSection',
29
+ readUser: () => readUser(request.ns),
30
+ get: () => source(),
31
+ update: async (patch) => {
32
+ if (settings.writable === false || typeof settings.update !== 'function')
33
+ return refuseWrite();
34
+ await settings.update(request.ns, patch);
35
+ },
36
+ };
37
+ }
38
+ if (typeof settings.register === 'function') {
39
+ const scope = settings.register(request.ns, request.schema, { base: request.entry });
40
+ return {
41
+ kind: 'register',
42
+ readUser: () => readUser(request.ns),
43
+ get: () => scope.get(),
44
+ update: async (patch) => {
45
+ if (settings.writable === false || typeof scope.update !== 'function')
46
+ return refuseWrite();
47
+ await scope.update(patch);
48
+ },
49
+ };
50
+ }
51
+ if (typeof settings.describe === 'function' && request.config !== undefined) {
52
+ const config = request.config;
53
+ const descriptor = () => config.ns === undefined
54
+ ? undefined
55
+ : settings.describe().find(row => row.ns === config.ns);
56
+ return {
57
+ kind: 'config',
58
+ readUser: () => readUser(config.ns),
59
+ // Config is readable during startup even before describe() includes this fiber.
60
+ get: () => {
61
+ const current = descriptor();
62
+ return current === undefined ? config.get() : current.value;
63
+ },
64
+ update: async (patch) => {
65
+ if (!config.live)
66
+ throw new Error(CONFIG_NOT_LIVE);
67
+ const current = descriptor();
68
+ if (current === undefined || settings.writable === false || typeof settings.update !== 'function'
69
+ || !Number.isSafeInteger(current.revision) || current.revision < 0)
70
+ return refuseWrite();
71
+ await settings.update(current.ns, patch, current.revision);
72
+ },
73
+ };
74
+ }
75
+ return {
76
+ kind: 'unsupported',
77
+ readUser: () => { throw new Error(READ_UNSUPPORTED); },
78
+ get: () => { throw new Error(READ_UNSUPPORTED); },
79
+ update: refuseWrite,
80
+ };
81
+ }
82
+ //# sourceMappingURL=section.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"section.js","sourceRoot":"","sources":["../../src/compat/section.ts"],"names":[],"mappings":"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"}
package/lib/config.d.ts CHANGED
@@ -1,4 +1,29 @@
1
- import type { TuiStartup } from './contracts.ts';
1
+ import z from '@deepseek-ai/schemastery';
2
+ import type { TuiRowConfig } from './contracts.ts';
3
+ /** Keep launch identity fixed while source hosts expose preferences as live Config fields. */
4
+ export declare const Config: z<Schemastery.ObjectS<{
5
+ sessionId: z<string, string>;
6
+ resume: z<boolean, boolean>;
7
+ resumePicker: z<boolean, boolean>;
8
+ model: z<string, string>;
9
+ provider: z<string, string>;
10
+ preset: z<string, string>;
11
+ color: z<boolean, boolean>;
12
+ bell: z<boolean, boolean>;
13
+ }>, Schemastery.ObjectT<{
14
+ sessionId: z<string, string>;
15
+ resume: z<boolean, boolean>;
16
+ resumePicker: z<boolean, boolean>;
17
+ model: z<string, string>;
18
+ provider: z<string, string>;
19
+ preset: z<string, string>;
20
+ color: z<boolean, boolean>;
21
+ bell: z<boolean, boolean>;
22
+ }>>;
23
+ /** Metadata alone makes source Loader skip remounts; writes require actual native references too. */
24
+ export declare function hasLiveRowSettings(raw: unknown): boolean;
25
+ /** Preserve raw malformed fields for the appearance owner to diagnose without losing opt-outs. */
26
+ export declare function readRowSettings(raw: unknown): unknown;
2
27
  /** A composed row whose configuration cannot describe a runnable terminal surface. */
3
28
  export declare class TuiConfigError extends Error {
4
29
  }
@@ -9,5 +34,5 @@ export declare class TuiConfigError extends Error {
9
34
  * may hand-configure this row in a profile patch, so the row validates its own
10
35
  * input instead of trusting the layer above it.
11
36
  */
12
- export declare function resolveConfig(raw: unknown): TuiStartup;
37
+ export declare function resolveConfig(raw: unknown): TuiRowConfig;
13
38
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAEhD,sFAAsF;AACtF,qBAAa,cAAe,SAAQ,KAAK;CAAG;AAsB5C;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU,CAetD"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,CAAC,MAAM,0BAA0B,CAAA;AAExC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAalD,8FAA8F;AAC9F,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;GAejB,CAAA;AAUF,qGAAqG;AACrG,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAQxD;AAED,kGAAkG;AAClG,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAOrD;AAED,sFAAsF;AACtF,qBAAa,cAAe,SAAQ,KAAK;CAAG;AAsB5C;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,YAAY,CAgBxD"}
package/lib/config.js CHANGED
@@ -1,4 +1,63 @@
1
1
  import { SessionId } from '@deepseek-ai/dsh-session';
2
+ import z from '@deepseek-ai/schemastery';
3
+ import { TuiSettingsSchema } from "./theme-settings.js";
4
+ /** Native references distinguish live Config from ordinary released schema output. */
5
+ const VOLATILE_REFERENCE = Symbol.for('cosmokit.volatile.write');
6
+ const PREFERENCE_SCHEMA = TuiSettingsSchema.dict;
7
+ const PREFERENCE_FIELDS = Object.keys(PREFERENCE_SCHEMA);
8
+ const CONFIG_HISTORY = z.object({
9
+ // A source host imports legacy settings after activation; absence is not consent.
10
+ enabled: z.boolean(),
11
+ ghost: z.boolean(),
12
+ maxEntries: PREFERENCE_SCHEMA.history.dict.maxEntries,
13
+ });
14
+ /** Keep launch identity fixed while source hosts expose preferences as live Config fields. */
15
+ export const Config = z.object({
16
+ sessionId: z.string().required(),
17
+ resume: z.boolean().default(false),
18
+ resumePicker: z.boolean().default(false),
19
+ model: z.string(),
20
+ provider: z.string(),
21
+ preset: z.string(),
22
+ color: z.boolean().default(true),
23
+ bell: z.boolean().default(true),
24
+ ...Object.fromEntries(Object.entries(PREFERENCE_SCHEMA).map(([key, schema]) => {
25
+ const field = new z((key === 'history' ? CONFIG_HISTORY : schema).toJSON());
26
+ // False metadata makes source Loader silently skip ordinary config updates.
27
+ const native = field;
28
+ return [key, typeof native.volatile === 'function' ? native.volatile() : field];
29
+ })),
30
+ });
31
+ /** Only native Config references may execute a getter; ordinary input remains data. */
32
+ function preferenceValue(value) {
33
+ if (typeof value !== 'object' || value === null || !(VOLATILE_REFERENCE in value))
34
+ return value;
35
+ const reference = value;
36
+ if (typeof reference.get !== 'function')
37
+ throw new TuiConfigError('invalid volatile preference reference');
38
+ return reference.get();
39
+ }
40
+ /** Metadata alone makes source Loader skip remounts; writes require actual native references too. */
41
+ export function hasLiveRowSettings(raw) {
42
+ if (typeof raw !== 'object' || raw === null || Array.isArray(raw))
43
+ return false;
44
+ const record = raw;
45
+ return PREFERENCE_FIELDS.every(key => {
46
+ const value = record[key];
47
+ return typeof value === 'object' && value !== null && VOLATILE_REFERENCE in value
48
+ && typeof Reflect.get(value, 'get') === 'function';
49
+ });
50
+ }
51
+ /** Preserve raw malformed fields for the appearance owner to diagnose without losing opt-outs. */
52
+ export function readRowSettings(raw) {
53
+ if (typeof raw !== 'object' || raw === null || Array.isArray(raw))
54
+ return raw;
55
+ const record = raw;
56
+ return Object.fromEntries(PREFERENCE_FIELDS.flatMap(key => {
57
+ const value = preferenceValue(record[key]);
58
+ return value === undefined ? [] : [[key, value]];
59
+ }));
60
+ }
2
61
  /** A composed row whose configuration cannot describe a runnable terminal surface. */
3
62
  export class TuiConfigError extends Error {
4
63
  }
@@ -31,7 +90,7 @@ function optionalBoolean(value, field, fallback) {
31
90
  * input instead of trusting the layer above it.
32
91
  */
33
92
  export function resolveConfig(raw) {
34
- if (typeof raw !== 'object' || raw === null) {
93
+ if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {
35
94
  throw new TuiConfigError('tui row configuration must be a mapping');
36
95
  }
37
96
  const record = raw;
@@ -42,6 +101,7 @@ export function resolveConfig(raw) {
42
101
  model: optionalString(record.model, 'model'),
43
102
  provider: optionalString(record.provider, 'provider'),
44
103
  preset: optionalString(record.preset, 'preset'),
104
+ theme: optionalString(preferenceValue(record.theme), 'theme'),
45
105
  color: optionalBoolean(record.color, 'color', true),
46
106
  bell: optionalBoolean(record.bell, 'bell', true),
47
107
  };
package/lib/config.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAGpD,sFAAsF;AACtF,MAAM,OAAO,cAAe,SAAQ,KAAK;CAAG;AAE5C,SAAS,aAAa,CAAC,KAAc,EAAE,KAAa;IAClD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACrD,MAAM,IAAI,cAAc,CAAC,GAAG,KAAK,6BAA6B,CAAC,CAAA;IACjE,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,cAAc,CAAC,KAAc,EAAE,KAAa;IACnD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,SAAS,CAAA;IAC3D,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,MAAM,IAAI,cAAc,CAAC,GAAG,KAAK,gCAAgC,CAAC,CAAA;IACjG,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAA;IAC5B,OAAO,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAA;AAC7C,CAAC;AAED,SAAS,eAAe,CAAC,KAAc,EAAE,KAAa,EAAE,QAAiB;IACvE,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,QAAQ,CAAA;IAC1D,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,MAAM,IAAI,cAAc,CAAC,GAAG,KAAK,iCAAiC,CAAC,CAAA;IACnG,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,GAAY;IACxC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QAC5C,MAAM,IAAI,cAAc,CAAC,yCAAyC,CAAC,CAAA;IACrE,CAAC;IACD,MAAM,MAAM,GAAG,GAA8B,CAAA;IAC7C,OAAO;QACL,SAAS,EAAE,SAAS,CAAC,aAAa,CAAC,MAAM,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QAClE,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC;QACvD,YAAY,EAAE,eAAe,CAAC,MAAM,CAAC,YAAY,EAAE,cAAc,EAAE,KAAK,CAAC;QACzE,KAAK,EAAE,cAAc,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC;QAC5C,QAAQ,EAAE,cAAc,CAAC,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC;QACrD,MAAM,EAAE,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC;QAC/C,KAAK,EAAE,eAAe,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC;QACnD,IAAI,EAAE,eAAe,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC;KACjD,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -22,9 +22,37 @@ export interface TuiStartup {
22
22
  /** Whether a long turn may ring the terminal bell when it finishes. */
23
23
  readonly bell: boolean;
24
24
  }
25
+ /**
26
+ * The row's own configuration: every launch option, plus what only the profile
27
+ * can name.
28
+ *
29
+ * Split from the startup service because no command-line flag can carry these
30
+ * values. A harness that keeps settings per row has no `dsh-tui:` document
31
+ * section left to write a theme into, so the row's own config is the one place a
32
+ * profile patch pins it — and that makes the row the config surface for it, not
33
+ * the launcher.
34
+ */
35
+ export interface TuiRowConfig extends TuiStartup {
36
+ /**
37
+ * Theme the row pins, below the settings section and above the package default.
38
+ *
39
+ * The section is the reader's own document and still outranks this; the
40
+ * package's default answers when neither names a theme.
41
+ */
42
+ readonly theme: string | undefined;
43
+ }
25
44
  declare module '@deepseek-ai/cordis' {
26
45
  interface Context {
27
46
  tuiStartup?: TuiStartup;
47
+ /**
48
+ * Set when this invocation must print the model directory and exit instead
49
+ * of mounting the surface.
50
+ *
51
+ * The flag is a boolean because the directory is read after the llm row
52
+ * mounts, which is after the command line has already parsed: the action
53
+ * only orders the listing, it never prints.
54
+ */
55
+ tuiListModels?: boolean;
28
56
  /** Printed after the terminal is handed back, so the session stays recoverable. */
29
57
  tuiGoodbyeMessage?: string;
30
58
  }
@@ -1 +1 @@
1
- {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAEzD;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,wEAAwE;IACxE,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;IAC7B,yEAAyE;IACzE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,qDAAqD;IACrD,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;IAC9B,mDAAmD;IACnD,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;IAClC,4DAA4D;IAC5D,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;IACrC,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IACnC,uCAAuC;IACvC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,uEAAuE;IACvE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CACvB;AAED,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,UAAU,CAAC,EAAE,UAAU,CAAA;QACvB,mFAAmF;QACnF,iBAAiB,CAAC,EAAE,MAAM,CAAA;KAC3B;CACF"}
1
+ {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAEzD;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,wEAAwE;IACxE,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;IAC7B,yEAAyE;IACzE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,qDAAqD;IACrD,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;IAC9B,mDAAmD;IACnD,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;IAClC,4DAA4D;IAC5D,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;IACrC,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IACnC,uCAAuC;IACvC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,uEAAuE;IACvE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CACvB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,YAAa,SAAQ,UAAU;IAC9C;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;CACnC;AAED,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,UAAU,CAAC,EAAE,UAAU,CAAA;QACvB;;;;;;;WAOG;QACH,aAAa,CAAC,EAAE,OAAO,CAAA;QACvB,mFAAmF;QACnF,iBAAiB,CAAC,EAAE,MAAM,CAAA;KAC3B;CACF"}
@@ -13,6 +13,14 @@ import type { ForkEvent } from './agent/fork.ts';
13
13
  * than the one just read — what `/new` does — would otherwise measure the new
14
14
  * conversation against the old one's numbering and drop all of it.
15
15
  */
16
+ /** A late stored log must not repaint a transcript the reader already left. */
17
+ export declare function replayIfCurrent<Event>(read: () => Promise<readonly Event[]>, current: () => boolean, apply: (event: Event) => void): Promise<number>;
18
+ /** An older asynchronous fold must lose ownership when the view resets. */
19
+ export declare class ViewGeneration {
20
+ private generation;
21
+ /** An old view cannot regain ownership if its read finishes out of order. */
22
+ begin(): () => boolean;
23
+ }
16
24
  /** Consumes durable events in sequence order, each exactly once per session. */
17
25
  export declare class FoldCursor {
18
26
  private session;
@@ -1 +1 @@
1
- {"version":3,"file":"fold-cursor.d.ts","sourceRoot":"","sources":["../src/fold-cursor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAEhD;;;;;;;;;;;;GAYG;AAEH,gFAAgF;AAChF,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,OAAO,CAAoB;IAEnC;;;;;OAKG;IACH,KAAK,IAAI,IAAI;IAKb,2EAA2E;IAC3E,MAAM,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO;CAWtD"}
1
+ {"version":3,"file":"fold-cursor.d.ts","sourceRoot":"","sources":["../src/fold-cursor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAEhD;;;;;;;;;;;;GAYG;AAEH,+EAA+E;AAC/E,wBAAsB,eAAe,CAAC,KAAK,EACzC,IAAI,EAAE,MAAM,OAAO,CAAC,SAAS,KAAK,EAAE,CAAC,EACrC,OAAO,EAAE,MAAM,OAAO,EACtB,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAC5B,OAAO,CAAC,MAAM,CAAC,CAKjB;AAED,2EAA2E;AAC3E,qBAAa,cAAc;IACzB,OAAO,CAAC,UAAU,CAAI;IAEtB,6EAA6E;IAC7E,KAAK,IAAI,MAAM,OAAO;CAIvB;AAED,gFAAgF;AAChF,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,OAAO,CAAoB;IAEnC;;;;;OAKG;IACH,KAAK,IAAI,IAAI;IAKb,2EAA2E;IAC3E,MAAM,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO;CAWtD"}
@@ -11,6 +11,24 @@
11
11
  * than the one just read — what `/new` does — would otherwise measure the new
12
12
  * conversation against the old one's numbering and drop all of it.
13
13
  */
14
+ /** A late stored log must not repaint a transcript the reader already left. */
15
+ export async function replayIfCurrent(read, current, apply) {
16
+ const events = await read();
17
+ if (!current())
18
+ return 0;
19
+ for (const event of events)
20
+ apply(event);
21
+ return events.length;
22
+ }
23
+ /** An older asynchronous fold must lose ownership when the view resets. */
24
+ export class ViewGeneration {
25
+ generation = 0;
26
+ /** An old view cannot regain ownership if its read finishes out of order. */
27
+ begin() {
28
+ const generation = ++this.generation;
29
+ return () => generation === this.generation;
30
+ }
31
+ }
14
32
  /** Consumes durable events in sequence order, each exactly once per session. */
15
33
  export class FoldCursor {
16
34
  session;
@@ -1 +1 @@
1
- {"version":3,"file":"fold-cursor.js","sourceRoot":"","sources":["../src/fold-cursor.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AAEH,gFAAgF;AAChF,MAAM,OAAO,UAAU;IACb,OAAO,CAAuB;IAC9B,OAAO,CAAoB;IAEnC;;;;;OAKG;IACH,KAAK;QACH,IAAI,CAAC,OAAO,GAAG,SAAS,CAAA;QACxB,IAAI,CAAC,OAAO,GAAG,SAAS,CAAA;IAC1B,CAAC;IAED,2EAA2E;IAC3E,MAAM,CAAC,OAAkB,EAAE,KAAgB;QACzC,IAAI,OAAO,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;YAC7B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;YACtB,IAAI,CAAC,OAAO,GAAG,SAAS,CAAA;QAC1B,CAAC;QACD,IAAI,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;YAClC,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,OAAO;gBAAE,OAAO,KAAK,CAAA;YACzE,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,GAAG,CAAA;QAC1B,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;CACF"}
1
+ {"version":3,"file":"fold-cursor.js","sourceRoot":"","sources":["../src/fold-cursor.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AAEH,+EAA+E;AAC/E,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAAqC,EACrC,OAAsB,EACtB,KAA6B;IAE7B,MAAM,MAAM,GAAG,MAAM,IAAI,EAAE,CAAA;IAC3B,IAAI,CAAC,OAAO,EAAE;QAAE,OAAO,CAAC,CAAA;IACxB,KAAK,MAAM,KAAK,IAAI,MAAM;QAAE,KAAK,CAAC,KAAK,CAAC,CAAA;IACxC,OAAO,MAAM,CAAC,MAAM,CAAA;AACtB,CAAC;AAED,2EAA2E;AAC3E,MAAM,OAAO,cAAc;IACjB,UAAU,GAAG,CAAC,CAAA;IAEtB,6EAA6E;IAC7E,KAAK;QACH,MAAM,UAAU,GAAG,EAAE,IAAI,CAAC,UAAU,CAAA;QACpC,OAAO,GAAG,EAAE,CAAC,UAAU,KAAK,IAAI,CAAC,UAAU,CAAA;IAC7C,CAAC;CACF;AAED,gFAAgF;AAChF,MAAM,OAAO,UAAU;IACb,OAAO,CAAuB;IAC9B,OAAO,CAAoB;IAEnC;;;;;OAKG;IACH,KAAK;QACH,IAAI,CAAC,OAAO,GAAG,SAAS,CAAA;QACxB,IAAI,CAAC,OAAO,GAAG,SAAS,CAAA;IAC1B,CAAC;IAED,2EAA2E;IAC3E,MAAM,CAAC,OAAkB,EAAE,KAAgB;QACzC,IAAI,OAAO,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;YAC7B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;YACtB,IAAI,CAAC,OAAO,GAAG,SAAS,CAAA;QAC1B,CAAC;QACD,IAAI,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;YAClC,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,OAAO;gBAAE,OAAO,KAAK,CAAA;YACzE,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,GAAG,CAAA;QAC1B,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;CACF"}
@@ -0,0 +1,77 @@
1
+ import { type GateCard, type GateInput, type GateQuestion } from '../gates.ts';
2
+ import { type Keymap } from '../input/actions.ts';
3
+ import type { PositionedOption } from './questions.ts';
4
+ /** The label a question earns for an answer the model did not list. */
5
+ export declare const CUSTOM_ROW_LABEL = "other";
6
+ /** What the free-text row does, said where the reader decides. */
7
+ export declare const CUSTOM_ROW_DESCRIPTION = "type your own answer";
8
+ /** How the list hint names that row, which the row itself already labels. */
9
+ export declare const CUSTOM_ROW_SHORTHAND = "0 answer freely";
10
+ /**
11
+ * How a hint names the keys of one action.
12
+ *
13
+ * A hint is prose about what a key does here, so the word comes from the card
14
+ * rather than from the catalog row, which has to read well out of context too.
15
+ */
16
+ export declare function namedKeys(map: Keymap, id: string, verb: string): string;
17
+ /**
18
+ * How the free-text row spells the keys that leave it.
19
+ *
20
+ * A text field keeps its own exits: the arrows and escape are the field's, not
21
+ * the question's, so a reader who moved question.up or question.skip somewhere
22
+ * else still leaves with these. The question's own movement keys leave it as
23
+ * well, which is how the navigation aliases reach a reader who is typing rather
24
+ * than filtering. The arrows stay one token because they are pinned together
25
+ * rather than listed one direction at a time.
26
+ */
27
+ export declare function customRowExits(map: Keymap): string;
28
+ /** The keys that answer the free-text row, where typing is the answer rather than a filter. */
29
+ export declare function customHint(map: Keymap): string;
30
+ /**
31
+ * The question-id suffix that declares a typed answer a credential. The seam
32
+ * has no field for it, so a caller marks its own id and the gate reads that
33
+ * declaration rather than the wording: ids are caller-owned, and a question
34
+ * that merely mentions a key must still show the answer its author meant read.
35
+ */
36
+ export declare const SECRET_ID_SUFFIX = ":secret";
37
+ /** The free-text row's label when the answer is a credential, so the reader sees what they hand over. */
38
+ export declare const SECRET_ROW_LABEL = "API KEY";
39
+ /** Whether a question declares its typed answer a credential through its id. */
40
+ export declare function declaresSecret(id: string): boolean;
41
+ /**
42
+ * Everything the question card draws, read off the gate at the moment of the
43
+ * call.
44
+ *
45
+ * The projection takes this snapshot rather than the gate itself, so a card
46
+ * cannot reach back into state that moved on while it was being assembled, and
47
+ * a test can describe a screen without building a gate to hold it.
48
+ */
49
+ export interface QuestionCardView {
50
+ /** The question on screen, or undefined once every one has been decided. */
51
+ readonly question: GateQuestion | undefined;
52
+ /** One-based position of that question among the gate's own. */
53
+ readonly position: number;
54
+ /** How many questions the gate asks; the title admits to it only when it is more than one. */
55
+ readonly total: number;
56
+ /** Labels already chosen on this question. */
57
+ readonly chosen: readonly string[];
58
+ /** The filter the reader typed, empty when none. */
59
+ readonly typed: string;
60
+ /** Whether the cursor is on the free-text row. */
61
+ readonly atCustom: boolean;
62
+ /** Whether the editor already holds an answer; the card decides where to draw it. */
63
+ readonly written: boolean;
64
+ /** Every option matching the filter, in row order. */
65
+ readonly matched: readonly PositionedOption[];
66
+ /** The slice of those rows the window shows. */
67
+ readonly rows: readonly PositionedOption[];
68
+ /** One-based row number the window starts at, and where the cursor stands in it. */
69
+ readonly start: number;
70
+ readonly cursor: number;
71
+ /** The keys and the editor in force, read per draw so a settings edit lands on the next frame. */
72
+ readonly keys: Keymap;
73
+ readonly input: GateInput;
74
+ }
75
+ /** The card for one question: its heading, its windowed options, the free-text row, and the answer in view. */
76
+ export declare function questionCard(view: QuestionCardView): GateCard;
77
+ //# sourceMappingURL=question-card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"question-card.d.ts","sourceRoot":"","sources":["../../src/gates/question-card.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAA;AACxG,OAAO,EAAoB,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAA;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAEtD,uEAAuE;AACvE,eAAO,MAAM,gBAAgB,UAAU,CAAA;AAEvC,kEAAkE;AAClE,eAAO,MAAM,sBAAsB,yBAAyB,CAAA;AAE5D,6EAA6E;AAC7E,eAAO,MAAM,oBAAoB,oBAAuC,CAAA;AAExE;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAIvE;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CASlD;AAED,+FAA+F;AAC/F,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,YAAY,CAAA;AAEzC,yGAAyG;AACzG,eAAO,MAAM,gBAAgB,YAAY,CAAA;AAEzC,gFAAgF;AAChF,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAElD;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,4EAA4E;IAC5E,QAAQ,CAAC,QAAQ,EAAE,YAAY,GAAG,SAAS,CAAA;IAC3C,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,8FAA8F;IAC9F,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,8CAA8C;IAC9C,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;IAClC,oDAAoD;IACpD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,kDAAkD;IAClD,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,qFAAqF;IACrF,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,sDAAsD;IACtD,QAAQ,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAA;IAC7C,gDAAgD;IAChD,QAAQ,CAAC,IAAI,EAAE,SAAS,gBAAgB,EAAE,CAAA;IAC1C,oFAAoF;IACpF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,kGAAkG;IAClG,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAA;CAC1B;AAED,+GAA+G;AAC/G,wBAAgB,YAAY,CAAC,IAAI,EAAE,gBAAgB,GAAG,QAAQ,CAmD7D"}
@@ -0,0 +1,113 @@
1
+ import { CUSTOM_ROW_NUMBER, lines } from "../gates.js";
2
+ import { keyName, keysFor } from "../input/actions.js";
3
+ /** The label a question earns for an answer the model did not list. */
4
+ export const CUSTOM_ROW_LABEL = 'other';
5
+ /** What the free-text row does, said where the reader decides. */
6
+ export const CUSTOM_ROW_DESCRIPTION = 'type your own answer';
7
+ /** How the list hint names that row, which the row itself already labels. */
8
+ export const CUSTOM_ROW_SHORTHAND = `${CUSTOM_ROW_NUMBER} answer freely`;
9
+ /**
10
+ * How a hint names the keys of one action.
11
+ *
12
+ * A hint is prose about what a key does here, so the word comes from the card
13
+ * rather than from the catalog row, which has to read well out of context too.
14
+ */
15
+ export function namedKeys(map, id, verb) {
16
+ // One verb for the action, however many keys reach it: a hint that repeated
17
+ // the word would read as two actions rather than two ways to do one.
18
+ return `${keysFor(map, id).map(keyName).join('/')} ${verb}`;
19
+ }
20
+ /**
21
+ * How the free-text row spells the keys that leave it.
22
+ *
23
+ * A text field keeps its own exits: the arrows and escape are the field's, not
24
+ * the question's, so a reader who moved question.up or question.skip somewhere
25
+ * else still leaves with these. The question's own movement keys leave it as
26
+ * well, which is how the navigation aliases reach a reader who is typing rather
27
+ * than filtering. The arrows stay one token because they are pinned together
28
+ * rather than listed one direction at a time.
29
+ */
30
+ export function customRowExits(map) {
31
+ const names = ['↑↓'];
32
+ for (const id of ['question.up', 'question.down']) {
33
+ for (const key of keysFor(map, id)) {
34
+ const name = keyName(key);
35
+ if (name !== 'up' && name !== 'down' && !names.includes(name))
36
+ names.push(name);
37
+ }
38
+ }
39
+ return names.join('/');
40
+ }
41
+ /** The keys that answer the free-text row, where typing is the answer rather than a filter. */
42
+ export function customHint(map) {
43
+ return `type or paste an answer · ${namedKeys(map, 'question.confirm', 'confirm')} · ${namedKeys(map, 'question.cancel', 'abandon')} · ${customRowExits(map)} or esc to options`;
44
+ }
45
+ /**
46
+ * The question-id suffix that declares a typed answer a credential. The seam
47
+ * has no field for it, so a caller marks its own id and the gate reads that
48
+ * declaration rather than the wording: ids are caller-owned, and a question
49
+ * that merely mentions a key must still show the answer its author meant read.
50
+ */
51
+ export const SECRET_ID_SUFFIX = ':secret';
52
+ /** The free-text row's label when the answer is a credential, so the reader sees what they hand over. */
53
+ export const SECRET_ROW_LABEL = 'API KEY';
54
+ /** Whether a question declares its typed answer a credential through its id. */
55
+ export function declaresSecret(id) {
56
+ return id.endsWith(SECRET_ID_SUFFIX);
57
+ }
58
+ /** The card for one question: its heading, its windowed options, the free-text row, and the answer in view. */
59
+ export function questionCard(view) {
60
+ const question = view.question;
61
+ if (question === undefined) {
62
+ return { kind: 'question', title: 'question', detail: [], optionOffset: 0, options: [], custom: undefined, answerInput: undefined, hint: 'finishing' };
63
+ }
64
+ const detail = question.detail === undefined ? [] : lines(question.detail);
65
+ const heading = question.header === undefined ? '' : question.header + ' · ';
66
+ const title = `${heading}${question.question}${view.total > 1 ? ` (${view.position}/${view.total})` : ''}`;
67
+ if (question.options.length === 0) {
68
+ return {
69
+ kind: 'question',
70
+ title,
71
+ detail,
72
+ optionOffset: 0,
73
+ options: [],
74
+ custom: undefined,
75
+ // The editor is the only place the text lands, so it is drawn even while
76
+ // empty: a question answered by typing needs somewhere to paste a key.
77
+ answerInput: view.input,
78
+ hint: `type or paste an answer · ${namedKeys(view.keys, 'question.confirm', 'confirm')} · ${namedKeys(view.keys, 'question.skip', 'skip')} · ${namedKeys(view.keys, 'question.cancel', 'abandon')}`,
79
+ };
80
+ }
81
+ if (view.typed !== '')
82
+ detail.push(`filter: ${view.typed}`);
83
+ const secret = declaresSecret(question.id);
84
+ if (view.rows.length < view.matched.length)
85
+ detail.push(`showing ${view.start + 1}–${view.start + view.rows.length} of ${view.matched.length}`);
86
+ return {
87
+ kind: 'question',
88
+ title,
89
+ detail,
90
+ optionOffset: view.start,
91
+ options: view.rows.map(({ option }, position) => ({
92
+ label: option.label,
93
+ description: option.description,
94
+ // The free-text row wears the cursor when it holds it: a mark on a row
95
+ // the reader is not pointing at is a mark that lies.
96
+ current: !view.atCustom && view.start + position === view.cursor,
97
+ selected: view.chosen.includes(option.label),
98
+ })),
99
+ custom: {
100
+ label: secret ? SECRET_ROW_LABEL : CUSTOM_ROW_LABEL,
101
+ description: CUSTOM_ROW_DESCRIPTION,
102
+ current: view.atCustom,
103
+ selected: view.atCustom || view.written,
104
+ },
105
+ // A written answer stays in view whether or not the cursor is on the row,
106
+ // because it is what an enter is about to send.
107
+ answerInput: view.atCustom || view.written ? view.input : undefined,
108
+ hint: view.atCustom
109
+ ? customHint(view.keys)
110
+ : `${namedKeys(view.keys, 'question.toggle', question.multiSelect ? 'toggle' : 'select')} · digits pick · ${CUSTOM_ROW_SHORTHAND} · type to filter · ${namedKeys(view.keys, 'question.confirm', 'confirm')} · ${namedKeys(view.keys, 'question.skip', 'skip')} · ${namedKeys(view.keys, 'question.cancel', 'abandon')}`,
111
+ };
112
+ }
113
+ //# sourceMappingURL=question-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"question-card.js","sourceRoot":"","sources":["../../src/gates/question-card.ts"],"names":[],"mappings":"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"}