@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,273 @@
1
+ import { chmodSync, cpSync, lstatSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, renameSync, rmSync } from 'node:fs';
2
+ import { homedir } from 'node:os';
3
+ import { dirname, join } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ const PACKAGE_ROOT = dirname(dirname(fileURLToPath(import.meta.url)));
6
+ const SKILLS_ROOT = join(PACKAGE_ROOT, '.agents', 'skills');
7
+ /** The user skill root, spelled once: the installer writes it and the drift check reads it. */
8
+ const AGENTS_DIRECTORY = '.agents';
9
+ const SKILLS_DIRECTORY = 'skills';
10
+ /** A bundled helper must keep its execute bit once the archive has stripped it. */
11
+ const HELPER_EXTENSIONS = ['.sh', '.mjs'];
12
+ const EXECUTABLE_MODE = 0o755;
13
+ /** The command a drift notice names, so the line it prints is the line that runs. */
14
+ export const SKILL_UPDATE_COMMAND = 'dsh --profile tui install-skills --update';
15
+ /** Separator the surface's own notices use, so a drift line reads like the rest. */
16
+ const NOTICE_SEPARATOR = ' · ';
17
+ function installedSkillsRoot(home) {
18
+ return join(home, AGENTS_DIRECTORY, SKILLS_DIRECTORY);
19
+ }
20
+ export class SkillAlreadyExistsError extends Error {
21
+ destination;
22
+ constructor(destination) {
23
+ super(`skill already exists: ${destination}`);
24
+ this.destination = destination;
25
+ }
26
+ }
27
+ /**
28
+ * The skills this package ships, read from the bundled directory rather than
29
+ * listed: a skill a reader can see here is one `install-skills` installs, and
30
+ * adding another never means editing the installer.
31
+ */
32
+ export function bundledSkillNames(bundled = SKILLS_ROOT) {
33
+ const root = lstatSync(bundled);
34
+ if (!root.isDirectory() || root.isSymbolicLink())
35
+ throw new Error(`invalid bundled skills: ${bundled}`);
36
+ const names = readdirSync(bundled, { withFileTypes: true })
37
+ .filter(entry => entry.isDirectory() && !entry.isSymbolicLink())
38
+ .map(entry => entry.name)
39
+ .sort();
40
+ if (names.length === 0)
41
+ throw new Error(`no bundled skills: ${bundled}`);
42
+ return names;
43
+ }
44
+ /** Every regular file a skill directory carries, keyed by its relative path. */
45
+ function skillFiles(root) {
46
+ const files = new Map();
47
+ const walk = (directory, prefix) => {
48
+ for (const entry of readdirSync(directory, { withFileTypes: true })) {
49
+ const relative = prefix === '' ? entry.name : prefix + '/' + entry.name;
50
+ const path = join(directory, entry.name);
51
+ if (entry.isDirectory()) {
52
+ walk(path, relative);
53
+ continue;
54
+ }
55
+ // A symlinked member is not content this package shipped, and following
56
+ // one would read whatever it happens to point at.
57
+ if (!entry.isFile())
58
+ continue;
59
+ files.set(relative, readFileSync(path));
60
+ }
61
+ };
62
+ walk(root, '');
63
+ return files;
64
+ }
65
+ /**
66
+ * The installed copies that no longer match what this package ships.
67
+ *
68
+ * Content only, over the bundled file set. The installer chmods its own
69
+ * helpers, so a mode difference is its doing rather than drift, and a file a
70
+ * reader added beside a skill is theirs: one startup line can explain neither,
71
+ * and a line that cries wolf gets read past when it matters.
72
+ */
73
+ export function driftedSkillNames(home = homedir(), bundled = SKILLS_ROOT) {
74
+ const skills = installedSkillsRoot(home);
75
+ return bundledSkillNames(bundled).filter(name => {
76
+ const destination = join(skills, name);
77
+ const entry = lstatSync(destination, { throwIfNoEntry: false });
78
+ // Never installed is not drift - a first install is that command's own
79
+ // prompt - and a symlinked copy is one the installer refuses to replace.
80
+ if (entry === undefined || entry.isSymbolicLink() || !entry.isDirectory())
81
+ return false;
82
+ const installed = skillFiles(destination);
83
+ for (const [path, content] of skillFiles(join(bundled, name))) {
84
+ const current = installed.get(path);
85
+ if (current === undefined || !current.equals(content))
86
+ return true;
87
+ }
88
+ return false;
89
+ });
90
+ }
91
+ /**
92
+ * The one line a startup can spare for an installed skill this build has moved
93
+ * past, or `undefined` when every installed copy still matches.
94
+ *
95
+ * Silence on any failure: a notice is a courtesy, and an unreadable home must
96
+ * not cost a reader the session they launched.
97
+ */
98
+ export function describeSkillDrift(home = homedir(), bundled = SKILLS_ROOT) {
99
+ try {
100
+ const drifted = driftedSkillNames(home, bundled);
101
+ if (drifted.length === 0)
102
+ return undefined;
103
+ return `bundled skills changed since they were installed: ${drifted.join(NOTICE_SEPARATOR)}`
104
+ + `${NOTICE_SEPARATOR}run ${SKILL_UPDATE_COMMAND}`;
105
+ }
106
+ catch {
107
+ return undefined;
108
+ }
109
+ }
110
+ /** Avoid writing through a pre-existing symlink into an unexpected directory. */
111
+ function ensureDirectory(path) {
112
+ try {
113
+ const entry = lstatSync(path);
114
+ if (entry.isSymbolicLink())
115
+ throw new Error(`refusing symbolic link: ${path}`);
116
+ if (!entry.isDirectory())
117
+ throw new Error(`not a directory: ${path}`);
118
+ }
119
+ catch (error) {
120
+ if (error.code !== 'ENOENT')
121
+ throw error;
122
+ mkdirSync(path);
123
+ }
124
+ }
125
+ /** The archive strips execute bits, so set them only on verified regular helpers. */
126
+ function restoreHelpers(destination) {
127
+ const scripts = join(destination, 'scripts');
128
+ const entry = lstatSync(scripts, { throwIfNoEntry: false });
129
+ if (entry === undefined)
130
+ return;
131
+ if (!entry.isDirectory() || entry.isSymbolicLink())
132
+ throw new Error(`invalid bundled skill scripts: ${scripts}`);
133
+ for (const name of readdirSync(scripts)) {
134
+ if (!HELPER_EXTENSIONS.some(extension => name.endsWith(extension)))
135
+ continue;
136
+ const helper = join(scripts, name);
137
+ const file = lstatSync(helper);
138
+ if (!file.isFile() || file.isSymbolicLink() || file.nlink !== 1)
139
+ throw new Error(`invalid bundled skill helper: ${helper}`);
140
+ chmodSync(helper, EXECUTABLE_MODE);
141
+ }
142
+ }
143
+ function copyBundledSkill(name, destination) {
144
+ const source = join(SKILLS_ROOT, name);
145
+ const bundled = lstatSync(source);
146
+ if (!bundled.isDirectory() || bundled.isSymbolicLink())
147
+ throw new Error(`invalid bundled skill: ${source}`);
148
+ mkdirSync(destination);
149
+ try {
150
+ for (const entry of readdirSync(source)) {
151
+ cpSync(join(source, entry), join(destination, entry), { recursive: true, force: false, errorOnExist: true });
152
+ }
153
+ restoreHelpers(destination);
154
+ }
155
+ catch (error) {
156
+ // A failed fresh copy must not turn the next unflagged install into a collision.
157
+ try {
158
+ rmSync(destination, { recursive: true, force: true });
159
+ }
160
+ catch (cleanupError) {
161
+ throw new Error(`skill copy failed; partial copy may remain at ${destination}: ${String(cleanupError)}`, { cause: error });
162
+ }
163
+ throw error;
164
+ }
165
+ }
166
+ /** Refuse a destination that is not a plain directory before anything is staged. */
167
+ function requireReplaceable(destination) {
168
+ const entry = lstatSync(destination, { throwIfNoEntry: false });
169
+ if (entry === undefined)
170
+ return;
171
+ if (entry.isSymbolicLink())
172
+ throw new Error(`refusing symbolic link: ${destination}`);
173
+ if (!entry.isDirectory())
174
+ throw new Error(`not a directory: ${destination}`);
175
+ }
176
+ /** Stage updates before moving an existing user skill, and restore it if replacement fails. */
177
+ function replaceBundledSkill(name, destination, skills) {
178
+ const workspace = mkdtempSync(join(skills, `.${name}-update-`));
179
+ const staged = join(workspace, 'new');
180
+ const backup = join(workspace, 'previous');
181
+ let oldCopyMoved = false;
182
+ try {
183
+ copyBundledSkill(name, staged);
184
+ const current = lstatSync(destination);
185
+ if (current.isSymbolicLink() || !current.isDirectory()) {
186
+ throw new Error(`invalid existing skill: ${destination}`);
187
+ }
188
+ renameSync(destination, backup);
189
+ oldCopyMoved = true;
190
+ try {
191
+ const previous = lstatSync(backup);
192
+ if (previous.isSymbolicLink() || !previous.isDirectory()) {
193
+ throw new Error(`invalid existing skill: ${backup}`);
194
+ }
195
+ renameSync(staged, destination);
196
+ }
197
+ catch (error) {
198
+ try {
199
+ renameSync(backup, destination);
200
+ oldCopyMoved = false;
201
+ }
202
+ catch (restoreError) {
203
+ throw new Error(`skill update failed; original remains at ${backup}; restore failed: ${String(restoreError)}`, { cause: error });
204
+ }
205
+ throw error;
206
+ }
207
+ try {
208
+ rmSync(workspace, { recursive: true });
209
+ }
210
+ catch (error) {
211
+ throw new Error(`skill updated; backup cleanup failed at ${workspace}: ${String(error)}`, { cause: error });
212
+ }
213
+ }
214
+ catch (error) {
215
+ if (oldCopyMoved) {
216
+ try {
217
+ renameSync(backup, destination);
218
+ }
219
+ catch {
220
+ // The original is still at the backup path; the thrown error names it.
221
+ }
222
+ }
223
+ try {
224
+ rmSync(workspace, { recursive: true, force: true });
225
+ }
226
+ catch {
227
+ // A leftover staging directory is reported by the error that caused it.
228
+ }
229
+ throw error;
230
+ }
231
+ return destination;
232
+ }
233
+ /** Install one bundled skill, or replace the installed copy when `update`. */
234
+ export function installBundledSkill(name, home = homedir(), update = false) {
235
+ return installBundledSkills(home, update, [name])[0];
236
+ }
237
+ /**
238
+ * Install every bundled skill, or exactly the named ones.
239
+ *
240
+ * Collisions are reported before the first copy, so a run either installs the
241
+ * whole set or leaves the home as it found it.
242
+ */
243
+ export function installBundledSkills(home = homedir(), update = false, names = bundledSkillNames()) {
244
+ ensureDirectory(home);
245
+ ensureDirectory(join(home, AGENTS_DIRECTORY));
246
+ const skills = installedSkillsRoot(home);
247
+ ensureDirectory(skills);
248
+ const destinations = names.map(name => join(skills, name));
249
+ for (const destination of destinations) {
250
+ const existing = lstatSync(destination, { throwIfNoEntry: false });
251
+ if (existing === undefined)
252
+ continue;
253
+ if (!update)
254
+ throw new SkillAlreadyExistsError(destination);
255
+ requireReplaceable(destination);
256
+ }
257
+ return names.map((name, index) => {
258
+ const destination = destinations[index];
259
+ if (lstatSync(destination, { throwIfNoEntry: false }) === undefined) {
260
+ try {
261
+ copyBundledSkill(name, destination);
262
+ }
263
+ catch (error) {
264
+ if (error.code === 'EEXIST')
265
+ throw new SkillAlreadyExistsError(destination);
266
+ throw error;
267
+ }
268
+ return destination;
269
+ }
270
+ return replaceBundledSkill(name, destination, skills);
271
+ });
272
+ }
273
+ //# sourceMappingURL=install-skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-skills.js","sourceRoot":"","sources":["../src/install-skills.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
- import { type ActionLayer, type Keymap } from './input/actions.ts';
1
+ import { type Keymap } from './input/actions.ts';
2
+ import { type ActionLayer } from './input/action-catalog.ts';
2
3
  /** The layers a reader may ask for, in the order the table lists them. */
