luca 3.0.0 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (372) hide show
  1. package/.github/workflows/release.yaml +1 -0
  2. package/CLAUDE.md +10 -2
  3. package/README.md +130 -112
  4. package/assistants/codingAssistant/CORE.md +6 -1
  5. package/assistants/codingAssistant/hooks.ts +1 -1
  6. package/assistants/inkbot/hooks.ts +1 -1
  7. package/assistants/inkbot/tools.ts +1 -1
  8. package/bun.lock +220 -322
  9. package/commands/audit-docs.ts +2 -2
  10. package/commands/build-bootstrap.ts +2 -3
  11. package/commands/build-python-bridge.ts +2 -3
  12. package/commands/build-scaffolds.ts +2 -3
  13. package/commands/bundle-consumer-project.ts +521 -0
  14. package/commands/generate-api-docs.ts +2 -2
  15. package/commands/inkbot.ts +2 -2
  16. package/commands/release.ts +2 -2
  17. package/commands/try-all-challenges.ts +3 -3
  18. package/commands/try-challenge.ts +3 -3
  19. package/dist/agi/container.server.d.ts +2 -2
  20. package/dist/agi/features/assistant.d.ts +2 -2
  21. package/dist/agi/features/assistants-manager.d.ts +1 -1
  22. package/dist/agi/features/autonomous-assistant.d.ts +1 -1
  23. package/dist/agi/features/browser-use.d.ts +1 -1
  24. package/dist/agi/features/claude-code.d.ts +1 -1
  25. package/dist/agi/features/conversation-history.d.ts +2 -2
  26. package/dist/agi/features/conversation.d.ts +1 -1
  27. package/dist/agi/features/docs-reader.d.ts +1 -1
  28. package/dist/agi/features/file-tools.d.ts +1 -1
  29. package/dist/agi/features/luca-coder.d.ts +1 -1
  30. package/dist/agi/features/openai-codex.d.ts +1 -1
  31. package/dist/agi/features/skills-library.d.ts +1 -1
  32. package/dist/clients/civitai/index.d.ts +4 -4
  33. package/dist/clients/client-template.d.ts +4 -4
  34. package/dist/clients/comfyui/index.d.ts +2 -2
  35. package/dist/clients/elevenlabs/index.d.ts +2 -2
  36. package/dist/clients/openai/index.d.ts +2 -2
  37. package/dist/clients/supabase/index.d.ts +3 -3
  38. package/dist/command.d.ts +1 -1
  39. package/dist/node/container.d.ts +1 -1
  40. package/dist/node/features/helpers.d.ts +3 -3
  41. package/dist/node/features/semantic-search.d.ts +1 -1
  42. package/dist/node/features/vm.d.ts +3 -3
  43. package/dist/node.d.ts +1 -1
  44. package/dist/scaffolds/generated.d.ts +1 -1
  45. package/dist/selector.d.ts +1 -1
  46. package/index.html +217 -190
  47. package/luca.console.ts +1 -1
  48. package/package.json +2 -2
  49. package/public/index.html +217 -190
  50. package/public/slides-ai-native.html +1 -1
  51. package/public/slides-intro.html +2 -2
  52. package/scripts/examples/ask-luca-expert.ts +1 -1
  53. package/scripts/examples/assistant-questions.ts +1 -1
  54. package/scripts/examples/excalidraw-expert.ts +1 -1
  55. package/scripts/examples/file-manager.ts +1 -1
  56. package/scripts/examples/ideas.ts +1 -1
  57. package/scripts/examples/interactive-chat.ts +1 -1
  58. package/scripts/examples/opening-a-web-browser.ts +1 -1
  59. package/scripts/examples/telegram-bot.ts +1 -1
  60. package/scripts/examples/using-assistant-with-mcp.ts +1 -1
  61. package/scripts/examples/using-claude-code.ts +1 -1
  62. package/scripts/examples/using-contentdb.ts +2 -2
  63. package/scripts/examples/using-conversations.ts +1 -1
  64. package/scripts/examples/using-disk-cache.ts +1 -1
  65. package/scripts/examples/using-docker-shell.ts +1 -1
  66. package/scripts/examples/using-elevenlabs.ts +1 -1
  67. package/scripts/examples/using-google-calendar.ts +1 -1
  68. package/scripts/examples/using-google-docs.ts +1 -1
  69. package/scripts/examples/using-google-drive.ts +1 -1
  70. package/scripts/examples/using-google-sheets.ts +1 -1
  71. package/scripts/examples/using-nlp.ts +1 -1
  72. package/scripts/examples/using-ollama.ts +1 -1
  73. package/scripts/examples/using-postgres.ts +1 -1
  74. package/scripts/examples/using-runpod.ts +1 -1
  75. package/scripts/examples/using-tts.ts +1 -1
  76. package/scripts/scaffold.ts +5 -5
  77. package/scripts/scratch.ts +1 -1
  78. package/scripts/test-assistant-hooks.ts +1 -1
  79. package/scripts/test-docs-reader.ts +1 -1
  80. package/src/agi/container.server.ts +6 -2
  81. package/src/agi/features/agent-memory.ts +25 -25
  82. package/src/agi/features/assistant.ts +34 -5
  83. package/src/agi/features/assistants-manager.ts +122 -6
  84. package/src/agi/features/autonomous-assistant.ts +1 -1
  85. package/src/agi/features/browser-use.ts +20 -1
  86. package/src/agi/features/claude-code.ts +51 -5
  87. package/src/agi/features/coding-tools.ts +1 -1
  88. package/src/agi/features/conversation-history.ts +181 -4
  89. package/src/agi/features/conversation.ts +186 -15
  90. package/src/agi/features/docs-reader.ts +2 -2
  91. package/src/agi/features/file-tools.ts +49 -2
  92. package/src/agi/features/luca-coder.ts +7 -5
  93. package/src/agi/features/mcp-bridge.ts +532 -0
  94. package/src/agi/features/openai-codex.ts +2 -2
  95. package/src/agi/features/skills-library.ts +131 -52
  96. package/src/agi/lib/token-counter.ts +80 -0
  97. package/src/bootstrap/generated.ts +56 -57
  98. package/src/browser.ts +1 -1
  99. package/src/cli/build-info.ts +2 -2
  100. package/src/cli/cli.ts +2 -2
  101. package/src/clients/civitai/index.ts +5 -5
  102. package/src/clients/client-template.ts +4 -4
  103. package/src/clients/comfyui/index.ts +4 -4
  104. package/src/clients/elevenlabs/index.ts +4 -4
  105. package/src/clients/openai/index.ts +7 -7
  106. package/src/clients/supabase/index.ts +4 -4
  107. package/src/clients/voicebox/index.ts +4 -4
  108. package/src/command.ts +2 -1
  109. package/src/commands/chat.ts +1 -0
  110. package/src/commands/eval.ts +2 -56
  111. package/src/commands/introspect.ts +1 -1
  112. package/src/commands/prompt.ts +41 -9
  113. package/src/container-describer.ts +8 -1
  114. package/src/container.ts +13 -0
  115. package/src/entity.ts +2 -2
  116. package/src/helper.ts +1 -1
  117. package/src/introspection/generated.agi.ts +28563 -27571
  118. package/src/introspection/generated.node.ts +20281 -20194
  119. package/src/introspection/generated.web.ts +605 -584
  120. package/src/introspection/scan.ts +11 -6
  121. package/src/node/container.ts +1 -1
  122. package/src/node/features/content-db.ts +39 -2
  123. package/src/node/features/display-result.ts +57 -0
  124. package/src/node/features/helpers.ts +42 -15
  125. package/src/node/features/python.ts +25 -19
  126. package/src/node/features/repl.ts +1 -1
  127. package/src/node/features/secure-shell.ts +11 -17
  128. package/src/node/features/semantic-search.ts +2 -2
  129. package/src/node/features/transpiler.ts +2 -3
  130. package/src/node/features/ui.ts +5 -0
  131. package/src/node/features/vm.ts +3 -3
  132. package/src/node.ts +3 -3
  133. package/src/python/generated.ts +0 -1
  134. package/src/scaffolds/generated.ts +82 -83
  135. package/src/selector.ts +1 -1
  136. package/src/servers/express.ts +1 -1
  137. package/src/web/features/helpers.ts +22 -0
  138. package/tsconfig.json +12 -12
  139. package/docs/CLI.md +0 -335
  140. package/docs/CNAME +0 -1
  141. package/docs/README.md +0 -60
  142. package/docs/TABLE-OF-CONTENTS.md +0 -183
  143. package/docs/apis/clients/elevenlabs.md +0 -308
  144. package/docs/apis/clients/graph.md +0 -107
  145. package/docs/apis/clients/openai.md +0 -429
  146. package/docs/apis/clients/rest.md +0 -161
  147. package/docs/apis/clients/websocket.md +0 -174
  148. package/docs/apis/features/agi/assistant.md +0 -625
  149. package/docs/apis/features/agi/assistants-manager.md +0 -282
  150. package/docs/apis/features/agi/auto-assistant.md +0 -279
  151. package/docs/apis/features/agi/browser-use.md +0 -802
  152. package/docs/apis/features/agi/claude-code.md +0 -884
  153. package/docs/apis/features/agi/conversation-history.md +0 -364
  154. package/docs/apis/features/agi/conversation.md +0 -548
  155. package/docs/apis/features/agi/docs-reader.md +0 -99
  156. package/docs/apis/features/agi/file-tools.md +0 -163
  157. package/docs/apis/features/agi/luca-coder.md +0 -407
  158. package/docs/apis/features/agi/openai-codex.md +0 -396
  159. package/docs/apis/features/agi/openapi.md +0 -138
  160. package/docs/apis/features/agi/semantic-search.md +0 -387
  161. package/docs/apis/features/agi/skills-library.md +0 -239
  162. package/docs/apis/features/node/container-link.md +0 -192
  163. package/docs/apis/features/node/content-db.md +0 -450
  164. package/docs/apis/features/node/disk-cache.md +0 -379
  165. package/docs/apis/features/node/dns.md +0 -652
  166. package/docs/apis/features/node/docker.md +0 -706
  167. package/docs/apis/features/node/downloader.md +0 -81
  168. package/docs/apis/features/node/esbuild.md +0 -60
  169. package/docs/apis/features/node/file-manager.md +0 -191
  170. package/docs/apis/features/node/fs.md +0 -1217
  171. package/docs/apis/features/node/git.md +0 -371
  172. package/docs/apis/features/node/google-auth.md +0 -193
  173. package/docs/apis/features/node/google-calendar.md +0 -202
  174. package/docs/apis/features/node/google-docs.md +0 -173
  175. package/docs/apis/features/node/google-drive.md +0 -246
  176. package/docs/apis/features/node/google-mail.md +0 -214
  177. package/docs/apis/features/node/google-sheets.md +0 -194
  178. package/docs/apis/features/node/grep.md +0 -292
  179. package/docs/apis/features/node/helpers.md +0 -164
  180. package/docs/apis/features/node/ink.md +0 -334
  181. package/docs/apis/features/node/ipc-socket.md +0 -249
  182. package/docs/apis/features/node/json-tree.md +0 -86
  183. package/docs/apis/features/node/networking.md +0 -316
  184. package/docs/apis/features/node/nlp.md +0 -133
  185. package/docs/apis/features/node/opener.md +0 -97
  186. package/docs/apis/features/node/os.md +0 -146
  187. package/docs/apis/features/node/package-finder.md +0 -392
  188. package/docs/apis/features/node/postgres.md +0 -234
  189. package/docs/apis/features/node/proc.md +0 -399
  190. package/docs/apis/features/node/process-manager.md +0 -305
  191. package/docs/apis/features/node/python.md +0 -604
  192. package/docs/apis/features/node/redis.md +0 -380
  193. package/docs/apis/features/node/repl.md +0 -88
  194. package/docs/apis/features/node/runpod.md +0 -674
  195. package/docs/apis/features/node/secure-shell.md +0 -176
  196. package/docs/apis/features/node/semantic-search.md +0 -408
  197. package/docs/apis/features/node/sqlite.md +0 -233
  198. package/docs/apis/features/node/telegram.md +0 -279
  199. package/docs/apis/features/node/transpiler.md +0 -74
  200. package/docs/apis/features/node/tts.md +0 -133
  201. package/docs/apis/features/node/ui.md +0 -701
  202. package/docs/apis/features/node/vault.md +0 -59
  203. package/docs/apis/features/node/vm.md +0 -75
  204. package/docs/apis/features/node/yaml-tree.md +0 -85
  205. package/docs/apis/features/node/yaml.md +0 -176
  206. package/docs/apis/features/web/asset-loader.md +0 -59
  207. package/docs/apis/features/web/container-link.md +0 -192
  208. package/docs/apis/features/web/esbuild.md +0 -54
  209. package/docs/apis/features/web/helpers.md +0 -164
  210. package/docs/apis/features/web/network.md +0 -44
  211. package/docs/apis/features/web/speech.md +0 -69
  212. package/docs/apis/features/web/vault.md +0 -59
  213. package/docs/apis/features/web/vm.md +0 -75
  214. package/docs/apis/features/web/voice.md +0 -84
  215. package/docs/apis/servers/express.md +0 -171
  216. package/docs/apis/servers/mcp.md +0 -238
  217. package/docs/apis/servers/websocket.md +0 -170
  218. package/docs/bootstrap/CLAUDE.md +0 -101
  219. package/docs/bootstrap/SKILL.md +0 -341
  220. package/docs/bootstrap/templates/about-command.ts +0 -41
  221. package/docs/bootstrap/templates/docs-models.ts +0 -22
  222. package/docs/bootstrap/templates/docs-readme.md +0 -43
  223. package/docs/bootstrap/templates/example-feature.ts +0 -53
  224. package/docs/bootstrap/templates/health-endpoint.ts +0 -15
  225. package/docs/bootstrap/templates/luca-cli.ts +0 -30
  226. package/docs/bootstrap/templates/runme.md +0 -54
  227. package/docs/challenges/caching-proxy.md +0 -16
  228. package/docs/challenges/content-db-round-trip.md +0 -14
  229. package/docs/challenges/custom-command.md +0 -9
  230. package/docs/challenges/file-watcher-pipeline.md +0 -11
  231. package/docs/challenges/grep-audit-report.md +0 -15
  232. package/docs/challenges/multi-feature-dashboard.md +0 -14
  233. package/docs/challenges/process-orchestrator.md +0 -17
  234. package/docs/challenges/rest-api-server-with-client.md +0 -12
  235. package/docs/challenges/script-runner-with-vm.md +0 -11
  236. package/docs/challenges/simple-rest-api.md +0 -15
  237. package/docs/challenges/websocket-serve-and-client.md +0 -11
  238. package/docs/challenges/yaml-config-system.md +0 -14
  239. package/docs/command-system-overhaul.md +0 -94
  240. package/docs/documentation-audit.md +0 -134
  241. package/docs/examples/assistant/CORE.md +0 -18
  242. package/docs/examples/assistant/hooks.ts +0 -3
  243. package/docs/examples/assistant/tools.ts +0 -10
  244. package/docs/examples/assistant-hooks-reference.ts +0 -171
  245. package/docs/examples/assistant-with-process-manager.md +0 -84
  246. package/docs/examples/content-db.md +0 -77
  247. package/docs/examples/disk-cache.md +0 -83
  248. package/docs/examples/docker.md +0 -101
  249. package/docs/examples/downloader.md +0 -70
  250. package/docs/examples/entity.md +0 -124
  251. package/docs/examples/esbuild.md +0 -80
  252. package/docs/examples/feature-as-tool-provider.md +0 -143
  253. package/docs/examples/file-manager.md +0 -82
  254. package/docs/examples/fs.md +0 -83
  255. package/docs/examples/git.md +0 -85
  256. package/docs/examples/google-auth.md +0 -88
  257. package/docs/examples/google-calendar.md +0 -94
  258. package/docs/examples/google-docs.md +0 -82
  259. package/docs/examples/google-drive.md +0 -96
  260. package/docs/examples/google-sheets.md +0 -95
  261. package/docs/examples/grep.md +0 -85
  262. package/docs/examples/ink-blocks.md +0 -75
  263. package/docs/examples/ink-renderer.md +0 -41
  264. package/docs/examples/ink.md +0 -103
  265. package/docs/examples/ipc-socket.md +0 -103
  266. package/docs/examples/json-tree.md +0 -91
  267. package/docs/examples/networking.md +0 -58
  268. package/docs/examples/nlp.md +0 -91
  269. package/docs/examples/opener.md +0 -78
  270. package/docs/examples/os.md +0 -72
  271. package/docs/examples/package-finder.md +0 -89
  272. package/docs/examples/postgres.md +0 -91
  273. package/docs/examples/proc.md +0 -81
  274. package/docs/examples/process-manager.md +0 -79
  275. package/docs/examples/python.md +0 -132
  276. package/docs/examples/repl.md +0 -93
  277. package/docs/examples/runpod.md +0 -119
  278. package/docs/examples/secure-shell.md +0 -92
  279. package/docs/examples/sqlite.md +0 -86
  280. package/docs/examples/structured-output-with-assistants.md +0 -144
  281. package/docs/examples/telegram.md +0 -77
  282. package/docs/examples/tts.md +0 -86
  283. package/docs/examples/ui.md +0 -80
  284. package/docs/examples/vault.md +0 -70
  285. package/docs/examples/vm.md +0 -86
  286. package/docs/examples/websocket-ask-and-reply-example.md +0 -128
  287. package/docs/examples/yaml-tree.md +0 -93
  288. package/docs/examples/yaml.md +0 -104
  289. package/docs/ideas/assistant-factory-pattern.md +0 -142
  290. package/docs/in-memory-fs.md +0 -4
  291. package/docs/introspection-audit.md +0 -49
  292. package/docs/introspection.md +0 -164
  293. package/docs/mcp/readme.md +0 -162
  294. package/docs/models.ts +0 -41
  295. package/docs/philosophy.md +0 -86
  296. package/docs/principles.md +0 -7
  297. package/docs/prompts/audit-codebase-for-failures-to-use-the-container.md +0 -34
  298. package/docs/prompts/check-for-undocumented-features.md +0 -27
  299. package/docs/prompts/mcp-test-easy-command.md +0 -27
  300. package/docs/scaffolds/client.md +0 -149
  301. package/docs/scaffolds/command.md +0 -120
  302. package/docs/scaffolds/endpoint.md +0 -171
  303. package/docs/scaffolds/feature.md +0 -158
  304. package/docs/scaffolds/selector.md +0 -91
  305. package/docs/scaffolds/server.md +0 -196
  306. package/docs/selectors.md +0 -115
  307. package/docs/sessions/custom-command/attempt-log-2.md +0 -195
  308. package/docs/sessions/file-watcher-pipeline/attempt-log-1.md +0 -728
  309. package/docs/sessions/file-watcher-pipeline/attempt-log-2.md +0 -555
  310. package/docs/sessions/grep-audit-report/attempt-log-1.md +0 -289
  311. package/docs/sessions/multi-feature-dashboard/attempt-log-2.md +0 -679
  312. package/docs/sessions/rest-api-server-with-client/attempt-log-1.md +0 -1
  313. package/docs/sessions/rest-api-server-with-client/attempt-log-3.md +0 -920
  314. package/docs/sessions/simple-rest-api/attempt-log-1.md +0 -593
  315. package/docs/sessions/websocket-serve-and-client/attempt-log-2.md +0 -995
  316. package/docs/tutorials/00-bootstrap.md +0 -166
  317. package/docs/tutorials/01-getting-started.md +0 -106
  318. package/docs/tutorials/02-container.md +0 -210
  319. package/docs/tutorials/03-scripts.md +0 -194
  320. package/docs/tutorials/04-features-overview.md +0 -196
  321. package/docs/tutorials/05-state-and-events.md +0 -171
  322. package/docs/tutorials/06-servers.md +0 -157
  323. package/docs/tutorials/07-endpoints.md +0 -198
  324. package/docs/tutorials/08-commands.md +0 -252
  325. package/docs/tutorials/09-clients.md +0 -162
  326. package/docs/tutorials/10-creating-features.md +0 -203
  327. package/docs/tutorials/11-contentbase.md +0 -191
  328. package/docs/tutorials/12-assistants.md +0 -215
  329. package/docs/tutorials/13-introspection.md +0 -157
  330. package/docs/tutorials/14-type-system.md +0 -174
  331. package/docs/tutorials/15-project-patterns.md +0 -222
  332. package/docs/tutorials/16-google-features.md +0 -534
  333. package/docs/tutorials/17-tui-blocks.md +0 -530
  334. package/docs/tutorials/18-semantic-search.md +0 -334
  335. package/docs/tutorials/19-python-sessions.md +0 -401
  336. package/docs/tutorials/20-browser-esm.md +0 -234
  337. package/src/agi/endpoints/ask.ts +0 -60
  338. package/src/agi/endpoints/conversations/[id].ts +0 -45
  339. package/src/agi/endpoints/conversations.ts +0 -31
  340. package/src/agi/endpoints/experts.ts +0 -37
  341. package/test/assistant-hooks.test.ts +0 -306
  342. package/test/assistant.test.ts +0 -81
  343. package/test/bus.test.ts +0 -134
  344. package/test/clients-servers.test.ts +0 -217
  345. package/test/command.test.ts +0 -267
  346. package/test/container-link.test.ts +0 -274
  347. package/test/conversation.test.ts +0 -220
  348. package/test/features.test.ts +0 -160
  349. package/test/fork-and-research.test.ts +0 -450
  350. package/test/integration.test.ts +0 -787
  351. package/test/interceptor-chain.test.ts +0 -61
  352. package/test/node-container.test.ts +0 -121
  353. package/test/python-session.test.ts +0 -105
  354. package/test/rate-limit.test.ts +0 -272
  355. package/test/semantic-search.test.ts +0 -550
  356. package/test/state.test.ts +0 -121
  357. package/test/vm-context.test.ts +0 -146
  358. package/test/vm-loadmodule.test.ts +0 -213
  359. package/test/websocket-ask.test.ts +0 -101
  360. package/test-integration/assistant.test.ts +0 -138
  361. package/test-integration/assistants-manager.test.ts +0 -113
  362. package/test-integration/claude-code.test.ts +0 -98
  363. package/test-integration/conversation-history.test.ts +0 -205
  364. package/test-integration/conversation.test.ts +0 -137
  365. package/test-integration/elevenlabs.test.ts +0 -55
  366. package/test-integration/google-services.test.ts +0 -80
  367. package/test-integration/helpers.ts +0 -89
  368. package/test-integration/memory.test.ts +0 -204
  369. package/test-integration/openai-codex.test.ts +0 -93
  370. package/test-integration/runpod.test.ts +0 -58
  371. package/test-integration/server-endpoints.test.ts +0 -97
  372. package/test-integration/telegram.test.ts +0 -46
