terminal-pilot 0.0.30 → 0.0.32

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 (329) hide show
  1. package/dist/cli.js +1599 -497
  2. package/dist/cli.js.map +4 -4
  3. package/dist/commands/close-session.js +489 -6
  4. package/dist/commands/close-session.js.map +4 -4
  5. package/dist/commands/create-session.js +489 -6
  6. package/dist/commands/create-session.js.map +4 -4
  7. package/dist/commands/fill.js +489 -6
  8. package/dist/commands/fill.js.map +4 -4
  9. package/dist/commands/get-session.js +489 -6
  10. package/dist/commands/get-session.js.map +4 -4
  11. package/dist/commands/index.js +630 -44
  12. package/dist/commands/index.js.map +4 -4
  13. package/dist/commands/install.js +626 -40
  14. package/dist/commands/install.js.map +4 -4
  15. package/dist/commands/installer.js +68 -17
  16. package/dist/commands/installer.js.map +4 -4
  17. package/dist/commands/list-sessions.js +489 -6
  18. package/dist/commands/list-sessions.js.map +4 -4
  19. package/dist/commands/press-key.js +489 -6
  20. package/dist/commands/press-key.js.map +4 -4
  21. package/dist/commands/read-history.js +489 -6
  22. package/dist/commands/read-history.js.map +4 -4
  23. package/dist/commands/read-screen.js +489 -6
  24. package/dist/commands/read-screen.js.map +4 -4
  25. package/dist/commands/resize.js +489 -6
  26. package/dist/commands/resize.js.map +4 -4
  27. package/dist/commands/runtime.js.map +1 -1
  28. package/dist/commands/screenshot.js +489 -6
  29. package/dist/commands/screenshot.js.map +4 -4
  30. package/dist/commands/send-signal.js +489 -6
  31. package/dist/commands/send-signal.js.map +4 -4
  32. package/dist/commands/type.js +489 -6
  33. package/dist/commands/type.js.map +4 -4
  34. package/dist/commands/uninstall.js +554 -20
  35. package/dist/commands/uninstall.js.map +4 -4
  36. package/dist/commands/wait-for-exit.js +489 -6
  37. package/dist/commands/wait-for-exit.js.map +4 -4
  38. package/dist/commands/wait-for.js +489 -6
  39. package/dist/commands/wait-for.js.map +4 -4
  40. package/dist/testing/cli-repl.js +1599 -497
  41. package/dist/testing/cli-repl.js.map +4 -4
  42. package/dist/testing/qa-cli.js +1609 -507
  43. package/dist/testing/qa-cli.js.map +4 -4
  44. package/node_modules/@poe-code/agent-defs/README.md +35 -0
  45. package/node_modules/@poe-code/agent-defs/dist/agents/claude-code.d.ts +2 -0
  46. package/node_modules/@poe-code/agent-defs/dist/agents/claude-code.js +21 -0
  47. package/node_modules/@poe-code/agent-defs/dist/agents/claude-desktop.d.ts +2 -0
  48. package/node_modules/@poe-code/agent-defs/dist/agents/claude-desktop.js +18 -0
  49. package/node_modules/@poe-code/agent-defs/dist/agents/codex.d.ts +2 -0
  50. package/node_modules/@poe-code/agent-defs/dist/agents/codex.js +25 -0
  51. package/node_modules/@poe-code/agent-defs/dist/agents/cursor.d.ts +2 -0
  52. package/node_modules/@poe-code/agent-defs/dist/agents/cursor.js +15 -0
  53. package/node_modules/@poe-code/agent-defs/dist/agents/gemini-cli.d.ts +2 -0
  54. package/node_modules/@poe-code/agent-defs/dist/agents/gemini-cli.js +16 -0
  55. package/node_modules/@poe-code/agent-defs/dist/agents/goose.d.ts +2 -0
  56. package/node_modules/@poe-code/agent-defs/dist/agents/goose.js +16 -0
  57. package/node_modules/@poe-code/agent-defs/dist/agents/index.d.ts +9 -0
  58. package/node_modules/@poe-code/agent-defs/dist/agents/index.js +9 -0
  59. package/node_modules/@poe-code/agent-defs/dist/agents/kimi.d.ts +2 -0
  60. package/node_modules/@poe-code/agent-defs/dist/agents/kimi.js +16 -0
  61. package/node_modules/@poe-code/agent-defs/dist/agents/opencode.d.ts +2 -0
  62. package/node_modules/@poe-code/agent-defs/dist/agents/opencode.js +20 -0
  63. package/node_modules/@poe-code/agent-defs/dist/agents/poe-agent.d.ts +2 -0
  64. package/node_modules/@poe-code/agent-defs/dist/agents/poe-agent.js +14 -0
  65. package/node_modules/@poe-code/agent-defs/dist/index.d.ts +5 -0
  66. package/node_modules/@poe-code/agent-defs/dist/index.js +3 -0
  67. package/node_modules/@poe-code/agent-defs/dist/registry.d.ts +3 -0
  68. package/node_modules/@poe-code/agent-defs/dist/registry.js +45 -0
  69. package/node_modules/@poe-code/agent-defs/dist/specifier.d.ts +7 -0
  70. package/node_modules/@poe-code/agent-defs/dist/specifier.js +40 -0
  71. package/node_modules/@poe-code/agent-defs/dist/types.d.ts +28 -0
  72. package/node_modules/@poe-code/agent-defs/dist/types.js +1 -0
  73. package/node_modules/@poe-code/agent-defs/package.json +20 -0
  74. package/node_modules/@poe-code/agent-skill-config/dist/apply.js +2 -1
  75. package/node_modules/@poe-code/agent-skill-config/dist/bridge-active-skills.d.ts +1 -0
  76. package/node_modules/@poe-code/agent-skill-config/dist/bridge-active-skills.js +37 -18
  77. package/node_modules/@poe-code/agent-skill-config/dist/resolve-skill-reference.js +8 -4
  78. package/node_modules/@poe-code/agent-skill-config/package.json +1 -5
  79. package/node_modules/@poe-code/config-mutations/README.md +55 -0
  80. package/node_modules/@poe-code/config-mutations/dist/error-codes.d.ts +1 -0
  81. package/node_modules/@poe-code/config-mutations/dist/error-codes.js +6 -0
  82. package/node_modules/@poe-code/config-mutations/dist/execution/apply-mutation.d.ts +6 -0
  83. package/node_modules/@poe-code/config-mutations/dist/execution/apply-mutation.js +829 -0
  84. package/node_modules/@poe-code/config-mutations/dist/execution/path-utils.d.ts +17 -0
  85. package/node_modules/@poe-code/config-mutations/dist/execution/path-utils.js +64 -0
  86. package/node_modules/@poe-code/config-mutations/dist/execution/run-mutations.d.ts +7 -0
  87. package/node_modules/@poe-code/config-mutations/dist/execution/run-mutations.js +39 -0
  88. package/node_modules/@poe-code/config-mutations/dist/formats/index.d.ts +13 -0
  89. package/node_modules/@poe-code/config-mutations/dist/formats/index.js +49 -0
  90. package/node_modules/@poe-code/config-mutations/dist/formats/json.d.ts +32 -0
  91. package/node_modules/@poe-code/config-mutations/dist/formats/json.js +171 -0
  92. package/node_modules/@poe-code/config-mutations/dist/formats/object.d.ts +4 -0
  93. package/node_modules/@poe-code/config-mutations/dist/formats/object.js +27 -0
  94. package/node_modules/@poe-code/config-mutations/dist/formats/toml.d.ts +2 -0
  95. package/node_modules/@poe-code/config-mutations/dist/formats/toml.js +75 -0
  96. package/node_modules/@poe-code/config-mutations/dist/formats/yaml.d.ts +2 -0
  97. package/node_modules/@poe-code/config-mutations/dist/formats/yaml.js +76 -0
  98. package/node_modules/@poe-code/config-mutations/dist/fs-utils.d.ts +18 -0
  99. package/node_modules/@poe-code/config-mutations/dist/fs-utils.js +43 -0
  100. package/node_modules/@poe-code/config-mutations/dist/index.d.ts +8 -0
  101. package/node_modules/@poe-code/config-mutations/dist/index.js +8 -0
  102. package/node_modules/@poe-code/config-mutations/dist/mutations/config-mutation.d.ts +47 -0
  103. package/node_modules/@poe-code/config-mutations/dist/mutations/config-mutation.js +34 -0
  104. package/node_modules/@poe-code/config-mutations/dist/mutations/file-mutation.d.ts +62 -0
  105. package/node_modules/@poe-code/config-mutations/dist/mutations/file-mutation.js +55 -0
  106. package/node_modules/@poe-code/config-mutations/dist/mutations/template-mutation.d.ts +40 -0
  107. package/node_modules/@poe-code/config-mutations/dist/mutations/template-mutation.js +32 -0
  108. package/node_modules/@poe-code/config-mutations/dist/template/render.d.ts +6 -0
  109. package/node_modules/@poe-code/config-mutations/dist/template/render.js +8 -0
  110. package/node_modules/@poe-code/config-mutations/dist/testing/format-utils.d.ts +7 -0
  111. package/node_modules/@poe-code/config-mutations/dist/testing/format-utils.js +21 -0
  112. package/node_modules/@poe-code/config-mutations/dist/testing/index.d.ts +3 -0
  113. package/node_modules/@poe-code/config-mutations/dist/testing/index.js +2 -0
  114. package/node_modules/@poe-code/config-mutations/dist/testing/mock-fs.d.ts +25 -0
  115. package/node_modules/@poe-code/config-mutations/dist/testing/mock-fs.js +194 -0
  116. package/node_modules/@poe-code/config-mutations/dist/types.d.ts +168 -0
  117. package/node_modules/@poe-code/config-mutations/dist/types.js +6 -0
  118. package/node_modules/@poe-code/config-mutations/package.json +29 -0
  119. package/node_modules/@poe-code/frontmatter/README.md +35 -0
  120. package/node_modules/@poe-code/frontmatter/dist/fences.d.ts +25 -0
  121. package/node_modules/@poe-code/frontmatter/dist/fences.js +100 -0
  122. package/node_modules/@poe-code/frontmatter/dist/index.d.ts +3 -0
  123. package/node_modules/@poe-code/frontmatter/dist/index.js +3 -0
  124. package/node_modules/@poe-code/frontmatter/dist/parse.d.ts +20 -0
  125. package/node_modules/@poe-code/frontmatter/dist/parse.js +209 -0
  126. package/node_modules/@poe-code/frontmatter/dist/stringify.d.ts +1 -0
  127. package/node_modules/@poe-code/frontmatter/dist/stringify.js +48 -0
  128. package/node_modules/@poe-code/frontmatter/package.json +25 -0
  129. package/node_modules/toolcraft-design/README.md +160 -0
  130. package/node_modules/toolcraft-design/dist/acp/components.d.ts +12 -0
  131. package/node_modules/toolcraft-design/dist/acp/components.js +137 -0
  132. package/node_modules/toolcraft-design/dist/acp/index.d.ts +3 -0
  133. package/node_modules/toolcraft-design/dist/acp/index.js +2 -0
  134. package/node_modules/toolcraft-design/dist/acp/writer.d.ts +13 -0
  135. package/node_modules/toolcraft-design/dist/acp/writer.js +21 -0
  136. package/node_modules/toolcraft-design/dist/components/browser.d.ts +15 -0
  137. package/node_modules/toolcraft-design/dist/components/browser.js +31 -0
  138. package/node_modules/toolcraft-design/dist/components/catalog.d.ts +26 -0
  139. package/node_modules/toolcraft-design/dist/components/catalog.js +95 -0
  140. package/node_modules/toolcraft-design/dist/components/color.d.ts +31 -0
  141. package/node_modules/toolcraft-design/dist/components/color.js +102 -0
  142. package/node_modules/toolcraft-design/dist/components/command-errors.d.ts +16 -0
  143. package/node_modules/toolcraft-design/dist/components/command-errors.js +23 -0
  144. package/node_modules/toolcraft-design/dist/components/detail-card.d.ts +22 -0
  145. package/node_modules/toolcraft-design/dist/components/detail-card.js +45 -0
  146. package/node_modules/toolcraft-design/dist/components/help-formatter-plain.d.ts +5 -0
  147. package/node_modules/toolcraft-design/dist/components/help-formatter-plain.js +132 -0
  148. package/node_modules/toolcraft-design/dist/components/help-formatter.d.ts +33 -0
  149. package/node_modules/toolcraft-design/dist/components/help-formatter.js +213 -0
  150. package/node_modules/toolcraft-design/dist/components/index.d.ts +16 -0
  151. package/node_modules/toolcraft-design/dist/components/index.js +10 -0
  152. package/node_modules/toolcraft-design/dist/components/logger.d.ts +11 -0
  153. package/node_modules/toolcraft-design/dist/components/logger.js +60 -0
  154. package/node_modules/toolcraft-design/dist/components/symbols.d.ts +12 -0
  155. package/node_modules/toolcraft-design/dist/components/symbols.js +71 -0
  156. package/node_modules/toolcraft-design/dist/components/table.d.ts +15 -0
  157. package/node_modules/toolcraft-design/dist/components/table.js +302 -0
  158. package/node_modules/toolcraft-design/dist/components/template.d.ts +10 -0
  159. package/node_modules/toolcraft-design/dist/components/template.js +437 -0
  160. package/node_modules/toolcraft-design/dist/components/text.d.ts +16 -0
  161. package/node_modules/toolcraft-design/dist/components/text.js +145 -0
  162. package/node_modules/toolcraft-design/dist/dashboard/ansi.d.ts +18 -0
  163. package/node_modules/toolcraft-design/dist/dashboard/ansi.js +343 -0
  164. package/node_modules/toolcraft-design/dist/dashboard/buffer.d.ts +25 -0
  165. package/node_modules/toolcraft-design/dist/dashboard/buffer.js +219 -0
  166. package/node_modules/toolcraft-design/dist/dashboard/components/border.d.ts +9 -0
  167. package/node_modules/toolcraft-design/dist/dashboard/components/border.js +123 -0
  168. package/node_modules/toolcraft-design/dist/dashboard/components/footer.d.ts +8 -0
  169. package/node_modules/toolcraft-design/dist/dashboard/components/footer.js +56 -0
  170. package/node_modules/toolcraft-design/dist/dashboard/components/output-pane.d.ts +12 -0
  171. package/node_modules/toolcraft-design/dist/dashboard/components/output-pane.js +268 -0
  172. package/node_modules/toolcraft-design/dist/dashboard/components/stats-pane.d.ts +7 -0
  173. package/node_modules/toolcraft-design/dist/dashboard/components/stats-pane.js +107 -0
  174. package/node_modules/toolcraft-design/dist/dashboard/dashboard.d.ts +20 -0
  175. package/node_modules/toolcraft-design/dist/dashboard/dashboard.js +167 -0
  176. package/node_modules/toolcraft-design/dist/dashboard/demo.d.ts +13 -0
  177. package/node_modules/toolcraft-design/dist/dashboard/demo.js +145 -0
  178. package/node_modules/toolcraft-design/dist/dashboard/index.d.ts +8 -0
  179. package/node_modules/toolcraft-design/dist/dashboard/index.js +4 -0
  180. package/node_modules/toolcraft-design/dist/dashboard/keymap.d.ts +8 -0
  181. package/node_modules/toolcraft-design/dist/dashboard/keymap.js +233 -0
  182. package/node_modules/toolcraft-design/dist/dashboard/layout.d.ts +25 -0
  183. package/node_modules/toolcraft-design/dist/dashboard/layout.js +79 -0
  184. package/node_modules/toolcraft-design/dist/dashboard/should-use-dashboard.d.ts +10 -0
  185. package/node_modules/toolcraft-design/dist/dashboard/should-use-dashboard.js +7 -0
  186. package/node_modules/toolcraft-design/dist/dashboard/snapshot.d.ts +10 -0
  187. package/node_modules/toolcraft-design/dist/dashboard/snapshot.js +68 -0
  188. package/node_modules/toolcraft-design/dist/dashboard/store.d.ts +8 -0
  189. package/node_modules/toolcraft-design/dist/dashboard/store.js +51 -0
  190. package/node_modules/toolcraft-design/dist/dashboard/terminal-width.d.ts +4 -0
  191. package/node_modules/toolcraft-design/dist/dashboard/terminal-width.js +71 -0
  192. package/node_modules/toolcraft-design/dist/dashboard/terminal.d.ts +37 -0
  193. package/node_modules/toolcraft-design/dist/dashboard/terminal.js +264 -0
  194. package/node_modules/toolcraft-design/dist/dashboard/types.d.ts +38 -0
  195. package/node_modules/toolcraft-design/dist/dashboard/types.js +1 -0
  196. package/node_modules/toolcraft-design/dist/explorer/actions.d.ts +16 -0
  197. package/node_modules/toolcraft-design/dist/explorer/actions.js +39 -0
  198. package/node_modules/toolcraft-design/dist/explorer/demo.d.ts +13 -0
  199. package/node_modules/toolcraft-design/dist/explorer/demo.js +297 -0
  200. package/node_modules/toolcraft-design/dist/explorer/events.d.ts +67 -0
  201. package/node_modules/toolcraft-design/dist/explorer/events.js +1 -0
  202. package/node_modules/toolcraft-design/dist/explorer/filter.d.ts +10 -0
  203. package/node_modules/toolcraft-design/dist/explorer/filter.js +95 -0
  204. package/node_modules/toolcraft-design/dist/explorer/index.d.ts +8 -0
  205. package/node_modules/toolcraft-design/dist/explorer/index.js +8 -0
  206. package/node_modules/toolcraft-design/dist/explorer/jobs.d.ts +7 -0
  207. package/node_modules/toolcraft-design/dist/explorer/jobs.js +59 -0
  208. package/node_modules/toolcraft-design/dist/explorer/keymap.d.ts +21 -0
  209. package/node_modules/toolcraft-design/dist/explorer/keymap.js +376 -0
  210. package/node_modules/toolcraft-design/dist/explorer/layout.d.ts +20 -0
  211. package/node_modules/toolcraft-design/dist/explorer/layout.js +73 -0
  212. package/node_modules/toolcraft-design/dist/explorer/reducer.d.ts +9 -0
  213. package/node_modules/toolcraft-design/dist/explorer/reducer.js +782 -0
  214. package/node_modules/toolcraft-design/dist/explorer/render/detail.d.ts +4 -0
  215. package/node_modules/toolcraft-design/dist/explorer/render/detail.js +97 -0
  216. package/node_modules/toolcraft-design/dist/explorer/render/footer.d.ts +4 -0
  217. package/node_modules/toolcraft-design/dist/explorer/render/footer.js +73 -0
  218. package/node_modules/toolcraft-design/dist/explorer/render/header.d.ts +4 -0
  219. package/node_modules/toolcraft-design/dist/explorer/render/header.js +49 -0
  220. package/node_modules/toolcraft-design/dist/explorer/render/index.d.ts +8 -0
  221. package/node_modules/toolcraft-design/dist/explorer/render/index.js +53 -0
  222. package/node_modules/toolcraft-design/dist/explorer/render/list.d.ts +4 -0
  223. package/node_modules/toolcraft-design/dist/explorer/render/list.js +116 -0
  224. package/node_modules/toolcraft-design/dist/explorer/render/modal.d.ts +3 -0
  225. package/node_modules/toolcraft-design/dist/explorer/render/modal.js +87 -0
  226. package/node_modules/toolcraft-design/dist/explorer/render/test-fixtures.d.ts +8 -0
  227. package/node_modules/toolcraft-design/dist/explorer/render/test-fixtures.js +156 -0
  228. package/node_modules/toolcraft-design/dist/explorer/render/text.d.ts +12 -0
  229. package/node_modules/toolcraft-design/dist/explorer/render/text.js +81 -0
  230. package/node_modules/toolcraft-design/dist/explorer/runtime.d.ts +2 -0
  231. package/node_modules/toolcraft-design/dist/explorer/runtime.js +340 -0
  232. package/node_modules/toolcraft-design/dist/explorer/runtime.test-helpers.d.ts +50 -0
  233. package/node_modules/toolcraft-design/dist/explorer/runtime.test-helpers.js +101 -0
  234. package/node_modules/toolcraft-design/dist/explorer/state.d.ts +137 -0
  235. package/node_modules/toolcraft-design/dist/explorer/state.js +86 -0
  236. package/node_modules/toolcraft-design/dist/explorer/theme.d.ts +27 -0
  237. package/node_modules/toolcraft-design/dist/explorer/theme.js +29 -0
  238. package/node_modules/toolcraft-design/dist/index.d.ts +50 -0
  239. package/node_modules/toolcraft-design/dist/index.js +43 -0
  240. package/node_modules/toolcraft-design/dist/internal/color-support.d.ts +9 -0
  241. package/node_modules/toolcraft-design/dist/internal/color-support.js +12 -0
  242. package/node_modules/toolcraft-design/dist/internal/output-format.d.ts +6 -0
  243. package/node_modules/toolcraft-design/dist/internal/output-format.js +22 -0
  244. package/node_modules/toolcraft-design/dist/internal/strip-ansi.d.ts +1 -0
  245. package/node_modules/toolcraft-design/dist/internal/strip-ansi.js +50 -0
  246. package/node_modules/toolcraft-design/dist/internal/theme-detect.d.ts +12 -0
  247. package/node_modules/toolcraft-design/dist/internal/theme-detect.js +71 -0
  248. package/node_modules/toolcraft-design/dist/internal/theme-state.d.ts +12 -0
  249. package/node_modules/toolcraft-design/dist/internal/theme-state.js +35 -0
  250. package/node_modules/toolcraft-design/dist/prompts/index.d.ts +91 -0
  251. package/node_modules/toolcraft-design/dist/prompts/index.js +137 -0
  252. package/node_modules/toolcraft-design/dist/prompts/interactive/cancel-symbol.d.ts +2 -0
  253. package/node_modules/toolcraft-design/dist/prompts/interactive/cancel-symbol.js +4 -0
  254. package/node_modules/toolcraft-design/dist/prompts/interactive/confirm.d.ts +9 -0
  255. package/node_modules/toolcraft-design/dist/prompts/interactive/confirm.js +47 -0
  256. package/node_modules/toolcraft-design/dist/prompts/interactive/core.d.ts +55 -0
  257. package/node_modules/toolcraft-design/dist/prompts/interactive/core.js +274 -0
  258. package/node_modules/toolcraft-design/dist/prompts/interactive/glyphs.d.ts +20 -0
  259. package/node_modules/toolcraft-design/dist/prompts/interactive/glyphs.js +53 -0
  260. package/node_modules/toolcraft-design/dist/prompts/interactive/index.d.ts +6 -0
  261. package/node_modules/toolcraft-design/dist/prompts/interactive/index.js +6 -0
  262. package/node_modules/toolcraft-design/dist/prompts/interactive/keys.d.ts +2 -0
  263. package/node_modules/toolcraft-design/dist/prompts/interactive/keys.js +28 -0
  264. package/node_modules/toolcraft-design/dist/prompts/interactive/multiselect.d.ts +13 -0
  265. package/node_modules/toolcraft-design/dist/prompts/interactive/multiselect.js +131 -0
  266. package/node_modules/toolcraft-design/dist/prompts/interactive/pagination.d.ts +10 -0
  267. package/node_modules/toolcraft-design/dist/prompts/interactive/pagination.js +52 -0
  268. package/node_modules/toolcraft-design/dist/prompts/interactive/password.d.ts +10 -0
  269. package/node_modules/toolcraft-design/dist/prompts/interactive/password.js +55 -0
  270. package/node_modules/toolcraft-design/dist/prompts/interactive/select.d.ts +18 -0
  271. package/node_modules/toolcraft-design/dist/prompts/interactive/select.js +89 -0
  272. package/node_modules/toolcraft-design/dist/prompts/interactive/test-helpers.d.ts +21 -0
  273. package/node_modules/toolcraft-design/dist/prompts/interactive/test-helpers.js +32 -0
  274. package/node_modules/toolcraft-design/dist/prompts/interactive/text.d.ts +12 -0
  275. package/node_modules/toolcraft-design/dist/prompts/interactive/text.js +60 -0
  276. package/node_modules/toolcraft-design/dist/prompts/interactive/wrap.d.ts +4 -0
  277. package/node_modules/toolcraft-design/dist/prompts/interactive/wrap.js +18 -0
  278. package/node_modules/toolcraft-design/dist/prompts/primitives/cancel.d.ts +2 -0
  279. package/node_modules/toolcraft-design/dist/prompts/primitives/cancel.js +9 -0
  280. package/node_modules/toolcraft-design/dist/prompts/primitives/intro.d.ts +1 -0
  281. package/node_modules/toolcraft-design/dist/prompts/primitives/intro.js +16 -0
  282. package/node_modules/toolcraft-design/dist/prompts/primitives/log.d.ts +18 -0
  283. package/node_modules/toolcraft-design/dist/prompts/primitives/log.js +104 -0
  284. package/node_modules/toolcraft-design/dist/prompts/primitives/note.d.ts +1 -0
  285. package/node_modules/toolcraft-design/dist/prompts/primitives/note.js +39 -0
  286. package/node_modules/toolcraft-design/dist/prompts/primitives/outro.d.ts +1 -0
  287. package/node_modules/toolcraft-design/dist/prompts/primitives/outro.js +16 -0
  288. package/node_modules/toolcraft-design/dist/prompts/primitives/spinner.d.ts +6 -0
  289. package/node_modules/toolcraft-design/dist/prompts/primitives/spinner.js +74 -0
  290. package/node_modules/toolcraft-design/dist/prompts/theme.d.ts +11 -0
  291. package/node_modules/toolcraft-design/dist/prompts/theme.js +15 -0
  292. package/node_modules/toolcraft-design/dist/static/index.d.ts +4 -0
  293. package/node_modules/toolcraft-design/dist/static/index.js +2 -0
  294. package/node_modules/toolcraft-design/dist/static/menu.d.ts +11 -0
  295. package/node_modules/toolcraft-design/dist/static/menu.js +42 -0
  296. package/node_modules/toolcraft-design/dist/static/spinner.d.ts +14 -0
  297. package/node_modules/toolcraft-design/dist/static/spinner.js +52 -0
  298. package/node_modules/toolcraft-design/dist/terminal-markdown/ast.d.ts +92 -0
  299. package/node_modules/toolcraft-design/dist/terminal-markdown/ast.js +1 -0
  300. package/node_modules/toolcraft-design/dist/terminal-markdown/demo-content.d.ts +2 -0
  301. package/node_modules/toolcraft-design/dist/terminal-markdown/demo-content.js +139 -0
  302. package/node_modules/toolcraft-design/dist/terminal-markdown/index.d.ts +6 -0
  303. package/node_modules/toolcraft-design/dist/terminal-markdown/index.js +8 -0
  304. package/node_modules/toolcraft-design/dist/terminal-markdown/parser/block.d.ts +7 -0
  305. package/node_modules/toolcraft-design/dist/terminal-markdown/parser/block.js +1495 -0
  306. package/node_modules/toolcraft-design/dist/terminal-markdown/parser/frontmatter.d.ts +8 -0
  307. package/node_modules/toolcraft-design/dist/terminal-markdown/parser/frontmatter.js +36 -0
  308. package/node_modules/toolcraft-design/dist/terminal-markdown/parser/inline.d.ts +10 -0
  309. package/node_modules/toolcraft-design/dist/terminal-markdown/parser/inline.js +1190 -0
  310. package/node_modules/toolcraft-design/dist/terminal-markdown/parser.d.ts +5 -0
  311. package/node_modules/toolcraft-design/dist/terminal-markdown/parser.js +42 -0
  312. package/node_modules/toolcraft-design/dist/terminal-markdown/renderer.d.ts +6 -0
  313. package/node_modules/toolcraft-design/dist/terminal-markdown/renderer.js +615 -0
  314. package/node_modules/toolcraft-design/dist/terminal-markdown/testing/theme-render-fixture.d.ts +1 -0
  315. package/node_modules/toolcraft-design/dist/terminal-markdown/testing/theme-render-fixture.js +27 -0
  316. package/node_modules/toolcraft-design/dist/tokens/brand.d.ts +5 -0
  317. package/node_modules/toolcraft-design/dist/tokens/brand.js +5 -0
  318. package/node_modules/toolcraft-design/dist/tokens/colors.d.ts +37 -0
  319. package/node_modules/toolcraft-design/dist/tokens/colors.js +85 -0
  320. package/node_modules/toolcraft-design/dist/tokens/index.d.ts +6 -0
  321. package/node_modules/toolcraft-design/dist/tokens/index.js +5 -0
  322. package/node_modules/toolcraft-design/dist/tokens/spacing.d.ts +6 -0
  323. package/node_modules/toolcraft-design/dist/tokens/spacing.js +6 -0
  324. package/node_modules/toolcraft-design/dist/tokens/typography.d.ts +7 -0
  325. package/node_modules/toolcraft-design/dist/tokens/typography.js +8 -0
  326. package/node_modules/toolcraft-design/dist/tokens/widths.d.ts +5 -0
  327. package/node_modules/toolcraft-design/dist/tokens/widths.js +5 -0
  328. package/node_modules/toolcraft-design/package.json +44 -0
  329. package/package.json +15 -5
