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,148 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
import { FeatureStateSchema, FeatureOptionsSchema } from '../../schemas/base.js'
|
|
3
|
+
import { Feature } from "../feature.js";
|
|
4
|
+
import { NodeContainer } from "../container.js";
|
|
5
|
+
import { camelCase, omit, set } from 'lodash-es'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Zod schema for the YamlTree feature state.
|
|
9
|
+
* Extends FeatureStateSchema and allows any additional string-keyed properties for tree data.
|
|
10
|
+
*/
|
|
11
|
+
export const YamlTreeStateSchema = FeatureStateSchema.extend({}).catchall(z.any()).describe('State schema for the YamlTree feature, stores loaded YAML tree data as arbitrary key-value pairs')
|
|
12
|
+
export type YamlTreeState = z.infer<typeof YamlTreeStateSchema>
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* YamlTree Feature - A powerful YAML file tree loader and processor
|
|
16
|
+
*
|
|
17
|
+
* This feature provides functionality to recursively load YAML files from a directory structure
|
|
18
|
+
* and build a hierarchical tree representation. It automatically processes file paths to create
|
|
19
|
+
* a nested object structure where file paths become object property paths.
|
|
20
|
+
*
|
|
21
|
+
* **Key Features:**
|
|
22
|
+
* - Recursive YAML file discovery in directory trees
|
|
23
|
+
* - Automatic path-to-property mapping using camelCase conversion
|
|
24
|
+
* - Integration with FileManager for efficient file operations
|
|
25
|
+
* - State-based tree storage and retrieval
|
|
26
|
+
* - Support for both .yml and .yaml file extensions
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* const yamlTree = container.feature('yamlTree', { enable: true });
|
|
31
|
+
* await yamlTree.loadTree('config', 'appConfig');
|
|
32
|
+
* const configData = yamlTree.tree.appConfig;
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* @template T - The state type, defaults to YamlTreeState
|
|
36
|
+
* @extends {Feature<T>}
|
|
37
|
+
*/
|
|
38
|
+
export class YamlTree<T extends YamlTreeState = YamlTreeState> extends Feature<T> {
|
|
39
|
+
static { Feature.register(this, 'yamlTree') }
|
|
40
|
+
/** The shortcut path for accessing this feature */
|
|
41
|
+
static override shortcut = "features.yamlTree" as const
|
|
42
|
+
static override stateSchema = YamlTreeStateSchema
|
|
43
|
+
static override optionsSchema = FeatureOptionsSchema
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Attaches the YamlTree feature to a NodeContainer instance.
|
|
47
|
+
* Registers the feature and creates an auto-enabled instance.
|
|
48
|
+
*
|
|
49
|
+
* @param container - The NodeContainer to attach to
|
|
50
|
+
* @returns The container for method chaining
|
|
51
|
+
*/
|
|
52
|
+
static attach(container: NodeContainer & { yamlTree?: YamlTree }) {
|
|
53
|
+
container.yamlTree = container.feature("yamlTree", { enable: true });
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Loads a tree of YAML files from the specified base path and stores them in state.
|
|
58
|
+
*
|
|
59
|
+
* This method recursively scans the provided directory for YAML files (.yml and .yaml),
|
|
60
|
+
* processes their content, and builds a hierarchical object structure. File paths are
|
|
61
|
+
* converted to camelCase property names, and the resulting tree is stored in the feature's state.
|
|
62
|
+
*
|
|
63
|
+
* **Path Processing:**
|
|
64
|
+
* - Removes the base path prefix from file paths
|
|
65
|
+
* - Converts directory/file names to camelCase
|
|
66
|
+
* - Creates nested objects based on directory structure
|
|
67
|
+
* - Removes file extensions (.yml/.yaml)
|
|
68
|
+
*
|
|
69
|
+
* **Example:**
|
|
70
|
+
* ```
|
|
71
|
+
* config/
|
|
72
|
+
* database/
|
|
73
|
+
* production.yml -> tree.config.database.production
|
|
74
|
+
* staging.yml -> tree.config.database.staging
|
|
75
|
+
* api/
|
|
76
|
+
* endpoints.yaml -> tree.config.api.endpoints
|
|
77
|
+
* ```
|
|
78
|
+
*
|
|
79
|
+
* @param basePath - The root directory path to scan for YAML files
|
|
80
|
+
* @param key - The key to store the tree under in state (defaults to first segment of basePath)
|
|
81
|
+
* @returns Promise resolving to the complete tree object
|
|
82
|
+
*
|
|
83
|
+
* @throws {Error} When FileManager fails to start or files cannot be read
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```typescript
|
|
87
|
+
* // Load all YAML files from 'config' directory into state.config
|
|
88
|
+
* await yamlTree.loadTree('config');
|
|
89
|
+
*
|
|
90
|
+
* // Load with custom key
|
|
91
|
+
* await yamlTree.loadTree('app/settings', 'appSettings');
|
|
92
|
+
*
|
|
93
|
+
* // Access the loaded data
|
|
94
|
+
* const dbConfig = yamlTree.tree.config.database.production;
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
async loadTree(basePath: string, key: string = basePath.split('/')[0]! ) {
|
|
98
|
+
const { container } = this;
|
|
99
|
+
const yamlFeature = container.feature("yaml");
|
|
100
|
+
const fileManager = container.feature("fileManager")
|
|
101
|
+
const fileSystem = container.feature("fs");
|
|
102
|
+
|
|
103
|
+
await fileManager.start()
|
|
104
|
+
|
|
105
|
+
// Use the FileManager to find all YAML files in the tree.
|
|
106
|
+
const yamlFiles = fileManager.matchFiles([
|
|
107
|
+
`${basePath}/**/*.yml`,
|
|
108
|
+
`${basePath}/**/*.yaml`
|
|
109
|
+
]);
|
|
110
|
+
|
|
111
|
+
const tree : any = {}
|
|
112
|
+
|
|
113
|
+
for (const file of yamlFiles.filter(Boolean)) {
|
|
114
|
+
if(file?.relativePath) {
|
|
115
|
+
const fileContent = fileSystem.readFile(file.relativePath);
|
|
116
|
+
const fileData = yamlFeature.parse(String(fileContent));
|
|
117
|
+
const path = file.relativePath.replace(/\.ya?ml$/, "").replace(basePath + "/", "").split("/").filter(v => v?.length).map(p => camelCase(p));
|
|
118
|
+
set(tree, path, fileData)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// @ts-ignore-next-line
|
|
123
|
+
this.setState({ ...this.tree, [key]: tree })
|
|
124
|
+
|
|
125
|
+
return this.tree
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Gets the current tree data, excluding the 'enabled' state property.
|
|
130
|
+
*
|
|
131
|
+
* Returns a clean copy of the tree data without internal state management properties.
|
|
132
|
+
* This provides access to only the YAML tree data that has been loaded.
|
|
133
|
+
*
|
|
134
|
+
* @returns The tree object containing all loaded YAML data, organized by keys
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```typescript
|
|
138
|
+
* await yamlTree.loadTree('config');
|
|
139
|
+
* const allTrees = yamlTree.tree;
|
|
140
|
+
* // Returns: { config: { database: { ... }, api: { ... } } }
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
get tree() {
|
|
144
|
+
return omit(this.state.current, 'enabled')
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export default YamlTree
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import * as yaml from 'js-yaml'
|
|
2
|
+
import { Feature } from '../feature.js'
|
|
3
|
+
import { FeatureStateSchema, FeatureOptionsSchema } from '../../schemas/base.js'
|
|
4
|
+
import { NodeContainer } from '../container.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The YAML feature provides utilities for parsing and stringifying YAML data.
|
|
8
|
+
*
|
|
9
|
+
* This feature wraps the js-yaml library to provide convenient methods for
|
|
10
|
+
* converting between YAML strings and JavaScript objects. It's automatically
|
|
11
|
+
* attached to Node containers for easy access.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* const yamlFeature = container.feature('yaml')
|
|
16
|
+
*
|
|
17
|
+
* // Parse YAML string to object
|
|
18
|
+
* const config = yamlFeature.parse(`
|
|
19
|
+
* name: MyApp
|
|
20
|
+
* version: 1.0.0
|
|
21
|
+
* settings:
|
|
22
|
+
* debug: true
|
|
23
|
+
* `)
|
|
24
|
+
*
|
|
25
|
+
* // Convert object to YAML string
|
|
26
|
+
* const yamlString = yamlFeature.stringify(config)
|
|
27
|
+
* console.log(yamlString)
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @extends Feature
|
|
31
|
+
*/
|
|
32
|
+
export class YAML extends Feature {
|
|
33
|
+
static override shortcut = 'features.yaml' as const
|
|
34
|
+
static override stateSchema = FeatureStateSchema
|
|
35
|
+
static override optionsSchema = FeatureOptionsSchema
|
|
36
|
+
static { Feature.register(this, 'yaml') }
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Automatically attaches the YAML feature to Node containers.
|
|
40
|
+
*
|
|
41
|
+
* This static method ensures the YAML feature is automatically available
|
|
42
|
+
* on Node containers without needing manual registration.
|
|
43
|
+
*
|
|
44
|
+
* @param {NodeContainer} c - The Node container to attach to
|
|
45
|
+
*/
|
|
46
|
+
static attach(c: NodeContainer) {
|
|
47
|
+
c.feature('yaml', { enable: true })
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Converts a JavaScript object to a YAML string.
|
|
52
|
+
*
|
|
53
|
+
* This method serializes JavaScript data structures into YAML format,
|
|
54
|
+
* which is human-readable and commonly used for configuration files.
|
|
55
|
+
*
|
|
56
|
+
* @param {any} data - The data to convert to YAML format
|
|
57
|
+
* @returns {string} The YAML string representation of the data
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* const config = {
|
|
62
|
+
* name: 'MyApp',
|
|
63
|
+
* version: '1.0.0',
|
|
64
|
+
* settings: {
|
|
65
|
+
* debug: true,
|
|
66
|
+
* ports: [3000, 3001]
|
|
67
|
+
* }
|
|
68
|
+
* }
|
|
69
|
+
*
|
|
70
|
+
* const yamlString = yaml.stringify(config)
|
|
71
|
+
* console.log(yamlString)
|
|
72
|
+
* // Output:
|
|
73
|
+
* // name: MyApp
|
|
74
|
+
* // version: 1.0.0
|
|
75
|
+
* // settings:
|
|
76
|
+
* // debug: true
|
|
77
|
+
* // ports:
|
|
78
|
+
* // - 3000
|
|
79
|
+
* // - 3001
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
stringify(data: any) : string {
|
|
83
|
+
return yaml.dump(data)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Parses a YAML string into a JavaScript object.
|
|
88
|
+
*
|
|
89
|
+
* This method deserializes YAML content into JavaScript data structures.
|
|
90
|
+
* It supports all standard YAML features including nested objects, arrays,
|
|
91
|
+
* and various data types.
|
|
92
|
+
*
|
|
93
|
+
* @template T - The expected type of the parsed object
|
|
94
|
+
* @param {string} yamlStr - The YAML string to parse
|
|
95
|
+
* @returns {T} The parsed JavaScript object
|
|
96
|
+
* @throws {Error} Throws an error if the YAML string is malformed
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```typescript
|
|
100
|
+
* const yamlContent = `
|
|
101
|
+
* name: MyApp
|
|
102
|
+
* version: 1.0.0
|
|
103
|
+
* settings:
|
|
104
|
+
* debug: true
|
|
105
|
+
* ports:
|
|
106
|
+
* - 3000
|
|
107
|
+
* - 3001
|
|
108
|
+
* `
|
|
109
|
+
*
|
|
110
|
+
* // Parse with type inference
|
|
111
|
+
* const config = yaml.parse(yamlContent)
|
|
112
|
+
* console.log(config.name) // 'MyApp'
|
|
113
|
+
*
|
|
114
|
+
* // Parse with explicit typing
|
|
115
|
+
* interface AppConfig {
|
|
116
|
+
* name: string
|
|
117
|
+
* version: string
|
|
118
|
+
* settings: {
|
|
119
|
+
* debug: boolean
|
|
120
|
+
* ports: number[]
|
|
121
|
+
* }
|
|
122
|
+
* }
|
|
123
|
+
*
|
|
124
|
+
* const typedConfig = yaml.parse<AppConfig>(yamlContent)
|
|
125
|
+
* console.log(typedConfig.settings.ports) // [3000, 3001]
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
parse<T extends object = any>(yamlStr: string) : T {
|
|
129
|
+
return yaml.load(yamlStr) as T
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export default YAML
|
package/src/node.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { NodeContainer, Feature } from './node/container'
|
|
2
|
+
import './introspection/generated.node'
|
|
3
|
+
|
|
4
|
+
export * from './node/container'
|
|
5
|
+
|
|
6
|
+
const container = new NodeContainer()
|
|
7
|
+
|
|
8
|
+
const { servers, features, clients } = container
|
|
9
|
+
|
|
10
|
+
export default container as NodeContainer
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Returns the singleton container instance.
|
|
14
|
+
* LLMs love to hallucinate this function — so we provide it, but warn.
|
|
15
|
+
* If you need a separate container, use `container.subcontainer()`.
|
|
16
|
+
*/
|
|
17
|
+
export function createContainer() {
|
|
18
|
+
console.warn(
|
|
19
|
+
'[luca] createContainer() is unnecessary — import the default export instead.\n' +
|
|
20
|
+
' `import container from "luca"`\n' +
|
|
21
|
+
' For a separate instance, use container.subcontainer().'
|
|
22
|
+
)
|
|
23
|
+
return container
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Convenient pre-enabled feature instances
|
|
27
|
+
export const ui = container.feature('ui')
|
|
28
|
+
export const fs = container.feature('fs')
|
|
29
|
+
export const vm = container.feature('vm')
|
|
30
|
+
export const proc = container.feature('proc')
|
|
31
|
+
|
|
32
|
+
// Registries
|
|
33
|
+
export { servers, features, clients }
|
|
34
|
+
|
|
35
|
+
// Core classes
|
|
36
|
+
export { Feature }
|
|
37
|
+
export { Container } from './container'
|
|
38
|
+
export { Helper } from './helper'
|
|
39
|
+
export { Bus } from './bus'
|
|
40
|
+
export { State } from './state'
|
|
41
|
+
export { Registry } from './registry'
|
|
42
|
+
|
|
43
|
+
// Helper subclasses & registries
|
|
44
|
+
export { Client, ClientsRegistry } from './client'
|
|
45
|
+
export { RestClient } from './clients/rest'
|
|
46
|
+
export { GraphClient } from './clients/graph'
|
|
47
|
+
export { WebSocketClient } from './clients/websocket'
|
|
48
|
+
export { Command, CommandsRegistry, commands, graftModule } from './command'
|
|
49
|
+
export { Endpoint, EndpointsRegistry, endpoints } from './endpoint'
|
|
50
|
+
export { Selector, SelectorsRegistry, selectors } from './selector'
|
|
51
|
+
export { Server, ServersRegistry } from './server'
|
|
52
|
+
export { FeaturesRegistry } from './feature'
|
|
53
|
+
|
|
54
|
+
// Concrete server implementations
|
|
55
|
+
export { ExpressServer } from './servers/express'
|
|
56
|
+
export { WebsocketServer } from './servers/socket'
|
|
57
|
+
|
|
58
|
+
// Types
|
|
59
|
+
export type { ContainerContext, ContainerArgv, Plugin, Extension } from './container'
|
|
60
|
+
export type { AvailableClients } from './client'
|
|
61
|
+
export type { AvailableCommands, CommandHandler } from './command'
|
|
62
|
+
export type { AvailableEndpoints, EndpointContext } from './endpoint'
|
|
63
|
+
export type { AvailableSelectors, SelectorsInterface, SelectorRunResult, SimpleSelector } from './selector'
|
|
64
|
+
export type { AvailableFeatures, FeatureOptions, FeatureState } from './feature'
|
|
65
|
+
export type { NodeContainer, NodeFeatures } from './node/container'
|
|
66
|
+
export type { AvailableServers, StartOptions, ServersInterface } from './server'
|
|
67
|
+
export type { HelperState, HelperOptions } from './helper'
|
|
68
|
+
export type { Entity } from './entity'
|
|
69
|
+
export type { EventMap } from './bus'
|
|
70
|
+
export type { SetStateValue, StateChangeType } from './state'
|
|
71
|
+
|
|
72
|
+
// Zod — so consumer code can `import { z } from 'luca'`
|
|
73
|
+
export { z } from 'zod'
|
|
74
|
+
|
|
75
|
+
// Schemas
|
|
76
|
+
export * from './schemas/base'
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Luca Python Bridge - persistent interactive Python session.
|
|
3
|
+
|
|
4
|
+
Communicates via JSON lines over stdin/stdout. Each request is a single
|
|
5
|
+
JSON object per line on stdin; each response is a single JSON object per
|
|
6
|
+
line on stdout. User print() output is captured per-execution via
|
|
7
|
+
io.StringIO so it never corrupts the protocol.
|
|
8
|
+
|
|
9
|
+
Python 3.8+ compatible (stdlib only).
|
|
10
|
+
"""
|
|
11
|
+
import sys
|
|
12
|
+
import json
|
|
13
|
+
import io
|
|
14
|
+
import traceback
|
|
15
|
+
import os
|
|
16
|
+
|
|
17
|
+
# Persistent namespace shared across all exec/eval calls
|
|
18
|
+
_namespace = {"__builtins__": __builtins__}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def setup_sys_path(project_dir):
|
|
22
|
+
"""Insert project_dir and common sub-paths into sys.path."""
|
|
23
|
+
paths_to_add = [project_dir]
|
|
24
|
+
|
|
25
|
+
# src/ layout (PEP 621 / setuptools)
|
|
26
|
+
src_dir = os.path.join(project_dir, "src")
|
|
27
|
+
if os.path.isdir(src_dir):
|
|
28
|
+
paths_to_add.append(src_dir)
|
|
29
|
+
|
|
30
|
+
# lib/ layout (less common but exists)
|
|
31
|
+
lib_dir = os.path.join(project_dir, "lib")
|
|
32
|
+
if os.path.isdir(lib_dir):
|
|
33
|
+
paths_to_add.append(lib_dir)
|
|
34
|
+
|
|
35
|
+
for p in reversed(paths_to_add):
|
|
36
|
+
if p not in sys.path:
|
|
37
|
+
sys.path.insert(0, p)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _safe_serialize(value):
|
|
41
|
+
"""Attempt JSON serialization; fall back to repr()."""
|
|
42
|
+
try:
|
|
43
|
+
json.dumps(value, default=str)
|
|
44
|
+
return value
|
|
45
|
+
except (TypeError, ValueError, OverflowError):
|
|
46
|
+
return repr(value)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def handle_exec(req):
|
|
50
|
+
"""Execute code in the persistent namespace."""
|
|
51
|
+
code = req.get("code", "")
|
|
52
|
+
variables = req.get("variables", {})
|
|
53
|
+
_namespace.update(variables)
|
|
54
|
+
|
|
55
|
+
old_stdout = sys.stdout
|
|
56
|
+
captured = io.StringIO()
|
|
57
|
+
sys.stdout = captured
|
|
58
|
+
try:
|
|
59
|
+
exec(code, _namespace)
|
|
60
|
+
sys.stdout = old_stdout
|
|
61
|
+
return {"ok": True, "stdout": captured.getvalue(), "result": None}
|
|
62
|
+
except Exception as e:
|
|
63
|
+
sys.stdout = old_stdout
|
|
64
|
+
return {
|
|
65
|
+
"ok": False,
|
|
66
|
+
"error": str(e),
|
|
67
|
+
"traceback": traceback.format_exc(),
|
|
68
|
+
"stdout": captured.getvalue(),
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def handle_eval(req):
|
|
73
|
+
"""Evaluate an expression and return its value."""
|
|
74
|
+
expression = req.get("expression", "")
|
|
75
|
+
|
|
76
|
+
old_stdout = sys.stdout
|
|
77
|
+
captured = io.StringIO()
|
|
78
|
+
sys.stdout = captured
|
|
79
|
+
try:
|
|
80
|
+
result = eval(expression, _namespace)
|
|
81
|
+
sys.stdout = old_stdout
|
|
82
|
+
return {
|
|
83
|
+
"ok": True,
|
|
84
|
+
"result": _safe_serialize(result),
|
|
85
|
+
"stdout": captured.getvalue(),
|
|
86
|
+
}
|
|
87
|
+
except Exception as e:
|
|
88
|
+
sys.stdout = old_stdout
|
|
89
|
+
return {
|
|
90
|
+
"ok": False,
|
|
91
|
+
"error": str(e),
|
|
92
|
+
"traceback": traceback.format_exc(),
|
|
93
|
+
"stdout": captured.getvalue(),
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def handle_import(req):
|
|
98
|
+
"""Import a module into the namespace."""
|
|
99
|
+
module_name = req.get("module", "")
|
|
100
|
+
alias = req.get("alias", module_name.split(".")[-1])
|
|
101
|
+
try:
|
|
102
|
+
mod = __import__(
|
|
103
|
+
module_name,
|
|
104
|
+
fromlist=[module_name.split(".")[-1]] if "." in module_name else [],
|
|
105
|
+
)
|
|
106
|
+
_namespace[alias] = mod
|
|
107
|
+
return {"ok": True, "result": "Imported {} as {}".format(module_name, alias)}
|
|
108
|
+
except Exception as e:
|
|
109
|
+
return {
|
|
110
|
+
"ok": False,
|
|
111
|
+
"error": str(e),
|
|
112
|
+
"traceback": traceback.format_exc(),
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def handle_call(req):
|
|
117
|
+
"""Call a function by dotted path in the namespace."""
|
|
118
|
+
func_path = req.get("function", "")
|
|
119
|
+
args = req.get("args", [])
|
|
120
|
+
kwargs = req.get("kwargs", {})
|
|
121
|
+
|
|
122
|
+
old_stdout = sys.stdout
|
|
123
|
+
captured = io.StringIO()
|
|
124
|
+
sys.stdout = captured
|
|
125
|
+
try:
|
|
126
|
+
parts = func_path.split(".")
|
|
127
|
+
obj = _namespace[parts[0]]
|
|
128
|
+
for part in parts[1:]:
|
|
129
|
+
obj = getattr(obj, part)
|
|
130
|
+
result = obj(*args, **kwargs)
|
|
131
|
+
sys.stdout = old_stdout
|
|
132
|
+
return {
|
|
133
|
+
"ok": True,
|
|
134
|
+
"result": _safe_serialize(result),
|
|
135
|
+
"stdout": captured.getvalue(),
|
|
136
|
+
}
|
|
137
|
+
except Exception as e:
|
|
138
|
+
sys.stdout = old_stdout
|
|
139
|
+
return {
|
|
140
|
+
"ok": False,
|
|
141
|
+
"error": str(e),
|
|
142
|
+
"traceback": traceback.format_exc(),
|
|
143
|
+
"stdout": captured.getvalue(),
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def handle_get_locals(req):
|
|
148
|
+
"""Return all non-dunder keys from the namespace."""
|
|
149
|
+
safe = {}
|
|
150
|
+
for k, v in _namespace.items():
|
|
151
|
+
if k.startswith("__"):
|
|
152
|
+
continue
|
|
153
|
+
safe[k] = _safe_serialize(v)
|
|
154
|
+
return {"ok": True, "result": safe}
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def handle_reset(req):
|
|
158
|
+
"""Clear the namespace."""
|
|
159
|
+
_namespace.clear()
|
|
160
|
+
_namespace["__builtins__"] = __builtins__
|
|
161
|
+
return {"ok": True, "result": "Session reset"}
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
HANDLERS = {
|
|
165
|
+
"exec": handle_exec,
|
|
166
|
+
"eval": handle_eval,
|
|
167
|
+
"import": handle_import,
|
|
168
|
+
"call": handle_call,
|
|
169
|
+
"get_locals": handle_get_locals,
|
|
170
|
+
"reset": handle_reset,
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def main():
|
|
175
|
+
# First line from stdin is the init handshake with project_dir
|
|
176
|
+
init_line = sys.stdin.readline().strip()
|
|
177
|
+
if init_line:
|
|
178
|
+
try:
|
|
179
|
+
init = json.loads(init_line)
|
|
180
|
+
if "project_dir" in init:
|
|
181
|
+
setup_sys_path(init["project_dir"])
|
|
182
|
+
except json.JSONDecodeError:
|
|
183
|
+
pass
|
|
184
|
+
|
|
185
|
+
# Signal ready
|
|
186
|
+
sys.stdout.write(json.dumps({"ok": True, "type": "ready"}) + "\n")
|
|
187
|
+
sys.stdout.flush()
|
|
188
|
+
|
|
189
|
+
# Main loop: read JSON commands, execute, respond
|
|
190
|
+
for line in sys.stdin:
|
|
191
|
+
line = line.strip()
|
|
192
|
+
if not line:
|
|
193
|
+
continue
|
|
194
|
+
|
|
195
|
+
try:
|
|
196
|
+
req = json.loads(line)
|
|
197
|
+
except json.JSONDecodeError as e:
|
|
198
|
+
resp = {"ok": False, "error": "Invalid JSON: {}".format(e)}
|
|
199
|
+
sys.stdout.write(json.dumps(resp) + "\n")
|
|
200
|
+
sys.stdout.flush()
|
|
201
|
+
continue
|
|
202
|
+
|
|
203
|
+
req_id = req.get("id")
|
|
204
|
+
req_type = req.get("type", "exec")
|
|
205
|
+
handler = HANDLERS.get(req_type)
|
|
206
|
+
|
|
207
|
+
if not handler:
|
|
208
|
+
resp = {"ok": False, "error": "Unknown request type: {}".format(req_type)}
|
|
209
|
+
else:
|
|
210
|
+
resp = handler(req)
|
|
211
|
+
|
|
212
|
+
if req_id:
|
|
213
|
+
resp["id"] = req_id
|
|
214
|
+
|
|
215
|
+
sys.stdout.write(json.dumps(resp, default=str) + "\n")
|
|
216
|
+
sys.stdout.flush()
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
if __name__ == "__main__":
|
|
220
|
+
main()
|