luca 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (763) hide show
  1. package/.github/workflows/release.yaml +169 -0
  2. package/AGENTS.md +99 -0
  3. package/CLAUDE.md +115 -0
  4. package/CNAME +1 -0
  5. package/README.md +257 -9
  6. package/RUNME.md +56 -0
  7. package/assistants/codingAssistant/ABOUT.md +5 -0
  8. package/assistants/codingAssistant/CORE.md +28 -0
  9. package/assistants/codingAssistant/hooks.ts +21 -0
  10. package/assistants/codingAssistant/tools.ts +12 -0
  11. package/assistants/inkbot/ABOUT.md +16 -0
  12. package/assistants/inkbot/CORE.md +330 -0
  13. package/assistants/inkbot/hooks.ts +6 -0
  14. package/assistants/inkbot/tools.ts +53 -0
  15. package/assistants/researcher/ABOUT.md +5 -0
  16. package/assistants/researcher/CORE.md +46 -0
  17. package/assistants/researcher/hooks.ts +16 -0
  18. package/assistants/researcher/tools.ts +237 -0
  19. package/bun.lock +2769 -0
  20. package/bunfig.toml +3 -0
  21. package/commands/audit-docs.ts +740 -0
  22. package/commands/build-bootstrap.ts +118 -0
  23. package/commands/build-python-bridge.ts +43 -0
  24. package/commands/build-scaffolds.ts +176 -0
  25. package/commands/generate-api-docs.ts +114 -0
  26. package/commands/inkbot.ts +874 -0
  27. package/commands/release.ts +80 -0
  28. package/commands/try-all-challenges.ts +543 -0
  29. package/commands/try-challenge.ts +100 -0
  30. package/dist/agi/container.server.d.ts +63 -0
  31. package/dist/agi/container.server.d.ts.map +1 -0
  32. package/dist/agi/endpoints/ask.d.ts +20 -0
  33. package/dist/agi/endpoints/ask.d.ts.map +1 -0
  34. package/dist/agi/endpoints/conversations/[id].d.ts +27 -0
  35. package/dist/agi/endpoints/conversations/[id].d.ts.map +1 -0
  36. package/dist/agi/endpoints/conversations.d.ts +18 -0
  37. package/dist/agi/endpoints/conversations.d.ts.map +1 -0
  38. package/dist/agi/endpoints/experts.d.ts +8 -0
  39. package/dist/agi/endpoints/experts.d.ts.map +1 -0
  40. package/dist/agi/feature.d.ts +9 -0
  41. package/dist/agi/feature.d.ts.map +1 -0
  42. package/dist/agi/features/assistant.d.ts +509 -0
  43. package/dist/agi/features/assistant.d.ts.map +1 -0
  44. package/dist/agi/features/assistants-manager.d.ts +236 -0
  45. package/dist/agi/features/assistants-manager.d.ts.map +1 -0
  46. package/dist/agi/features/autonomous-assistant.d.ts +281 -0
  47. package/dist/agi/features/autonomous-assistant.d.ts.map +1 -0
  48. package/dist/agi/features/browser-use.d.ts +479 -0
  49. package/dist/agi/features/browser-use.d.ts.map +1 -0
  50. package/dist/agi/features/claude-code.d.ts +824 -0
  51. package/dist/agi/features/claude-code.d.ts.map +1 -0
  52. package/dist/agi/features/conversation-history.d.ts +245 -0
  53. package/dist/agi/features/conversation-history.d.ts.map +1 -0
  54. package/dist/agi/features/conversation.d.ts +464 -0
  55. package/dist/agi/features/conversation.d.ts.map +1 -0
  56. package/dist/agi/features/docs-reader.d.ts +72 -0
  57. package/dist/agi/features/docs-reader.d.ts.map +1 -0
  58. package/dist/agi/features/file-tools.d.ts +110 -0
  59. package/dist/agi/features/file-tools.d.ts.map +1 -0
  60. package/dist/agi/features/luca-coder.d.ts +323 -0
  61. package/dist/agi/features/luca-coder.d.ts.map +1 -0
  62. package/dist/agi/features/openai-codex.d.ts +381 -0
  63. package/dist/agi/features/openai-codex.d.ts.map +1 -0
  64. package/dist/agi/features/openapi.d.ts +200 -0
  65. package/dist/agi/features/openapi.d.ts.map +1 -0
  66. package/dist/agi/features/skills-library.d.ts +167 -0
  67. package/dist/agi/features/skills-library.d.ts.map +1 -0
  68. package/dist/agi/index.d.ts +5 -0
  69. package/dist/agi/index.d.ts.map +1 -0
  70. package/dist/agi/lib/interceptor-chain.d.ts +44 -0
  71. package/dist/agi/lib/interceptor-chain.d.ts.map +1 -0
  72. package/dist/agi/lib/token-counter.d.ts +13 -0
  73. package/dist/agi/lib/token-counter.d.ts.map +1 -0
  74. package/dist/bootstrap/generated.d.ts +5 -0
  75. package/dist/bootstrap/generated.d.ts.map +1 -0
  76. package/dist/browser.d.ts +12 -0
  77. package/dist/browser.d.ts.map +1 -0
  78. package/dist/bus.d.ts +29 -0
  79. package/dist/bus.d.ts.map +1 -0
  80. package/dist/cli/build-info.d.ts +4 -0
  81. package/dist/cli/build-info.d.ts.map +1 -0
  82. package/dist/cli/cli.d.ts +3 -12
  83. package/dist/cli/cli.d.ts.map +1 -0
  84. package/dist/client.d.ts +60 -0
  85. package/dist/client.d.ts.map +1 -0
  86. package/dist/clients/civitai/index.d.ts +472 -0
  87. package/dist/clients/civitai/index.d.ts.map +1 -0
  88. package/dist/clients/client-template.d.ts +30 -0
  89. package/dist/clients/client-template.d.ts.map +1 -0
  90. package/dist/clients/comfyui/index.d.ts +281 -0
  91. package/dist/clients/comfyui/index.d.ts.map +1 -0
  92. package/dist/clients/elevenlabs/index.d.ts +197 -0
  93. package/dist/clients/elevenlabs/index.d.ts.map +1 -0
  94. package/dist/clients/graph.d.ts +64 -0
  95. package/dist/clients/graph.d.ts.map +1 -0
  96. package/dist/clients/openai/index.d.ts +247 -0
  97. package/dist/clients/openai/index.d.ts.map +1 -0
  98. package/dist/clients/rest.d.ts +92 -0
  99. package/dist/clients/rest.d.ts.map +1 -0
  100. package/dist/clients/supabase/index.d.ts +176 -0
  101. package/dist/clients/supabase/index.d.ts.map +1 -0
  102. package/dist/clients/websocket.d.ts +127 -0
  103. package/dist/clients/websocket.d.ts.map +1 -0
  104. package/dist/command.d.ts +163 -0
  105. package/dist/command.d.ts.map +1 -0
  106. package/dist/commands/bootstrap.d.ts +20 -0
  107. package/dist/commands/bootstrap.d.ts.map +1 -0
  108. package/dist/commands/chat.d.ts +37 -0
  109. package/dist/commands/chat.d.ts.map +1 -0
  110. package/dist/commands/code.d.ts +28 -0
  111. package/dist/commands/code.d.ts.map +1 -0
  112. package/dist/commands/console.d.ts +22 -0
  113. package/dist/commands/console.d.ts.map +1 -0
  114. package/dist/commands/describe.d.ts +50 -0
  115. package/dist/commands/describe.d.ts.map +1 -0
  116. package/dist/commands/eval.d.ts +23 -0
  117. package/dist/commands/eval.d.ts.map +1 -0
  118. package/dist/commands/help.d.ts +25 -0
  119. package/dist/commands/help.d.ts.map +1 -0
  120. package/dist/commands/index.d.ts +18 -0
  121. package/dist/commands/index.d.ts.map +1 -0
  122. package/dist/commands/introspect.d.ts +24 -0
  123. package/dist/commands/introspect.d.ts.map +1 -0
  124. package/dist/commands/mcp.d.ts +35 -0
  125. package/dist/commands/mcp.d.ts.map +1 -0
  126. package/dist/commands/prompt.d.ts +38 -0
  127. package/dist/commands/prompt.d.ts.map +1 -0
  128. package/dist/commands/run.d.ts +24 -0
  129. package/dist/commands/run.d.ts.map +1 -0
  130. package/dist/commands/sandbox-mcp.d.ts +34 -0
  131. package/dist/commands/sandbox-mcp.d.ts.map +1 -0
  132. package/dist/commands/save-api-docs.d.ts +21 -0
  133. package/dist/commands/save-api-docs.d.ts.map +1 -0
  134. package/dist/commands/scaffold.d.ts +24 -0
  135. package/dist/commands/scaffold.d.ts.map +1 -0
  136. package/dist/commands/select.d.ts +22 -0
  137. package/dist/commands/select.d.ts.map +1 -0
  138. package/dist/commands/serve.d.ts +29 -0
  139. package/dist/commands/serve.d.ts.map +1 -0
  140. package/dist/container-describer.d.ts +144 -0
  141. package/dist/container-describer.d.ts.map +1 -0
  142. package/dist/container.d.ts +451 -0
  143. package/dist/container.d.ts.map +1 -0
  144. package/dist/endpoint.d.ts +113 -0
  145. package/dist/endpoint.d.ts.map +1 -0
  146. package/dist/feature.d.ts +47 -0
  147. package/dist/feature.d.ts.map +1 -0
  148. package/dist/graft.d.ts +29 -0
  149. package/dist/graft.d.ts.map +1 -0
  150. package/dist/hash-object.d.ts +8 -0
  151. package/dist/hash-object.d.ts.map +1 -0
  152. package/dist/helper.d.ts +209 -0
  153. package/dist/helper.d.ts.map +1 -0
  154. package/dist/introspection/generated.node.d.ts +44623 -0
  155. package/dist/introspection/generated.node.d.ts.map +1 -0
  156. package/dist/introspection/generated.web.d.ts +1412 -0
  157. package/dist/introspection/generated.web.d.ts.map +1 -0
  158. package/dist/introspection/index.d.ts +156 -0
  159. package/dist/introspection/index.d.ts.map +1 -0
  160. package/dist/introspection/scan.d.ts +147 -0
  161. package/dist/introspection/scan.d.ts.map +1 -0
  162. package/dist/node/container.d.ts +256 -0
  163. package/dist/node/container.d.ts.map +1 -0
  164. package/dist/node/feature.d.ts +9 -0
  165. package/dist/node/feature.d.ts.map +1 -0
  166. package/dist/node/features/container-link.d.ts +213 -0
  167. package/dist/node/features/container-link.d.ts.map +1 -0
  168. package/dist/node/features/content-db.d.ts +354 -0
  169. package/dist/node/features/content-db.d.ts.map +1 -0
  170. package/dist/node/features/disk-cache.d.ts +236 -0
  171. package/dist/node/features/disk-cache.d.ts.map +1 -0
  172. package/dist/node/features/dns.d.ts +511 -0
  173. package/dist/node/features/dns.d.ts.map +1 -0
  174. package/dist/node/features/docker.d.ts +485 -0
  175. package/dist/node/features/docker.d.ts.map +1 -0
  176. package/dist/node/features/downloader.d.ts +73 -0
  177. package/dist/node/features/downloader.d.ts.map +1 -0
  178. package/dist/node/features/figlet-fonts.d.ts +4 -0
  179. package/dist/node/features/figlet-fonts.d.ts.map +1 -0
  180. package/dist/node/features/file-manager.d.ts +177 -0
  181. package/dist/node/features/file-manager.d.ts.map +1 -0
  182. package/dist/node/features/fs.d.ts +635 -0
  183. package/dist/node/features/fs.d.ts.map +1 -0
  184. package/dist/node/features/git.d.ts +329 -0
  185. package/dist/node/features/git.d.ts.map +1 -0
  186. package/dist/node/features/google-auth.d.ts +200 -0
  187. package/dist/node/features/google-auth.d.ts.map +1 -0
  188. package/dist/node/features/google-calendar.d.ts +194 -0
  189. package/dist/node/features/google-calendar.d.ts.map +1 -0
  190. package/dist/node/features/google-docs.d.ts +138 -0
  191. package/dist/node/features/google-docs.d.ts.map +1 -0
  192. package/dist/node/features/google-drive.d.ts +202 -0
  193. package/dist/node/features/google-drive.d.ts.map +1 -0
  194. package/dist/node/features/google-mail.d.ts +221 -0
  195. package/dist/node/features/google-mail.d.ts.map +1 -0
  196. package/dist/node/features/google-sheets.d.ts +157 -0
  197. package/dist/node/features/google-sheets.d.ts.map +1 -0
  198. package/dist/node/features/grep.d.ts +207 -0
  199. package/dist/node/features/grep.d.ts.map +1 -0
  200. package/dist/node/features/helpers.d.ts +236 -0
  201. package/dist/node/features/helpers.d.ts.map +1 -0
  202. package/dist/node/features/ink.d.ts +332 -0
  203. package/dist/node/features/ink.d.ts.map +1 -0
  204. package/dist/node/features/ipc-socket.d.ts +298 -0
  205. package/dist/node/features/ipc-socket.d.ts.map +1 -0
  206. package/dist/node/features/json-tree.d.ts +140 -0
  207. package/dist/node/features/json-tree.d.ts.map +1 -0
  208. package/dist/node/features/networking.d.ts +373 -0
  209. package/dist/node/features/networking.d.ts.map +1 -0
  210. package/dist/node/features/nlp.d.ts +125 -0
  211. package/dist/node/features/nlp.d.ts.map +1 -0
  212. package/dist/node/features/opener.d.ts +93 -0
  213. package/dist/node/features/opener.d.ts.map +1 -0
  214. package/dist/node/features/os.d.ts +168 -0
  215. package/dist/node/features/os.d.ts.map +1 -0
  216. package/dist/node/features/package-finder.d.ts +419 -0
  217. package/dist/node/features/package-finder.d.ts.map +1 -0
  218. package/dist/node/features/postgres.d.ts +173 -0
  219. package/dist/node/features/postgres.d.ts.map +1 -0
  220. package/dist/node/features/proc.d.ts +285 -0
  221. package/dist/node/features/proc.d.ts.map +1 -0
  222. package/dist/node/features/process-manager.d.ts +427 -0
  223. package/dist/node/features/process-manager.d.ts.map +1 -0
  224. package/dist/node/features/python.d.ts +477 -0
  225. package/dist/node/features/python.d.ts.map +1 -0
  226. package/dist/node/features/redis.d.ts +247 -0
  227. package/dist/node/features/redis.d.ts.map +1 -0
  228. package/dist/node/features/repl.d.ts +84 -0
  229. package/dist/node/features/repl.d.ts.map +1 -0
  230. package/dist/node/features/runpod.d.ts +527 -0
  231. package/dist/node/features/runpod.d.ts.map +1 -0
  232. package/dist/node/features/secure-shell.d.ts +145 -0
  233. package/dist/node/features/secure-shell.d.ts.map +1 -0
  234. package/dist/node/features/semantic-search.d.ts +207 -0
  235. package/dist/node/features/semantic-search.d.ts.map +1 -0
  236. package/dist/node/features/sqlite.d.ts +180 -0
  237. package/dist/node/features/sqlite.d.ts.map +1 -0
  238. package/dist/node/features/telegram.d.ts +173 -0
  239. package/dist/node/features/telegram.d.ts.map +1 -0
  240. package/dist/node/features/transpiler.d.ts +51 -0
  241. package/dist/node/features/transpiler.d.ts.map +1 -0
  242. package/dist/node/features/tts.d.ts +108 -0
  243. package/dist/node/features/tts.d.ts.map +1 -0
  244. package/dist/node/features/ui.d.ts +562 -0
  245. package/dist/node/features/ui.d.ts.map +1 -0
  246. package/dist/node/features/vault.d.ts +90 -0
  247. package/dist/node/features/vault.d.ts.map +1 -0
  248. package/dist/node/features/vm.d.ts +285 -0
  249. package/dist/node/features/vm.d.ts.map +1 -0
  250. package/dist/node/features/yaml-tree.d.ts +118 -0
  251. package/dist/node/features/yaml-tree.d.ts.map +1 -0
  252. package/dist/node/features/yaml.d.ts +127 -0
  253. package/dist/node/features/yaml.d.ts.map +1 -0
  254. package/dist/node.d.ts +67 -0
  255. package/dist/node.d.ts.map +1 -0
  256. package/dist/python/generated.d.ts +2 -0
  257. package/dist/python/generated.d.ts.map +1 -0
  258. package/dist/react/index.d.ts +36 -0
  259. package/dist/react/index.d.ts.map +1 -0
  260. package/dist/registry.d.ts +97 -0
  261. package/dist/registry.d.ts.map +1 -0
  262. package/dist/scaffolds/generated.d.ts +13 -0
  263. package/dist/scaffolds/generated.d.ts.map +1 -0
  264. package/dist/scaffolds/template.d.ts +11 -0
  265. package/dist/scaffolds/template.d.ts.map +1 -0
  266. package/dist/schemas/base.d.ts +254 -0
  267. package/dist/schemas/base.d.ts.map +1 -0
  268. package/dist/selector.d.ts +130 -0
  269. package/dist/selector.d.ts.map +1 -0
  270. package/dist/server.d.ts +89 -0
  271. package/dist/server.d.ts.map +1 -0
  272. package/dist/servers/express.d.ts +104 -0
  273. package/dist/servers/express.d.ts.map +1 -0
  274. package/dist/servers/mcp.d.ts +201 -0
  275. package/dist/servers/mcp.d.ts.map +1 -0
  276. package/dist/servers/socket.d.ts +121 -0
  277. package/dist/servers/socket.d.ts.map +1 -0
  278. package/dist/state.d.ts +24 -0
  279. package/dist/state.d.ts.map +1 -0
  280. package/dist/web/clients/socket.d.ts +37 -0
  281. package/dist/web/clients/socket.d.ts.map +1 -0
  282. package/dist/web/container.d.ts +55 -0
  283. package/dist/web/container.d.ts.map +1 -0
  284. package/dist/web/extension.d.ts +4 -0
  285. package/dist/web/extension.d.ts.map +1 -0
  286. package/dist/web/feature.d.ts +8 -0
  287. package/dist/web/feature.d.ts.map +1 -0
  288. package/dist/web/features/asset-loader.d.ts +35 -0
  289. package/dist/web/features/asset-loader.d.ts.map +1 -0
  290. package/dist/web/features/container-link.d.ts +167 -0
  291. package/dist/web/features/container-link.d.ts.map +1 -0
  292. package/dist/web/features/esbuild.d.ts +51 -0
  293. package/dist/web/features/esbuild.d.ts.map +1 -0
  294. package/dist/web/features/helpers.d.ts +140 -0
  295. package/dist/web/features/helpers.d.ts.map +1 -0
  296. package/dist/web/features/network.d.ts +69 -0
  297. package/dist/web/features/network.d.ts.map +1 -0
  298. package/dist/web/features/speech.d.ts +71 -0
  299. package/dist/web/features/speech.d.ts.map +1 -0
  300. package/dist/web/features/vault.d.ts +62 -0
  301. package/dist/web/features/vault.d.ts.map +1 -0
  302. package/dist/web/features/vm.d.ts +48 -0
  303. package/dist/web/features/vm.d.ts.map +1 -0
  304. package/dist/web/features/voice-recognition.d.ts +96 -0
  305. package/dist/web/features/voice-recognition.d.ts.map +1 -0
  306. package/dist/web/shims/isomorphic-vm.d.ts +22 -0
  307. package/dist/web/shims/isomorphic-vm.d.ts.map +1 -0
  308. package/docs/CLI.md +335 -0
  309. package/docs/CNAME +1 -0
  310. package/docs/README.md +60 -0
  311. package/docs/TABLE-OF-CONTENTS.md +183 -0
  312. package/docs/apis/clients/elevenlabs.md +308 -0
  313. package/docs/apis/clients/graph.md +107 -0
  314. package/docs/apis/clients/openai.md +429 -0
  315. package/docs/apis/clients/rest.md +161 -0
  316. package/docs/apis/clients/websocket.md +174 -0
  317. package/docs/apis/features/agi/assistant.md +625 -0
  318. package/docs/apis/features/agi/assistants-manager.md +282 -0
  319. package/docs/apis/features/agi/auto-assistant.md +279 -0
  320. package/docs/apis/features/agi/browser-use.md +802 -0
  321. package/docs/apis/features/agi/claude-code.md +884 -0
  322. package/docs/apis/features/agi/conversation-history.md +364 -0
  323. package/docs/apis/features/agi/conversation.md +548 -0
  324. package/docs/apis/features/agi/docs-reader.md +99 -0
  325. package/docs/apis/features/agi/file-tools.md +163 -0
  326. package/docs/apis/features/agi/luca-coder.md +407 -0
  327. package/docs/apis/features/agi/openai-codex.md +396 -0
  328. package/docs/apis/features/agi/openapi.md +138 -0
  329. package/docs/apis/features/agi/semantic-search.md +387 -0
  330. package/docs/apis/features/agi/skills-library.md +239 -0
  331. package/docs/apis/features/node/container-link.md +192 -0
  332. package/docs/apis/features/node/content-db.md +450 -0
  333. package/docs/apis/features/node/disk-cache.md +379 -0
  334. package/docs/apis/features/node/dns.md +652 -0
  335. package/docs/apis/features/node/docker.md +706 -0
  336. package/docs/apis/features/node/downloader.md +81 -0
  337. package/docs/apis/features/node/esbuild.md +60 -0
  338. package/docs/apis/features/node/file-manager.md +191 -0
  339. package/docs/apis/features/node/fs.md +1217 -0
  340. package/docs/apis/features/node/git.md +371 -0
  341. package/docs/apis/features/node/google-auth.md +193 -0
  342. package/docs/apis/features/node/google-calendar.md +202 -0
  343. package/docs/apis/features/node/google-docs.md +173 -0
  344. package/docs/apis/features/node/google-drive.md +246 -0
  345. package/docs/apis/features/node/google-mail.md +214 -0
  346. package/docs/apis/features/node/google-sheets.md +194 -0
  347. package/docs/apis/features/node/grep.md +292 -0
  348. package/docs/apis/features/node/helpers.md +164 -0
  349. package/docs/apis/features/node/ink.md +334 -0
  350. package/docs/apis/features/node/ipc-socket.md +249 -0
  351. package/docs/apis/features/node/json-tree.md +86 -0
  352. package/docs/apis/features/node/networking.md +316 -0
  353. package/docs/apis/features/node/nlp.md +133 -0
  354. package/docs/apis/features/node/opener.md +97 -0
  355. package/docs/apis/features/node/os.md +146 -0
  356. package/docs/apis/features/node/package-finder.md +392 -0
  357. package/docs/apis/features/node/postgres.md +234 -0
  358. package/docs/apis/features/node/proc.md +399 -0
  359. package/docs/apis/features/node/process-manager.md +305 -0
  360. package/docs/apis/features/node/python.md +604 -0
  361. package/docs/apis/features/node/redis.md +380 -0
  362. package/docs/apis/features/node/repl.md +88 -0
  363. package/docs/apis/features/node/runpod.md +674 -0
  364. package/docs/apis/features/node/secure-shell.md +176 -0
  365. package/docs/apis/features/node/semantic-search.md +408 -0
  366. package/docs/apis/features/node/sqlite.md +233 -0
  367. package/docs/apis/features/node/telegram.md +279 -0
  368. package/docs/apis/features/node/transpiler.md +74 -0
  369. package/docs/apis/features/node/tts.md +133 -0
  370. package/docs/apis/features/node/ui.md +701 -0
  371. package/docs/apis/features/node/vault.md +59 -0
  372. package/docs/apis/features/node/vm.md +75 -0
  373. package/docs/apis/features/node/yaml-tree.md +85 -0
  374. package/docs/apis/features/node/yaml.md +176 -0
  375. package/docs/apis/features/web/asset-loader.md +59 -0
  376. package/docs/apis/features/web/container-link.md +192 -0
  377. package/docs/apis/features/web/esbuild.md +54 -0
  378. package/docs/apis/features/web/helpers.md +164 -0
  379. package/docs/apis/features/web/network.md +44 -0
  380. package/docs/apis/features/web/speech.md +69 -0
  381. package/docs/apis/features/web/vault.md +59 -0
  382. package/docs/apis/features/web/vm.md +75 -0
  383. package/docs/apis/features/web/voice.md +84 -0
  384. package/docs/apis/servers/express.md +171 -0
  385. package/docs/apis/servers/mcp.md +238 -0
  386. package/docs/apis/servers/websocket.md +170 -0
  387. package/docs/bootstrap/CLAUDE.md +101 -0
  388. package/docs/bootstrap/SKILL.md +341 -0
  389. package/docs/bootstrap/templates/about-command.ts +41 -0
  390. package/docs/bootstrap/templates/docs-models.ts +22 -0
  391. package/docs/bootstrap/templates/docs-readme.md +43 -0
  392. package/docs/bootstrap/templates/example-feature.ts +53 -0
  393. package/docs/bootstrap/templates/health-endpoint.ts +15 -0
  394. package/docs/bootstrap/templates/luca-cli.ts +30 -0
  395. package/docs/bootstrap/templates/runme.md +54 -0
  396. package/docs/challenges/caching-proxy.md +16 -0
  397. package/docs/challenges/content-db-round-trip.md +14 -0
  398. package/docs/challenges/custom-command.md +9 -0
  399. package/docs/challenges/file-watcher-pipeline.md +11 -0
  400. package/docs/challenges/grep-audit-report.md +15 -0
  401. package/docs/challenges/multi-feature-dashboard.md +14 -0
  402. package/docs/challenges/process-orchestrator.md +17 -0
  403. package/docs/challenges/rest-api-server-with-client.md +12 -0
  404. package/docs/challenges/script-runner-with-vm.md +11 -0
  405. package/docs/challenges/simple-rest-api.md +15 -0
  406. package/docs/challenges/websocket-serve-and-client.md +11 -0
  407. package/docs/challenges/yaml-config-system.md +14 -0
  408. package/docs/command-system-overhaul.md +94 -0
  409. package/docs/documentation-audit.md +134 -0
  410. package/docs/examples/assistant/CORE.md +18 -0
  411. package/docs/examples/assistant/hooks.ts +3 -0
  412. package/docs/examples/assistant/tools.ts +10 -0
  413. package/docs/examples/assistant-hooks-reference.ts +171 -0
  414. package/docs/examples/assistant-with-process-manager.md +84 -0
  415. package/docs/examples/content-db.md +77 -0
  416. package/docs/examples/disk-cache.md +83 -0
  417. package/docs/examples/docker.md +101 -0
  418. package/docs/examples/downloader.md +70 -0
  419. package/docs/examples/entity.md +124 -0
  420. package/docs/examples/esbuild.md +80 -0
  421. package/docs/examples/feature-as-tool-provider.md +143 -0
  422. package/docs/examples/file-manager.md +82 -0
  423. package/docs/examples/fs.md +83 -0
  424. package/docs/examples/git.md +85 -0
  425. package/docs/examples/google-auth.md +88 -0
  426. package/docs/examples/google-calendar.md +94 -0
  427. package/docs/examples/google-docs.md +82 -0
  428. package/docs/examples/google-drive.md +96 -0
  429. package/docs/examples/google-sheets.md +95 -0
  430. package/docs/examples/grep.md +85 -0
  431. package/docs/examples/ink-blocks.md +75 -0
  432. package/docs/examples/ink-renderer.md +41 -0
  433. package/docs/examples/ink.md +103 -0
  434. package/docs/examples/ipc-socket.md +103 -0
  435. package/docs/examples/json-tree.md +91 -0
  436. package/docs/examples/networking.md +58 -0
  437. package/docs/examples/nlp.md +91 -0
  438. package/docs/examples/opener.md +78 -0
  439. package/docs/examples/os.md +72 -0
  440. package/docs/examples/package-finder.md +89 -0
  441. package/docs/examples/postgres.md +91 -0
  442. package/docs/examples/proc.md +81 -0
  443. package/docs/examples/process-manager.md +79 -0
  444. package/docs/examples/python.md +132 -0
  445. package/docs/examples/repl.md +93 -0
  446. package/docs/examples/runpod.md +119 -0
  447. package/docs/examples/secure-shell.md +92 -0
  448. package/docs/examples/sqlite.md +86 -0
  449. package/docs/examples/structured-output-with-assistants.md +144 -0
  450. package/docs/examples/telegram.md +77 -0
  451. package/docs/examples/tts.md +86 -0
  452. package/docs/examples/ui.md +80 -0
  453. package/docs/examples/vault.md +70 -0
  454. package/docs/examples/vm.md +86 -0
  455. package/docs/examples/websocket-ask-and-reply-example.md +128 -0
  456. package/docs/examples/yaml-tree.md +93 -0
  457. package/docs/examples/yaml.md +104 -0
  458. package/docs/ideas/assistant-factory-pattern.md +142 -0
  459. package/docs/in-memory-fs.md +4 -0
  460. package/docs/introspection-audit.md +49 -0
  461. package/docs/introspection.md +164 -0
  462. package/docs/mcp/readme.md +162 -0
  463. package/docs/models.ts +41 -0
  464. package/docs/philosophy.md +86 -0
  465. package/docs/principles.md +7 -0
  466. package/docs/prompts/audit-codebase-for-failures-to-use-the-container.md +34 -0
  467. package/docs/prompts/check-for-undocumented-features.md +27 -0
  468. package/docs/prompts/mcp-test-easy-command.md +27 -0
  469. package/docs/scaffolds/client.md +149 -0
  470. package/docs/scaffolds/command.md +120 -0
  471. package/docs/scaffolds/endpoint.md +171 -0
  472. package/docs/scaffolds/feature.md +158 -0
  473. package/docs/scaffolds/selector.md +91 -0
  474. package/docs/scaffolds/server.md +196 -0
  475. package/docs/selectors.md +115 -0
  476. package/docs/sessions/custom-command/attempt-log-2.md +195 -0
  477. package/docs/sessions/file-watcher-pipeline/attempt-log-1.md +728 -0
  478. package/docs/sessions/file-watcher-pipeline/attempt-log-2.md +555 -0
  479. package/docs/sessions/grep-audit-report/attempt-log-1.md +289 -0
  480. package/docs/sessions/multi-feature-dashboard/attempt-log-2.md +679 -0
  481. package/docs/sessions/rest-api-server-with-client/attempt-log-1.md +1 -0
  482. package/docs/sessions/rest-api-server-with-client/attempt-log-3.md +920 -0
  483. package/docs/sessions/simple-rest-api/attempt-log-1.md +593 -0
  484. package/docs/sessions/websocket-serve-and-client/attempt-log-2.md +995 -0
  485. package/docs/tutorials/00-bootstrap.md +166 -0
  486. package/docs/tutorials/01-getting-started.md +106 -0
  487. package/docs/tutorials/02-container.md +210 -0
  488. package/docs/tutorials/03-scripts.md +194 -0
  489. package/docs/tutorials/04-features-overview.md +196 -0
  490. package/docs/tutorials/05-state-and-events.md +171 -0
  491. package/docs/tutorials/06-servers.md +157 -0
  492. package/docs/tutorials/07-endpoints.md +198 -0
  493. package/docs/tutorials/08-commands.md +252 -0
  494. package/docs/tutorials/09-clients.md +162 -0
  495. package/docs/tutorials/10-creating-features.md +203 -0
  496. package/docs/tutorials/11-contentbase.md +191 -0
  497. package/docs/tutorials/12-assistants.md +215 -0
  498. package/docs/tutorials/13-introspection.md +157 -0
  499. package/docs/tutorials/14-type-system.md +174 -0
  500. package/docs/tutorials/15-project-patterns.md +222 -0
  501. package/docs/tutorials/16-google-features.md +534 -0
  502. package/docs/tutorials/17-tui-blocks.md +530 -0
  503. package/docs/tutorials/18-semantic-search.md +334 -0
  504. package/docs/tutorials/19-python-sessions.md +401 -0
  505. package/docs/tutorials/20-browser-esm.md +234 -0
  506. package/index.html +1430 -0
  507. package/index.ts +1 -0
  508. package/install.sh +84 -0
  509. package/luca.cli.ts +16 -0
  510. package/luca.console.ts +9 -0
  511. package/main.py +6 -0
  512. package/package.json +219 -58
  513. package/public/index.html +1430 -0
  514. package/public/slides-ai-native.html +902 -0
  515. package/public/slides-intro.html +974 -0
  516. package/pyproject.toml +7 -0
  517. package/scripts/build-web.ts +28 -0
  518. package/scripts/examples/ask-luca-expert.ts +42 -0
  519. package/scripts/examples/assistant-questions.ts +12 -0
  520. package/scripts/examples/excalidraw-expert.ts +75 -0
  521. package/scripts/examples/expert-chat.ts +0 -0
  522. package/scripts/examples/file-manager.ts +14 -0
  523. package/scripts/examples/ideas.ts +12 -0
  524. package/scripts/examples/interactive-chat.ts +20 -0
  525. package/scripts/examples/openai-tool-calls.ts +113 -0
  526. package/scripts/examples/opening-a-web-browser.ts +5 -0
  527. package/scripts/examples/telegram-bot.ts +79 -0
  528. package/scripts/examples/using-assistant-with-mcp.ts +555 -0
  529. package/scripts/examples/using-claude-code.ts +10 -0
  530. package/scripts/examples/using-contentdb.ts +35 -0
  531. package/scripts/examples/using-conversations.ts +35 -0
  532. package/scripts/examples/using-disk-cache.ts +10 -0
  533. package/scripts/examples/using-docker-shell.ts +75 -0
  534. package/scripts/examples/using-elevenlabs.ts +25 -0
  535. package/scripts/examples/using-google-calendar.ts +57 -0
  536. package/scripts/examples/using-google-docs.ts +74 -0
  537. package/scripts/examples/using-google-drive.ts +74 -0
  538. package/scripts/examples/using-google-sheets.ts +89 -0
  539. package/scripts/examples/using-nlp.ts +55 -0
  540. package/scripts/examples/using-ollama.ts +11 -0
  541. package/scripts/examples/using-postgres.ts +55 -0
  542. package/scripts/examples/using-runpod.ts +32 -0
  543. package/scripts/examples/using-tts.ts +40 -0
  544. package/scripts/scaffold.ts +391 -0
  545. package/scripts/scratch.ts +15 -0
  546. package/scripts/stamp-build.sh +12 -0
  547. package/scripts/test-assistant-hooks.ts +13 -0
  548. package/scripts/test-docs-reader.ts +10 -0
  549. package/scripts/test-linux-binary.sh +80 -0
  550. package/scripts/update-introspection-data.ts +58 -0
  551. package/src/agi/README.md +14 -0
  552. package/src/agi/container.server.ts +152 -0
  553. package/src/agi/endpoints/ask.ts +60 -0
  554. package/src/agi/endpoints/conversations/[id].ts +45 -0
  555. package/src/agi/endpoints/conversations.ts +31 -0
  556. package/src/agi/endpoints/experts.ts +37 -0
  557. package/src/agi/feature.ts +13 -0
  558. package/src/agi/features/agent-memory.ts +694 -0
  559. package/src/agi/features/assistant.ts +1624 -0
  560. package/src/agi/features/assistants-manager.ts +418 -0
  561. package/src/agi/features/autonomous-assistant.ts +431 -0
  562. package/src/agi/features/browser-use.ts +653 -0
  563. package/src/agi/features/claude-code.ts +1538 -0
  564. package/src/agi/features/coding-tools.ts +175 -0
  565. package/src/agi/features/conversation-history.ts +495 -0
  566. package/src/agi/features/conversation.ts +1323 -0
  567. package/src/agi/features/docs-reader.ts +167 -0
  568. package/src/agi/features/file-tools.ts +293 -0
  569. package/src/agi/features/luca-coder.ts +639 -0
  570. package/src/agi/features/openai-codex.ts +651 -0
  571. package/src/agi/features/openapi.ts +445 -0
  572. package/src/agi/features/skills-library.ts +478 -0
  573. package/src/agi/index.ts +6 -0
  574. package/src/agi/lib/interceptor-chain.ts +89 -0
  575. package/src/agi/lib/token-counter.ts +122 -0
  576. package/src/bootstrap/generated.ts +9792 -0
  577. package/src/browser.ts +25 -0
  578. package/src/bus.ts +122 -0
  579. package/src/cli/build-info.ts +4 -0
  580. package/src/cli/cli.ts +355 -0
  581. package/src/client.ts +170 -0
  582. package/src/clients/civitai/index.ts +537 -0
  583. package/src/clients/client-template.ts +41 -0
  584. package/src/clients/comfyui/index.ts +604 -0
  585. package/src/clients/elevenlabs/index.ts +317 -0
  586. package/src/clients/graph.ts +87 -0
  587. package/src/clients/openai/index.ts +456 -0
  588. package/src/clients/rest.ts +207 -0
  589. package/src/clients/supabase/index.ts +357 -0
  590. package/src/clients/voicebox/index.ts +300 -0
  591. package/src/clients/websocket.ts +251 -0
  592. package/src/command.ts +505 -0
  593. package/src/commands/bootstrap.ts +244 -0
  594. package/src/commands/chat.ts +308 -0
  595. package/src/commands/code.ts +371 -0
  596. package/src/commands/console.ts +189 -0
  597. package/src/commands/describe.ts +243 -0
  598. package/src/commands/eval.ts +121 -0
  599. package/src/commands/help.ts +240 -0
  600. package/src/commands/index.ts +19 -0
  601. package/src/commands/introspect.ts +218 -0
  602. package/src/commands/mcp.ts +64 -0
  603. package/src/commands/prompt.ts +982 -0
  604. package/src/commands/run.ts +278 -0
  605. package/src/commands/sandbox-mcp.ts +343 -0
  606. package/src/commands/save-api-docs.ts +51 -0
  607. package/src/commands/scaffold.ts +225 -0
  608. package/src/commands/select.ts +99 -0
  609. package/src/commands/serve.ts +208 -0
  610. package/src/container-describer.ts +1084 -0
  611. package/src/container.ts +1186 -0
  612. package/src/endpoint.ts +365 -0
  613. package/src/entity.ts +173 -0
  614. package/src/feature.ts +118 -0
  615. package/src/graft.ts +181 -0
  616. package/src/hash-object.ts +97 -0
  617. package/src/helper.ts +849 -0
  618. package/src/introspection/generated.agi.ts +40208 -0
  619. package/src/introspection/generated.node.ts +28686 -0
  620. package/src/introspection/generated.web.ts +2251 -0
  621. package/src/introspection/index.ts +296 -0
  622. package/src/introspection/scan.ts +1131 -0
  623. package/src/node/container.ts +409 -0
  624. package/src/node/feature.ts +13 -0
  625. package/src/node/features/container-link.ts +559 -0
  626. package/src/node/features/content-db.ts +812 -0
  627. package/src/node/features/disk-cache.ts +388 -0
  628. package/src/node/features/dns.ts +669 -0
  629. package/src/node/features/docker.ts +921 -0
  630. package/src/node/features/downloader.ts +79 -0
  631. package/src/node/features/figlet-fonts.ts +600 -0
  632. package/src/node/features/file-manager.ts +535 -0
  633. package/src/node/features/fs.ts +1050 -0
  634. package/src/node/features/git.ts +592 -0
  635. package/src/node/features/google-auth.ts +504 -0
  636. package/src/node/features/google-calendar.ts +306 -0
  637. package/src/node/features/google-docs.ts +412 -0
  638. package/src/node/features/google-drive.ts +346 -0
  639. package/src/node/features/google-mail.ts +540 -0
  640. package/src/node/features/google-sheets.ts +286 -0
  641. package/src/node/features/grep.ts +427 -0
  642. package/src/node/features/helpers.ts +735 -0
  643. package/src/node/features/ink.ts +490 -0
  644. package/src/node/features/ipc-socket.ts +649 -0
  645. package/src/node/features/json-tree.ts +170 -0
  646. package/src/node/features/networking.ts +961 -0
  647. package/src/node/features/nlp.ts +212 -0
  648. package/src/node/features/opener.ts +180 -0
  649. package/src/node/features/os.ts +403 -0
  650. package/src/node/features/package-finder.ts +540 -0
  651. package/src/node/features/postgres.ts +289 -0
  652. package/src/node/features/proc.ts +503 -0
  653. package/src/node/features/process-manager.ts +844 -0
  654. package/src/node/features/python.ts +906 -0
  655. package/src/node/features/redis.ts +446 -0
  656. package/src/node/features/repl.ts +212 -0
  657. package/src/node/features/runpod.ts +811 -0
  658. package/src/node/features/secure-shell.ts +267 -0
  659. package/src/node/features/semantic-search.ts +935 -0
  660. package/src/node/features/sqlite.ts +289 -0
  661. package/src/node/features/telegram.ts +343 -0
  662. package/src/node/features/transpiler.ts +161 -0
  663. package/src/node/features/tts.ts +185 -0
  664. package/src/node/features/ui.ts +786 -0
  665. package/src/node/features/vault.ts +153 -0
  666. package/src/node/features/vm.ts +462 -0
  667. package/src/node/features/yaml-tree.ts +148 -0
  668. package/src/node/features/yaml.ts +133 -0
  669. package/src/node.ts +76 -0
  670. package/src/python/bridge.py +220 -0
  671. package/src/python/generated.ts +227 -0
  672. package/src/react/index.ts +175 -0
  673. package/src/registry.ts +210 -0
  674. package/src/scaffolds/generated.ts +1815 -0
  675. package/src/scaffolds/template.ts +46 -0
  676. package/src/schemas/base.ts +296 -0
  677. package/src/selector.ts +352 -0
  678. package/src/server.ts +229 -0
  679. package/src/servers/express.ts +283 -0
  680. package/src/servers/mcp.ts +802 -0
  681. package/src/servers/socket.ts +258 -0
  682. package/src/state.ts +101 -0
  683. package/src/web/clients/socket.ts +99 -0
  684. package/src/web/container.ts +75 -0
  685. package/src/web/extension.ts +30 -0
  686. package/src/web/feature.ts +12 -0
  687. package/src/web/features/asset-loader.ts +72 -0
  688. package/src/web/features/container-link.ts +382 -0
  689. package/src/web/features/esbuild.ts +93 -0
  690. package/src/web/features/helpers.ts +269 -0
  691. package/src/web/features/network.ts +85 -0
  692. package/src/web/features/speech.ts +104 -0
  693. package/src/web/features/vault.ts +207 -0
  694. package/src/web/features/vm.ts +85 -0
  695. package/src/web/features/voice-recognition.ts +161 -0
  696. package/src/web/shims/isomorphic-vm.ts +149 -0
  697. package/test/assistant-hooks.test.ts +306 -0
  698. package/test/assistant.test.ts +81 -0
  699. package/test/bus.test.ts +134 -0
  700. package/test/clients-servers.test.ts +217 -0
  701. package/test/command.test.ts +267 -0
  702. package/test/container-link.test.ts +274 -0
  703. package/test/conversation.test.ts +220 -0
  704. package/test/features.test.ts +160 -0
  705. package/test/fork-and-research.test.ts +450 -0
  706. package/test/integration.test.ts +787 -0
  707. package/test/interceptor-chain.test.ts +61 -0
  708. package/test/node-container.test.ts +121 -0
  709. package/test/python-session.test.ts +105 -0
  710. package/test/rate-limit.test.ts +272 -0
  711. package/test/semantic-search.test.ts +550 -0
  712. package/test/state.test.ts +121 -0
  713. package/test/vm-context.test.ts +146 -0
  714. package/test/vm-loadmodule.test.ts +213 -0
  715. package/test/websocket-ask.test.ts +101 -0
  716. package/test-integration/assistant.test.ts +138 -0
  717. package/test-integration/assistants-manager.test.ts +113 -0
  718. package/test-integration/claude-code.test.ts +98 -0
  719. package/test-integration/conversation-history.test.ts +205 -0
  720. package/test-integration/conversation.test.ts +137 -0
  721. package/test-integration/elevenlabs.test.ts +55 -0
  722. package/test-integration/google-services.test.ts +80 -0
  723. package/test-integration/helpers.ts +89 -0
  724. package/test-integration/memory.test.ts +204 -0
  725. package/test-integration/openai-codex.test.ts +93 -0
  726. package/test-integration/runpod.test.ts +58 -0
  727. package/test-integration/server-endpoints.test.ts +97 -0
  728. package/test-integration/telegram.test.ts +46 -0
  729. package/tsconfig.build.json +12 -0
  730. package/tsconfig.json +58 -0
  731. package/uv.lock +8 -0
  732. package/LICENSE +0 -21
  733. package/dist/cli/cli.js +0 -48
  734. package/dist/cli/common.d.ts +0 -2
  735. package/dist/cli/common.js +0 -6
  736. package/dist/cli/index.d.ts +0 -2
  737. package/dist/cli/index.js +0 -5
  738. package/dist/cli/run.d.ts +0 -1
  739. package/dist/cli/run.js +0 -38
  740. package/dist/core/index.d.ts +0 -4
  741. package/dist/core/index.js +0 -32
  742. package/dist/core/read.d.ts +0 -2
  743. package/dist/core/read.js +0 -29
  744. package/dist/core/request.d.ts +0 -1
  745. package/dist/core/request.js +0 -2
  746. package/dist/core/write.d.ts +0 -2
  747. package/dist/core/write.js +0 -21
  748. package/dist/index.d.ts +0 -1
  749. package/dist/index.js +0 -5
  750. package/dist/utils/common.d.ts +0 -9
  751. package/dist/utils/common.js +0 -57
  752. package/dist/utils/consts.d.ts +0 -3
  753. package/dist/utils/consts.js +0 -11
  754. package/dist/utils/dict.d.ts +0 -1
  755. package/dist/utils/dict.js +0 -7
  756. package/dist/utils/index.d.ts +0 -5
  757. package/dist/utils/index.js +0 -21
  758. package/dist/utils/log.d.ts +0 -1
  759. package/dist/utils/log.js +0 -5
  760. package/dist/utils/types.d.ts +0 -1
  761. package/dist/utils/types.js +0 -2
  762. package/dist/utils/utils.test.d.ts +0 -1
  763. package/dist/utils/utils.test.js +0 -7
