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
package/src/server.ts
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import type { NodeContainer } from './node/container.js'
|
|
2
|
+
import { Helper } from './helper.js'
|
|
3
|
+
import { Registry } from './registry.js'
|
|
4
|
+
import { z } from 'zod'
|
|
5
|
+
import { ServerStateSchema, ServerOptionsSchema, ServerEventsSchema } from './schemas/base.js'
|
|
6
|
+
|
|
7
|
+
export type ServerState = z.infer<typeof ServerStateSchema>
|
|
8
|
+
export type ServerOptions = z.infer<typeof ServerOptionsSchema>
|
|
9
|
+
|
|
10
|
+
export type StartOptions = {
|
|
11
|
+
port?: number;
|
|
12
|
+
host?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type ServerFactory = <T extends keyof AvailableServers>(
|
|
16
|
+
key: T,
|
|
17
|
+
options?: ConstructorParameters<AvailableServers[T]>[0]
|
|
18
|
+
) => NonNullable<InstanceType<AvailableServers[T]>>
|
|
19
|
+
|
|
20
|
+
export interface ServersInterface {
|
|
21
|
+
servers: ServersRegistry;
|
|
22
|
+
server: ServerFactory
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface AvailableServers {}
|
|
26
|
+
|
|
27
|
+
export class Server<T extends ServerState = ServerState, K extends ServerOptions = ServerOptions> extends Helper<T, K> {
|
|
28
|
+
static override stateSchema = ServerStateSchema
|
|
29
|
+
static override optionsSchema = ServerOptionsSchema
|
|
30
|
+
static override eventsSchema = ServerEventsSchema
|
|
31
|
+
|
|
32
|
+
/** Self-register a Server subclass from a static initialization block. */
|
|
33
|
+
static register: (SubClass: abstract new (options: any, context: any) => Server, id?: string) => abstract new (options: any, context: any) => Server
|
|
34
|
+
|
|
35
|
+
override get initialState() : T {
|
|
36
|
+
return ({
|
|
37
|
+
port: this.options.port || 3000,
|
|
38
|
+
listening: false,
|
|
39
|
+
configured: false,
|
|
40
|
+
stopped: false
|
|
41
|
+
} as unknown) as T
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
override get options() : K {
|
|
45
|
+
return {
|
|
46
|
+
port: 3000,
|
|
47
|
+
host: '0.0.0.0',
|
|
48
|
+
...this._options,
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
static attach(container: NodeContainer & ServersInterface) {
|
|
53
|
+
container.servers = servers
|
|
54
|
+
|
|
55
|
+
Object.assign(container, {
|
|
56
|
+
server<T extends keyof AvailableServers>(
|
|
57
|
+
id: T,
|
|
58
|
+
options?: ConstructorParameters<AvailableServers[T]>[0]
|
|
59
|
+
): NonNullable<InstanceType<AvailableServers[T]>> {
|
|
60
|
+
const BaseClass = servers.lookup(id) as AvailableServers[T]
|
|
61
|
+
|
|
62
|
+
return container.createHelperInstance({
|
|
63
|
+
cache: helperCache,
|
|
64
|
+
type: 'server',
|
|
65
|
+
id: String(id),
|
|
66
|
+
BaseClass,
|
|
67
|
+
options,
|
|
68
|
+
fallbackName: String(id),
|
|
69
|
+
}) as NonNullable<InstanceType<AvailableServers[T]>>
|
|
70
|
+
}
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
container.registerHelperType('servers', 'server')
|
|
74
|
+
|
|
75
|
+
return container
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
override get container() : NodeContainer {
|
|
79
|
+
return super.container as NodeContainer
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Async functions passed to `.use()` before `start()` — drained in `start()`. */
|
|
83
|
+
_pendingPlugins: Promise<void>[] = []
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Register a setup function against this server. The function receives the
|
|
87
|
+
* server instance and can configure it however it likes.
|
|
88
|
+
*
|
|
89
|
+
* - If the server hasn't started yet, async return values are queued and
|
|
90
|
+
* awaited when `start()` is called.
|
|
91
|
+
* - If the server is already listening, the function is fire-and-forget.
|
|
92
|
+
* - Always returns `this` synchronously for chaining.
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```typescript
|
|
96
|
+
* server
|
|
97
|
+
* .use((s) => s.app.use(cors()))
|
|
98
|
+
* .use(async (s) => { await loadRoutes(s) })
|
|
99
|
+
* await server.start()
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
use(fn: (server: this) => void | Promise<void>): this {
|
|
103
|
+
const result = fn(this)
|
|
104
|
+
if (result && typeof (result as any).then === 'function') {
|
|
105
|
+
if (!this.isListening) {
|
|
106
|
+
this._pendingPlugins.push(result as Promise<void>)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return this
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** Drain all pending `.use()` promises. Subclasses should call this at the top of `start()`. */
|
|
113
|
+
protected async _drainPendingPlugins() {
|
|
114
|
+
if (this._pendingPlugins.length) {
|
|
115
|
+
await Promise.all(this._pendingPlugins)
|
|
116
|
+
this._pendingPlugins = []
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
get isListening() {
|
|
121
|
+
return !!this.state.get('listening')
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
get isConfigured() {
|
|
125
|
+
return !!this.state.get('configured')
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
get isStopped() {
|
|
129
|
+
return !!this.state.get('stopped')
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** The port this server will bind to. Reads from state first (set by start() or configure()), then constructor options, then defaults to 3000. */
|
|
133
|
+
get port() {
|
|
134
|
+
return this.state.get('port') || this.options.port || 3000
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async stop() {
|
|
138
|
+
if(this.isStopped) {
|
|
139
|
+
return this
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
this.state.set('stopped', true)
|
|
143
|
+
|
|
144
|
+
return this
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Start the server. Runtime options override constructor options and update state
|
|
149
|
+
* so that `server.port` always reflects the actual listening port.
|
|
150
|
+
*
|
|
151
|
+
* @param options - Optional runtime overrides for port and host
|
|
152
|
+
*/
|
|
153
|
+
async start(options?: StartOptions) {
|
|
154
|
+
if(this.isListening) {
|
|
155
|
+
return this
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
await this._drainPendingPlugins()
|
|
159
|
+
|
|
160
|
+
if (options?.port) {
|
|
161
|
+
this.state.set('port', options.port)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
this.state.set('listening', true)
|
|
165
|
+
|
|
166
|
+
return this
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
async configure() {
|
|
170
|
+
const port = await this.container.networking.findOpenPort(this.port)
|
|
171
|
+
|
|
172
|
+
if(port !== this.port) {
|
|
173
|
+
this.state.set('port', port)
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
this.state.set('configured', true)
|
|
177
|
+
|
|
178
|
+
return this
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export class ServersRegistry extends Registry<Server<any>> {
|
|
183
|
+
override scope = "servers"
|
|
184
|
+
override baseClass = Server
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export const servers = new ServersRegistry()
|
|
188
|
+
|
|
189
|
+
export const helperCache = new Map()
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Self-register a Server subclass from a static initialization block.
|
|
193
|
+
* IMPORTANT: Place the static block AFTER all static override declarations
|
|
194
|
+
* so schemas, envVars, and other metadata are set before interceptRegistration fires.
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* ```typescript
|
|
198
|
+
* export class ExpressServer extends Server {
|
|
199
|
+
* static override stateSchema = ServerStateSchema
|
|
200
|
+
* static override optionsSchema = ExpressServerOptionsSchema
|
|
201
|
+
* static { Server.register(this, 'express') } // must come last
|
|
202
|
+
* }
|
|
203
|
+
* ```
|
|
204
|
+
*/
|
|
205
|
+
Server.register = function registerServer(
|
|
206
|
+
SubClass: abstract new (options: any, context: any) => Server,
|
|
207
|
+
id?: string,
|
|
208
|
+
) {
|
|
209
|
+
const registryId = id ?? SubClass.name[0]!.toLowerCase() + SubClass.name.slice(1)
|
|
210
|
+
|
|
211
|
+
// Auto-set shortcut if not explicitly overridden on this class
|
|
212
|
+
if (!Object.getOwnPropertyDescriptor(SubClass, 'shortcut')?.value ||
|
|
213
|
+
(SubClass as any).shortcut === 'unspecified') {
|
|
214
|
+
;(SubClass as any).shortcut = `servers.${registryId}` as const
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Register in the servers registry (interceptRegistration sees all statics above)
|
|
218
|
+
servers.register(registryId, SubClass as any)
|
|
219
|
+
|
|
220
|
+
// Generate default attach() if not explicitly overridden on this class
|
|
221
|
+
if (!Object.getOwnPropertyDescriptor(SubClass, 'attach')) {
|
|
222
|
+
;(SubClass as any).attach = (container: any) => {
|
|
223
|
+
servers.register(registryId, SubClass as any)
|
|
224
|
+
return container
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return SubClass
|
|
229
|
+
}
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import express from 'express'
|
|
2
|
+
import type { Express } from 'express'
|
|
3
|
+
import cors from 'cors'
|
|
4
|
+
import { z } from 'zod'
|
|
5
|
+
import { ServerStateSchema, ServerOptionsSchema } from '../schemas/base.js'
|
|
6
|
+
import { type StartOptions, Server, type ServerState } from '../server.js'
|
|
7
|
+
import { Endpoint, type EndpointModule, warnUnknownExports } from '../endpoint.js'
|
|
8
|
+
|
|
9
|
+
declare module '../server' {
|
|
10
|
+
interface AvailableServers {
|
|
11
|
+
express: typeof ExpressServer
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const ExpressServerOptionsSchema = ServerOptionsSchema.extend({
|
|
16
|
+
cors: z.boolean().optional().describe('Whether to enable CORS middleware'),
|
|
17
|
+
static: z.string().optional().describe('Path to serve static files from'),
|
|
18
|
+
historyFallback: z.boolean().optional().describe('Serve index.html for unmatched routes (SPA history fallback)'),
|
|
19
|
+
create: z.any().optional().describe('(app: Express, server: Server) => Express'),
|
|
20
|
+
beforeStart: z.any().optional().describe('(options: StartOptions, server: Server) => Promise<any>'),
|
|
21
|
+
})
|
|
22
|
+
export type ExpressServerOptions = z.infer<typeof ExpressServerOptionsSchema>
|
|
23
|
+
|
|
24
|
+
const defaultCreate = (app: Express, server: Server) => app
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Express.js HTTP server with automatic endpoint mounting, CORS, and SPA history fallback.
|
|
28
|
+
*
|
|
29
|
+
* Wraps an Express application with convention-based endpoint discovery. Endpoints
|
|
30
|
+
* defined as modules are automatically mounted as routes. Supports static file serving,
|
|
31
|
+
* CORS configuration, and single-page app history fallback out of the box.
|
|
32
|
+
*
|
|
33
|
+
* @extends Server
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* const server = container.server('express', { cors: true, static: './public' })
|
|
38
|
+
* await server.start({ port: 3000 })
|
|
39
|
+
*
|
|
40
|
+
* // Mount endpoints programmatically
|
|
41
|
+
* server.mount(myEndpoint)
|
|
42
|
+
*
|
|
43
|
+
* // Access the underlying Express app
|
|
44
|
+
* server.app.get('/health', (req, res) => res.json({ ok: true }))
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export class ExpressServer<T extends ServerState = ServerState, K extends ExpressServerOptions = ExpressServerOptions> extends Server<T,K> {
|
|
48
|
+
static override shortcut = 'servers.express' as const
|
|
49
|
+
static override stateSchema = ServerStateSchema
|
|
50
|
+
static override optionsSchema = ExpressServerOptionsSchema
|
|
51
|
+
|
|
52
|
+
static { Server.register(this, 'express') }
|
|
53
|
+
|
|
54
|
+
_app?: Express
|
|
55
|
+
_listener?: any
|
|
56
|
+
_mountedEndpoints: Endpoint[] = []
|
|
57
|
+
|
|
58
|
+
get express(): typeof express {
|
|
59
|
+
return express
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
get hooks(): { create: (app: Express, server: Server) => Express; beforeStart: (options: any, server: Server) => any } {
|
|
63
|
+
const { create = defaultCreate, beforeStart = () => {} } = this.options
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
create,
|
|
67
|
+
beforeStart
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
get app(): Express {
|
|
72
|
+
if(this._app) {
|
|
73
|
+
return this._app
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const app = express()
|
|
77
|
+
|
|
78
|
+
if (this.options.cors !== false) {
|
|
79
|
+
app.use(cors())
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
app.use(express.json({ limit: "500mb" }))
|
|
83
|
+
app.use(express.urlencoded({ extended: true, limit: "500mb", parameterLimit: 50000 }))
|
|
84
|
+
|
|
85
|
+
if (this.options.static) {
|
|
86
|
+
app.use(express.static(this.options.static))
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// @ts-ignore-next-line
|
|
90
|
+
const server : Server = this
|
|
91
|
+
this._app = this.hooks.create(app, server) || app
|
|
92
|
+
|
|
93
|
+
return app
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Start the Express HTTP server. A runtime `port` overrides the constructor
|
|
98
|
+
* option and is written to state so `server.port` always reflects reality.
|
|
99
|
+
*
|
|
100
|
+
* @param options - Optional runtime overrides for port and host
|
|
101
|
+
*/
|
|
102
|
+
override async start(options?: StartOptions): Promise<this> {
|
|
103
|
+
if (this.isListening) {
|
|
104
|
+
return this
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
await this._drainPendingPlugins()
|
|
108
|
+
|
|
109
|
+
// Apply runtime port to state so this.port reflects the override
|
|
110
|
+
if (options?.port) {
|
|
111
|
+
this.state.set('port', options.port)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const startOptions = {
|
|
115
|
+
port: this.port,
|
|
116
|
+
host: options?.host || this.options.host || '0.0.0.0',
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// @ts-ignore-next-line
|
|
120
|
+
await this.hooks.beforeStart(startOptions, this)
|
|
121
|
+
|
|
122
|
+
// SPA history fallback: serve index.html for unmatched GET routes
|
|
123
|
+
if (this.options.historyFallback && this.options.static) {
|
|
124
|
+
const indexPath = `${this.options.static}/index.html`
|
|
125
|
+
this.app.get('*', (_req: any, res: any) => {
|
|
126
|
+
res.sendFile(indexPath)
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
await new Promise((res) => {
|
|
131
|
+
this._listener = this.app.listen(startOptions.port, startOptions.host, () => {
|
|
132
|
+
this.state.set('listening', true)
|
|
133
|
+
res(null)
|
|
134
|
+
})
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
return this
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
override async stop(): Promise<this> {
|
|
141
|
+
if (this.isStopped) {
|
|
142
|
+
return this
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
await Promise.race([
|
|
146
|
+
new Promise<void>((resolve) => {
|
|
147
|
+
if (!this._listener) {
|
|
148
|
+
resolve()
|
|
149
|
+
return
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
try {
|
|
153
|
+
this._listener.close(() => {
|
|
154
|
+
this._listener = undefined
|
|
155
|
+
resolve()
|
|
156
|
+
})
|
|
157
|
+
} catch {
|
|
158
|
+
this._listener = undefined
|
|
159
|
+
resolve()
|
|
160
|
+
}
|
|
161
|
+
}),
|
|
162
|
+
new Promise<void>((resolve) => setTimeout(resolve, 500)),
|
|
163
|
+
])
|
|
164
|
+
|
|
165
|
+
this.state.set('listening', false)
|
|
166
|
+
this.state.set('stopped', true)
|
|
167
|
+
return this
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
override async configure(): Promise<this> {
|
|
171
|
+
this.state.set('configured', true)
|
|
172
|
+
return this
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
useEndpoint(endpoint: Endpoint): this {
|
|
176
|
+
endpoint.mount(this.app)
|
|
177
|
+
this._mountedEndpoints.push(endpoint)
|
|
178
|
+
return this
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
async useEndpoints(dir: string): Promise<this> {
|
|
182
|
+
const { Glob } = globalThis.Bun || (await import('bun'))
|
|
183
|
+
const glob = new Glob('**/*.ts')
|
|
184
|
+
|
|
185
|
+
// Use the helpers feature's VM-aware loader so endpoints can resolve
|
|
186
|
+
// packages like zod and luca even from the compiled binary
|
|
187
|
+
const helpers = this.container.feature('helpers') as any
|
|
188
|
+
|
|
189
|
+
for await (const file of glob.scan({ cwd: dir, absolute: true })) {
|
|
190
|
+
try {
|
|
191
|
+
const mod = await helpers.loadModuleExports(file)
|
|
192
|
+
const endpointModule: EndpointModule = mod.default || mod
|
|
193
|
+
|
|
194
|
+
if (!endpointModule.path) {
|
|
195
|
+
continue
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
warnUnknownExports(mod, file)
|
|
199
|
+
|
|
200
|
+
const endpoint = new Endpoint(
|
|
201
|
+
{ path: endpointModule.path, filePath: file },
|
|
202
|
+
this.container.context
|
|
203
|
+
)
|
|
204
|
+
await endpoint.load(endpointModule)
|
|
205
|
+
this.useEndpoint(endpoint)
|
|
206
|
+
} catch (err) {
|
|
207
|
+
console.error(`Failed to load endpoint from ${file}:`, err)
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return this
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Reload a mounted endpoint by its file path. Re-reads the module through
|
|
216
|
+
* the helpers VM loader so the next request picks up the new handlers.
|
|
217
|
+
*
|
|
218
|
+
* @param filePath - Absolute path to the endpoint file
|
|
219
|
+
* @returns The reloaded Endpoint, or null if no mounted endpoint matches
|
|
220
|
+
*/
|
|
221
|
+
async reloadEndpoint(filePath: string): Promise<Endpoint | null> {
|
|
222
|
+
const endpoint = this._mountedEndpoints.find(ep => (ep.options as any).filePath === filePath)
|
|
223
|
+
if (!endpoint) return null
|
|
224
|
+
|
|
225
|
+
const helpers = this.container.feature('helpers') as any
|
|
226
|
+
const mod = await helpers.loadModuleExports(filePath, { cacheBust: true })
|
|
227
|
+
const endpointModule: EndpointModule = mod.default || mod
|
|
228
|
+
await endpoint.load(endpointModule)
|
|
229
|
+
return endpoint
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
async useEndpointModules(modules: EndpointModule[]): Promise<this> {
|
|
233
|
+
for (const mod of modules) {
|
|
234
|
+
try {
|
|
235
|
+
const endpointModule: EndpointModule = (mod as any).default || mod
|
|
236
|
+
|
|
237
|
+
if (!endpointModule.path) {
|
|
238
|
+
continue
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const endpoint = new Endpoint(
|
|
242
|
+
{ path: endpointModule.path },
|
|
243
|
+
this.container.context
|
|
244
|
+
)
|
|
245
|
+
await endpoint.load(endpointModule)
|
|
246
|
+
this.useEndpoint(endpoint)
|
|
247
|
+
} catch (err) {
|
|
248
|
+
console.error(`Failed to load endpoint module (${(mod as any).path || 'unknown'}):`, err)
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return this
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
serveOpenAPISpec(options: { title?: string; version?: string; description?: string } = {}): this {
|
|
256
|
+
const server = this
|
|
257
|
+
this.app.get('/openapi.json', (_req: any, res: any) => {
|
|
258
|
+
res.json(server.generateOpenAPISpec(options))
|
|
259
|
+
})
|
|
260
|
+
return this
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
generateOpenAPISpec(options: { title?: string; version?: string; description?: string } = {}): Record<string, any> {
|
|
264
|
+
const paths: Record<string, any> = {}
|
|
265
|
+
|
|
266
|
+
for (const ep of this._mountedEndpoints) {
|
|
267
|
+
paths[ep.path] = ep.toOpenAPIPathItem()
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
return {
|
|
271
|
+
openapi: '3.1.0',
|
|
272
|
+
info: {
|
|
273
|
+
title: options.title || 'Luca API',
|
|
274
|
+
version: options.version || '1.0.0',
|
|
275
|
+
description: options.description || 'Auto-generated from Luca endpoints',
|
|
276
|
+
},
|
|
277
|
+
servers: [{ url: `http://localhost:${this.port}` }],
|
|
278
|
+
paths,
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
export default ExpressServer
|