@@ -161,6 +161,7 @@ export default async function chat(options: z.infer<typeof argsSchema>, context:
161
161
 
162
162
  assistant.on('toolCall', (toolName: string, args: any) => {
163
163
  if (inkInstance) { inkInstance.unmount(); inkInstance = null }
164
+ responseBuffer = ''
164
165
  const argsStr = JSON.stringify(args).slice(0, 120)
165
166
  process.stdout.write(ui.colors.dim(`\n ⟳ ${toolName}`) + ui.colors.dim(`(${argsStr})\n`))
166
167
  })
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod'
2
- import { inspect } from 'util'
3
2
  import { commands } from '../command.js'
3
+ import { displayResult } from '../node/features/display-result.js'
4
4
  import { CommandOptionsSchema } from '../schemas/base.js'
5
5
  import type { ContainerContext } from '../container.js'
6
6
 
@@ -58,61 +58,7 @@ export default async function evalCommand(options: z.infer<typeof argsSchema>, c
58
58
  }
59
59
  }
60
60
 
61
- const BUILTIN_TYPES = new Set(['Object', 'Array', 'Map', 'Set', 'Date', 'RegExp', 'Promise', 'Error', 'Number', 'String', 'Boolean'])
62
-
63
- export function displayResult(value: any) {
64
- if (typeof value !== 'object' || value === null) {
65
- console.log(value)
66
- return
67
- }
68
-
69
- const hasCustomInspect = typeof value[Symbol.for('nodejs.util.inspect.custom')] === 'function'
70
- const ctorName = value.constructor?.name
71
- const isClassInstance = ctorName && !BUILTIN_TYPES.has(ctorName)
72
-
73
- // Objects with custom inspect or builtins: use standard inspect
74
- if (hasCustomInspect || !isClassInstance) {
75
- console.log(inspect(value, { colors: true, depth: 4 }))
76
- return
77
- }
78
-
79
- // Class instances: show clean data (no _ props, no functions)
80
- const data: Record<string, any> = {}
81
- for (const [k, v] of Object.entries(value)) {
82
- if (k.startsWith('_') || typeof v === 'function') continue
83
- data[k] = v
84
- }
85
- const body = inspect(data, { colors: true, depth: 3 })
86
- console.log(`${ctorName} ${body}`)
87
-
88
- // Collect methods and getters from own + prototype chain
89
- const methods: string[] = []
90
- const getters: string[] = []
91
-
92
- for (const [k, v] of Object.entries(value)) {
93
- if (k.startsWith('_')) continue
94
- if (typeof v === 'function') methods.push(k)
95
- }
96
-
97
- let proto = Object.getPrototypeOf(value)
98
- while (proto && proto !== Object.prototype) {
99
- for (const k of Object.getOwnPropertyNames(proto)) {
100
- if (k === 'constructor' || k.startsWith('_')) continue
101
- const desc = Object.getOwnPropertyDescriptor(proto, k)
102
- if (!desc) continue
103
- if (desc.get && !getters.includes(k)) getters.push(k)
104
- else if (typeof desc.value === 'function' && !methods.includes(k)) methods.push(k)
105
- }
106
- proto = Object.getPrototypeOf(proto)
107
- }
108
-
109
- if (getters.length || methods.length) {
110
- const parts: string[] = []
111
- if (getters.length) parts.push(` \x1b[36mgetters:\x1b[0m ${getters.sort().join(', ')}`)
112
- if (methods.length) parts.push(` \x1b[36mmethods:\x1b[0m ${methods.sort().map(m => m + '()').join(', ')}`)
113
- console.log(parts.join('\n'))
114
- }
115
- }
61
+ export { displayResult } from '../node/features/display-result.js'
116
62
 
