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,478 @@
1
+ import { z } from 'zod'
2
+ import { FeatureStateSchema, FeatureOptionsSchema, FeatureEventsSchema } from '../../schemas/base.js'
3
+ import { type AvailableFeatures } from '@soederpop/luca/feature'
4
+ import { Feature } from '../feature.js'
5
+ import { parse } from 'contentbase'
6
+ import type { DocsReader } from './docs-reader.js'
7
+ import Assistant from './assistant.js'
8
+
9
+ declare module '@soederpop/luca/feature' {
10
+ interface AvailableFeatures {
11
+ skillsLibrary: typeof SkillsLibrary
12
+ }
13
+ }
14
+
15
+ export interface SkillInfo {
16
+ /** Skill name derived from folder name or frontmatter */
17
+ name: string
18
+ /** Description from frontmatter */
19
+ description: string
20
+ /** Absolute path to the skill folder (dirname of SKILL.md) */
21
+ path: string
22
+ /** Absolute path to SKILL.md */
23
+ skillFilePath: string
24
+ /** Which location this skill was found in */
25
+ locationPath: string
26
+ /** All frontmatter metadata */
27
+ meta: Record<string, unknown>
28
+ }
29
+
30
+ export const SkillsLibraryStateSchema = FeatureStateSchema.extend({
31
+ loaded: z.boolean().describe('Whether skill locations have been scanned'),
32
+ locations: z.array(z.string()).describe('Tracked skill location folder paths'),
33
+ skillCount: z.number().describe('Total number of discovered skills'),
34
+ skills: z.record(z.string(), z.any()).describe('Discovered skills keyed by name'),
35
+ })
36
+
37
+ export const SkillsLibraryOptionsSchema = FeatureOptionsSchema.extend({
38
+ configPath: z.string().optional().describe('Override path for skills.json (defaults to ~/.luca/skills.json)'),
39
+ })
40
+
41
+ export const SkillsLibraryEventsSchema = FeatureEventsSchema.extend({
42
+ started: z.tuple([]).describe('Fired after all skill locations have been scanned'),
43
+ locationAdded: z.tuple([z.string().describe('The absolute path of the added location')]).describe('Fired when a new skill location is registered'),
44
+ skillDiscovered: z.tuple([z.any().describe('The SkillInfo object')]).describe('Fired when a skill is discovered during scanning'),
45
+ }).describe('SkillsLibrary events')
46
+
47
+ export type SkillsLibraryState = z.infer<typeof SkillsLibraryStateSchema>
48
+ export type SkillsLibraryOptions = z.infer<typeof SkillsLibraryOptionsSchema>
49
+
50
+ /**
51
+ * Manages a registry of skill locations — folders containing SKILL.md files.
52
+ *
53
+ * Persists known locations to ~/.luca/skills.json and scans them on start.
54
+ * Each skill folder can be opened as a DocsReader for AI-assisted Q&A.
55
+ * Exposes tools for assistant integration via assistant.use(skillsLibrary).
56
+ *
57
+ * @extends Feature
58
+ * @example
59
+ * ```typescript
60
+ * const lib = container.feature('skillsLibrary')
61
+ * await lib.start()
62
+ * await lib.addLocation('~/.claude/skills')
63
+ * lib.list() // => SkillInfo[]
64
+ * const reader = lib.createSkillReader('my-skill')
65
+ * ```
66
+ */
67
+ export class SkillsLibrary extends Feature<SkillsLibraryState, SkillsLibraryOptions> {
68
+ static override stateSchema = SkillsLibraryStateSchema
69
+ static override optionsSchema = SkillsLibraryOptionsSchema
70
+ static override eventsSchema = SkillsLibraryEventsSchema
71
+ static override shortcut = 'features.skillsLibrary' as const
72
+
73
+ static { Feature.register(this, 'skillsLibrary') }
74
+
75
+ /** Tools for assistant integration via assistant.use(skillsLibrary). */
76
+ static override tools: Record<string, { schema: z.ZodType; handler?: Function }> = {
77
+ searchAvailableSkills: {
78
+ schema: z.object({
79
+ query: z.string().optional().describe('A keyword or phrase to filter skills by name or description. Omit to list all available skills.'),
80
+ }).describe('Discover what skills are available. Call this first when you need specialized knowledge — skills are curated guides and reference material for specific domains (frameworks, tools, patterns). Returns skill names and descriptions so you can decide which to load.'),
81
+ },
82
+ loadSkill: {
83
+ schema: z.object({
84
+ skillName: z.string().describe('The exact skill name as returned by searchAvailableSkills'),
85
+ }).describe('Load a skill\'s full reference content (SKILL.md). This gives you detailed guidance, examples, and best practices for that domain. Load a skill before attempting work in an unfamiliar area — the content is curated to prevent common mistakes.'),
86
+ },
87
+ askSkillBasedQuestion: {
88
+ schema: z.object({
89
+ skillName: z.string().describe('The exact skill name to query'),
90
+ question: z.string().describe('A specific question about the skill\'s domain. Be precise — "how do I add a new feature to the container?" is better than "tell me about features".'),
91
+ }).describe('Ask a focused question about a skill\'s domain using AI-assisted document reading. Use this when you need a specific answer from a skill rather than reading the whole thing. More efficient than loadSkill for targeted lookups.'),
92
+ },
93
+ }
94
+
95
+ /** @returns Default state. */
96
+ override get initialState(): SkillsLibraryState {
97
+ return {
98
+ ...super.initialState,
99
+ started: false,
100
+ locations: [],
101
+ skillCount: 0,
102
+ skills: {},
103
+ }
104
+ }
105
+
106
+ override setupToolsConsumer(assistant: Feature) {
107
+ if (!(assistant instanceof Assistant)) {
108
+ throw new Error('Skills library tools require an Assistant instance (including subclasses).')
109
+ }
110
+
111
+ const a : Assistant = assistant as Assistant
112
+
113
+ a.addSystemPromptExtension('skillsLibrary', [
114
+ '## Skills Library',
115
+ '',
116
+ 'You have access to a library of curated skills — domain-specific reference guides with examples, patterns, and best practices.',
117
+ '',
118
+ '**When to use skills:**',
119
+ '- When working in an unfamiliar domain or framework — load the skill before writing code',
120
+ '- When the user asks about a topic that might have a matching skill — search first',
121
+ '- When you see "Required Skills" in a message — load those skills immediately with `loadSkill` before answering',
122
+ '',
123
+ '**Workflow:** `searchAvailableSkills` → find relevant skill → `loadSkill` to get the full guide → follow its patterns. Use `askSkillBasedQuestion` for targeted lookups when you don\'t need the whole guide.',
124
+ '',
125
+ '**Skills are authoritative.** When a loaded skill contradicts your general knowledge, follow the skill — it reflects project-specific conventions and decisions.',
126
+ ].join('\n'))
127
+
128
+ const { container } = a
129
+
130
+ const skillsLibrary = this
131
+
132
+ const preloadSkills : string[] = []
133
+ if (a.meta.skills) {
134
+ if (Array.isArray(a.meta.skills)) {
135
+ preloadSkills.push(...a.meta.skills)
136
+ } else {
137
+ preloadSkills.push(a.meta.skills)
138
+ }
139
+ }
140
+
141
+ async function beforeAskCheckIfWeNeedSkills(ctx: any, next: any) {
142
+ const { question } = ctx
143
+ const skills = await skillsLibrary.findRelevantSkillsForAssistant(a, question as string)
144
+
145
+ const allSkillsToLoad : string[] = container.utils.lodash.uniq([
146
+ ...skills,
147
+ ...preloadSkills,
148
+ ])
149
+
150
+ if (allSkillsToLoad.length) {
151
+ ctx.question = `${ctx.question} \n\n## Required Skills\nYou will need to load the following skills to answer this question: ${skills.join(', ')}`
152
+ }
153
+
154
+ a.interceptors.beforeAsk.remove(beforeAskCheckIfWeNeedSkills)
155
+
156
+ await next()
157
+ }
158
+
159
+ assistant.intercept('beforeAsk', beforeAskCheckIfWeNeedSkills as any)
160
+
161
+ return assistant
162
+ }
163
+
164
+ /** Discovered skills keyed by name. */
165
+ get skills(): Record<string, SkillInfo> {
166
+ return (this.state.get('skills') || {}) as Record<string, SkillInfo>
167
+ }
168
+
169
+ get availableSkills() {
170
+ return Object.keys(this.skills)
171
+ }
172
+
173
+ get skillsTable() : Record<string, string> {
174
+ const skills = this.skills
175
+
176
+ return Object.fromEntries(
177
+ Object.keys(skills).map((name) => [name, this.skills[name]!.description])
178
+ )
179
+ }
180
+
181
+ /** Resolved path to the skills.json config file. */
182
+ get configPath(): string {
183
+ if (this.options.configPath) return this.options.configPath
184
+ const { os, paths } = this.container
185
+ return paths.resolve(os.homedir, '.luca', 'skills.json')
186
+ }
187
+
188
+ /** Whether the library has been loaded. */
189
+ get isStarted(): boolean {
190
+ return !!this.state.get('started')
191
+ }
192
+
193
+ /** Expand ~ to home directory in a path. */
194
+ private expandHome(p: string): string {
195
+ return p.replace(/^\~/, this.container.os.homedir)
196
+ }
197
+
198
+ /** Read the persisted config, creating it if it doesn't exist. */
199
+ private readConfig(): { locations: string[] } {
200
+ const { fs } = this.container
201
+
202
+ if (!fs.exists(this.configPath)) {
203
+ const defaultConfig = { locations: [] as string[] }
204
+ this.writeConfig(defaultConfig)
205
+ return defaultConfig
206
+ }
207
+
208
+ return fs.readJson(this.configPath)
209
+ }
210
+
211
+ /** Write the config back to disk. */
212
+ private writeConfig(config: { locations: string[] }): void {
213
+ const { fs, os, paths } = this.container
214
+ fs.mkdirp(paths.resolve(os.homedir, '.luca'))
215
+ fs.writeJson(this.configPath, config, 2)
216
+ }
217
+
218
+ /**
219
+ * Start the skills library: read config, scan all locations.
220
+ *
221
+ * @returns This instance for chaining
222
+ */
223
+ async start(): Promise<SkillsLibrary> {
224
+ if (this.isStarted) return this
225
+
226
+ const { uniq } = this.container.utils.lodash
227
+ const config = this.readConfig()
228
+ const configLocations = config.locations.map(l => this.expandHome(l))
229
+ const allLocations = uniq([
230
+ ...configLocations,
231
+ (this.container as any).paths.resolve((this.container as any).os.homedir, '.claude', 'skills'),
232
+ (this.container as any).paths.resolve((this.container as any).cwd, '.claude', 'skills')
233
+ ]).filter(Boolean).filter(l => (this.container as any).fs.exists(l))
234
+ this.state.set('locations', allLocations)
235
+
236
+ for (const loc of allLocations) {
237
+ await this.scanLocation(loc)
238
+ }
239
+
240
+ this.state.set('started', true)
241
+ this.state.set('skillCount', Object.keys(this.skills).length)
242
+ this.emit('started')
243
+
244
+ return this
245
+ }
246
+
247
+ /**
248
+ * Add a new skill location folder and scan it for skills.
249
+ *
250
+ * @param locationPath - Path to a directory containing skill subfolders with SKILL.md
251
+ */
252
+ async addLocation(locationPath: string): Promise<void> {
253
+ const resolved = this.expandHome(locationPath)
254
+ const current = this.state.get('locations') as string[]
255
+
256
+ if (current.includes(resolved)) return
257
+
258
+ const updated = [...current, resolved]
259
+ this.state.set('locations', updated)
260
+
261
+ // Persist — store the original (unexpanded) path for portability
262
+ const config = this.readConfig()
263
+ if (!config.locations.includes(locationPath)) {
264
+ config.locations.push(locationPath)
265
+ this.writeConfig(config)
266
+ }
267
+
268
+ await this.scanLocation(resolved)
269
+ this.state.set('skillCount', Object.keys(this.skills).length)
270
+ this.emit('locationAdded', resolved)
271
+ }
272
+
273
+ /**
274
+ * Remove a skill location and its skills from the library.
275
+ *
276
+ * @param locationPath - The location path to remove
277
+ */
278
+ async removeLocation(locationPath: string): Promise<void> {
279
+ const resolved = this.expandHome(locationPath)
280
+ const current = this.state.get('locations') as string[]
281
+ this.state.set('locations', current.filter(l => l !== resolved))
282
+
283
+ // Remove skills from this location
284
+ const remaining: Record<string, SkillInfo> = {}
285
+ for (const [name, info] of Object.entries(this.skills)) {
286
+ if (info.locationPath !== resolved) {
287
+ remaining[name] = info
288
+ }
289
+ }
290
+ this.state.set('skills', remaining)
291
+ this.state.set('skillCount', Object.keys(remaining).length)
292
+
293
+ // Persist
294
+ const config = this.readConfig()
295
+ config.locations = config.locations.filter(l => this.expandHome(l) !== resolved)
296
+ this.writeConfig(config)
297
+ }
298
+
299
+ /**
300
+ * Scan a location folder for skill subfolders containing SKILL.md.
301
+ *
302
+ * @param locationPath - Absolute path to scan
303
+ */
304
+ async scanLocation(locationPath: string): Promise<void> {
305
+ const { fs, paths } = this.container
306
+ if (!fs.exists(locationPath)) return
307
+
308
+ const entries = fs.readdirSync(locationPath)
309
+
310
+ for (const entry of entries) {
311
+ const skillDir = paths.resolve(locationPath, entry)
312
+ const skillFile = paths.resolve(skillDir, 'SKILL.md')
313
+
314
+ if (!fs.exists(skillFile)) continue
315
+
316
+ try {
317
+ const parsed = await parse(skillFile)
318
+ const meta = (parsed.meta || {}) as Record<string, unknown>
319
+ const name = entry
320
+
321
+ const info: SkillInfo = {
322
+ name,
323
+ description: (meta.description as string) || '',
324
+ path: skillDir,
325
+ skillFilePath: skillFile,
326
+ locationPath,
327
+ meta,
328
+ }
329
+
330
+ this.state.set('skills', { ...this.skills, [name]: info })
331
+ this.emit('skillDiscovered', info)
332
+ } catch {
333
+ // Skip unparseable skill files
334
+ }
335
+ }
336
+ }
337
+
338
+ /** Return all discovered skills. */
339
+ list(): SkillInfo[] {
340
+ return Object.values(this.skills)
341
+ }
342
+
343
+ /** Find a skill by name. */
344
+ find(skillName: string): SkillInfo | undefined {
345
+ return this.skills[skillName]
346
+ }
347
+
348
+ /**
349
+ * Create a DocsReader for a skill's folder, enabling AI-assisted Q&A.
350
+ *
351
+ * @param skillName - Name of the skill to create a reader for
352
+ * @returns A DocsReader instance rooted at the skill's folder
353
+ */
354
+ createSkillReader(skillName: string): DocsReader {
355
+ const skill = this.find(skillName)
356
+ if (!skill) throw new Error(`Skill "${skillName}" not found in the library`)
357
+
358
+ return this.container.feature('docsReader', { contentDb: skill.path })
359
+ }
360
+
361
+ /**
362
+ * Create a tmp directory containing symlinked/copied skill folders by name,
363
+ * suitable for passing to claude --add-dir.
364
+ *
365
+ * @param skillNames - Array of skill names to include
366
+ * @returns Absolute path to the created directory
367
+ */
368
+ ensureFolderCreatedWithSkillsByName(skillNames: string[]): string {
369
+ const { fs, paths, os } = this.container
370
+ const hash = this.container.utils.hashObject(skillNames.sort())
371
+ const dir = paths.resolve(os.tmpdir, 'luca-skills', hash)
372
+
373
+ if (fs.exists(dir)) return dir
374
+
375
+ fs.mkdirp(dir)
376
+
377
+ for (const name of skillNames) {
378
+ const skill = this.find(name)
379
+ if (!skill) throw new Error(`Skill "${name}" not found in the library`)
380
+
381
+ const dest = paths.resolve(dir, name)
382
+ if (!fs.exists(dest)) {
383
+ fs.copy(skill.path, dest)
384
+ }
385
+ }
386
+
387
+ return dir
388
+ }
389
+
390
+ // --- Tool handlers for assistant.use(skillsLibrary) ---
391
+
392
+ /** Search available skills, optionally filtered by a query string. */
393
+ async searchAvailableSkills({ query }: { query?: string } = {}): Promise<string> {
394
+ if (!this.isStarted) await this.start()
395
+
396
+ let skills = this.list()
397
+
398
+ if (query) {
399
+ const q = query.toLowerCase()
400
+ skills = skills.filter(s =>
401
+ s.name.toLowerCase().includes(q) ||
402
+ s.description.toLowerCase().includes(q)
403
+ )
404
+ }
405
+
406
+ if (skills.length === 0) return 'No skills found.'
407
+
408
+ return skills.map(s => `- **${s.name}**: ${s.description || '(no description)'}\n Path: ${s.path}`).join('\n')
409
+ }
410
+
411
+ /** Load a skill's full SKILL.md content and metadata. */
412
+ async loadSkill({ skillName }: { skillName: string }): Promise<string> {
413
+ if (!this.isStarted) await this.start()
414
+
415
+ const skill = this.find(skillName)
416
+ if (!skill) return `Skill "${skillName}" not found.`
417
+
418
+ const content = this.container.fs.readFile(skill.skillFilePath)
419
+
420
+ return `# Skill: ${skill.name}\n\n**Description:** ${skill.description}\n**Path:** ${skill.path}\n\n---\n\n${content}`
421
+ }
422
+
423
+ /** Ask a question about a specific skill using a DocsReader. */
424
+ async askSkillBasedQuestion({ skillName, question }: { skillName: string; question: string }): Promise<string> {
425
+ if (!this.isStarted) await this.start()
426
+
427
+ const reader = this.createSkillReader(skillName)
428
+ const answer = await reader.ask(question)
429
+ return answer
430
+ }
431
+
432
+ /**
433
+ * Fork the given assistant and ask it which skills (if any) are relevant
434
+ * to the user's query. Returns an array of skill names that should be loaded
435
+ * before the real question is answered.
436
+ *
437
+ * The fork is ephemeral (historyMode: 'none') and uses structured output so
438
+ * the result is always a clean string array — never free text.
439
+ *
440
+ * @param assistant - The assistant instance to fork
441
+ * @param userQuery - The user's original question
442
+ * @returns Array of skill names relevant to the query (may be empty)
443
+ */
444
+ async findRelevantSkillsForAssistant(assistant: Assistant, userQuery: string): Promise<string[]> {
445
+ if (!this.isStarted) await this.start()
446
+
447
+ const skills = this.list()
448
+ if (skills.length === 0) return []
449
+
450
+ const responseSchema = z.object({
451
+ skills: z.array(z.string()).describe('Names of skills relevant to the query. Empty array if none apply.'),
452
+ })
453
+
454
+ const skillsDescription = Object.entries(this.skillsTable)
455
+ .map(([title,description]) => `- **${title}**: ${description}`)
456
+ .join("\n")
457
+
458
+ const prompt = this.container.ui.endent(`You are a routing assistant. Given a user query and a list of available skills, determine which skills (if any) should be loaded to help answer the query.
459
+ Available skills:
460
+ -------
461
+ ${skillsDescription}
462
+
463
+ User query: ${userQuery}
464
+
465
+ Return only the skill names that are directly relevant. Return an empty array if none apply. Do not load skills speculatively — only include ones that would materially help answer this specific query.`)
466
+
467
+ const fork = assistant.conversation.fork()
468
+ const result = await fork.ask(prompt, { schema: responseSchema }) as unknown as { skills: string[] }
469
+
470
+ const found = result.skills.filter(name => this.find(name) !== undefined)
471
+
472
+ this.emit('foundSkills', found, assistant, userQuery)
473
+
474
+ return found
475
+ }
476
+ }
477
+
478
+ export default SkillsLibrary
@@ -0,0 +1,6 @@
1
+ import container from './container.server'
2
+ import type { AGIContainer } from './container.server'
3
+
4
+ export * from './container.server'
5
+
6
+ export default container as AGIContainer
@@ -0,0 +1,89 @@
1
+ /**
2
+ * A composable middleware chain. Each interceptor receives a mutable
3
+ * context and a `next` function. Calling `next()` continues the chain;
4
+ * skipping it short-circuits.
5
+ */
6
+
7
+ export type InterceptorFn<T> = (ctx: T, next: () => Promise<void>) => Promise<void>
8
+
9
+ export class InterceptorChain<T> {
10
+ private fns: InterceptorFn<T>[] = []
11
+
12
+ add(fn: InterceptorFn<T>): void {
13
+ this.fns.push(fn)
14
+ }
15
+
16
+ remove(fn: InterceptorFn<T>): void {
17
+ const idx = this.fns.indexOf(fn)
18
+ if (idx !== -1) this.fns.splice(idx, 1)
19
+ }
20
+
21
+ get hasInterceptors(): boolean {
22
+ return this.fns.length > 0
23
+ }
24
+
25
+ get size(): number {
26
+ return this.fns.length
27
+ }
28
+
29
+ clear(): void {
30
+ this.fns = []
31
+ }
32
+
33
+ clone(): InterceptorChain<T> {
34
+ const copy = new InterceptorChain<T>()
35
+ for (const fn of this.fns) copy.add(fn)
36
+ return copy
37
+ }
38
+
39
+ async run(ctx: T, final: () => Promise<void>): Promise<void> {
40
+ let index = 0
41
+ const fns = this.fns
42
+
43
+ const next = async (): Promise<void> => {
44
+ if (index < fns.length) {
45
+ const fn = fns[index++]!
46
+ await fn(ctx, next)
47
+ } else {
48
+ await final()
49
+ }
50
+ }
51
+
52
+ await next()
53
+ }
54
+ }
55
+
56
+ export interface BeforeAskCtx {
57
+ question: string | any[]
58
+ options?: any
59
+ result?: string
60
+ }
61
+
62
+ export interface ToolCallCtx {
63
+ name: string
64
+ args: Record<string, any>
65
+ result?: string
66
+ error?: any
67
+ skip?: boolean
68
+ }
69
+
70
+ export interface BeforeResponseCtx {
71
+ text: string
72
+ }
73
+
74
+ export interface BeforeTurnCtx {
75
+ turn: number
76
+ isFollowUp: boolean
77
+ messages: any[]
78
+ skip?: boolean
79
+ }
80
+
81
+ export interface InterceptorPoints {
82
+ beforeAsk: BeforeAskCtx
83
+ beforeTurn: BeforeTurnCtx
84
+ beforeToolCall: ToolCallCtx
85
+ afterToolCall: ToolCallCtx
86
+ beforeResponse: BeforeResponseCtx
87
+ }
88
+
89
+ export type InterceptorPoint = keyof InterceptorPoints
@@ -0,0 +1,122 @@
1
+ import { encodingForModel, getEncoding } from 'js-tiktoken'
2
+ import type { Tiktoken } from 'js-tiktoken'
3
+
4
+ /**
5
+ * Known model context window sizes. Prefix-matched for dated variants
6
+ * (e.g. "gpt-4o-2024-08-06" matches "gpt-4o").
7
+ */
8
+ const MODEL_CONTEXT_WINDOWS: Record<string, number> = {
9
+ 'gpt-4.1': 1_000_000,
10
+ 'gpt-4.1-mini': 1_000_000,
11
+ 'gpt-4.1-nano': 1_000_000,
12
+ 'gpt-4o': 128_000,
13
+ 'gpt-4o-mini': 128_000,
14
+ 'gpt-4-turbo': 128_000,
15
+ 'gpt-4': 8_192,
16
+ 'gpt-3.5-turbo': 16_385,
17
+ 'o1': 200_000,
18
+ 'o1-mini': 128_000,
19
+ 'o1-pro': 200_000,
20
+ 'o3': 200_000,
21
+ 'o3-mini': 200_000,
22
+ 'o4-mini': 200_000,
23
+ 'gpt-5': 1_000_000,
24
+ }
25
+
26
+ const DEFAULT_CONTEXT_WINDOW = 128_000
27
+
28
+ const encoderCache = new Map<string, Tiktoken>()
29
+
30
+ /** Look up the context window size for a model name (exact then prefix match). */
31
+ export function getContextWindow(model: string): number {
32
+ if (MODEL_CONTEXT_WINDOWS[model]) return MODEL_CONTEXT_WINDOWS[model]
33
+
34
+ // Prefix match — longest prefix wins (e.g. "gpt-4o-mini" before "gpt-4o")
35
+ let best = ''
36
+ for (const key of Object.keys(MODEL_CONTEXT_WINDOWS)) {
37
+ if (model.startsWith(key) && key.length > best.length) {
38
+ best = key
39
+ }
40
+ }
41
+
42
+ return best ? MODEL_CONTEXT_WINDOWS[best] ?? DEFAULT_CONTEXT_WINDOW : DEFAULT_CONTEXT_WINDOW
43
+ }
44
+
45
+ /** Get a cached tiktoken encoder for a model (falls back to o200k_base). */
46
+ export function getEncoder(model: string): Tiktoken {
47
+ if (encoderCache.has(model)) return encoderCache.get(model)!
48
+
49
+ let enc: Tiktoken
50
+ try {
51
+ enc = encodingForModel(model as any)
52
+ } catch {
53
+ enc = getEncoding('o200k_base')
54
+ }
55
+
56
+ encoderCache.set(model, enc)
57
+ return enc
58
+ }
59
+
60
+ /** Count tokens in a plain string. */
61
+ export function countTokens(text: string, model: string): number {
62
+ return getEncoder(model).encode(text).length
63
+ }
64
+
65
+ /**
66
+ * Estimate the total input token count for a messages array.
67
+ * Follows the OpenAI token counting recipe with per-message overhead.
68
+ */
69
+ export function countMessageTokens(messages: any[], model: string): number {
70
+ const enc = getEncoder(model)
71
+ const TOKENS_PER_MESSAGE = 3 // <|start|>role\ncontent<|end|>
72
+ const REPLY_PRIMING = 3
73
+
74
+ let total = 0
75
+
76
+ for (const msg of messages) {
77
+ total += TOKENS_PER_MESSAGE
78
+
79
+ // Role
80
+ if (msg.role) {
81
+ total += enc.encode(msg.role).length
82
+ }
83
+
84
+ // Content
85
+ if (typeof msg.content === 'string') {
86
+ total += enc.encode(msg.content).length
87
+ } else if (Array.isArray(msg.content)) {
88
+ for (const part of msg.content) {
89
+ if (part.type === 'text' && part.text) {
90
+ total += enc.encode(part.text).length
91
+ } else if (part.type === 'image_url') {
92
+ // Rough image token estimates
93
+ const detail = part.image_url?.detail || 'auto'
94
+ total += detail === 'low' ? 85 : 170
95
+ } else if (part.type === 'input_audio' || part.type === 'input_file') {
96
+ total += 50 // rough placeholder for non-text parts
97
+ }
98
+ }
99
+ }
100
+
101
+ // Tool calls on assistant messages
102
+ if (msg.tool_calls && Array.isArray(msg.tool_calls)) {
103
+ for (const tc of msg.tool_calls) {
104
+ total += 3 // tool call overhead
105
+ if (tc.function?.name) {
106
+ total += enc.encode(tc.function.name).length
107
+ }
108
+ if (tc.function?.arguments) {
109
+ total += enc.encode(tc.function.arguments).length
110
+ }
111
+ }
112
+ }
113
+
114
+ // Name field (used on some message types)
115
+ if (msg.name) {
116
+ total += enc.encode(msg.name).length + 1
117
+ }
118
+ }
119
+
120
+ total += REPLY_PRIMING
121
+ return total
122
+ }