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,153 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
import { FeatureStateSchema, FeatureOptionsSchema } from '../../schemas/base.js'
|
|
3
|
+
import crypto from 'node:crypto'
|
|
4
|
+
import { Feature } from '../feature.js'
|
|
5
|
+
import { type ContainerContext } from '../../container.js'
|
|
6
|
+
|
|
7
|
+
export const VaultStateSchema = FeatureStateSchema.extend({
|
|
8
|
+
/** Secret key buffer used for encryption/decryption */
|
|
9
|
+
secret: z.custom<Buffer>().optional().describe('Secret key buffer used for encryption/decryption'),
|
|
10
|
+
})
|
|
11
|
+
export type VaultState = z.infer<typeof VaultStateSchema>
|
|
12
|
+
|
|
13
|
+
export const VaultOptionsSchema = FeatureOptionsSchema.extend({
|
|
14
|
+
/** Secret key as Buffer or base64 string for encryption */
|
|
15
|
+
secret: z.union([z.custom<Buffer>(), z.string()]).optional().describe('Secret key as Buffer or base64 string for encryption'),
|
|
16
|
+
})
|
|
17
|
+
export type VaultOptions = z.infer<typeof VaultOptionsSchema>
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The Vault feature provides encryption and decryption capabilities using AES-256-GCM.
|
|
21
|
+
*
|
|
22
|
+
* This feature allows you to securely encrypt and decrypt sensitive data using
|
|
23
|
+
* industry-standard encryption. It manages secret keys and provides a simple
|
|
24
|
+
* interface for cryptographic operations.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const vault = container.feature('vault')
|
|
29
|
+
*
|
|
30
|
+
* // Encrypt sensitive data
|
|
31
|
+
* const encrypted = vault.encrypt('sensitive information')
|
|
32
|
+
* console.log(encrypted) // Base64 encoded encrypted data
|
|
33
|
+
*
|
|
34
|
+
* // Decrypt the data
|
|
35
|
+
* const decrypted = vault.decrypt(encrypted)
|
|
36
|
+
* console.log(decrypted) // 'sensitive information'
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @extends Feature
|
|
40
|
+
*/
|
|
41
|
+
export class Vault extends Feature<VaultState, VaultOptions> {
|
|
42
|
+
static override shortcut = 'features.vault' as const
|
|
43
|
+
static override stateSchema = VaultStateSchema
|
|
44
|
+
static override optionsSchema = VaultOptionsSchema
|
|
45
|
+
static { Feature.register(this, 'vault') }
|
|
46
|
+
|
|
47
|
+
constructor(options: VaultOptions, context: ContainerContext) {
|
|
48
|
+
let secret = options.secret
|
|
49
|
+
|
|
50
|
+
if (typeof secret === 'string') {
|
|
51
|
+
secret = Buffer.from(secret, 'base64')
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
super({ ...options, secret }, context)
|
|
55
|
+
|
|
56
|
+
this.state.set('secret', secret)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Gets the secret key as a base64-encoded string.
|
|
61
|
+
*
|
|
62
|
+
* @returns {string | undefined} The secret key encoded as base64, or undefined if no secret is set
|
|
63
|
+
*/
|
|
64
|
+
get secretText() {
|
|
65
|
+
return this.state.get('secret')!?.toString('base64')
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Gets or generates a secret key for encryption operations.
|
|
70
|
+
*
|
|
71
|
+
* @param {object} [options={}] - Options for secret key handling
|
|
72
|
+
* @param {boolean} [options.refresh=false] - Whether to generate a new secret key
|
|
73
|
+
* @param {boolean} [options.set=true] - Whether to store the generated key in state
|
|
74
|
+
* @returns {Buffer} The secret key as a Buffer
|
|
75
|
+
*/
|
|
76
|
+
secret({ refresh = false, set = true } = {}) : Buffer {
|
|
77
|
+
if (!refresh && this.state.get('secret')) {
|
|
78
|
+
return this.state.get('secret')!
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const val = generateSecretKey()
|
|
82
|
+
|
|
83
|
+
if(set && !this.state.get('secret')) {
|
|
84
|
+
this.state.set('secret', val)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return val
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Decrypts an encrypted payload that was created by the encrypt method.
|
|
92
|
+
*
|
|
93
|
+
* @param {string} payload - The encrypted payload to decrypt (base64 encoded with delimiters)
|
|
94
|
+
* @returns {string} The decrypted plaintext
|
|
95
|
+
* @throws {Error} Throws an error if decryption fails or the payload is malformed
|
|
96
|
+
*/
|
|
97
|
+
decrypt(payload: string) {
|
|
98
|
+
const [iv, ciphertext, authTag] = payload.split('\n------\n').map((v) => Buffer.from(v, 'base64'))
|
|
99
|
+
return this._decrypt(ciphertext!, iv!, authTag!)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Encrypts a plaintext string using AES-256-GCM encryption.
|
|
104
|
+
*
|
|
105
|
+
* @param {string} payload - The plaintext string to encrypt
|
|
106
|
+
* @returns {string} The encrypted payload as a base64 encoded string with delimiters
|
|
107
|
+
*/
|
|
108
|
+
encrypt(payload: string) {
|
|
109
|
+
const { iv, ciphertext, authTag } = this._encrypt(payload)
|
|
110
|
+
|
|
111
|
+
return [
|
|
112
|
+
iv.toString('base64'),
|
|
113
|
+
ciphertext.toString('base64'),
|
|
114
|
+
authTag.toString('base64')
|
|
115
|
+
].join('\n------\n')
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
private _encrypt(payload: string) {
|
|
119
|
+
const secret = this.secret()
|
|
120
|
+
const { iv, ciphertext, authTag } = encrypt(payload, secret)
|
|
121
|
+
return { iv, ciphertext, authTag }
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
private _decrypt(cipher: Buffer, iv: Buffer, authTag: Buffer) {
|
|
125
|
+
return decrypt(cipher, this.secret(), iv, authTag)
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export default Vault
|
|
130
|
+
function generateSecretKey(): Buffer {
|
|
131
|
+
return crypto.randomBytes(32);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
type EncryptionResult = {
|
|
135
|
+
iv: Buffer;
|
|
136
|
+
ciphertext: Buffer;
|
|
137
|
+
authTag: Buffer;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
function encrypt(plaintext: string, secretKey: Buffer): EncryptionResult {
|
|
141
|
+
const iv = crypto.randomBytes(12);
|
|
142
|
+
const cipher = crypto.createCipheriv("aes-256-gcm", secretKey, iv);
|
|
143
|
+
const ciphertext = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
|
|
144
|
+
const authTag = cipher.getAuthTag();
|
|
145
|
+
return { iv, ciphertext, authTag };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function decrypt(ciphertext: Buffer, secretKey: Buffer, iv: Buffer, authTag: Buffer): string {
|
|
149
|
+
const decipher = crypto.createDecipheriv("aes-256-gcm", secretKey, iv);
|
|
150
|
+
decipher.setAuthTag(authTag);
|
|
151
|
+
const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString("utf8");
|
|
152
|
+
return plaintext;
|
|
153
|
+
}
|
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
import { createRequire } from 'module'
|
|
3
|
+
import { dirname } from 'path'
|
|
4
|
+
import { FeatureStateSchema, FeatureOptionsSchema } from '../../schemas/base.js'
|
|
5
|
+
import vm from 'vm'
|
|
6
|
+
import { Feature } from "../feature.js";
|
|
7
|
+
|
|
8
|
+
export const VMStateSchema = FeatureStateSchema.extend({})
|
|
9
|
+
export type VMState = z.infer<typeof VMStateSchema>
|
|
10
|
+
|
|
11
|
+
export const VMOptionsSchema = FeatureOptionsSchema.extend({
|
|
12
|
+
/** Default context object to inject into the VM execution environment */
|
|
13
|
+
context: z.any().describe('Default context object to inject into the VM execution environment'),
|
|
14
|
+
})
|
|
15
|
+
export type VMOptions = z.infer<typeof VMOptionsSchema>
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The VM feature provides Node.js virtual machine capabilities for executing JavaScript code.
|
|
19
|
+
*
|
|
20
|
+
* This feature wraps Node.js's built-in `vm` module to provide secure code execution
|
|
21
|
+
* in isolated contexts. It's useful for running untrusted code, creating sandboxed
|
|
22
|
+
* environments, or dynamically executing code with controlled access to variables and modules.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const vm = container.feature('vm')
|
|
27
|
+
*
|
|
28
|
+
* // Execute simple code
|
|
29
|
+
* const result = vm.run('1 + 2 + 3')
|
|
30
|
+
* console.log(result) // 6
|
|
31
|
+
*
|
|
32
|
+
* // Execute code with custom context
|
|
33
|
+
* const result2 = vm.run('greeting + " " + name', {
|
|
34
|
+
* greeting: 'Hello',
|
|
35
|
+
* name: 'World'
|
|
36
|
+
* })
|
|
37
|
+
* console.log(result2) // 'Hello World'
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* @extends Feature
|
|
41
|
+
*/
|
|
42
|
+
export class VM<
|
|
43
|
+
T extends VMState = VMState,
|
|
44
|
+
K extends VMOptions = VMOptions
|
|
45
|
+
> extends Feature<T, K> {
|
|
46
|
+
static override shortcut = "features.vm" as const
|
|
47
|
+
static override stateSchema = VMStateSchema
|
|
48
|
+
static override optionsSchema = VMOptionsSchema
|
|
49
|
+
static { Feature.register(this, 'vm') }
|
|
50
|
+
|
|
51
|
+
/** Map of virtual module IDs to their exports, consulted before Node's native require */
|
|
52
|
+
modules: Map<string, any> = new Map()
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Register a virtual module that will be available to `require()` inside VM-executed code.
|
|
56
|
+
* Modules registered here take precedence over Node's native resolution.
|
|
57
|
+
*
|
|
58
|
+
* @param id - The module specifier (e.g. `'luca'`, `'zod'`)
|
|
59
|
+
* @param exports - The module's exports object
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```typescript
|
|
63
|
+
* const vm = container.feature('vm')
|
|
64
|
+
* vm.defineModule('luca', { Container, Feature, fs, proc })
|
|
65
|
+
* vm.defineModule('zod', { z })
|
|
66
|
+
*
|
|
67
|
+
* // Now loadModule can resolve these in user code:
|
|
68
|
+
* // import { Container } from 'luca' → works
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
defineModule(id: string, exports: any): void {
|
|
72
|
+
this.modules.set(id, exports)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Build a require function that resolves from the virtual modules map first,
|
|
77
|
+
* falling back to Node's native `createRequire` for everything else.
|
|
78
|
+
*
|
|
79
|
+
* @param filePath - The file path to scope native require resolution to
|
|
80
|
+
* @returns A require function with `.resolve` preserved from the native require
|
|
81
|
+
*/
|
|
82
|
+
createRequireFor(filePath: string): ((id: string) => any) & { resolve: RequireResolve } {
|
|
83
|
+
const nodeRequire = createRequire(filePath)
|
|
84
|
+
const modules = this.modules
|
|
85
|
+
|
|
86
|
+
const customRequire = (id: string) => {
|
|
87
|
+
if (modules.has(id)) return modules.get(id)
|
|
88
|
+
return nodeRequire(id)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
customRequire.resolve = nodeRequire.resolve.bind(nodeRequire)
|
|
92
|
+
return customRequire
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Creates a new VM script from the provided code.
|
|
97
|
+
*
|
|
98
|
+
* This method compiles JavaScript code into a VM script that can be executed
|
|
99
|
+
* multiple times in different contexts. The script is pre-compiled for better
|
|
100
|
+
* performance when executing the same code repeatedly.
|
|
101
|
+
*
|
|
102
|
+
* @param {string} code - The JavaScript code to compile into a script
|
|
103
|
+
* @param {vm.ScriptOptions} [options] - Options for script compilation
|
|
104
|
+
* @returns {vm.Script} A compiled VM script ready for execution
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```typescript
|
|
108
|
+
* const script = vm.createScript('Math.max(a, b)')
|
|
109
|
+
*
|
|
110
|
+
* // Execute the script multiple times with different contexts
|
|
111
|
+
* const result1 = script.runInContext(vm.createContext({ a: 5, b: 3 }))
|
|
112
|
+
* const result2 = script.runInContext(vm.createContext({ a: 10, b: 20 }))
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
createScript(code: string, options?: vm.ScriptOptions): vm.Script {
|
|
116
|
+
return new vm.Script(code, {
|
|
117
|
+
...options
|
|
118
|
+
})
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Check whether an object has already been contextified by `vm.createContext()`.
|
|
123
|
+
*
|
|
124
|
+
* Useful to avoid double-contextifying when you're not sure if the caller
|
|
125
|
+
* passed a plain object or an existing context.
|
|
126
|
+
*
|
|
127
|
+
* @param ctx - The object to check
|
|
128
|
+
* @returns True if the object is a VM context
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```typescript
|
|
132
|
+
* const ctx = vm.createContext({ x: 1 })
|
|
133
|
+
* vm.isContext(ctx) // true
|
|
134
|
+
* vm.isContext({ x: 1 }) // false
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
isContext(ctx: unknown): ctx is vm.Context {
|
|
138
|
+
return typeof ctx === 'object' && ctx !== null && vm.isContext(ctx as vm.Context)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Create an isolated JavaScript execution context.
|
|
143
|
+
*
|
|
144
|
+
* Combines the container's context with any additional variables provided.
|
|
145
|
+
* If the input is already a VM context, it is returned as-is.
|
|
146
|
+
*
|
|
147
|
+
* @param ctx - Additional context variables to include
|
|
148
|
+
* @returns A VM context ready for script execution
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* ```typescript
|
|
152
|
+
* const context = vm.createContext({ user: { name: 'John' } })
|
|
153
|
+
* const result = vm.runSync('user.name', context)
|
|
154
|
+
* ```
|
|
155
|
+
*/
|
|
156
|
+
createContext(ctx: any = {}): vm.Context {
|
|
157
|
+
if (this.isContext(ctx)) return ctx
|
|
158
|
+
return vm.createContext({
|
|
159
|
+
console,
|
|
160
|
+
setTimeout,
|
|
161
|
+
setInterval,
|
|
162
|
+
clearTimeout,
|
|
163
|
+
clearInterval,
|
|
164
|
+
process,
|
|
165
|
+
Buffer,
|
|
166
|
+
URL,
|
|
167
|
+
URLSearchParams,
|
|
168
|
+
...this.container.context,
|
|
169
|
+
...ctx
|
|
170
|
+
})
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Executes JavaScript code in a controlled environment.
|
|
175
|
+
*
|
|
176
|
+
* This method creates a script from the provided code, sets up an execution context
|
|
177
|
+
* with the specified variables, and runs the code safely. It handles errors gracefully
|
|
178
|
+
* and returns either the result or the error object.
|
|
179
|
+
*
|
|
180
|
+
* @param {string} code - The JavaScript code to execute
|
|
181
|
+
* @param {any} [ctx={}] - Context variables to make available to the executing code
|
|
182
|
+
* @returns {any} The result of the code execution, or an Error object if execution failed
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* ```typescript
|
|
186
|
+
* // Simple calculation
|
|
187
|
+
* const result = vm.run('2 + 3 * 4')
|
|
188
|
+
* console.log(result) // 14
|
|
189
|
+
*
|
|
190
|
+
* // Using context variables
|
|
191
|
+
* const greeting = vm.run('`Hello ${name}!`', { name: 'Alice' })
|
|
192
|
+
* console.log(greeting) // 'Hello Alice!'
|
|
193
|
+
*
|
|
194
|
+
* // Array operations
|
|
195
|
+
* const sum = vm.run('numbers.reduce((a, b) => a + b, 0)', {
|
|
196
|
+
* numbers: [1, 2, 3, 4, 5]
|
|
197
|
+
* })
|
|
198
|
+
* console.log(sum) // 15
|
|
199
|
+
*
|
|
200
|
+
* // Error handling
|
|
201
|
+
* const error = vm.run('invalidFunction()')
|
|
202
|
+
* if (error instanceof Error) {
|
|
203
|
+
* console.log('Execution failed:', error.message)
|
|
204
|
+
* }
|
|
205
|
+
* ```
|
|
206
|
+
*/
|
|
207
|
+
/**
|
|
208
|
+
* Wrap code containing top-level `await` in an async IIFE, injecting
|
|
209
|
+
* `return` before the last expression so the value is not lost.
|
|
210
|
+
*
|
|
211
|
+
* If the code does not contain `await`, or is already wrapped in an
|
|
212
|
+
* async function/arrow, it is returned unchanged.
|
|
213
|
+
*/
|
|
214
|
+
wrapTopLevelAwait(code: string): string {
|
|
215
|
+
if (!/\bawait\b/.test(code) || /^\s*\(?\s*async\b/.test(code)) {
|
|
216
|
+
return code
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const lines = code.split('\n')
|
|
220
|
+
|
|
221
|
+
// Find the last non-empty line
|
|
222
|
+
let lastIdx = lines.length - 1
|
|
223
|
+
while (lastIdx > 0 && !(lines[lastIdx] ?? '').trim()) lastIdx--
|
|
224
|
+
|
|
225
|
+
let lastLine = lines[lastIdx] ?? ''
|
|
226
|
+
|
|
227
|
+
// For single-line code with semicolons (e.g. CLI eval), split the last line
|
|
228
|
+
// into statements and only try to return the final statement.
|
|
229
|
+
const stmts = lastLine.split(';').map(s => s.trim()).filter(Boolean)
|
|
230
|
+
if (stmts.length > 1) {
|
|
231
|
+
const finalStmt = stmts[stmts.length - 1]!
|
|
232
|
+
if (!/^\s*(var|let|const|if|for|while|switch|try|throw|class|function|return)\b/.test(finalStmt)) {
|
|
233
|
+
stmts[stmts.length - 1] = `return ${finalStmt}`
|
|
234
|
+
}
|
|
235
|
+
lines[lastIdx] = stmts.join('; ')
|
|
236
|
+
} else if (!/^\s*(var|let|const|if|for|while|switch|try|throw|class|function|return)\b/.test(lastLine)) {
|
|
237
|
+
lines[lastIdx] = `return ${lastLine}`
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return `(async () => {\n${lines.join('\n')}\n})()`
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
async run<T extends any>(code: string, ctx: any = {}): Promise<T> {
|
|
244
|
+
const wrapped = this.wrapTopLevelAwait(code)
|
|
245
|
+
const script = this.createScript(wrapped)
|
|
246
|
+
const context = this.isContext(ctx) ? ctx : this.createContext(ctx)
|
|
247
|
+
|
|
248
|
+
return (await script.runInContext(context)) as T
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Execute code and capture all console output as structured JSON.
|
|
253
|
+
*
|
|
254
|
+
* Returns both the execution result and an array of every `console.*` call
|
|
255
|
+
* made during execution, each entry recording the method name and arguments.
|
|
256
|
+
*
|
|
257
|
+
* @param code - The JavaScript code to execute
|
|
258
|
+
* @param ctx - Context variables to make available to the executing code
|
|
259
|
+
* @returns The result, an array of captured console calls, and the context
|
|
260
|
+
*
|
|
261
|
+
* @example
|
|
262
|
+
* ```typescript
|
|
263
|
+
* const { result, console: calls } = await vm.runCaptured('console.log("hi"); console.warn("oh"); 42')
|
|
264
|
+
* // result === 42
|
|
265
|
+
* // calls === [{ method: 'log', args: ['hi'] }, { method: 'warn', args: ['oh'] }]
|
|
266
|
+
* ```
|
|
267
|
+
*/
|
|
268
|
+
async runCaptured<T extends any>(code: string, ctx: any = {}): Promise<{
|
|
269
|
+
result: T
|
|
270
|
+
console: Array<{ method: string, args: any[] }>
|
|
271
|
+
context: vm.Context
|
|
272
|
+
}> {
|
|
273
|
+
const calls: Array<{ method: string, args: any[] }> = []
|
|
274
|
+
const captureConsole: Record<string, (...args: any[]) => void> = {}
|
|
275
|
+
|
|
276
|
+
for (const method of ['log', 'info', 'warn', 'error', 'debug', 'trace', 'dir', 'table'] as const) {
|
|
277
|
+
captureConsole[method] = (...args: any[]) => {
|
|
278
|
+
calls.push({ method, args })
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const isExisting = this.isContext(ctx)
|
|
283
|
+
const context = isExisting ? ctx : this.createContext({ ...ctx, console: captureConsole })
|
|
284
|
+
|
|
285
|
+
// For existing contexts, swap console in for the run and restore after
|
|
286
|
+
const prevConsole = isExisting ? ctx.console : undefined
|
|
287
|
+
if (isExisting) ctx.console = captureConsole
|
|
288
|
+
|
|
289
|
+
const wrapped = this.wrapTopLevelAwait(code)
|
|
290
|
+
const script = this.createScript(wrapped)
|
|
291
|
+
try {
|
|
292
|
+
const result = (await script.runInContext(context)) as T
|
|
293
|
+
return { result, console: calls, context }
|
|
294
|
+
} finally {
|
|
295
|
+
if (isExisting) ctx.console = prevConsole
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Execute JavaScript code synchronously in a controlled environment.
|
|
301
|
+
*
|
|
302
|
+
* @param code - The JavaScript code to execute
|
|
303
|
+
* @param ctx - Context variables to make available to the executing code
|
|
304
|
+
* @returns The result of the code execution
|
|
305
|
+
*
|
|
306
|
+
* @example
|
|
307
|
+
* ```typescript
|
|
308
|
+
* const sum = vm.runSync('a + b', { a: 2, b: 3 })
|
|
309
|
+
* console.log(sum) // 5
|
|
310
|
+
* ```
|
|
311
|
+
*/
|
|
312
|
+
runSync<T extends any = any>(code: string, ctx: any = {}): T {
|
|
313
|
+
const script = this.createScript(code)
|
|
314
|
+
const context = this.isContext(ctx) ? ctx : this.createContext(ctx)
|
|
315
|
+
|
|
316
|
+
return script.runInContext(context) as T
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Execute code asynchronously and return both the result and the execution context.
|
|
321
|
+
*
|
|
322
|
+
* Unlike `run`, this method also returns the context object, allowing you to inspect
|
|
323
|
+
* variables set during execution.
|
|
324
|
+
*
|
|
325
|
+
* @param code - The JavaScript code to execute
|
|
326
|
+
* @param ctx - Context variables to make available to the executing code
|
|
327
|
+
* @returns The execution result and the context object
|
|
328
|
+
*
|
|
329
|
+
* @example
|
|
330
|
+
* ```typescript
|
|
331
|
+
* const { result, context } = await vm.perform('x = 42; x * 2', { x: 0 })
|
|
332
|
+
* console.log(result) // 84
|
|
333
|
+
* console.log(context.x) // 42
|
|
334
|
+
* ```
|
|
335
|
+
*/
|
|
336
|
+
async perform<T extends any>(code: string, ctx: any = {}): Promise<{ result: T, context: vm.Context }> {
|
|
337
|
+
const script = this.createScript(code)
|
|
338
|
+
const context = this.isContext(ctx) ? ctx : this.createContext(ctx)
|
|
339
|
+
|
|
340
|
+
return { result: (await script.runInContext(context)) as T, context }
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Executes JavaScript code synchronously and returns both the result and the execution context.
|
|
345
|
+
*
|
|
346
|
+
* Unlike `runSync`, this method also returns the context object, allowing you to inspect
|
|
347
|
+
* variables set during execution (e.g. `module.exports`). This is the synchronous equivalent
|
|
348
|
+
* of `perform()`.
|
|
349
|
+
*
|
|
350
|
+
* @param {string} code - The JavaScript code to execute
|
|
351
|
+
* @param {any} [ctx={}] - Context variables to make available to the executing code
|
|
352
|
+
* @returns {{ result: T, context: vm.Context }} The execution result and the context object
|
|
353
|
+
*
|
|
354
|
+
* @example
|
|
355
|
+
* ```typescript
|
|
356
|
+
* const { result, context } = vm.performSync(code, {
|
|
357
|
+
* exports: {},
|
|
358
|
+
* module: { exports: {} },
|
|
359
|
+
* })
|
|
360
|
+
* const moduleExports = context.module?.exports || context.exports
|
|
361
|
+
* ```
|
|
362
|
+
*/
|
|
363
|
+
performSync<T extends any = any>(code: string, ctx: any = {}): { result: T, context: vm.Context } {
|
|
364
|
+
const script = this.createScript(code)
|
|
365
|
+
const context = this.isContext(ctx) ? ctx : this.createContext(ctx)
|
|
366
|
+
|
|
367
|
+
return { result: script.runInContext(context) as T, context }
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Synchronously loads a JavaScript/TypeScript module from a file path, executing it
|
|
372
|
+
* in an isolated VM context and returning its exports. The module gets `require`,
|
|
373
|
+
* `exports`, and `module` globals automatically, plus any additional context you provide.
|
|
374
|
+
*
|
|
375
|
+
* @param {string} filePath - Absolute path to the module file to load
|
|
376
|
+
* @param {any} [ctx={}] - Additional context variables to inject into the module's execution environment
|
|
377
|
+
* @returns {Record<string, any>} The module's exports (from `module.exports` or `exports`)
|
|
378
|
+
*
|
|
379
|
+
* @example
|
|
380
|
+
* ```typescript
|
|
381
|
+
* const vm = container.feature('vm')
|
|
382
|
+
*
|
|
383
|
+
* // Load a tools module, injecting the container
|
|
384
|
+
* const tools = vm.loadModule('/path/to/tools.ts', { container, me: assistant })
|
|
385
|
+
* // tools.myFunction, tools.schemas, etc.
|
|
386
|
+
* ```
|
|
387
|
+
*/
|
|
388
|
+
loadModule(filePath: string, ctx: any = {}): Record<string, any> {
|
|
389
|
+
const { fs } = this.container
|
|
390
|
+
|
|
391
|
+
if (!fs.exists(filePath)) return {}
|
|
392
|
+
|
|
393
|
+
// If we have virtual modules defined, use bundling to inline all other imports.
|
|
394
|
+
// Virtual module IDs are marked external so they resolve via our custom require.
|
|
395
|
+
if (this.modules.size > 0) {
|
|
396
|
+
return this._loadModuleBundled(filePath, ctx)
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
const raw = fs.readFile(filePath)
|
|
400
|
+
const { code } = this.container.feature('transpiler').transformSync(String(raw), { format: 'cjs' })
|
|
401
|
+
|
|
402
|
+
return this._execModule(code, filePath, ctx)
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/** @internal Bundle a file with Bun.build, keeping virtual modules external, then execute it. */
|
|
406
|
+
private _loadModuleBundled(filePath: string, ctx: any): Record<string, any> {
|
|
407
|
+
const external = [...this.modules.keys()]
|
|
408
|
+
|
|
409
|
+
const result = Bun.spawnSync({
|
|
410
|
+
cmd: ['bun', 'build', filePath, '--target=bun', '--format=cjs', ...external.flatMap(e => ['--external', e])],
|
|
411
|
+
stdout: 'pipe',
|
|
412
|
+
stderr: 'pipe',
|
|
413
|
+
})
|
|
414
|
+
|
|
415
|
+
if (result.exitCode !== 0) {
|
|
416
|
+
// Fall back to simple transpile if bundling fails
|
|
417
|
+
const raw = this.container.fs.readFile(filePath)
|
|
418
|
+
const { code } = this.container.feature('transpiler').transformSync(String(raw), { format: 'cjs' })
|
|
419
|
+
return this._execModule(code, filePath, ctx)
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
let code = result.stdout.toString()
|
|
423
|
+
|
|
424
|
+
// Bun's CJS output wraps everything in (function(exports, require, module, __filename, __dirname) { ... })
|
|
425
|
+
// Strip the wrapper so the inner code runs directly in our VM context which already provides these globals.
|
|
426
|
+
const wrapperStart = '(function(exports, require, module, __filename, __dirname) {'
|
|
427
|
+
if (code.includes(wrapperStart)) {
|
|
428
|
+
const startIdx = code.indexOf(wrapperStart) + wrapperStart.length
|
|
429
|
+
const endIdx = code.lastIndexOf('})')
|
|
430
|
+
code = code.substring(startIdx, endIdx)
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
return this._execModule(code, filePath, ctx)
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/** @internal Execute CJS code in a VM context and return its exports. */
|
|
437
|
+
private _execModule(code: string, filePath: string, ctx: any): Record<string, any> {
|
|
438
|
+
const sharedExports = {}
|
|
439
|
+
const { context } = this.performSync(code, {
|
|
440
|
+
require: this.createRequireFor(filePath),
|
|
441
|
+
exports: sharedExports,
|
|
442
|
+
module: { exports: sharedExports },
|
|
443
|
+
__filename: filePath,
|
|
444
|
+
__dirname: dirname(filePath),
|
|
445
|
+
console,
|
|
446
|
+
setTimeout,
|
|
447
|
+
setInterval,
|
|
448
|
+
clearTimeout,
|
|
449
|
+
clearInterval,
|
|
450
|
+
process,
|
|
451
|
+
Buffer,
|
|
452
|
+
URL,
|
|
453
|
+
URLSearchParams,
|
|
454
|
+
fetch,
|
|
455
|
+
...ctx,
|
|
456
|
+
})
|
|
457
|
+
|
|
458
|
+
return context.module?.exports || context.exports || {}
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
export default VM
|