@hydranium/cli 1.0.0-next.42 → 1.0.0-next.420

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 (371) hide show
  1. package/README.md +125 -204
  2. package/bin/hydranium-cli.js +13 -0
  3. package/heap-analysis/heap/core/load.mjs +2 -2
  4. package/heap-analysis/heap/langium/langium.classifier.mjs +22 -11
  5. package/lib/cli-version.js.map +1 -1
  6. package/lib/cli.js +11 -2
  7. package/lib/cli.js.map +1 -1
  8. package/lib/commands/analyze-heap-args.d.ts.map +1 -1
  9. package/lib/commands/analyze-heap-args.js +1 -2
  10. package/lib/commands/analyze-heap-args.js.map +1 -1
  11. package/lib/commands/analyze-heap.d.ts +3 -0
  12. package/lib/commands/analyze-heap.d.ts.map +1 -1
  13. package/lib/commands/analyze-heap.js +2 -1
  14. package/lib/commands/analyze-heap.js.map +1 -1
  15. package/lib/commands/ast-ground-truth-args.d.ts +3 -2
  16. package/lib/commands/ast-ground-truth-args.d.ts.map +1 -1
  17. package/lib/commands/ast-ground-truth-args.js +12 -10
  18. package/lib/commands/ast-ground-truth-args.js.map +1 -1
  19. package/lib/commands/ast-ground-truth-driver.js +4 -2
  20. package/lib/commands/ast-ground-truth-driver.js.map +1 -1
  21. package/lib/commands/ast-ground-truth.js +1 -1
  22. package/lib/commands/ast-ground-truth.js.map +1 -1
  23. package/lib/commands/check-skills-args.d.ts +11 -0
  24. package/lib/commands/check-skills-args.d.ts.map +1 -0
  25. package/lib/commands/check-skills-args.js +71 -0
  26. package/lib/commands/check-skills-args.js.map +1 -0
  27. package/lib/commands/client-session.d.ts +17 -0
  28. package/lib/commands/client-session.d.ts.map +1 -0
  29. package/lib/commands/client-session.js +27 -0
  30. package/lib/commands/client-session.js.map +1 -0
  31. package/lib/commands/create-args.d.ts +17 -0
  32. package/lib/commands/create-args.d.ts.map +1 -0
  33. package/lib/commands/create-args.js +53 -0
  34. package/lib/commands/create-args.js.map +1 -0
  35. package/lib/commands/create.d.ts +38 -0
  36. package/lib/commands/create.d.ts.map +1 -0
  37. package/lib/commands/create.js +43 -0
  38. package/lib/commands/create.js.map +1 -0
  39. package/lib/commands/delete-args.d.ts +17 -0
  40. package/lib/commands/delete-args.d.ts.map +1 -0
  41. package/lib/commands/delete-args.js +49 -0
  42. package/lib/commands/delete-args.js.map +1 -0
  43. package/lib/commands/delete.d.ts +30 -0
  44. package/lib/commands/delete.d.ts.map +1 -0
  45. package/lib/commands/delete.js +32 -0
  46. package/lib/commands/delete.js.map +1 -0
  47. package/lib/commands/generate-ast-builder.d.ts +1 -1
  48. package/lib/commands/generate-ast-builder.d.ts.map +1 -1
  49. package/lib/commands/generate-ast-builder.js +2 -11
  50. package/lib/commands/generate-ast-builder.js.map +1 -1
  51. package/lib/commands/generate-languages.d.ts +35 -0
  52. package/lib/commands/generate-languages.d.ts.map +1 -0
  53. package/lib/commands/generate-languages.js +105 -0
  54. package/lib/commands/generate-languages.js.map +1 -0
  55. package/lib/commands/generate-transfer-builder.d.ts +33 -0
  56. package/lib/commands/generate-transfer-builder.d.ts.map +1 -0
  57. package/lib/commands/generate-transfer-builder.js +86 -0
  58. package/lib/commands/generate-transfer-builder.js.map +1 -0
  59. package/lib/commands/generate-transfer-model-args.d.ts.map +1 -1
  60. package/lib/commands/generate-transfer-model-args.js +20 -5
  61. package/lib/commands/generate-transfer-model-args.js.map +1 -1
  62. package/lib/commands/generate-transfer-model-config.d.ts.map +1 -1
  63. package/lib/commands/generate-transfer-model-config.js +8 -3
  64. package/lib/commands/generate-transfer-model-config.js.map +1 -1
  65. package/lib/commands/generate-transfer-model.d.ts +41 -9
  66. package/lib/commands/generate-transfer-model.d.ts.map +1 -1
  67. package/lib/commands/generate-transfer-model.js +225 -68
  68. package/lib/commands/generate-transfer-model.js.map +1 -1
  69. package/lib/commands/generated-module-path.d.ts +16 -0
  70. package/lib/commands/generated-module-path.d.ts.map +1 -0
  71. package/lib/commands/generated-module-path.js +21 -0
  72. package/lib/commands/generated-module-path.js.map +1 -0
  73. package/lib/commands/harness-args.d.ts +46 -43
  74. package/lib/commands/harness-args.d.ts.map +1 -1
  75. package/lib/commands/harness-args.js +170 -29
  76. package/lib/commands/harness-args.js.map +1 -1
  77. package/lib/commands/headless-harness.d.ts +37 -20
  78. package/lib/commands/headless-harness.d.ts.map +1 -1
  79. package/lib/commands/headless-harness.js +71 -19
  80. package/lib/commands/headless-harness.js.map +1 -1
  81. package/lib/commands/init-args.d.ts +5 -18
  82. package/lib/commands/init-args.d.ts.map +1 -1
  83. package/lib/commands/init-args.js +131 -35
  84. package/lib/commands/init-args.js.map +1 -1
  85. package/lib/commands/init-hosts.d.ts +24 -0
  86. package/lib/commands/init-hosts.d.ts.map +1 -0
  87. package/lib/commands/init-hosts.js +37 -0
  88. package/lib/commands/init-hosts.js.map +1 -0
  89. package/lib/commands/init-prompt.d.ts +3 -3
  90. package/lib/commands/init-prompt.d.ts.map +1 -1
  91. package/lib/commands/init-prompt.js +4 -5
  92. package/lib/commands/init-prompt.js.map +1 -1
  93. package/lib/commands/init-skills.d.ts +41 -0
  94. package/lib/commands/init-skills.d.ts.map +1 -0
  95. package/lib/commands/init-skills.js +110 -0
  96. package/lib/commands/init-skills.js.map +1 -0
  97. package/lib/commands/init-templates.d.ts +20 -14
  98. package/lib/commands/init-templates.d.ts.map +1 -1
  99. package/lib/commands/init-templates.js +3107 -759
  100. package/lib/commands/init-templates.js.map +1 -1
  101. package/lib/commands/init-wizard.d.ts +10 -0
  102. package/lib/commands/init-wizard.d.ts.map +1 -1
  103. package/lib/commands/init-wizard.js +76 -31
  104. package/lib/commands/init-wizard.js.map +1 -1
  105. package/lib/commands/init-workspace.d.ts +13 -11
  106. package/lib/commands/init-workspace.d.ts.map +1 -1
  107. package/lib/commands/init-workspace.js +21 -7
  108. package/lib/commands/init-workspace.js.map +1 -1
  109. package/lib/commands/init.d.ts +61 -24
  110. package/lib/commands/init.d.ts.map +1 -1
  111. package/lib/commands/init.js +244 -50
  112. package/lib/commands/init.js.map +1 -1
  113. package/lib/commands/kebab.d.ts +15 -0
  114. package/lib/commands/kebab.d.ts.map +1 -0
  115. package/lib/commands/kebab.js +17 -0
  116. package/lib/commands/kebab.js.map +1 -0
  117. package/lib/commands/lint-grammar-args.d.ts +3 -2
  118. package/lib/commands/lint-grammar-args.d.ts.map +1 -1
  119. package/lib/commands/lint-grammar-args.js +14 -11
  120. package/lib/commands/lint-grammar-args.js.map +1 -1
  121. package/lib/commands/lint-grammar-driver.js +2 -1
  122. package/lib/commands/lint-grammar-driver.js.map +1 -1
  123. package/lib/commands/lint-grammar-report.js.map +1 -1
  124. package/lib/commands/lint-grammar.js +1 -1
  125. package/lib/commands/lint-grammar.js.map +1 -1
  126. package/lib/commands/measure-memory-args.d.ts +3 -2
  127. package/lib/commands/measure-memory-args.d.ts.map +1 -1
  128. package/lib/commands/measure-memory-args.js +26 -14
  129. package/lib/commands/measure-memory-args.js.map +1 -1
  130. package/lib/commands/measure-memory-driver.js +5 -3
  131. package/lib/commands/measure-memory-driver.js.map +1 -1
  132. package/lib/commands/measure-memory.d.ts +1 -1
  133. package/lib/commands/measure-memory.d.ts.map +1 -1
  134. package/lib/commands/measure-memory.js +6 -3
  135. package/lib/commands/measure-memory.js.map +1 -1
  136. package/lib/commands/message-catalogue-args.d.ts +16 -0
  137. package/lib/commands/message-catalogue-args.d.ts.map +1 -0
  138. package/lib/commands/message-catalogue-args.js +53 -0
  139. package/lib/commands/message-catalogue-args.js.map +1 -0
  140. package/lib/commands/message-catalogue.d.ts +21 -0
  141. package/lib/commands/message-catalogue.d.ts.map +1 -0
  142. package/lib/commands/message-catalogue.js +48 -0
  143. package/lib/commands/message-catalogue.js.map +1 -0
  144. package/lib/commands/model-docs-args.d.ts +4 -3
  145. package/lib/commands/model-docs-args.d.ts.map +1 -1
  146. package/lib/commands/model-docs-args.js +13 -11
  147. package/lib/commands/model-docs-args.js.map +1 -1
  148. package/lib/commands/model-docs-driver.js +2 -1
  149. package/lib/commands/model-docs-driver.js.map +1 -1
  150. package/lib/commands/model-docs.js +1 -1
  151. package/lib/commands/model-docs.js.map +1 -1
  152. package/lib/commands/projects-args.d.ts.map +1 -1
  153. package/lib/commands/projects-args.js +5 -5
  154. package/lib/commands/projects-args.js.map +1 -1
  155. package/lib/commands/projects.d.ts +3 -4
  156. package/lib/commands/projects.d.ts.map +1 -1
  157. package/lib/commands/projects.js +2 -2
  158. package/lib/commands/projects.js.map +1 -1
  159. package/lib/commands/query-args.d.ts.map +1 -1
  160. package/lib/commands/query-args.js +6 -5
  161. package/lib/commands/query-args.js.map +1 -1
  162. package/lib/commands/query.d.ts +6 -5
  163. package/lib/commands/query.d.ts.map +1 -1
  164. package/lib/commands/query.js +5 -4
  165. package/lib/commands/query.js.map +1 -1
  166. package/lib/commands/reflect-args.d.ts +3 -2
  167. package/lib/commands/reflect-args.d.ts.map +1 -1
  168. package/lib/commands/reflect-args.js +14 -11
  169. package/lib/commands/reflect-args.js.map +1 -1
  170. package/lib/commands/reflect-driver.js +2 -1
  171. package/lib/commands/reflect-driver.js.map +1 -1
  172. package/lib/commands/reflect-report.js.map +1 -1
  173. package/lib/commands/reflect.js +1 -1
  174. package/lib/commands/reflect.js.map +1 -1
  175. package/lib/commands/save-args.d.ts.map +1 -1
  176. package/lib/commands/save-args.js +7 -4
  177. package/lib/commands/save-args.js.map +1 -1
  178. package/lib/commands/save.d.ts +8 -4
  179. package/lib/commands/save.d.ts.map +1 -1
  180. package/lib/commands/save.js +12 -23
  181. package/lib/commands/save.js.map +1 -1
  182. package/lib/commands/skills.d.ts +22 -0
  183. package/lib/commands/skills.d.ts.map +1 -0
  184. package/lib/commands/skills.js +129 -0
  185. package/lib/commands/skills.js.map +1 -0
  186. package/lib/commands/validate-args.d.ts +3 -2
  187. package/lib/commands/validate-args.d.ts.map +1 -1
  188. package/lib/commands/validate-args.js +14 -11
  189. package/lib/commands/validate-args.js.map +1 -1
  190. package/lib/commands/validate-driver.js +2 -1
  191. package/lib/commands/validate-driver.js.map +1 -1
  192. package/lib/commands/validate-report.js.map +1 -1
  193. package/lib/commands/validate.js +1 -1
  194. package/lib/commands/validate.js.map +1 -1
  195. package/lib/commands/watch-args.d.ts.map +1 -1
  196. package/lib/commands/watch-args.js +6 -4
  197. package/lib/commands/watch-args.js.map +1 -1
  198. package/lib/commands/watch.d.ts +3 -4
  199. package/lib/commands/watch.d.ts.map +1 -1
  200. package/lib/commands/watch.js +5 -2
  201. package/lib/commands/watch.js.map +1 -1
  202. package/lib/driver-heap.d.ts +52 -0
  203. package/lib/driver-heap.d.ts.map +1 -0
  204. package/lib/driver-heap.js +51 -0
  205. package/lib/driver-heap.js.map +1 -0
  206. package/lib/index.d.ts +3 -0
  207. package/lib/index.d.ts.map +1 -1
  208. package/lib/index.js +3 -0
  209. package/lib/index.js.map +1 -1
  210. package/lib/log-level.d.ts +21 -11
  211. package/lib/log-level.d.ts.map +1 -1
  212. package/lib/log-level.js +25 -14
  213. package/lib/log-level.js.map +1 -1
  214. package/lib/spawn-data-server.d.ts +9 -4
  215. package/lib/spawn-data-server.d.ts.map +1 -1
  216. package/lib/spawn-data-server.js +5 -4
  217. package/lib/spawn-data-server.js.map +1 -1
  218. package/lib/stderr-connection-logger.d.ts +12 -0
  219. package/lib/stderr-connection-logger.d.ts.map +1 -0
  220. package/lib/stderr-connection-logger.js +16 -0
  221. package/lib/stderr-connection-logger.js.map +1 -0
  222. package/lib/testing/echo-server.js +9 -1
  223. package/lib/testing/echo-server.js.map +1 -1
  224. package/package.json +99 -41
  225. package/src/cli.ts +11 -2
  226. package/src/commands/analyze-heap-args.ts +1 -2
  227. package/src/commands/analyze-heap.ts +4 -1
  228. package/src/commands/ast-ground-truth-args.ts +16 -13
  229. package/src/commands/ast-ground-truth-driver.ts +4 -2
  230. package/src/commands/ast-ground-truth.ts +1 -1
  231. package/src/commands/check-skills-args.ts +70 -0
  232. package/src/commands/client-session.ts +33 -0
  233. package/src/commands/create-args.ts +68 -0
  234. package/src/commands/create.ts +83 -0
  235. package/src/commands/delete-args.ts +64 -0
  236. package/src/commands/delete.ts +61 -0
  237. package/src/commands/generate-ast-builder.ts +2 -12
  238. package/src/commands/generate-languages.ts +132 -0
  239. package/src/commands/generate-transfer-builder.ts +101 -0
  240. package/src/commands/generate-transfer-model-args.ts +20 -5
  241. package/src/commands/generate-transfer-model-config.ts +8 -3
  242. package/src/commands/generate-transfer-model.ts +297 -66
  243. package/src/commands/generated-module-path.ts +22 -0
  244. package/src/commands/harness-args.ts +163 -33
  245. package/src/commands/headless-harness.ts +89 -28
  246. package/src/commands/init-args.ts +135 -35
  247. package/src/commands/init-hosts.ts +51 -0
  248. package/src/commands/init-prompt.ts +5 -6
  249. package/src/commands/init-skills.ts +129 -0
  250. package/src/commands/init-templates.ts +3300 -785
  251. package/src/commands/init-wizard.ts +97 -32
  252. package/src/commands/init-workspace.ts +31 -16
  253. package/src/commands/init.ts +311 -65
  254. package/src/commands/kebab.ts +17 -0
  255. package/src/commands/lint-grammar-args.ts +18 -14
  256. package/src/commands/lint-grammar-driver.ts +2 -1
  257. package/src/commands/lint-grammar.ts +1 -1
  258. package/src/commands/measure-memory-args.ts +31 -17
  259. package/src/commands/measure-memory-driver.ts +5 -3
  260. package/src/commands/measure-memory.ts +6 -3
  261. package/src/commands/message-catalogue-args.ts +55 -0
  262. package/src/commands/message-catalogue.ts +56 -0
  263. package/src/commands/model-docs-args.ts +17 -14
  264. package/src/commands/model-docs-driver.ts +2 -1
  265. package/src/commands/model-docs.ts +1 -1
  266. package/src/commands/projects-args.ts +5 -4
  267. package/src/commands/projects.ts +4 -6
  268. package/src/commands/query-args.ts +6 -4
  269. package/src/commands/query.ts +9 -9
  270. package/src/commands/reflect-args.ts +18 -14
  271. package/src/commands/reflect-driver.ts +2 -1
  272. package/src/commands/reflect.ts +1 -1
  273. package/src/commands/save-args.ts +7 -3
  274. package/src/commands/save.ts +24 -27
  275. package/src/commands/skills.ts +146 -0
  276. package/src/commands/validate-args.ts +18 -14
  277. package/src/commands/validate-driver.ts +2 -1
  278. package/src/commands/validate.ts +1 -1
  279. package/src/commands/watch-args.ts +6 -3
  280. package/src/commands/watch.ts +7 -6
  281. package/src/driver-heap.ts +65 -0
  282. package/src/index.ts +3 -0
  283. package/src/log-level.ts +42 -14
  284. package/src/spawn-data-server.ts +17 -5
  285. package/src/stderr-connection-logger.ts +18 -0
  286. package/src/testing/echo-server.ts +11 -2
  287. package/templates/client/gitignore +3 -0
  288. package/templates/client/src/__GRAMMAR_ID__-diagram-module.ts +82 -0
  289. package/templates/editorconfig +15 -0
  290. package/templates/gitignore +1 -0
  291. package/templates/host-browser/esbuild.mjs +82 -0
  292. package/templates/host-browser/gitignore +4 -0
  293. package/templates/host-browser/hydranium-mark.svg +40 -0
  294. package/templates/host-browser/index.html +287 -0
  295. package/templates/host-browser/playwright.config.mts +24 -0
  296. package/templates/host-browser/src/data-status.ts +15 -0
  297. package/templates/host-browser/src/diagram-save.ts +60 -0
  298. package/templates/host-browser/src/diagram.ts +121 -0
  299. package/templates/host-browser/src/editor.ts +116 -0
  300. package/templates/host-browser/src/log.ts +14 -0
  301. package/templates/host-browser/src/monaco-editor-core-worker.d.ts +7 -0
  302. package/templates/host-browser/src/monaco-editor-worker.ts +10 -0
  303. package/templates/host-browser/src/posix-path-shim.ts +23 -0
  304. package/templates/host-browser/src/shown-file.ts +61 -0
  305. package/templates/host-browser/src/workspace.ts +5 -0
  306. package/templates/host-browser/tsconfig.e2e.json +16 -0
  307. package/templates/host-browser/tsconfig.page.json +16 -0
  308. package/templates/host-browser/tsconfig.worker.json +16 -0
  309. package/templates/host-theia-browser/esbuild.mjs +24 -0
  310. package/templates/host-theia-browser/gitignore +9 -0
  311. package/templates/host-theia-browser/playwright.config.mts +42 -0
  312. package/templates/host-theia-browser/start.mjs +50 -0
  313. package/templates/host-theia-browser/tsconfig.e2e.json +16 -0
  314. package/templates/host-theia-electron/esbuild.mjs +27 -0
  315. package/templates/host-theia-electron/gitignore +8 -0
  316. package/templates/host-theia-electron/playwright.config.mts +12 -0
  317. package/templates/host-theia-electron/start.mjs +47 -0
  318. package/templates/host-theia-electron/tsconfig.e2e.json +16 -0
  319. package/templates/host-vscode/esbuild.mjs +38 -0
  320. package/templates/host-vscode/gitignore +7 -0
  321. package/templates/host-vscode/playwright.config.mts +14 -0
  322. package/templates/host-vscode/src/__GRAMMAR_ID__-diagram-editor.ts +19 -0
  323. package/templates/host-vscode/src/show-model-command.ts +24 -0
  324. package/templates/host-vscode/src/webview/__GRAMMAR_ID__-diagram.ts +18 -0
  325. package/templates/host-vscode/src/webview/diagram.css +40 -0
  326. package/templates/host-vscode/start.mjs +22 -0
  327. package/templates/host-vscode/test/content-server.cjs +40 -0
  328. package/templates/host-vscode/test/install-vscode.mts +21 -0
  329. package/templates/host-vscode/test/virtual-documents.spec.mts +28 -0
  330. package/templates/host-vscode/test/vscode-version.mts +10 -0
  331. package/templates/host-vscode/tsconfig.e2e.json +17 -0
  332. package/templates/host-vscode/tsconfig.json +19 -0
  333. package/templates/host-vscode/tsconfig.webview.json +17 -0
  334. package/templates/oxlintrc.json +4 -0
  335. package/templates/protocol/gitignore +3 -0
  336. package/templates/protocol/src/__GRAMMAR_ID__-diagram-types.ts +47 -0
  337. package/templates/server/gitignore +6 -0
  338. package/templates/server/src/glsp/__GRAMMAR_ID__/create-node-operation-handler.ts +62 -0
  339. package/templates/server/src/glsp/__GRAMMAR_ID__/delete-operation-handler.ts +63 -0
  340. package/templates/server/src/glsp/__GRAMMAR_ID__/gmodel-factory.ts +144 -0
  341. package/templates/server/src/glsp/__GRAMMAR_ID__/state.ts +18 -0
  342. package/templates/server/src/glsp/__GRAMMAR_ID__/storage.ts +16 -0
  343. package/templates/server/src/glsp/__GRAMMAR_ID__/submission-handler.ts +24 -0
  344. package/templates/server/src/grammar/common.langium +12 -0
  345. package/templates/server/src/language-server/__GRAMMAR_ID__-semantic-tokens.ts +10 -0
  346. package/templates/server/src/language-server/__GRAMMAR_ID__-serializer.ts +53 -0
  347. package/templates/server/src/language-server/__GRAMMAR_ID__-validation.ts +30 -0
  348. package/templates/server/src/language-server/ast.ts +23 -0
  349. package/templates/server/src/node/services.ts +16 -0
  350. package/templates/server/test/__GRAMMAR_ID__-diagram.test.ts +403 -0
  351. package/templates/server/test/__GRAMMAR_ID__-semantic-tokens.test.ts +34 -0
  352. package/templates/server/test/tsconfig.json +4 -0
  353. package/templates/server/tsconfig.test.json +10 -0
  354. package/templates/server/vitest.config.ts +14 -0
  355. package/templates/theia/gitignore +3 -0
  356. package/templates/theia/src/browser/__GRAMMAR_ID__-diagram-frontend-module.ts +65 -0
  357. package/templates/theia/src/browser/__PROJECT_ID__-connection-preload-module.ts +15 -0
  358. package/templates/theia/src/browser/__PROJECT_ID__-data-connection.ts +15 -0
  359. package/templates/theia/src/browser/__PROJECT_ID__-data-port.ts +11 -0
  360. package/templates/theia/src/browser/__PROJECT_ID__-glsp-client-contribution.ts +13 -0
  361. package/templates/theia/src/browser/__PROJECT_ID__-show-model-command.ts +51 -0
  362. package/templates/theia/src/common/__PROJECT_ID__-glsp-contribution.ts +3 -0
  363. package/templates/theia/src/node/__PROJECT_ID__-connection-backend-module.ts +12 -0
  364. package/templates/theia/src/node/__PROJECT_ID__-data-backend-module.ts +15 -0
  365. package/templates/theia/src/node/__PROJECT_ID__-glsp-backend-module.ts +16 -0
  366. package/templates/theia/style/diagram.css +20 -0
  367. package/templates/theia/tsconfig.json +24 -0
  368. package/templates/vscode-servers/gitignore +4 -0
  369. package/templates/vscode-servers/tsconfig.json +19 -0
  370. package/templates/workspace/nodes.__EXTENSION__ +5 -0
  371. package/templates/workspace/references.__EXTENSION__ +2 -0
