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