luca 2.0.0 → 3.0.2

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 (532) hide show
  1. package/.github/workflows/release.yaml +170 -0
  2. package/AGENTS.md +99 -0
  3. package/CLAUDE.md +123 -0
  4. package/CNAME +1 -0
  5. package/README.md +275 -9
  6. package/RUNME.md +56 -0
  7. package/assistants/codingAssistant/ABOUT.md +5 -0
  8. package/assistants/codingAssistant/CORE.md +33 -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 +2667 -0
  20. package/bunfig.toml +3 -0
  21. package/commands/audit-docs.ts +740 -0
  22. package/commands/build-bootstrap.ts +117 -0
  23. package/commands/build-python-bridge.ts +42 -0
  24. package/commands/build-scaffolds.ts +175 -0
  25. package/commands/bundle-consumer-project.ts +521 -0
  26. package/commands/generate-api-docs.ts +114 -0
  27. package/commands/inkbot.ts +874 -0
  28. package/commands/release.ts +80 -0
  29. package/commands/try-all-challenges.ts +543 -0
  30. package/commands/try-challenge.ts +100 -0
  31. package/dist/agi/container.server.d.ts +63 -0
  32. package/dist/agi/container.server.d.ts.map +1 -0
  33. package/dist/agi/endpoints/ask.d.ts +20 -0
  34. package/dist/agi/endpoints/ask.d.ts.map +1 -0
  35. package/dist/agi/endpoints/conversations/[id].d.ts +27 -0
  36. package/dist/agi/endpoints/conversations/[id].d.ts.map +1 -0
  37. package/dist/agi/endpoints/conversations.d.ts +18 -0
  38. package/dist/agi/endpoints/conversations.d.ts.map +1 -0
  39. package/dist/agi/endpoints/experts.d.ts +8 -0
  40. package/dist/agi/endpoints/experts.d.ts.map +1 -0
  41. package/dist/agi/feature.d.ts +9 -0
  42. package/dist/agi/feature.d.ts.map +1 -0
  43. package/dist/agi/features/assistant.d.ts +509 -0
  44. package/dist/agi/features/assistant.d.ts.map +1 -0
  45. package/dist/agi/features/assistants-manager.d.ts +236 -0
  46. package/dist/agi/features/assistants-manager.d.ts.map +1 -0
  47. package/dist/agi/features/autonomous-assistant.d.ts +281 -0
  48. package/dist/agi/features/autonomous-assistant.d.ts.map +1 -0
  49. package/dist/agi/features/browser-use.d.ts +479 -0
  50. package/dist/agi/features/browser-use.d.ts.map +1 -0
  51. package/dist/agi/features/claude-code.d.ts +824 -0
  52. package/dist/agi/features/claude-code.d.ts.map +1 -0
  53. package/dist/agi/features/conversation-history.d.ts +245 -0
  54. package/dist/agi/features/conversation-history.d.ts.map +1 -0
  55. package/dist/agi/features/conversation.d.ts +464 -0
  56. package/dist/agi/features/conversation.d.ts.map +1 -0
  57. package/dist/agi/features/docs-reader.d.ts +72 -0
  58. package/dist/agi/features/docs-reader.d.ts.map +1 -0
  59. package/dist/agi/features/file-tools.d.ts +110 -0
  60. package/dist/agi/features/file-tools.d.ts.map +1 -0
  61. package/dist/agi/features/luca-coder.d.ts +323 -0
  62. package/dist/agi/features/luca-coder.d.ts.map +1 -0
  63. package/dist/agi/features/openai-codex.d.ts +381 -0
  64. package/dist/agi/features/openai-codex.d.ts.map +1 -0
  65. package/dist/agi/features/openapi.d.ts +200 -0
  66. package/dist/agi/features/openapi.d.ts.map +1 -0
  67. package/dist/agi/features/skills-library.d.ts +167 -0
  68. package/dist/agi/features/skills-library.d.ts.map +1 -0
  69. package/dist/agi/index.d.ts +5 -0
  70. package/dist/agi/index.d.ts.map +1 -0
  71. package/dist/agi/lib/interceptor-chain.d.ts +44 -0
  72. package/dist/agi/lib/interceptor-chain.d.ts.map +1 -0
  73. package/dist/agi/lib/token-counter.d.ts +13 -0
  74. package/dist/agi/lib/token-counter.d.ts.map +1 -0
  75. package/dist/bootstrap/generated.d.ts +5 -0
  76. package/dist/bootstrap/generated.d.ts.map +1 -0
  77. package/dist/browser.d.ts +12 -0
  78. package/dist/browser.d.ts.map +1 -0
  79. package/dist/bus.d.ts +29 -0
  80. package/dist/bus.d.ts.map +1 -0
  81. package/dist/cli/build-info.d.ts +4 -0
  82. package/dist/cli/build-info.d.ts.map +1 -0
  83. package/dist/cli/cli.d.ts +3 -12
  84. package/dist/cli/cli.d.ts.map +1 -0
  85. package/dist/client.d.ts +60 -0
  86. package/dist/client.d.ts.map +1 -0
  87. package/dist/clients/civitai/index.d.ts +472 -0
  88. package/dist/clients/civitai/index.d.ts.map +1 -0
  89. package/dist/clients/client-template.d.ts +30 -0
  90. package/dist/clients/client-template.d.ts.map +1 -0
  91. package/dist/clients/comfyui/index.d.ts +281 -0
  92. package/dist/clients/comfyui/index.d.ts.map +1 -0
  93. package/dist/clients/elevenlabs/index.d.ts +197 -0
  94. package/dist/clients/elevenlabs/index.d.ts.map +1 -0
  95. package/dist/clients/graph.d.ts +64 -0
  96. package/dist/clients/graph.d.ts.map +1 -0
  97. package/dist/clients/openai/index.d.ts +247 -0
  98. package/dist/clients/openai/index.d.ts.map +1 -0
  99. package/dist/clients/rest.d.ts +92 -0
  100. package/dist/clients/rest.d.ts.map +1 -0
  101. package/dist/clients/supabase/index.d.ts +176 -0
  102. package/dist/clients/supabase/index.d.ts.map +1 -0
  103. package/dist/clients/websocket.d.ts +127 -0
  104. package/dist/clients/websocket.d.ts.map +1 -0
  105. package/dist/command.d.ts +163 -0
  106. package/dist/command.d.ts.map +1 -0
  107. package/dist/commands/bootstrap.d.ts +20 -0
  108. package/dist/commands/bootstrap.d.ts.map +1 -0
  109. package/dist/commands/chat.d.ts +37 -0
  110. package/dist/commands/chat.d.ts.map +1 -0
  111. package/dist/commands/code.d.ts +28 -0
  112. package/dist/commands/code.d.ts.map +1 -0
  113. package/dist/commands/console.d.ts +22 -0
  114. package/dist/commands/console.d.ts.map +1 -0
  115. package/dist/commands/describe.d.ts +50 -0
  116. package/dist/commands/describe.d.ts.map +1 -0
  117. package/dist/commands/eval.d.ts +23 -0
  118. package/dist/commands/eval.d.ts.map +1 -0
  119. package/dist/commands/help.d.ts +25 -0
  120. package/dist/commands/help.d.ts.map +1 -0
  121. package/dist/commands/index.d.ts +18 -0
  122. package/dist/commands/index.d.ts.map +1 -0
  123. package/dist/commands/introspect.d.ts +24 -0
  124. package/dist/commands/introspect.d.ts.map +1 -0
  125. package/dist/commands/mcp.d.ts +35 -0
  126. package/dist/commands/mcp.d.ts.map +1 -0
  127. package/dist/commands/prompt.d.ts +38 -0
  128. package/dist/commands/prompt.d.ts.map +1 -0
  129. package/dist/commands/run.d.ts +24 -0
  130. package/dist/commands/run.d.ts.map +1 -0
  131. package/dist/commands/sandbox-mcp.d.ts +34 -0
  132. package/dist/commands/sandbox-mcp.d.ts.map +1 -0
  133. package/dist/commands/save-api-docs.d.ts +21 -0
  134. package/dist/commands/save-api-docs.d.ts.map +1 -0
  135. package/dist/commands/scaffold.d.ts +24 -0
  136. package/dist/commands/scaffold.d.ts.map +1 -0
  137. package/dist/commands/select.d.ts +22 -0
  138. package/dist/commands/select.d.ts.map +1 -0
  139. package/dist/commands/serve.d.ts +29 -0
  140. package/dist/commands/serve.d.ts.map +1 -0
  141. package/dist/container-describer.d.ts +144 -0
  142. package/dist/container-describer.d.ts.map +1 -0
  143. package/dist/container.d.ts +451 -0
  144. package/dist/container.d.ts.map +1 -0
  145. package/dist/endpoint.d.ts +113 -0
  146. package/dist/endpoint.d.ts.map +1 -0
  147. package/dist/feature.d.ts +47 -0
  148. package/dist/feature.d.ts.map +1 -0
  149. package/dist/graft.d.ts +29 -0
  150. package/dist/graft.d.ts.map +1 -0
  151. package/dist/hash-object.d.ts +8 -0
  152. package/dist/hash-object.d.ts.map +1 -0
  153. package/dist/helper.d.ts +209 -0
  154. package/dist/helper.d.ts.map +1 -0
  155. package/dist/introspection/generated.node.d.ts +44623 -0
  156. package/dist/introspection/generated.node.d.ts.map +1 -0
  157. package/dist/introspection/generated.web.d.ts +1412 -0
  158. package/dist/introspection/generated.web.d.ts.map +1 -0
  159. package/dist/introspection/index.d.ts +156 -0
  160. package/dist/introspection/index.d.ts.map +1 -0
  161. package/dist/introspection/scan.d.ts +147 -0
  162. package/dist/introspection/scan.d.ts.map +1 -0
  163. package/dist/node/container.d.ts +256 -0
  164. package/dist/node/container.d.ts.map +1 -0
  165. package/dist/node/feature.d.ts +9 -0
  166. package/dist/node/feature.d.ts.map +1 -0
  167. package/dist/node/features/container-link.d.ts +213 -0
  168. package/dist/node/features/container-link.d.ts.map +1 -0
  169. package/dist/node/features/content-db.d.ts +354 -0
  170. package/dist/node/features/content-db.d.ts.map +1 -0
  171. package/dist/node/features/disk-cache.d.ts +236 -0
  172. package/dist/node/features/disk-cache.d.ts.map +1 -0
  173. package/dist/node/features/dns.d.ts +511 -0
  174. package/dist/node/features/dns.d.ts.map +1 -0
  175. package/dist/node/features/docker.d.ts +485 -0
  176. package/dist/node/features/docker.d.ts.map +1 -0
  177. package/dist/node/features/downloader.d.ts +73 -0
  178. package/dist/node/features/downloader.d.ts.map +1 -0
  179. package/dist/node/features/figlet-fonts.d.ts +4 -0
  180. package/dist/node/features/figlet-fonts.d.ts.map +1 -0
  181. package/dist/node/features/file-manager.d.ts +177 -0
  182. package/dist/node/features/file-manager.d.ts.map +1 -0
  183. package/dist/node/features/fs.d.ts +635 -0
  184. package/dist/node/features/fs.d.ts.map +1 -0
  185. package/dist/node/features/git.d.ts +329 -0
  186. package/dist/node/features/git.d.ts.map +1 -0
  187. package/dist/node/features/google-auth.d.ts +200 -0
  188. package/dist/node/features/google-auth.d.ts.map +1 -0
  189. package/dist/node/features/google-calendar.d.ts +194 -0
  190. package/dist/node/features/google-calendar.d.ts.map +1 -0
  191. package/dist/node/features/google-docs.d.ts +138 -0
  192. package/dist/node/features/google-docs.d.ts.map +1 -0
  193. package/dist/node/features/google-drive.d.ts +202 -0
  194. package/dist/node/features/google-drive.d.ts.map +1 -0
  195. package/dist/node/features/google-mail.d.ts +221 -0
  196. package/dist/node/features/google-mail.d.ts.map +1 -0
  197. package/dist/node/features/google-sheets.d.ts +157 -0
  198. package/dist/node/features/google-sheets.d.ts.map +1 -0
  199. package/dist/node/features/grep.d.ts +207 -0
  200. package/dist/node/features/grep.d.ts.map +1 -0
  201. package/dist/node/features/helpers.d.ts +236 -0
  202. package/dist/node/features/helpers.d.ts.map +1 -0
  203. package/dist/node/features/ink.d.ts +332 -0
  204. package/dist/node/features/ink.d.ts.map +1 -0
  205. package/dist/node/features/ipc-socket.d.ts +298 -0
  206. package/dist/node/features/ipc-socket.d.ts.map +1 -0
  207. package/dist/node/features/json-tree.d.ts +140 -0
  208. package/dist/node/features/json-tree.d.ts.map +1 -0
  209. package/dist/node/features/networking.d.ts +373 -0
  210. package/dist/node/features/networking.d.ts.map +1 -0
  211. package/dist/node/features/nlp.d.ts +125 -0
  212. package/dist/node/features/nlp.d.ts.map +1 -0
  213. package/dist/node/features/opener.d.ts +93 -0
  214. package/dist/node/features/opener.d.ts.map +1 -0
  215. package/dist/node/features/os.d.ts +168 -0
  216. package/dist/node/features/os.d.ts.map +1 -0
  217. package/dist/node/features/package-finder.d.ts +419 -0
  218. package/dist/node/features/package-finder.d.ts.map +1 -0
  219. package/dist/node/features/postgres.d.ts +173 -0
  220. package/dist/node/features/postgres.d.ts.map +1 -0
  221. package/dist/node/features/proc.d.ts +285 -0
  222. package/dist/node/features/proc.d.ts.map +1 -0
  223. package/dist/node/features/process-manager.d.ts +427 -0
  224. package/dist/node/features/process-manager.d.ts.map +1 -0
  225. package/dist/node/features/python.d.ts +477 -0
  226. package/dist/node/features/python.d.ts.map +1 -0
  227. package/dist/node/features/redis.d.ts +247 -0
  228. package/dist/node/features/redis.d.ts.map +1 -0
  229. package/dist/node/features/repl.d.ts +84 -0
  230. package/dist/node/features/repl.d.ts.map +1 -0
  231. package/dist/node/features/runpod.d.ts +527 -0
  232. package/dist/node/features/runpod.d.ts.map +1 -0
  233. package/dist/node/features/secure-shell.d.ts +145 -0
  234. package/dist/node/features/secure-shell.d.ts.map +1 -0
  235. package/dist/node/features/semantic-search.d.ts +207 -0
  236. package/dist/node/features/semantic-search.d.ts.map +1 -0
  237. package/dist/node/features/sqlite.d.ts +180 -0
  238. package/dist/node/features/sqlite.d.ts.map +1 -0
  239. package/dist/node/features/telegram.d.ts +173 -0
  240. package/dist/node/features/telegram.d.ts.map +1 -0
  241. package/dist/node/features/transpiler.d.ts +51 -0
  242. package/dist/node/features/transpiler.d.ts.map +1 -0
  243. package/dist/node/features/tts.d.ts +108 -0
  244. package/dist/node/features/tts.d.ts.map +1 -0
  245. package/dist/node/features/ui.d.ts +562 -0
  246. package/dist/node/features/ui.d.ts.map +1 -0
  247. package/dist/node/features/vault.d.ts +90 -0
  248. package/dist/node/features/vault.d.ts.map +1 -0
  249. package/dist/node/features/vm.d.ts +285 -0
  250. package/dist/node/features/vm.d.ts.map +1 -0
  251. package/dist/node/features/yaml-tree.d.ts +118 -0
  252. package/dist/node/features/yaml-tree.d.ts.map +1 -0
  253. package/dist/node/features/yaml.d.ts +127 -0
  254. package/dist/node/features/yaml.d.ts.map +1 -0
  255. package/dist/node.d.ts +67 -0
  256. package/dist/node.d.ts.map +1 -0
  257. package/dist/python/generated.d.ts +2 -0
  258. package/dist/python/generated.d.ts.map +1 -0
  259. package/dist/react/index.d.ts +36 -0
  260. package/dist/react/index.d.ts.map +1 -0
  261. package/dist/registry.d.ts +97 -0
  262. package/dist/registry.d.ts.map +1 -0
  263. package/dist/scaffolds/generated.d.ts +13 -0
  264. package/dist/scaffolds/generated.d.ts.map +1 -0
  265. package/dist/scaffolds/template.d.ts +11 -0
  266. package/dist/scaffolds/template.d.ts.map +1 -0
  267. package/dist/schemas/base.d.ts +254 -0
  268. package/dist/schemas/base.d.ts.map +1 -0
  269. package/dist/selector.d.ts +130 -0
  270. package/dist/selector.d.ts.map +1 -0
  271. package/dist/server.d.ts +89 -0
  272. package/dist/server.d.ts.map +1 -0
  273. package/dist/servers/express.d.ts +104 -0
  274. package/dist/servers/express.d.ts.map +1 -0
  275. package/dist/servers/mcp.d.ts +201 -0
  276. package/dist/servers/mcp.d.ts.map +1 -0
  277. package/dist/servers/socket.d.ts +121 -0
  278. package/dist/servers/socket.d.ts.map +1 -0
  279. package/dist/state.d.ts +24 -0
  280. package/dist/state.d.ts.map +1 -0
  281. package/dist/web/clients/socket.d.ts +37 -0
  282. package/dist/web/clients/socket.d.ts.map +1 -0
  283. package/dist/web/container.d.ts +55 -0
  284. package/dist/web/container.d.ts.map +1 -0
  285. package/dist/web/extension.d.ts +4 -0
  286. package/dist/web/extension.d.ts.map +1 -0
  287. package/dist/web/feature.d.ts +8 -0
  288. package/dist/web/feature.d.ts.map +1 -0
  289. package/dist/web/features/asset-loader.d.ts +35 -0
  290. package/dist/web/features/asset-loader.d.ts.map +1 -0
  291. package/dist/web/features/container-link.d.ts +167 -0
  292. package/dist/web/features/container-link.d.ts.map +1 -0
  293. package/dist/web/features/esbuild.d.ts +51 -0
  294. package/dist/web/features/esbuild.d.ts.map +1 -0
  295. package/dist/web/features/helpers.d.ts +140 -0
  296. package/dist/web/features/helpers.d.ts.map +1 -0
  297. package/dist/web/features/network.d.ts +69 -0
  298. package/dist/web/features/network.d.ts.map +1 -0
  299. package/dist/web/features/speech.d.ts +71 -0
  300. package/dist/web/features/speech.d.ts.map +1 -0
  301. package/dist/web/features/vault.d.ts +62 -0
  302. package/dist/web/features/vault.d.ts.map +1 -0
  303. package/dist/web/features/vm.d.ts +48 -0
  304. package/dist/web/features/vm.d.ts.map +1 -0
  305. package/dist/web/features/voice-recognition.d.ts +96 -0
  306. package/dist/web/features/voice-recognition.d.ts.map +1 -0
  307. package/dist/web/shims/isomorphic-vm.d.ts +22 -0
  308. package/dist/web/shims/isomorphic-vm.d.ts.map +1 -0
  309. package/index.html +1457 -0
  310. package/index.ts +1 -0
  311. package/install.sh +84 -0
  312. package/luca.cli.ts +16 -0
  313. package/luca.console.ts +9 -0
  314. package/main.py +6 -0
  315. package/package.json +219 -58
  316. package/public/index.html +1457 -0
  317. package/public/slides-ai-native.html +902 -0
  318. package/public/slides-intro.html +974 -0
  319. package/pyproject.toml +7 -0
  320. package/scripts/build-web.ts +28 -0
  321. package/scripts/examples/ask-luca-expert.ts +42 -0
  322. package/scripts/examples/assistant-questions.ts +12 -0
  323. package/scripts/examples/excalidraw-expert.ts +75 -0
  324. package/scripts/examples/expert-chat.ts +0 -0
  325. package/scripts/examples/file-manager.ts +14 -0
  326. package/scripts/examples/ideas.ts +12 -0
  327. package/scripts/examples/interactive-chat.ts +20 -0
  328. package/scripts/examples/openai-tool-calls.ts +113 -0
  329. package/scripts/examples/opening-a-web-browser.ts +5 -0
  330. package/scripts/examples/telegram-bot.ts +79 -0
  331. package/scripts/examples/using-assistant-with-mcp.ts +555 -0
  332. package/scripts/examples/using-claude-code.ts +10 -0
  333. package/scripts/examples/using-contentdb.ts +35 -0
  334. package/scripts/examples/using-conversations.ts +35 -0
  335. package/scripts/examples/using-disk-cache.ts +10 -0
  336. package/scripts/examples/using-docker-shell.ts +75 -0
  337. package/scripts/examples/using-elevenlabs.ts +25 -0
  338. package/scripts/examples/using-google-calendar.ts +57 -0
  339. package/scripts/examples/using-google-docs.ts +74 -0
  340. package/scripts/examples/using-google-drive.ts +74 -0
  341. package/scripts/examples/using-google-sheets.ts +89 -0
  342. package/scripts/examples/using-nlp.ts +55 -0
  343. package/scripts/examples/using-ollama.ts +11 -0
  344. package/scripts/examples/using-postgres.ts +55 -0
  345. package/scripts/examples/using-runpod.ts +32 -0
  346. package/scripts/examples/using-tts.ts +40 -0
  347. package/scripts/scaffold.ts +391 -0
  348. package/scripts/scratch.ts +15 -0
  349. package/scripts/stamp-build.sh +12 -0
  350. package/scripts/test-assistant-hooks.ts +13 -0
  351. package/scripts/test-docs-reader.ts +10 -0
  352. package/scripts/test-linux-binary.sh +80 -0
  353. package/scripts/update-introspection-data.ts +58 -0
  354. package/src/agi/README.md +14 -0
  355. package/src/agi/container.server.ts +156 -0
  356. package/src/agi/feature.ts +13 -0
  357. package/src/agi/features/agent-memory.ts +694 -0
  358. package/src/agi/features/assistant.ts +1653 -0
  359. package/src/agi/features/assistants-manager.ts +534 -0
  360. package/src/agi/features/autonomous-assistant.ts +431 -0
  361. package/src/agi/features/browser-use.ts +672 -0
  362. package/src/agi/features/claude-code.ts +1584 -0
  363. package/src/agi/features/coding-tools.ts +175 -0
  364. package/src/agi/features/conversation-history.ts +672 -0
  365. package/src/agi/features/conversation.ts +1494 -0
  366. package/src/agi/features/docs-reader.ts +167 -0
  367. package/src/agi/features/file-tools.ts +340 -0
  368. package/src/agi/features/luca-coder.ts +641 -0
  369. package/src/agi/features/mcp-bridge.ts +532 -0
  370. package/src/agi/features/openai-codex.ts +651 -0
  371. package/src/agi/features/openapi.ts +445 -0
  372. package/src/agi/features/skills-library.ts +557 -0
  373. package/src/agi/index.ts +6 -0
  374. package/src/agi/lib/interceptor-chain.ts +89 -0
  375. package/src/agi/lib/token-counter.ts +202 -0
  376. package/src/bootstrap/generated.ts +9791 -0
  377. package/src/browser.ts +25 -0
  378. package/src/bus.ts +122 -0
  379. package/src/cli/build-info.ts +4 -0
  380. package/src/cli/cli.ts +355 -0
  381. package/src/client.ts +170 -0
  382. package/src/clients/civitai/index.ts +537 -0
  383. package/src/clients/client-template.ts +41 -0
  384. package/src/clients/comfyui/index.ts +604 -0
  385. package/src/clients/elevenlabs/index.ts +317 -0
  386. package/src/clients/graph.ts +87 -0
  387. package/src/clients/openai/index.ts +456 -0
  388. package/src/clients/rest.ts +207 -0
  389. package/src/clients/supabase/index.ts +357 -0
  390. package/src/clients/voicebox/index.ts +300 -0
  391. package/src/clients/websocket.ts +251 -0
  392. package/src/command.ts +506 -0
  393. package/src/commands/bootstrap.ts +244 -0
  394. package/src/commands/chat.ts +309 -0
  395. package/src/commands/code.ts +371 -0
  396. package/src/commands/console.ts +189 -0
  397. package/src/commands/describe.ts +243 -0
  398. package/src/commands/eval.ts +67 -0
  399. package/src/commands/help.ts +240 -0
  400. package/src/commands/index.ts +19 -0
  401. package/src/commands/introspect.ts +218 -0
  402. package/src/commands/mcp.ts +64 -0
  403. package/src/commands/prompt.ts +1014 -0
  404. package/src/commands/run.ts +278 -0
  405. package/src/commands/sandbox-mcp.ts +343 -0
  406. package/src/commands/save-api-docs.ts +51 -0
  407. package/src/commands/scaffold.ts +225 -0
  408. package/src/commands/select.ts +99 -0
  409. package/src/commands/serve.ts +208 -0
  410. package/src/container-describer.ts +1091 -0
  411. package/src/container.ts +1199 -0
  412. package/src/endpoint.ts +365 -0
  413. package/src/entity.ts +173 -0
  414. package/src/feature.ts +118 -0
  415. package/src/graft.ts +181 -0
  416. package/src/hash-object.ts +97 -0
  417. package/src/helper.ts +849 -0
  418. package/src/introspection/generated.agi.ts +41200 -0
  419. package/src/introspection/generated.node.ts +28773 -0
  420. package/src/introspection/generated.web.ts +2272 -0
  421. package/src/introspection/index.ts +296 -0
  422. package/src/introspection/scan.ts +1136 -0
  423. package/src/node/container.ts +409 -0
  424. package/src/node/feature.ts +13 -0
  425. package/src/node/features/container-link.ts +559 -0
  426. package/src/node/features/content-db.ts +849 -0
  427. package/src/node/features/disk-cache.ts +388 -0
  428. package/src/node/features/display-result.ts +57 -0
  429. package/src/node/features/dns.ts +669 -0
  430. package/src/node/features/docker.ts +921 -0
  431. package/src/node/features/downloader.ts +79 -0
  432. package/src/node/features/figlet-fonts.ts +600 -0
  433. package/src/node/features/file-manager.ts +535 -0
  434. package/src/node/features/fs.ts +1050 -0
  435. package/src/node/features/git.ts +592 -0
  436. package/src/node/features/google-auth.ts +504 -0
  437. package/src/node/features/google-calendar.ts +306 -0
  438. package/src/node/features/google-docs.ts +412 -0
  439. package/src/node/features/google-drive.ts +346 -0
  440. package/src/node/features/google-mail.ts +540 -0
  441. package/src/node/features/google-sheets.ts +286 -0
  442. package/src/node/features/grep.ts +427 -0
  443. package/src/node/features/helpers.ts +762 -0
  444. package/src/node/features/ink.ts +490 -0
  445. package/src/node/features/ipc-socket.ts +649 -0
  446. package/src/node/features/json-tree.ts +170 -0
  447. package/src/node/features/networking.ts +961 -0
  448. package/src/node/features/nlp.ts +212 -0
  449. package/src/node/features/opener.ts +180 -0
  450. package/src/node/features/os.ts +403 -0
  451. package/src/node/features/package-finder.ts +540 -0
  452. package/src/node/features/postgres.ts +289 -0
  453. package/src/node/features/proc.ts +503 -0
  454. package/src/node/features/process-manager.ts +844 -0
  455. package/src/node/features/python.ts +912 -0
  456. package/src/node/features/redis.ts +446 -0
  457. package/src/node/features/repl.ts +212 -0
  458. package/src/node/features/runpod.ts +811 -0
  459. package/src/node/features/secure-shell.ts +261 -0
  460. package/src/node/features/semantic-search.ts +935 -0
  461. package/src/node/features/sqlite.ts +289 -0
  462. package/src/node/features/telegram.ts +343 -0
  463. package/src/node/features/transpiler.ts +160 -0
  464. package/src/node/features/tts.ts +185 -0
  465. package/src/node/features/ui.ts +791 -0
  466. package/src/node/features/vault.ts +153 -0
  467. package/src/node/features/vm.ts +462 -0
  468. package/src/node/features/yaml-tree.ts +148 -0
  469. package/src/node/features/yaml.ts +133 -0
  470. package/src/node.ts +76 -0
  471. package/src/python/bridge.py +220 -0
  472. package/src/python/generated.ts +226 -0
  473. package/src/react/index.ts +175 -0
  474. package/src/registry.ts +210 -0
  475. package/src/scaffolds/generated.ts +1814 -0
  476. package/src/scaffolds/template.ts +46 -0
  477. package/src/schemas/base.ts +296 -0
  478. package/src/selector.ts +352 -0
  479. package/src/server.ts +229 -0
  480. package/src/servers/express.ts +283 -0
  481. package/src/servers/mcp.ts +802 -0
  482. package/src/servers/socket.ts +258 -0
  483. package/src/state.ts +101 -0
  484. package/src/web/clients/socket.ts +99 -0
  485. package/src/web/container.ts +75 -0
  486. package/src/web/extension.ts +30 -0
  487. package/src/web/feature.ts +12 -0
  488. package/src/web/features/asset-loader.ts +72 -0
  489. package/src/web/features/container-link.ts +382 -0
  490. package/src/web/features/esbuild.ts +93 -0
  491. package/src/web/features/helpers.ts +291 -0
  492. package/src/web/features/network.ts +85 -0
  493. package/src/web/features/speech.ts +104 -0
  494. package/src/web/features/vault.ts +207 -0
  495. package/src/web/features/vm.ts +85 -0
  496. package/src/web/features/voice-recognition.ts +161 -0
  497. package/src/web/shims/isomorphic-vm.ts +149 -0
  498. package/tsconfig.build.json +12 -0
  499. package/tsconfig.json +58 -0
  500. package/uv.lock +8 -0
  501. package/LICENSE +0 -21
  502. package/dist/cli/cli.js +0 -48
  503. package/dist/cli/common.d.ts +0 -2
  504. package/dist/cli/common.js +0 -6
  505. package/dist/cli/index.d.ts +0 -2
  506. package/dist/cli/index.js +0 -5
  507. package/dist/cli/run.d.ts +0 -1
  508. package/dist/cli/run.js +0 -38
  509. package/dist/core/index.d.ts +0 -4
  510. package/dist/core/index.js +0 -32
  511. package/dist/core/read.d.ts +0 -2
  512. package/dist/core/read.js +0 -29
  513. package/dist/core/request.d.ts +0 -1
  514. package/dist/core/request.js +0 -2
  515. package/dist/core/write.d.ts +0 -2
  516. package/dist/core/write.js +0 -21
  517. package/dist/index.d.ts +0 -1
  518. package/dist/index.js +0 -5
  519. package/dist/utils/common.d.ts +0 -9
  520. package/dist/utils/common.js +0 -57
  521. package/dist/utils/consts.d.ts +0 -3
  522. package/dist/utils/consts.js +0 -11
  523. package/dist/utils/dict.d.ts +0 -1
  524. package/dist/utils/dict.js +0 -7
  525. package/dist/utils/index.d.ts +0 -5
  526. package/dist/utils/index.js +0 -21
  527. package/dist/utils/log.d.ts +0 -1
  528. package/dist/utils/log.js +0 -5
  529. package/dist/utils/types.d.ts +0 -1
  530. package/dist/utils/types.js +0 -2
  531. package/dist/utils/utils.test.d.ts +0 -1
  532. package/dist/utils/utils.test.js +0 -7