@@ -26,11 +26,14 @@
26
26
  * association is gone.
27
27
  */
28
28
 
29
+ import * as path from 'node:path';
29
30
  import { assertRequired, exitWithUsage, helpRequested, printHelp, type UsageError } from './harness-args.js';
30
- import { isNonEmptyDir, runInit, type InitHead } from './init.js';
31
+ import { isNonEmptyDir, runInit, validateInitInstallation, type InitHead } from './init.js';
32
+ import type { InitHost } from './init-hosts.js';
31
33
  import { createClackPrompt } from './init-prompt.js';
32
34
  import { runInitWizard } from './init-wizard.js';
33
35
  import { createNodeWorkspaceProbe, detectWorkspace } from './init-workspace.js';
36
+ import { installSkills, offerSkills, parseSkillInstallation, SKILLS_INSTALLER } from './init-skills.js';
34
37
 
35
38
  /** One grammar as the command line collected it, before any derivation. */
36
39
  export interface ParsedInitGrammar {
@@ -45,7 +48,11 @@ export interface ParsedInitArgs {
45
48
  targetDir?: string;
46
49
  name?: string;
47
50
  force: boolean;
51
+ install: boolean;
52
+ skills?: string;
53
+ agents?: string;
48
54
  heads?: InitHead[];
55
+ hosts?: InitHost[];
49
56
  monorepo: boolean;
50
57
  scope?: string;
51
58
  public: boolean;
@@ -62,7 +69,11 @@ export interface ParsedInitArgs {
62
69
  export const INIT_FLAGS: readonly string[] = [
63
70
  '--name',
64
71
  '--heads',
72
+ '--hosts',
65
73
  '--force',
74
+ '--install',
75
+ '--skills',
76
+ '--agents',
66
77
  '--monorepo',
67
78
  '--scope',
68
79
  '--public',
@@ -76,7 +87,17 @@ export const INIT_FLAGS: readonly string[] = [
76
87
  * The subset that takes a value, so `--help` in a value position reads as data.
77
88
  * The rest are presence-only.
78
89
  */
79
- export const INIT_VALUE_FLAGS: readonly string[] = ['--name', '--heads', '--scope', '--grammar', '--extensions', '--language-id'];
90
+ export const INIT_VALUE_FLAGS: readonly string[] = [
91
+ '--skills',
92
+ '--agents',
93
+ '--name',
94
+ '--heads',
95
+ '--hosts',
96
+ '--scope',
97
+ '--grammar',
98
+ '--extensions',
99
+ '--language-id'
100
+ ];
80
101
 
81
102
  /**
82
103
  * Parse `init`'s flags without deciding whether the result is complete.
@@ -93,7 +114,11 @@ export function parseInitArgs(args: string[], onError: UsageError = exitWithUsag
93
114
  let targetDir: string | undefined;
94
115
  let name: string | undefined;
95
116
  let force = false;
117
+ let install = false;
118
+ let skills: string | undefined;
119
+ let agents: string | undefined;
96
120
  let heads: InitHead[] | undefined;
121
+ let hosts: InitHost[] | undefined;
97
122
  let monorepo = false;
98
123
  let scope: string | undefined;
99
124
  let isPublic = false;
@@ -119,6 +144,12 @@ export function parseInitArgs(args: string[], onError: UsageError = exitWithUsag
119
144
  return current;
120
145
  };
121
146
  switch (flag) {
147
+ case '--skills':
148
+ skills = next();
149
+ break;
150
+ case '--agents':
151
+ agents = next();
152
+ break;
122
153
  case '--name':
123
154
  name = next();
124
155
  break;
@@ -137,14 +168,20 @@ export function parseInitArgs(args: string[], onError: UsageError = exitWithUsag
137
168
  scoped().diagram = true;
138
169
  break;
139
170
  case '--heads': {
140
- // Validated in `resolveInitComposition`, which owns the rule that
141
- // `lsp` is mandatory; the cast only gets the strings that far.
171
+ // Validated in `resolveInitComposition`; the cast only gets the
172
+ // strings that far.
142
173
  heads = next().split(',') as InitHead[];
143
174
  break;
144
175
  }
176
+ case '--hosts':
177
+ hosts = next().split(',') as InitHost[];
178
+ break;
145
179
  case '--force':
146
180
  force = true;
147
181
  break;
182
+ case '--install':
183
+ install = true;
184
+ break;
148
185
  case '--monorepo':
149
186
  monorepo = true;
150
187
  break;
@@ -169,7 +206,7 @@ export function parseInitArgs(args: string[], onError: UsageError = exitWithUsag
169
206
  }
170
207
  }
171
208
  }
172
- return { targetDir, name, force, heads, monorepo, scope, public: isPublic, grammars };
209
+ return { targetDir, name, force, install, skills, agents, heads, hosts, monorepo, scope, public: isPublic, grammars };
173
210
  }
174
211
 
175
212
  /**
@@ -180,46 +217,87 @@ export function parseInitArgs(args: string[], onError: UsageError = exitWithUsag
180
217
  * authoritative, and a flag missing from it is a capability nobody finds.
181
218
  */
182
219
  export const INIT_HELP: readonly string[] = [
183
- 'Usage: hydranium-cli init <target-dir> --name <Name> [--heads <list>] [--force]',
184
- ' [--monorepo] [--scope <@scope>] [--public]',
220
+ 'Usage: hydranium-cli init <target-dir> --name <Name> [--heads <list>]',
221
+ ' [--hosts <list>] [--force] [--monorepo]',
222
+ ' [--scope <@scope>] [--public] [--install]',
185
223
  ' ( --grammar <Name> [--extensions <list>]',
186
224
  ' [--language-id <id>] [--diagram] )...',
187
225
  '',
188
- 'Scaffold a new Hydranium language project end-to-end: a starter grammar per',
189
- '--grammar, the `create<Name>Services` DI wiring, an LSP + data-server launch,',
190
- 'langium-config, package.json, and build scripts. Does NOT run `npm install` or',
191
- '`langium generate` — those are printed as next steps. Refuses a non-empty',
192
- 'directory without --force.',
226
+ 'Scaffold a new Hydranium language project end-to-end: its packages and a',
227
+ 'starter workspace, each in its own directory. server/ holds a starter grammar',
228
+ 'per --grammar, the `create<Name>Services` DI wiring, a launch of every head',
229
+ 'and build scripts; protocol/ holds what the server and its clients both',
230
+ 'import; client/, with a diagram, holds its host-neutral client side;',
231
+ 'host-<name>/ holds each --hosts application, vscode-servers/ the server',
232
+ 'launch of the VS Code and Theia ones, and theia/ the Theia extension;',
233
+ 'workspace/ holds two starter model files per grammar. A standalone project',
234
+ 'also gets a root manifest naming the packages as npm workspaces.',
235
+ 'Stays offline unless --install or --skills is requested. With --install,',
236
+ 'runs `npm install` after writing the scaffold. Building remains a next step.',
237
+ 'Refuses a non-empty directory',
238
+ 'without --force.',
193
239
  '',
194
240
  'Run it with no --name on a terminal to be prompted instead. The wizard echoes',
195
241
  'the command it composed before running it, so every answer is reproducible as',
196
242
  'flags. Without a terminal a missing --name stays an error, so CI never hangs.',
243
+ 'For a standalone project, the wizard ends by offering npm install unless',
244
+ '--install already requested it.',
245
+ 'After a successful scaffold, the wizard offers coding-agent skills separately.',
246
+ 'Skipping or cancelling that offer leaves the scaffold intact.',
197
247
  '',
198
248
  'Project options (position-free):',
199
- ' <target-dir> Directory to scaffold into (required).',
249
+ ' <target-dir> The project directory to scaffold into (required).',
200
250
  ' --name <Name> PascalCase PROJECT name; drives the services and the',
201
251
  ' Langium projectName, i.e. the shared generated symbols',
202
252
  ' (<Name>AstReflection, <Name>GeneratedSharedModule) (required).',
203
- ' --heads <list> Comma-separated protocol heads: lsp, data, glsp.',
204
- ' `lsp` is mandatory — it owns the workspace, the build',
205
- ' pipeline and the shared tier the others read through.',
206
- ' The emitted dependencies, main.ts and module bindings',
207
- ' all follow this set. Default: lsp,data.',
253
+ ' --heads <list> Comma-separated protocol heads: lsp, data, glsp, any',
254
+ ' non-empty set. Without lsp, main.ts serves the socket',
255
+ ' heads from a workspace path it is given and prints',
256
+ ' their ports. The emitted dependencies, main.ts and',
257
+ ' module bindings all follow this set. Default: lsp,data.',
258
+ ' --hosts <list> Comma-separated host applications to emit around the',
259
+ ' heads: browser, a page running every head in a web',
260
+ ' worker, which needs lsp or glsp; without lsp it has',
261
+ ' no editor and saves through the diagram. vscode, a',
262
+ ' VS Code extension and the servers-only extension it',
263
+ ' starts the server through, which needs lsp.',
264
+ ' theia-browser, a Theia browser application, its',
265
+ ' Theia extension and the servers-only extension it',
266
+ ' sideloads, which needs lsp. theia-electron, the',
267
+ ' same in a Theia Electron application. Without',
268
+ ' --hosts, the server with its Node entry points, and',
269
+ ' with glsp the client/ package a host mounts.',
208
270
  ' --force Scaffold into a non-empty directory anyway.',
209
- ' --monorepo Scaffold a member of the surrounding npm workspace:',
210
- ' tsconfig extends the root config that actually carries',
211
- ' compilerOptions, .gitignore is left to the root, and the',
212
- ' scripts address the package by --prefix. Errors when no',
213
- ' ancestor declares `workspaces`. Never writes outside the',
214
- ' target — the root `workspaces` entry is printed, not added.',
215
- ' --scope <@scope> npm scope for the package name, e.g. @acme. Not inferred:',
271
+ ' --skills <names> After scaffolding, install named skills: hydranium-profiling,',
272
+ ` langium. Requires --agents. Downloads with npx ${SKILLS_INSTALLER} add`,
273
+ ' --copy, preserving unrelated skills and lock entries.',
274
+ ' With --monorepo, skills are written at the workspace root.',
275
+ ' --agents <names> Comma-separated agents for --skills: codex, claude-code,',
276
+ ' cursor, github-copilot, opencode.',
277
+ ' --install Run npm install in the scaffold, with lifecycle scripts',
278
+ ' and network access. Cannot be combined with --monorepo:',
279
+ ' its parent manifest needs manual edits first.',
280
+ ' --monorepo Scaffold the packages as members of the surrounding npm',
281
+ ' workspace, with no root of their own: each tsconfig',
282
+ ' extends the root config that actually carries',
283
+ ' compilerOptions, and the scripts address the server by',
284
+ ' --prefix. Errors when no ancestor declares `workspaces`.',
285
+ ' Scaffold files stay inside the target; optional skills',
286
+ ' go at the workspace root. The root `workspaces`',
287
+ ' entries and dependency pins are printed, not added.',
288
+ ' --scope <@scope> npm scope for the package names, e.g. @acme. Not inferred:',
216
289
  ' a root manifest is usually named for the repo, not the',
217
290
  ' scope. The wizard offers the siblings’ scope as a default.',
218
- ' --public Omit "private": true, so the package can be published.',
219
- ' The scaffold emits it by default, because the manifest',
220
- ' it also emits declares license "UNLICENSED": a package',
221
- ' granting no rights on a public registry contradicts',
222
- ' itself. Pass this once the project has picked a licence.',
291
+ ' The VS Code extensions stay unscoped, since vsce',
292
+ ' refuses a scoped extension name.',
293
+ ' --public Omit "private": true from the server, protocol,',
294
+ ' client and Theia extension packages, so they can be',
295
+ ' published together; a host package stays private.',
296
+ ' The scaffold emits it by default, because the',
297
+ ' manifests also declare license "UNLICENSED": a',
298
+ ' package granting no rights on a public registry',
299
+ ' contradicts itself. Pass this once the project has',
300
+ ' picked a licence.',
223
301
  '',
224
302
  'Grammar options — each applies to the PRECEDING --grammar:',
225
303
  ' --grammar <Name> PascalCase GRAMMAR name; drives the `grammar X` declaration',
@@ -233,8 +311,12 @@ export const INIT_HELP: readonly string[] = [
233
311
  ' (default: <project-id>-<grammar-id>).',
234
312
  ' --diagram Scaffold a GLSP diagram for that grammar. Requires',
235
313
  ' `glsp` in --heads. Derived when there is exactly one',
236
- ' grammar; required when there are several, because a',
237
- ' diagram type binds exactly one grammar.',
314
+ ' grammar; required when there are several, because the',
315
+ ' scaffolded diagram is typed over one grammar’s model.',
316
+ '',
317
+ 'Example — one grammar, three heads, in a browser page:',
318
+ ' hydranium-cli init ./bookstore --name Bookstore --heads lsp,data,glsp \\',
319
+ ' --hosts browser',
238
320
  '',
239
321
  'Example — three grammars, one with a differing extension, three heads:',
240
322
  ' hydranium-cli init ./order-flow --name OrderFlow --heads lsp,data,glsp \\',
@@ -247,27 +329,45 @@ export async function runInitCommand(args: string[]): Promise<void> {
247
329
  printHelp(INIT_HELP);
248
330
  return;
249
331
  }
250
- const parsed = parseInitArgs(args);
332
+ let parsed = parseInitArgs(args);
333
+ validateInitInstallation(parsed);
334
+ let selection = parseSkillInstallation(parsed.skills, parsed.agents);
335
+ let prompt: Awaited<ReturnType<typeof createClackPrompt>> | undefined;
251
336
  // The wizard's entry point: no `--name` on an interactive terminal. Safe
252
337
  // because that combination has no non-wizard meaning, and gated on a TTY
253
338
  // because a non-interactive caller must keep failing fast — a prompt in CI
254
339
  // hangs the job instead of reporting the missing flag.
255
340
  if (parsed.name === undefined && process.stdin.isTTY && process.stdout.isTTY) {
256
- const prompt = await createClackPrompt();
341
+ prompt = await createClackPrompt();
257
342
  const argv = await runInitWizard(prompt, targetDir => detectWorkspace(targetDir, createNodeWorkspaceProbe()), {
258
343
  targetDir: parsed.targetDir,
344
+ install: parsed.install,
345
+ skills: parsed.skills,
346
+ agents: parsed.agents,
259
347
  isOccupied: isNonEmptyDir
260
348
  });
261
- return runInitCommand(argv);
349
+ parsed = parseInitArgs(argv);
262
350
  }
263
351
  runInit({
264
352
  targetDir: assertRequired(parsed.targetDir, '<target-dir>', 'init'),
265
353
  name: assertRequired(parsed.name, '--name', 'init'),
266
354
  grammars: parsed.grammars,
267
355
  heads: parsed.heads,
356
+ hosts: parsed.hosts,
268
357
  force: parsed.force,
358
+ install: parsed.install,
269
359
  monorepo: parsed.monorepo,
270
360
  scope: parsed.scope,
271
361
  public: parsed.public
272
362
  });
363
+ const target = path.resolve(parsed.targetDir!);
364
+ const project = parsed.monorepo ? detectWorkspace(target, createNodeWorkspaceProbe())!.rootDir : target;
365
+ if (selection === undefined && prompt !== undefined) {
366
+ selection = await offerSkills(prompt, project);
367
+ }
368
+ if (selection !== undefined) {
369
+ installSkills(project, path.join(target, 'server'), selection);
370
+ } else {
371
+ process.stdout.write('\nOptional agent skills: see the Work with coding-agent skills guide.\n');
372
+ }
273
373
  }
@@ -0,0 +1,51 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 EclipseSource and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the MIT License which is available in the project root.
6
+ *
7
+ * SPDX-License-Identifier: MIT
8
+ ********************************************************************************/
9
+
10
+ /**
11
+ * The host applications `init` can emit around the server: each holds the
12
+ * clients of the heads it runs, in a sibling package of its own.
13
+ */
14
+
15
+ import type { InitHead } from './init.js';
16
+
17
+ /** The hosts a scaffold can emit, in the order a workspace lists them. */
18
+ export const INIT_HOSTS = ['browser', 'vscode', 'theia-browser', 'theia-electron'] as const;
19
+
20
+ /** One host application — see {@link INIT_HOSTS}. */
21
+ export type InitHost = (typeof INIT_HOSTS)[number];
22
+
23
+ /**
24
+ * The heads a host needs at least one of: those whose client edits and saves
25
+ * the files. The browser page has no filesystem of its own, so it saves through
26
+ * the LSP head's editor or the GLSP head's diagram. VS Code and Theia own the
27
+ * files and reach the server through a language client, so they need the LSP
28
+ * head. Every other head is optional, and a head the host does not know is left
29
+ * unused.
30
+ */
31
+ const EDITING_HEADS: Record<InitHost, readonly InitHead[]> = {
32
+ browser: ['lsp', 'glsp'],
33
+ vscode: ['lsp'],
34
+ 'theia-browser': ['lsp'],
35
+ 'theia-electron': ['lsp']
36
+ };
37
+
38
+ /** True for a string naming one of {@link INIT_HOSTS}. */
39
+ export function isInitHost(value: string): value is InitHost {
40
+ return (INIT_HOSTS as readonly string[]).includes(value);
41
+ }
42
+
43
+ /** True for a host that is a Theia application, which runs the Theia extension. */
44
+ export function isTheiaHost(host: InitHost): boolean {
45
+ return host === 'theia-browser' || host === 'theia-electron';
46
+ }
47
+
48
+ /** The heads {@link host} needs at least one of in the composition. */
49
+ export function editingHeads(host: InitHost): readonly InitHead[] {
50
+ return EDITING_HEADS[host];
51
+ }
@@ -66,7 +66,7 @@ export interface PromptPort {
66
66
  readonly choices: ReadonlyArray<PromptChoice<Value>>;
67
67
  readonly initialValue?: Value;
68
68
  }) => Promise<Value>;
69
- /** Ask for any number of several choices, including none. */
69
+ /** Ask for at least one of several choices. */
70
70
  readonly multiselect: <Value extends string>(options: {
71
71
  readonly message: string;
72
72
  readonly choices: ReadonlyArray<PromptChoice<Value>>;
@@ -78,8 +78,9 @@ export interface PromptPort {
78
78
  readonly outro: (message: string) => void;
79
79
  }
80
80
 
81
- /** The optional heads, as a checkbox list. `lsp` is not offered — see `askHeads`. */
82
- export const OPTIONAL_HEAD_CHOICES: ReadonlyArray<PromptChoice<Exclude<InitHead, 'lsp'>>> = [
81
+ /** The heads, as a checkbox list. */
82
+ export const HEAD_CHOICES: ReadonlyArray<PromptChoice<InitHead>> = [
83
+ { value: 'lsp', label: 'lsp', hint: 'text editing in an LSP client' },
83
84
  { value: 'data', label: 'data', hint: 'typed JSON-RPC for forms, trees and code-gen' },
84
85
  { value: 'glsp', label: 'glsp', hint: 'graphical editing; adds a scaffolded diagram' }
85
86
  ];
@@ -138,9 +139,7 @@ export async function createClackPrompt(): Promise<PromptPort> {
138
139
  message: options.message,
139
140
  options: toOptions(options.choices),
140
141
  initialValues: options.initialValues ? [...options.initialValues] : [],
141
- // Legal and meaningful: an `lsp`-only project is a plain LSP
142
- // server, so an empty selection must not be rejected.
143
- required: false
142
+ required: true
144
143
  })
145
144
  ),
146
145
  confirm: async options => unwrap(await clack.confirm({ message: options.message, initialValue: options.initialValue })),
@@ -0,0 +1,129 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 EclipseSource and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the MIT License which is available in the project root.
6
+ *
7
+ * SPDX-License-Identifier: MIT
8
+ ********************************************************************************/
9
+
10
+ import { spawnSync } from 'node:child_process';
11
+ import * as path from 'node:path';
12
+ import { InitWizardCancelled, type PromptPort } from './init-prompt.js';
13
+ import { checkSkills } from './skills.js';
14
+
15
+ export const SKILLS_INSTALLER = 'skills@1.7.6';
16
+
17
+ export const ADOPTER_SKILLS = {
18
+ 'hydranium-profiling': { source: 'eclipse-emfcloud/hydranium', label: 'Hydranium profiling' },
19
+ langium: { source: 'eclipse-langium/langium-ai', label: 'Langium grammar and runtime' }
20
+ } as const;
21
+
22
+ export type AdopterSkill = keyof typeof ADOPTER_SKILLS;
23
+
24
+ export const SKILL_AGENTS = {
25
+ codex: 'Codex',
26
+ 'claude-code': 'Claude Code',
27
+ cursor: 'Cursor',
28
+ 'github-copilot': 'GitHub Copilot',
29
+ opencode: 'OpenCode'
30
+ } as const;
31
+
32
+ export type SkillAgent = keyof typeof SKILL_AGENTS;
33
+
34
+ export interface SkillInstallation {
35
+ readonly skills: readonly AdopterSkill[];
36
+ readonly agents: readonly SkillAgent[];
37
+ }
38
+
39
+ /** Validate before scaffolding so a misspelling cannot leave a half-completed command. */
40
+ export function parseSkillInstallation(skills?: string, agents?: string): SkillInstallation | undefined {
41
+ if (skills === undefined && agents === undefined) {
42
+ return undefined;
43
+ }
44
+ if (!skills || !agents) {
45
+ throw new Error('--skills and --agents must be supplied together.');
46
+ }
47
+ const selectedSkills = skills.split(',');
48
+ const selectedAgents = agents.split(',');
49
+ for (const name of selectedSkills) {
50
+ if (!Object.hasOwn(ADOPTER_SKILLS, name)) {
51
+ throw new Error(`Unknown skill '${name}'. Choose ${Object.keys(ADOPTER_SKILLS).join(', ')}.`);
52
+ }
53
+ }
54
+ for (const name of selectedAgents) {
55
+ if (!Object.hasOwn(SKILL_AGENTS, name)) {
56
+ throw new Error(`Unknown agent '${name}'. Choose ${Object.keys(SKILL_AGENTS).join(', ')}.`);
57
+ }
58
+ }
59
+ return { skills: [...new Set(selectedSkills)] as AdopterSkill[], agents: [...new Set(selectedAgents)] as SkillAgent[] };
60
+ }
61
+
62
+ export function skillInstallArgs(skill: AdopterSkill, agents: readonly SkillAgent[]): string[] {
63
+ return ['--yes', SKILLS_INSTALLER, 'add', ADOPTER_SKILLS[skill].source, '--skill', skill, '--agent', ...agents, '--copy', '--yes'];
64
+ }
65
+
66
+ /** A failed optional download leaves the scaffold usable and gives an independently runnable retry. */
67
+ export function installSkills(
68
+ project: string,
69
+ from: string,
70
+ selection: SkillInstallation,
71
+ write: (message: string) => void = message => process.stdout.write(message)
72
+ ): void {
73
+ for (const skill of selection.skills) {
74
+ const args = skillInstallArgs(skill, selection.agents);
75
+ write(`\nIn ${project}: npx ${args.join(' ')}\n`);
76
+ try {
77
+ // Only catalogued names reach the Windows shim's shell; paths travel as cwd, never shell text.
78
+ const result = spawnSync(process.platform === 'win32' ? 'npx.cmd' : 'npx', args, {
79
+ cwd: project,
80
+ stdio: 'inherit',
81
+ shell: process.platform === 'win32'
82
+ });
83
+ if (result.signal === 'SIGINT' || result.status === 130) {
84
+ write('Skill installation cancelled. Scaffold kept.\n');
85
+ return;
86
+ }
87
+ if (result.error || result.signal || result.status !== 0) {
88
+ throw result.error ?? new Error(result.signal ?? `exit code ${result.status}`);
89
+ }
90
+ for (const result of checkSkills(project, from, [skill])) {
91
+ write(`${result.status}: ${result.file}: ${result.detail}\n`);
92
+ }
93
+ } catch (error) {
94
+ write(`Skill installation failed (${error instanceof Error ? error.message : String(error)}). Scaffold kept.\n`);
95
+ write(`Retry in ${project}: npx ${args.join(' ')}\n`);
96
+ }
97
+ }
98
+ const relative = path.relative(project, from) || '.';
99
+ const quoted = `'${relative.replace(/'/g, "'\\''")}'`;
100
+ write(`Check again after installing or updating dependencies: npx hydranium-cli check-skills --from ${quoted}\n`);
101
+ }
102
+
103
+ /** This prompt runs only after the scaffold succeeds; cancelling it cannot undo the scaffold. */
104
+ export async function offerSkills(prompt: PromptPort, project: string): Promise<SkillInstallation | undefined> {
105
+ try {
106
+ prompt.intro('Optional coding-agent skills');
107
+ if (!(await prompt.confirm({ message: `Install coding-agent skills in ${project}?`, initialValue: false }))) {
108
+ prompt.outro('Skills skipped.');
109
+ return undefined;
110
+ }
111
+ const skills = await prompt.multiselect<AdopterSkill>({
112
+ message: 'Skills to install',
113
+ choices: Object.entries(ADOPTER_SKILLS).map(([value, skill]) => ({ value: value as AdopterSkill, label: skill.label })),
114
+ initialValues: ['hydranium-profiling', 'langium']
115
+ });
116
+ const agents = await prompt.multiselect<SkillAgent>({
117
+ message: 'Coding agents',
118
+ choices: Object.entries(SKILL_AGENTS).map(([value, label]) => ({ value: value as SkillAgent, label }))
119
+ });
120
+ prompt.outro('Installing selected skills as project files. Commit the files and skills-lock.json.');
121
+ return { skills, agents };
122
+ } catch (error) {
123
+ if (error instanceof InitWizardCancelled) {
124
+ prompt.outro('Skills skipped. Scaffold kept.');
125
+ return undefined;
126
+ }
127
+ throw error;
128
+ }
129
+ }