3
4
  export declare const KEYMAP_LAYERS: readonly ActionLayer[];
4
5
  /** The layer a reader named, or nothing when the name is not one of them. */
@@ -1 +1 @@
1
- {"version":3,"file":"keys-command.d.ts","sourceRoot":"","sources":["../src/keys-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6D,KAAK,WAAW,EAAE,KAAK,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAE7H,0EAA0E;AAC1E,eAAO,MAAM,aAAa,EAAE,SAAS,WAAW,EAA4E,CAAA;AAmB5H,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAEjE;AAED,6FAA6F;AAC7F,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAEpD;AAED,oDAAoD;AACpD,MAAM,WAAW,SAAS;IACxB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,gFAAgF;IAChF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,2FAA2F;IAC3F,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,uFAAuF;IACvF,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CACzB;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,SAAS,SAAS,EAAE,CAyBhF"}
1
+ {"version":3,"file":"keys-command.d.ts","sourceRoot":"","sources":["../src/keys-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6C,KAAK,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAC3F,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,2BAA2B,CAAA;AAE5E,0EAA0E;AAC1E,eAAO,MAAM,aAAa,EAAE,SAAS,WAAW,EAA4E,CAAA;AAmB5H,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAEjE;AAED,6FAA6F;AAC7F,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAEpD;AAED,oDAAoD;AACpD,MAAM,WAAW,SAAS;IACxB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,gFAAgF;IAChF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,2FAA2F;IAC3F,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,uFAAuF;IACvF,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CACzB;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,SAAS,SAAS,EAAE,CAyBhF"}
@@ -1,4 +1,5 @@
1
- import { ACTION_CATALOG, actionLabel, keyName, keysFor, newShadows } from "./input/actions.js";
1
+ import { actionLabel, keyName, keysFor, newShadows } from "./input/actions.js";
2
+ import { ACTION_CATALOG } from "./input/action-catalog.js";
2
3
  /** The layers a reader may ask for, in the order the table lists them. */
3
4
  export const KEYMAP_LAYERS = ['prompt', 'surface', 'chord', 'gate', 'question', 'picker', 'library'];
4
5
  /** What each layer is for, so a list narrowed to one reads as a surface rather than a dump. */
@@ -1 +1 @@
1
- {"version":3,"file":"keys-command.js","sourceRoot":"","sources":["../src/keys-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAiC,MAAM,oBAAoB,CAAA;AAE7H,0EAA0E;AAC1E,MAAM,CAAC,MAAM,aAAa,GAA2B,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAA;AAE5H,+FAA+F;AAC/F,MAAM,WAAW,GAA0C;IACzD,MAAM,EAAE,gBAAgB;IACxB,OAAO,EAAE,yCAAyC;IAClD,KAAK,EAAE,gDAAgD;IACvD,IAAI,EAAE,aAAa;IACnB,QAAQ,EAAE,4BAA4B;IACtC,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,0DAA0D;CACpE,CAAA;AAED,iGAAiG;AACjG,MAAM,YAAY,GAAG,WAAW,CAAA;AAEhC,+FAA+F;AAC/F,MAAM,WAAW,GAAG,kBAAkB,CAAA;AAEtC,6EAA6E;AAC7E,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC,CAAA;AACpD,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,SAAS,CAAC,KAAkB;IAC1C,OAAO,WAAW,CAAC,KAAK,CAAC,CAAA;AAC3B,CAAC;AAgBD;;;;;;;;;GASG;AACH,MAAM,UAAU,UAAU,CAAC,GAAW,EAAE,IAAkB;IACxD,MAAM,MAAM,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;IAC1D,MAAM,IAAI,GAAgB,EAAE,CAAA;IAC5B,KAAK,MAAM,MAAM,IAAI,cAAc,EAAE,CAAC;QACpC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC;YAAE,SAAQ;QAC5C,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAC7D,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QAC1C,IAAI,CAAC,IAAI,CAAC;YACR,EAAE,EAAE,MAAM,CAAC,EAAE;YACb,KAAK,EAAE,GAAG,MAAM,CAAC,EAAE,MAAM,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,MAAM,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE;YACnH,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,OAAO;YACP,MAAM,EAAE,IAAI;SACb,CAAC,CAAA;IACJ,CAAC;IACD,KAAK,MAAM,MAAM,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrC,IAAI,CAAC,IAAI,CAAC;YACR,EAAE,EAAE,UAAU,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE;YAC3C,KAAK,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,MAAM,SAAS,MAAM,CAAC,KAAK,EAAE;YACtE,KAAK,EAAE,WAAW;YAClB,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,KAAK;SACd,CAAC,CAAA;IACJ,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC"}
1
+ {"version":3,"file":"keys-command.js","sourceRoot":"","sources":["../src/keys-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAe,MAAM,oBAAoB,CAAA;AAC3F,OAAO,EAAE,cAAc,EAAoB,MAAM,2BAA2B,CAAA;AAE5E,0EAA0E;AAC1E,MAAM,CAAC,MAAM,aAAa,GAA2B,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAA;AAE5H,+FAA+F;AAC/F,MAAM,WAAW,GAA0C;IACzD,MAAM,EAAE,gBAAgB;IACxB,OAAO,EAAE,yCAAyC;IAClD,KAAK,EAAE,gDAAgD;IACvD,IAAI,EAAE,aAAa;IACnB,QAAQ,EAAE,4BAA4B;IACtC,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,0DAA0D;CACpE,CAAA;AAED,iGAAiG;AACjG,MAAM,YAAY,GAAG,WAAW,CAAA;AAEhC,+FAA+F;AAC/F,MAAM,WAAW,GAAG,kBAAkB,CAAA;AAEtC,6EAA6E;AAC7E,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC,CAAA;AACpD,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,SAAS,CAAC,KAAkB;IAC1C,OAAO,WAAW,CAAC,KAAK,CAAC,CAAA;AAC3B,CAAC;AAgBD;;;;;;;;;GASG;AACH,MAAM,UAAU,UAAU,CAAC,GAAW,EAAE,IAAkB;IACxD,MAAM,MAAM,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;IAC1D,MAAM,IAAI,GAAgB,EAAE,CAAA;IAC5B,KAAK,MAAM,MAAM,IAAI,cAAc,EAAE,CAAC;QACpC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC;YAAE,SAAQ;QAC5C,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAC7D,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QAC1C,IAAI,CAAC,IAAI,CAAC;YACR,EAAE,EAAE,MAAM,CAAC,EAAE;YACb,KAAK,EAAE,GAAG,MAAM,CAAC,EAAE,MAAM,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,MAAM,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE;YACnH,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,OAAO;YACP,MAAM,EAAE,IAAI;SACb,CAAC,CAAA;IACJ,CAAC;IACD,KAAK,MAAM,MAAM,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrC,IAAI,CAAC,IAAI,CAAC;YACR,EAAE,EAAE,UAAU,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE;YAC3C,KAAK,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,MAAM,SAAS,MAAM,CAAC,KAAK,EAAE;YACtE,KAAK,EAAE,WAAW;YAClB,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,KAAK;SACd,CAAC,CAAA;IACJ,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC"}
@@ -0,0 +1,37 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ /**
3
+ * The directory slice a listing reads.
4
+ *
5
+ * Structural rather than the catalog's own type so formatting stays free of the
6
+ * llm service; the order and the entries are exactly what the picker reads. A
7
+ * name is optional here because an adapter may advertise a route without one,
8
+ * while the id is always the value a request would name.
9
+ */
10
+ export interface ModelListCatalog {
11
+ providers(): readonly {
12
+ readonly id: string;
13
+ readonly name: string;
14
+ }[];
15
+ models(provider: string): Promise<readonly {
16
+ readonly id: string;
17
+ readonly name?: string;
18
+ }[]>;
19
+ }
20
+ /**
21
+ * Format one line per reachable route, in the picker's own order.
22
+ *
23
+ * The order — registered providers in turn, then each provider's models in the
24
+ * order its adapter answered — is read from the catalog and never re-sorted, so
25
+ * any disagreement with the picker is a catalog disagreement, never a
26
+ * formatting one.
27
+ */
28
+ export declare function modelListLines(catalog: ModelListCatalog): Promise<string[]>;
29
+ /**
30
+ * Print the model directory to stdout and exit, without touching the terminal.
31
+ *
32
+ * The exit code is the command's contract for a caller that pipes the output:
33
+ * zero only after a line was printed, so a deployment that advertises nothing
34
+ * cannot pass for one that was enumerated.
35
+ */
36
+ export declare function runModelList(ctx: Context, exit: (code: number) => void): Promise<void>;
37
+ //# sourceMappingURL=model-list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-list.d.ts","sourceRoot":"","sources":["../src/model-list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAclD;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,SAAS,IAAI,SAAS;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACtE,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC,CAAA;CAC9F;AAED;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAQjF;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAuB5F"}
@@ -0,0 +1,60 @@
1
+ import { createModelCatalog } from "./agent/model.js";
2
+ /**
3
+ * Column separator between the route and the display name.
4
+ *
5
+ * A tab keeps the route column machine-splittable for a caller that pipes the
6
+ * output, and a display name is free to contain spaces.
7
+ */
8
+ const FIELD_SEPARATOR = '\t';
9
+ /** Prefix every refusal carries, so a piped run names the command that failed. */
10
+ const FAILURE_PREFIX = 'dsh --profile tui list-models: ';
11
+ /**
12
+ * Format one line per reachable route, in the picker's own order.
13
+ *
14
+ * The order — registered providers in turn, then each provider's models in the
15
+ * order its adapter answered — is read from the catalog and never re-sorted, so
16
+ * any disagreement with the picker is a catalog disagreement, never a
17
+ * formatting one.
18
+ */
19
+ export async function modelListLines(catalog) {
20
+ const lines = [];
21
+ for (const provider of catalog.providers()) {
22
+ for (const model of await catalog.models(provider.id)) {
23
+ lines.push(`${provider.id}/${model.id}${FIELD_SEPARATOR}${model.name ?? model.id}`);
24
+ }
25
+ }
26
+ return lines;
27
+ }
28
+ /**
29
+ * Print the model directory to stdout and exit, without touching the terminal.
30
+ *
31
+ * The exit code is the command's contract for a caller that pipes the output:
32
+ * zero only after a line was printed, so a deployment that advertises nothing
33
+ * cannot pass for one that was enumerated.
34
+ */
35
+ export async function runModelList(ctx, exit) {
36
+ const fail = (message) => {
37
+ process.stderr.write(`${FAILURE_PREFIX}${message}\n`);
38
+ exit(1);
39
+ };
40
+ const catalog = createModelCatalog(ctx);
41
+ if (catalog === undefined) {
42
+ fail('this profile has no llm service, so models cannot be listed');
43
+ return;
44
+ }
45
+ let lines;
46
+ try {
47
+ lines = await modelListLines(catalog);
48
+ }
49
+ catch (error) {
50
+ fail(`could not list models: ${error instanceof Error ? error.message : String(error)}`);
51
+ return;
52
+ }
53
+ if (lines.length === 0) {
54
+ fail('no configured provider advertises a model');
55
+ return;
56
+ }
57
+ process.stdout.write(`${lines.join('\n')}\n`);
58
+ exit(0);
59
+ }
60
+ //# sourceMappingURL=model-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-list.js","sourceRoot":"","sources":["../src/model-list.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAErD;;;;;GAKG;AACH,MAAM,eAAe,GAAG,IAAI,CAAA;AAE5B,kFAAkF;AAClF,MAAM,cAAc,GAAG,iCAAiC,CAAA;AAexD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAyB;IAC5D,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,KAAK,MAAM,QAAQ,IAAI,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;QAC3C,KAAK,MAAM,KAAK,IAAI,MAAM,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;YACtD,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,EAAE,IAAI,KAAK,CAAC,EAAE,GAAG,eAAe,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,EAAE,EAAE,CAAC,CAAA;QACrF,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAY,EAAE,IAA4B;IAC3E,MAAM,IAAI,GAAG,CAAC,OAAe,EAAQ,EAAE;QACrC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,cAAc,GAAG,OAAO,IAAI,CAAC,CAAA;QACrD,IAAI,CAAC,CAAC,CAAC,CAAA;IACT,CAAC,CAAA;IACD,MAAM,OAAO,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAA;IACvC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,IAAI,CAAC,6DAA6D,CAAC,CAAA;QACnE,OAAM;IACR,CAAC;IACD,IAAI,KAAe,CAAA;IACnB,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,CAAA;IACvC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,0BAA0B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QACxF,OAAM;IACR,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,IAAI,CAAC,2CAA2C,CAAC,CAAA;QACjD,OAAM;IACR,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC7C,IAAI,CAAC,CAAC,CAAC,CAAA;AACT,CAAC"}
package/lib/startup.d.ts CHANGED
@@ -7,6 +7,14 @@ export { PROFILE_NAME } from './identity.ts';
7
7
  export declare const MAIN_AGENT_ID = "main";
8
8
  /** Context key of the parsed launch service consumed by the tui row. */
9
9
  export declare const TUI_STARTUP_SERVICE = "tuiStartup";
10
+ /**
11
+ * Context key of the boolean service that turns one invocation into a listing run.
12
+ *
13
+ * A boolean rather than the lines themselves: the command line runs before llm
14
+ * mounts, so the action can only order the listing, and the surface row that
15
+ * reads the directory decides when to answer it.
16
+ */
17
+ export declare const LIST_MODELS_SERVICE = "tuiListModels";
10
18
  /**
11
19
  * Parse this app's own flags and publish the launch identity.
12
20
  *
@@ -1 +1 @@
1
- {"version":3,"file":"startup.d.ts","sourceRoot":"","sources":["../src/startup.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAMlD,eAAO,MAAM,IAAI,gBAAgB,CAAA;AAEjC,6EAA6E;AAC7E,eAAO,MAAM,MAAM,UAAkB,CAAA;AAErC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAE5C,uEAAuE;AACvE,eAAO,MAAM,aAAa,SAAS,CAAA;AAEnC,wEAAwE;AACxE,eAAO,MAAM,mBAAmB,eAAe,CAAA;AAE/C;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CA2DxC"}
1
+ {"version":3,"file":"startup.d.ts","sourceRoot":"","sources":["../src/startup.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAOlD,eAAO,MAAM,IAAI,gBAAgB,CAAA;AAEjC,6EAA6E;AAC7E,eAAO,MAAM,MAAM,UAAkB,CAAA;AAErC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAE5C,uEAAuE;AACvE,eAAO,MAAM,aAAa,SAAS,CAAA;AAEnC,wEAAwE;AACxE,eAAO,MAAM,mBAAmB,eAAe,CAAA;AAE/C;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,kBAAkB,CAAA;AAyDlD;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CA6FxC"}
package/lib/startup.js CHANGED
@@ -1,8 +1,10 @@
1
1
  import { randomUUID } from 'node:crypto';
2
+ import { createInterface } from 'node:readline/promises';
2
3
  import { Command } from 'commander';
3
4
  import { parseCmdline } from '@deepseek-ai/dsh-cmdline';
4
5
  import { CONFIGURED_AGENT_IDENTITIES_KEY } from '@deepseek-ai/dsh-agent-loop';
5
6
  import { LaunchUsageError, PROFILE_NAME, identityOf, resolveLaunchIntent, resumeHint } from "./identity.js";
7
+ import { installBundledSkills, SkillAlreadyExistsError } from "./install-skills.js";
6
8
  export const name = 'tui-startup';
7
9
  /** The launcher owns the arguments; this row only reads its own snapshot. */
8
10
  export const inject = ['cmdlineArgs'];
@@ -11,6 +13,53 @@ export { PROFILE_NAME } from "./identity.js";
11
13
  export const MAIN_AGENT_ID = 'main';
12
14
  /** Context key of the parsed launch service consumed by the tui row. */
13
15
  export const TUI_STARTUP_SERVICE = 'tuiStartup';
16
+ /**
17
+ * Context key of the boolean service that turns one invocation into a listing run.
18
+ *
19
+ * A boolean rather than the lines themselves: the command line runs before llm
20
+ * mounts, so the action can only order the listing, and the surface row that
21
+ * reads the directory decides when to answer it.
22
+ */
23
+ export const LIST_MODELS_SERVICE = 'tuiListModels';
24
+ /**
25
+ * Resolve the launch identity and the startup service both actions publish.
26
+ *
27
+ * Shared because the surface row injects `tuiStartup` and reads its own config
28
+ * from it: an invocation that published no startup, the listing included, would
29
+ * leave the row unmounted and print nothing.
30
+ */
31
+ function launchOf(program, mode, session, options) {
32
+ let intent;
33
+ try {
34
+ intent = resolveLaunchIntent({
35
+ mode,
36
+ session,
37
+ resumeFlag: options.resume,
38
+ newSession: options.new,
39
+ });
40
+ }
41
+ catch (error) {
42
+ if (error instanceof LaunchUsageError) {
43
+ program.error(`dsh --profile tui: ${error.message}`);
44
+ return undefined;
45
+ }
46
+ throw error;
47
+ }
48
+ const identity = identityOf(intent, randomUUID());
49
+ return {
50
+ identity,
51
+ startup: {
52
+ sessionId: identity.id,
53
+ resume: identity.resume,
54
+ resumePicker: intent.resumePicker,
55
+ model: options.model?.trim() || undefined,
56
+ provider: options.provider?.trim() || undefined,
57
+ preset: options.preset?.trim() || undefined,
58
+ color: options.color !== false,
59
+ bell: options.bell !== false,
60
+ },
61
+ };
62
+ }
14
63
  /**
15
64
  * Parse this app's own flags and publish the launch identity.
16
65
  *
@@ -31,36 +80,83 @@ export function apply(ctx) {
31
80
  .option('--preset <preset>', 'agent preset (mode) the new session runs')
32
81
  .option('--no-color', 'disable ANSI styling')
33
82
  .option('--no-bell', 'do not ring the terminal bell when a long turn finishes');
34
- program.action((mode, session, options) => {
35
- let intent;
83
+ program.command('install-skills')
84
+ .description('install or update the bundled skills in ~/.agents/skills/')
85
+ .option('--update', 'replace an existing skill without asking')
86
+ .action((options) => {
87
+ const exit = ctx.get('appExit');
88
+ if (exit === undefined)
89
+ throw new Error('dsh --profile tui: the launcher must provide appExit');
90
+ const fail = (error) => {
91
+ process.stderr.write(`dsh --profile tui install-skills: ${error instanceof Error ? error.message : String(error)}\n`);
92
+ exit(1);
93
+ };
94
+ const install = (update) => {
95
+ for (const destination of installBundledSkills(undefined, update)) {
96
+ process.stdout.write(`Installed ${destination}\n`);
97
+ }
98
+ exit(0);
99
+ };
100
+ if (options.update === true) {
101
+ try {
102
+ install(true);
103
+ }
104
+ catch (error) {
105
+ fail(error);
106
+ }
107
+ return;
108
+ }
36
109
  try {
37
- intent = resolveLaunchIntent({
38
- mode,
39
- session,
40
- resumeFlag: options.resume,
41
- newSession: options.new,
42
- });
110
+ install(false);
43
111
  }
44
112
  catch (error) {
45
- if (error instanceof LaunchUsageError) {
46
- program.error(`dsh --profile tui: ${error.message}`);
113
+ if (!(error instanceof SkillAlreadyExistsError)) {
114
+ fail(error);
47
115
  return;
48
116
  }
49
- throw error;
117
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
118
+ fail(new Error(`${error.message}; rerun with --update in non-interactive mode`));
119
+ return;
120
+ }
121
+ // parseCmdline uses synchronous Commander.parse, so handle the prompt promise here.
122
+ const confirmUpdate = async () => {
123
+ const readline = createInterface({ input: process.stdin, output: process.stdout });
124
+ let answer;
125
+ try {
126
+ answer = await readline.question(`Update existing skill at ${error.destination}? [y/N] `);
127
+ }
128
+ finally {
129
+ readline.close();
130
+ }
131
+ if (!/^(y|yes)$/i.test(answer.trim())) {
132
+ process.stdout.write(`Unchanged ${error.destination}\n`);
133
+ exit(0);
134
+ return;
135
+ }
136
+ install(true);
137
+ };
138
+ void confirmUpdate().catch(fail);
50
139
  }
51
- const identity = identityOf(intent, randomUUID());
52
- ctx.provide(CONFIGURED_AGENT_IDENTITIES_KEY, { [MAIN_AGENT_ID]: identity });
53
- ctx.provide(TUI_STARTUP_SERVICE, {
54
- sessionId: identity.id,
55
- resume: identity.resume,
56
- resumePicker: intent.resumePicker,
57
- model: options.model?.trim() || undefined,
58
- provider: options.provider?.trim() || undefined,
59
- preset: options.preset?.trim() || undefined,
60
- color: options.color !== false,
61
- bell: options.bell !== false,
62
- });
63
- ctx.provide('tuiGoodbyeMessage', resumeHint(identity.id, PROFILE_NAME));
140
+ });
141
+ program.command('list-models')
142
+ .description('print every provider/model the model picker can reach, then exit')
143
+ .action(() => {
144
+ // The flag is published before the startup service, because the surface
145
+ // row's action runs as soon as its injected tuiStartup exists and must
146
+ // already know this run lists instead of claiming the terminal.
147
+ ctx.provide(LIST_MODELS_SERVICE, true);
148
+ const launch = launchOf(program, undefined, undefined, {});
149
+ if (launch === undefined)
150
+ return;
151
+ ctx.provide(TUI_STARTUP_SERVICE, launch.startup);
152
+ });
153
+ program.action((mode, session, options) => {
154
+ const launch = launchOf(program, mode, session, options);
155
+ if (launch === undefined)
156
+ return;
157
+ ctx.provide(CONFIGURED_AGENT_IDENTITIES_KEY, { [MAIN_AGENT_ID]: launch.identity });
158
+ ctx.provide(TUI_STARTUP_SERVICE, launch.startup);
159
+ ctx.provide('tuiGoodbyeMessage', resumeHint(launch.identity.id, PROFILE_NAME));
64
160
  });
65
161
  parseCmdline(ctx, program);
66
162
  }
@@ -1 +1 @@
1
- {"version":3,"file":"startup.js","sourceRoot":"","sources":["../src/startup.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"startup.js","sourceRoot":"","sources":["../src/startup.ts"],"names":[],"mappings":"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"}