@@ -0,0 +1,371 @@
1
+ import { z } from 'zod'
2
+ import * as readline from 'readline'
3
+ import { commands } from '../command.js'
4
+ import { CommandOptionsSchema } from '../schemas/base.js'
5
+ import type { ContainerContext } from '../container.js'
6
+ import type { AGIContainer, AGIFeatures } from '../agi/container.server.js'
7
+
8
+ declare module '../command.js' {
9
+ interface AvailableCommands {
10
+ code: ReturnType<typeof commands.registerHandler>
11
+ }
12
+ }
13
+
14
+ export const argsSchema = CommandOptionsSchema.extend({
15
+ model: z.string().optional().describe('Override the LLM model'),
16
+ local: z.boolean().default(false).describe('Use a local API server'),
17
+ prompt: z.string().optional().describe('Path to a markdown file or inline text for the system prompt'),
18
+ allowAll: z.boolean().default(false).describe('Start with all permissions set to allow (fully autonomous)'),
19
+ denyWrites: z.boolean().default(false).describe('Deny all write/delete/move operations'),
20
+ skills: z.string().optional().describe('Comma-separated list of additional skill names to load'),
21
+ })
22
+
23
+ export const positionals = ['prompt']
24
+
25
+ export default async function code(options: z.infer<typeof argsSchema>, context: ContainerContext<AGIFeatures>) {
26
+ const container = context.container as AGIContainer
27
+ const ui = container.feature('ui')
28
+ const colors = ui.colors
29
+ const fs = container.feature('fs')
30
+
31
+ // ── Resolve system prompt ──────────────────────────────────────────────
32
+ // The lucaCoder feature has a solid default system prompt. Only override
33
+ // if the user explicitly provides one via --prompt.
34
+ let systemPrompt: string | undefined
35
+
36
+ if (options.prompt) {
37
+ const resolved = container.paths.resolve(options.prompt)
38
+ if (fs.exists(resolved)) {
39
+ systemPrompt = String(fs.readFile(resolved))
40
+ } else if (!options.prompt.endsWith('.md')) {
41
+ systemPrompt = options.prompt
42
+ } else {
43
+ console.error(colors.red(`File not found: ${resolved}`))
44
+ process.exit(1)
45
+ }
46
+ }
47
+
48
+ // ── Permission profile ─────────────────────────────────────────────────
49
+ const readTools = ['readFile', 'searchFiles', 'findFiles', 'listDirectory', 'fileInfo']
50
+ const writeTools = ['writeFile', 'editFile', 'createDirectory', 'moveFile', 'copyFile', 'bash']
51
+ const dangerTools = ['deleteFile']
52
+ const skillTools = ['searchAvailableSkills', 'loadSkill', 'askSkillBasedQuestion']
53
+
54
+ const permissions: Record<string, 'allow' | 'ask' | 'deny'> = {}
55
+
56
+ // Skill tools are always allowed — they're read-only discovery operations
57
+ for (const t of skillTools) permissions[t] = 'allow'
58
+
59
+ if (options.allowAll) {
60
+ for (const t of [...readTools, ...writeTools, ...dangerTools]) permissions[t] = 'allow'
61
+ } else if (options.denyWrites) {
62
+ for (const t of readTools) permissions[t] = 'allow'
63
+ for (const t of writeTools) permissions[t] = 'deny'
64
+ for (const t of dangerTools) permissions[t] = 'deny'
65
+ } else {
66
+ // Default: reads are free, writes need approval, danger is denied
67
+ for (const t of readTools) permissions[t] = 'allow'
68
+ for (const t of writeTools) permissions[t] = 'ask'
69
+ for (const t of dangerTools) permissions[t] = 'deny'
70
+ }
71
+
72
+ // ── Parse extra skills ────────────────────────────────────────────────
73
+ const extraSkills = options.skills ? options.skills.split(',').map((s: string) => s.trim()).filter(Boolean) : undefined
74
+
75
+ // ── Create the luca coder ──────────────────────────────────────────────
76
+ const coder = container.feature('lucaCoder', {
77
+ tools: ['fileTools'],
78
+ permissions,
79
+ defaultPermission: 'ask',
80
+ systemPrompt,
81
+ model: options.model,
82
+ local: options.local,
83
+ skills: extraSkills,
84
+ maxTokens: 2048,
85
+ autoLoadLucaSkill: true,
86
+ })
87
+
88
+ // ── UI setup ───────────────────────────────────────────────────────────
89
+ const ink = container.feature('ink', { enable: true })
90
+ await ink.loadModules()
91
+ const React = ink.React
92
+ const { Text } = ink.components
93
+ const inkModule = await import('ink')
94
+
95
+ let responseBuffer = ''
96
+ let inkInstance: any = null
97
+
98
+ function mdElement(content: string) {
99
+ const rendered = content ? String(ui.markdown(content)).trimEnd() : ''
100
+ return React.createElement(Text, null, rendered)
101
+ }
102
+
103
+ // Wire events on coder before starting (it forwards from inner assistant)
104
+ coder.on('chunk', (text: string) => {
105
+ responseBuffer += text
106
+ if (!inkInstance) {
107
+ process.stdout.write('\n')
108
+ inkInstance = inkModule.render(mdElement(responseBuffer), { patchConsole: false })
109
+ } else {
110
+ inkInstance.rerender(mdElement(responseBuffer))
111
+ }
112
+ })
113
+
114
+ coder.on('toolCall', (toolName: string, args: any) => {
115
+ if (inkInstance) { inkInstance.unmount(); inkInstance = null }
116
+ responseBuffer = ''
117
+ const argsStr = JSON.stringify(args).slice(0, 120)
118
+ process.stdout.write(colors.dim(`\n ⟳ ${toolName}`) + colors.dim(`(${argsStr})\n`))
119
+ })
120
+
121
+ coder.on('toolResult', (toolName: string, result: any) => {
122
+ const preview = typeof result === 'string' ? result.slice(0, 100) : JSON.stringify(result).slice(0, 100)
123
+ process.stdout.write(colors.green(` ✓ ${toolName}`) + colors.dim(` → ${preview}${preview.length >= 100 ? '…' : ''}\n`))
124
+ })
125
+
126
+ coder.on('toolError', (toolName: string, error: any) => {
127
+ const msg = error?.message || String(error)
128
+ process.stdout.write(colors.red(` ✗ ${toolName}: ${msg}\n`))
129
+ })
130
+
131
+ coder.on('response', () => {
132
+ if (inkInstance) { inkInstance.unmount(); inkInstance = null }
133
+ responseBuffer = ''
134
+ process.stdout.write('\n')
135
+ })
136
+
137
+ // Start the coder (creates inner assistant, registers bash tool, stacks fileTools, loads skills)
138
+ await coder.start()
139
+
140
+ // ── Permission request handler ─────────────────────────────────────────
141
+ coder.on('permissionRequest', ({ id, toolName, args }: { id: string; toolName: string; args: Record<string, any> }) => {
142
+ if (inkInstance) { inkInstance.unmount(); inkInstance = null }
143
+
144
+ const argsPreview = Object.entries(args)
145
+ .map(([k, v]) => {
146
+ const val = typeof v === 'string'
147
+ ? (v.length > 60 ? v.slice(0, 57) + '...' : v)
148
+ : JSON.stringify(v)
149
+ return ` ${colors.dim(k)}: ${val}`
150
+ })
151
+ .join('\n')
152
+
153
+ process.stdout.write('\n')
154
+ process.stdout.write(colors.yellow(` ⚡ Permission required: ${colors.bold(toolName)}\n`))
155
+ if (argsPreview) process.stdout.write(argsPreview + '\n')
156
+ process.stdout.write(colors.dim(`\n [y] approve [n] deny [a] allow all future ${toolName} calls\n`))
157
+
158
+ promptApproval(id, toolName)
159
+ })
160
+
161
+ coder.on('toolBlocked', (toolName: string, reason: string) => {
162
+ process.stdout.write(colors.red(` ✗ ${toolName} blocked (${reason})\n`))
163
+ })
164
+
165
+ // ── Readline ───────────────────────────────────────────────────────────
166
+ let rl = readline.createInterface({
167
+ input: process.stdin,
168
+ output: process.stdout,
169
+ })
170
+ let rlClosed = false
171
+ rl.on('close', () => { rlClosed = true })
172
+
173
+ function ensureRl() {
174
+ if (rlClosed) {
175
+ rl = readline.createInterface({ input: process.stdin, output: process.stdout })
176
+ rlClosed = false
177
+ rl.on('close', () => { rlClosed = true })
178
+ }
179
+ }
180
+
181
+ function prompt(): Promise<string> {
182
+ return new Promise((resolve) => {
183
+ ensureRl()
184
+ rl.question(colors.cyan('\n code > '), (answer: string) => resolve(answer.trim()))
185
+ })
186
+ }
187
+
188
+ function promptApproval(id: string, toolName: string) {
189
+ ensureRl()
190
+ rl.question(colors.yellow(' > '), (answer: string) => {
191
+ const a = answer.trim().toLowerCase()
192
+ if (a === 'y' || a === 'yes') {
193
+ coder.approve(id)
194
+ } else if (a === 'a' || a === 'always') {
195
+ coder.permitTool(toolName)
196
+ coder.approve(id)
197
+ process.stdout.write(colors.green(` ✓ ${toolName} will be auto-approved from now on\n`))
198
+ } else {
199
+ coder.deny(id)
200
+ }
201
+ })
202
+ }
203
+
204
+ // ── Piped stdin mode ──────────────────────────────────────────────────
205
+ // When stdin is piped (e.g. `cat prompt.md | luca code`), read all of
206
+ // stdin as the initial prompt, run it, print the result, and exit.
207
+ if (!process.stdin.isTTY) {
208
+ const chunks: Buffer[] = []
209
+ for await (const chunk of process.stdin) {
210
+ chunks.push(chunk as Buffer)
211
+ }
212
+ const pipedInput = Buffer.concat(chunks).toString('utf-8').trim()
213
+
214
+ if (!pipedInput) {
215
+ console.error(colors.red(' No input received from stdin'))
216
+ process.exit(1)
217
+ }
218
+
219
+ console.log(colors.dim(` Piped input: ${pipedInput.length} chars`))
220
+ await coder.ask(pipedInput)
221
+ process.exit(0)
222
+ }
223
+
224
+ // ── Banner ─────────────────────────────────────────────────────────────
225
+ console.log()
226
+ console.log(ui.banner('CODE', { font: 'Small', colors: ['cyan', 'blue'] }))
227
+
228
+ const toolCount = Object.keys(coder.tools).length
229
+ const allowCount = Object.values(permissions).filter(v => v === 'allow').length
230
+ const askCount = Object.values(permissions).filter(v => v === 'ask').length
231
+ const denyCount = Object.values(permissions).filter(v => v === 'deny').length
232
+ const loadedSkills = coder.state.get('loadedSkills') as string[]
233
+
234
+ console.log(colors.dim(` ${toolCount} tools loaded`))
235
+ console.log(
236
+ colors.green(` ${allowCount} allow`) + colors.dim(' · ') +
237
+ colors.yellow(`${askCount} ask`) + colors.dim(' · ') +
238
+ colors.red(`${denyCount} deny`)
239
+ )
240
+ if (loadedSkills.length) {
241
+ console.log(colors.dim(` Skills: ${loadedSkills.join(', ')}`))
242
+ }
243
+ console.log()
244
+ console.log(colors.dim(' Commands: .exit .perms .skills .allow <tool> .deny <tool> .gate <tool> .allow-all /console'))
245
+ console.log()
246
+
247
+ // ── Main loop ──────────────────────────────────────────────────────────
248
+ while (true) {
249
+ const input = await prompt()
250
+ if (!input) continue
251
+
252
+ // Meta commands
253
+ if (input === '.exit') break
254
+
255
+ if (input === '.perms') {
256
+ const perms = coder.permissions
257
+ const def = coder.state.get('defaultPermission')
258
+ console.log()
259
+ console.log(colors.dim(` Default: ${def}`))
260
+ for (const [name, level] of Object.entries(perms).sort()) {
261
+ const color = level === 'allow' ? colors.green : level === 'deny' ? colors.red : colors.yellow
262
+ console.log(` ${color(level.padEnd(5))} ${name}`)
263
+ }
264
+ console.log()
265
+ continue
266
+ }
267
+
268
+ if (input === '.skills') {
269
+ const skillsLib = container.feature('skillsLibrary')
270
+ if (!skillsLib.isStarted) await skillsLib.start()
271
+ const available = skillsLib.list()
272
+ const loaded = coder.state.get('loadedSkills') as string[]
273
+ console.log()
274
+ if (available.length === 0) {
275
+ console.log(colors.dim(' No skills found'))
276
+ } else {
277
+ for (const skill of available) {
278
+ const isLoaded = loaded.includes(skill.name)
279
+ const marker = isLoaded ? colors.green('●') : colors.dim('○')
280
+ console.log(` ${marker} ${colors.bold(skill.name)} ${colors.dim('—')} ${colors.dim(skill.description || '')}`)
281
+ }
282
+ console.log()
283
+ console.log(colors.dim(` ${loaded.length} loaded into context, ${available.length} total available`))
284
+ }
285
+ console.log()
286
+ continue
287
+ }
288
+
289
+ if (input.startsWith('.allow-all')) {
290
+ for (const t of Object.keys(coder.tools)) {
291
+ coder.permitTool(t)
292
+ }
293
+ console.log(colors.green(' All tools set to allow'))
294
+ continue
295
+ }
296
+
297
+ if (input.startsWith('.allow ')) {
298
+ const tool = input.slice(7).trim()
299
+ coder.permitTool(tool)
300
+ console.log(colors.green(` ${tool} → allow`))
301
+ continue
302
+ }
303
+
304
+ if (input.startsWith('.deny ')) {
305
+ const tool = input.slice(6).trim()
306
+ coder.blockTool(tool)
307
+ console.log(colors.red(` ${tool} → deny`))
308
+ continue
309
+ }
310
+
311
+ if (input.startsWith('.gate ')) {
312
+ const tool = input.slice(6).trim()
313
+ coder.gateTool(tool)
314
+ console.log(colors.yellow(` ${tool} → ask`))
315
+ continue
316
+ }
317
+
318
+ if (input === '/console') {
319
+ // Pause readline so the REPL can own stdin
320
+ rl.close()
321
+
322
+ const featureContext: Record<string, any> = {}
323
+ for (const fname of container.features.available) {
324
+ try { featureContext[fname] = (container as any).feature(fname) } catch {}
325
+ }
326
+
327
+ const replPrompt = ui.colors.magenta('console') + ui.colors.dim(' > ')
328
+ const repl = container.feature('repl', { prompt: replPrompt })
329
+
330
+ console.log()
331
+ console.log(colors.dim(' Dropping into console. The coder is available as `coder`.'))
332
+ console.log(colors.dim(' Type .exit to return to code.'))
333
+ console.log()
334
+
335
+ await repl.start({
336
+ context: {
337
+ ...featureContext,
338
+ coder,
339
+ console,
340
+ setTimeout, setInterval, clearTimeout, clearInterval,
341
+ fetch,
342
+ },
343
+ })
344
+
345
+ // Wait for the REPL to close
346
+ await new Promise<void>((resolve) => {
347
+ repl._rl!.on('close', resolve)
348
+ })
349
+
350
+ // Resume readline
351
+ console.log()
352
+ console.log(colors.dim(' Back in code mode.'))
353
+ rl = readline.createInterface({ input: process.stdin, output: process.stdout })
354
+ rlClosed = false
355
+ rl.on('close', () => { rlClosed = true })
356
+ continue
357
+ }
358
+
359
+ // Ask the coder
360
+ await coder.ask(input)
361
+ }
362
+
363
+ rl.close()
364
+ console.log()
365
+ }
366
+
367
+ commands.registerHandler('code', {
368
+ description: 'Autonomous coding assistant with file tools, bash, and permission gating',
369
+ argsSchema,
370
+ handler: code,
371
+ })
@@ -0,0 +1,189 @@
1
+ import { z } from 'zod'
2
+ import { commands } from '../command.js'
3
+ import { CommandOptionsSchema } from '../schemas/base.js'
4
+ import type { ContainerContext } from '../container.js'
5
+
6
+ declare module '../command.js' {
7
+ interface AvailableCommands {
8
+ console: ReturnType<typeof commands.registerHandler>
9
+ }
10
+ }
11
+
12
+ export const argsSchema = CommandOptionsSchema.extend({
13
+ enable: z.string().optional().describe('Enable a feature before starting the REPL (e.g. --enable diskCache)'),
14
+ eval: z.string().optional().describe('Evaluate code, a script, or markdown file before dropping into the REPL'),
15
+ })
16
+
17
+ function resolveEvalTarget(ref: string, container: any): { type: 'code' | 'script' | 'markdown', value: string } {
18
+ const candidates = [ref, `${ref}.ts`, `${ref}.js`, `${ref}.md`]
19
+
20
+ for (const candidate of candidates) {
21
+ const resolved = container.paths.resolve(candidate)
22
+ if (container.fs.exists(resolved)) {
23
+ if (resolved.endsWith('.md')) return { type: 'markdown', value: resolved }
24
+ return { type: 'script', value: resolved }
25
+ }
26
+ }
27
+
28
+ // Not a file — treat as inline code
29
+ return { type: 'code', value: ref }
30
+ }
31
+
32
+ async function evalBeforeRepl(evalArg: string, container: any, featureContext: Record<string, any>): Promise<Record<string, any>> {
33
+ const target = resolveEvalTarget(evalArg, container)
34
+ const vm = container.feature('vm')
35
+ const ui = container.feature('ui')
36
+ const extraContext: Record<string, any> = {}
37
+
38
+ if (target.type === 'markdown') {
39
+ await container.docs.load()
40
+ const doc = await container.docs.parseMarkdownAtPath(target.value)
41
+ const transpiler = container.feature('transpiler')
42
+ const shared = vm.createContext({
43
+ console, fetch, URL, URLSearchParams,
44
+ setTimeout, clearTimeout, setInterval, clearInterval,
45
+ ...featureContext,
46
+ ...container.context,
47
+ })
48
+
49
+ const children = doc.ast.children
50
+ for (let i = 0; i < children.length; i++) {
51
+ const node = children[i]
52
+ if (node.type === 'code') {
53
+ const { value, lang, meta } = node
54
+ if (lang !== 'ts' && lang !== 'js' && lang !== 'tsx' && lang !== 'jsx') continue
55
+ if (meta && typeof meta === 'string' && meta.toLowerCase().includes('skip')) continue
56
+
57
+ console.log(ui.markdown(['```' + lang, value, '```'].join('\n')))
58
+
59
+ const needsTransform = lang === 'tsx' || lang === 'jsx'
60
+ let code = value
61
+ if (needsTransform) {
62
+ const { code: transformed } = transpiler.transformSync(value, { loader: lang as 'tsx' | 'jsx', format: 'cjs' })
63
+ code = transformed
64
+ }
65
+
66
+ await vm.run(code, shared)
67
+ Object.assign(shared, container.context)
68
+ } else {
69
+ const md = doc.stringify({ type: 'root', children: [node] })
70
+ console.log(ui.markdown(md))
71
+ }
72
+ }
73
+
74
+ Object.assign(extraContext, shared)
75
+ } else if (target.type === 'script') {
76
+ const code = container.fs.readFile(target.value, 'utf8')
77
+ const ctx = vm.createContext({
78
+ console, fetch, URL, URLSearchParams,
79
+ setTimeout, clearTimeout, setInterval, clearInterval,
80
+ ...featureContext,
81
+ ...container.context,
82
+ })
83
+ await vm.run(code, ctx)
84
+ Object.assign(extraContext, ctx)
85
+ } else {
86
+ const ctx = vm.createContext({
87
+ console, fetch, URL, URLSearchParams,
88
+ setTimeout, clearTimeout, setInterval, clearInterval,
89
+ ...featureContext,
90
+ ...container.context,
91
+ })
92
+ await vm.run(target.value, ctx)
93
+ Object.assign(extraContext, ctx)
94
+ }
95
+
96
+ return extraContext
97
+ }
98
+
99
+ export default async function lucaConsole(options: z.infer<typeof argsSchema>, context: ContainerContext) {
100
+ const container = context.container as any
101
+ const ui = container.feature('ui')
102
+
103
+ await container.helpers.discoverAll()
104
+
105
+ // make it easy to create features
106
+ container.addContext('feature', (...args: any) => container.feature(...args))
107
+
108
+ //this is a hack to make it so we can enable things before the console starts
109
+ if (container.argv.enable) {
110
+ for (const id of Array(container.argv.enable)) {
111
+ try {
112
+ container.feature(id, { ...container.argv, enable: true }).enable()
113
+ } catch(error: any) {
114
+ console.error(`Error enabling feature`, error.message)
115
+ }
116
+ }
117
+ }
118
+
119
+ const featureContext: Record<string, any> = {}
120
+ for (const name of container.features.available) {
121
+ try {
122
+ featureContext[name] = container.feature(name)
123
+ } catch {}
124
+ }
125
+
126
+ // Load user console module if present
127
+ const consoleModulePath = container.paths.resolve('luca.console.ts')
128
+ let consoleModuleLoaded = false
129
+ let consoleModuleError: Error | null = null
130
+
131
+ if (container.fs.exists(consoleModulePath)) {
132
+ try {
133
+ const vmFeature = container.feature('vm')
134
+ const userExports = vmFeature.loadModule(consoleModulePath, { container, console })
135
+ Object.assign(featureContext, userExports)
136
+ consoleModuleLoaded = true
137
+ } catch (err: any) {
138
+ consoleModuleError = err
139
+ }
140
+ }
141
+
142
+ // Run --eval target before starting the REPL
143
+ let evalContext: Record<string, any> = {}
144
+ if (options.eval) {
145
+ try {
146
+ evalContext = await evalBeforeRepl(options.eval, container, featureContext)
147
+ } catch (err: any) {
148
+ console.error(ui.colors.red(` Error evaluating: ${err.message}`))
149
+ }
150
+ }
151
+
152
+ const prompt = ui.colors.cyan('luca') + ui.colors.dim(' > ')
153
+
154
+ console.log()
155
+ console.log(ui.colors.dim(' Luca REPL — all container features in scope. Tab to autocomplete.'))
156
+ if (options.eval) {
157
+ console.log(ui.colors.dim(` Evaluated: ${options.eval}`))
158
+ }
159
+ if (consoleModuleLoaded) {
160
+ console.log(ui.colors.dim(' Loaded luca.console.ts exports into scope.'))
161
+ } else if (consoleModuleError) {
162
+ console.log(ui.colors.yellow(' ⚠ Failed to load luca.console.ts:'))
163
+ console.log(ui.colors.yellow(` ${consoleModuleError.message}`))
164
+ console.log(ui.colors.dim(' The REPL will start without your custom exports.'))
165
+ }
166
+ console.log(ui.colors.dim(' Type .exit to quit.'))
167
+ console.log()
168
+
169
+ const repl = container.feature('repl', { prompt })
170
+ await repl.start({
171
+ context: {
172
+ ...featureContext,
173
+ ...evalContext,
174
+ console,
175
+ setTimeout,
176
+ setInterval,
177
+ clearTimeout,
178
+ clearInterval,
179
+ fetch,
180
+ Bun,
181
+ },
182
+ })
183
+ }
184
+
185
+ commands.registerHandler('console', {
186
+ description: 'Start an interactive REPL with all container features in scope',
187
+ argsSchema,
188
+ handler: lucaConsole,
189
+ })