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,47 @@
1
+ import type { ConfigMergeMutation, ConfigPruneMutation, ConfigTransformMutation, ConfigObject, ValueResolver, MutationOptions } from "../types.js";
2
+ export interface MergeOptions {
3
+ /** Target file path (must start with ~) */
4
+ target: ValueResolver<string>;
5
+ /** Value to merge into the config file */
6
+ value: ValueResolver<ConfigObject>;
7
+ /** Optional explicit format override */
8
+ format?: "json" | "toml" | "yaml";
9
+ /** Optional prune by prefix before merging (TOML) */
10
+ pruneByPrefix?: Record<string, string>;
11
+ /** Optional human-readable label for logging */
12
+ label?: string;
13
+ }
14
+ export interface PruneOptions {
15
+ /** Target file path (must start with ~) */
16
+ target: ValueResolver<string>;
17
+ /** Shape to prune from the config file */
18
+ shape: ValueResolver<ConfigObject>;
19
+ /** Optional explicit format override */
20
+ format?: "json" | "toml" | "yaml";
21
+ /** Optional guard - only prune if predicate returns true */
22
+ onlyIf?: (doc: ConfigObject, ctx: MutationOptions) => boolean;
23
+ /** Optional human-readable label for logging */
24
+ label?: string;
25
+ }
26
+ export interface TransformOptions {
27
+ /** Target file path (must start with ~) */
28
+ target: ValueResolver<string>;
29
+ /** Optional explicit format override */
30
+ format?: "json" | "toml" | "yaml";
31
+ /** Transform function - receives parsed content, returns transformed content */
32
+ transform: (content: ConfigObject, ctx: MutationOptions) => {
33
+ content: ConfigObject | null;
34
+ changed: boolean;
35
+ };
36
+ /** Optional human-readable label for logging */
37
+ label?: string;
38
+ }
39
+ declare function merge(options: MergeOptions): ConfigMergeMutation;
40
+ declare function prune(options: PruneOptions): ConfigPruneMutation;
41
+ declare function transform(options: TransformOptions): ConfigTransformMutation;
42
+ export declare const configMutation: {
43
+ merge: typeof merge;
44
+ prune: typeof prune;
45
+ transform: typeof transform;
46
+ };
47
+ export {};
@@ -0,0 +1,34 @@
1
+ function merge(options) {
2
+ return {
3
+ kind: "configMerge",
4
+ target: options.target,
5
+ value: options.value,
6
+ format: options.format,
7
+ pruneByPrefix: options.pruneByPrefix,
8
+ label: options.label
9
+ };
10
+ }
11
+ function prune(options) {
12
+ return {
13
+ kind: "configPrune",
14
+ target: options.target,
15
+ shape: options.shape,
16
+ format: options.format,
17
+ onlyIf: options.onlyIf,
18
+ label: options.label
19
+ };
20
+ }
21
+ function transform(options) {
22
+ return {
23
+ kind: "configTransform",
24
+ target: options.target,
25
+ format: options.format,
26
+ transform: options.transform,
27
+ label: options.label
28
+ };
29
+ }
30
+ export const configMutation = {
31
+ merge,
32
+ prune,
33
+ transform
34
+ };
@@ -0,0 +1,62 @@
1
+ import type { EnsureDirectoryMutation, RemoveDirectoryMutation, RemoveFileMutation, ChmodMutation, BackupMutation, RestoreBackupMutation, ValueResolver } from "../types.js";
2
+ export interface EnsureDirectoryOptions {
3
+ /** Directory path (must start with ~) */
4
+ path: ValueResolver<string>;
5
+ /** Optional human-readable label for logging */
6
+ label?: string;
7
+ }
8
+ export interface RemoveOptions {
9
+ /** Target file path (must start with ~) */
10
+ target: ValueResolver<string>;
11
+ /** Only remove if file is empty/whitespace */
12
+ whenEmpty?: boolean;
13
+ /** Only remove if content matches regex */
14
+ whenContentMatches?: RegExp;
15
+ /** Optional human-readable label for logging */
16
+ label?: string;
17
+ }
18
+ export interface RemoveDirectoryOptions {
19
+ /** Directory path (must start with ~) */
20
+ path: ValueResolver<string>;
21
+ /** Remove directory even when not empty */
22
+ force?: boolean;
23
+ /** Optional human-readable label for logging */
24
+ label?: string;
25
+ }
26
+ export interface ChmodOptions {
27
+ /** Target file path (must start with ~) */
28
+ target: ValueResolver<string>;
29
+ /** File permission mode (e.g., 0o755) */
30
+ mode: number;
31
+ /** Optional human-readable label for logging */
32
+ label?: string;
33
+ }
34
+ export interface BackupOptions {
35
+ /** Target file path to backup (must start with ~) */
36
+ target: ValueResolver<string>;
37
+ /** Keep the first baseline only, including an originally missing target. */
38
+ once?: boolean;
39
+ /** Optional human-readable label for logging */
40
+ label?: string;
41
+ }
42
+ export interface RestoreBackupOptions {
43
+ /** Target file path whose latest generated backup should be restored. */
44
+ target: ValueResolver<string>;
45
+ /** Optional human-readable label for logging */
46
+ label?: string;
47
+ }
48
+ declare function ensureDirectory(options: EnsureDirectoryOptions): EnsureDirectoryMutation;
49
+ declare function remove(options: RemoveOptions): RemoveFileMutation;
50
+ declare function removeDirectory(options: RemoveDirectoryOptions): RemoveDirectoryMutation;
51
+ declare function chmod(options: ChmodOptions): ChmodMutation;
52
+ declare function backup(options: BackupOptions): BackupMutation;
53
+ declare function restoreBackup(options: RestoreBackupOptions): RestoreBackupMutation;
54
+ export declare const fileMutation: {
55
+ ensureDirectory: typeof ensureDirectory;
56
+ remove: typeof remove;
57
+ removeDirectory: typeof removeDirectory;
58
+ chmod: typeof chmod;
59
+ backup: typeof backup;
60
+ restoreBackup: typeof restoreBackup;
61
+ };
62
+ export {};
@@ -0,0 +1,55 @@
1
+ function ensureDirectory(options) {
2
+ return {
3
+ kind: "ensureDirectory",
4
+ path: options.path,
5
+ label: options.label
6
+ };
7
+ }
8
+ function remove(options) {
9
+ return {
10
+ kind: "removeFile",
11
+ target: options.target,
12
+ whenEmpty: options.whenEmpty,
13
+ whenContentMatches: options.whenContentMatches,
14
+ label: options.label
15
+ };
16
+ }
17
+ function removeDirectory(options) {
18
+ return {
19
+ kind: "removeDirectory",
20
+ path: options.path,
21
+ force: options.force,
22
+ label: options.label
23
+ };
24
+ }
25
+ function chmod(options) {
26
+ return {
27
+ kind: "chmod",
28
+ target: options.target,
29
+ mode: options.mode,
30
+ label: options.label
31
+ };
32
+ }
33
+ function backup(options) {
34
+ return {
35
+ kind: "backup",
36
+ target: options.target,
37
+ once: options.once,
38
+ label: options.label
39
+ };
40
+ }
41
+ function restoreBackup(options) {
42
+ return {
43
+ kind: "restoreBackup",
44
+ target: options.target,
45
+ label: options.label
46
+ };
47
+ }
48
+ export const fileMutation = {
49
+ ensureDirectory,
50
+ remove,
51
+ removeDirectory,
52
+ chmod,
53
+ backup,
54
+ restoreBackup
55
+ };
@@ -0,0 +1,40 @@
1
+ import type { TemplateWriteMutation, TemplateMergeTomlMutation, TemplateMergeJsonMutation, ConfigObject, ValueResolver } from "../types.js";
2
+ export interface WriteOptions {
3
+ /** Target file path (must start with ~) */
4
+ target: ValueResolver<string>;
5
+ /** Template ID to load via template loader */
6
+ templateId: string;
7
+ /** Context to pass to renderTemplate() */
8
+ context?: ValueResolver<ConfigObject>;
9
+ /** Optional human-readable label for logging */
10
+ label?: string;
11
+ }
12
+ export interface MergeTomlOptions {
13
+ /** Target TOML file path (must start with ~) */
14
+ target: ValueResolver<string>;
15
+ /** Template ID to load via template loader */
16
+ templateId: string;
17
+ /** Context to pass to renderTemplate() */
18
+ context?: ValueResolver<ConfigObject>;
19
+ /** Optional human-readable label for logging */
20
+ label?: string;
21
+ }
22
+ export interface MergeJsonOptions {
23
+ /** Target JSON file path (must start with ~) */
24
+ target: ValueResolver<string>;
25
+ /** Template ID to load via template loader */
26
+ templateId: string;
27
+ /** Context to pass to renderTemplate() */
28
+ context?: ValueResolver<ConfigObject>;
29
+ /** Optional human-readable label for logging */
30
+ label?: string;
31
+ }
32
+ declare function write(options: WriteOptions): TemplateWriteMutation;
33
+ declare function mergeToml(options: MergeTomlOptions): TemplateMergeTomlMutation;
34
+ declare function mergeJson(options: MergeJsonOptions): TemplateMergeJsonMutation;
35
+ export declare const templateMutation: {
36
+ write: typeof write;
37
+ mergeToml: typeof mergeToml;
38
+ mergeJson: typeof mergeJson;
39
+ };
40
+ export {};
@@ -0,0 +1,32 @@
1
+ function write(options) {
2
+ return {
3
+ kind: "templateWrite",
4
+ target: options.target,
5
+ templateId: options.templateId,
6
+ context: options.context,
7
+ label: options.label
8
+ };
9
+ }
10
+ function mergeToml(options) {
11
+ return {
12
+ kind: "templateMergeToml",
13
+ target: options.target,
14
+ templateId: options.templateId,
15
+ context: options.context,
16
+ label: options.label
17
+ };
18
+ }
19
+ function mergeJson(options) {
20
+ return {
21
+ kind: "templateMergeJson",
22
+ target: options.target,
23
+ templateId: options.templateId,
24
+ context: options.context,
25
+ label: options.label
26
+ };
27
+ }
28
+ export const templateMutation = {
29
+ write,
30
+ mergeToml,
31
+ mergeJson
32
+ };
@@ -0,0 +1,6 @@
1
+ export type TemplateVariables = Record<string, string | number | boolean | string[]>;
2
+ /**
3
+ * Render a mustache template with the given variables.
4
+ * HTML escaping is disabled.
5
+ */
6
+ export declare function renderTemplate(template: string, variables: TemplateVariables): string;
@@ -0,0 +1,8 @@
1
+ import { renderTemplate as renderDesignTemplate } from "toolcraft-design";
2
+ /**
3
+ * Render a mustache template with the given variables.
4
+ * HTML escaping is disabled.
5
+ */
6
+ export function renderTemplate(template, variables) {
7
+ return renderDesignTemplate(template, variables, { escape: "none" });
8
+ }
@@ -0,0 +1,7 @@
1
+ import type { ConfigObject } from "../types.js";
2
+ export declare function parseToml(content: string): ConfigObject;
3
+ export declare function serializeToml(obj: ConfigObject): string;
4
+ export declare function parseJson(content: string): ConfigObject;
5
+ export declare function serializeJson(obj: ConfigObject): string;
6
+ export declare function parseYaml(content: string): ConfigObject;
7
+ export declare function serializeYaml(obj: ConfigObject): string;
@@ -0,0 +1,21 @@
1
+ import { jsonFormat } from "../formats/json.js";
2
+ import { tomlFormat } from "../formats/toml.js";
3
+ import { yamlFormat } from "../formats/yaml.js";
4
+ export function parseToml(content) {
5
+ return tomlFormat.parse(content);
6
+ }
7
+ export function serializeToml(obj) {
8
+ return tomlFormat.serialize(obj);
9
+ }
10
+ export function parseJson(content) {
11
+ return jsonFormat.parse(content);
12
+ }
13
+ export function serializeJson(obj) {
14
+ return jsonFormat.serialize(obj);
15
+ }
16
+ export function parseYaml(content) {
17
+ return yamlFormat.parse(content);
18
+ }
19
+ export function serializeYaml(obj) {
20
+ return yamlFormat.serialize(obj);
21
+ }
@@ -0,0 +1,3 @@
1
+ export { createMockFs } from "./mock-fs.js";
2
+ export type { MockFileSystem } from "./mock-fs.js";
3
+ export { parseToml, serializeToml, parseJson, serializeJson, parseYaml, serializeYaml } from "./format-utils.js";
@@ -0,0 +1,2 @@
1
+ export { createMockFs } from "./mock-fs.js";
2
+ export { parseToml, serializeToml, parseJson, serializeJson, parseYaml, serializeYaml } from "./format-utils.js";
@@ -0,0 +1,25 @@
1
+ import type { FileSystem } from "../types.js";
2
+ export interface MockFileSystem extends FileSystem {
3
+ /** Current file contents, keyed by absolute path */
4
+ files: Record<string, string>;
5
+ /** Created directories */
6
+ directories: Set<string>;
7
+ /** Check if a path exists (file or directory) */
8
+ exists(path: string): boolean;
9
+ /** Get file content or undefined if not found */
10
+ getContent(path: string): string | undefined;
11
+ /** Read file with encoding overloads for compatibility */
12
+ readFile(path: string, encoding: BufferEncoding): Promise<string>;
13
+ readFile(path: string): Promise<Buffer>;
14
+ }
15
+ export interface MockFsOptions {
16
+ /** Initial files - paths can use ~ which will be expanded to homeDir */
17
+ [path: string]: string;
18
+ }
19
+ /**
20
+ * Create an in-memory mock filesystem for testing mutations.
21
+ *
22
+ * @param initialFiles - Initial files to populate the filesystem with
23
+ * @param homeDir - Home directory for ~ expansion (defaults to /home/test)
24
+ */
25
+ export declare function createMockFs(initialFiles?: MockFsOptions, homeDir?: string): MockFileSystem;
@@ -0,0 +1,194 @@
1
+ import path from "node:path";
2
+ const DEFAULT_HOME_DIR = "/home/test";
3
+ /**
4
+ * Create an in-memory mock filesystem for testing mutations.
5
+ *
6
+ * @param initialFiles - Initial files to populate the filesystem with
7
+ * @param homeDir - Home directory for ~ expansion (defaults to /home/test)
8
+ */
9
+ export function createMockFs(initialFiles, homeDir = DEFAULT_HOME_DIR) {
10
+ const files = {};
11
+ const directories = new Set();
12
+ // Initialize with provided files
13
+ if (initialFiles) {
14
+ for (const [filePath, content] of Object.entries(initialFiles)) {
15
+ const absolutePath = expandPath(filePath, homeDir);
16
+ files[absolutePath] = content;
17
+ // Ensure parent directories exist
18
+ const parentDir = path.dirname(absolutePath);
19
+ addDirectoryTree(parentDir, directories);
20
+ }
21
+ }
22
+ // Ensure home directory exists
23
+ addDirectoryTree(homeDir, directories);
24
+ const mockFs = {
25
+ files,
26
+ directories,
27
+ exists(filePath) {
28
+ const absolutePath = expandPath(filePath, homeDir);
29
+ return absolutePath in files || directories.has(absolutePath);
30
+ },
31
+ getContent(filePath) {
32
+ const absolutePath = expandPath(filePath, homeDir);
33
+ return files[absolutePath];
34
+ },
35
+ async readFile(filePath, encoding) {
36
+ const absolutePath = expandPath(filePath, homeDir);
37
+ if (!(absolutePath in files)) {
38
+ const error = new Error(`ENOENT: no such file or directory, open '${absolutePath}'`);
39
+ error.code = "ENOENT";
40
+ throw error;
41
+ }
42
+ const content = files[absolutePath];
43
+ if (encoding) {
44
+ return content;
45
+ }
46
+ return Buffer.from(content, "utf8");
47
+ },
48
+ async writeFile(filePath, content, options) {
49
+ const absolutePath = expandPath(filePath, homeDir);
50
+ if (options?.flag === "wx" && absolutePath in files) {
51
+ const error = new Error(`EEXIST: file already exists, open '${absolutePath}'`);
52
+ error.code = "EEXIST";
53
+ throw error;
54
+ }
55
+ // Ensure parent directory exists
56
+ const parentDir = path.dirname(absolutePath);
57
+ if (!directories.has(parentDir)) {
58
+ const error = new Error(`ENOENT: no such file or directory, open '${absolutePath}'`);
59
+ error.code = "ENOENT";
60
+ throw error;
61
+ }
62
+ if (typeof content === "string") {
63
+ files[absolutePath] = content;
64
+ }
65
+ else if (Buffer.isBuffer(content)) {
66
+ files[absolutePath] = content.toString("utf8");
67
+ }
68
+ else {
69
+ files[absolutePath] = Buffer.from(content.buffer, content.byteOffset, content.byteLength).toString("utf8");
70
+ }
71
+ },
72
+ async mkdir(dirPath, options) {
73
+ const absolutePath = expandPath(dirPath, homeDir);
74
+ if (options?.recursive) {
75
+ addDirectoryTree(absolutePath, directories);
76
+ }
77
+ else {
78
+ // Check parent exists
79
+ const parentDir = path.dirname(absolutePath);
80
+ if (parentDir !== absolutePath && !directories.has(parentDir)) {
81
+ const error = new Error(`ENOENT: no such file or directory, mkdir '${absolutePath}'`);
82
+ error.code = "ENOENT";
83
+ throw error;
84
+ }
85
+ directories.add(absolutePath);
86
+ }
87
+ },
88
+ async unlink(filePath) {
89
+ const absolutePath = expandPath(filePath, homeDir);
90
+ if (!(absolutePath in files)) {
91
+ const error = new Error(`ENOENT: no such file or directory, unlink '${absolutePath}'`);
92
+ error.code = "ENOENT";
93
+ throw error;
94
+ }
95
+ delete files[absolutePath];
96
+ },
97
+ async rename(oldPath, newPath) {
98
+ const absoluteOldPath = expandPath(oldPath, homeDir);
99
+ const absoluteNewPath = expandPath(newPath, homeDir);
100
+ if (!(absoluteOldPath in files)) {
101
+ const error = new Error(`ENOENT: no such file or directory, rename '${absoluteOldPath}'`);
102
+ error.code = "ENOENT";
103
+ throw error;
104
+ }
105
+ files[absoluteNewPath] = files[absoluteOldPath];
106
+ delete files[absoluteOldPath];
107
+ },
108
+ async stat(filePath) {
109
+ const absolutePath = expandPath(filePath, homeDir);
110
+ if (absolutePath in files) {
111
+ return { mode: 0o644 };
112
+ }
113
+ if (directories.has(absolutePath)) {
114
+ return { mode: 0o755 };
115
+ }
116
+ const error = new Error(`ENOENT: no such file or directory, stat '${absolutePath}'`);
117
+ error.code = "ENOENT";
118
+ throw error;
119
+ },
120
+ async lstat(filePath) {
121
+ const absolutePath = expandPath(filePath, homeDir);
122
+ if (absolutePath in files || directories.has(absolutePath)) {
123
+ return { isSymbolicLink: () => false };
124
+ }
125
+ const error = new Error(`ENOENT: no such file or directory, lstat '${absolutePath}'`);
126
+ error.code = "ENOENT";
127
+ throw error;
128
+ },
129
+ async readdir(dirPath) {
130
+ const absolutePath = expandPath(dirPath, homeDir);
131
+ if (absolutePath in files) {
132
+ const error = new Error(`ENOTDIR: not a directory, scandir '${absolutePath}'`);
133
+ error.code = "ENOTDIR";
134
+ throw error;
135
+ }
136
+ if (!directories.has(absolutePath)) {
137
+ const error = new Error(`ENOENT: no such file or directory, scandir '${absolutePath}'`);
138
+ error.code = "ENOENT";
139
+ throw error;
140
+ }
141
+ const entries = new Set();
142
+ for (const filePath of Object.keys(files)) {
143
+ if (path.dirname(filePath) === absolutePath) {
144
+ entries.add(path.basename(filePath));
145
+ }
146
+ }
147
+ for (const dir of directories) {
148
+ if (dir !== absolutePath && path.dirname(dir) === absolutePath) {
149
+ entries.add(path.basename(dir));
150
+ }
151
+ }
152
+ return Array.from(entries);
153
+ },
154
+ async chmod(filePath, mode) {
155
+ void mode; // In mock fs, we don't actually store mode changes
156
+ const absolutePath = expandPath(filePath, homeDir);
157
+ if (!(absolutePath in files) && !directories.has(absolutePath)) {
158
+ const error = new Error(`ENOENT: no such file or directory, chmod '${absolutePath}'`);
159
+ error.code = "ENOENT";
160
+ throw error;
161
+ }
162
+ // Mode change is a no-op in mock fs but we don't throw
163
+ }
164
+ };
165
+ return mockFs;
166
+ }
167
+ /**
168
+ * Expand ~ to homeDir in a path.
169
+ */
170
+ function expandPath(inputPath, homeDir) {
171
+ if (inputPath.startsWith("~/")) {
172
+ return path.join(homeDir, inputPath.slice(2));
173
+ }
174
+ if (inputPath === "~") {
175
+ return homeDir;
176
+ }
177
+ if (inputPath.startsWith("~")) {
178
+ // ~something (not ~/) - treat as relative path from home
179
+ return path.join(homeDir, inputPath.slice(1));
180
+ }
181
+ return inputPath;
182
+ }
183
+ /**
184
+ * Add a directory and all its parent directories to the set.
185
+ */
186
+ function addDirectoryTree(dirPath, directories) {
187
+ const parts = dirPath.split(path.sep).filter(Boolean);
188
+ let current = "/";
189
+ directories.add(current);
190
+ for (const part of parts) {
191
+ current = path.join(current, part);
192
+ directories.add(current);
193
+ }
194
+ }