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,278 @@
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
+ run: ReturnType<typeof commands.registerHandler>
9
+ }
10
+ }
11
+
12
+ export const argsSchema = CommandOptionsSchema.extend({
13
+ safe: z.boolean().default(false).describe('Require approval before each code block (markdown mode)'),
14
+ console: z.boolean().default(false).describe('Start an interactive REPL after executing a markdown file, with all accumulated context'),
15
+ onlySections: z.string().optional().describe('Comma-separated list of section headings to run (case-insensitive, markdown only)'),
16
+ dontInjectContext: z.boolean().default(false).describe('Skip auto-injecting container context into scripts (run with plain bun instead)'),
17
+ })
18
+
19
+
20
+ function resolveScript(ref: string, context: ContainerContext): string | null {
21
+ const container = context.container as any
22
+ const candidates = [
23
+ ref,
24
+ `${ref}.ts`,
25
+ `${ref}.js`,
26
+ `${ref}.md`,
27
+ ]
28
+
29
+ for (const candidate of candidates) {
30
+ const resolved = container.paths.resolve(candidate)
31
+ if (container.fs.exists(resolved)) return resolved
32
+ }
33
+
34
+ return null
35
+ }
36
+
37
+ /**
38
+ * Find the ## Blocks section in the AST and return the indices to skip
39
+ * plus the tsx/jsx code block values to register.
40
+ */
41
+ function extractBlocksSection(children: any[]): { skipIndices: Set<number>, blockSources: string[] } {
42
+ const skipIndices = new Set<number>()
43
+ const blockSources: string[] = []
44
+
45
+ let inBlocks = false
46
+ for (let i = 0; i < children.length; i++) {
47
+ const node = children[i]
48
+
49
+ if (node.type === 'heading' && node.depth === 2) {
50
+ const text = (node.children || []).map((c: any) => c.value || '').join('').trim()
51
+ if (text === 'Blocks') {
52
+ inBlocks = true
53
+ skipIndices.add(i)
54
+ continue
55
+ } else if (inBlocks) {
56
+ // hit the next ## heading — stop collecting
57
+ break
58
+ }
59
+ }
60
+
61
+ if (inBlocks) {
62
+ skipIndices.add(i)
63
+ if (node.type === 'code' && (node.lang === 'tsx' || node.lang === 'jsx')) {
64
+ blockSources.push(node.value)
65
+ }
66
+ }
67
+ }
68
+
69
+ return { skipIndices, blockSources }
70
+ }
71
+
72
+ async function runMarkdown(scriptPath: string, options: z.infer<typeof argsSchema>, context: ContainerContext) {
73
+ console.clear()
74
+ const container = context.container as any
75
+ const requireApproval = options.safe
76
+ await container.docs.load()
77
+
78
+ const doc = await container.docs.parseMarkdownAtPath(scriptPath)
79
+
80
+ const transpiler = container.feature('transpiler')
81
+ const ink = container.feature('ink', { enable: true })
82
+ await ink.loadModules()
83
+
84
+ const vm = container.feature('vm')
85
+ const render = async (name: string, data?: any) => ink.renderBlock(name, data)
86
+ const renderAsync = async (name: string, data?: any, options?: { timeout?: number }) => ink.renderBlockAsync(name, data, options)
87
+ const shared = vm.createContext({
88
+ console, ink, render, renderAsync,
89
+ setTimeout, clearTimeout, setInterval, clearInterval,
90
+ fetch, URL, URLSearchParams,
91
+ ...container.context,
92
+ $doc: doc
93
+ })
94
+
95
+ // ─── Parse and register ## Blocks section ──────────────────────────
96
+ const { skipIndices, blockSources } = extractBlocksSection(doc.ast.children)
97
+
98
+ for (const source of blockSources) {
99
+ const keysBefore = new Set(Object.keys(shared))
100
+ const { code: transformed } = transpiler.transformSync(source, { loader: 'tsx', format: 'cjs' })
101
+
102
+ await vm.run(transformed, shared)
103
+
104
+ // auto-register any new functions as blocks
105
+ for (const key of Object.keys(shared)) {
106
+ if (!keysBefore.has(key) && typeof shared[key] === 'function') {
107
+ ink.registerBlock(key, shared[key])
108
+ }
109
+ }
110
+ }
111
+
112
+ // ─── Build section filter from --only-sections ───────────────────
113
+ let allowedIndices: Set<number> | null = null
114
+ if (options.onlySections) {
115
+ const requestedSections = options.onlySections.split(',').map(s => s.trim())
116
+ allowedIndices = new Set<number>()
117
+ for (const sectionName of requestedSections) {
118
+ try {
119
+ const sectionNodes = doc.extractSection(sectionName)
120
+ for (const node of sectionNodes) {
121
+ const idx = doc.ast.children.indexOf(node as any)
122
+ if (idx !== -1) allowedIndices.add(idx)
123
+ }
124
+ } catch {
125
+ // Section not found — skip silently
126
+ }
127
+ }
128
+ }
129
+
130
+ // ─── Execute document ──────────────────────────────────────────────
131
+ const children = doc.ast.children
132
+ for (let i = 0; i < children.length; i++) {
133
+ if (skipIndices.has(i)) continue
134
+ if (allowedIndices && !allowedIndices.has(i)) continue
135
+
136
+ const node = children[i]
137
+ if (node.type === 'code') {
138
+ const { value, lang, meta } = node
139
+
140
+ if (lang !== 'ts' && lang !== 'js' && lang !== 'tsx' && lang !== 'jsx') {
141
+ console.log(container.ui.markdown(['```' + (lang || ''), value, '```'].join('\n')))
142
+ continue
143
+ }
144
+
145
+ if (meta && typeof meta === 'string' && meta.toLowerCase().includes('skip')) {
146
+ console.log(container.ui.markdown(['```' + lang, value, '```'].join('\n')))
147
+ continue
148
+ }
149
+
150
+ console.log(container.ui.markdown(['```' + lang, value, '```'].join('\n')))
151
+
152
+ if (requireApproval) {
153
+ const answer = await container.ui.askQuestion('Run this block? (y/n)')
154
+ if (answer.question.toLowerCase() !== 'y') continue
155
+ }
156
+
157
+ // Transform tsx/jsx through esbuild, and also ts for consistency
158
+ const needsTransform = lang === 'tsx' || lang === 'jsx'
159
+ let code = value
160
+
161
+ if (needsTransform) {
162
+ const { code: transformed } = transpiler.transformSync(value, {
163
+ loader: lang as 'tsx' | 'jsx',
164
+ format: 'cjs',
165
+ })
166
+ code = transformed
167
+ }
168
+
169
+ await vm.run(code, shared)
170
+
171
+ // if we enabled any features, they will be in the context object
172
+ Object.assign(shared, container.context)
173
+ } else {
174
+ const md = doc.stringify({ type: 'root', children: [node] })
175
+ console.log(container.ui.markdown(md))
176
+ }
177
+ }
178
+
179
+ return shared
180
+ }
181
+
182
+ async function runScript(scriptPath: string, context: ContainerContext, options: { dontInjectContext?: boolean } = {}) {
183
+ const container = context.container as any
184
+
185
+ if (options.dontInjectContext) {
186
+ const { exitCode, stderr } = await container.proc.execAndCapture(`bun run ${scriptPath}`, {
187
+ onOutput: (data: string) => process.stdout.write(data),
188
+ onError: (data: string) => process.stderr.write(data),
189
+ })
190
+
191
+ if (exitCode === 0) return
192
+
193
+ console.error(`\nScript failed with exit code ${exitCode}.\n`)
194
+ if (stderr.length) {
195
+ console.error(stderr)
196
+ }
197
+ return
198
+ }
199
+
200
+ const vm = container.feature('vm')
201
+ const transpiler = container.feature('transpiler')
202
+ const raw = container.fs.readFile(scriptPath)
203
+
204
+ const { code } = transpiler.transformSync(raw, { format: 'cjs' })
205
+
206
+ const ctx = {
207
+ require: vm.createRequireFor(scriptPath),
208
+ exports: {},
209
+ module: { exports: {} },
210
+ console,
211
+ setTimeout, setInterval, clearTimeout, clearInterval,
212
+ process, Buffer, URL, URLSearchParams,
213
+ fetch,
214
+ ...container.context,
215
+ }
216
+
217
+ await vm.run(code, ctx)
218
+ }
219
+
220
+ async function diagnoseError(_scriptPath: string, error: Error, _context: ContainerContext) {
221
+ console.error(`\n${error.stack || error.message}\n`)
222
+ }
223
+
224
+ export default async function run(options: z.infer<typeof argsSchema>, context: ContainerContext) {
225
+ const container = context.container as any
226
+ const fileRef = container.argv._[1] as string
227
+
228
+ if (!fileRef) {
229
+ console.error('Usage: luca run <file>')
230
+ process.exit(1)
231
+ }
232
+
233
+ const scriptPath = resolveScript(fileRef, context)
234
+
235
+ if (!scriptPath) {
236
+ console.error(`Could not find script: ${fileRef}`)
237
+ process.exit(1)
238
+ }
239
+
240
+ try {
241
+ if (scriptPath.endsWith('.md')) {
242
+ const shared = await runMarkdown(scriptPath, options, context)
243
+
244
+ if (options.console) {
245
+ const ui = container.feature('ui')
246
+ const prompt = ui.colors.cyan('luca') + ui.colors.dim(' > ')
247
+
248
+ console.log()
249
+ console.log(ui.colors.dim(' Entering REPL with markdown context. Type .exit to quit.'))
250
+ console.log()
251
+
252
+ const repl = container.feature('repl', { prompt })
253
+ await repl.start({
254
+ context: {
255
+ ...shared,
256
+ console,
257
+ setTimeout,
258
+ setInterval,
259
+ clearTimeout,
260
+ clearInterval,
261
+ fetch,
262
+ Bun,
263
+ },
264
+ })
265
+ }
266
+ } else {
267
+ await runScript(scriptPath, context, { dontInjectContext: options.dontInjectContext })
268
+ }
269
+ } catch (err: any) {
270
+ await diagnoseError(scriptPath, err instanceof Error ? err : new Error(String(err)), context)
271
+ }
272
+ }
273
+
274
+ commands.registerHandler('run', {
275
+ description: 'Run a script or markdown file (.ts, .js, .md)',
276
+ argsSchema,
277
+ handler: run,
278
+ })
@@ -0,0 +1,343 @@
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
+ import type { MCPServer } from '../servers/mcp.js'
6
+ import { mcpReadme } from '../scaffolds/generated.js'
7
+
8
+ declare module '../command.js' {
9
+ interface AvailableCommands {
10
+ 'sandbox-mcp': ReturnType<typeof commands.registerHandler>
11
+ }
12
+ }
13
+
14
+ export const argsSchema = CommandOptionsSchema.extend({
15
+ transport: z.enum(['stdio', 'http']).default('stdio').describe('Transport type (stdio or http)'),
16
+ port: z.number().default(3002).describe('Port for HTTP transport'),
17
+ mcpCompat: z.enum(['standard', 'codex']).optional()
18
+ .describe('HTTP compatibility profile. Defaults to standard. Can also be set via MCP_HTTP_COMPAT.'),
19
+ stdioCompat: z.enum(['standard', 'codex', 'auto']).optional()
20
+ .describe('Stdio framing compatibility profile. Defaults to standard. Can also be set via MCP_STDIO_COMPAT.'),
21
+ })
22
+
23
+ /**
24
+ * Run a luca CLI command as a subprocess and return its output.
25
+ * Always spawns fresh so callers see the latest project code.
26
+ */
27
+ async function lucaCLI(proc: any, command: string, args: string[] = []): Promise<{ stdout: string; stderr: string; exitCode: number }> {
28
+ const result = await proc.spawnAndCapture('luca', [command, ...args])
29
+ return { stdout: result.stdout.trim(), stderr: result.stderr.trim(), exitCode: result.exitCode ?? 0 }
30
+ }
31
+
32
+ export default async function mcpSandbox(options: z.infer<typeof argsSchema>, context: ContainerContext) {
33
+ const container = context.container as any
34
+ const proc = container.feature('proc')
35
+ const envCompat = process.env.MCP_HTTP_COMPAT?.toLowerCase()
36
+ const resolvedCompat = options.mcpCompat || (envCompat === 'codex' ? 'codex' : 'standard')
37
+ const envStdioCompat = process.env.MCP_STDIO_COMPAT?.toLowerCase()
38
+ const resolvedStdioCompat = options.stdioCompat
39
+ || (envStdioCompat === 'codex' || envStdioCompat === 'auto' ? envStdioCompat : 'standard')
40
+
41
+ const mcpServer = container.server('mcp', {
42
+ transport: options.transport,
43
+ port: options.port,
44
+ serverName: 'luca-sandbox',
45
+ serverVersion: container.manifest?.version || '1.0.0',
46
+ mcpCompat: options.mcpCompat,
47
+ stdioCompat: options.stdioCompat,
48
+ }) as MCPServer
49
+
50
+ // --- Tool: read_me ---
51
+ mcpServer.tool('read_me', {
52
+ description: [
53
+ 'Returns the Luca framework development guide. Call this BEFORE writing any code in a luca project.',
54
+ 'Contains the import conventions, capability map, and workflow for discovering and using container features.',
55
+ 'You should call this tool at the start of every session.',
56
+ ].join('\n'),
57
+ schema: z.object({}),
58
+ handler: () => mcpReadme,
59
+ })
60
+
61
+ // --- Tool: find_capability ---
62
+ mcpServer.tool('find_capability', {
63
+ description: [
64
+ 'Search for container capabilities by intent. Returns the full catalog of available features, clients,',
65
+ 'and servers with their descriptions so you can find what you need before writing code.',
66
+ 'Call this when you need to do something and aren\'t sure which helper provides it.',
67
+ 'Prefer this over installing npm packages — the container likely already has what you need.',
68
+ ].join('\n'),
69
+ schema: z.object({}),
70
+ handler: async () => {
71
+ const { stdout, stderr } = await lucaCLI(proc, 'eval', [
72
+ '[container.features.describeAll(), container.clients.describeAll(), container.servers.describeAll()].join("\\n\\n---\\n\\n")',
73
+ ])
74
+ return stdout || stderr
75
+ },
76
+ })
77
+
78
+ // --- Tool: scaffold ---
79
+ mcpServer.tool('scaffold', {
80
+ description: [
81
+ 'Generate correct boilerplate for a new luca helper (feature, client, server, command, or endpoint).',
82
+ 'Returns the complete file content with your name and description filled in.',
83
+ 'Write this to a file, then fill in your implementation.',
84
+ 'The scaffold follows all luca conventions including schemas, jsdoc, module augmentation, and registration.',
85
+ ].join('\n'),
86
+ schema: z.object({
87
+ type: z.enum(['feature', 'client', 'server', 'command', 'endpoint'])
88
+ .describe('What kind of helper to scaffold'),
89
+ name: z.string()
90
+ .describe('Name for the helper (e.g. "diskCache", "myApi", "healthCheck")'),
91
+ description: z.string().optional()
92
+ .describe('Brief description of what this helper does'),
93
+ }),
94
+ handler: async (args) => {
95
+ const cliArgs = [args.type, args.name]
96
+ if (args.description) cliArgs.push('--description', args.description)
97
+ const { stdout, stderr } = await lucaCLI(proc, 'scaffold', cliArgs)
98
+ return stdout || stderr
99
+ },
100
+ })
101
+
102
+ // --- Tool: eval ---
103
+ mcpServer.tool('eval', {
104
+ description: [
105
+ 'Evaluate JavaScript/TypeScript code in a Luca container sandbox.',
106
+ 'Use this to prototype and test container API calls before writing them into files.',
107
+ 'Each call runs in a fresh luca process — always reflects the latest project code.',
108
+ '',
109
+ 'The sandbox has a live `container` object and all enabled features as top-level variables',
110
+ '(e.g. `fs`, `git`, `ui`, `vm`, `proc`, `networking`, etc).',
111
+ '',
112
+ 'The result of the last expression is returned. For async code, use `await`.',
113
+ '',
114
+ 'Quick reference:',
115
+ ' container.features.available — list available feature names',
116
+ ' container.clients.available — list available client names',
117
+ ' container.servers.available — list available server names',
118
+ ' container.commands.available — list available command names',
119
+ ' container.features.describe(n) — get docs for a feature by name',
120
+ ' container.clients.describe(n) — get docs for a client by name',
121
+ ' container.introspectAsText() — full container introspection',
122
+ ' fs.readFile(path) — read a file',
123
+ ' fs.readdir(dir) — list directory contents',
124
+ ' proc.exec(cmd) — run a shell command',
125
+ ].join('\n'),
126
+ schema: z.object({
127
+ code: z.string().describe('JavaScript code to evaluate in the Luca container sandbox'),
128
+ }),
129
+ handler: async (args) => {
130
+ const { stdout, stderr, exitCode } = await lucaCLI(proc, 'eval', [args.code])
131
+ const text = stdout || stderr || 'undefined'
132
+ return {
133
+ content: [{ type: 'text' as const, text }],
134
+ isError: exitCode !== 0,
135
+ }
136
+ },
137
+ })
138
+
139
+ // --- Tool: inspect_container ---
140
+ mcpServer.tool('inspect_container', {
141
+ description: [
142
+ 'Inspect the Luca container — registries, state, methods, events, environment.',
143
+ '',
144
+ 'Returns a markdown overview of the container. Optionally filter to a specific section.',
145
+ '',
146
+ 'Sections: "methods", "getters", "events", "state", "options", "envVars"',
147
+ 'Leave section empty for the full overview.',
148
+ ].join('\n'),
149
+ schema: z.object({
150
+ section: z.enum(['methods', 'getters', 'events', 'state', 'options', 'envVars']).optional()
151
+ .describe('Optional section to filter to. Omit for full overview.'),
152
+ }),
153
+ handler: async (args) => {
154
+ const code = args.section
155
+ ? `container.introspectAsText("${args.section}")`
156
+ : 'container.introspectAsText()'
157
+ const { stdout, stderr } = await lucaCLI(proc, 'eval', [code])
158
+ return stdout || stderr
159
+ },
160
+ })
161
+
162
+ // --- Tool: list_registry ---
163
+ mcpServer.tool('list_registry', {
164
+ description: [
165
+ 'List available items in a container registry.',
166
+ '',
167
+ 'Returns names and brief descriptions for all registered helpers in the chosen registry.',
168
+ 'Use describe_helper to get full documentation for a specific item.',
169
+ ].join('\n'),
170
+ schema: z.object({
171
+ registry: z.enum(['features', 'clients', 'servers', 'commands', 'endpoints'])
172
+ .describe('Which registry to list'),
173
+ }),
174
+ handler: async (args) => {
175
+ const { stdout, stderr } = await lucaCLI(proc, 'eval', [
176
+ `container.${args.registry}.available.map(n => { try { const C = container.${args.registry}.lookup(n); return "- **" + n + "**" + (C.description ? ": " + C.description : "") } catch { return "- **" + n + "**" } }).join("\\n")`,
177
+ ])
178
+ return stdout || stderr
179
+ },
180
+ })
181
+
182
+ // --- Tool: describe_helper ---
183
+ mcpServer.tool('describe_helper', {
184
+ description: [
185
+ 'Get full documentation for a specific helper (feature, client, server, command, endpoint).',
186
+ 'This is the API documentation for any luca helper. There is no other documentation available —',
187
+ 'call this before writing code that uses a feature, client, or server.',
188
+ '',
189
+ 'Returns markdown with options, state schema, methods, getters, events, env vars, and descriptions.',
190
+ 'Use list_registry or find_capability first to see what is available.',
191
+ ].join('\n'),
192
+ schema: z.object({
193
+ name: z.string().describe('Name of the helper (e.g. "fs", "rest", "express", "serve")'),
194
+ section: z.enum(['methods', 'getters', 'events', 'state', 'options', 'envVars']).optional()
195
+ .describe('Optional section to filter to. Omit for full documentation.'),
196
+ }),
197
+ handler: async (args) => {
198
+ const describeArgs = [args.name]
199
+ if (args.section) describeArgs.push(args.section)
200
+ const { stdout, stderr } = await lucaCLI(proc, 'describe', describeArgs)
201
+ return stdout || stderr
202
+ },
203
+ })
204
+
205
+ // --- Tool: inspect_helper_instance ---
206
+ mcpServer.tool('inspect_helper_instance', {
207
+ description: [
208
+ 'Inspect a live helper instance (enabled feature, active client/server).',
209
+ 'Use this to inspect a live, running instance — see its current state,',
210
+ 'check method signatures, and understand runtime behavior.',
211
+ '',
212
+ 'Runs in a fresh process so you always see the latest code.',
213
+ 'Optionally filter to a specific section.',
214
+ ].join('\n'),
215
+ schema: z.object({
216
+ type: z.enum(['feature', 'client', 'server'])
217
+ .describe('What kind of helper to inspect'),
218
+ name: z.string().describe('Name of the helper (e.g. "fs", "rest", "express")'),
219
+ section: z.enum(['methods', 'getters', 'events', 'state', 'options', 'envVars']).optional()
220
+ .describe('Optional section to filter to. Omit for full introspection.'),
221
+ }),
222
+ handler: async (args) => {
223
+ const accessor = args.type === 'feature'
224
+ ? `container.feature('${args.name}')`
225
+ : args.type === 'client'
226
+ ? `container.client('${args.name}')`
227
+ : `container.server('${args.name}')`
228
+ const code = args.section
229
+ ? `${accessor}.introspectAsText("${args.section}")`
230
+ : `${accessor}.introspectAsText()`
231
+ const { stdout, stderr } = await lucaCLI(proc, 'eval', [code])
232
+ return stdout || stderr
233
+ },
234
+ })
235
+
236
+ // --- Prompt: discover ---
237
+ mcpServer.prompt('discover', {
238
+ description: 'Learn how to explore the Luca container and discover available features, clients, servers, and commands.',
239
+ handler: () => [{
240
+ role: 'user' as const,
241
+ content: [
242
+ '# Luca Container Sandbox',
243
+ '',
244
+ 'You have access to a live Luca container through the `eval` tool. Each call runs in a fresh process,',
245
+ 'so you always see the latest project code. Use the `eval` tool to prototype and explore.',
246
+ '',
247
+ '## Discovering what is available',
248
+ '',
249
+ 'The container has registries for each helper type. Each registry has:',
250
+ '- `.available` — array of registered names',
251
+ '- `.describe(name)` — returns markdown docs for one helper',
252
+ '- `.describeAll()` — returns a condensed overview of all helpers (name + description)',
253
+ '',
254
+ '### Registries',
255
+ '```',
256
+ 'container.features.available // Features (fs, git, ui, vm, proc, ...)',
257
+ 'container.clients.available // Clients (rest, websocket, graphql, ...)',
258
+ 'container.servers.available // Servers (express, mcp, socket, ...)',
259
+ 'container.commands.available // Commands (run, console, serve, ...)',
260
+ '```',
261
+ '',
262
+ '### Getting documentation',
263
+ '```',
264
+ 'container.features.describe("fs") // Docs for the fs feature',
265
+ 'container.features.describe("vm") // Docs for the vm feature',
266
+ 'container.clients.describe("rest") // Docs for the rest client',
267
+ 'container.introspectAsText() // Full container introspection',
268
+ 'container.introspectAsText("methods") // Just the methods section',
269
+ 'container.introspectAsText("state") // Just the state section',
270
+ '```',
271
+ '',
272
+ '### Using features directly',
273
+ 'All enabled features are available as top-level variables:',
274
+ '```',
275
+ 'fs.readFile("package.json") // Read a file',
276
+ 'fs.readdir("src") // List directory',
277
+ 'git.log({ max: 5 }) // Recent git commits',
278
+ 'proc.exec("ls -la") // Run a shell command',
279
+ '```',
280
+ ].join('\n'),
281
+ }],
282
+ })
283
+
284
+ // --- Prompt: introspect ---
285
+ mcpServer.prompt('introspect', {
286
+ description: 'Get full introspection of the Luca container — all registries, state, methods, events, and environment info.',
287
+ handler: async () => {
288
+ const { stdout } = await lucaCLI(proc, 'eval', ['container.introspectAsText()'])
289
+ return [{
290
+ role: 'user' as const,
291
+ content: `Here is the full container introspection:\n\n${stdout}`,
292
+ }]
293
+ },
294
+ })
295
+
296
+ // --- Resource: container-info ---
297
+ mcpServer.resource('luca://container/info', {
298
+ name: 'Container Info',
299
+ description: 'Full introspection of the running Luca container',
300
+ mimeType: 'text/markdown',
301
+ handler: async () => {
302
+ const { stdout } = await lucaCLI(proc, 'eval', ['container.introspectAsText()'])
303
+ return stdout
304
+ },
305
+ })
306
+
307
+ // --- Resource: feature list ---
308
+ mcpServer.resource('luca://features', {
309
+ name: 'Available Features',
310
+ description: 'List of all registered features with descriptions',
311
+ mimeType: 'text/markdown',
312
+ handler: async () => {
313
+ const { stdout } = await lucaCLI(proc, 'eval', [
314
+ '"# Available Features\\n" + container.features.available.map(n => { try { const C = container.features.lookup(n); return "- **" + n + "**: " + (C.description || "") } catch { return "- **" + n + "**" } }).join("\\n")',
315
+ ])
316
+ return stdout
317
+ },
318
+ })
319
+
320
+ // Start the server
321
+ await mcpServer.start({
322
+ transport: options.transport,
323
+ port: options.port,
324
+ mcpCompat: options.mcpCompat,
325
+ stdioCompat: options.stdioCompat,
326
+ })
327
+
328
+ if (options.transport === 'http') {
329
+ console.log(`\nLuca Sandbox MCP listening on http://localhost:${options.port}/mcp`)
330
+ console.log(`Compatibility: ${resolvedCompat}`)
331
+ } else {
332
+ console.error(`Luca Sandbox MCP started (stdio transport)`)
333
+ console.error(`Stdio Compatibility: ${resolvedStdioCompat}`)
334
+ console.error(`Tools: read_me, find_capability, scaffold, eval, inspect_container, list_registry, describe_helper, inspect_helper_instance`)
335
+ console.error(`Prompts: discover, introspect | Resources: luca://container/info, luca://features`)
336
+ }
337
+ }
338
+
339
+ commands.registerHandler('sandbox-mcp', {
340
+ description: 'Start an MCP server with a Luca container sandbox for AI agents to explore and test code',
341
+ argsSchema,
342
+ handler: mcpSandbox,
343
+ })
@@ -0,0 +1,51 @@
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
+ import type { NodeContainer } from '../node/container.js'
6
+
7
+ declare module '../command.js' {
8
+ interface AvailableCommands {
9
+ introspect: ReturnType<typeof commands.registerHandler>
10
+ }
11
+ }
12
+
13
+ export const argsSchema = CommandOptionsSchema.extend({
14
+ outputPath: z.string().default('docs/luca').describe('The path to save generated API docs to')
15
+ })
16
+
17
+ export async function apiDocs(options: z.infer<typeof argsSchema>, context: ContainerContext) {
18
+ const container = context.container as unknown as NodeContainer
19
+ await container.helpers.discoverAll()
20
+ const outputFolder = options.outputPath ? container.paths.resolve(options.outputPath) : container.paths.resolve('docs','luca')
21
+
22
+ await container.fs.ensureFolder(
23
+ outputFolder
24
+ )
25
+
26
+ const mkPath = (...args: string[]) => container.paths.resolve(outputFolder, ...args)
27
+
28
+ await container.fs.writeFileAsync(mkPath('agi-container.md'), (container as any).introspectAsText())
29
+
30
+ for(const reg of ['features','clients','servers']) {
31
+ const registry = (container as any)[reg]
32
+ const helperIds: string[] = registry.available
33
+ const folder = mkPath(reg)
34
+ await container.fs.ensureFolder(folder)
35
+
36
+ await Promise.all(
37
+ helperIds.map((helperId: string) => container.fs.writeFileAsync(
38
+ container.paths.resolve(folder, `${helperId}.md`),
39
+ registry.describe(helperId)
40
+ ))
41
+ )
42
+ }
43
+
44
+ container.ui.print.green(`Finished saving API Docs`)
45
+ }
46
+
47
+ commands.registerHandler('api-docs', {
48
+ description: 'Save the helper introspection() content as markdown API docs in docs/luca',
49
+ argsSchema,
50
+ handler: apiDocs,
51
+ })