@soederpop/luca 0.1.2 → 0.2.1
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.
- package/.github/workflows/release.yaml +167 -0
- package/CLAUDE.md +2 -0
- package/README.md +3 -0
- package/assistants/codingAssistant/ABOUT.md +3 -0
- package/assistants/codingAssistant/CORE.md +22 -17
- package/assistants/codingAssistant/hooks.ts +17 -4
- package/assistants/codingAssistant/tools.ts +1 -106
- package/assistants/inkbot/ABOUT.md +5 -0
- package/assistants/inkbot/CORE.md +71 -0
- package/assistants/inkbot/hooks.ts +14 -0
- package/assistants/inkbot/tools.ts +47 -0
- package/bun.lock +20 -4
- package/commands/inkbot.ts +353 -0
- package/commands/release.ts +75 -181
- package/dist/agi/container.server.d.ts +63 -0
- package/dist/agi/container.server.d.ts.map +1 -0
- package/dist/agi/endpoints/ask.d.ts +20 -0
- package/dist/agi/endpoints/ask.d.ts.map +1 -0
- package/dist/agi/endpoints/conversations/[id].d.ts +27 -0
- package/dist/agi/endpoints/conversations/[id].d.ts.map +1 -0
- package/dist/agi/endpoints/conversations.d.ts +18 -0
- package/dist/agi/endpoints/conversations.d.ts.map +1 -0
- package/dist/agi/endpoints/experts.d.ts +8 -0
- package/dist/agi/endpoints/experts.d.ts.map +1 -0
- package/dist/agi/feature.d.ts +9 -0
- package/dist/agi/feature.d.ts.map +1 -0
- package/dist/agi/features/assistant.d.ts +509 -0
- package/dist/agi/features/assistant.d.ts.map +1 -0
- package/dist/agi/features/assistants-manager.d.ts +236 -0
- package/dist/agi/features/assistants-manager.d.ts.map +1 -0
- package/dist/agi/features/autonomous-assistant.d.ts +281 -0
- package/dist/agi/features/autonomous-assistant.d.ts.map +1 -0
- package/dist/agi/features/browser-use.d.ts +479 -0
- package/dist/agi/features/browser-use.d.ts.map +1 -0
- package/dist/agi/features/claude-code.d.ts +824 -0
- package/dist/agi/features/claude-code.d.ts.map +1 -0
- package/dist/agi/features/conversation-history.d.ts +245 -0
- package/dist/agi/features/conversation-history.d.ts.map +1 -0
- package/dist/agi/features/conversation.d.ts +464 -0
- package/dist/agi/features/conversation.d.ts.map +1 -0
- package/dist/agi/features/docs-reader.d.ts +72 -0
- package/dist/agi/features/docs-reader.d.ts.map +1 -0
- package/dist/agi/features/file-tools.d.ts +110 -0
- package/dist/agi/features/file-tools.d.ts.map +1 -0
- package/dist/agi/features/luca-coder.d.ts +323 -0
- package/dist/agi/features/luca-coder.d.ts.map +1 -0
- package/dist/agi/features/openai-codex.d.ts +381 -0
- package/dist/agi/features/openai-codex.d.ts.map +1 -0
- package/dist/agi/features/openapi.d.ts +200 -0
- package/dist/agi/features/openapi.d.ts.map +1 -0
- package/dist/agi/features/skills-library.d.ts +167 -0
- package/dist/agi/features/skills-library.d.ts.map +1 -0
- package/dist/agi/index.d.ts +5 -0
- package/dist/agi/index.d.ts.map +1 -0
- package/dist/agi/lib/interceptor-chain.d.ts +44 -0
- package/dist/agi/lib/interceptor-chain.d.ts.map +1 -0
- package/dist/agi/lib/token-counter.d.ts +13 -0
- package/dist/agi/lib/token-counter.d.ts.map +1 -0
- package/dist/bootstrap/generated.d.ts +5 -0
- package/dist/bootstrap/generated.d.ts.map +1 -0
- package/dist/browser.d.ts +12 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/bus.d.ts +29 -0
- package/dist/bus.d.ts.map +1 -0
- package/dist/cli/build-info.d.ts +4 -0
- package/dist/cli/build-info.d.ts.map +1 -0
- package/dist/cli/cli.d.ts +3 -0
- package/dist/cli/cli.d.ts.map +1 -0
- package/dist/client.d.ts +60 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/clients/civitai/index.d.ts +472 -0
- package/dist/clients/civitai/index.d.ts.map +1 -0
- package/dist/clients/client-template.d.ts +30 -0
- package/dist/clients/client-template.d.ts.map +1 -0
- package/dist/clients/comfyui/index.d.ts +281 -0
- package/dist/clients/comfyui/index.d.ts.map +1 -0
- package/dist/clients/elevenlabs/index.d.ts +197 -0
- package/dist/clients/elevenlabs/index.d.ts.map +1 -0
- package/dist/clients/graph.d.ts +64 -0
- package/dist/clients/graph.d.ts.map +1 -0
- package/dist/clients/openai/index.d.ts +247 -0
- package/dist/clients/openai/index.d.ts.map +1 -0
- package/dist/clients/rest.d.ts +92 -0
- package/dist/clients/rest.d.ts.map +1 -0
- package/dist/clients/supabase/index.d.ts +176 -0
- package/dist/clients/supabase/index.d.ts.map +1 -0
- package/dist/clients/websocket.d.ts +127 -0
- package/dist/clients/websocket.d.ts.map +1 -0
- package/dist/command.d.ts +163 -0
- package/dist/command.d.ts.map +1 -0
- package/dist/commands/bootstrap.d.ts +20 -0
- package/dist/commands/bootstrap.d.ts.map +1 -0
- package/dist/commands/chat.d.ts +37 -0
- package/dist/commands/chat.d.ts.map +1 -0
- package/dist/commands/code.d.ts +28 -0
- package/dist/commands/code.d.ts.map +1 -0
- package/dist/commands/console.d.ts +22 -0
- package/dist/commands/console.d.ts.map +1 -0
- package/dist/commands/describe.d.ts +50 -0
- package/dist/commands/describe.d.ts.map +1 -0
- package/dist/commands/eval.d.ts +23 -0
- package/dist/commands/eval.d.ts.map +1 -0
- package/dist/commands/help.d.ts +25 -0
- package/dist/commands/help.d.ts.map +1 -0
- package/dist/commands/index.d.ts +18 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/introspect.d.ts +24 -0
- package/dist/commands/introspect.d.ts.map +1 -0
- package/dist/commands/mcp.d.ts +35 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/prompt.d.ts +38 -0
- package/dist/commands/prompt.d.ts.map +1 -0
- package/dist/commands/run.d.ts +24 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/sandbox-mcp.d.ts +34 -0
- package/dist/commands/sandbox-mcp.d.ts.map +1 -0
- package/dist/commands/save-api-docs.d.ts +21 -0
- package/dist/commands/save-api-docs.d.ts.map +1 -0
- package/dist/commands/scaffold.d.ts +24 -0
- package/dist/commands/scaffold.d.ts.map +1 -0
- package/dist/commands/select.d.ts +22 -0
- package/dist/commands/select.d.ts.map +1 -0
- package/dist/commands/serve.d.ts +29 -0
- package/dist/commands/serve.d.ts.map +1 -0
- package/dist/container-describer.d.ts +144 -0
- package/dist/container-describer.d.ts.map +1 -0
- package/dist/container.d.ts +451 -0
- package/dist/container.d.ts.map +1 -0
- package/dist/endpoint.d.ts +113 -0
- package/dist/endpoint.d.ts.map +1 -0
- package/dist/feature.d.ts +47 -0
- package/dist/feature.d.ts.map +1 -0
- package/dist/graft.d.ts +29 -0
- package/dist/graft.d.ts.map +1 -0
- package/dist/hash-object.d.ts +8 -0
- package/dist/hash-object.d.ts.map +1 -0
- package/dist/helper.d.ts +209 -0
- package/dist/helper.d.ts.map +1 -0
- package/dist/introspection/generated.node.d.ts +44623 -0
- package/dist/introspection/generated.node.d.ts.map +1 -0
- package/dist/introspection/generated.web.d.ts +1412 -0
- package/dist/introspection/generated.web.d.ts.map +1 -0
- package/dist/introspection/index.d.ts +156 -0
- package/dist/introspection/index.d.ts.map +1 -0
- package/dist/introspection/scan.d.ts +147 -0
- package/dist/introspection/scan.d.ts.map +1 -0
- package/dist/node/container.d.ts +256 -0
- package/dist/node/container.d.ts.map +1 -0
- package/dist/node/feature.d.ts +9 -0
- package/dist/node/feature.d.ts.map +1 -0
- package/dist/node/features/container-link.d.ts +213 -0
- package/dist/node/features/container-link.d.ts.map +1 -0
- package/dist/node/features/content-db.d.ts +354 -0
- package/dist/node/features/content-db.d.ts.map +1 -0
- package/dist/node/features/disk-cache.d.ts +236 -0
- package/dist/node/features/disk-cache.d.ts.map +1 -0
- package/dist/node/features/dns.d.ts +511 -0
- package/dist/node/features/dns.d.ts.map +1 -0
- package/dist/node/features/docker.d.ts +485 -0
- package/dist/node/features/docker.d.ts.map +1 -0
- package/dist/node/features/downloader.d.ts +73 -0
- package/dist/node/features/downloader.d.ts.map +1 -0
- package/dist/node/features/figlet-fonts.d.ts +4 -0
- package/dist/node/features/figlet-fonts.d.ts.map +1 -0
- package/dist/node/features/file-manager.d.ts +177 -0
- package/dist/node/features/file-manager.d.ts.map +1 -0
- package/dist/node/features/fs.d.ts +635 -0
- package/dist/node/features/fs.d.ts.map +1 -0
- package/dist/node/features/git.d.ts +329 -0
- package/dist/node/features/git.d.ts.map +1 -0
- package/dist/node/features/google-auth.d.ts +200 -0
- package/dist/node/features/google-auth.d.ts.map +1 -0
- package/dist/node/features/google-calendar.d.ts +194 -0
- package/dist/node/features/google-calendar.d.ts.map +1 -0
- package/dist/node/features/google-docs.d.ts +138 -0
- package/dist/node/features/google-docs.d.ts.map +1 -0
- package/dist/node/features/google-drive.d.ts +202 -0
- package/dist/node/features/google-drive.d.ts.map +1 -0
- package/dist/node/features/google-mail.d.ts +221 -0
- package/dist/node/features/google-mail.d.ts.map +1 -0
- package/dist/node/features/google-sheets.d.ts +157 -0
- package/dist/node/features/google-sheets.d.ts.map +1 -0
- package/dist/node/features/grep.d.ts +207 -0
- package/dist/node/features/grep.d.ts.map +1 -0
- package/dist/node/features/helpers.d.ts +236 -0
- package/dist/node/features/helpers.d.ts.map +1 -0
- package/dist/node/features/ink.d.ts +332 -0
- package/dist/node/features/ink.d.ts.map +1 -0
- package/dist/node/features/ipc-socket.d.ts +298 -0
- package/dist/node/features/ipc-socket.d.ts.map +1 -0
- package/dist/node/features/json-tree.d.ts +140 -0
- package/dist/node/features/json-tree.d.ts.map +1 -0
- package/dist/node/features/networking.d.ts +373 -0
- package/dist/node/features/networking.d.ts.map +1 -0
- package/dist/node/features/nlp.d.ts +125 -0
- package/dist/node/features/nlp.d.ts.map +1 -0
- package/dist/node/features/opener.d.ts +93 -0
- package/dist/node/features/opener.d.ts.map +1 -0
- package/dist/node/features/os.d.ts +168 -0
- package/dist/node/features/os.d.ts.map +1 -0
- package/dist/node/features/package-finder.d.ts +419 -0
- package/dist/node/features/package-finder.d.ts.map +1 -0
- package/dist/node/features/postgres.d.ts +173 -0
- package/dist/node/features/postgres.d.ts.map +1 -0
- package/dist/node/features/proc.d.ts +285 -0
- package/dist/node/features/proc.d.ts.map +1 -0
- package/dist/node/features/process-manager.d.ts +427 -0
- package/dist/node/features/process-manager.d.ts.map +1 -0
- package/dist/node/features/python.d.ts +477 -0
- package/dist/node/features/python.d.ts.map +1 -0
- package/dist/node/features/redis.d.ts +247 -0
- package/dist/node/features/redis.d.ts.map +1 -0
- package/dist/node/features/repl.d.ts +84 -0
- package/dist/node/features/repl.d.ts.map +1 -0
- package/dist/node/features/runpod.d.ts +527 -0
- package/dist/node/features/runpod.d.ts.map +1 -0
- package/dist/node/features/secure-shell.d.ts +145 -0
- package/dist/node/features/secure-shell.d.ts.map +1 -0
- package/dist/node/features/semantic-search.d.ts +207 -0
- package/dist/node/features/semantic-search.d.ts.map +1 -0
- package/dist/node/features/sqlite.d.ts +180 -0
- package/dist/node/features/sqlite.d.ts.map +1 -0
- package/dist/node/features/telegram.d.ts +173 -0
- package/dist/node/features/telegram.d.ts.map +1 -0
- package/dist/node/features/transpiler.d.ts +51 -0
- package/dist/node/features/transpiler.d.ts.map +1 -0
- package/dist/node/features/tts.d.ts +108 -0
- package/dist/node/features/tts.d.ts.map +1 -0
- package/dist/node/features/ui.d.ts +562 -0
- package/dist/node/features/ui.d.ts.map +1 -0
- package/dist/node/features/vault.d.ts +90 -0
- package/dist/node/features/vault.d.ts.map +1 -0
- package/dist/node/features/vm.d.ts +285 -0
- package/dist/node/features/vm.d.ts.map +1 -0
- package/dist/node/features/yaml-tree.d.ts +118 -0
- package/dist/node/features/yaml-tree.d.ts.map +1 -0
- package/dist/node/features/yaml.d.ts +127 -0
- package/dist/node/features/yaml.d.ts.map +1 -0
- package/dist/node.d.ts +67 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/python/generated.d.ts +2 -0
- package/dist/python/generated.d.ts.map +1 -0
- package/dist/react/index.d.ts +36 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/registry.d.ts +97 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/scaffolds/generated.d.ts +13 -0
- package/dist/scaffolds/generated.d.ts.map +1 -0
- package/dist/scaffolds/template.d.ts +11 -0
- package/dist/scaffolds/template.d.ts.map +1 -0
- package/dist/schemas/base.d.ts +254 -0
- package/dist/schemas/base.d.ts.map +1 -0
- package/dist/selector.d.ts +130 -0
- package/dist/selector.d.ts.map +1 -0
- package/dist/server.d.ts +89 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/servers/express.d.ts +104 -0
- package/dist/servers/express.d.ts.map +1 -0
- package/dist/servers/mcp.d.ts +201 -0
- package/dist/servers/mcp.d.ts.map +1 -0
- package/dist/servers/socket.d.ts +121 -0
- package/dist/servers/socket.d.ts.map +1 -0
- package/dist/state.d.ts +24 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/web/clients/socket.d.ts +37 -0
- package/dist/web/clients/socket.d.ts.map +1 -0
- package/dist/web/container.d.ts +55 -0
- package/dist/web/container.d.ts.map +1 -0
- package/dist/web/extension.d.ts +4 -0
- package/dist/web/extension.d.ts.map +1 -0
- package/dist/web/feature.d.ts +8 -0
- package/dist/web/feature.d.ts.map +1 -0
- package/dist/web/features/asset-loader.d.ts +35 -0
- package/dist/web/features/asset-loader.d.ts.map +1 -0
- package/dist/web/features/container-link.d.ts +167 -0
- package/dist/web/features/container-link.d.ts.map +1 -0
- package/dist/web/features/esbuild.d.ts +51 -0
- package/dist/web/features/esbuild.d.ts.map +1 -0
- package/dist/web/features/helpers.d.ts +140 -0
- package/dist/web/features/helpers.d.ts.map +1 -0
- package/dist/web/features/network.d.ts +69 -0
- package/dist/web/features/network.d.ts.map +1 -0
- package/dist/web/features/speech.d.ts +71 -0
- package/dist/web/features/speech.d.ts.map +1 -0
- package/dist/web/features/vault.d.ts +62 -0
- package/dist/web/features/vault.d.ts.map +1 -0
- package/dist/web/features/vm.d.ts +48 -0
- package/dist/web/features/vm.d.ts.map +1 -0
- package/dist/web/features/voice-recognition.d.ts +96 -0
- package/dist/web/features/voice-recognition.d.ts.map +1 -0
- package/dist/web/shims/isomorphic-vm.d.ts +22 -0
- package/dist/web/shims/isomorphic-vm.d.ts.map +1 -0
- package/docs/apis/features/agi/assistant.md +1 -0
- package/docs/apis/features/agi/assistants-manager.md +62 -2
- package/docs/apis/features/agi/auto-assistant.md +11 -109
- package/docs/apis/features/agi/claude-code.md +138 -0
- package/docs/apis/features/agi/conversation.md +60 -31
- package/docs/apis/features/agi/luca-coder.md +407 -0
- package/docs/apis/features/agi/openapi.md +2 -2
- package/docs/apis/features/agi/skills-library.md +12 -0
- package/docs/apis/features/node/python.md +81 -11
- package/docs/apis/features/node/transpiler.md +74 -0
- package/docs/apis/features/web/esbuild.md +0 -6
- package/docs/apis/servers/mcp.md +2 -2
- package/docs/examples/entity.md +124 -0
- package/docs/ideas/assistant-factory-pattern.md +142 -0
- package/package.json +74 -21
- package/src/agi/container.server.ts +10 -0
- package/src/agi/feature.ts +13 -0
- package/src/agi/features/agent-memory.ts +694 -0
- package/src/agi/features/assistant.ts +37 -26
- package/src/agi/features/assistants-manager.ts +95 -5
- package/src/agi/features/autonomous-assistant.ts +1 -5
- package/src/agi/features/browser-use.ts +32 -2
- package/src/agi/features/claude-code.ts +165 -1
- package/src/agi/features/coding-tools.ts +175 -0
- package/src/agi/features/conversation-history.ts +2 -6
- package/src/agi/features/conversation.ts +95 -3
- package/src/agi/features/docs-reader.ts +2 -1
- package/src/agi/features/file-tools.ts +35 -28
- package/src/agi/features/luca-coder.ts +1 -5
- package/src/agi/features/openai-codex.ts +1 -1
- package/src/agi/features/openapi.ts +3 -3
- package/src/agi/features/skills-library.ts +111 -13
- package/src/agi/lib/interceptor-chain.ts +10 -0
- package/src/agi/lib/token-counter.ts +1 -1
- package/src/bootstrap/generated.ts +126 -1
- package/src/bus.ts +27 -5
- package/src/cli/build-info.ts +2 -2
- package/src/client.ts +2 -2
- package/src/clients/elevenlabs/index.ts +5 -0
- package/src/clients/voicebox/index.ts +300 -0
- package/src/commands/bootstrap.ts +2 -1
- package/src/commands/chat.ts +1 -0
- package/src/commands/code.ts +4 -2
- package/src/commands/prompt.ts +34 -34
- package/src/commands/sandbox-mcp.ts +69 -163
- package/src/commands/save-api-docs.ts +10 -8
- package/src/commands/select.ts +8 -3
- package/src/container-describer.ts +70 -84
- package/src/container.ts +93 -3
- package/src/endpoint.ts +1 -1
- package/src/entity.ts +173 -0
- package/src/feature.ts +3 -3
- package/src/helper.ts +8 -4
- package/src/introspection/generated.agi.ts +3012 -1356
- package/src/introspection/generated.node.ts +179 -33
- package/src/introspection/generated.web.ts +95 -3
- package/src/introspection/scan.ts +1 -1
- package/src/node/container.ts +1 -1
- package/src/node/features/content-db.ts +57 -30
- package/src/node/features/file-manager.ts +10 -9
- package/src/node/features/git.ts +5 -5
- package/src/node/features/helpers.ts +1 -1
- package/src/node/features/json-tree.ts +1 -1
- package/src/node/features/os.ts +3 -3
- package/src/node/features/package-finder.ts +1 -1
- package/src/node/features/process-manager.ts +51 -18
- package/src/node/features/python.ts +3 -3
- package/src/node/features/redis.ts +1 -1
- package/src/node/features/repl.ts +2 -2
- package/src/node/features/transpiler.ts +2 -2
- package/src/node/features/ui.ts +1 -1
- package/src/node/features/vm.ts +3 -3
- package/src/node/features/yaml-tree.ts +1 -1
- package/src/node.ts +1 -0
- package/src/python/generated.ts +1 -1
- package/src/scaffolds/generated.ts +1 -1
- package/src/selector.ts +74 -4
- package/src/server.ts +2 -2
- package/src/servers/mcp.ts +6 -6
- package/src/web/features/helpers.ts +1 -1
- package/src/web/features/network.ts +1 -0
- package/test/assistant.test.ts +14 -5
- package/test/conversation.test.ts +220 -0
- package/test-integration/memory.test.ts +204 -0
- package/tsconfig.build.json +12 -0
- package/tsconfig.json +1 -1
- package/scripts/examples/telegram-ink-ui.ts +0 -302
- package/scripts/examples/using-openai-codex.ts +0 -23
- package/scripts/examples/vm-loading-esm-modules.ts +0 -16
|
@@ -3,8 +3,7 @@ import { commands } from '../command.js'
|
|
|
3
3
|
import { CommandOptionsSchema } from '../schemas/base.js'
|
|
4
4
|
import type { ContainerContext } from '../container.js'
|
|
5
5
|
import type { MCPServer } from '../servers/mcp.js'
|
|
6
|
-
import {
|
|
7
|
-
import { generateScaffold } from '../scaffolds/template.js'
|
|
6
|
+
import { mcpReadme } from '../scaffolds/generated.js'
|
|
8
7
|
|
|
9
8
|
declare module '../command.js' {
|
|
10
9
|
interface AvailableCommands {
|
|
@@ -21,8 +20,18 @@ export const argsSchema = CommandOptionsSchema.extend({
|
|
|
21
20
|
.describe('Stdio framing compatibility profile. Defaults to standard. Can also be set via MCP_STDIO_COMPAT.'),
|
|
22
21
|
})
|
|
23
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Run a luca CLI command as a subprocess and return its output.
|
|
25
|
+
* Always spawns fresh so callers see the latest project code.
|
|
26
|
+
*/
|
|
27
|
+
async function lucaCLI(proc: any, command: string, args: string[] = []): Promise<{ stdout: string; stderr: string; exitCode: number }> {
|
|
28
|
+
const result = await proc.spawnAndCapture('luca', [command, ...args])
|
|
29
|
+
return { stdout: result.stdout.trim(), stderr: result.stderr.trim(), exitCode: result.exitCode ?? 0 }
|
|
30
|
+
}
|
|
31
|
+
|
|
24
32
|
export default async function mcpSandbox(options: z.infer<typeof argsSchema>, context: ContainerContext) {
|
|
25
33
|
const container = context.container as any
|
|
34
|
+
const proc = container.feature('proc')
|
|
26
35
|
const envCompat = process.env.MCP_HTTP_COMPAT?.toLowerCase()
|
|
27
36
|
const resolvedCompat = options.mcpCompat || (envCompat === 'codex' ? 'codex' : 'standard')
|
|
28
37
|
const envStdioCompat = process.env.MCP_STDIO_COMPAT?.toLowerCase()
|
|
@@ -38,26 +47,6 @@ export default async function mcpSandbox(options: z.infer<typeof argsSchema>, co
|
|
|
38
47
|
stdioCompat: options.stdioCompat,
|
|
39
48
|
}) as MCPServer
|
|
40
49
|
|
|
41
|
-
// Persistent VM context shared across eval calls so variables survive between invocations
|
|
42
|
-
const vmFeature = container.feature('vm')
|
|
43
|
-
const sandboxContext = vmFeature.createContext({
|
|
44
|
-
container,
|
|
45
|
-
console,
|
|
46
|
-
setTimeout,
|
|
47
|
-
setInterval,
|
|
48
|
-
clearTimeout,
|
|
49
|
-
clearInterval,
|
|
50
|
-
fetch,
|
|
51
|
-
Bun,
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
// Pre-populate sandbox with all enabled features
|
|
55
|
-
for (const name of container.features.available) {
|
|
56
|
-
try {
|
|
57
|
-
vmFeature.runSync(`var ${name} = container.feature('${name}')`, sandboxContext)
|
|
58
|
-
} catch {}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
50
|
// --- Tool: read_me ---
|
|
62
51
|
mcpServer.tool('read_me', {
|
|
63
52
|
description: [
|
|
@@ -78,22 +67,11 @@ export default async function mcpSandbox(options: z.infer<typeof argsSchema>, co
|
|
|
78
67
|
'Prefer this over installing npm packages — the container likely already has what you need.',
|
|
79
68
|
].join('\n'),
|
|
80
69
|
schema: z.object({}),
|
|
81
|
-
handler: () => {
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
} catch {}
|
|
87
|
-
|
|
88
|
-
try {
|
|
89
|
-
sections.push(container.clients.describeAll())
|
|
90
|
-
} catch {}
|
|
91
|
-
|
|
92
|
-
try {
|
|
93
|
-
sections.push(container.servers.describeAll())
|
|
94
|
-
} catch {}
|
|
95
|
-
|
|
96
|
-
return sections.join('\n\n---\n\n')
|
|
70
|
+
handler: async () => {
|
|
71
|
+
const { stdout, stderr } = await lucaCLI(proc, 'eval', [
|
|
72
|
+
'[container.features.describeAll(), container.clients.describeAll(), container.servers.describeAll()].join("\\n\\n---\\n\\n")',
|
|
73
|
+
])
|
|
74
|
+
return stdout || stderr
|
|
97
75
|
},
|
|
98
76
|
})
|
|
99
77
|
|
|
@@ -113,9 +91,11 @@ export default async function mcpSandbox(options: z.infer<typeof argsSchema>, co
|
|
|
113
91
|
description: z.string().optional()
|
|
114
92
|
.describe('Brief description of what this helper does'),
|
|
115
93
|
}),
|
|
116
|
-
handler: (args) => {
|
|
117
|
-
const
|
|
118
|
-
|
|
94
|
+
handler: async (args) => {
|
|
95
|
+
const cliArgs = [args.type, args.name]
|
|
96
|
+
if (args.description) cliArgs.push('--description', args.description)
|
|
97
|
+
const { stdout, stderr } = await lucaCLI(proc, 'scaffold', cliArgs)
|
|
98
|
+
return stdout || stderr
|
|
119
99
|
},
|
|
120
100
|
})
|
|
121
101
|
|
|
@@ -124,13 +104,11 @@ export default async function mcpSandbox(options: z.infer<typeof argsSchema>, co
|
|
|
124
104
|
description: [
|
|
125
105
|
'Evaluate JavaScript/TypeScript code in a Luca container sandbox.',
|
|
126
106
|
'Use this to prototype and test container API calls before writing them into files.',
|
|
127
|
-
'
|
|
107
|
+
'Each call runs in a fresh luca process — always reflects the latest project code.',
|
|
128
108
|
'',
|
|
129
109
|
'The sandbox has a live `container` object and all enabled features as top-level variables',
|
|
130
110
|
'(e.g. `fs`, `git`, `ui`, `vm`, `proc`, `networking`, etc).',
|
|
131
111
|
'',
|
|
132
|
-
'Variables you define persist across calls, so you can build up state incrementally.',
|
|
133
|
-
'',
|
|
134
112
|
'The result of the last expression is returned. For async code, use `await`.',
|
|
135
113
|
'',
|
|
136
114
|
'Quick reference:',
|
|
@@ -149,46 +127,11 @@ export default async function mcpSandbox(options: z.infer<typeof argsSchema>, co
|
|
|
149
127
|
code: z.string().describe('JavaScript code to evaluate in the Luca container sandbox'),
|
|
150
128
|
}),
|
|
151
129
|
handler: async (args) => {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
// Include captured console output if any
|
|
158
|
-
if (calls.length > 0) {
|
|
159
|
-
const consoleLines = calls.map(c => {
|
|
160
|
-
const prefix = c.method === 'log' ? '' : `[${c.method}] `
|
|
161
|
-
return prefix + c.args.map(a => typeof a === 'object' ? JSON.stringify(a, null, 2) : String(a)).join(' ')
|
|
162
|
-
})
|
|
163
|
-
content.push({ type: 'text' as const, text: consoleLines.join('\n') })
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// Include the result
|
|
167
|
-
let text: string
|
|
168
|
-
if (result === undefined) {
|
|
169
|
-
text = 'undefined'
|
|
170
|
-
} else if (result === null) {
|
|
171
|
-
text = 'null'
|
|
172
|
-
} else if (typeof result === 'string') {
|
|
173
|
-
text = result
|
|
174
|
-
} else if (typeof result === 'object') {
|
|
175
|
-
try {
|
|
176
|
-
text = JSON.stringify(result, null, 2)
|
|
177
|
-
} catch {
|
|
178
|
-
text = String(result)
|
|
179
|
-
}
|
|
180
|
-
} else {
|
|
181
|
-
text = String(result)
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
content.push({ type: 'text' as const, text })
|
|
185
|
-
|
|
186
|
-
return { content }
|
|
187
|
-
} catch (error: any) {
|
|
188
|
-
return {
|
|
189
|
-
content: [{ type: 'text' as const, text: `Error: ${error.message}\n\n${error.stack || ''}` }],
|
|
190
|
-
isError: true,
|
|
191
|
-
}
|
|
130
|
+
const { stdout, stderr, exitCode } = await lucaCLI(proc, 'eval', [args.code])
|
|
131
|
+
const text = stdout || stderr || 'undefined'
|
|
132
|
+
return {
|
|
133
|
+
content: [{ type: 'text' as const, text }],
|
|
134
|
+
isError: exitCode !== 0,
|
|
192
135
|
}
|
|
193
136
|
},
|
|
194
137
|
})
|
|
@@ -207,8 +150,12 @@ export default async function mcpSandbox(options: z.infer<typeof argsSchema>, co
|
|
|
207
150
|
section: z.enum(['methods', 'getters', 'events', 'state', 'options', 'envVars']).optional()
|
|
208
151
|
.describe('Optional section to filter to. Omit for full overview.'),
|
|
209
152
|
}),
|
|
210
|
-
handler: (args) => {
|
|
211
|
-
|
|
153
|
+
handler: async (args) => {
|
|
154
|
+
const code = args.section
|
|
155
|
+
? `container.introspectAsText("${args.section}")`
|
|
156
|
+
: 'container.introspectAsText()'
|
|
157
|
+
const { stdout, stderr } = await lucaCLI(proc, 'eval', [code])
|
|
158
|
+
return stdout || stderr
|
|
212
159
|
},
|
|
213
160
|
})
|
|
214
161
|
|
|
@@ -224,22 +171,11 @@ export default async function mcpSandbox(options: z.infer<typeof argsSchema>, co
|
|
|
224
171
|
registry: z.enum(['features', 'clients', 'servers', 'commands', 'endpoints'])
|
|
225
172
|
.describe('Which registry to list'),
|
|
226
173
|
}),
|
|
227
|
-
handler: (args) => {
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
const lines = [`# Available ${args.registry}\n`]
|
|
233
|
-
for (const name of names) {
|
|
234
|
-
try {
|
|
235
|
-
const Ctor = registry.lookup(name) as any
|
|
236
|
-
const desc = Ctor.description || ''
|
|
237
|
-
lines.push(`- **${name}**${desc ? `: ${desc}` : ''}`)
|
|
238
|
-
} catch {
|
|
239
|
-
lines.push(`- **${name}**`)
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
return lines.join('\n')
|
|
174
|
+
handler: async (args) => {
|
|
175
|
+
const { stdout, stderr } = await lucaCLI(proc, 'eval', [
|
|
176
|
+
`container.${args.registry}.available.map(n => { try { const C = container.${args.registry}.lookup(n); return "- **" + n + "**" + (C.description ? ": " + C.description : "") } catch { return "- **" + n + "**" } }).join("\\n")`,
|
|
177
|
+
])
|
|
178
|
+
return stdout || stderr
|
|
243
179
|
},
|
|
244
180
|
})
|
|
245
181
|
|
|
@@ -254,24 +190,15 @@ export default async function mcpSandbox(options: z.infer<typeof argsSchema>, co
|
|
|
254
190
|
'Use list_registry or find_capability first to see what is available.',
|
|
255
191
|
].join('\n'),
|
|
256
192
|
schema: z.object({
|
|
257
|
-
|
|
258
|
-
.describe('Which registry the helper belongs to'),
|
|
259
|
-
name: z.string().describe('Name of the helper (e.g. "fs", "rest", "express")'),
|
|
193
|
+
name: z.string().describe('Name of the helper (e.g. "fs", "rest", "express", "serve")'),
|
|
260
194
|
section: z.enum(['methods', 'getters', 'events', 'state', 'options', 'envVars']).optional()
|
|
261
195
|
.describe('Optional section to filter to. Omit for full documentation.'),
|
|
262
196
|
}),
|
|
263
|
-
handler: (args) => {
|
|
264
|
-
const
|
|
265
|
-
if (
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
}
|
|
269
|
-
try {
|
|
270
|
-
const Ctor = registry.lookup(args.name) as any
|
|
271
|
-
return Ctor.introspectAsText(args.section)
|
|
272
|
-
} catch (e: any) {
|
|
273
|
-
return `Error describing ${args.name}: ${e.message}`
|
|
274
|
-
}
|
|
197
|
+
handler: async (args) => {
|
|
198
|
+
const describeArgs = [args.name]
|
|
199
|
+
if (args.section) describeArgs.push(args.section)
|
|
200
|
+
const { stdout, stderr } = await lucaCLI(proc, 'describe', describeArgs)
|
|
201
|
+
return stdout || stderr
|
|
275
202
|
},
|
|
276
203
|
})
|
|
277
204
|
|
|
@@ -282,8 +209,7 @@ export default async function mcpSandbox(options: z.infer<typeof argsSchema>, co
|
|
|
282
209
|
'Use this to inspect a live, running instance — see its current state,',
|
|
283
210
|
'check method signatures, and understand runtime behavior.',
|
|
284
211
|
'',
|
|
285
|
-
'
|
|
286
|
-
'rich markdown documentation available on any Helper instance at runtime.',
|
|
212
|
+
'Runs in a fresh process so you always see the latest code.',
|
|
287
213
|
'Optionally filter to a specific section.',
|
|
288
214
|
].join('\n'),
|
|
289
215
|
schema: z.object({
|
|
@@ -293,20 +219,17 @@ export default async function mcpSandbox(options: z.infer<typeof argsSchema>, co
|
|
|
293
219
|
section: z.enum(['methods', 'getters', 'events', 'state', 'options', 'envVars']).optional()
|
|
294
220
|
.describe('Optional section to filter to. Omit for full introspection.'),
|
|
295
221
|
}),
|
|
296
|
-
handler: (args) => {
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
} catch (e: any) {
|
|
308
|
-
return `Error inspecting ${args.type} "${args.name}": ${e.message}`
|
|
309
|
-
}
|
|
222
|
+
handler: async (args) => {
|
|
223
|
+
const accessor = args.type === 'feature'
|
|
224
|
+
? `container.feature('${args.name}')`
|
|
225
|
+
: args.type === 'client'
|
|
226
|
+
? `container.client('${args.name}')`
|
|
227
|
+
: `container.server('${args.name}')`
|
|
228
|
+
const code = args.section
|
|
229
|
+
? `${accessor}.introspectAsText("${args.section}")`
|
|
230
|
+
: `${accessor}.introspectAsText()`
|
|
231
|
+
const { stdout, stderr } = await lucaCLI(proc, 'eval', [code])
|
|
232
|
+
return stdout || stderr
|
|
310
233
|
},
|
|
311
234
|
})
|
|
312
235
|
|
|
@@ -318,7 +241,8 @@ export default async function mcpSandbox(options: z.infer<typeof argsSchema>, co
|
|
|
318
241
|
content: [
|
|
319
242
|
'# Luca Container Sandbox',
|
|
320
243
|
'',
|
|
321
|
-
'You have access to a live Luca container through the `eval` tool.
|
|
244
|
+
'You have access to a live Luca container through the `eval` tool. Each call runs in a fresh process,',
|
|
245
|
+
'so you always see the latest project code. Use the `eval` tool to prototype and explore.',
|
|
322
246
|
'',
|
|
323
247
|
'## Discovering what is available',
|
|
324
248
|
'',
|
|
@@ -353,20 +277,6 @@ export default async function mcpSandbox(options: z.infer<typeof argsSchema>, co
|
|
|
353
277
|
'git.log({ max: 5 }) // Recent git commits',
|
|
354
278
|
'proc.exec("ls -la") // Run a shell command',
|
|
355
279
|
'```',
|
|
356
|
-
'',
|
|
357
|
-
'### Persistent state',
|
|
358
|
-
'Variables you define in one eval call persist to the next:',
|
|
359
|
-
'```',
|
|
360
|
-
'// Call 1',
|
|
361
|
-
'const data = fs.readFile("package.json")',
|
|
362
|
-
'// Call 2',
|
|
363
|
-
'JSON.parse(data).name // still has `data` from previous call',
|
|
364
|
-
'```',
|
|
365
|
-
'',
|
|
366
|
-
'## Recommended first steps',
|
|
367
|
-
'1. `container.features.available` — see what features exist',
|
|
368
|
-
'2. Pick an interesting feature and `container.features.describe("name")` it',
|
|
369
|
-
'3. Try using the feature directly',
|
|
370
280
|
].join('\n'),
|
|
371
281
|
}],
|
|
372
282
|
})
|
|
@@ -375,10 +285,10 @@ export default async function mcpSandbox(options: z.infer<typeof argsSchema>, co
|
|
|
375
285
|
mcpServer.prompt('introspect', {
|
|
376
286
|
description: 'Get full introspection of the Luca container — all registries, state, methods, events, and environment info.',
|
|
377
287
|
handler: async () => {
|
|
378
|
-
const
|
|
288
|
+
const { stdout } = await lucaCLI(proc, 'eval', ['container.introspectAsText()'])
|
|
379
289
|
return [{
|
|
380
290
|
role: 'user' as const,
|
|
381
|
-
content: `Here is the full container introspection:\n\n${
|
|
291
|
+
content: `Here is the full container introspection:\n\n${stdout}`,
|
|
382
292
|
}]
|
|
383
293
|
},
|
|
384
294
|
})
|
|
@@ -388,7 +298,10 @@ export default async function mcpSandbox(options: z.infer<typeof argsSchema>, co
|
|
|
388
298
|
name: 'Container Info',
|
|
389
299
|
description: 'Full introspection of the running Luca container',
|
|
390
300
|
mimeType: 'text/markdown',
|
|
391
|
-
handler: () =>
|
|
301
|
+
handler: async () => {
|
|
302
|
+
const { stdout } = await lucaCLI(proc, 'eval', ['container.introspectAsText()'])
|
|
303
|
+
return stdout
|
|
304
|
+
},
|
|
392
305
|
})
|
|
393
306
|
|
|
394
307
|
// --- Resource: feature list ---
|
|
@@ -396,18 +309,11 @@ export default async function mcpSandbox(options: z.infer<typeof argsSchema>, co
|
|
|
396
309
|
name: 'Available Features',
|
|
397
310
|
description: 'List of all registered features with descriptions',
|
|
398
311
|
mimeType: 'text/markdown',
|
|
399
|
-
handler: () => {
|
|
400
|
-
const
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
const desc = Ctor.description || ''
|
|
405
|
-
lines.push(`- **${name}**: ${desc}`)
|
|
406
|
-
} catch {
|
|
407
|
-
lines.push(`- **${name}**`)
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
return lines.join('\n')
|
|
312
|
+
handler: async () => {
|
|
313
|
+
const { stdout } = await lucaCLI(proc, 'eval', [
|
|
314
|
+
'"# Available Features\\n" + container.features.available.map(n => { try { const C = container.features.lookup(n); return "- **" + n + "**: " + (C.description || "") } catch { return "- **" + n + "**" } }).join("\\n")',
|
|
315
|
+
])
|
|
316
|
+
return stdout
|
|
411
317
|
},
|
|
412
318
|
})
|
|
413
319
|
|
|
@@ -2,6 +2,7 @@ import { z } from 'zod'
|
|
|
2
2
|
import { commands } from '../command.js'
|
|
3
3
|
import { CommandOptionsSchema } from '../schemas/base.js'
|
|
4
4
|
import type { ContainerContext } from '../container.js'
|
|
5
|
+
import type { NodeContainer } from '../node/container.js'
|
|
5
6
|
|
|
6
7
|
declare module '../command.js' {
|
|
7
8
|
interface AvailableCommands {
|
|
@@ -14,7 +15,7 @@ export const argsSchema = CommandOptionsSchema.extend({
|
|
|
14
15
|
})
|
|
15
16
|
|
|
16
17
|
export async function apiDocs(options: z.infer<typeof argsSchema>, context: ContainerContext) {
|
|
17
|
-
const
|
|
18
|
+
const container = context.container as unknown as NodeContainer
|
|
18
19
|
await container.helpers.discoverAll()
|
|
19
20
|
const outputFolder = options.outputPath ? container.paths.resolve(options.outputPath) : container.paths.resolve('docs','luca')
|
|
20
21
|
|
|
@@ -22,19 +23,20 @@ export async function apiDocs(options: z.infer<typeof argsSchema>, context: Cont
|
|
|
22
23
|
outputFolder
|
|
23
24
|
)
|
|
24
25
|
|
|
25
|
-
const mkPath = (...args) => container.paths.resolve(outputFolder, ...args)
|
|
26
|
+
const mkPath = (...args: string[]) => container.paths.resolve(outputFolder, ...args)
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
await container.fs.writeFileAsync(mkPath('agi-container.md'), (container as any).introspectAsText())
|
|
28
29
|
|
|
29
|
-
for(
|
|
30
|
-
const
|
|
31
|
-
const
|
|
30
|
+
for(const reg of ['features','clients','servers']) {
|
|
31
|
+
const registry = (container as any)[reg]
|
|
32
|
+
const helperIds: string[] = registry.available
|
|
33
|
+
const folder = mkPath(reg)
|
|
32
34
|
await container.fs.ensureFolder(folder)
|
|
33
35
|
|
|
34
36
|
await Promise.all(
|
|
35
|
-
helperIds.map((helperId) => container.fs.writeFileAsync(
|
|
37
|
+
helperIds.map((helperId: string) => container.fs.writeFileAsync(
|
|
36
38
|
container.paths.resolve(folder, `${helperId}.md`),
|
|
37
|
-
|
|
39
|
+
registry.describe(helperId)
|
|
38
40
|
))
|
|
39
41
|
)
|
|
40
42
|
}
|
package/src/commands/select.ts
CHANGED
|
@@ -13,7 +13,7 @@ declare module '../command.js' {
|
|
|
13
13
|
export const argsSchema = CommandOptionsSchema.extend({
|
|
14
14
|
json: z.boolean().default(false).describe('Output result as raw JSON (data only, no metadata)'),
|
|
15
15
|
noCache: z.boolean().default(false).describe('Skip cache lookup and force a fresh run'),
|
|
16
|
-
})
|
|
16
|
+
}).passthrough()
|
|
17
17
|
|
|
18
18
|
export default async function selectCommand(options: z.infer<typeof argsSchema>, context: ContainerContext) {
|
|
19
19
|
const container = context.container as any
|
|
@@ -42,13 +42,18 @@ export default async function selectCommand(options: z.infer<typeof argsSchema>,
|
|
|
42
42
|
|
|
43
43
|
const instance = container.select(name)
|
|
44
44
|
|
|
45
|
-
// Pass remaining args (after command name and selector name) as input
|
|
46
|
-
|
|
45
|
+
// Pass remaining args (after command name and selector name) as input.
|
|
46
|
+
// Pull from container.argv directly — the select command's own argsSchema
|
|
47
|
+
// would otherwise strip selector-specific keys during Zod parse.
|
|
48
|
+
const rawArgv = { ...(container as any).argv }
|
|
49
|
+
const selectorArgs: Record<string, any> = { ...rawArgv }
|
|
47
50
|
delete selectorArgs._
|
|
48
51
|
delete selectorArgs.json
|
|
49
52
|
delete selectorArgs.noCache
|
|
50
53
|
delete selectorArgs.cache
|
|
51
54
|
delete selectorArgs.dispatchSource
|
|
55
|
+
delete selectorArgs.help
|
|
56
|
+
delete selectorArgs.name
|
|
52
57
|
|
|
53
58
|
// minimist turns --no-cache into { cache: false }
|
|
54
59
|
const skipCache = options.noCache || (container.argv.cache === false)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { IntrospectionSection, MethodIntrospection, GetterIntrospection, HelperIntrospection } from './introspection/index.js'
|
|
2
2
|
import { presentIntrospectionAsMarkdown } from './helper.js'
|
|
3
|
+
import { z } from 'zod'
|
|
3
4
|
|
|
4
5
|
type Platform = 'browser' | 'server' | 'node' | 'all'
|
|
5
6
|
|
|
@@ -189,93 +190,78 @@ export class ContainerDescriber {
|
|
|
189
190
|
* Generate tool definitions suitable for use with AI assistant tool-calling interfaces.
|
|
190
191
|
* Registry names in the enum are populated dynamically from the container.
|
|
191
192
|
*/
|
|
192
|
-
toTools():
|
|
193
|
-
const registryEnum = this.registryNames
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
193
|
+
toTools(): { schemas: Record<string, z.ZodType>; handlers: Record<string, Function> } {
|
|
194
|
+
const registryEnum = this.registryNames as [string, ...string[]]
|
|
195
|
+
const sectionEnum = ['description', 'usage', 'methods', 'getters', 'events', 'state', 'options', 'envVars', 'examples'] as const
|
|
196
|
+
const platformEnum = ['browser', 'server', 'all'] as const
|
|
197
|
+
|
|
198
|
+
const schemas: Record<string, z.ZodType> = {
|
|
199
|
+
describe_container: z.object({
|
|
200
|
+
sections: z.array(z.enum(sectionEnum)).optional().describe('Which sections to include. Omit for all.'),
|
|
201
|
+
}).describe('Describe the container itself — its class, registries, and configuration.'),
|
|
202
|
+
|
|
203
|
+
describe_registry: z.object({
|
|
204
|
+
registry: z.enum(registryEnum).describe(`Which registry to describe. Available: ${registryEnum.join(', ')}`),
|
|
205
|
+
platform: z.enum(platformEnum).optional().describe('Filter by platform. Defaults to all.'),
|
|
206
|
+
sections: z.array(z.enum(sectionEnum)).optional().describe('Which sections to include per helper. Omit for concise index.'),
|
|
207
|
+
}).describe(`List all helpers in a registry with concise summaries. Available registries: ${registryEnum.join(', ')}`),
|
|
208
|
+
|
|
209
|
+
describe_helper: z.object({
|
|
210
|
+
target: z.string().describe('The helper to describe. Examples: "fs", "features.fs", "fs.readFile", "ui.banner"'),
|
|
211
|
+
platform: z.enum(platformEnum).optional().describe('Filter by platform. Defaults to all.'),
|
|
212
|
+
sections: z.array(z.enum(sectionEnum)).optional().describe('Which sections to include. Omit for all.'),
|
|
213
|
+
}).describe('Describe a specific helper by name. Supports qualified names like "features.fs" or unqualified like "fs". Also supports member access like "fs.readFile" or "ui.banner".'),
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const handlers: Record<string, Function> = {
|
|
217
|
+
describe_container: async (args: any) => {
|
|
218
|
+
const result = await this.describeContainer({ sections: args.sections })
|
|
219
|
+
return result.text
|
|
214
220
|
},
|
|
215
|
-
{
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
registry: {
|
|
222
|
-
type: 'string',
|
|
223
|
-
enum: registryEnum,
|
|
224
|
-
description: 'Which registry to describe.',
|
|
225
|
-
},
|
|
226
|
-
platform: {
|
|
227
|
-
type: 'string',
|
|
228
|
-
enum: ['browser', 'server', 'all'],
|
|
229
|
-
description: 'Filter by platform. Defaults to all.',
|
|
230
|
-
},
|
|
231
|
-
sections: {
|
|
232
|
-
type: 'array',
|
|
233
|
-
items: { type: 'string', enum: ['description', 'usage', 'methods', 'getters', 'events', 'state', 'options', 'envVars', 'examples'] },
|
|
234
|
-
description: 'Which sections to include per helper. Omit for concise index.',
|
|
235
|
-
},
|
|
236
|
-
},
|
|
237
|
-
required: ['registry'],
|
|
238
|
-
},
|
|
239
|
-
execute: async (args: any) => {
|
|
240
|
-
const result = await this.describeRegistry(args.registry, {
|
|
241
|
-
sections: args.sections,
|
|
242
|
-
platform: args.platform,
|
|
243
|
-
})
|
|
244
|
-
return result.text
|
|
245
|
-
},
|
|
221
|
+
describe_registry: async (args: any) => {
|
|
222
|
+
const result = await this.describeRegistry(args.registry, {
|
|
223
|
+
sections: args.sections,
|
|
224
|
+
platform: args.platform,
|
|
225
|
+
})
|
|
226
|
+
return result.text
|
|
246
227
|
},
|
|
247
|
-
{
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
target: {
|
|
254
|
-
type: 'string',
|
|
255
|
-
description: 'The helper to describe. Examples: "fs", "features.fs", "fs.readFile", "ui.banner"',
|
|
256
|
-
},
|
|
257
|
-
platform: {
|
|
258
|
-
type: 'string',
|
|
259
|
-
enum: ['browser', 'server', 'all'],
|
|
260
|
-
description: 'Filter by platform. Defaults to all.',
|
|
261
|
-
},
|
|
262
|
-
sections: {
|
|
263
|
-
type: 'array',
|
|
264
|
-
items: { type: 'string', enum: ['description', 'usage', 'methods', 'getters', 'events', 'state', 'options', 'envVars', 'examples'] },
|
|
265
|
-
description: 'Which sections to include. Omit for all.',
|
|
266
|
-
},
|
|
267
|
-
},
|
|
268
|
-
required: ['target'],
|
|
269
|
-
},
|
|
270
|
-
execute: async (args: any) => {
|
|
271
|
-
const result = await this.describeHelper(args.target, {
|
|
272
|
-
sections: args.sections,
|
|
273
|
-
platform: args.platform,
|
|
274
|
-
})
|
|
275
|
-
return result.text
|
|
276
|
-
},
|
|
228
|
+
describe_helper: async (args: any) => {
|
|
229
|
+
const result = await this.describeHelper(args.target, {
|
|
230
|
+
sections: args.sections,
|
|
231
|
+
platform: args.platform,
|
|
232
|
+
})
|
|
233
|
+
return result.text
|
|
277
234
|
},
|
|
278
|
-
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return { schemas, handlers }
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Register the describer tools on an assistant and append a system prompt
|
|
242
|
+
* extension explaining how and when to use them.
|
|
243
|
+
*
|
|
244
|
+
* @param assistant - Any assistant instance that exposes `use()` and `addSystemPromptExtension()`
|
|
245
|
+
*/
|
|
246
|
+
setupToolsConsumer(assistant: {
|
|
247
|
+
use: (tools: { schemas: Record<string, z.ZodType>; handlers: Record<string, Function> }) => void
|
|
248
|
+
addSystemPromptExtension: (key: string, value: string) => void
|
|
249
|
+
}): void {
|
|
250
|
+
assistant.use(this.toTools())
|
|
251
|
+
|
|
252
|
+
const registries = this.registryNames.join(', ')
|
|
253
|
+
|
|
254
|
+
assistant.addSystemPromptExtension('container_describer', `
|
|
255
|
+
## Container Introspection Tools
|
|
256
|
+
|
|
257
|
+
You have access to three tools for exploring the runtime container and its helpers:
|
|
258
|
+
|
|
259
|
+
- **describe_container** — Overview of the container itself: its registries, configuration, and what it provides.
|
|
260
|
+
- **describe_registry** — List all helpers in a registry with concise summaries. Available registries: ${registries}.
|
|
261
|
+
- **describe_helper** — Full docs for a specific helper. Accepts unqualified names ("fs"), registry-qualified names ("features.fs"), or member access ("fs.readFile", "ui.banner").
|
|
262
|
+
|
|
263
|
+
Use these tools whenever you are unsure what helpers are available, what a helper does, or how to call one of its methods. Always prefer introspecting the container over guessing at method signatures.
|
|
264
|
+
`.trim())
|
|
279
265
|
}
|
|
280
266
|
|
|
281
267
|
// --- Resolution ---
|