luca 1.1.2 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (754) hide show
  1. package/.github/workflows/release.yaml +169 -0
  2. package/AGENTS.md +99 -0
  3. package/CLAUDE.md +115 -0
  4. package/CNAME +1 -0
  5. package/README.md +257 -8
  6. package/RUNME.md +56 -0
  7. package/assistants/codingAssistant/ABOUT.md +5 -0
  8. package/assistants/codingAssistant/CORE.md +28 -0
  9. package/assistants/codingAssistant/hooks.ts +21 -0
  10. package/assistants/codingAssistant/tools.ts +12 -0
  11. package/assistants/inkbot/ABOUT.md +16 -0
  12. package/assistants/inkbot/CORE.md +330 -0
  13. package/assistants/inkbot/hooks.ts +6 -0
  14. package/assistants/inkbot/tools.ts +53 -0
  15. package/assistants/researcher/ABOUT.md +5 -0
  16. package/assistants/researcher/CORE.md +46 -0
  17. package/assistants/researcher/hooks.ts +16 -0
  18. package/assistants/researcher/tools.ts +237 -0
  19. package/bun.lock +2769 -0
  20. package/bunfig.toml +3 -0
  21. package/commands/audit-docs.ts +740 -0
  22. package/commands/build-bootstrap.ts +118 -0
  23. package/commands/build-python-bridge.ts +43 -0
  24. package/commands/build-scaffolds.ts +176 -0
  25. package/commands/generate-api-docs.ts +114 -0
  26. package/commands/inkbot.ts +874 -0
  27. package/commands/release.ts +80 -0
  28. package/commands/try-all-challenges.ts +543 -0
  29. package/commands/try-challenge.ts +100 -0
  30. package/dist/agi/container.server.d.ts +63 -0
  31. package/dist/agi/container.server.d.ts.map +1 -0
  32. package/dist/agi/endpoints/ask.d.ts +20 -0
  33. package/dist/agi/endpoints/ask.d.ts.map +1 -0
  34. package/dist/agi/endpoints/conversations/[id].d.ts +27 -0
  35. package/dist/agi/endpoints/conversations/[id].d.ts.map +1 -0
  36. package/dist/agi/endpoints/conversations.d.ts +18 -0
  37. package/dist/agi/endpoints/conversations.d.ts.map +1 -0
  38. package/dist/agi/endpoints/experts.d.ts +8 -0
  39. package/dist/agi/endpoints/experts.d.ts.map +1 -0
  40. package/dist/agi/feature.d.ts +9 -0
  41. package/dist/agi/feature.d.ts.map +1 -0
  42. package/dist/agi/features/assistant.d.ts +509 -0
  43. package/dist/agi/features/assistant.d.ts.map +1 -0
  44. package/dist/agi/features/assistants-manager.d.ts +236 -0
  45. package/dist/agi/features/assistants-manager.d.ts.map +1 -0
  46. package/dist/agi/features/autonomous-assistant.d.ts +281 -0
  47. package/dist/agi/features/autonomous-assistant.d.ts.map +1 -0
  48. package/dist/agi/features/browser-use.d.ts +479 -0
  49. package/dist/agi/features/browser-use.d.ts.map +1 -0
  50. package/dist/agi/features/claude-code.d.ts +824 -0
  51. package/dist/agi/features/claude-code.d.ts.map +1 -0
  52. package/dist/agi/features/conversation-history.d.ts +245 -0
  53. package/dist/agi/features/conversation-history.d.ts.map +1 -0
  54. package/dist/agi/features/conversation.d.ts +464 -0
  55. package/dist/agi/features/conversation.d.ts.map +1 -0
  56. package/dist/agi/features/docs-reader.d.ts +72 -0
  57. package/dist/agi/features/docs-reader.d.ts.map +1 -0
  58. package/dist/agi/features/file-tools.d.ts +110 -0
  59. package/dist/agi/features/file-tools.d.ts.map +1 -0
  60. package/dist/agi/features/luca-coder.d.ts +323 -0
  61. package/dist/agi/features/luca-coder.d.ts.map +1 -0
  62. package/dist/agi/features/openai-codex.d.ts +381 -0
  63. package/dist/agi/features/openai-codex.d.ts.map +1 -0
  64. package/dist/agi/features/openapi.d.ts +200 -0
  65. package/dist/agi/features/openapi.d.ts.map +1 -0
  66. package/dist/agi/features/skills-library.d.ts +167 -0
  67. package/dist/agi/features/skills-library.d.ts.map +1 -0
  68. package/dist/agi/index.d.ts +5 -0
  69. package/dist/agi/index.d.ts.map +1 -0
  70. package/dist/agi/lib/interceptor-chain.d.ts +44 -0
  71. package/dist/agi/lib/interceptor-chain.d.ts.map +1 -0
  72. package/dist/agi/lib/token-counter.d.ts +13 -0
  73. package/dist/agi/lib/token-counter.d.ts.map +1 -0
  74. package/dist/bootstrap/generated.d.ts +5 -0
  75. package/dist/bootstrap/generated.d.ts.map +1 -0
  76. package/dist/browser.d.ts +12 -0
  77. package/dist/browser.d.ts.map +1 -0
  78. package/dist/bus.d.ts +29 -0
  79. package/dist/bus.d.ts.map +1 -0
  80. package/dist/cli/build-info.d.ts +4 -0
  81. package/dist/cli/build-info.d.ts.map +1 -0
  82. package/dist/cli/cli.d.ts +3 -0
  83. package/dist/cli/cli.d.ts.map +1 -0
  84. package/dist/client.d.ts +60 -0
  85. package/dist/client.d.ts.map +1 -0
  86. package/dist/clients/civitai/index.d.ts +472 -0
  87. package/dist/clients/civitai/index.d.ts.map +1 -0
  88. package/dist/clients/client-template.d.ts +30 -0
  89. package/dist/clients/client-template.d.ts.map +1 -0
  90. package/dist/clients/comfyui/index.d.ts +281 -0
  91. package/dist/clients/comfyui/index.d.ts.map +1 -0
  92. package/dist/clients/elevenlabs/index.d.ts +197 -0
  93. package/dist/clients/elevenlabs/index.d.ts.map +1 -0
  94. package/dist/clients/graph.d.ts +64 -0
  95. package/dist/clients/graph.d.ts.map +1 -0
  96. package/dist/clients/openai/index.d.ts +247 -0
  97. package/dist/clients/openai/index.d.ts.map +1 -0
  98. package/dist/clients/rest.d.ts +92 -0
  99. package/dist/clients/rest.d.ts.map +1 -0
  100. package/dist/clients/supabase/index.d.ts +176 -0
  101. package/dist/clients/supabase/index.d.ts.map +1 -0
  102. package/dist/clients/websocket.d.ts +127 -0
  103. package/dist/clients/websocket.d.ts.map +1 -0
  104. package/dist/command.d.ts +163 -0
  105. package/dist/command.d.ts.map +1 -0
  106. package/dist/commands/bootstrap.d.ts +20 -0
  107. package/dist/commands/bootstrap.d.ts.map +1 -0
  108. package/dist/commands/chat.d.ts +37 -0
  109. package/dist/commands/chat.d.ts.map +1 -0
  110. package/dist/commands/code.d.ts +28 -0
  111. package/dist/commands/code.d.ts.map +1 -0
  112. package/dist/commands/console.d.ts +22 -0
  113. package/dist/commands/console.d.ts.map +1 -0
  114. package/dist/commands/describe.d.ts +50 -0
  115. package/dist/commands/describe.d.ts.map +1 -0
  116. package/dist/commands/eval.d.ts +23 -0
  117. package/dist/commands/eval.d.ts.map +1 -0
  118. package/dist/commands/help.d.ts +25 -0
  119. package/dist/commands/help.d.ts.map +1 -0
  120. package/dist/commands/index.d.ts +18 -0
  121. package/dist/commands/index.d.ts.map +1 -0
  122. package/dist/commands/introspect.d.ts +24 -0
  123. package/dist/commands/introspect.d.ts.map +1 -0
  124. package/dist/commands/mcp.d.ts +35 -0
  125. package/dist/commands/mcp.d.ts.map +1 -0
  126. package/dist/commands/prompt.d.ts +38 -0
  127. package/dist/commands/prompt.d.ts.map +1 -0
  128. package/dist/commands/run.d.ts +24 -0
  129. package/dist/commands/run.d.ts.map +1 -0
  130. package/dist/commands/sandbox-mcp.d.ts +34 -0
  131. package/dist/commands/sandbox-mcp.d.ts.map +1 -0
  132. package/dist/commands/save-api-docs.d.ts +21 -0
  133. package/dist/commands/save-api-docs.d.ts.map +1 -0
  134. package/dist/commands/scaffold.d.ts +24 -0
  135. package/dist/commands/scaffold.d.ts.map +1 -0
  136. package/dist/commands/select.d.ts +22 -0
  137. package/dist/commands/select.d.ts.map +1 -0
  138. package/dist/commands/serve.d.ts +29 -0
  139. package/dist/commands/serve.d.ts.map +1 -0
  140. package/dist/container-describer.d.ts +144 -0
  141. package/dist/container-describer.d.ts.map +1 -0
  142. package/dist/container.d.ts +451 -0
  143. package/dist/container.d.ts.map +1 -0
  144. package/dist/endpoint.d.ts +113 -0
  145. package/dist/endpoint.d.ts.map +1 -0
  146. package/dist/feature.d.ts +47 -0
  147. package/dist/feature.d.ts.map +1 -0
  148. package/dist/graft.d.ts +29 -0
  149. package/dist/graft.d.ts.map +1 -0
  150. package/dist/hash-object.d.ts +8 -0
  151. package/dist/hash-object.d.ts.map +1 -0
  152. package/dist/helper.d.ts +209 -0
  153. package/dist/helper.d.ts.map +1 -0
  154. package/dist/introspection/generated.node.d.ts +44623 -0
  155. package/dist/introspection/generated.node.d.ts.map +1 -0
  156. package/dist/introspection/generated.web.d.ts +1412 -0
  157. package/dist/introspection/generated.web.d.ts.map +1 -0
  158. package/dist/introspection/index.d.ts +156 -0
  159. package/dist/introspection/index.d.ts.map +1 -0
  160. package/dist/introspection/scan.d.ts +147 -0
  161. package/dist/introspection/scan.d.ts.map +1 -0
  162. package/dist/node/container.d.ts +256 -0
  163. package/dist/node/container.d.ts.map +1 -0
  164. package/dist/node/feature.d.ts +9 -0
  165. package/dist/node/feature.d.ts.map +1 -0
  166. package/dist/node/features/container-link.d.ts +213 -0
  167. package/dist/node/features/container-link.d.ts.map +1 -0
  168. package/dist/node/features/content-db.d.ts +354 -0
  169. package/dist/node/features/content-db.d.ts.map +1 -0
  170. package/dist/node/features/disk-cache.d.ts +236 -0
  171. package/dist/node/features/disk-cache.d.ts.map +1 -0
  172. package/dist/node/features/dns.d.ts +511 -0
  173. package/dist/node/features/dns.d.ts.map +1 -0
  174. package/dist/node/features/docker.d.ts +485 -0
  175. package/dist/node/features/docker.d.ts.map +1 -0
  176. package/dist/node/features/downloader.d.ts +73 -0
  177. package/dist/node/features/downloader.d.ts.map +1 -0
  178. package/dist/node/features/figlet-fonts.d.ts +4 -0
  179. package/dist/node/features/figlet-fonts.d.ts.map +1 -0
  180. package/dist/node/features/file-manager.d.ts +177 -0
  181. package/dist/node/features/file-manager.d.ts.map +1 -0
  182. package/dist/node/features/fs.d.ts +635 -0
  183. package/dist/node/features/fs.d.ts.map +1 -0
  184. package/dist/node/features/git.d.ts +329 -0
  185. package/dist/node/features/git.d.ts.map +1 -0
  186. package/dist/node/features/google-auth.d.ts +200 -0
  187. package/dist/node/features/google-auth.d.ts.map +1 -0
  188. package/dist/node/features/google-calendar.d.ts +194 -0
  189. package/dist/node/features/google-calendar.d.ts.map +1 -0
  190. package/dist/node/features/google-docs.d.ts +138 -0
  191. package/dist/node/features/google-docs.d.ts.map +1 -0
  192. package/dist/node/features/google-drive.d.ts +202 -0
  193. package/dist/node/features/google-drive.d.ts.map +1 -0
  194. package/dist/node/features/google-mail.d.ts +221 -0
  195. package/dist/node/features/google-mail.d.ts.map +1 -0
  196. package/dist/node/features/google-sheets.d.ts +157 -0
  197. package/dist/node/features/google-sheets.d.ts.map +1 -0
  198. package/dist/node/features/grep.d.ts +207 -0
  199. package/dist/node/features/grep.d.ts.map +1 -0
  200. package/dist/node/features/helpers.d.ts +236 -0
  201. package/dist/node/features/helpers.d.ts.map +1 -0
  202. package/dist/node/features/ink.d.ts +332 -0
  203. package/dist/node/features/ink.d.ts.map +1 -0
  204. package/dist/node/features/ipc-socket.d.ts +298 -0
  205. package/dist/node/features/ipc-socket.d.ts.map +1 -0
  206. package/dist/node/features/json-tree.d.ts +140 -0
  207. package/dist/node/features/json-tree.d.ts.map +1 -0
  208. package/dist/node/features/networking.d.ts +373 -0
  209. package/dist/node/features/networking.d.ts.map +1 -0
  210. package/dist/node/features/nlp.d.ts +125 -0
  211. package/dist/node/features/nlp.d.ts.map +1 -0
  212. package/dist/node/features/opener.d.ts +93 -0
  213. package/dist/node/features/opener.d.ts.map +1 -0
  214. package/dist/node/features/os.d.ts +168 -0
  215. package/dist/node/features/os.d.ts.map +1 -0
  216. package/dist/node/features/package-finder.d.ts +419 -0
  217. package/dist/node/features/package-finder.d.ts.map +1 -0
  218. package/dist/node/features/postgres.d.ts +173 -0
  219. package/dist/node/features/postgres.d.ts.map +1 -0
  220. package/dist/node/features/proc.d.ts +285 -0
  221. package/dist/node/features/proc.d.ts.map +1 -0
  222. package/dist/node/features/process-manager.d.ts +427 -0
  223. package/dist/node/features/process-manager.d.ts.map +1 -0
  224. package/dist/node/features/python.d.ts +477 -0
  225. package/dist/node/features/python.d.ts.map +1 -0
  226. package/dist/node/features/redis.d.ts +247 -0
  227. package/dist/node/features/redis.d.ts.map +1 -0
  228. package/dist/node/features/repl.d.ts +84 -0
  229. package/dist/node/features/repl.d.ts.map +1 -0
  230. package/dist/node/features/runpod.d.ts +527 -0
  231. package/dist/node/features/runpod.d.ts.map +1 -0
  232. package/dist/node/features/secure-shell.d.ts +145 -0
  233. package/dist/node/features/secure-shell.d.ts.map +1 -0
  234. package/dist/node/features/semantic-search.d.ts +207 -0
  235. package/dist/node/features/semantic-search.d.ts.map +1 -0
  236. package/dist/node/features/sqlite.d.ts +180 -0
  237. package/dist/node/features/sqlite.d.ts.map +1 -0
  238. package/dist/node/features/telegram.d.ts +173 -0
  239. package/dist/node/features/telegram.d.ts.map +1 -0
  240. package/dist/node/features/transpiler.d.ts +51 -0
  241. package/dist/node/features/transpiler.d.ts.map +1 -0
  242. package/dist/node/features/tts.d.ts +108 -0
  243. package/dist/node/features/tts.d.ts.map +1 -0
  244. package/dist/node/features/ui.d.ts +562 -0
  245. package/dist/node/features/ui.d.ts.map +1 -0
  246. package/dist/node/features/vault.d.ts +90 -0
  247. package/dist/node/features/vault.d.ts.map +1 -0
  248. package/dist/node/features/vm.d.ts +285 -0
  249. package/dist/node/features/vm.d.ts.map +1 -0
  250. package/dist/node/features/yaml-tree.d.ts +118 -0
  251. package/dist/node/features/yaml-tree.d.ts.map +1 -0
  252. package/dist/node/features/yaml.d.ts +127 -0
  253. package/dist/node/features/yaml.d.ts.map +1 -0
  254. package/dist/node.d.ts +67 -0
  255. package/dist/node.d.ts.map +1 -0
  256. package/dist/python/generated.d.ts +2 -0
  257. package/dist/python/generated.d.ts.map +1 -0
  258. package/dist/react/index.d.ts +36 -0
  259. package/dist/react/index.d.ts.map +1 -0
  260. package/dist/registry.d.ts +97 -0
  261. package/dist/registry.d.ts.map +1 -0
  262. package/dist/scaffolds/generated.d.ts +13 -0
  263. package/dist/scaffolds/generated.d.ts.map +1 -0
  264. package/dist/scaffolds/template.d.ts +11 -0
  265. package/dist/scaffolds/template.d.ts.map +1 -0
  266. package/dist/schemas/base.d.ts +254 -0
  267. package/dist/schemas/base.d.ts.map +1 -0
  268. package/dist/selector.d.ts +130 -0
  269. package/dist/selector.d.ts.map +1 -0
  270. package/dist/server.d.ts +89 -0
  271. package/dist/server.d.ts.map +1 -0
  272. package/dist/servers/express.d.ts +104 -0
  273. package/dist/servers/express.d.ts.map +1 -0
  274. package/dist/servers/mcp.d.ts +201 -0
  275. package/dist/servers/mcp.d.ts.map +1 -0
  276. package/dist/servers/socket.d.ts +121 -0
  277. package/dist/servers/socket.d.ts.map +1 -0
  278. package/dist/state.d.ts +24 -0
  279. package/dist/state.d.ts.map +1 -0
  280. package/dist/web/clients/socket.d.ts +37 -0
  281. package/dist/web/clients/socket.d.ts.map +1 -0
  282. package/dist/web/container.d.ts +55 -0
  283. package/dist/web/container.d.ts.map +1 -0
  284. package/dist/web/extension.d.ts +4 -0
  285. package/dist/web/extension.d.ts.map +1 -0
  286. package/dist/web/feature.d.ts +8 -0
  287. package/dist/web/feature.d.ts.map +1 -0
  288. package/dist/web/features/asset-loader.d.ts +35 -0
  289. package/dist/web/features/asset-loader.d.ts.map +1 -0
  290. package/dist/web/features/container-link.d.ts +167 -0
  291. package/dist/web/features/container-link.d.ts.map +1 -0
  292. package/dist/web/features/esbuild.d.ts +51 -0
  293. package/dist/web/features/esbuild.d.ts.map +1 -0
  294. package/dist/web/features/helpers.d.ts +140 -0
  295. package/dist/web/features/helpers.d.ts.map +1 -0
  296. package/dist/web/features/network.d.ts +69 -0
  297. package/dist/web/features/network.d.ts.map +1 -0
  298. package/dist/web/features/speech.d.ts +71 -0
  299. package/dist/web/features/speech.d.ts.map +1 -0
  300. package/dist/web/features/vault.d.ts +62 -0
  301. package/dist/web/features/vault.d.ts.map +1 -0
  302. package/dist/web/features/vm.d.ts +48 -0
  303. package/dist/web/features/vm.d.ts.map +1 -0
  304. package/dist/web/features/voice-recognition.d.ts +96 -0
  305. package/dist/web/features/voice-recognition.d.ts.map +1 -0
  306. package/dist/web/shims/isomorphic-vm.d.ts +22 -0
  307. package/dist/web/shims/isomorphic-vm.d.ts.map +1 -0
  308. package/docs/CLI.md +335 -0
  309. package/docs/CNAME +1 -0
  310. package/docs/README.md +60 -0
  311. package/docs/TABLE-OF-CONTENTS.md +183 -0
  312. package/docs/apis/clients/elevenlabs.md +308 -0
  313. package/docs/apis/clients/graph.md +107 -0
  314. package/docs/apis/clients/openai.md +429 -0
  315. package/docs/apis/clients/rest.md +161 -0
  316. package/docs/apis/clients/websocket.md +174 -0
  317. package/docs/apis/features/agi/assistant.md +625 -0
  318. package/docs/apis/features/agi/assistants-manager.md +282 -0
  319. package/docs/apis/features/agi/auto-assistant.md +279 -0
  320. package/docs/apis/features/agi/browser-use.md +802 -0
  321. package/docs/apis/features/agi/claude-code.md +884 -0
  322. package/docs/apis/features/agi/conversation-history.md +364 -0
  323. package/docs/apis/features/agi/conversation.md +548 -0
  324. package/docs/apis/features/agi/docs-reader.md +99 -0
  325. package/docs/apis/features/agi/file-tools.md +163 -0
  326. package/docs/apis/features/agi/luca-coder.md +407 -0
  327. package/docs/apis/features/agi/openai-codex.md +396 -0
  328. package/docs/apis/features/agi/openapi.md +138 -0
  329. package/docs/apis/features/agi/semantic-search.md +387 -0
  330. package/docs/apis/features/agi/skills-library.md +239 -0
  331. package/docs/apis/features/node/container-link.md +192 -0
  332. package/docs/apis/features/node/content-db.md +450 -0
  333. package/docs/apis/features/node/disk-cache.md +379 -0
  334. package/docs/apis/features/node/dns.md +652 -0
  335. package/docs/apis/features/node/docker.md +706 -0
  336. package/docs/apis/features/node/downloader.md +81 -0
  337. package/docs/apis/features/node/esbuild.md +60 -0
  338. package/docs/apis/features/node/file-manager.md +191 -0
  339. package/docs/apis/features/node/fs.md +1217 -0
  340. package/docs/apis/features/node/git.md +371 -0
  341. package/docs/apis/features/node/google-auth.md +193 -0
  342. package/docs/apis/features/node/google-calendar.md +202 -0
  343. package/docs/apis/features/node/google-docs.md +173 -0
  344. package/docs/apis/features/node/google-drive.md +246 -0
  345. package/docs/apis/features/node/google-mail.md +214 -0
  346. package/docs/apis/features/node/google-sheets.md +194 -0
  347. package/docs/apis/features/node/grep.md +292 -0
  348. package/docs/apis/features/node/helpers.md +164 -0
  349. package/docs/apis/features/node/ink.md +334 -0
  350. package/docs/apis/features/node/ipc-socket.md +249 -0
  351. package/docs/apis/features/node/json-tree.md +86 -0
  352. package/docs/apis/features/node/networking.md +316 -0
  353. package/docs/apis/features/node/nlp.md +133 -0
  354. package/docs/apis/features/node/opener.md +97 -0
  355. package/docs/apis/features/node/os.md +146 -0
  356. package/docs/apis/features/node/package-finder.md +392 -0
  357. package/docs/apis/features/node/postgres.md +234 -0
  358. package/docs/apis/features/node/proc.md +399 -0
  359. package/docs/apis/features/node/process-manager.md +305 -0
  360. package/docs/apis/features/node/python.md +604 -0
  361. package/docs/apis/features/node/redis.md +380 -0
  362. package/docs/apis/features/node/repl.md +88 -0
  363. package/docs/apis/features/node/runpod.md +674 -0
  364. package/docs/apis/features/node/secure-shell.md +176 -0
  365. package/docs/apis/features/node/semantic-search.md +408 -0
  366. package/docs/apis/features/node/sqlite.md +233 -0
  367. package/docs/apis/features/node/telegram.md +279 -0
  368. package/docs/apis/features/node/transpiler.md +74 -0
  369. package/docs/apis/features/node/tts.md +133 -0
  370. package/docs/apis/features/node/ui.md +701 -0
  371. package/docs/apis/features/node/vault.md +59 -0
  372. package/docs/apis/features/node/vm.md +75 -0
  373. package/docs/apis/features/node/yaml-tree.md +85 -0
  374. package/docs/apis/features/node/yaml.md +176 -0
  375. package/docs/apis/features/web/asset-loader.md +59 -0
  376. package/docs/apis/features/web/container-link.md +192 -0
  377. package/docs/apis/features/web/esbuild.md +54 -0
  378. package/docs/apis/features/web/helpers.md +164 -0
  379. package/docs/apis/features/web/network.md +44 -0
  380. package/docs/apis/features/web/speech.md +69 -0
  381. package/docs/apis/features/web/vault.md +59 -0
  382. package/docs/apis/features/web/vm.md +75 -0
  383. package/docs/apis/features/web/voice.md +84 -0
  384. package/docs/apis/servers/express.md +171 -0
  385. package/docs/apis/servers/mcp.md +238 -0
  386. package/docs/apis/servers/websocket.md +170 -0
  387. package/docs/bootstrap/CLAUDE.md +101 -0
  388. package/docs/bootstrap/SKILL.md +341 -0
  389. package/docs/bootstrap/templates/about-command.ts +41 -0
  390. package/docs/bootstrap/templates/docs-models.ts +22 -0
  391. package/docs/bootstrap/templates/docs-readme.md +43 -0
  392. package/docs/bootstrap/templates/example-feature.ts +53 -0
  393. package/docs/bootstrap/templates/health-endpoint.ts +15 -0
  394. package/docs/bootstrap/templates/luca-cli.ts +30 -0
  395. package/docs/bootstrap/templates/runme.md +54 -0
  396. package/docs/challenges/caching-proxy.md +16 -0
  397. package/docs/challenges/content-db-round-trip.md +14 -0
  398. package/docs/challenges/custom-command.md +9 -0
  399. package/docs/challenges/file-watcher-pipeline.md +11 -0
  400. package/docs/challenges/grep-audit-report.md +15 -0
  401. package/docs/challenges/multi-feature-dashboard.md +14 -0
  402. package/docs/challenges/process-orchestrator.md +17 -0
  403. package/docs/challenges/rest-api-server-with-client.md +12 -0
  404. package/docs/challenges/script-runner-with-vm.md +11 -0
  405. package/docs/challenges/simple-rest-api.md +15 -0
  406. package/docs/challenges/websocket-serve-and-client.md +11 -0
  407. package/docs/challenges/yaml-config-system.md +14 -0
  408. package/docs/command-system-overhaul.md +94 -0
  409. package/docs/documentation-audit.md +134 -0
  410. package/docs/examples/assistant/CORE.md +18 -0
  411. package/docs/examples/assistant/hooks.ts +3 -0
  412. package/docs/examples/assistant/tools.ts +10 -0
  413. package/docs/examples/assistant-hooks-reference.ts +171 -0
  414. package/docs/examples/assistant-with-process-manager.md +84 -0
  415. package/docs/examples/content-db.md +77 -0
  416. package/docs/examples/disk-cache.md +83 -0
  417. package/docs/examples/docker.md +101 -0
  418. package/docs/examples/downloader.md +70 -0
  419. package/docs/examples/entity.md +124 -0
  420. package/docs/examples/esbuild.md +80 -0
  421. package/docs/examples/feature-as-tool-provider.md +143 -0
  422. package/docs/examples/file-manager.md +82 -0
  423. package/docs/examples/fs.md +83 -0
  424. package/docs/examples/git.md +85 -0
  425. package/docs/examples/google-auth.md +88 -0
  426. package/docs/examples/google-calendar.md +94 -0
  427. package/docs/examples/google-docs.md +82 -0
  428. package/docs/examples/google-drive.md +96 -0
  429. package/docs/examples/google-sheets.md +95 -0
  430. package/docs/examples/grep.md +85 -0
  431. package/docs/examples/ink-blocks.md +75 -0
  432. package/docs/examples/ink-renderer.md +41 -0
  433. package/docs/examples/ink.md +103 -0
  434. package/docs/examples/ipc-socket.md +103 -0
  435. package/docs/examples/json-tree.md +91 -0
  436. package/docs/examples/networking.md +58 -0
  437. package/docs/examples/nlp.md +91 -0
  438. package/docs/examples/opener.md +78 -0
  439. package/docs/examples/os.md +72 -0
  440. package/docs/examples/package-finder.md +89 -0
  441. package/docs/examples/postgres.md +91 -0
  442. package/docs/examples/proc.md +81 -0
  443. package/docs/examples/process-manager.md +79 -0
  444. package/docs/examples/python.md +132 -0
  445. package/docs/examples/repl.md +93 -0
  446. package/docs/examples/runpod.md +119 -0
  447. package/docs/examples/secure-shell.md +92 -0
  448. package/docs/examples/sqlite.md +86 -0
  449. package/docs/examples/structured-output-with-assistants.md +144 -0
  450. package/docs/examples/telegram.md +77 -0
  451. package/docs/examples/tts.md +86 -0
  452. package/docs/examples/ui.md +80 -0
  453. package/docs/examples/vault.md +70 -0
  454. package/docs/examples/vm.md +86 -0
  455. package/docs/examples/websocket-ask-and-reply-example.md +128 -0
  456. package/docs/examples/yaml-tree.md +93 -0
  457. package/docs/examples/yaml.md +104 -0
  458. package/docs/ideas/assistant-factory-pattern.md +142 -0
  459. package/docs/in-memory-fs.md +4 -0
  460. package/docs/introspection-audit.md +49 -0
  461. package/docs/introspection.md +164 -0
  462. package/docs/mcp/readme.md +162 -0
  463. package/docs/models.ts +41 -0
  464. package/docs/philosophy.md +86 -0
  465. package/docs/principles.md +7 -0
  466. package/docs/prompts/audit-codebase-for-failures-to-use-the-container.md +34 -0
  467. package/docs/prompts/check-for-undocumented-features.md +27 -0
  468. package/docs/prompts/mcp-test-easy-command.md +27 -0
  469. package/docs/scaffolds/client.md +149 -0
  470. package/docs/scaffolds/command.md +120 -0
  471. package/docs/scaffolds/endpoint.md +171 -0
  472. package/docs/scaffolds/feature.md +158 -0
  473. package/docs/scaffolds/selector.md +91 -0
  474. package/docs/scaffolds/server.md +196 -0
  475. package/docs/selectors.md +115 -0
  476. package/docs/sessions/custom-command/attempt-log-2.md +195 -0
  477. package/docs/sessions/file-watcher-pipeline/attempt-log-1.md +728 -0
  478. package/docs/sessions/file-watcher-pipeline/attempt-log-2.md +555 -0
  479. package/docs/sessions/grep-audit-report/attempt-log-1.md +289 -0
  480. package/docs/sessions/multi-feature-dashboard/attempt-log-2.md +679 -0
  481. package/docs/sessions/rest-api-server-with-client/attempt-log-1.md +1 -0
  482. package/docs/sessions/rest-api-server-with-client/attempt-log-3.md +920 -0
  483. package/docs/sessions/simple-rest-api/attempt-log-1.md +593 -0
  484. package/docs/sessions/websocket-serve-and-client/attempt-log-2.md +995 -0
  485. package/docs/tutorials/00-bootstrap.md +166 -0
  486. package/docs/tutorials/01-getting-started.md +106 -0
  487. package/docs/tutorials/02-container.md +210 -0
  488. package/docs/tutorials/03-scripts.md +194 -0
  489. package/docs/tutorials/04-features-overview.md +196 -0
  490. package/docs/tutorials/05-state-and-events.md +171 -0
  491. package/docs/tutorials/06-servers.md +157 -0
  492. package/docs/tutorials/07-endpoints.md +198 -0
  493. package/docs/tutorials/08-commands.md +252 -0
  494. package/docs/tutorials/09-clients.md +162 -0
  495. package/docs/tutorials/10-creating-features.md +203 -0
  496. package/docs/tutorials/11-contentbase.md +191 -0
  497. package/docs/tutorials/12-assistants.md +215 -0
  498. package/docs/tutorials/13-introspection.md +157 -0
  499. package/docs/tutorials/14-type-system.md +174 -0
  500. package/docs/tutorials/15-project-patterns.md +222 -0
  501. package/docs/tutorials/16-google-features.md +534 -0
  502. package/docs/tutorials/17-tui-blocks.md +530 -0
  503. package/docs/tutorials/18-semantic-search.md +334 -0
  504. package/docs/tutorials/19-python-sessions.md +401 -0
  505. package/docs/tutorials/20-browser-esm.md +234 -0
  506. package/index.html +1430 -0
  507. package/index.ts +1 -0
  508. package/install.sh +84 -0
  509. package/luca.cli.ts +16 -0
  510. package/luca.console.ts +9 -0
  511. package/main.py +6 -0
  512. package/package.json +219 -66
  513. package/public/index.html +1430 -0
  514. package/public/slides-ai-native.html +902 -0
  515. package/public/slides-intro.html +974 -0
  516. package/pyproject.toml +7 -0
  517. package/scripts/build-web.ts +28 -0
  518. package/scripts/examples/ask-luca-expert.ts +42 -0
  519. package/scripts/examples/assistant-questions.ts +12 -0
  520. package/scripts/examples/excalidraw-expert.ts +75 -0
  521. package/scripts/examples/expert-chat.ts +0 -0
  522. package/scripts/examples/file-manager.ts +14 -0
  523. package/scripts/examples/ideas.ts +12 -0
  524. package/scripts/examples/interactive-chat.ts +20 -0
  525. package/scripts/examples/openai-tool-calls.ts +113 -0
  526. package/scripts/examples/opening-a-web-browser.ts +5 -0
  527. package/scripts/examples/telegram-bot.ts +79 -0
  528. package/scripts/examples/using-assistant-with-mcp.ts +555 -0
  529. package/scripts/examples/using-claude-code.ts +10 -0
  530. package/scripts/examples/using-contentdb.ts +35 -0
  531. package/scripts/examples/using-conversations.ts +35 -0
  532. package/scripts/examples/using-disk-cache.ts +10 -0
  533. package/scripts/examples/using-docker-shell.ts +75 -0
  534. package/scripts/examples/using-elevenlabs.ts +25 -0
  535. package/scripts/examples/using-google-calendar.ts +57 -0
  536. package/scripts/examples/using-google-docs.ts +74 -0
  537. package/scripts/examples/using-google-drive.ts +74 -0
  538. package/scripts/examples/using-google-sheets.ts +89 -0
  539. package/scripts/examples/using-nlp.ts +55 -0
  540. package/scripts/examples/using-ollama.ts +11 -0
  541. package/scripts/examples/using-postgres.ts +55 -0
  542. package/scripts/examples/using-runpod.ts +32 -0
  543. package/scripts/examples/using-tts.ts +40 -0
  544. package/scripts/scaffold.ts +391 -0
  545. package/scripts/scratch.ts +15 -0
  546. package/scripts/stamp-build.sh +12 -0
  547. package/scripts/test-assistant-hooks.ts +13 -0
  548. package/scripts/test-docs-reader.ts +10 -0
  549. package/scripts/test-linux-binary.sh +80 -0
  550. package/scripts/update-introspection-data.ts +58 -0
  551. package/src/agi/README.md +14 -0
  552. package/src/agi/container.server.ts +152 -0
  553. package/src/agi/endpoints/ask.ts +60 -0
  554. package/src/agi/endpoints/conversations/[id].ts +45 -0
  555. package/src/agi/endpoints/conversations.ts +31 -0
  556. package/src/agi/endpoints/experts.ts +37 -0
  557. package/src/agi/feature.ts +13 -0
  558. package/src/agi/features/agent-memory.ts +694 -0
  559. package/src/agi/features/assistant.ts +1624 -0
  560. package/src/agi/features/assistants-manager.ts +418 -0
  561. package/src/agi/features/autonomous-assistant.ts +431 -0
  562. package/src/agi/features/browser-use.ts +653 -0
  563. package/src/agi/features/claude-code.ts +1538 -0
  564. package/src/agi/features/coding-tools.ts +175 -0
  565. package/src/agi/features/conversation-history.ts +495 -0
  566. package/src/agi/features/conversation.ts +1323 -0
  567. package/src/agi/features/docs-reader.ts +167 -0
  568. package/src/agi/features/file-tools.ts +293 -0
  569. package/src/agi/features/luca-coder.ts +639 -0
  570. package/src/agi/features/openai-codex.ts +651 -0
  571. package/src/agi/features/openapi.ts +445 -0
  572. package/src/agi/features/skills-library.ts +478 -0
  573. package/src/agi/index.ts +6 -0
  574. package/src/agi/lib/interceptor-chain.ts +89 -0
  575. package/src/agi/lib/token-counter.ts +122 -0
  576. package/src/bootstrap/generated.ts +9792 -0
  577. package/src/browser.ts +25 -0
  578. package/src/bus.ts +122 -0
  579. package/src/cli/build-info.ts +4 -0
  580. package/src/cli/cli.ts +355 -0
  581. package/src/client.ts +170 -0
  582. package/src/clients/civitai/index.ts +537 -0
  583. package/src/clients/client-template.ts +41 -0
  584. package/src/clients/comfyui/index.ts +604 -0
  585. package/src/clients/elevenlabs/index.ts +317 -0
  586. package/src/clients/graph.ts +87 -0
  587. package/src/clients/openai/index.ts +456 -0
  588. package/src/clients/rest.ts +207 -0
  589. package/src/clients/supabase/index.ts +357 -0
  590. package/src/clients/voicebox/index.ts +300 -0
  591. package/src/clients/websocket.ts +251 -0
  592. package/src/command.ts +505 -0
  593. package/src/commands/bootstrap.ts +244 -0
  594. package/src/commands/chat.ts +308 -0
  595. package/src/commands/code.ts +371 -0
  596. package/src/commands/console.ts +189 -0
  597. package/src/commands/describe.ts +243 -0
  598. package/src/commands/eval.ts +121 -0
  599. package/src/commands/help.ts +240 -0
  600. package/src/commands/index.ts +19 -0
  601. package/src/commands/introspect.ts +218 -0
  602. package/src/commands/mcp.ts +64 -0
  603. package/src/commands/prompt.ts +982 -0
  604. package/src/commands/run.ts +278 -0
  605. package/src/commands/sandbox-mcp.ts +343 -0
  606. package/src/commands/save-api-docs.ts +51 -0
  607. package/src/commands/scaffold.ts +225 -0
  608. package/src/commands/select.ts +99 -0
  609. package/src/commands/serve.ts +208 -0
  610. package/src/container-describer.ts +1084 -0
  611. package/src/container.ts +1186 -0
  612. package/src/endpoint.ts +365 -0
  613. package/src/entity.ts +173 -0
  614. package/src/feature.ts +118 -0
  615. package/src/graft.ts +181 -0
  616. package/src/hash-object.ts +97 -0
  617. package/src/helper.ts +849 -0
  618. package/src/introspection/generated.agi.ts +40208 -0
  619. package/src/introspection/generated.node.ts +28686 -0
  620. package/src/introspection/generated.web.ts +2251 -0
  621. package/src/introspection/index.ts +296 -0
  622. package/src/introspection/scan.ts +1131 -0
  623. package/src/node/container.ts +409 -0
  624. package/src/node/feature.ts +13 -0
  625. package/src/node/features/container-link.ts +559 -0
  626. package/src/node/features/content-db.ts +812 -0
  627. package/src/node/features/disk-cache.ts +388 -0
  628. package/src/node/features/dns.ts +669 -0
  629. package/src/node/features/docker.ts +921 -0
  630. package/src/node/features/downloader.ts +79 -0
  631. package/src/node/features/figlet-fonts.ts +600 -0
  632. package/src/node/features/file-manager.ts +535 -0
  633. package/src/node/features/fs.ts +1050 -0
  634. package/src/node/features/git.ts +592 -0
  635. package/src/node/features/google-auth.ts +504 -0
  636. package/src/node/features/google-calendar.ts +306 -0
  637. package/src/node/features/google-docs.ts +412 -0
  638. package/src/node/features/google-drive.ts +346 -0
  639. package/src/node/features/google-mail.ts +540 -0
  640. package/src/node/features/google-sheets.ts +286 -0
  641. package/src/node/features/grep.ts +427 -0
  642. package/src/node/features/helpers.ts +735 -0
  643. package/src/node/features/ink.ts +490 -0
  644. package/src/node/features/ipc-socket.ts +649 -0
  645. package/src/node/features/json-tree.ts +170 -0
  646. package/src/node/features/networking.ts +961 -0
  647. package/src/node/features/nlp.ts +212 -0
  648. package/src/node/features/opener.ts +180 -0
  649. package/src/node/features/os.ts +403 -0
  650. package/src/node/features/package-finder.ts +540 -0
  651. package/src/node/features/postgres.ts +289 -0
  652. package/src/node/features/proc.ts +503 -0
  653. package/src/node/features/process-manager.ts +844 -0
  654. package/src/node/features/python.ts +906 -0
  655. package/src/node/features/redis.ts +446 -0
  656. package/src/node/features/repl.ts +212 -0
  657. package/src/node/features/runpod.ts +811 -0
  658. package/src/node/features/secure-shell.ts +267 -0
  659. package/src/node/features/semantic-search.ts +935 -0
  660. package/src/node/features/sqlite.ts +289 -0
  661. package/src/node/features/telegram.ts +343 -0
  662. package/src/node/features/transpiler.ts +161 -0
  663. package/src/node/features/tts.ts +185 -0
  664. package/src/node/features/ui.ts +786 -0
  665. package/src/node/features/vault.ts +153 -0
  666. package/src/node/features/vm.ts +462 -0
  667. package/src/node/features/yaml-tree.ts +148 -0
  668. package/src/node/features/yaml.ts +133 -0
  669. package/src/node.ts +76 -0
  670. package/src/python/bridge.py +220 -0
  671. package/src/python/generated.ts +227 -0
  672. package/src/react/index.ts +175 -0
  673. package/src/registry.ts +210 -0
  674. package/src/scaffolds/generated.ts +1815 -0
  675. package/src/scaffolds/template.ts +46 -0
  676. package/src/schemas/base.ts +296 -0
  677. package/src/selector.ts +352 -0
  678. package/src/server.ts +229 -0
  679. package/src/servers/express.ts +283 -0
  680. package/src/servers/mcp.ts +802 -0
  681. package/src/servers/socket.ts +258 -0
  682. package/src/state.ts +101 -0
  683. package/src/web/clients/socket.ts +99 -0
  684. package/src/web/container.ts +75 -0
  685. package/src/web/extension.ts +30 -0
  686. package/src/web/feature.ts +12 -0
  687. package/src/web/features/asset-loader.ts +72 -0
  688. package/src/web/features/container-link.ts +382 -0
  689. package/src/web/features/esbuild.ts +93 -0
  690. package/src/web/features/helpers.ts +269 -0
  691. package/src/web/features/network.ts +85 -0
  692. package/src/web/features/speech.ts +104 -0
  693. package/src/web/features/vault.ts +207 -0
  694. package/src/web/features/vm.ts +85 -0
  695. package/src/web/features/voice-recognition.ts +161 -0
  696. package/src/web/shims/isomorphic-vm.ts +149 -0
  697. package/test/assistant-hooks.test.ts +306 -0
  698. package/test/assistant.test.ts +81 -0
  699. package/test/bus.test.ts +134 -0
  700. package/test/clients-servers.test.ts +217 -0
  701. package/test/command.test.ts +267 -0
  702. package/test/container-link.test.ts +274 -0
  703. package/test/conversation.test.ts +220 -0
  704. package/test/features.test.ts +160 -0
  705. package/test/fork-and-research.test.ts +450 -0
  706. package/test/integration.test.ts +787 -0
  707. package/test/interceptor-chain.test.ts +61 -0
  708. package/test/node-container.test.ts +121 -0
  709. package/test/python-session.test.ts +105 -0
  710. package/test/rate-limit.test.ts +272 -0
  711. package/test/semantic-search.test.ts +550 -0
  712. package/test/state.test.ts +121 -0
  713. package/test/vm-context.test.ts +146 -0
  714. package/test/vm-loadmodule.test.ts +213 -0
  715. package/test/websocket-ask.test.ts +101 -0
  716. package/test-integration/assistant.test.ts +138 -0
  717. package/test-integration/assistants-manager.test.ts +113 -0
  718. package/test-integration/claude-code.test.ts +98 -0
  719. package/test-integration/conversation-history.test.ts +205 -0
  720. package/test-integration/conversation.test.ts +137 -0
  721. package/test-integration/elevenlabs.test.ts +55 -0
  722. package/test-integration/google-services.test.ts +80 -0
  723. package/test-integration/helpers.ts +89 -0
  724. package/test-integration/memory.test.ts +204 -0
  725. package/test-integration/openai-codex.test.ts +93 -0
  726. package/test-integration/runpod.test.ts +58 -0
  727. package/test-integration/server-endpoints.test.ts +97 -0
  728. package/test-integration/telegram.test.ts +46 -0
  729. package/tsconfig.build.json +12 -0
  730. package/tsconfig.json +58 -0
  731. package/uv.lock +8 -0
  732. package/LICENSE +0 -21
  733. package/dist/cli/index.d.ts +0 -2
  734. package/dist/cli/index.js +0 -5
  735. package/dist/cli/run.d.ts +0 -12
  736. package/dist/cli/run.js +0 -42
  737. package/dist/config/consts.d.ts +0 -2
  738. package/dist/config/consts.js +0 -29
  739. package/dist/config/default.d.ts +0 -8
  740. package/dist/config/default.js +0 -15
  741. package/dist/config/initConfig.d.ts +0 -1
  742. package/dist/config/initConfig.js +0 -52
  743. package/dist/config/openConfig.d.ts +0 -2
  744. package/dist/config/openConfig.js +0 -24
  745. package/dist/config/runConfig.d.ts +0 -3
  746. package/dist/config/runConfig.js +0 -117
  747. package/dist/config/types.d.ts +0 -13
  748. package/dist/config/types.js +0 -2
  749. package/dist/index.d.ts +0 -1
  750. package/dist/index.js +0 -5
  751. package/dist/utils/common.d.ts +0 -2
  752. package/dist/utils/common.js +0 -52
  753. package/dist/utils/index.d.ts +0 -1
  754. package/dist/utils/index.js +0 -17