@@ -0,0 +1,1186 @@
1
+ // @ts-nocheck
2
+ import { Bus } from './bus'
3
+ import { SetStateValue, State } from './state'
4
+ import { AvailableFeatures, features, Feature, FeaturesRegistry } from './feature'
5
+ import { Helper, normalizeTypeString, renderTypeScriptParams, isGenericObjectType } from './helper'
6
+ import uuid from 'node-uuid'
7
+ import hashObject from './hash-object'
8
+ import { uniq, keyBy, uniqBy, groupBy, debounce, throttle, mapValues, mapKeys, pick, get, set, omit, kebabCase, camelCase, upperFirst, lowerFirst } from 'lodash-es'
9
+ import { pluralize, singularize } from 'inflect'
10
+ import { z } from 'zod'
11
+ import { ContainerStateSchema, describeZodShape } from './schemas/base'
12
+ import { getContainerBuildTimeData, type ContainerIntrospection, type RegistryIntrospection, type IntrospectionSection } from './introspection/index'
13
+ import { ContainerDescriber } from './container-describer'
14
+ import { createEntityObject, type Entity, type EventMap as EntityEventMap } from './entity'
15
+
16
+ export { z }
17
+
18
+ const { v4 } = uuid
19
+
20
+ const stringUtils = { kebabCase, camelCase, upperFirst, lowerFirst, pluralize, singularize }
21
+
22
+ export type { AvailableFeatures }
23
+
24
+ // I want the InstanceType of each value of AvailableFeatures, AvailableClients, whatever
25
+ export type AvailableInstanceTypes<T> = {
26
+ [K in keyof T]: T[K] extends new (...args: any) => any ? InstanceType<T[K]> : never
27
+ }
28
+
29
+ /**
30
+ * Maps a feature registry to the INPUT type of each feature's optionsSchema.
31
+ * This allows feature() to accept partial/optional options (e.g. omitting fields
32
+ * that have .default() on them) rather than requiring the fully-parsed OUTPUT type.
33
+ *
34
+ * For any feature class that exposes a static `optionsSchema`, we use `z.input<S>` so
35
+ * that callers can omit fields that have `.default(...)` — Zod's output type marks
36
+ * defaulted fields as required, but the input type correctly makes them optional.
37
+ */
38
+ export type FeatureInputOptions<Features> = {
39
+ [K in keyof Features]: Features[K] extends { optionsSchema: infer S extends z.ZodType }
40
+ ? z.input<S>
41
+ : Features[K] extends new (options: infer O, ...args: any[]) => any
42
+ ? O
43
+ : Record<string, unknown>
44
+ }
45
+
46
+ /**
47
+ * You'll want to use module augmentation to add your own options to the ContainerArgv interface
48
+ */
49
+ export interface ContainerArgv {
50
+ _?: string[]
51
+ }
52
+
53
+ export type ContainerState = z.infer<typeof ContainerStateSchema>
54
+
55
+ export interface Plugin<T> {
56
+ attach?: (container: Container<any> & T, options?: any) => any
57
+ }
58
+
59
+ export type Extension<T> = 'string' | keyof AvailableFeatures | Plugin<T> | { attach: (container: Container<any>, options?: any) => T}
60
+
61
+ export interface ContainerUtils {
62
+ /** Generate a v4 UUID */
63
+ uuid: () => string
64
+ /** Deterministic hash of any object */
65
+ hashObject: (obj: any) => string
66
+ /** String case conversion and inflection utilities */
67
+ stringUtils: { kebabCase: typeof kebabCase; camelCase: typeof camelCase; upperFirst: typeof upperFirst; lowerFirst: typeof lowerFirst; pluralize: typeof pluralize; singularize: typeof singularize }
68
+ /** Lodash utility subset */
69
+ lodash: { uniq: typeof uniq; keyBy: typeof keyBy; uniqBy: typeof uniqBy; groupBy: typeof groupBy; debounce: typeof debounce; throttle: typeof throttle; mapValues: typeof mapValues; mapKeys: typeof mapKeys; pick: typeof pick; get: typeof get; set: typeof set; omit: typeof omit }
70
+ }
71
+
72
+ export interface ContainerContext<T extends AvailableFeatures = any> {
73
+ container: Container<T>
74
+ [key: string]: unknown
75
+ }
76
+
77
+ /**
78
+ * The Container is the core runtime object in Luca. It is a singleton per process that acts as an
79
+ * event bus, state machine, and dependency injector. It holds registries of helpers (features, clients,
80
+ * servers, commands, endpoints) and provides factory methods to create instances from them.
81
+ *
82
+ * All helper instances share the container's context, enabling them to communicate and coordinate.
83
+ * The container detects its runtime environment (Node, Bun, browser, Electron) and can load
84
+ * platform-specific feature implementations accordingly.
85
+ *
86
+ * Use `container.feature('name')` to create feature instances, `container.use(Plugin)` to extend
87
+ * the container with new capabilities, and `container.on('event', handler)` to react to lifecycle events.
88
+ *
89
+ * @example
90
+ * ```ts
91
+ * // Create a feature instance (cached — same args return same instance)
92
+ * const fs = container.feature('fs')
93
+ * const content = fs.readFile('README.md')
94
+ * ```
95
+ *
96
+ * @example
97
+ * ```ts
98
+ * // Listen for state changes
99
+ * container.on('stateChange', (state) => console.log('State changed:', state))
100
+ * container.setState({ started: true })
101
+ * ```
102
+ *
103
+ * @example
104
+ * ```ts
105
+ * // Extend with a plugin
106
+ * container.use(MyClient) // calls MyClient.attach(container)
107
+ * container.use('contentDb') // enable a feature by name
108
+ * ```
109
+ */
110
+ export class Container<Features extends AvailableFeatures = AvailableFeatures, ContainerState extends ContainerState = ContainerState > {
111
+ static stateSchema = ContainerStateSchema
112
+
113
+ readonly uuid = v4()
114
+ private readonly _events = new Bus()
115
+ private readonly _state: State<ContainerState>
116
+
117
+ /**
118
+ * You can use module augmentation to define the starting interface for your container
119
+ * whether it is process.argv, process.env, or some combination thereof
120
+ */
121
+ readonly options: ContainerArgv
122
+
123
+ constructor(options: ContainerArgv) {
124
+ this.options = options
125
+ this._state = new State<ContainerState>()
126
+ this.z = z
127
+ this.state
128
+ .set('enabledFeatures', [])
129
+ .set('started', false)
130
+ .set('registries', ['features'])
131
+ .set('factories', ['feature'])
132
+
133
+ this._hide('options', '_state', '_events', 'uuid', '_plugins', 'z')
134
+
135
+ this.on('featureEnabled', (featureId: string, feature: any) => {
136
+ const featureKey = featureId.replace(/^features\./,'')
137
+ const mapKey = `${this.uuid}/${featureKey}`
138
+ featureIdToHelperCacheKeyMap.set(mapKey, feature.cacheKey)
139
+ this.state.set('enabledFeatures', uniq([
140
+ ...this.state.get('enabledFeatures')!,
141
+ featureKey
142
+ ]))
143
+ this.addContext(featureKey, feature)
144
+ })
145
+
146
+ this.state.observe(() => {
147
+ this.emit('stateChange', this.state.current)
148
+ })
149
+ }
150
+
151
+ /**
152
+ * Creates a new subcontainer instance of the same concrete Container subclass.
153
+ * The new instance is constructed with the same options as this container,
154
+ * shallow-merged with any overrides you provide. This preserves the runtime
155
+ * container type (e.g. NodeContainer, AGIContainer, etc.).
156
+ *
157
+ * @param options - Options to override for the new container instance
158
+ * @returns A new container instance of the same subclass
159
+ *
160
+ * @example
161
+ * ```ts
162
+ * const child = container.subcontainer({ cwd: '/tmp/workspace' })
163
+ * child.cwd // '/tmp/workspace'
164
+ * ```
165
+ */
166
+ subcontainer<This extends Container<any, any>>(
167
+ this: This,
168
+ options: ConstructorParameters<This['constructor']>[0]
169
+ ): This {
170
+ const Ctor = this.constructor as new (options: ConstructorParameters<This['constructor']>[0]) => This
171
+ const mergedOptions = {
172
+ ...(this as any).options || {},
173
+ ...(options || {}),
174
+ }
175
+ return new Ctor(mergedOptions)
176
+ }
177
+
178
+ z!: typeof z
179
+
180
+
181
+ /** The observable state object for this container instance. */
182
+ get state(): State<ContainerState> {
183
+ return this._state
184
+ }
185
+
186
+ /** Returns the list of shortcut IDs for all currently enabled features. */
187
+ get enabledFeatureIds(): string[] {
188
+ return this.state.get('enabledFeatures') || []
189
+ }
190
+
191
+ /** Returns a map of enabled feature shortcut IDs to their instances. */
192
+ get enabledFeatures() : Partial<AvailableInstanceTypes<Features>> {
193
+ return Object.fromEntries(
194
+ this.enabledFeatureIds.map((featureId) => [featureId, (this as any)[featureId]])
195
+ ) as AvailableInstanceTypes<Features>
196
+ }
197
+
198
+ /**
199
+ * Common utilities available on every container. Provides UUID generation, object hashing,
200
+ * string case conversion, and lodash helpers — no imports needed.
201
+ *
202
+ * - `utils.uuid()` — generate a v4 UUID
203
+ * - `utils.hashObject(obj)` — deterministic hash of any object
204
+ * - `utils.stringUtils` — `{ kebabCase, camelCase, upperFirst, lowerFirst, pluralize, singularize }`
205
+ * - `utils.lodash` — `{ uniq, keyBy, uniqBy, groupBy, debounce, throttle, mapValues, mapKeys, pick, get, set, omit }`
206
+ *
207
+ * @example
208
+ * ```ts
209
+ * const id = container.utils.uuid()
210
+ * const hash = container.utils.hashObject({ foo: 'bar' })
211
+ * const name = container.utils.stringUtils.camelCase('my-feature')
212
+ * const unique = container.utils.lodash.uniq([1, 2, 2, 3])
213
+ * ```
214
+ */
215
+ get utils(): ContainerUtils {
216
+ return {
217
+ hashObject: (obj: any) => hashObject(obj),
218
+ get stringUtils() { return stringUtils },
219
+ uuid: () => v4(),
220
+ lodash: {
221
+ uniq, keyBy, uniqBy, groupBy, debounce, throttle, mapValues, mapKeys, pick, get, set, omit,
222
+ }
223
+ }
224
+ }
225
+
226
+ private _describer?: ContainerDescriber
227
+
228
+ /**
229
+ * Lazy-initialized ContainerDescriber for introspecting registries, helpers, and members.
230
+ * @internal
231
+ */
232
+ get describer(): ContainerDescriber {
233
+ if (!this._describer) {
234
+ this._describer = new ContainerDescriber(this)
235
+ }
236
+ return this._describer
237
+ }
238
+
239
+ addContext<K extends keyof ContainerContext>(key: K, value: ContainerContext[K]): this
240
+ addContext(context: Partial<ContainerContext>): this
241
+ /**
242
+ * Add a value to the container's shared context, which is passed to all helper instances.
243
+ * Accepts either a key and value, or an object of key-value pairs to merge in.
244
+ *
245
+ * @param key - The context key, or an object of key-value pairs to merge
246
+ * @param value - The context value (omit when passing an object)
247
+ * @returns The container instance (for chaining)
248
+ *
249
+ * @example
250
+ * ```ts
251
+ * container.addContext('db', dbConnection)
252
+ * container.addContext({ db: dbConnection, cache: redisClient })
253
+ * ```
254
+ */
255
+ addContext(keyOrContext: keyof ContainerContext | Partial<ContainerContext>, value?: ContainerContext[keyof ContainerContext]): this {
256
+ if (arguments.length === 1 && typeof keyOrContext === 'object' && keyOrContext !== null) {
257
+ for (const [k, v] of Object.entries(keyOrContext)) {
258
+ if (v !== undefined) {
259
+ this.addContext(k as keyof ContainerContext, v as ContainerContext[keyof ContainerContext])
260
+ }
261
+ }
262
+ return this
263
+ }
264
+ const contexts = contextMap.get(this) || new Map()
265
+ contexts.set(keyOrContext as keyof ContainerContext, value)
266
+ contextMap.set(this, contexts)
267
+ return this
268
+ }
269
+
270
+ /**
271
+ * The Container's context is an object that contains the enabled features, the container itself, and any additional context that has been added to the container.
272
+ *
273
+ * All helper instances that are created by the container will have access to the shared context.
274
+ */
275
+ get context(): ContainerContext<Features> & Partial<AvailableInstanceTypes<AvailableFeatures>> {
276
+ const contexts = contextMap.get(this) || new Map()
277
+
278
+ return {
279
+ ...this.enabledFeatures,
280
+ ...Object.fromEntries(Array.from(contexts.entries())) as ContainerContext<Features>,
281
+ container: this as Container<Features>,
282
+ }
283
+ }
284
+
285
+ /**
286
+ * The current state of the container.
287
+ *
288
+ * This is a snapshot of the container's state at the time this method is called.
289
+ *
290
+ * @returns The current state of the container.
291
+ */
292
+ get currentState(): ContainerState {
293
+ return this.state.current
294
+ }
295
+
296
+ /**
297
+ * Sets the state of the container. Accepts a partial state object to merge, or a function
298
+ * that receives the current state and returns the new state.
299
+ *
300
+ * @param newState - A partial state object to merge, or a function `(current) => newState`
301
+ * @returns The container instance (for chaining)
302
+ *
303
+ * @example
304
+ * ```ts
305
+ * container.setState({ started: true })
306
+ * container.setState((prev) => ({ ...prev, started: true }))
307
+ * ```
308
+ */
309
+ setState(newState: SetStateValue<ContainerState>): this {
310
+ this.state.setState(newState)
311
+ return this
312
+ }
313
+
314
+ get Feature() {
315
+ return Feature
316
+ }
317
+
318
+ get Helper() {
319
+ return Helper
320
+ }
321
+
322
+ get State() {
323
+ return State
324
+ }
325
+
326
+ /**
327
+ * The features registry. Use it to check what features are available, look up feature classes,
328
+ * or check if a feature is registered.
329
+ *
330
+ * @example
331
+ * ```ts
332
+ * container.features.available // ['fs', 'git', 'grep', ...]
333
+ * container.features.has('fs') // true
334
+ * container.features.lookup('fs') // FS class
335
+ * ```
336
+ */
337
+ get features(): FeaturesRegistry {
338
+ return features
339
+ }
340
+
341
+ /**
342
+ * Create a new standalone event bus instance. Useful when you need a scoped event channel
343
+ * that is independent of the container's own event bus.
344
+ *
345
+ * @returns A new Bus instance
346
+ *
347
+ * @example
348
+ * ```ts
349
+ * const myBus = container.bus()
350
+ * myBus.on('data', (payload) => console.log(payload))
351
+ * myBus.emit('data', { count: 42 })
352
+ * ```
353
+ */
354
+ bus(): Bus {
355
+ return new Bus()
356
+ }
357
+
358
+ /**
359
+ * Create a new standalone observable State object. Useful when you need reactive state
360
+ * that is independent of the container's own state.
361
+ *
362
+ * @param initialState - The initial state object (defaults to empty)
363
+ * @returns A new State instance
364
+ *
365
+ * @example
366
+ * ```ts
367
+ * const myState = container.newState({ count: 0, loading: false })
368
+ * myState.observe(() => console.log('Changed:', myState.current))
369
+ * myState.set('count', 1)
370
+ * ```
371
+ */
372
+ newState<T extends object = any>(initialState: T = {} as T): State<T> {
373
+ return new State<T>({ initialState })
374
+ }
375
+
376
+ /**
377
+ * Parse helper options through the helper's static options schema so defaults are materialized.
378
+ * @internal
379
+ */
380
+ normalizeHelperOptions(BaseClass: any, options: any, fallbackName?: string) {
381
+ const candidate = { ...(options || {}) }
382
+
383
+ if (fallbackName && (candidate.name === undefined || candidate.name === null || candidate.name === '')) {
384
+ candidate.name = fallbackName
385
+ }
386
+
387
+ const schema = BaseClass?.optionsSchema
388
+ if (!schema || typeof schema.safeParse !== 'function') {
389
+ return candidate
390
+ }
391
+
392
+ const parsed = schema.safeParse(candidate)
393
+ if (parsed.success) {
394
+ return parsed.data
395
+ }
396
+
397
+ const target = BaseClass?.shortcut || BaseClass?.name || 'helper'
398
+ const details = parsed.error.issues
399
+ .map((issue: any) => `${issue.path?.join('.') || 'options'}: ${issue.message}`)
400
+ .join('; ')
401
+ throw new Error(`Invalid options for ${target}: ${details || parsed.error.message}`)
402
+ }
403
+
404
+ /** @internal */
405
+ buildHelperCacheKey(type: string, id: string, options: any, omitOptionKeys: string[] = []) {
406
+ const hashableOptions = omit(options || {}, uniq(['_cacheKey', ...omitOptionKeys]))
407
+
408
+ return hashObject({
409
+ __type: type,
410
+ id,
411
+ options: hashableOptions,
412
+ uuid: this.uuid,
413
+ })
414
+ }
415
+
416
+ /** @internal */
417
+ createHelperInstance({
418
+ cache,
419
+ type,
420
+ id,
421
+ BaseClass,
422
+ options,
423
+ fallbackName,
424
+ omitOptionKeys = [],
425
+ context,
426
+ }: {
427
+ cache: Map<string, any>
428
+ type: string
429
+ id: string
430
+ BaseClass: any
431
+ options?: any
432
+ fallbackName?: string
433
+ omitOptionKeys?: string[]
434
+ context?: any
435
+ }) {
436
+ const normalizedOptions = this.normalizeHelperOptions(BaseClass, options, fallbackName || id)
437
+ const cacheKey = this.buildHelperCacheKey(type, id, normalizedOptions, omitOptionKeys)
438
+ const cached = cache.get(cacheKey)
439
+
440
+ if (cached) {
441
+ return cached
442
+ }
443
+
444
+ const helperOptions = {
445
+ ...normalizedOptions,
446
+ _cacheKey: normalizedOptions._cacheKey || cacheKey,
447
+ }
448
+
449
+ const instance = new (BaseClass as any)(helperOptions, context || this.context)
450
+ cache.set(cacheKey, instance)
451
+ uuidCache.set(instance.uuid, instance)
452
+ return instance
453
+ }
454
+
455
+ /**
456
+ * Creates a new instance of a feature.
457
+ *
458
+ * If you pass the same arguments, it will return the same instance as last time you created that.
459
+ *
460
+ * If you need the ability to create fresh instances, it is up to you how you define your options to support that.
461
+ *
462
+ * @param id - The id of the feature to create.
463
+ * @param options - The options to pass to the feature constructor.
464
+ * @returns The new feature instance.
465
+ */
466
+ feature<T extends keyof Features>(
467
+ id: T,
468
+ options?: FeatureInputOptions<Features>[T] | Record<string, unknown>
469
+ ): InstanceType<Features[T]> {
470
+ const BaseClass = this.features.lookup(id as string) as Features[T]
471
+
472
+ return this.createHelperInstance({
473
+ cache: helperCache,
474
+ type: 'feature',
475
+ id: String(id),
476
+ BaseClass,
477
+ options,
478
+ omitOptionKeys: ['enable'],
479
+ context: { container: this },
480
+ }) as InstanceType<Features[T]>
481
+ }
482
+
483
+ /**
484
+ * Creates a lightweight entity object with observable state, a typed event bus, and
485
+ * access to the container. Same id + options always returns the same cached base instance.
486
+ *
487
+ * An optional third argument auto-extends the entity with functions and getters.
488
+ * All extended methods and getters can access the entity (state, options, container,
489
+ * on/off/emit, etc.) via `this`.
490
+ *
491
+ * @param id - Stable identifier for this entity (included in cache key)
492
+ * @param options - Arbitrary options stored on `entity.options` (included in cache key)
493
+ * @param extensions - Optional object of functions/getters to graft onto the entity
494
+ *
495
+ * @example
496
+ * ```ts
497
+ * // Basic entity with typed state and events
498
+ * const counter = container.entity<{ count: number }>('counter')
499
+ * counter.setState({ count: 0 })
500
+ * counter.on('tick', () => counter.setState(s => ({ count: s.count + 1 })))
501
+ *
502
+ * // With options and auto-extension
503
+ * const user = container.entity('user:42', { name: 'Alice' }, {
504
+ * greet() { return `Hello ${this.options.name}` },
505
+ * get label() { return `User: ${this.options.name}` },
506
+ * })
507
+ * user.greet() // "Hello Alice"
508
+ * ```
509
+ */
510
+ entity<
511
+ TState extends Record<string, any> = Record<string, any>,
512
+ TOptions extends Record<string, any> = Record<string, any>,
513
+ TEvents extends EntityEventMap = EntityEventMap,
514
+ Ext extends Record<string, any> = {},
515
+ >(
516
+ id: string,
517
+ options?: TOptions,
518
+ extensions?: Ext & ThisType<Entity<TState, TOptions, TEvents> & Ext>
519
+ ): Entity<TState, TOptions, TEvents> & Ext {
520
+ const normalizedOptions = (options || {}) as TOptions
521
+ const cacheKey = this.buildHelperCacheKey('entity', id, normalizedOptions)
522
+
523
+ let base = entityCache.get(cacheKey)
524
+ if (!base) {
525
+ base = createEntityObject<TState, TOptions, TEvents>(id, this, normalizedOptions)
526
+ entityCache.set(cacheKey, base)
527
+ }
528
+
529
+ return extensions ? base.extend(extensions) : base
530
+ }
531
+
532
+ /**
533
+ * Look up any helper instance (feature, client, server) by its UUID.
534
+ * Returns undefined if the UUID is unknown or the instance was never created.
535
+ *
536
+ * @param uuid - The `instance.uuid` value assigned at construction time
537
+ * @returns The helper instance, or undefined
538
+ *
539
+ * @example
540
+ * ```ts
541
+ * const assistant = container.feature('assistant')
542
+ * const { uuid } = assistant
543
+ * // ... later ...
544
+ * const same = container.getHelperByUUID(uuid) // === assistant
545
+ * ```
546
+ */
547
+ getHelperByUUID(uuid: string): Helper | undefined {
548
+ return uuidCache.get(uuid)
549
+ }
550
+
551
+ /**
552
+ * Start the container. Emits the 'started' event and sets `state.started` to true.
553
+ * Plugins and features can listen for this event to perform initialization.
554
+ *
555
+ * @returns The container instance
556
+ *
557
+ * @example
558
+ * ```ts
559
+ * container.on('started', () => console.log('Ready'))
560
+ * await container.start()
561
+ * ```
562
+ */
563
+ async start(): Promise<this> {
564
+ this.emit('started', this as Container<Features>)
565
+ this.state.set('started', true)
566
+ return this
567
+ }
568
+
569
+ /**
570
+ * ENVIRONMENT DETECTION METHODS
571
+ *
572
+ * One of the ideas of the container is that it can detect what kind of environment it is running in and
573
+ * e.g. perhaps load different versions of features to provide the same API with different implementations.
574
+ *
575
+ */
576
+
577
+ /**
578
+ * Returns true if the container is running in a browser.
579
+ */
580
+ get isBrowser(): boolean {
581
+ return typeof window !== 'undefined' && typeof document !== 'undefined'
582
+ }
583
+
584
+ /**
585
+ * Returns true if the container is running in Bun.
586
+ */
587
+ get isBun(): boolean {
588
+ return this.isNode && typeof Bun !== 'undefined'
589
+ }
590
+
591
+ /**
592
+ * Returns true if the container is running in Node.
593
+ */
594
+ get isNode(): boolean {
595
+ return typeof process !== 'undefined' && typeof process.versions !== 'undefined' && typeof process.versions.node !== 'undefined'
596
+ }
597
+
598
+ /**
599
+ * Returns true if the container is running in Electron.
600
+ */
601
+ get isElectron(): boolean {
602
+ return typeof process !== 'undefined' && typeof process.versions !== 'undefined' && typeof process.versions.electron !== 'undefined'
603
+ }
604
+
605
+ /**
606
+ * Returns true if the container is running in development mode.
607
+ */
608
+ get isDevelopment(): boolean {
609
+ return typeof process !== 'undefined' && process.env.NODE_ENV === 'development'
610
+ }
611
+
612
+ /**
613
+ * Returns true if the container is running in production mode.
614
+ */
615
+ get isProduction(): boolean {
616
+ return typeof process !== 'undefined' && process.env.NODE_ENV === 'production'
617
+ }
618
+
619
+ /**
620
+ * Returns true if the container is running in a CI environment.
621
+ */
622
+ get isCI(): boolean {
623
+ return typeof process !== 'undefined' && process.env.CI !== undefined && String(process.env.CI).length > 0
624
+ }
625
+
626
+ /**
627
+ * Emit an event on the container's event bus.
628
+ *
629
+ * @param event - The event name
630
+ * @param args - Arguments to pass to listeners
631
+ * @returns The container instance (for chaining)
632
+ *
633
+ * @example
634
+ * ```ts
635
+ * container.emit('taskCompleted', { id: 'abc', result: 42 })
636
+ * ```
637
+ */
638
+ emit(event: string, ...args: any[]): this {
639
+ this._events.emit(event, ...args)
640
+ return this
641
+ }
642
+
643
+ /**
644
+ * Subscribe to an event on the container's event bus.
645
+ *
646
+ * @param event - The event name
647
+ * @param listener - The callback function
648
+ * @returns The container instance (for chaining)
649
+ *
650
+ * @example
651
+ * ```ts
652
+ * container.on('featureEnabled', (id, feature) => {
653
+ * console.log(`Feature ${id} enabled`)
654
+ * })
655
+ * ```
656
+ */
657
+ on(event: string, listener: (...args: any[]) => void): this {
658
+ this._events.on(event, listener)
659
+ return this
660
+ }
661
+
662
+ /**
663
+ * Unsubscribe a listener from an event on the container's event bus.
664
+ *
665
+ * @param event - The event name
666
+ * @param listener - The listener to remove
667
+ * @returns The container instance (for chaining)
668
+ */
669
+ off(event: string, listener?: (...args: any[]) => void): this {
670
+ this._events.off(event, listener)
671
+ return this
672
+ }
673
+
674
+ /**
675
+ * Subscribe to an event on the container's event bus, but only fire once.
676
+ *
677
+ * @param event - The event name
678
+ * @param listener - The callback function (invoked at most once)
679
+ * @returns The container instance (for chaining)
680
+ */
681
+ once(event: string, listener: (...args: any[]) => void): this {
682
+ this._events.once(event, listener)
683
+ return this
684
+ }
685
+
686
+ /**
687
+ * Returns a promise that resolves the next time the given event is emitted.
688
+ * Useful for awaiting one-time lifecycle transitions.
689
+ *
690
+ * @param event - The event name to wait for
691
+ * @returns A promise that resolves with the event arguments
692
+ *
693
+ * @example
694
+ * ```ts
695
+ * await container.waitFor('started')
696
+ * console.log('Container is ready')
697
+ * ```
698
+ */
699
+ async waitFor(event: string): Promise<any> {
700
+ const resp = await this._events.waitFor(event)
701
+ return resp
702
+ }
703
+
704
+ /**
705
+ * Register a helper type (registry + factory pair) on this container.
706
+ * Called automatically by Helper.attach() methods (e.g. Client.attach, Server.attach).
707
+ * @internal
708
+ */
709
+ registerHelperType(registryName: string, factoryName: string) {
710
+ const registries = uniq([...this.state.get('registries')!, registryName])
711
+ const factories = uniq([...this.state.get('factories')!, factoryName])
712
+ this.state.set('registries', registries)
713
+ this.state.set('factories', factories)
714
+ return this
715
+ }
716
+
717
+ /** Returns the names of all attached registries (e.g. ["features", "clients", "servers"]). */
718
+ get registryNames(): string[] {
719
+ return this.state.get('registries') || ['features']
720
+ }
721
+
722
+ /** Returns the names of all available factory methods (e.g. ["feature", "client", "server"]). */
723
+ get factoryNames(): string[] {
724
+ return this.state.get('factories') || ['feature']
725
+ }
726
+
727
+ /**
728
+ * Returns a full introspection object for this container, merging build-time AST data
729
+ * (JSDoc descriptions, methods, getters) with runtime data (registries, factories, state, environment).
730
+ *
731
+ * @returns The complete introspection data as a structured object
732
+ *
733
+ * @example
734
+ * ```ts
735
+ * const info = container.introspect()
736
+ * console.log(info.methods) // all public methods with descriptions
737
+ * console.log(info.getters) // all getters with return types
738
+ * console.log(info.registries) // features, clients, servers, etc.
739
+ * ```
740
+ */
741
+ introspect(): ContainerIntrospection {
742
+ const className = this.constructor.name
743
+ const buildTimeData = getContainerBuildTimeData(className) || {}
744
+
745
+ // Walk up the prototype chain to merge inherited build-time data
746
+ let mergedMethods = { ...(buildTimeData.methods || {}) }
747
+ let mergedGetters = { ...(buildTimeData.getters || {}) }
748
+ let mergedEvents = { ...(buildTimeData.events || {}) }
749
+ let mergedDescription = buildTimeData.description || ''
750
+
751
+ let proto = Object.getPrototypeOf(this.constructor)
752
+ while (proto && proto.name) {
753
+ const parentData = getContainerBuildTimeData(proto.name)
754
+ if (parentData) {
755
+ mergedMethods = { ...parentData.methods, ...mergedMethods }
756
+ mergedGetters = { ...parentData.getters, ...mergedGetters }
757
+ mergedEvents = { ...parentData.events, ...mergedEvents }
758
+ if (!mergedDescription && parentData.description) {
759
+ mergedDescription = parentData.description
760
+ }
761
+ }
762
+ proto = Object.getPrototypeOf(proto)
763
+ }
764
+
765
+ // Build registry introspection from runtime data
766
+ const registryNames = this.registryNames
767
+ const registries: RegistryIntrospection[] = registryNames.map((name) => {
768
+ const registry = (this as any)[name]
769
+ return {
770
+ name,
771
+ baseClass: registry?.baseClass?.name || 'Helper',
772
+ available: registry?.available || []
773
+ }
774
+ })
775
+
776
+ // Get state description from the Zod schema
777
+ const stateSchema = (this.constructor as any).stateSchema
778
+ const stateDescription = stateSchema ? describeZodShape(stateSchema) : {}
779
+
780
+ return {
781
+ className,
782
+ uuid: this.uuid,
783
+ description: mergedDescription,
784
+ registries,
785
+ factories: this.factoryNames,
786
+ methods: mergedMethods,
787
+ getters: mergedGetters,
788
+ events: mergedEvents,
789
+ state: stateDescription,
790
+ enabledFeatures: this.enabledFeatureIds,
791
+ environment: {
792
+ isBrowser: this.isBrowser,
793
+ isNode: this.isNode,
794
+ isBun: this.isBun,
795
+ isElectron: this.isElectron,
796
+ isDevelopment: this.isDevelopment,
797
+ isProduction: this.isProduction,
798
+ isCI: this.isCI
799
+ }
800
+ }
801
+ }
802
+
803
+ /**
804
+ * Returns a human-readable markdown representation of this container's introspection data.
805
+ * Useful in REPLs, AI agent contexts, or documentation generation. Pass a section name
806
+ * to render only that section (e.g. 'methods', 'getters', 'events', 'state').
807
+ *
808
+ * @param sectionOrDepth - A section name to render, or heading depth number
809
+ * @param startHeadingDepth - Starting markdown heading depth (default 1)
810
+ * @returns Markdown-formatted introspection text
811
+ *
812
+ * @example
813
+ * ```ts
814
+ * console.log(container.introspectAsText()) // full description
815
+ * console.log(container.introspectAsText('methods')) // just methods
816
+ * ```
817
+ */
818
+ introspectAsText(sectionOrDepth?: IntrospectionSection | number, startHeadingDepth?: number): string {
819
+ let section: IntrospectionSection | undefined
820
+ let depth = 1
821
+
822
+ if (typeof sectionOrDepth === 'string') {
823
+ section = sectionOrDepth
824
+ depth = startHeadingDepth ?? 1
825
+ } else if (typeof sectionOrDepth === 'number') {
826
+ depth = sectionOrDepth
827
+ }
828
+
829
+ const data = this.introspect()
830
+ return presentContainerIntrospectionAsMarkdown(data, depth, section)
831
+ }
832
+
833
+ /** Returns JSON introspection data. */
834
+ introspectAsJSON(): ContainerIntrospection {
835
+ return this.introspect()
836
+ }
837
+
838
+ /**
839
+ * Returns the container's introspection data formatted as a TypeScript interface declaration.
840
+ * Includes the container's own methods, getters, factories, and registered helper types.
841
+ *
842
+ * @example
843
+ * ```ts
844
+ * console.log(container.introspectAsType())
845
+ * // interface NodeContainer {
846
+ * // feature<T>(id: string, options?: object): T;
847
+ * // readonly uuid: string;
848
+ * // ...
849
+ * // }
850
+ * ```
851
+ */
852
+ introspectAsType(): string {
853
+ const data = this.introspect()
854
+ return presentContainerIntrospectionAsTypeScript(data)
855
+ }
856
+
857
+ /** Make a property non-enumerable, which is nice for inspecting it in the REPL */
858
+ _hide(...propNames: string[]) {
859
+ propNames.map((propName) => {
860
+ Object.defineProperty(this, propName, { enumerable: false })
861
+ })
862
+
863
+ return this
864
+ }
865
+
866
+ /** Sleep for the specified number of milliseconds. Useful for scripting and sequencing. */
867
+ async sleep(ms: number = 1000): Promise<this> {
868
+ await new Promise((res) => setTimeout(res,ms))
869
+ return this
870
+ }
871
+
872
+ _plugins: (() => void)[] = []
873
+
874
+ /**
875
+ * Apply a plugin or enable a feature by string name. Plugins are classes with a static `attach(container)` method
876
+ * that extend the container with new registries, factories, or capabilities.
877
+ *
878
+ * @param plugin - A feature name string, or a class/object with a static attach method
879
+ * @param options - Options to pass to the plugin's attach method
880
+ * @returns The container instance (with the plugin's type merged in)
881
+ *
882
+ * @example
883
+ * ```ts
884
+ * // Enable a feature by name
885
+ * container.use('contentDb')
886
+ *
887
+ * // Attach a plugin class (e.g. Client, Server, or custom)
888
+ * container.use(Client) // registers the clients registry + client() factory
889
+ * container.use(Server) // registers the servers registry + server() factory
890
+ * ```
891
+ */
892
+ use<T = {}>(plugin: Extension<T>, options: any = {}) : this & T {
893
+ const container = this
894
+
895
+ if(typeof plugin === 'string' && features.has(plugin)) {
896
+ const featureId = plugin as keyof AvailableFeatures
897
+ this.feature(featureId, {
898
+ ...options,
899
+ enable: true
900
+ })
901
+ } else if (typeof plugin === 'string' && !features.has(plugin)) {
902
+ throw new Error(`Feature ${plugin} is not available.`)
903
+ } else if ((typeof plugin === 'object' || typeof plugin === 'function') && typeof plugin?.attach === 'function') {
904
+ // This is like using a Helper or Feature subclass which declares a static attach method
905
+ plugin.attach(container as this & T, options)
906
+ }
907
+
908
+ return this as (this & T)
909
+ }
910
+ }
911
+
912
+ const helperCache = new Map()
913
+ const entityCache = new Map()
914
+ const uuidCache = new Map<string, Helper>()
915
+ const featureIdToHelperCacheKeyMap= new Map()
916
+ const contextMap = new WeakMap()
917
+
918
+ function presentContainerIntrospectionAsMarkdown(data: ContainerIntrospection, startHeadingDepth: number = 1, section?: IntrospectionSection): string {
919
+ const sections: string[] = []
920
+ const heading = (level: number) => '#'.repeat(Math.max(1, startHeadingDepth + level - 1))
921
+
922
+ const shouldRender = (name: IntrospectionSection | string) => !section || section === name
923
+
924
+ if (!section) {
925
+ // Header
926
+ sections.push(`${heading(1)} ${data.className}\n\n${data.description || ''}`)
927
+
928
+ // Container Properties section — dynamic from getters data, not hardcoded
929
+ // (cwd, paths, manifest, argv, utils etc. come through as getters from the introspection scanner)
930
+
931
+ // Registries section
932
+ if (data.registries && data.registries.length > 0) {
933
+ sections.push(`${heading(2)} Registries`)
934
+
935
+ for (const reg of data.registries) {
936
+ sections.push(`${heading(3)} ${reg.name} (${reg.baseClass})`)
937
+ if (reg.available.length > 0) {
938
+ sections.push(reg.available.map(a => `- \`${a}\``).join('\n'))
939
+ } else {
940
+ sections.push('_No members registered_')
941
+ }
942
+ }
943
+ }
944
+
945
+ // Factories section
946
+ if (data.factories && data.factories.length > 0) {
947
+ sections.push(`${heading(2)} Factory Methods`)
948
+ sections.push(data.factories.map(f => `- \`${f}()\``).join('\n'))
949
+ }
950
+ }
951
+
952
+ // Methods section
953
+ if (shouldRender('methods') && data.methods && Object.keys(data.methods).length > 0) {
954
+ sections.push(`${heading(2)} Methods`)
955
+
956
+ for (const [methodName, methodInfo] of Object.entries(data.methods)) {
957
+ sections.push(`${heading(3)} ${methodName}`)
958
+
959
+ if (methodInfo.description) {
960
+ sections.push(methodInfo.description)
961
+ }
962
+
963
+ if (methodInfo.parameters && Object.keys(methodInfo.parameters).length > 0) {
964
+ const tableRows = [
965
+ `**Parameters:**`,
966
+ '',
967
+ `| Name | Type | Required | Description |`,
968
+ `|------|------|----------|-------------|`,
969
+ ]
970
+
971
+ for (const [paramName, paramInfo] of Object.entries(methodInfo.parameters)) {
972
+ const isRequired = methodInfo.required?.includes(paramName) ? '✓' : ''
973
+ tableRows.push(`| \`${paramName}\` | \`${paramInfo.type || 'any'}\` | ${isRequired} | ${paramInfo.description || ''} |`)
974
+
975
+ if (paramInfo.properties && Object.keys(paramInfo.properties).length > 0) {
976
+ tableRows.push('')
977
+ tableRows.push(`\`${paramInfo.type}\` properties:`)
978
+ tableRows.push('')
979
+ tableRows.push(`| Property | Type | Description |`)
980
+ tableRows.push(`|----------|------|-------------|`)
981
+
982
+ for (const [propName, propInfo] of Object.entries(paramInfo.properties)) {
983
+ tableRows.push(`| \`${propName}\` | \`${propInfo.type || 'any'}\` | ${propInfo.description || ''} |`)
984
+ }
985
+ }
986
+ }
987
+ sections.push(tableRows.join('\n'))
988
+ }
989
+
990
+ if (methodInfo.returns) {
991
+ sections.push(`**Returns:** \`${methodInfo.returns}\``)
992
+ }
993
+
994
+ if ((methodInfo as any).examples && (methodInfo as any).examples.length > 0) {
995
+ for (const example of (methodInfo as any).examples) {
996
+ if (example.title) {
997
+ sections.push(`**Example: ${example.title}**`)
998
+ }
999
+ sections.push(`\`\`\`${example.language || 'ts'}\n${example.code}\n\`\`\``)
1000
+ }
1001
+ }
1002
+
1003
+ sections.push('')
1004
+ }
1005
+ }
1006
+
1007
+ // Getters section
1008
+ if (shouldRender('getters') && data.getters && Object.keys(data.getters).length > 0) {
1009
+ const getterTableRows = [
1010
+ `${heading(2)} Getters`,
1011
+ '',
1012
+ `| Property | Type | Description |`,
1013
+ `|----------|------|-------------|`,
1014
+ ]
1015
+
1016
+ const gettersWithExamples: [string, any][] = []
1017
+
1018
+ for (const [getterName, getterInfo] of Object.entries(data.getters)) {
1019
+ // Truncate long descriptions in the table
1020
+ const desc = getterInfo.description || ''
1021
+ const shortDesc = desc.length > 120 ? desc.slice(0, 117) + '...' : desc
1022
+ getterTableRows.push(`| \`${getterName}\` | \`${getterInfo.returns || 'any'}\` | ${shortDesc} |`)
1023
+ if ((getterInfo as any).examples && (getterInfo as any).examples.length > 0) {
1024
+ gettersWithExamples.push([getterName, getterInfo])
1025
+ }
1026
+ }
1027
+ sections.push(getterTableRows.join('\n'))
1028
+
1029
+ // Render examples for getters that have them
1030
+ if (gettersWithExamples.length > 0) {
1031
+ for (const [getterName, getterInfo] of gettersWithExamples) {
1032
+ for (const example of (getterInfo as any).examples) {
1033
+ sections.push(`\`\`\`${example.language || 'ts'}\n${example.code}\n\`\`\``)
1034
+ }
1035
+ }
1036
+ }
1037
+ }
1038
+
1039
+ // Events section
1040
+ if (shouldRender('events') && data.events && Object.keys(data.events).length > 0) {
1041
+ sections.push(`${heading(2)} Events`)
1042
+
1043
+ for (const [eventName, eventInfo] of Object.entries(data.events)) {
1044
+ sections.push(`${heading(3)} ${eventName}`)
1045
+
1046
+ if (eventInfo.description) {
1047
+ sections.push(eventInfo.description)
1048
+ }
1049
+
1050
+ if (eventInfo.arguments && Object.keys(eventInfo.arguments).length > 0) {
1051
+ const tableRows = [
1052
+ `**Event Arguments:**`,
1053
+ '',
1054
+ `| Name | Type | Description |`,
1055
+ `|------|------|-------------|`,
1056
+ ]
1057
+
1058
+ for (const [argName, argInfo] of Object.entries(eventInfo.arguments)) {
1059
+ tableRows.push(`| \`${argName}\` | \`${argInfo.type || 'any'}\` | ${argInfo.description || ''} |`)
1060
+ }
1061
+ sections.push(tableRows.join('\n'))
1062
+ }
1063
+
1064
+ sections.push('')
1065
+ }
1066
+ }
1067
+
1068
+ // State section
1069
+ if (shouldRender('state') && data.state && Object.keys(data.state).length > 0) {
1070
+ const stateTableRows = [
1071
+ `${heading(2)} State`,
1072
+ '',
1073
+ `| Property | Type | Description |`,
1074
+ `|----------|------|-------------|`,
1075
+ ]
1076
+
1077
+ for (const [stateName, stateInfo] of Object.entries(data.state)) {
1078
+ stateTableRows.push(`| \`${stateName}\` | \`${stateInfo.type || 'any'}\` | ${stateInfo.description || ''} |`)
1079
+ }
1080
+ sections.push(stateTableRows.join('\n'))
1081
+ }
1082
+
1083
+ if (!section) {
1084
+ // Enabled features section
1085
+ if (data.enabledFeatures && data.enabledFeatures.length > 0) {
1086
+ sections.push(`${heading(2)} Enabled Features`)
1087
+ sections.push(data.enabledFeatures.map(f => `- \`${f}\``).join('\n'))
1088
+ }
1089
+
1090
+ // Environment section
1091
+ if (data.environment) {
1092
+ const envTableRows = [
1093
+ `${heading(2)} Environment`,
1094
+ '',
1095
+ `| Flag | Value |`,
1096
+ `|------|-------|`,
1097
+ ]
1098
+ for (const [key, value] of Object.entries(data.environment)) {
1099
+ envTableRows.push(`| \`${key}\` | ${value} |`)
1100
+ }
1101
+ sections.push(envTableRows.join('\n'))
1102
+ }
1103
+ }
1104
+
1105
+ return sections.join('\n\n')
1106
+ }
1107
+
1108
+ function presentContainerIntrospectionAsTypeScript(data: ContainerIntrospection): string {
1109
+ const members: string[] = []
1110
+
1111
+ // Getters
1112
+ if (data.getters && Object.keys(data.getters).length > 0) {
1113
+ for (const [name, info] of Object.entries(data.getters)) {
1114
+ if (info.description) {
1115
+ members.push(` /** ${info.description} */`)
1116
+ }
1117
+ members.push(` readonly ${name}: ${normalizeTypeString(info.returns || 'any')};`)
1118
+ }
1119
+ }
1120
+
1121
+ // Methods
1122
+ if (data.methods && Object.keys(data.methods).length > 0) {
1123
+ if (members.length > 0) members.push('')
1124
+ for (const [name, info] of Object.entries(data.methods)) {
1125
+ if (info.description) {
1126
+ members.push(` /** ${info.description} */`)
1127
+ }
1128
+ const params = renderTypeScriptParams(info)
1129
+ members.push(` ${name}(${params}): ${normalizeTypeString(info.returns || 'void')};`)
1130
+ }
1131
+ }
1132
+
1133
+ // Factory methods
1134
+ if (data.factories && data.factories.length > 0) {
1135
+ if (members.length > 0) members.push('')
1136
+ members.push(' // Factory methods')
1137
+ for (const factory of data.factories) {
1138
+ members.push(` ${factory}(id: string, options?: Record<string, any>): any;`)
1139
+ }
1140
+ }
1141
+
1142
+ // Registries
1143
+ if (data.registries && data.registries.length > 0) {
1144
+ if (members.length > 0) members.push('')
1145
+ members.push(' // Registries')
1146
+ for (const reg of data.registries) {
1147
+ const available = reg.available.length > 0
1148
+ ? reg.available.map(a => `'${a}'`).join(' | ')
1149
+ : 'string'
1150
+ members.push(` readonly ${reg.name}: { available: (${available})[]; lookup(id: string): any; };`)
1151
+ }
1152
+ }
1153
+
1154
+ // Events — as on() overloads
1155
+ if (data.events && Object.keys(data.events).length > 0) {
1156
+ if (members.length > 0) members.push('')
1157
+ for (const [eventName, eventInfo] of Object.entries(data.events)) {
1158
+ const args = Object.entries(eventInfo.arguments || {})
1159
+ const listenerParams = args.length > 0
1160
+ ? args.map(([argName, argInfo]) => `${argName}: ${normalizeTypeString(argInfo.type || 'any')}`).join(', ')
1161
+ : ''
1162
+ if (eventInfo.description) {
1163
+ members.push(` /** ${eventInfo.description} */`)
1164
+ }
1165
+ members.push(` on(event: '${eventName}', listener: (${listenerParams}) => void): this;`)
1166
+ }
1167
+ }
1168
+
1169
+ // State
1170
+ if (data.state && Object.keys(data.state).length > 0) {
1171
+ if (members.length > 0) members.push('')
1172
+ const stateMembers = Object.entries(data.state)
1173
+ .map(([name, info]) => {
1174
+ const comment = info.description ? ` /** ${info.description} */\n` : ''
1175
+ return `${comment} ${name}: ${normalizeTypeString(info.type || 'any')};`
1176
+ })
1177
+ .join('\n')
1178
+ members.push(` state: {\n${stateMembers}\n };`)
1179
+ }
1180
+
1181
+ const description = data.description
1182
+ ? `/**\n * ${data.description.split('\n').join('\n * ')}\n */\n`
1183
+ : ''
1184
+
1185
+ return `${description}interface ${data.className} {\n${members.join('\n')}\n}`
1186
+ }