@@ -0,0 +1,17 @@
1
+ import type { PathMapper } from "../types.js";
2
+ /**
3
+ * Expand ~ shortcut to the provided home directory.
4
+ */
5
+ export declare function expandHome(targetPath: string, homeDir: string): string;
6
+ /**
7
+ * Validate that a path is home-relative (starts with ~).
8
+ * Throws if the path is not home-relative.
9
+ */
10
+ export declare function validateHomePath(targetPath: string): void;
11
+ /**
12
+ * Resolve a path with optional path mapping for isolated configurations.
13
+ * 1. Validates the path starts with ~
14
+ * 2. Expands ~ to home directory
15
+ * 3. If pathMapper is provided, maps the directory portion and reconstructs the path
16
+ */
17
+ export declare function resolvePath(rawPath: string, homeDir: string, pathMapper?: PathMapper): string;
@@ -0,0 +1,64 @@
1
+ import path from "node:path";
2
+ /**
3
+ * Expand ~ shortcut to the provided home directory.
4
+ */
5
+ export function expandHome(targetPath, homeDir) {
6
+ if (!targetPath?.startsWith("~")) {
7
+ return targetPath;
8
+ }
9
+ // Handle ~./ -> ~/.
10
+ if (targetPath.startsWith("~./")) {
11
+ targetPath = `~/.${targetPath.slice(3)}`;
12
+ }
13
+ let remainder = targetPath.slice(1);
14
+ // Remove leading slash or backslash
15
+ if (remainder.startsWith("/") || remainder.startsWith("\\")) {
16
+ remainder = remainder.slice(1);
17
+ }
18
+ else if (remainder.startsWith(".")) {
19
+ // Handle ~/.
20
+ remainder = remainder.slice(1);
21
+ if (remainder.startsWith("/") || remainder.startsWith("\\")) {
22
+ remainder = remainder.slice(1);
23
+ }
24
+ }
25
+ return remainder.length === 0 ? homeDir : path.join(homeDir, remainder);
26
+ }
27
+ /**
28
+ * Validate that a path is home-relative (starts with ~).
29
+ * Throws if the path is not home-relative.
30
+ */
31
+ export function validateHomePath(targetPath) {
32
+ if (typeof targetPath !== "string" || targetPath.length === 0) {
33
+ throw new Error("Target path must be a non-empty string.");
34
+ }
35
+ if (!targetPath.startsWith("~")) {
36
+ throw new Error(`All target paths must be home-relative (start with ~). Received: "${targetPath}"`);
37
+ }
38
+ }
39
+ /**
40
+ * Resolve a path with optional path mapping for isolated configurations.
41
+ * 1. Validates the path starts with ~
42
+ * 2. Expands ~ to home directory
43
+ * 3. If pathMapper is provided, maps the directory portion and reconstructs the path
44
+ */
45
+ export function resolvePath(rawPath, homeDir, pathMapper) {
46
+ validateHomePath(rawPath);
47
+ const expanded = expandHome(rawPath, homeDir);
48
+ const canonicalHome = path.resolve(homeDir);
49
+ const canonicalExpanded = path.resolve(expanded);
50
+ const relative = path.relative(canonicalHome, canonicalExpanded);
51
+ if (relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
52
+ throw new Error(`Target path resolves outside home directory: "${rawPath}"`);
53
+ }
54
+ if (!pathMapper) {
55
+ return canonicalExpanded;
56
+ }
57
+ // Map the directory portion
58
+ const rawDirectory = path.dirname(expanded);
59
+ const mappedDirectory = pathMapper.mapTargetDirectory({
60
+ targetDirectory: rawDirectory
61
+ });
62
+ const filename = path.basename(expanded);
63
+ return filename.length === 0 ? mappedDirectory : path.join(mappedDirectory, filename);
64
+ }
@@ -0,0 +1,7 @@
1
+ import type { Mutation, MutationContext, MutationResult, MutationOptions } from "../types.js";
2
+ /**
3
+ * Execute an array of mutations in order.
4
+ *
5
+ * All dependencies must be injected - no defaults, no globals.
6
+ */
7
+ export declare function runMutations(mutations: Mutation[], context: MutationContext, options?: MutationOptions): Promise<MutationResult>;
@@ -0,0 +1,39 @@
1
+ import { applyMutation, resolveMutationDetails } from "./apply-mutation.js";
2
+ /**
3
+ * Execute an array of mutations in order.
4
+ *
5
+ * All dependencies must be injected - no defaults, no globals.
6
+ */
7
+ export async function runMutations(mutations, context, options) {
8
+ const effects = [];
9
+ let anyChanged = false;
10
+ const resolverOptions = options ?? {};
11
+ for (const mutation of mutations) {
12
+ const { outcome } = await executeMutation(mutation, context, resolverOptions);
13
+ effects.push(outcome);
14
+ if (outcome.changed) {
15
+ anyChanged = true;
16
+ }
17
+ }
18
+ return {
19
+ changed: anyChanged,
20
+ effects
21
+ };
22
+ }
23
+ async function executeMutation(mutation, context, options) {
24
+ const pendingDetails = resolveMutationDetails(mutation, context, options);
25
+ // Call onStart observer
26
+ context.observers?.onStart?.(pendingDetails);
27
+ try {
28
+ const { outcome, details } = await applyMutation(mutation, context, options);
29
+ // Call onComplete observer
30
+ context.observers?.onComplete?.(details, outcome);
31
+ return { outcome, details };
32
+ }
33
+ catch (error) {
34
+ // Call onError observer
35
+ context.observers?.onError?.(pendingDetails, error);
36
+ // Re-throw the error
37
+ throw error;
38
+ }
39
+ }
@@ -0,0 +1,13 @@
1
+ import type { ConfigFormat } from "../types.js";
2
+ export type FormatName = "json" | "toml" | "yaml";
3
+ /**
4
+ * Get a format handler by path (auto-detect from extension) or explicit format name.
5
+ */
6
+ export declare function getConfigFormat(pathOrFormat: string): ConfigFormat;
7
+ /**
8
+ * Detect format name from a file path.
9
+ */
10
+ export declare function detectFormat(path: string): FormatName | undefined;
11
+ export { jsonFormat } from "./json.js";
12
+ export { tomlFormat } from "./toml.js";
13
+ export { yamlFormat } from "./yaml.js";
@@ -0,0 +1,49 @@
1
+ import { jsonFormat } from "./json.js";
2
+ import { tomlFormat } from "./toml.js";
3
+ import { yamlFormat } from "./yaml.js";
4
+ const formatRegistry = {
5
+ json: jsonFormat,
6
+ toml: tomlFormat,
7
+ yaml: yamlFormat
8
+ };
9
+ const extensionMap = {
10
+ ".json": "json",
11
+ ".toml": "toml",
12
+ ".yaml": "yaml",
13
+ ".yml": "yaml"
14
+ };
15
+ /**
16
+ * Get a format handler by path (auto-detect from extension) or explicit format name.
17
+ */
18
+ export function getConfigFormat(pathOrFormat) {
19
+ // Check if it's an explicit format name
20
+ if (Object.prototype.hasOwnProperty.call(formatRegistry, pathOrFormat)) {
21
+ return formatRegistry[pathOrFormat];
22
+ }
23
+ // Try to detect from extension
24
+ const ext = getExtension(pathOrFormat);
25
+ const formatName = extensionMap[ext];
26
+ if (!formatName) {
27
+ throw new Error(`Unsupported config format. Cannot detect format from "${pathOrFormat}". ` +
28
+ `Supported extensions: ${Object.keys(extensionMap).join(", ")}. ` +
29
+ `Supported format names: ${Object.keys(formatRegistry).join(", ")}.`);
30
+ }
31
+ return formatRegistry[formatName];
32
+ }
33
+ /**
34
+ * Detect format name from a file path.
35
+ */
36
+ export function detectFormat(path) {
37
+ const ext = getExtension(path);
38
+ return extensionMap[ext];
39
+ }
40
+ function getExtension(path) {
41
+ const lastDot = path.lastIndexOf(".");
42
+ if (lastDot === -1) {
43
+ return "";
44
+ }
45
+ return path.slice(lastDot).toLowerCase();
46
+ }
47
+ export { jsonFormat } from "./json.js";
48
+ export { tomlFormat } from "./toml.js";
49
+ export { yamlFormat } from "./yaml.js";
@@ -0,0 +1,32 @@
1
+ import type { ConfigFormat, ConfigObject, ConfigValue } from "../types.js";
2
+ declare function detectIndent(content: string): string;
3
+ /**
4
+ * Modify JSON content at a specific path while preserving comments and formatting.
5
+ * Uses jsonc-parser's modify() for targeted updates.
6
+ *
7
+ * @param content - The original JSON content (may include comments)
8
+ * @param path - JSON path array, e.g. ["mcpServers", "my-server"]
9
+ * @param value - The value to set (or undefined to remove)
10
+ * @returns The modified JSON content with comments preserved
11
+ */
12
+ declare function modifyAtPath(content: string, path: (string | number)[], value: ConfigValue | undefined): string;
13
+ /**
14
+ * Merge a patch into JSON content while preserving comments and formatting.
15
+ * Uses jsonc.modify() for each top-level key to preserve existing comments.
16
+ *
17
+ * @param content - The original JSON content (may include comments)
18
+ * @param patch - Object with values to merge
19
+ * @returns The modified JSON content with comments preserved
20
+ */
21
+ declare function mergePreservingComments(content: string, patch: ConfigObject): string;
22
+ /**
23
+ * Remove a key from JSON content while preserving comments and formatting.
24
+ *
25
+ * @param content - The original JSON content
26
+ * @param path - JSON path array to the key to remove
27
+ * @returns The modified JSON content with comments preserved
28
+ */
29
+ declare function removeAtPath(content: string, path: (string | number)[]): string;
30
+ declare function serializeUpdate(content: string, current: ConfigObject, next: ConfigObject): string;
31
+ export { detectIndent, modifyAtPath, mergePreservingComments, removeAtPath, serializeUpdate };
32
+ export declare const jsonFormat: ConfigFormat;
@@ -0,0 +1,171 @@
1
+ import * as jsonc from "jsonc-parser";
2
+ import { cloneConfigObject, hasConfigEntry, setConfigEntry } from "./object.js";
3
+ function isConfigObject(value) {
4
+ return typeof value === "object" && value !== null && !Array.isArray(value);
5
+ }
6
+ function detectIndent(content) {
7
+ const match = content.match(/^[\t ]+/m);
8
+ if (match) {
9
+ return match[0];
10
+ }
11
+ return " ";
12
+ }
13
+ function parse(content) {
14
+ if (!content || content.trim() === "") {
15
+ return {};
16
+ }
17
+ const errors = [];
18
+ const parsed = jsonc.parse(content, errors, {
19
+ allowTrailingComma: true,
20
+ disallowComments: false
21
+ });
22
+ if (errors.length > 0) {
23
+ throw new Error(`JSON parse error: ${jsonc.printParseErrorCode(errors[0].error)}`);
24
+ }
25
+ if (parsed === null || parsed === undefined) {
26
+ return {};
27
+ }
28
+ if (!isConfigObject(parsed)) {
29
+ throw new Error("Expected JSON object.");
30
+ }
31
+ return cloneConfigObject(parsed);
32
+ }
33
+ function serialize(obj) {
34
+ return `${JSON.stringify(obj, null, 2)}\n`;
35
+ }
36
+ function merge(base, patch) {
37
+ const result = cloneConfigObject(base);
38
+ for (const [key, value] of Object.entries(patch)) {
39
+ if (value === undefined) {
40
+ continue;
41
+ }
42
+ const existing = hasConfigEntry(result, key) ? result[key] : undefined;
43
+ if (isConfigObject(existing) && isConfigObject(value)) {
44
+ setConfigEntry(result, key, merge(existing, value));
45
+ continue;
46
+ }
47
+ setConfigEntry(result, key, value);
48
+ }
49
+ return result;
50
+ }
51
+ function configValuesEqual(left, right) {
52
+ return JSON.stringify(left) === JSON.stringify(right);
53
+ }
54
+ function prune(obj, shape) {
55
+ let changed = false;
56
+ const result = cloneConfigObject(obj);
57
+ for (const [key, pattern] of Object.entries(shape)) {
58
+ if (!hasConfigEntry(result, key)) {
59
+ continue;
60
+ }
61
+ const current = result[key];
62
+ // Empty object pattern means "delete this key entirely"
63
+ if (isConfigObject(pattern) && Object.keys(pattern).length === 0) {
64
+ delete result[key];
65
+ changed = true;
66
+ continue;
67
+ }
68
+ // Non-empty object pattern with object current: recurse
69
+ if (isConfigObject(pattern) && isConfigObject(current)) {
70
+ const { changed: childChanged, result: childResult } = prune(current, pattern);
71
+ if (childChanged) {
72
+ changed = true;
73
+ }
74
+ if (Object.keys(childResult).length === 0) {
75
+ delete result[key];
76
+ }
77
+ else {
78
+ setConfigEntry(result, key, childResult);
79
+ }
80
+ continue;
81
+ }
82
+ if (isConfigObject(pattern) && Object.keys(pattern).length > 0) {
83
+ continue;
84
+ }
85
+ delete result[key];
86
+ changed = true;
87
+ }
88
+ return { changed, result };
89
+ }
90
+ /**
91
+ * Modify JSON content at a specific path while preserving comments and formatting.
92
+ * Uses jsonc-parser's modify() for targeted updates.
93
+ *
94
+ * @param content - The original JSON content (may include comments)
95
+ * @param path - JSON path array, e.g. ["mcpServers", "my-server"]
96
+ * @param value - The value to set (or undefined to remove)
97
+ * @returns The modified JSON content with comments preserved
98
+ */
99
+ function modifyAtPath(content, path, value) {
100
+ const indent = detectIndent(content);
101
+ const formattingOptions = {
102
+ tabSize: indent === "\t" ? 1 : indent.length,
103
+ insertSpaces: indent !== "\t",
104
+ eol: "\n"
105
+ };
106
+ const edits = jsonc.modify(content, path, value, { formattingOptions });
107
+ let result = jsonc.applyEdits(content, edits);
108
+ if (!result.endsWith("\n")) {
109
+ result += "\n";
110
+ }
111
+ return result;
112
+ }
113
+ /**
114
+ * Merge a patch into JSON content while preserving comments and formatting.
115
+ * Uses jsonc.modify() for each top-level key to preserve existing comments.
116
+ *
117
+ * @param content - The original JSON content (may include comments)
118
+ * @param patch - Object with values to merge
119
+ * @returns The modified JSON content with comments preserved
120
+ */
121
+ function mergePreservingComments(content, patch) {
122
+ const current = parse(content);
123
+ return serializeUpdate(content || "{}", current, merge(current, patch));
124
+ }
125
+ /**
126
+ * Remove a key from JSON content while preserving comments and formatting.
127
+ *
128
+ * @param content - The original JSON content
129
+ * @param path - JSON path array to the key to remove
130
+ * @returns The modified JSON content with comments preserved
131
+ */
132
+ function removeAtPath(content, path) {
133
+ return modifyAtPath(content, path, undefined);
134
+ }
135
+ function serializeUpdate(content, current, next) {
136
+ let result = content || "{}";
137
+ result = applyObjectUpdate(result, [], current, next);
138
+ if (!result.endsWith("\n")) {
139
+ result += "\n";
140
+ }
141
+ return result;
142
+ }
143
+ function applyObjectUpdate(content, path, current, next) {
144
+ let result = content;
145
+ for (const key of Object.keys(current)) {
146
+ if (!hasConfigEntry(next, key)) {
147
+ result = removeAtPath(result, [...path, key]);
148
+ }
149
+ }
150
+ for (const [key, nextValue] of Object.entries(next)) {
151
+ const nextPath = [...path, key];
152
+ const hasCurrent = hasConfigEntry(current, key);
153
+ const currentValue = hasCurrent ? current[key] : undefined;
154
+ if (hasCurrent && isConfigObject(currentValue) && isConfigObject(nextValue)) {
155
+ result = applyObjectUpdate(result, nextPath, currentValue, nextValue);
156
+ continue;
157
+ }
158
+ if (!hasCurrent || !configValuesEqual(currentValue, nextValue)) {
159
+ result = modifyAtPath(result, nextPath, nextValue);
160
+ }
161
+ }
162
+ return result;
163
+ }
164
+ export { detectIndent, modifyAtPath, mergePreservingComments, removeAtPath, serializeUpdate };
165
+ export const jsonFormat = {
166
+ parse,
167
+ serialize,
168
+ serializeUpdate,
169
+ merge,
170
+ prune
171
+ };
@@ -0,0 +1,4 @@
1
+ import type { ConfigObject, ConfigValue } from "../types.js";
2
+ export declare function cloneConfigObject(value: ConfigObject): ConfigObject;
3
+ export declare function setConfigEntry(target: ConfigObject, key: string, value: ConfigValue): void;
4
+ export declare function hasConfigEntry(target: ConfigObject, key: string): boolean;
@@ -0,0 +1,27 @@
1
+ export function cloneConfigObject(value) {
2
+ const result = {};
3
+ for (const [key, entry] of Object.entries(value)) {
4
+ setConfigEntry(result, key, cloneConfigValue(entry));
5
+ }
6
+ return result;
7
+ }
8
+ export function setConfigEntry(target, key, value) {
9
+ Object.defineProperty(target, key, {
10
+ configurable: true,
11
+ enumerable: true,
12
+ writable: true,
13
+ value
14
+ });
15
+ }
16
+ export function hasConfigEntry(target, key) {
17
+ return Object.prototype.hasOwnProperty.call(target, key);
18
+ }
19
+ function cloneConfigValue(value) {
20
+ if (Array.isArray(value)) {
21
+ return value.map((entry) => cloneConfigValue(entry));
22
+ }
23
+ if (value && typeof value === "object" && !(value instanceof Date)) {
24
+ return cloneConfigObject(value);
25
+ }
26
+ return value;
27
+ }
@@ -0,0 +1,2 @@
1
+ import type { ConfigFormat } from "../types.js";
2
+ export declare const tomlFormat: ConfigFormat;
@@ -0,0 +1,75 @@
1
+ import { parse as parseToml, stringify as stringifyToml } from "smol-toml";
2
+ import { cloneConfigObject, hasConfigEntry, setConfigEntry } from "./object.js";
3
+ function isConfigObject(value) {
4
+ return typeof value === "object" && value !== null && !Array.isArray(value);
5
+ }
6
+ function parse(content) {
7
+ if (!content || content.trim() === "") {
8
+ return {};
9
+ }
10
+ const parsed = parseToml(content);
11
+ if (!isConfigObject(parsed)) {
12
+ throw new Error("Expected TOML document to be a table.");
13
+ }
14
+ return cloneConfigObject(parsed);
15
+ }
16
+ function serialize(obj) {
17
+ const serialized = stringifyToml(obj);
18
+ return serialized.endsWith("\n") ? serialized : `${serialized}\n`;
19
+ }
20
+ function merge(base, patch) {
21
+ const result = cloneConfigObject(base);
22
+ for (const [key, value] of Object.entries(patch)) {
23
+ if (value === undefined) {
24
+ continue;
25
+ }
26
+ const existing = hasConfigEntry(result, key) ? result[key] : undefined;
27
+ if (isConfigObject(existing) && isConfigObject(value)) {
28
+ setConfigEntry(result, key, merge(existing, value));
29
+ continue;
30
+ }
31
+ setConfigEntry(result, key, value);
32
+ }
33
+ return result;
34
+ }
35
+ function prune(obj, shape) {
36
+ let changed = false;
37
+ const result = cloneConfigObject(obj);
38
+ for (const [key, pattern] of Object.entries(shape)) {
39
+ if (!hasConfigEntry(result, key)) {
40
+ continue;
41
+ }
42
+ const current = result[key];
43
+ // Empty object pattern means "delete this key entirely"
44
+ if (isConfigObject(pattern) && Object.keys(pattern).length === 0) {
45
+ delete result[key];
46
+ changed = true;
47
+ continue;
48
+ }
49
+ // Non-empty object pattern with object current: recurse
50
+ if (isConfigObject(pattern) && isConfigObject(current)) {
51
+ const { changed: childChanged, result: childResult } = prune(current, pattern);
52
+ if (childChanged) {
53
+ changed = true;
54
+ }
55
+ if (Object.keys(childResult).length === 0) {
56
+ delete result[key];
57
+ }
58
+ else {
59
+ setConfigEntry(result, key, childResult);
60
+ }
61
+ continue;
62
+ }
63
+ if (!isConfigObject(pattern) || Object.keys(pattern).length === 0) {
64
+ delete result[key];
65
+ changed = true;
66
+ }
67
+ }
68
+ return { changed, result };
69
+ }
70
+ export const tomlFormat = {
71
+ parse,
72
+ serialize,
73
+ merge,
74
+ prune
75
+ };
@@ -0,0 +1,2 @@
1
+ import type { ConfigFormat } from "../types.js";
2
+ export declare const yamlFormat: ConfigFormat;
@@ -0,0 +1,76 @@
1
+ import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
2
+ import { cloneConfigObject, hasConfigEntry, setConfigEntry } from "./object.js";
3
+ function isConfigObject(value) {
4
+ return typeof value === "object" && value !== null && !Array.isArray(value);
5
+ }
6
+ function parse(content) {
7
+ if (!content || content.trim() === "") {
8
+ return {};
9
+ }
10
+ const parsed = parseYaml(content);
11
+ if (parsed === null || parsed === undefined) {
12
+ return {};
13
+ }
14
+ if (!isConfigObject(parsed)) {
15
+ throw new Error("Expected YAML object.");
16
+ }
17
+ return cloneConfigObject(parsed);
18
+ }
19
+ function serialize(obj) {
20
+ const serialized = stringifyYaml(obj);
21
+ return serialized.endsWith("\n") ? serialized : `${serialized}\n`;
22
+ }
23
+ function merge(base, patch) {
24
+ const result = cloneConfigObject(base);
25
+ for (const [key, value] of Object.entries(patch)) {
26
+ if (value === undefined) {
27
+ continue;
28
+ }
29
+ const existing = hasConfigEntry(result, key) ? result[key] : undefined;
30
+ if (isConfigObject(existing) && isConfigObject(value)) {
31
+ setConfigEntry(result, key, merge(existing, value));
32
+ continue;
33
+ }
34
+ setConfigEntry(result, key, value);
35
+ }
36
+ return result;
37
+ }
38
+ function prune(obj, shape) {
39
+ let changed = false;
40
+ const result = cloneConfigObject(obj);
41
+ for (const [key, pattern] of Object.entries(shape)) {
42
+ if (!hasConfigEntry(result, key)) {
43
+ continue;
44
+ }
45
+ const current = result[key];
46
+ if (isConfigObject(pattern) && Object.keys(pattern).length === 0) {
47
+ delete result[key];
48
+ changed = true;
49
+ continue;
50
+ }
51
+ if (isConfigObject(pattern) && isConfigObject(current)) {
52
+ const { changed: childChanged, result: childResult } = prune(current, pattern);
53
+ if (childChanged) {
54
+ changed = true;
55
+ }
56
+ if (Object.keys(childResult).length === 0) {
57
+ delete result[key];
58
+ }
59
+ else {
60
+ setConfigEntry(result, key, childResult);
61
+ }
62
+ continue;
63
+ }
64
+ if (!isConfigObject(pattern) || Object.keys(pattern).length === 0) {
65
+ delete result[key];
66
+ changed = true;
67
+ }
68
+ }
69
+ return { changed, result };
70
+ }
71
+ export const yamlFormat = {
72
+ parse,
73
+ serialize,
74
+ merge,
75
+ prune
76
+ };
@@ -0,0 +1,18 @@
1
+ import type { FileSystem } from "./types.js";
2
+ /**
3
+ * Check if an error is a "file not found" (ENOENT) error.
4
+ */
5
+ export declare function isNotFound(error: unknown): boolean;
6
+ /**
7
+ * Read a file if it exists, returning null if not found.
8
+ */
9
+ export declare function readFileIfExists(fs: FileSystem, target: string): Promise<string | null>;
10
+ /**
11
+ * Check if a path exists (file or directory).
12
+ */
13
+ export declare function pathExists(fs: FileSystem, target: string): Promise<boolean>;
14
+ /**
15
+ * Create an ISO timestamp safe for use in filenames.
16
+ * Replaces colons and dots with dashes.
17
+ */
18
+ export declare function createTimestamp(): string;
@@ -0,0 +1,43 @@
1
+ import { hasOwnErrorCode } from "./error-codes.js";
2
+ /**
3
+ * Check if an error is a "file not found" (ENOENT) error.
4
+ */
5
+ export function isNotFound(error) {
6
+ return hasOwnErrorCode(error, "ENOENT");
7
+ }
8
+ /**
9
+ * Read a file if it exists, returning null if not found.
10
+ */
11
+ export async function readFileIfExists(fs, target) {
12
+ try {
13
+ return await fs.readFile(target, "utf8");
14
+ }
15
+ catch (error) {
16
+ if (isNotFound(error)) {
17
+ return null;
18
+ }
19
+ throw error;
20
+ }
21
+ }
22
+ /**
23
+ * Check if a path exists (file or directory).
24
+ */
25
+ export async function pathExists(fs, target) {
26
+ try {
27
+ await fs.stat(target);
28
+ return true;
29
+ }
30
+ catch (error) {
31
+ if (isNotFound(error)) {
32
+ return false;
33
+ }
34
+ throw error;
35
+ }
36
+ }
37
+ /**
38
+ * Create an ISO timestamp safe for use in filenames.
39
+ * Replaces colons and dots with dashes.
40
+ */
41
+ export function createTimestamp() {
42
+ return new Date().toISOString().replaceAll(":", "-").replaceAll(".", "-");
43
+ }
@@ -0,0 +1,8 @@
1
+ export { configMutation } from "./mutations/config-mutation.js";
2
+ export { fileMutation } from "./mutations/file-mutation.js";
3
+ export { templateMutation } from "./mutations/template-mutation.js";
4
+ export { runMutations } from "./execution/run-mutations.js";
5
+ export { renderTemplate, type TemplateVariables } from "./template/render.js";
6
+ export { isNotFound, readFileIfExists, pathExists, createTimestamp } from "./fs-utils.js";
7
+ export type { ConfigObject, ConfigValue, Mutation, MutationContext, MutationResult, MutationObservers, MutationDetails, MutationOutcome, FileSystem, TemplateLoader, ConfigFormat, PathMapper } from "./types.js";
8
+ export { isConfigObject } from "./types.js";
@@ -0,0 +1,8 @@
1
+ // Main exports
2
+ export { configMutation } from "./mutations/config-mutation.js";
3
+ export { fileMutation } from "./mutations/file-mutation.js";
4
+ export { templateMutation } from "./mutations/template-mutation.js";
5
+ export { runMutations } from "./execution/run-mutations.js";
6
+ export { renderTemplate } from "./template/render.js";
7
+ export { isNotFound, readFileIfExists, pathExists, createTimestamp } from "./fs-utils.js";
8
+ export { isConfigObject } from "./types.js";