@@ -0,0 +1,1050 @@
1
+ import { Feature } from "../feature.js";
2
+ import { FeatureStateSchema, FeatureOptionsSchema } from '../../schemas/base.js'
3
+ import {
4
+ mkdirSync,
5
+ writeFileSync,
6
+ appendFileSync,
7
+ readdirSync,
8
+ statSync,
9
+ readFileSync,
10
+ cpSync,
11
+ renameSync,
12
+ lstatSync,
13
+ realpathSync,
14
+
15
+ rmSync as nodeRmSync,
16
+ type Stats,
17
+ } from "fs";
18
+ import { join, resolve, dirname, relative } from "path";
19
+ import { readFile, stat, lstat, realpath, unlink, mkdir, writeFile, appendFile, readdir, cp, rename, rm as nodeRm } from "fs/promises";
20
+ import { native as rimraf } from 'rimraf'
21
+ import micromatch from 'micromatch'
22
+
23
+ type WalkOptions = {
24
+ directories?: boolean;
25
+ files?: boolean;
26
+ exclude?: string | string[];
27
+ include?: string | string[];
28
+ /** When true, returned paths are relative to `baseDir` instead of absolute. */
29
+ relative?: boolean;
30
+ };
31
+
32
+ /**
33
+ * Checks whether a path matches any of the given glob-like patterns.
34
+ * Delegates to micromatch for correct glob semantics (**, *, {}, etc.).
35
+ */
36
+ function matchesPattern(filePath: string, patterns: string[]): boolean {
37
+ return micromatch.isMatch(filePath, patterns, { dot: true })
38
+ }
39
+
40
+ /** Sync: check if a symlink target is a directory */
41
+ function lstatFollowIsDir(fullPath: string): boolean {
42
+ try { return statSync(fullPath).isDirectory() } catch { return false }
43
+ }
44
+
45
+ /** Async: check if a symlink target is a directory */
46
+ async function lstatFollowIsDirAsync(fullPath: string): Promise<boolean> {
47
+ try { return (await stat(fullPath)).isDirectory() } catch { return false }
48
+ }
49
+
50
+ /**
51
+ * The FS feature provides methods for interacting with the file system, relative to the
52
+ * container's cwd.
53
+ *
54
+ * @extends Feature
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * const fs = container.feature('fs')
59
+ * const content = fs.readFile('package.json')
60
+ * const exists = fs.exists('tsconfig.json')
61
+ * await fs.writeFileAsync('output.txt', 'Hello World')
62
+ * fs.writeFile('sync-output.txt', 'Hello Sync')
63
+ * fs.copy('src', 'backup/src')
64
+ * ```
65
+ */
66
+ export class FS extends Feature {
67
+ static override shortcut = "features.fs" as const
68
+ static override stateSchema = FeatureStateSchema
69
+ static override optionsSchema = FeatureOptionsSchema
70
+ static { Feature.register(this, 'fs') }
71
+
72
+ // ---------------------------------------------------------------------------
73
+ // Read
74
+ // ---------------------------------------------------------------------------
75
+
76
+ /**
77
+ * Synchronously reads a file and returns its contents as a string.
78
+ *
79
+ * @param {string} path - The file path relative to the container's working directory
80
+ * @param {BufferEncoding | null} [encoding='utf-8'] - The encoding to use. Pass null to get a raw Buffer.
81
+ * @returns {string | Buffer} The file contents as a string (default) or Buffer if encoding is null
82
+ * @throws {Error} Throws an error if the file doesn't exist or cannot be read
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * const content = fs.readFile('README.md')
87
+ * const buffer = fs.readFile('image.png', null)
88
+ * ```
89
+ */
90
+ readFile(path: string, encoding?: BufferEncoding | null): string | Buffer {
91
+ const filePath = this.container.paths.resolve(path);
92
+ if (encoding === null) {
93
+ return readFileSync(filePath)
94
+ }
95
+ return readFileSync(filePath, encoding ?? 'utf-8')
96
+ }
97
+
98
+ /**
99
+ * Synchronously reads a file and returns its contents as a string.
100
+ * added this method because AI Assistants are understandly confused by this deviation from 2000's era node style
101
+ * @alias readFile
102
+ */
103
+ readFileSync(path: string, encoding?: BufferEncoding | null): string | Buffer {
104
+ return this.readFile(path,encoding)
105
+ }
106
+
107
+
108
+ /**
109
+ * Asynchronously reads a file and returns its contents as a string.
110
+ *
111
+ * @param {string} path - The file path relative to the container's working directory
112
+ * @param {BufferEncoding | null} [encoding='utf-8'] - The encoding to use. Pass null to get a raw Buffer.
113
+ * @returns {Promise<string | Buffer>} A promise that resolves to the file contents as a string (default) or Buffer
114
+ * @throws {Error} Throws an error if the file doesn't exist or cannot be read
115
+ *
116
+ * @example
117
+ * ```typescript
118
+ * const content = await fs.readFileAsync('data.txt')
119
+ * const buffer = await fs.readFileAsync('image.png', null)
120
+ * ```
121
+ */
122
+ async readFileAsync(path: string, encoding?: BufferEncoding | null): Promise<string | Buffer> {
123
+ const filePath = this.container.paths.resolve(path);
124
+ if (encoding === null) {
125
+ return await readFile(filePath)
126
+ }
127
+ return await readFile(filePath, encoding ?? 'utf-8')
128
+ }
129
+
130
+ /**
131
+ * Synchronously reads and parses a JSON file.
132
+ *
133
+ * @param {string} path - The path to the JSON file
134
+ * @returns {any} The parsed JSON content
135
+ * @throws {Error} Throws an error if the file doesn't exist, cannot be read, or contains invalid JSON
136
+ *
137
+ * @example
138
+ * ```typescript
139
+ * const config = fs.readJson('config.json')
140
+ * console.log(config.version)
141
+ * ```
142
+ */
143
+ readJson(path: string): any {
144
+ return JSON.parse(this.readFile(path) as string)
145
+ }
146
+
147
+ /**
148
+ * Read and parse a JSON file synchronously
149
+ * @alias readJson
150
+ */
151
+ readJsonSync(path: string): any {
152
+ return this.readJson(path)
153
+ }
154
+
155
+ /**
156
+ * Asynchronously reads and parses a JSON file.
157
+ *
158
+ * @param {string} path - The path to the JSON file
159
+ * @returns {Promise<any>} A promise that resolves to the parsed JSON content
160
+ * @throws {Error} Throws an error if the file doesn't exist, cannot be read, or contains invalid JSON
161
+ *
162
+ * @example
163
+ * ```typescript
164
+ * const config = await fs.readJsonAsync('config.json')
165
+ * console.log(config.version)
166
+ * ```
167
+ */
168
+ async readJsonAsync(path: string): Promise<any> {
169
+ const content = await this.readFileAsync(path)
170
+ return JSON.parse(content as string)
171
+ }
172
+
173
+ /**
174
+ * Synchronously reads the contents of a directory.
175
+ *
176
+ * @param {string} path - The directory path relative to the container's working directory
177
+ * @returns {string[]} An array of file and directory names
178
+ * @throws {Error} Throws an error if the directory doesn't exist or cannot be read
179
+ *
180
+ * @example
181
+ * ```typescript
182
+ * const entries = fs.readdirSync('src')
183
+ * console.log(entries) // ['index.ts', 'utils.ts', 'components']
184
+ * ```
185
+ */
186
+ readdirSync(path: string): string[] {
187
+ return readdirSync(this.container.paths.resolve(path))
188
+ }
189
+
190
+ /**
191
+ * Asynchronously reads the contents of a directory.
192
+ *
193
+ * @param {string} path - The directory path relative to the container's working directory
194
+ * @returns {Promise<string[]>} A promise that resolves to an array of file and directory names
195
+ * @throws {Error} Throws an error if the directory doesn't exist or cannot be read
196
+ *
197
+ * @example
198
+ * ```typescript
199
+ * const entries = await fs.readdir('src')
200
+ * console.log(entries) // ['index.ts', 'utils.ts', 'components']
201
+ * ```
202
+ */
203
+ async readdir(path: string): Promise<string[]> {
204
+ return await readdir(this.container.paths.resolve(path))
205
+ }
206
+
207
+ // ---------------------------------------------------------------------------
208
+ // Write
209
+ // ---------------------------------------------------------------------------
210
+
211
+ /**
212
+ * Synchronously writes content to a file.
213
+ *
214
+ * @param {string} path - The file path where content should be written
215
+ * @param {Buffer | string} content - The content to write to the file
216
+ * @throws {Error} Throws an error if the file cannot be written
217
+ *
218
+ * @example
219
+ * ```typescript
220
+ * fs.writeFile('output.txt', 'Hello World')
221
+ * fs.writeFile('data.bin', Buffer.from([1, 2, 3, 4]))
222
+ * ```
223
+ */
224
+ writeFile(path: string, content: Buffer | string): void {
225
+ writeFileSync(this.container.paths.resolve(path), content)
226
+ }
227
+
228
+ /**
229
+ * Asynchronously writes content to a file.
230
+ *
231
+ * @param {string} path - The file path where content should be written
232
+ * @param {Buffer | string} content - The content to write to the file
233
+ * @returns {Promise<void>} A promise that resolves when the file is written
234
+ * @throws {Error} Throws an error if the file cannot be written
235
+ *
236
+ * @example
237
+ * ```typescript
238
+ * await fs.writeFileAsync('output.txt', 'Hello World')
239
+ * await fs.writeFileAsync('data.bin', Buffer.from([1, 2, 3, 4]))
240
+ * ```
241
+ */
242
+ async writeFileAsync(path: string, content: Buffer | string) {
243
+ return writeFile(this.container.paths.resolve(path), content)
244
+ }
245
+
246
+ /**
247
+ * Synchronously writes an object to a file as JSON.
248
+ *
249
+ * @param {string} path - The file path where the JSON should be written
250
+ * @param {any} data - The data to serialize as JSON
251
+ * @param {number} [indent=2] - The number of spaces to use for indentation
252
+ * @throws {Error} Throws an error if the file cannot be written
253
+ *
254
+ * @example
255
+ * ```typescript
256
+ * fs.writeJson('config.json', { version: '1.0.0', debug: false })
257
+ * ```
258
+ */
259
+ writeJson(path: string, data: any, indent: number = 2): void {
260
+ this.writeFile(path, JSON.stringify(data, null, indent) + '\n')
261
+ }
262
+
263
+ /**
264
+ * Asynchronously writes an object to a file as JSON.
265
+ *
266
+ * @param {string} path - The file path where the JSON should be written
267
+ * @param {any} data - The data to serialize as JSON
268
+ * @param {number} [indent=2] - The number of spaces to use for indentation
269
+ * @returns {Promise<void>} A promise that resolves when the file is written
270
+ * @throws {Error} Throws an error if the file cannot be written
271
+ *
272
+ * @example
273
+ * ```typescript
274
+ * await fs.writeJsonAsync('config.json', { version: '1.0.0', debug: false })
275
+ * ```
276
+ */
277
+ async writeJsonAsync(path: string, data: any, indent: number = 2) {
278
+ return this.writeFileAsync(path, JSON.stringify(data, null, indent) + '\n')
279
+ }
280
+
281
+ /**
282
+ * Synchronously appends content to a file.
283
+ *
284
+ * @param {string} path - The file path to append to
285
+ * @param {Buffer | string} content - The content to append
286
+ *
287
+ * @example
288
+ * ```typescript
289
+ * fs.appendFile('log.txt', 'New line\n')
290
+ * ```
291
+ */
292
+ appendFile(path: string, content: Buffer | string): void {
293
+ appendFileSync(this.container.paths.resolve(path), content)
294
+ }
295
+
296
+ /**
297
+ * Asynchronously appends content to a file.
298
+ *
299
+ * @param {string} path - The file path to append to
300
+ * @param {Buffer | string} content - The content to append
301
+ * @returns {Promise<void>} A promise that resolves when the content is appended
302
+ *
303
+ * @example
304
+ * ```typescript
305
+ * await fs.appendFileAsync('log.txt', 'New line\n')
306
+ * ```
307
+ */
308
+ async appendFileAsync(path: string, content: Buffer | string) {
309
+ return appendFile(this.container.paths.resolve(path), content)
310
+ }
311
+
312
+ // ---------------------------------------------------------------------------
313
+ // Ensure (create if missing)
314
+ // ---------------------------------------------------------------------------
315
+
316
+ /**
317
+ * Synchronously ensures a file exists with the specified content, creating directories as needed.
318
+ *
319
+ * @param {string} path - The file path where the file should be created
320
+ * @param {string} content - The content to write to the file
321
+ * @param {boolean} [overwrite=false] - Whether to overwrite the file if it already exists
322
+ * @returns {string} The resolved file path
323
+ * @throws {Error} Throws an error if the file cannot be created or written
324
+ *
325
+ * @example
326
+ * ```typescript
327
+ * fs.ensureFile('logs/app.log', '', false)
328
+ * ```
329
+ */
330
+ ensureFile(path: string, content: string, overwrite = false): string {
331
+ path = this.container.paths.resolve(path);
332
+
333
+ if (this.exists(path) && !overwrite) {
334
+ return path;
335
+ }
336
+
337
+ const { dir } = this.container.paths.parse(path);
338
+ mkdirSync(dir, { recursive: true });
339
+ writeFileSync(path, content);
340
+ return path;
341
+ }
342
+
343
+ /**
344
+ * Asynchronously ensures a file exists with the specified content, creating directories as needed.
345
+ *
346
+ * @param {string} path - The file path where the file should be created
347
+ * @param {string} content - The content to write to the file
348
+ * @param {boolean} [overwrite=false] - Whether to overwrite the file if it already exists
349
+ * @returns {Promise<string>} A promise that resolves to the absolute file path
350
+ * @throws {Error} Throws an error if the file cannot be created or written
351
+ *
352
+ * @example
353
+ * ```typescript
354
+ * await fs.ensureFileAsync('config/settings.json', '{}', true)
355
+ * ```
356
+ */
357
+ async ensureFileAsync(path: string, content: string, overwrite = false): Promise<string> {
358
+ path = this.container.paths.resolve(path);
359
+
360
+ if (this.exists(path) && !overwrite) {
361
+ return path;
362
+ }
363
+
364
+ const { dir } = this.container.paths.parse(path);
365
+ await mkdir(dir, { recursive: true });
366
+ await writeFile(path, content);
367
+ return path;
368
+ }
369
+
370
+ /**
371
+ * Synchronously ensures a directory exists, creating parent directories as needed.
372
+ *
373
+ * @param {string} path - The directory path to create
374
+ * @returns {string} The resolved directory path
375
+ * @throws {Error} Throws an error if the directory cannot be created
376
+ *
377
+ * @example
378
+ * ```typescript
379
+ * fs.ensureFolder('logs/debug')
380
+ * ```
381
+ */
382
+ ensureFolder(path: string): string {
383
+ mkdirSync(this.container.paths.resolve(path), { recursive: true });
384
+ return this.container.paths.resolve(path);
385
+ }
386
+
387
+ /**
388
+ * Asynchronously ensures a directory exists, creating parent directories as needed.
389
+ *
390
+ * @param {string} path - The directory path to create
391
+ * @returns {Promise<string>} A promise that resolves to the resolved directory path
392
+ * @throws {Error} Throws an error if the directory cannot be created
393
+ *
394
+ * @example
395
+ * ```typescript
396
+ * await fs.ensureFolderAsync('logs/debug')
397
+ * ```
398
+ */
399
+ async ensureFolderAsync(path: string): Promise<string> {
400
+ const resolved = this.container.paths.resolve(path);
401
+ await mkdir(resolved, { recursive: true });
402
+ return resolved;
403
+ }
404
+
405
+ /**
406
+ * Alias for ensureFolder. Synchronously creates a directory and all parent directories.
407
+ *
408
+ * @param {string} folder - The directory path to create
409
+ * @returns {string} The resolved directory path
410
+ *
411
+ * @example
412
+ * ```typescript
413
+ * fs.mkdirp('deep/nested/path')
414
+ * ```
415
+ */
416
+ mkdirp(folder: string): string {
417
+ return this.ensureFolder(folder)
418
+ }
419
+
420
+ // ---------------------------------------------------------------------------
421
+ // Existence & stat
422
+ // ---------------------------------------------------------------------------
423
+
424
+ /**
425
+ * Synchronously checks if a file or directory exists.
426
+ *
427
+ * @param {string} path - The path to check for existence
428
+ * @returns {boolean} True if the path exists, false otherwise
429
+ *
430
+ * @example
431
+ * ```typescript
432
+ * if (fs.exists('config.json')) {
433
+ * console.log('Config file exists!')
434
+ * }
435
+ * ```
436
+ */
437
+ exists(path: string): boolean {
438
+ const filePath = this.container.paths.resolve(path);
439
+ try {
440
+ statSync(filePath);
441
+ return true;
442
+ } catch (error) {
443
+ return false;
444
+ }
445
+ }
446
+
447
+ /**
448
+ * Alias for exists. Synchronously checks if a file or directory exists.
449
+ *
450
+ * @param {string} path - The path to check for existence
451
+ * @returns {boolean} True if the path exists, false otherwise
452
+ *
453
+ * @example
454
+ * ```typescript
455
+ * if (fs.existsSync('config.json')) {
456
+ * console.log('Config file exists!')
457
+ * }
458
+ * ```
459
+ */
460
+ existsSync(path: string): boolean {
461
+ return this.exists(path)
462
+ }
463
+
464
+ /**
465
+ * Asynchronously checks if a file or directory exists.
466
+ *
467
+ * @param {string} path - The path to check for existence
468
+ * @returns {Promise<boolean>} A promise that resolves to true if the path exists, false otherwise
469
+ *
470
+ * @example
471
+ * ```typescript
472
+ * if (await fs.existsAsync('config.json')) {
473
+ * console.log('Config file exists!')
474
+ * }
475
+ * ```
476
+ */
477
+ async existsAsync(path: string): Promise<boolean> {
478
+ const filePath = this.container.paths.resolve(path);
479
+ return stat(filePath).then(() => true).catch(() => false)
480
+ }
481
+
482
+ /**
483
+ * Checks if a path is a symbolic link.
484
+ *
485
+ * @param {string} path - The path to check
486
+ * @returns {boolean} True if the path is a symlink
487
+ */
488
+ isSymlink(path: string): boolean {
489
+ const filePath = this.container.paths.resolve(path);
490
+ try { return lstatSync(filePath).isSymbolicLink() } catch { return false }
491
+ }
492
+
493
+ /**
494
+ * Resolves a symlink to its real path. Returns the resolved path as-is if not a symlink.
495
+ *
496
+ * @param {string} path - The path to resolve
497
+ * @returns {string} The real path after resolving all symlinks
498
+ */
499
+ realpath(path: string): string {
500
+ const filePath = this.container.paths.resolve(path);
501
+ return realpathSync(filePath)
502
+ }
503
+
504
+ /**
505
+ * Synchronously returns the stat object for a file or directory.
506
+ *
507
+ * @param {string} path - The path to stat
508
+ * @returns {import('fs').Stats} The Stats object with size, timestamps, and type checks
509
+ * @throws {Error} Throws an error if the path doesn't exist
510
+ *
511
+ * @example
512
+ * ```typescript
513
+ * const info = fs.stat('package.json')
514
+ * console.log(info.size, info.mtime)
515
+ * ```
516
+ */
517
+ stat(path: string): Stats {
518
+ return statSync(this.container.paths.resolve(path))
519
+ }
520
+
521
+ /**
522
+ * Asynchronously returns the stat object for a file or directory.
523
+ *
524
+ * @param {string} path - The path to stat
525
+ * @returns {Promise<import('fs').Stats>} A promise that resolves to the Stats object
526
+ * @throws {Error} Throws an error if the path doesn't exist
527
+ *
528
+ * @example
529
+ * ```typescript
530
+ * const info = await fs.statAsync('package.json')
531
+ * console.log(info.size, info.mtime)
532
+ * ```
533
+ */
534
+ async statAsync(path: string): Promise<Stats> {
535
+ return stat(this.container.paths.resolve(path))
536
+ }
537
+
538
+ /**
539
+ * Synchronously checks if a path is a file.
540
+ *
541
+ * @param {string} path - The path to check
542
+ * @returns {boolean} True if the path is a file, false otherwise
543
+ *
544
+ * @example
545
+ * ```typescript
546
+ * if (fs.isFile('package.json')) {
547
+ * console.log('It is a file')
548
+ * }
549
+ * ```
550
+ */
551
+ isFile(path: string): boolean {
552
+ try {
553
+ return statSync(this.container.paths.resolve(path)).isFile()
554
+ } catch {
555
+ return false
556
+ }
557
+ }
558
+
559
+ /**
560
+ * Asynchronously checks if a path is a file.
561
+ *
562
+ * @param {string} path - The path to check
563
+ * @returns {Promise<boolean>} A promise that resolves to true if the path is a file
564
+ *
565
+ * @example
566
+ * ```typescript
567
+ * if (await fs.isFileAsync('package.json')) {
568
+ * console.log('It is a file')
569
+ * }
570
+ * ```
571
+ */
572
+ async isFileAsync(path: string): Promise<boolean> {
573
+ return stat(this.container.paths.resolve(path)).then(s => s.isFile()).catch(() => false)
574
+ }
575
+
576
+ /**
577
+ * Synchronously checks if a path is a directory.
578
+ *
579
+ * @param {string} path - The path to check
580
+ * @returns {boolean} True if the path is a directory, false otherwise
581
+ *
582
+ * @example
583
+ * ```typescript
584
+ * if (fs.isDirectory('src')) {
585
+ * console.log('It is a directory')
586
+ * }
587
+ * ```
588
+ */
589
+ isDirectory(path: string): boolean {
590
+ try {
591
+ return statSync(this.container.paths.resolve(path)).isDirectory()
592
+ } catch {
593
+ return false
594
+ }
595
+ }
596
+
597
+ /**
598
+ * Asynchronously checks if a path is a directory.
599
+ *
600
+ * @param {string} path - The path to check
601
+ * @returns {Promise<boolean>} A promise that resolves to true if the path is a directory
602
+ *
603
+ * @example
604
+ * ```typescript
605
+ * if (await fs.isDirectoryAsync('src')) {
606
+ * console.log('It is a directory')
607
+ * }
608
+ * ```
609
+ */
610
+ async isDirectoryAsync(path: string): Promise<boolean> {
611
+ return stat(this.container.paths.resolve(path)).then(s => s.isDirectory()).catch(() => false)
612
+ }
613
+
614
+ // ---------------------------------------------------------------------------
615
+ // Delete
616
+ // ---------------------------------------------------------------------------
617
+
618
+ /**
619
+ * Synchronously removes a file.
620
+ *
621
+ * @param {string} path - The path of the file to remove
622
+ * @throws {Error} Throws an error if the file cannot be removed or doesn't exist
623
+ *
624
+ * @example
625
+ * ```typescript
626
+ * fs.rmSync('temp/cache.tmp')
627
+ * ```
628
+ */
629
+ rmSync(path: string): void {
630
+ nodeRmSync(this.container.paths.resolve(path), { force: true })
631
+ }
632
+
633
+ /**
634
+ * Asynchronously removes a file.
635
+ *
636
+ * @param {string} path - The path of the file to remove
637
+ * @returns {Promise<void>} A promise that resolves when the file is removed
638
+ * @throws {Error} Throws an error if the file cannot be removed or doesn't exist
639
+ *
640
+ * @example
641
+ * ```typescript
642
+ * await fs.rm('temp/cache.tmp')
643
+ * ```
644
+ */
645
+ async rm(path: string) {
646
+ return await unlink(this.container.paths.resolve(path));
647
+ }
648
+
649
+ /**
650
+ * Synchronously removes a directory and all its contents.
651
+ *
652
+ * @param {string} dirPath - The path of the directory to remove
653
+ * @throws {Error} Throws an error if the directory cannot be removed
654
+ *
655
+ * @example
656
+ * ```typescript
657
+ * fs.rmdirSync('temp/cache')
658
+ * ```
659
+ */
660
+ rmdirSync(dirPath: string): void {
661
+ nodeRmSync(this.container.paths.resolve(dirPath), { recursive: true, force: true })
662
+ }
663
+
664
+ /**
665
+ * Asynchronously removes a directory and all its contents.
666
+ *
667
+ * @param {string} dirPath - The path of the directory to remove
668
+ * @returns {Promise<void>} A promise that resolves when the directory is removed
669
+ * @throws {Error} Throws an error if the directory cannot be removed
670
+ *
671
+ * @example
672
+ * ```typescript
673
+ * await fs.rmdir('temp/cache')
674
+ * ```
675
+ */
676
+ async rmdir(dirPath: string) {
677
+ await rimraf(this.container.paths.resolve(dirPath));
678
+ }
679
+
680
+ // ---------------------------------------------------------------------------
681
+ // Copy & Move
682
+ // ---------------------------------------------------------------------------
683
+
684
+ /**
685
+ * Synchronously copies a file or directory. Auto-detects whether the source is a file or directory
686
+ * and handles each appropriately (recursive for directories).
687
+ *
688
+ * @param {string} src - The source path to copy from
689
+ * @param {string} dest - The destination path to copy to
690
+ * @param {object} [options={}] - Copy options
691
+ * @param {boolean} [options.overwrite=true] - Whether to overwrite existing files at the destination
692
+ * @throws {Error} Throws an error if the source doesn't exist or the copy fails
693
+ *
694
+ * @example
695
+ * ```typescript
696
+ * fs.copy('src/config.json', 'backup/config.json')
697
+ * fs.copy('src', 'backup/src')
698
+ * ```
699
+ */
700
+ copy(src: string, dest: string, options: { overwrite?: boolean } = {}): void {
701
+ const { overwrite = true } = options
702
+ const resolvedSrc = this.container.paths.resolve(src)
703
+ const resolvedDest = this.container.paths.resolve(dest)
704
+ cpSync(resolvedSrc, resolvedDest, { recursive: true, force: overwrite })
705
+ }
706
+
707
+ /**
708
+ * Asynchronously copies a file or directory. Auto-detects whether the source is a file or directory
709
+ * and handles each appropriately (recursive for directories).
710
+ *
711
+ * @param {string} src - The source path to copy from
712
+ * @param {string} dest - The destination path to copy to
713
+ * @param {object} [options={}] - Copy options
714
+ * @param {boolean} [options.overwrite=true] - Whether to overwrite existing files at the destination
715
+ * @returns {Promise<void>} A promise that resolves when the copy is complete
716
+ * @throws {Error} Throws an error if the source doesn't exist or the copy fails
717
+ *
718
+ * @example
719
+ * ```typescript
720
+ * await fs.copyAsync('src/config.json', 'backup/config.json')
721
+ * await fs.copyAsync('src', 'backup/src')
722
+ * ```
723
+ */
724
+ async copyAsync(src: string, dest: string, options: { overwrite?: boolean } = {}) {
725
+ const { overwrite = true } = options
726
+ const resolvedSrc = this.container.paths.resolve(src)
727
+ const resolvedDest = this.container.paths.resolve(dest)
728
+ await cp(resolvedSrc, resolvedDest, { recursive: true, force: overwrite })
729
+ }
730
+
731
+ /**
732
+ * Synchronously moves (renames) a file or directory. Falls back to copy + delete for cross-device moves.
733
+ *
734
+ * @param {string} src - The source path to move from
735
+ * @param {string} dest - The destination path to move to
736
+ * @throws {Error} Throws an error if the source doesn't exist or the move fails
737
+ *
738
+ * @example
739
+ * ```typescript
740
+ * fs.move('temp/draft.txt', 'final/document.txt')
741
+ * fs.move('old-dir', 'new-dir')
742
+ * ```
743
+ */
744
+ move(src: string, dest: string): void {
745
+ const resolvedSrc = this.container.paths.resolve(src)
746
+ const resolvedDest = this.container.paths.resolve(dest)
747
+ const destDir = dirname(resolvedDest)
748
+ mkdirSync(destDir, { recursive: true })
749
+ try {
750
+ renameSync(resolvedSrc, resolvedDest)
751
+ } catch (err: any) {
752
+ if (err.code === 'EXDEV') {
753
+ cpSync(resolvedSrc, resolvedDest, { recursive: true, force: true })
754
+ nodeRmSync(resolvedSrc, { recursive: true, force: true })
755
+ } else {
756
+ throw err
757
+ }
758
+ }
759
+ }
760
+
761
+ /**
762
+ * Asynchronously moves (renames) a file or directory. Falls back to copy + delete for cross-device moves.
763
+ *
764
+ * @param {string} src - The source path to move from
765
+ * @param {string} dest - The destination path to move to
766
+ * @returns {Promise<void>} A promise that resolves when the move is complete
767
+ * @throws {Error} Throws an error if the source doesn't exist or the move fails
768
+ *
769
+ * @example
770
+ * ```typescript
771
+ * await fs.moveAsync('temp/draft.txt', 'final/document.txt')
772
+ * await fs.moveAsync('old-dir', 'new-dir')
773
+ * ```
774
+ */
775
+ async moveAsync(src: string, dest: string) {
776
+ const resolvedSrc = this.container.paths.resolve(src)
777
+ const resolvedDest = this.container.paths.resolve(dest)
778
+ const destDir = dirname(resolvedDest)
779
+ await mkdir(destDir, { recursive: true })
780
+ try {
781
+ await rename(resolvedSrc, resolvedDest)
782
+ } catch (err: any) {
783
+ if (err.code === 'EXDEV') {
784
+ await cp(resolvedSrc, resolvedDest, { recursive: true, force: true })
785
+ await nodeRm(resolvedSrc, { recursive: true, force: true })
786
+ } else {
787
+ throw err
788
+ }
789
+ }
790
+ }
791
+
792
+ // ---------------------------------------------------------------------------
793
+ // Walk
794
+ // ---------------------------------------------------------------------------
795
+
796
+ /**
797
+ * Recursively walks a directory and returns arrays of file and directory paths.
798
+ * By default paths are absolute. Pass `relative: true` to get paths relative to `basePath`.
799
+ * Supports filtering with exclude and include glob patterns.
800
+ *
801
+ * @param {string} basePath - The base directory path to start walking from
802
+ * @param {WalkOptions} options - Options to configure the walk behavior
803
+ * @param {boolean} [options.directories=true] - Whether to include directories in results
804
+ * @param {boolean} [options.files=true] - Whether to include files in results
805
+ * @param {string | string[]} [options.exclude=[]] - Glob patterns to exclude (e.g. 'node_modules', '*.log')
806
+ * @param {string | string[]} [options.include=[]] - Glob patterns to include (only matching paths are returned)
807
+ * @param {boolean} [options.relative=false] - When true, returned paths are relative to basePath
808
+ * @returns {{ directories: string[], files: string[] }} Object containing arrays of directory and file paths
809
+ *
810
+ * @example
811
+ * ```typescript
812
+ * const result = fs.walk('src', { files: true, directories: false })
813
+ * const filtered = fs.walk('.', { exclude: ['node_modules', '.git'], include: ['*.ts'] })
814
+ * const relative = fs.walk('inbox', { relative: true }) // => { files: ['contact-1.json', ...] }
815
+ * ```
816
+ */
817
+ walk(basePath: string, options: WalkOptions = {}): { directories: string[], files: string[] } {
818
+ const {
819
+ directories = true,
820
+ files = true,
821
+ exclude = [],
822
+ include = [],
823
+ relative: useRelative = false,
824
+ } = options;
825
+
826
+ const excludePatterns = Array.isArray(exclude) ? exclude : [exclude]
827
+ const includePatterns = Array.isArray(include) ? include : [include]
828
+ const resolvedBase = this.container.paths.resolve(basePath)
829
+
830
+ const walk = (baseDir: string) => {
831
+ const results = {
832
+ directories: [] as string[],
833
+ files: [] as string[],
834
+ };
835
+
836
+ const entries = readdirSync(baseDir, { withFileTypes: true });
837
+
838
+ for (const entry of entries) {
839
+ const name = entry.name;
840
+ const fullPath = join(baseDir, name);
841
+ const relativePath = relative(resolvedBase, fullPath)
842
+ const outputPath = useRelative ? relativePath : fullPath;
843
+ // Follow symlinks: isDirectory() returns false for symlinks,
844
+ // so check isSymbolicLink() and resolve to the real target
845
+ const isDir = entry.isDirectory() || (entry.isSymbolicLink() && lstatFollowIsDir(fullPath));
846
+
847
+ if (excludePatterns.length && matchesPattern(relativePath, excludePatterns)) {
848
+ continue
849
+ }
850
+
851
+ const passes = !includePatterns.length || matchesPattern(relativePath, includePatterns)
852
+
853
+ if (isDir && directories && passes) {
854
+ results.directories.push(outputPath);
855
+ }
856
+
857
+ if (!isDir && files && passes) {
858
+ results.files.push(outputPath);
859
+ }
860
+
861
+ if (isDir) {
862
+ const subResults = walk(fullPath);
863
+ results.files.push(...subResults.files);
864
+ results.directories.push(...subResults.directories);
865
+ }
866
+ }
867
+
868
+ return results;
869
+ };
870
+
871
+ return walk(resolvedBase);
872
+ }
873
+
874
+ /**
875
+ * Asynchronously and recursively walks a directory and returns arrays of file and directory paths.
876
+ * By default paths are absolute. Pass `relative: true` to get paths relative to `baseDir`.
877
+ * Supports filtering with exclude and include glob patterns.
878
+ *
879
+ * @param {string} baseDir - The base directory path to start walking from
880
+ * @param {WalkOptions} options - Options to configure the walk behavior
881
+ * @param {boolean} [options.directories=true] - Whether to include directories in results
882
+ * @param {boolean} [options.files=true] - Whether to include files in results
883
+ * @param {string | string[]} [options.exclude=[]] - Glob patterns to exclude (e.g. 'node_modules', '.git')
884
+ * @param {string | string[]} [options.include=[]] - Glob patterns to include (only matching paths are returned)
885
+ * @param {boolean} [options.relative=false] - When true, returned paths are relative to baseDir
886
+ * @returns {Promise<{ directories: string[], files: string[] }>} Promise resolving to object with directory and file paths
887
+ * @throws {Error} Throws an error if the directory cannot be accessed
888
+ *
889
+ * @example
890
+ * ```typescript
891
+ * const result = await fs.walkAsync('src', { exclude: ['node_modules'] })
892
+ * const files = await fs.walkAsync('inbox', { relative: true })
893
+ * // files.files => ['contact-1.json', 'subfolder/file.txt', ...]
894
+ * ```
895
+ */
896
+ async walkAsync(baseDir: string, options: WalkOptions = {}): Promise<{ directories: string[], files: string[] }> {
897
+ const {
898
+ directories = true,
899
+ files = true,
900
+ exclude = [],
901
+ include = [],
902
+ relative: useRelative = false,
903
+ } = options;
904
+
905
+ const excludePatterns = Array.isArray(exclude) ? exclude : [exclude]
906
+ const includePatterns = Array.isArray(include) ? include : [include]
907
+ const resolvedBase = this.container.paths.resolve(baseDir)
908
+
909
+ const walk = async (currentDir: string) => {
910
+ const results = {
911
+ directories: [] as string[],
912
+ files: [] as string[],
913
+ };
914
+
915
+ const entries = await readdir(currentDir, { withFileTypes: true });
916
+
917
+ for (const entry of entries) {
918
+ const name = entry.name;
919
+ const fullPath = join(currentDir, name);
920
+ const relativePath = relative(resolvedBase, fullPath)
921
+ const outputPath = useRelative ? relativePath : fullPath;
922
+ // Follow symlinks: isDirectory() returns false for symlinks,
923
+ // so check isSymbolicLink() and resolve to the real target
924
+ const isDir = entry.isDirectory() || (entry.isSymbolicLink() && await lstatFollowIsDirAsync(fullPath));
925
+
926
+ if (excludePatterns.length && matchesPattern(relativePath, excludePatterns)) {
927
+ continue
928
+ }
929
+
930
+ const passes = !includePatterns.length || matchesPattern(relativePath, includePatterns)
931
+
932
+ if (isDir && directories && passes) {
933
+ results.directories.push(outputPath);
934
+ }
935
+
936
+ if (!isDir && files && passes) {
937
+ results.files.push(outputPath);
938
+ }
939
+
940
+ if (isDir) {
941
+ const subResults = await walk(fullPath);
942
+ results.files.push(...subResults.files);
943
+ results.directories.push(...subResults.directories);
944
+ }
945
+ }
946
+
947
+ return results;
948
+ };
949
+
950
+ return walk(resolvedBase);
951
+ }
952
+
953
+ // ---------------------------------------------------------------------------
954
+ // Find Up
955
+ // ---------------------------------------------------------------------------
956
+
957
+ /**
958
+ * Synchronously finds a file by walking up the directory tree from the current working directory.
959
+ *
960
+ * @param {string} fileName - The name of the file to search for
961
+ * @param {object} [options={}] - Options for the search
962
+ * @param {string} [options.cwd] - The directory to start searching from (defaults to container.cwd)
963
+ * @returns {string | null} The absolute path to the found file, or null if not found
964
+ *
965
+ * @example
966
+ * ```typescript
967
+ * const packageJson = fs.findUp('package.json')
968
+ * if (packageJson) {
969
+ * console.log(`Found package.json at: ${packageJson}`)
970
+ * }
971
+ * ```
972
+ */
973
+ findUp(fileName: string, options: { cwd?: string } = {}): string | null {
974
+ const { cwd = this.container.cwd } = options;
975
+ let startAt = cwd;
976
+
977
+ if (this.exists(join(startAt, fileName))) {
978
+ return resolve(startAt, fileName);
979
+ }
980
+
981
+ while (startAt !== dirname(startAt)) {
982
+ startAt = dirname(startAt);
983
+ if (this.exists(join(startAt, fileName))) {
984
+ return resolve(startAt, fileName);
985
+ }
986
+ }
987
+
988
+ return null;
989
+ }
990
+
991
+ /**
992
+ * Asynchronously finds a file by walking up the directory tree.
993
+ *
994
+ * @param {string} fileName - The name of the file to search for
995
+ * @param {object} [options={}] - Options for the search
996
+ * @param {string} [options.cwd] - The directory to start searching from (defaults to container.cwd)
997
+ * @param {boolean} [options.multiple=false] - Whether to find multiple instances of the file
998
+ * @returns {Promise<string | string[] | null>} The path(s) to the found file(s), or null if not found
999
+ *
1000
+ * @example
1001
+ * ```typescript
1002
+ * const packageJson = await fs.findUpAsync('package.json')
1003
+ * const allPackageJsons = await fs.findUpAsync('package.json', { multiple: true })
1004
+ * ```
1005
+ */
1006
+ async findUpAsync(
1007
+ fileName: string,
1008
+ options: { cwd?: string; multiple?: boolean } = {}
1009
+ ): Promise<string | string[] | null> {
1010
+ const { cwd = this.container.cwd, multiple = false } = options;
1011
+ let startAt = cwd;
1012
+ const foundFiles = [];
1013
+
1014
+ const fileExistsInDir = async (dir: string, file: string) => {
1015
+ try {
1016
+ await stat(join(dir, file));
1017
+ return true;
1018
+ } catch (error) {
1019
+ return false;
1020
+ }
1021
+ };
1022
+
1023
+ if (await fileExistsInDir(startAt, fileName)) {
1024
+ if (multiple) {
1025
+ foundFiles.push(resolve(startAt, fileName));
1026
+ } else {
1027
+ return resolve(startAt, fileName);
1028
+ }
1029
+ }
1030
+
1031
+ while (startAt !== dirname(startAt)) {
1032
+ startAt = dirname(startAt);
1033
+ if (await fileExistsInDir(startAt, fileName)) {
1034
+ if (multiple) {
1035
+ foundFiles.push(resolve(startAt, fileName));
1036
+ } else {
1037
+ return resolve(startAt, fileName);
1038
+ }
1039
+ }
1040
+ }
1041
+
1042
+ if (multiple && foundFiles.length > 0) {
1043
+ return foundFiles;
1044
+ }
1045
+
1046
+ return null;
1047
+ }
1048
+ }
1049
+
1050
+ export default FS