117
63
  commands.registerHandler('eval', {
118
64
  description: 'Evaluate a JavaScript/TypeScript expression with the container in scope',
@@ -178,7 +178,7 @@ async function introspect(options: z.infer<typeof argsSchema>, context: Containe
178
178
  }
179
179
 
180
180
  const outputPath = options.output || 'features/introspection.generated.ts'
181
- const importSource = '@soederpop/luca/introspection'
181
+ const importSource = 'luca/introspection'
182
182
 
183
183
  console.log(`Scanning: ${src.join(', ')}`)
184
184
  console.log(`Output: ${outputPath}`)
@@ -23,7 +23,7 @@ export const argsSchema = CommandOptionsSchema.extend({
23
23
  'exclude-sections': z.string().optional().describe('Comma-separated list of section headings to exclude from the prompt'),
24
24
  'chrome': z.boolean().default(false).describe('Launch Claude Code with a Chrome browser tool'),
25
25
  'dry-run': z.boolean().default(false).describe('Display the resolved prompt and options without running the assistant'),
26
- 'local': z.boolean().default(false).describe('Use local models for assistant mode'),
26
+ 'local': z.boolean().default(false).describe('Use local models (sets ANTHROPIC_BASE_URL and model for claudeCode, or local flag for assistants)'),
27
27
  })
28
28
 
29
29
  function normalizeTarget(raw: string): string {
@@ -97,7 +97,12 @@ async function runClaudeOrCodex(target: 'claude' | 'codex', promptContent: strin
97
97
 
98
98
  let outputTokens = 0
99
99
 
100
- // Render complete messages — text gets markdown formatting, tool_use gets a summary line
100
+ // Stream text via deltas for real-time output
101
+ feature.on('session:delta', ({ text }: { text: string }) => {
102
+ process.stdout.write(text)
103
+ })
104
+
105
+ // Render complete messages — only tool_use blocks and final text (markdown formatted)
101
106
  feature.on('session:message', ({ message }: { message: any }) => {
102
107
  const role = message?.message?.role ?? message?.role
103
108
  if (role && role !== 'assistant') return
@@ -108,10 +113,12 @@ async function runClaudeOrCodex(target: 'claude' | 'codex', promptContent: strin
108
113
  const usage = message?.message?.usage ?? message?.usage
109
114
  if (usage?.output_tokens) outputTokens += usage.output_tokens
110
115
 
116
+ // Skip partial messages — text is already rendered via session:delta
117
+ const stopReason = message?.message?.stop_reason ?? message?.stop_reason
118
+ if (!stopReason) return
119
+
111
120
  for (const block of content) {
112
- if (block.type === 'text' && block.text) {
113
- process.stdout.write(ui.markdown(block.text))
114
- } else if (block.type === 'tool_use') {
121
+ if (block.type === 'tool_use') {
115
122
  const argsStr = JSON.stringify(block.input).slice(0, 120)
116
123
  process.stdout.write(ui.colors.dim(`\n ⟳ ${block.name}`) + ui.colors.dim(`(${argsStr})\n`))
117
124
  }
@@ -122,7 +129,12 @@ async function runClaudeOrCodex(target: 'claude' | 'codex', promptContent: strin
122
129
  const collectedEvents: any[] = []
123
130
  if (options['out-file']) {
124
131
  feature.on('session:event', ({ event }: { event: any }) => {
125
- if (event.type === 'assistant' || event.type === 'tool_result' || event.type === 'message' || event.type === 'function_call_output' || event.type === 'item.completed' || event.type === 'turn.completed') {
132
+ // Skip partial assistant messages (streaming tokens) only collect complete messages with stop_reason
133
+ if (event.type === 'assistant') {
134
+ if (event.message?.stop_reason) collectedEvents.push(event)
135
+ return
136
+ }
137
+ if (event.type === 'tool_result' || event.type === 'message' || event.type === 'function_call_output' || event.type === 'item.completed' || event.type === 'turn.completed') {
126
138
  collectedEvents.push(event)
127
139
  }
128
140
  })
@@ -137,6 +149,7 @@ async function runClaudeOrCodex(target: 'claude' | 'codex', promptContent: strin
137
149
  if (target === 'claude') {
138
150
  runOptions.permissionMode = options['permission-mode']
139
151
  if (options.chrome) runOptions.chrome = true
152
+ if (options.local) runOptions.local = true
140
153
  }
141
154
 
142
155
  // CLI flags override agentOptions from frontmatter
@@ -179,6 +192,7 @@ async function runAssistant(name: string, promptContent: string, options: z.infe
179
192
 
180
193
  // Collect structured events for --out-file
181
194
  const collectedEvents: any[] = []
195
+ let textBuffer = ''
182
196
 
183
197
  assistant.on('chunk', (text: string) => {
184
198
  if (isFirstChunk) {
@@ -187,7 +201,7 @@ async function runAssistant(name: string, promptContent: string, options: z.infe
187
201
  }
188
202
  process.stdout.write(text)
189
203
  if (options['out-file']) {
190
- collectedEvents.push({ type: 'assistant', message: { content: [{ type: 'text', text }] } })
204
+ textBuffer += text
191
205
  }
192
206
  })
193
207
 
@@ -216,6 +230,12 @@ async function runAssistant(name: string, promptContent: string, options: z.infe
216
230
  await assistant.ask(promptContent)
217
231
  process.stdout.write('\n')
218
232
 
233
+ // Flush accumulated text buffer as a single event
234
+ if (textBuffer) {
235
+ collectedEvents.push({ type: 'assistant', message: { content: [{ type: 'text', text: textBuffer }] } })
236
+ textBuffer = ''
237
+ }
238
+
219
239
  return { collectedEvents, durationMs: Date.now() - startTime, outputTokens: 0 }
220
240
  }
221
241
 
@@ -291,6 +311,7 @@ async function runParallel(
291
311
  if (target === 'claude') {
292
312
  runOptions.permissionMode = options['permission-mode']
293
313
  if (options.chrome) runOptions.chrome = true
314
+ if (options.local) runOptions.local = true
294
315
  }
295
316
 
296
317
  feature.on('session:message', ({ sessionId, message }: { sessionId: string; message: any }) => {
@@ -320,7 +341,12 @@ async function runParallel(
320
341
  feature.on('session:event', ({ sessionId, event }: { sessionId: string; event: any }) => {
321
342
  const idx = sessionMap.get(sessionId)
322
343
  if (idx === undefined) return
323
- if (event.type === 'assistant' || event.type === 'tool_result' || event.type === 'message' || event.type === 'function_call_output') {
344
+ // Skip partial assistant messages (streaming tokens) only collect complete messages
345
+ if (event.type === 'assistant') {
346
+ if (event.message?.stop_reason) promptStates[idx]!.collectedEvents.push(event)
347
+ return
348
+ }
349
+ if (event.type === 'tool_result' || event.type === 'message' || event.type === 'function_call_output') {
324
350
  promptStates[idx]!.collectedEvents.push(event)
325
351
  }
326
352
  })
@@ -366,6 +392,7 @@ async function runParallel(
366
392
  }
367
393
 
368
394
  const lineBuffers: string[] = prepared.map(() => '')
395
+ const textBuffers: string[] = prepared.map(() => '')
369
396
 
370
397
  const assistants = prepared.map((p, i) => {
371
398
  const createOptions: Record<string, any> = { ...p.agentOptions }
@@ -384,7 +411,7 @@ async function runParallel(
384
411
  }
385
412
  }
386
413
  if (options['out-file']) {
387
- promptStates[i]!.collectedEvents.push({ type: 'assistant', message: { content: [{ type: 'text', text }] } })
414
+ textBuffers[i] += text
388
415
  }
389
416
  })
390
417
 
@@ -427,6 +454,11 @@ async function runParallel(
427
454
  promptStates[i]!.lines.push(lineBuffers[i]!)
428
455
  lineBuffers[i] = ''
429
456
  }
457
+ // Flush accumulated text as a single event for out-file
458
+ if (textBuffers[i]) {
459
+ promptStates[i]!.collectedEvents.push({ type: 'assistant', message: { content: [{ type: 'text', text: textBuffers[i] }] } })
460
+ textBuffers[i] = ''
461
+ }
430
462
  if (r.status === 'rejected') {
431
463
  promptStates[i]!.status = 'error'
432
464
  promptStates[i]!.error = String(r.reason)
@@ -274,7 +274,14 @@ Use these tools whenever you are unsure what helpers are available, what a helpe
274
274
  const includeNode = this.shouldIncludeNode(platform)
275
275
  const includeBrowser = this.shouldIncludeBrowser(platform)
276
276
 
277
- if (lower === 'container' || lower === 'self') {
277
+ if (
278
+ lower === 'container' ||
279
+ lower === 'self' ||
280
+ lower === 'luca' ||
281
+ lower === 'lucaframework' ||
282
+ lower === 'luca-framework' ||
283
+ lower === 'framework'
284
+ ) {
278
285
  return [{ kind: 'container' }]
279
286
  }
280
287
 
package/src/container.ts CHANGED
@@ -915,6 +915,19 @@ const uuidCache = new Map<string, Helper>()
915
915
  const featureIdToHelperCacheKeyMap= new Map()
916
916
  const contextMap = new WeakMap()
917
917
 
918
+ /**
919
+ * Returns all helper instances that have been created by any container in this process.
920
+ * Optionally filtered by class.
921
+ *
922
+ * @param FilterClass - When provided, only instances of this class are returned.
923
+ */
924
+ export function allHelperInstances(): Helper[]
925
+ export function allHelperInstances<T extends Helper>(FilterClass: new (...args: any[]) => T): T[]
926
+ export function allHelperInstances<T extends Helper>(FilterClass?: new (...args: any[]) => T): Helper[] | T[] {
927
+ const all = [...uuidCache.values()]
928
+ return FilterClass ? all.filter((h): h is T => h instanceof FilterClass) : all
929
+ }
930
+
918
931
  function presentContainerIntrospectionAsMarkdown(data: ContainerIntrospection, startHeadingDepth: number = 1, section?: IntrospectionSection): string {
919
932
  const sections: string[] = []
920
933
  const heading = (level: number) => '#'.repeat(Math.max(1, startHeadingDepth + level - 1))
package/src/entity.ts CHANGED
@@ -71,7 +71,7 @@ export type Entity<
71
71
  * assistant.addTools(agent)
72
72
  * ```
73
73
  */
74
- expose(functionName: string, schema: z.ZodType): this
74
+ expose(this: Entity<TState, TOptions, TEvents>, functionName: string, schema: z.ZodType): Entity<TState, TOptions, TEvents>
75
75
 
76
76
  /**
77
77
  * Returns `{ schemas, handlers }` for all tools registered via `.expose()`.
@@ -104,7 +104,7 @@ export function createEntityObject<
104
104
  on(event: any, listener: any) { _events.on(event, listener) },
105
105
  off(event: any, listener?: any) { _events.off(event, listener) },
106
106
  once(event: any, listener: any) { _events.once(event, listener) },
107
- emit(event: any, ...args: any[]) { _events.emit(event, ...args) },
107
+ emit(event: any, ...args: any[]) { _events.emit(event, ...args as any) },
108
108
  waitFor(event: any) { return _events.waitFor(event) },
109
109
  setState(value: any) { _state.setState(value) },
110
110
  extend(extensions: any) { return applyExtensions(this as any, extensions) },
package/src/helper.ts CHANGED
@@ -842,7 +842,7 @@ function normalizeTypeString(type: string): string {
842
842
  (_match, _kind, name) => {
843
843
  // Convert shortcut name to PascalCase class name
844
844
  const className = name.replace(/(^|[-_])(\w)/g, (_: string, _sep: string, ch: string) => ch.toUpperCase())
845
- return `import('@soederpop/luca').${className}`
845
+ return `import('luca').${className}`
846
846
  }
847
847
  )
848
848
  return type