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,46 @@
1
+ import { scaffolds } from './generated.js'
2
+
3
+ /** Convert a string to PascalCase */
4
+ export function toPascalCase(str: string): string {
5
+ return str
6
+ .replace(/[-_\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ''))
7
+ .replace(/^(.)/, (_, c) => c.toUpperCase())
8
+ }
9
+
10
+ /** Convert a string to camelCase */
11
+ export function toCamelCase(str: string): string {
12
+ const pascal = toPascalCase(str)
13
+ return pascal.charAt(0).toLowerCase() + pascal.slice(1)
14
+ }
15
+
16
+ /** Convert a string to kebab-case */
17
+ export function toKebabCase(str: string): string {
18
+ return str
19
+ .replace(/([a-z])([A-Z])/g, '$1-$2')
20
+ .replace(/[_\s]+/g, '-')
21
+ .toLowerCase()
22
+ }
23
+
24
+ /** Apply mustache-style template variables to scaffold code */
25
+ export function applyTemplate(template: string, vars: Record<string, string>): string {
26
+ let result = template
27
+ for (const [key, value] of Object.entries(vars)) {
28
+ result = result.replace(new RegExp(`\\{\\{${key}\\}\\}`, 'g'), value)
29
+ }
30
+ return result
31
+ }
32
+
33
+ /** Generate scaffolded code for a given helper type */
34
+ export function generateScaffold(type: string, name: string, description?: string): string | null {
35
+ const scaffold = scaffolds[type]
36
+ if (!scaffold?.full) return null
37
+
38
+ const vars = {
39
+ PascalName: toPascalCase(name),
40
+ camelName: toCamelCase(name),
41
+ kebabName: toKebabCase(name),
42
+ description: description || `A ${type} that does something useful`,
43
+ }
44
+
45
+ return applyTemplate(scaffold.full, vars)
46
+ }
@@ -0,0 +1,296 @@
1
+ import { z } from 'zod'
2
+
3
+ // Base helper schemas — looseObject allows additional properties so subclass
4
+ // state types can structurally extend the base via z.infer<>
5
+ export const HelperStateSchema = z.looseObject({}).describe('Base state for all helpers')
6
+
7
+ export const HelperOptionsSchema = z.object({
8
+ name: z.string().optional().describe('Optional name identifier for this helper instance'),
9
+ _cacheKey: z.string().optional().describe('Internal cache key used for instance deduplication'),
10
+ }).describe('Base options for all helpers')
11
+
12
+ // Type inference utilities
13
+ export type InferState<T extends z.ZodType> = z.infer<T>
14
+ export type InferOptions<T extends z.ZodType> = z.infer<T>
15
+
16
+ /**
17
+ * Infer an EventMap from an events schema where each key is an event name
18
+ * and each value is a z.tuple() describing the listener arguments.
19
+ *
20
+ * e.g. z.object({ ready: z.tuple([]), message: z.tuple([z.string()]) })
21
+ * => { ready: [], message: [string] }
22
+ */
23
+ export type InferEvents<T extends z.ZodType> = z.infer<T> extends infer E
24
+ ? { [K in keyof E]: E[K] extends any[] ? E[K] : any[] }
25
+ : Record<string, any[]>
26
+
27
+ // Schema composition helpers
28
+ export const createHelperSchemas = <
29
+ StateSchema extends z.ZodType,
30
+ OptionsSchema extends z.ZodType
31
+ >(
32
+ stateSchema: StateSchema,
33
+ optionsSchema: OptionsSchema
34
+ ) => ({
35
+ state: stateSchema,
36
+ options: optionsSchema,
37
+ types: {} as {
38
+ State: InferState<StateSchema>
39
+ Options: InferOptions<OptionsSchema>
40
+ }
41
+ })
42
+
43
+ // Container state schema
44
+ export const ContainerStateSchema = z.object({
45
+ started: z.boolean().default(false).describe('Whether the container has been started'),
46
+ enabledFeatures: z.array(z.string()).describe('List of currently enabled feature shortcut IDs'),
47
+ registries: z.array(z.string()).describe('Names of attached registries (e.g. features, clients, servers)'),
48
+ factories: z.array(z.string()).describe('Names of available factory methods (e.g. feature, client, server)'),
49
+ }).describe('Core container state')
50
+
51
+ // Base schemas for common types
52
+ export const FeatureStateSchema = HelperStateSchema.extend({
53
+ enabled: z.boolean().default(false).describe('Whether this feature is currently enabled'),
54
+ }).describe('Base feature state with enabled flag')
55
+
56
+ export const FeatureOptionsSchema = HelperOptionsSchema.extend({
57
+ cached: z.boolean().optional().describe('Whether to cache this feature instance'),
58
+ enable: z.boolean().optional().describe('Whether to automatically enable the feature on creation'),
59
+ }).describe('Base feature options with cached and enable flags')
60
+
61
+ export const ClientStateSchema = HelperStateSchema.extend({
62
+ connected: z.boolean().default(false).describe('Whether the client is currently connected'),
63
+ }).describe('Base client state with connection status')
64
+
65
+ export const ClientOptionsSchema = HelperOptionsSchema.extend({
66
+ baseURL: z.string().optional().describe('Base URL for the client connection'),
67
+ json: z.boolean().optional().describe('Whether to automatically parse responses as JSON'),
68
+ }).describe('Base client options with connection settings')
69
+
70
+ export const ServerStateSchema = HelperStateSchema.extend({
71
+ port: z.number().optional().describe('The port the server is bound to'),
72
+ listening: z.boolean().default(false).describe('Whether the server is actively listening for connections'),
73
+ configured: z.boolean().default(false).describe('Whether the server has been configured'),
74
+ stopped: z.boolean().default(false).describe('Whether the server has been stopped'),
75
+ }).describe('Base server state with port and status information')
76
+
77
+ export const ServerOptionsSchema = HelperOptionsSchema.extend({
78
+ port: z.number().positive().optional().describe('Port number to listen on'),
79
+ host: z.string().optional().describe('Hostname or IP address to bind to'),
80
+ }).describe('Base server options with port and host settings')
81
+
82
+ // Events schemas — each key is an event name, value is z.tuple() of listener args
83
+ export const HelperEventsSchema = z.object({
84
+ stateChange: z.tuple([z.any().describe('The current state object')]),
85
+ }).describe('Base events for all helpers')
86
+
87
+ export const FeatureEventsSchema = HelperEventsSchema.extend({
88
+ enabled: z.tuple([]).describe('Emitted when the feature is enabled'),
89
+ }).describe('Base feature events')
90
+
91
+ export const ClientEventsSchema = HelperEventsSchema.extend({
92
+ failure: z.tuple([z.any().describe('The error object')]).describe('Emitted when a request fails'),
93
+ }).describe('Base client events')
94
+
95
+ // WebSocket client schemas
96
+ export const WebSocketClientStateSchema = ClientStateSchema.extend({
97
+ connectionError: z.any().optional().describe('The last connection error, if any'),
98
+ reconnectAttempts: z.number().default(0).describe('Number of reconnection attempts made'),
99
+ }).describe('WebSocket client state with connection error and reconnect tracking')
100
+
101
+ export const WebSocketClientOptionsSchema = ClientOptionsSchema.extend({
102
+ reconnect: z.boolean().optional().describe('Whether to automatically reconnect on disconnection'),
103
+ reconnectInterval: z.number().optional().describe('Base interval in milliseconds between reconnection attempts'),
104
+ maxReconnectAttempts: z.number().optional().describe('Maximum number of reconnection attempts before giving up'),
105
+ }).describe('WebSocket client options with reconnection settings')
106
+
107
+ export const WebSocketClientEventsSchema = ClientEventsSchema.extend({
108
+ message: z.tuple([z.any().describe('The parsed message data')]).describe('Emitted when a message is received'),
109
+ open: z.tuple([]).describe('Emitted when the WebSocket connection is established'),
110
+ close: z.tuple([z.number().optional().describe('Close code'), z.string().optional().describe('Close reason')]).describe('Emitted when the WebSocket connection is closed'),
111
+ error: z.tuple([z.any().describe('The error')]).describe('Emitted when a WebSocket error occurs'),
112
+ reconnecting: z.tuple([z.number().describe('Attempt number')]).describe('Emitted when attempting to reconnect'),
113
+ }).describe('WebSocket client events')
114
+
115
+ // GraphQL client schemas
116
+ export const GraphClientOptionsSchema = ClientOptionsSchema.extend({
117
+ endpoint: z.string().optional().describe('The GraphQL endpoint path, defaults to /graphql'),
118
+ }).describe('GraphQL client options')
119
+
120
+ export const GraphClientEventsSchema = ClientEventsSchema.extend({
121
+ graphqlError: z.tuple([z.array(z.any()).describe('Array of GraphQL errors')]).describe('Emitted when GraphQL-level errors are present in the response'),
122
+ }).describe('GraphQL client events')
123
+
124
+ export const ServerEventsSchema = HelperEventsSchema.extend({}).describe('Base server events')
125
+
126
+ // MCP Server schemas
127
+ export const MCPServerOptionsSchema = ServerOptionsSchema.extend({
128
+ transport: z.enum(['stdio', 'http']).optional().describe('Transport type for MCP communication'),
129
+ serverName: z.string().optional().describe('Server name reported to MCP clients'),
130
+ serverVersion: z.string().optional().describe('Server version reported to MCP clients'),
131
+ mcpCompat: z.enum(['standard', 'codex']).optional().describe('HTTP compatibility profile for MCP clients'),
132
+ stdioCompat: z.enum(['standard', 'codex', 'auto']).optional().describe('Stdio framing compatibility profile for MCP clients'),
133
+ }).describe('MCP server options')
134
+
135
+ export const MCPServerStateSchema = ServerStateSchema.extend({
136
+ transport: z.string().optional().describe('Active transport type'),
137
+ toolCount: z.number().default(0).describe('Number of registered tools'),
138
+ resourceCount: z.number().default(0).describe('Number of registered resources'),
139
+ promptCount: z.number().default(0).describe('Number of registered prompts'),
140
+ }).describe('MCP server state with tool/resource/prompt counts')
141
+
142
+ export const MCPServerEventsSchema = ServerEventsSchema.extend({
143
+ toolRegistered: z.tuple([z.string().describe('Tool name')]).describe('Emitted when a tool is registered'),
144
+ resourceRegistered: z.tuple([z.string().describe('Resource URI')]).describe('Emitted when a resource is registered'),
145
+ promptRegistered: z.tuple([z.string().describe('Prompt name')]).describe('Emitted when a prompt is registered'),
146
+ toolCalled: z.tuple([z.string().describe('Tool name'), z.any().describe('Arguments')]).describe('Emitted when a tool is called'),
147
+ }).describe('MCP server events')
148
+
149
+ // Command schemas
150
+ export const CommandStateSchema = HelperStateSchema.extend({
151
+ running: z.boolean().default(false).describe('Whether the command is currently executing'),
152
+ exitCode: z.number().optional().describe('Exit code after command finishes'),
153
+ }).describe('Base command state')
154
+
155
+ export const CommandOptionsSchema = HelperOptionsSchema.extend({
156
+ _: z.array(z.string()).default([]).describe('Positional arguments from minimist'),
157
+ dispatchSource: z.enum(['cli', 'headless', 'mcp', 'rpc']).default('cli').describe('How this command was invoked — controls arg normalization and output capture'),
158
+ }).describe('Base command options parsed from argv')
159
+
160
+ export type DispatchSource = 'cli' | 'headless' | 'mcp' | 'rpc'
161
+
162
+ export interface CommandRunResult {
163
+ exitCode: number
164
+ stdout: string
165
+ stderr: string
166
+ }
167
+
168
+ export const CommandEventsSchema = HelperEventsSchema.extend({
169
+ started: z.tuple([]).describe('Emitted when command execution begins'),
170
+ completed: z.tuple([z.number().describe('Exit code')]).describe('Emitted when command execution finishes'),
171
+ failed: z.tuple([z.any().describe('The error')]).describe('Emitted when command execution fails'),
172
+ }).describe('Base command events')
173
+
174
+ // Selector schemas
175
+ export const SelectorStateSchema = HelperStateSchema.extend({
176
+ running: z.boolean().default(false).describe('Whether the selector is currently running'),
177
+ lastRanAt: z.number().optional().describe('Unix timestamp of last successful run'),
178
+ }).describe('Base selector state')
179
+
180
+ export const SelectorOptionsSchema = HelperOptionsSchema.extend({
181
+ dispatchSource: z.enum(['cli', 'headless', 'mcp', 'rpc']).default('headless').describe('How this selector was invoked'),
182
+ }).describe('Base selector options')
183
+
184
+ export interface SelectorRunResult<T = any> {
185
+ data: T
186
+ cached: boolean
187
+ cacheKey: string
188
+ }
189
+
190
+ export const SelectorEventsSchema = HelperEventsSchema.extend({
191
+ started: z.tuple([]).describe('Emitted when selector execution begins'),
192
+ completed: z.tuple([z.any().describe('The result data')]).describe('Emitted when selector execution finishes'),
193
+ failed: z.tuple([z.any().describe('The error')]).describe('Emitted when selector execution fails'),
194
+ }).describe('Base selector events')
195
+
196
+ // Endpoint schemas
197
+ export const EndpointStateSchema = HelperStateSchema.extend({
198
+ mounted: z.boolean().default(false).describe('Whether the endpoint is mounted on a server'),
199
+ path: z.string().default('').describe('The URL path this endpoint is served from'),
200
+ methods: z.array(z.string()).default([]).describe('HTTP methods this endpoint handles'),
201
+ requestCount: z.number().default(0).describe('Total number of requests handled'),
202
+ }).describe('Base endpoint state')
203
+
204
+ export const EndpointOptionsSchema = HelperOptionsSchema.extend({
205
+ path: z.string().describe('The URL path this endpoint is served from'),
206
+ filePath: z.string().optional().describe('Absolute path to the endpoint source file'),
207
+ }).describe('Base endpoint options')
208
+
209
+ export const EndpointEventsSchema = HelperEventsSchema.extend({
210
+ loaded: z.tuple([z.any().describe('The loaded endpoint module')]).describe('Emitted when the endpoint module is loaded'),
211
+ mounted: z.tuple([z.string().describe('The path')]).describe('Emitted when the endpoint is mounted on a server'),
212
+ request: z.tuple([z.string().describe('HTTP method'), z.string().describe('Path'), z.any().describe('Parameters')]).describe('Emitted on every request'),
213
+ error: z.tuple([z.any().describe('The error object')]).describe('Emitted when a request handler throws'),
214
+ }).describe('Base endpoint events')
215
+
216
+ /**
217
+ * Converts a ZodObject into an introspection-friendly record.
218
+ * Uses Zod v4's native toJSONSchema() and transforms properties
219
+ * into { fieldName: { type, description } } for the introspection system.
220
+ */
221
+ export function describeZodShape(schema: z.ZodType): Record<string, { type: string, description: string }> {
222
+ try {
223
+ const jsonSchema = (schema as any).toJSONSchema()
224
+ const properties = jsonSchema?.properties || {}
225
+ const result: Record<string, { type: string, description: string }> = {}
226
+
227
+ for (const [key, prop] of Object.entries(properties) as [string, any][]) {
228
+ result[key] = {
229
+ type: prop.type || 'any',
230
+ description: prop.description || ''
231
+ }
232
+ }
233
+
234
+ return result
235
+ } catch {
236
+ return {}
237
+ }
238
+ }
239
+
240
+ /**
241
+ * Converts an events ZodObject schema into introspection-friendly EventIntrospection records.
242
+ *
243
+ * Each top-level key is an event name, and its value should be a z.tuple() describing
244
+ * the positional arguments passed to listeners.
245
+ *
246
+ * Merges with existing build-time event data (e.g. descriptions from AST scanning)
247
+ * while adding argument type information from the Zod schema.
248
+ */
249
+ export function describeEventsSchema(
250
+ schema: z.ZodType,
251
+ existing: Record<string, { name: string, description: string, arguments: Record<string, { type: string, description: string }> }> = {}
252
+ ): Record<string, { name: string, description: string, arguments: Record<string, { type: string, description: string }> }> {
253
+ try {
254
+ const jsonSchema = (schema as any).toJSONSchema()
255
+ const properties = jsonSchema?.properties || {}
256
+ const result: Record<string, { name: string, description: string, arguments: Record<string, { type: string, description: string }> }> = { ...existing }
257
+
258
+ for (const [eventName, eventProp] of Object.entries(properties) as [string, any][]) {
259
+ const args: Record<string, { type: string, description: string }> = {}
260
+
261
+ // The event value is a tuple schema — its items describe positional args
262
+ const items = eventProp?.prefixItems || eventProp?.items
263
+ if (Array.isArray(items)) {
264
+ if (items.length === 1 && items[0].type === 'object' && items[0].properties) {
265
+ // Single object payload — expand its properties as named arguments
266
+ for (const [propName, propSchema] of Object.entries(items[0].properties) as [string, any][]) {
267
+ args[propName] = {
268
+ type: propSchema.enum ? propSchema.enum.map((v: any) => `'${v}'`).join(' | ') : (propSchema.type || 'any'),
269
+ description: propSchema.description || ''
270
+ }
271
+ }
272
+ } else {
273
+ items.forEach((item: any, index: number) => {
274
+ args[`arg${index}`] = {
275
+ type: item.type || 'any',
276
+ description: item.description || ''
277
+ }
278
+ })
279
+ }
280
+ }
281
+
282
+ result[eventName] = {
283
+ name: eventName,
284
+ description: eventProp.description || existing[eventName]?.description || `Event: ${eventName}`,
285
+ arguments: {
286
+ ...(existing[eventName]?.arguments || {}),
287
+ ...args
288
+ }
289
+ }
290
+ }
291
+
292
+ return result
293
+ } catch {
294
+ return existing
295
+ }
296
+ }
@@ -0,0 +1,352 @@
1
+ import { Helper } from './helper.js'
2
+ import type { Container, ContainerContext } from './container.js'
3
+ import { Registry } from './registry.js'
4
+ import { SelectorStateSchema, SelectorOptionsSchema, SelectorEventsSchema, type SelectorRunResult } from './schemas/base.js'
5
+ import { z } from 'zod'
6
+ import { join } from 'path'
7
+ import { graftModule, isNativeHelperClass } from './graft.js'
8
+
9
+ export type { SelectorRunResult }
10
+
11
+ export type SelectorState = z.infer<typeof SelectorStateSchema>
12
+ export type SelectorOptions = z.infer<typeof SelectorOptionsSchema>
13
+
14
+ export interface AvailableSelectors {}
15
+
16
+ export type SelectorFactory = <T extends keyof AvailableSelectors>(
17
+ key: T,
18
+ options?: ConstructorParameters<AvailableSelectors[T]>[0]
19
+ ) => NonNullable<InstanceType<AvailableSelectors[T]>>
20
+
21
+ export interface SelectorsInterface {
22
+ selectors: SelectorsRegistry
23
+ select: SelectorFactory
24
+ }
25
+
26
+ /**
27
+ * Type helper for module-augmentation of AvailableSelectors when using the
28
+ * module-based pattern.
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * declare module '@soederpop/luca' {
33
+ * interface AvailableSelectors {
34
+ * packageInfo: SimpleSelector<typeof argsSchema>
35
+ * }
36
+ * }
37
+ * ```
38
+ */
39
+ export type SimpleSelector<Schema extends z.ZodType = z.ZodType> = typeof Selector & {
40
+ argsSchema: Schema
41
+ }
42
+
43
+ /**
44
+ * A Selector is a helper that returns data. Where Commands perform actions,
45
+ * Selectors query and return structured results with built-in caching.
46
+ *
47
+ * Module authors export a `run(args, context)` function that returns data.
48
+ * The `select()` dispatch method wraps `run()` with cache check/store and
49
+ * returns `{ data, cached, cacheKey }`.
50
+ *
51
+ * Caching is on by default and keyed by `hashObject({ selectorName, args, gitSha })`.
52
+ * Export a `cacheKey(args, context)` function to customize, or set `cacheable = false`
53
+ * to disable.
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * // selectors/package-info.ts
58
+ * export const description = 'Returns parsed package.json data'
59
+ * export const argsSchema = z.object({ field: z.string().optional() })
60
+ *
61
+ * export function cacheKey(args, context) {
62
+ * return context.container.git.sha
63
+ * }
64
+ *
65
+ * export async function run(args, context) {
66
+ * const manifest = context.container.manifest
67
+ * return args.field ? manifest[args.field] : manifest
68
+ * }
69
+ * ```
70
+ */
71
+ export class Selector<
72
+ T extends SelectorState = SelectorState,
73
+ K extends SelectorOptions = SelectorOptions
74
+ > extends Helper<T, K> {
75
+ static override shortcut = 'selectors.base'
76
+ static override description = 'Base selector'
77
+ static override stateSchema = SelectorStateSchema
78
+ static override optionsSchema = SelectorOptionsSchema
79
+ static override eventsSchema = SelectorEventsSchema
80
+
81
+ static selectorDescription: string = ''
82
+ static argsSchema: z.ZodType = SelectorOptionsSchema
83
+ static cacheable: boolean = true
84
+
85
+ /** Self-register a Selector subclass from a static initialization block. */
86
+ static register: (SubClass: typeof Selector, id?: string) => typeof Selector
87
+
88
+ override get initialState(): T {
89
+ return ({ running: false } as unknown) as T
90
+ }
91
+
92
+ /**
93
+ * The user-defined selector payload. Override this in module-based selectors
94
+ * by exporting a `run` function.
95
+ *
96
+ * Receives validated args and the container context. Must return data.
97
+ */
98
+ async run(_args: any, _context: ContainerContext): Promise<any> {
99
+ // override via grafted module export
100
+ }
101
+
102
+ /**
103
+ * Compute the cache key for a given set of args.
104
+ * Override by exporting a `cacheKey(args, context)` function in the module.
105
+ *
106
+ * Default: hashObject({ selectorName, args, gitSha })
107
+ */
108
+ resolveCacheKey(args: any, _context: ContainerContext): string {
109
+ const name = (this.constructor as typeof Selector).shortcut || 'selector'
110
+ const gitSha = (this.container as any).git?.currentCommitSha ?? 'unknown'
111
+ return (this.container as any).utils.hashObject({ selectorName: name, args, gitSha })
112
+ }
113
+
114
+ /**
115
+ * The public dispatch method. Checks cache, calls run(), stores result.
116
+ *
117
+ * @returns `{ data, cached, cacheKey }` — the result and cache metadata
118
+ */
119
+ async select(args?: Record<string, any>): Promise<SelectorRunResult> {
120
+ const Cls = this.constructor as typeof Selector
121
+ const parsed = Cls.argsSchema.parse(args ?? {})
122
+ const resolvedCacheKey = this.resolveCacheKey(parsed, this.context)
123
+
124
+ // Cache check
125
+ if (Cls.cacheable) {
126
+ try {
127
+ const cache = this._getCache()
128
+ if (await cache.has(resolvedCacheKey)) {
129
+ const data = await cache.get(resolvedCacheKey, true)
130
+ return { data, cached: true, cacheKey: resolvedCacheKey }
131
+ }
132
+ } catch {
133
+ // Cache miss or unavailable — proceed to run
134
+ }
135
+ }
136
+
137
+ // Run the selector
138
+ this.state.set('running' as any, true as any)
139
+ this.emit('started' as any)
140
+
141
+ let data: any
142
+ try {
143
+ data = await this.run(parsed, this.context)
144
+ this.state.set('running' as any, false as any)
145
+ this.state.set('lastRanAt' as any, Date.now() as any)
146
+ this.emit('completed' as any, data)
147
+ } catch (err: any) {
148
+ this.state.set('running' as any, false as any)
149
+ this.emit('failed' as any, err)
150
+ throw err
151
+ }
152
+
153
+ // Cache store
154
+ if (Cls.cacheable) {
155
+ try {
156
+ await this._getCache().set(resolvedCacheKey, data)
157
+ } catch {
158
+ // Cache write failure is non-fatal
159
+ }
160
+ }
161
+
162
+ return { data, cached: false, cacheKey: resolvedCacheKey }
163
+ }
164
+
165
+ /** Lazily access diskCache. */
166
+ private _getCache(): any {
167
+ return (this.container as any).feature('diskCache', { enable: true })
168
+ }
169
+
170
+ static attach(container: Container<any> & SelectorsInterface) {
171
+ container.selectors = selectors
172
+
173
+ Object.assign(container, {
174
+ select<T extends keyof AvailableSelectors>(
175
+ id: T,
176
+ options?: ConstructorParameters<AvailableSelectors[T]>[0]
177
+ ): NonNullable<InstanceType<AvailableSelectors[T]>> {
178
+ const BaseClass = selectors.lookup(id as string) as any
179
+
180
+ return container.createHelperInstance({
181
+ cache: selectorHelperCache,
182
+ type: 'selector',
183
+ id: String(id),
184
+ BaseClass,
185
+ options,
186
+ fallbackName: String(id),
187
+ }) as NonNullable<InstanceType<AvailableSelectors[T]>>
188
+ },
189
+ })
190
+
191
+ container.registerHelperType('selectors', 'select')
192
+ return container
193
+ }
194
+ }
195
+
196
+ export class SelectorsRegistry extends Registry<Selector<any>> {
197
+ override scope = 'selectors'
198
+ override baseClass = Selector as any
199
+
200
+ /**
201
+ * Convert all registered selectors into a `{ schemas, handlers }` object
202
+ * compatible with `assistant.use()`.
203
+ *
204
+ * Each selector becomes a tool whose parameters come from the selector's
205
+ * `argsSchema` (with internal fields stripped) and whose handler dispatches
206
+ * the selector and returns the data directly (cache metadata is not exposed).
207
+ *
208
+ * @param container - The container used to instantiate and run selectors
209
+ * @param options - Optional filter/transform options
210
+ * @param options.include - Only include these selector names (default: all)
211
+ * @param options.exclude - Exclude these selector names (default: none)
212
+ * @param options.prefix - Prefix tool names (e.g. 'sel_' → 'sel_packageInfo')
213
+ */
214
+ toTools(
215
+ container: Container<any> & SelectorsInterface,
216
+ options?: { include?: string[], exclude?: string[], prefix?: string },
217
+ ): { schemas: Record<string, z.ZodType>, handlers: Record<string, Function> } {
218
+ const schemas: Record<string, z.ZodType> = {}
219
+ const handlers: Record<string, Function> = {}
220
+ const prefix = options?.prefix ?? ''
221
+ const includeSet = options?.include ? new Set(options.include) : null
222
+ const excludeSet = new Set(options?.exclude ?? [])
223
+
224
+ // Internal fields from HelperOptionsSchema and SelectorOptionsSchema
225
+ const internalFields = ['name', '_cacheKey', 'dispatchSource']
226
+
227
+ for (const name of this.available) {
228
+ if (excludeSet.has(name)) continue
229
+ if (includeSet && !includeSet.has(name)) continue
230
+
231
+ const Sel = this.lookup(name) as typeof Selector
232
+ const rawSchema = Sel.argsSchema
233
+ const description = Sel.selectorDescription || Sel.description || name
234
+
235
+ let toolSchema: z.ZodType
236
+ try {
237
+ const shape = typeof (rawSchema as any)?._def?.shape === 'function'
238
+ ? (rawSchema as any)._def.shape()
239
+ : (rawSchema as any)?._def?.shape
240
+
241
+ if (shape) {
242
+ const cleanShape: Record<string, z.ZodType> = {}
243
+ for (const [key, val] of Object.entries(shape)) {
244
+ if (internalFields.includes(key)) continue
245
+ cleanShape[key] = val as z.ZodType
246
+ }
247
+
248
+ toolSchema = Object.keys(cleanShape).length > 0
249
+ ? z.object(cleanShape).describe(description)
250
+ : z.object({}).describe(description)
251
+ } else {
252
+ toolSchema = z.object({}).describe(description)
253
+ }
254
+ } catch {
255
+ toolSchema = z.object({}).describe(description)
256
+ }
257
+
258
+ const toolName = `${prefix}${name}`
259
+ schemas[toolName] = toolSchema
260
+ handlers[toolName] = async (args: Record<string, any>) => {
261
+ const sel = (container.select as any)(name)
262
+ const result = await sel.select(args ?? {})
263
+ return result.data
264
+ }
265
+ }
266
+
267
+ return { schemas, handlers }
268
+ }
269
+
270
+ /**
271
+ * Discover and register selectors from a directory.
272
+ * Detection order:
273
+ * 1. Default export is a class extending Selector -> register directly
274
+ * 2. Module exports a `run` function -> graft as SimpleSelector
275
+ */
276
+ async discover(options: { directory: string }) {
277
+ const { Glob } = globalThis.Bun || (await import('bun'))
278
+ const glob = new Glob('*.ts')
279
+
280
+ for await (const file of glob.scan({ cwd: options.directory })) {
281
+ if (file === 'index.ts') continue
282
+
283
+ const name = file.replace(/\.ts$/, '')
284
+ if (this.has(name)) continue
285
+
286
+ const mod = await import(join(options.directory, file))
287
+
288
+ // 1. Class-based: default export extends Selector
289
+ if (isNativeHelperClass(mod.default, Selector)) {
290
+ const ExportedClass = mod.default
291
+ if (!ExportedClass.shortcut || ExportedClass.shortcut === 'selectors.base') {
292
+ ExportedClass.shortcut = `selectors.${name}`
293
+ }
294
+ this.register(name, ExportedClass)
295
+ continue
296
+ }
297
+
298
+ const selectorModule = mod.default || mod
299
+
300
+ // 2. Module-based with `run` export
301
+ if (typeof selectorModule.run === 'function') {
302
+ const Grafted = graftModule(Selector as any, selectorModule, name, 'selectors')
303
+ this.register(name, Grafted as any)
304
+ }
305
+ }
306
+ }
307
+ }
308
+
309
+ export const selectors = new SelectorsRegistry()
310
+ export const selectorHelperCache = new Map()
311
+
312
+ /**
313
+ * Self-register a Selector subclass from a static initialization block.
314
+ *
315
+ * @example
316
+ * ```typescript
317
+ * export class PackageInfoSelector extends Selector {
318
+ * static override description = 'Returns parsed package.json data'
319
+ * static { Selector.register(this, 'packageInfo') }
320
+ *
321
+ * override async run(args, context) { return context.container.manifest }
322
+ * }
323
+ * ```
324
+ */
325
+ Selector.register = function registerSelector(
326
+ SubClass: typeof Selector,
327
+ id?: string,
328
+ ) {
329
+ const registryId = id ?? (SubClass.name
330
+ ? SubClass.name[0]!.toLowerCase() + SubClass.name.slice(1).replace(/Selector$/, '')
331
+ : `selector_${Date.now()}`)
332
+
333
+ if (!Object.getOwnPropertyDescriptor(SubClass, 'shortcut')?.value ||
334
+ (SubClass as any).shortcut === 'selectors.base') {
335
+ ;(SubClass as any).shortcut = `selectors.${registryId}`
336
+ }
337
+
338
+ selectors.register(registryId, SubClass as any)
339
+
340
+ if (!Object.getOwnPropertyDescriptor(SubClass, 'attach')) {
341
+ ;(SubClass as any).attach = (container: any) => {
342
+ selectors.register(registryId, SubClass as any)
343
+ return container
344
+ }
345
+ }
346
+
347
+ return SubClass
348
+ }
349
+
350
+ export { graftModule, isNativeHelperClass } from './graft.js'
351
+
352
+ export default Selector