luca 2.0.0 → 3.0.0
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 +169 -0
- package/AGENTS.md +99 -0
- package/CLAUDE.md +115 -0
- package/CNAME +1 -0
- package/README.md +257 -9
- package/RUNME.md +56 -0
- package/assistants/codingAssistant/ABOUT.md +5 -0
- package/assistants/codingAssistant/CORE.md +28 -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 +2769 -0
- package/bunfig.toml +3 -0
- package/commands/audit-docs.ts +740 -0
- package/commands/build-bootstrap.ts +118 -0
- package/commands/build-python-bridge.ts +43 -0
- package/commands/build-scaffolds.ts +176 -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/docs/CLI.md +335 -0
- package/docs/CNAME +1 -0
- package/docs/README.md +60 -0
- package/docs/TABLE-OF-CONTENTS.md +183 -0
- package/docs/apis/clients/elevenlabs.md +308 -0
- package/docs/apis/clients/graph.md +107 -0
- package/docs/apis/clients/openai.md +429 -0
- package/docs/apis/clients/rest.md +161 -0
- package/docs/apis/clients/websocket.md +174 -0
- package/docs/apis/features/agi/assistant.md +625 -0
- package/docs/apis/features/agi/assistants-manager.md +282 -0
- package/docs/apis/features/agi/auto-assistant.md +279 -0
- package/docs/apis/features/agi/browser-use.md +802 -0
- package/docs/apis/features/agi/claude-code.md +884 -0
- package/docs/apis/features/agi/conversation-history.md +364 -0
- package/docs/apis/features/agi/conversation.md +548 -0
- package/docs/apis/features/agi/docs-reader.md +99 -0
- package/docs/apis/features/agi/file-tools.md +163 -0
- package/docs/apis/features/agi/luca-coder.md +407 -0
- package/docs/apis/features/agi/openai-codex.md +396 -0
- package/docs/apis/features/agi/openapi.md +138 -0
- package/docs/apis/features/agi/semantic-search.md +387 -0
- package/docs/apis/features/agi/skills-library.md +239 -0
- package/docs/apis/features/node/container-link.md +192 -0
- package/docs/apis/features/node/content-db.md +450 -0
- package/docs/apis/features/node/disk-cache.md +379 -0
- package/docs/apis/features/node/dns.md +652 -0
- package/docs/apis/features/node/docker.md +706 -0
- package/docs/apis/features/node/downloader.md +81 -0
- package/docs/apis/features/node/esbuild.md +60 -0
- package/docs/apis/features/node/file-manager.md +191 -0
- package/docs/apis/features/node/fs.md +1217 -0
- package/docs/apis/features/node/git.md +371 -0
- package/docs/apis/features/node/google-auth.md +193 -0
- package/docs/apis/features/node/google-calendar.md +202 -0
- package/docs/apis/features/node/google-docs.md +173 -0
- package/docs/apis/features/node/google-drive.md +246 -0
- package/docs/apis/features/node/google-mail.md +214 -0
- package/docs/apis/features/node/google-sheets.md +194 -0
- package/docs/apis/features/node/grep.md +292 -0
- package/docs/apis/features/node/helpers.md +164 -0
- package/docs/apis/features/node/ink.md +334 -0
- package/docs/apis/features/node/ipc-socket.md +249 -0
- package/docs/apis/features/node/json-tree.md +86 -0
- package/docs/apis/features/node/networking.md +316 -0
- package/docs/apis/features/node/nlp.md +133 -0
- package/docs/apis/features/node/opener.md +97 -0
- package/docs/apis/features/node/os.md +146 -0
- package/docs/apis/features/node/package-finder.md +392 -0
- package/docs/apis/features/node/postgres.md +234 -0
- package/docs/apis/features/node/proc.md +399 -0
- package/docs/apis/features/node/process-manager.md +305 -0
- package/docs/apis/features/node/python.md +604 -0
- package/docs/apis/features/node/redis.md +380 -0
- package/docs/apis/features/node/repl.md +88 -0
- package/docs/apis/features/node/runpod.md +674 -0
- package/docs/apis/features/node/secure-shell.md +176 -0
- package/docs/apis/features/node/semantic-search.md +408 -0
- package/docs/apis/features/node/sqlite.md +233 -0
- package/docs/apis/features/node/telegram.md +279 -0
- package/docs/apis/features/node/transpiler.md +74 -0
- package/docs/apis/features/node/tts.md +133 -0
- package/docs/apis/features/node/ui.md +701 -0
- package/docs/apis/features/node/vault.md +59 -0
- package/docs/apis/features/node/vm.md +75 -0
- package/docs/apis/features/node/yaml-tree.md +85 -0
- package/docs/apis/features/node/yaml.md +176 -0
- package/docs/apis/features/web/asset-loader.md +59 -0
- package/docs/apis/features/web/container-link.md +192 -0
- package/docs/apis/features/web/esbuild.md +54 -0
- package/docs/apis/features/web/helpers.md +164 -0
- package/docs/apis/features/web/network.md +44 -0
- package/docs/apis/features/web/speech.md +69 -0
- package/docs/apis/features/web/vault.md +59 -0
- package/docs/apis/features/web/vm.md +75 -0
- package/docs/apis/features/web/voice.md +84 -0
- package/docs/apis/servers/express.md +171 -0
- package/docs/apis/servers/mcp.md +238 -0
- package/docs/apis/servers/websocket.md +170 -0
- package/docs/bootstrap/CLAUDE.md +101 -0
- package/docs/bootstrap/SKILL.md +341 -0
- package/docs/bootstrap/templates/about-command.ts +41 -0
- package/docs/bootstrap/templates/docs-models.ts +22 -0
- package/docs/bootstrap/templates/docs-readme.md +43 -0
- package/docs/bootstrap/templates/example-feature.ts +53 -0
- package/docs/bootstrap/templates/health-endpoint.ts +15 -0
- package/docs/bootstrap/templates/luca-cli.ts +30 -0
- package/docs/bootstrap/templates/runme.md +54 -0
- package/docs/challenges/caching-proxy.md +16 -0
- package/docs/challenges/content-db-round-trip.md +14 -0
- package/docs/challenges/custom-command.md +9 -0
- package/docs/challenges/file-watcher-pipeline.md +11 -0
- package/docs/challenges/grep-audit-report.md +15 -0
- package/docs/challenges/multi-feature-dashboard.md +14 -0
- package/docs/challenges/process-orchestrator.md +17 -0
- package/docs/challenges/rest-api-server-with-client.md +12 -0
- package/docs/challenges/script-runner-with-vm.md +11 -0
- package/docs/challenges/simple-rest-api.md +15 -0
- package/docs/challenges/websocket-serve-and-client.md +11 -0
- package/docs/challenges/yaml-config-system.md +14 -0
- package/docs/command-system-overhaul.md +94 -0
- package/docs/documentation-audit.md +134 -0
- package/docs/examples/assistant/CORE.md +18 -0
- package/docs/examples/assistant/hooks.ts +3 -0
- package/docs/examples/assistant/tools.ts +10 -0
- package/docs/examples/assistant-hooks-reference.ts +171 -0
- package/docs/examples/assistant-with-process-manager.md +84 -0
- package/docs/examples/content-db.md +77 -0
- package/docs/examples/disk-cache.md +83 -0
- package/docs/examples/docker.md +101 -0
- package/docs/examples/downloader.md +70 -0
- package/docs/examples/entity.md +124 -0
- package/docs/examples/esbuild.md +80 -0
- package/docs/examples/feature-as-tool-provider.md +143 -0
- package/docs/examples/file-manager.md +82 -0
- package/docs/examples/fs.md +83 -0
- package/docs/examples/git.md +85 -0
- package/docs/examples/google-auth.md +88 -0
- package/docs/examples/google-calendar.md +94 -0
- package/docs/examples/google-docs.md +82 -0
- package/docs/examples/google-drive.md +96 -0
- package/docs/examples/google-sheets.md +95 -0
- package/docs/examples/grep.md +85 -0
- package/docs/examples/ink-blocks.md +75 -0
- package/docs/examples/ink-renderer.md +41 -0
- package/docs/examples/ink.md +103 -0
- package/docs/examples/ipc-socket.md +103 -0
- package/docs/examples/json-tree.md +91 -0
- package/docs/examples/networking.md +58 -0
- package/docs/examples/nlp.md +91 -0
- package/docs/examples/opener.md +78 -0
- package/docs/examples/os.md +72 -0
- package/docs/examples/package-finder.md +89 -0
- package/docs/examples/postgres.md +91 -0
- package/docs/examples/proc.md +81 -0
- package/docs/examples/process-manager.md +79 -0
- package/docs/examples/python.md +132 -0
- package/docs/examples/repl.md +93 -0
- package/docs/examples/runpod.md +119 -0
- package/docs/examples/secure-shell.md +92 -0
- package/docs/examples/sqlite.md +86 -0
- package/docs/examples/structured-output-with-assistants.md +144 -0
- package/docs/examples/telegram.md +77 -0
- package/docs/examples/tts.md +86 -0
- package/docs/examples/ui.md +80 -0
- package/docs/examples/vault.md +70 -0
- package/docs/examples/vm.md +86 -0
- package/docs/examples/websocket-ask-and-reply-example.md +128 -0
- package/docs/examples/yaml-tree.md +93 -0
- package/docs/examples/yaml.md +104 -0
- package/docs/ideas/assistant-factory-pattern.md +142 -0
- package/docs/in-memory-fs.md +4 -0
- package/docs/introspection-audit.md +49 -0
- package/docs/introspection.md +164 -0
- package/docs/mcp/readme.md +162 -0
- package/docs/models.ts +41 -0
- package/docs/philosophy.md +86 -0
- package/docs/principles.md +7 -0
- package/docs/prompts/audit-codebase-for-failures-to-use-the-container.md +34 -0
- package/docs/prompts/check-for-undocumented-features.md +27 -0
- package/docs/prompts/mcp-test-easy-command.md +27 -0
- package/docs/scaffolds/client.md +149 -0
- package/docs/scaffolds/command.md +120 -0
- package/docs/scaffolds/endpoint.md +171 -0
- package/docs/scaffolds/feature.md +158 -0
- package/docs/scaffolds/selector.md +91 -0
- package/docs/scaffolds/server.md +196 -0
- package/docs/selectors.md +115 -0
- package/docs/sessions/custom-command/attempt-log-2.md +195 -0
- package/docs/sessions/file-watcher-pipeline/attempt-log-1.md +728 -0
- package/docs/sessions/file-watcher-pipeline/attempt-log-2.md +555 -0
- package/docs/sessions/grep-audit-report/attempt-log-1.md +289 -0
- package/docs/sessions/multi-feature-dashboard/attempt-log-2.md +679 -0
- package/docs/sessions/rest-api-server-with-client/attempt-log-1.md +1 -0
- package/docs/sessions/rest-api-server-with-client/attempt-log-3.md +920 -0
- package/docs/sessions/simple-rest-api/attempt-log-1.md +593 -0
- package/docs/sessions/websocket-serve-and-client/attempt-log-2.md +995 -0
- package/docs/tutorials/00-bootstrap.md +166 -0
- package/docs/tutorials/01-getting-started.md +106 -0
- package/docs/tutorials/02-container.md +210 -0
- package/docs/tutorials/03-scripts.md +194 -0
- package/docs/tutorials/04-features-overview.md +196 -0
- package/docs/tutorials/05-state-and-events.md +171 -0
- package/docs/tutorials/06-servers.md +157 -0
- package/docs/tutorials/07-endpoints.md +198 -0
- package/docs/tutorials/08-commands.md +252 -0
- package/docs/tutorials/09-clients.md +162 -0
- package/docs/tutorials/10-creating-features.md +203 -0
- package/docs/tutorials/11-contentbase.md +191 -0
- package/docs/tutorials/12-assistants.md +215 -0
- package/docs/tutorials/13-introspection.md +157 -0
- package/docs/tutorials/14-type-system.md +174 -0
- package/docs/tutorials/15-project-patterns.md +222 -0
- package/docs/tutorials/16-google-features.md +534 -0
- package/docs/tutorials/17-tui-blocks.md +530 -0
- package/docs/tutorials/18-semantic-search.md +334 -0
- package/docs/tutorials/19-python-sessions.md +401 -0
- package/docs/tutorials/20-browser-esm.md +234 -0
- package/index.html +1430 -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 +1430 -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 +152 -0
- package/src/agi/endpoints/ask.ts +60 -0
- package/src/agi/endpoints/conversations/[id].ts +45 -0
- package/src/agi/endpoints/conversations.ts +31 -0
- package/src/agi/endpoints/experts.ts +37 -0
- package/src/agi/feature.ts +13 -0
- package/src/agi/features/agent-memory.ts +694 -0
- package/src/agi/features/assistant.ts +1624 -0
- package/src/agi/features/assistants-manager.ts +418 -0
- package/src/agi/features/autonomous-assistant.ts +431 -0
- package/src/agi/features/browser-use.ts +653 -0
- package/src/agi/features/claude-code.ts +1538 -0
- package/src/agi/features/coding-tools.ts +175 -0
- package/src/agi/features/conversation-history.ts +495 -0
- package/src/agi/features/conversation.ts +1323 -0
- package/src/agi/features/docs-reader.ts +167 -0
- package/src/agi/features/file-tools.ts +293 -0
- package/src/agi/features/luca-coder.ts +639 -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 +478 -0
- package/src/agi/index.ts +6 -0
- package/src/agi/lib/interceptor-chain.ts +89 -0
- package/src/agi/lib/token-counter.ts +122 -0
- package/src/bootstrap/generated.ts +9792 -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 +505 -0
- package/src/commands/bootstrap.ts +244 -0
- package/src/commands/chat.ts +308 -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 +121 -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 +982 -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 +1084 -0
- package/src/container.ts +1186 -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 +40208 -0
- package/src/introspection/generated.node.ts +28686 -0
- package/src/introspection/generated.web.ts +2251 -0
- package/src/introspection/index.ts +296 -0
- package/src/introspection/scan.ts +1131 -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 +812 -0
- package/src/node/features/disk-cache.ts +388 -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 +735 -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 +906 -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 +267 -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 +161 -0
- package/src/node/features/tts.ts +185 -0
- package/src/node/features/ui.ts +786 -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 +227 -0
- package/src/react/index.ts +175 -0
- package/src/registry.ts +210 -0
- package/src/scaffolds/generated.ts +1815 -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 +269 -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/test/assistant-hooks.test.ts +306 -0
- package/test/assistant.test.ts +81 -0
- package/test/bus.test.ts +134 -0
- package/test/clients-servers.test.ts +217 -0
- package/test/command.test.ts +267 -0
- package/test/container-link.test.ts +274 -0
- package/test/conversation.test.ts +220 -0
- package/test/features.test.ts +160 -0
- package/test/fork-and-research.test.ts +450 -0
- package/test/integration.test.ts +787 -0
- package/test/interceptor-chain.test.ts +61 -0
- package/test/node-container.test.ts +121 -0
- package/test/python-session.test.ts +105 -0
- package/test/rate-limit.test.ts +272 -0
- package/test/semantic-search.test.ts +550 -0
- package/test/state.test.ts +121 -0
- package/test/vm-context.test.ts +146 -0
- package/test/vm-loadmodule.test.ts +213 -0
- package/test/websocket-ask.test.ts +101 -0
- package/test-integration/assistant.test.ts +138 -0
- package/test-integration/assistants-manager.test.ts +113 -0
- package/test-integration/claude-code.test.ts +98 -0
- package/test-integration/conversation-history.test.ts +205 -0
- package/test-integration/conversation.test.ts +137 -0
- package/test-integration/elevenlabs.test.ts +55 -0
- package/test-integration/google-services.test.ts +80 -0
- package/test-integration/helpers.ts +89 -0
- package/test-integration/memory.test.ts +204 -0
- package/test-integration/openai-codex.test.ts +93 -0
- package/test-integration/runpod.test.ts +58 -0
- package/test-integration/server-endpoints.test.ts +97 -0
- package/test-integration/telegram.test.ts +46 -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,401 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Working with Python Projects
|
|
3
|
+
tags: [python, sessions, persistent, bridge, codebase, interop, data-science]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Working with Python Projects
|
|
7
|
+
|
|
8
|
+
Luca's `python` feature has two modes: **stateless** execution (fire-and-forget, one process per call) and **persistent sessions** (a long-lived Python process that maintains state across calls). This tutorial focuses on sessions — the mode that lets you actually work inside a Python codebase.
|
|
9
|
+
|
|
10
|
+
## When to Use Sessions
|
|
11
|
+
|
|
12
|
+
Stateless `execute()` is fine for one-off scripts. But if you need any of these, you want a session:
|
|
13
|
+
|
|
14
|
+
- **Imports that persist** — load `pandas` once, use it across many calls
|
|
15
|
+
- **State that builds up** — query a database, filter results, then export
|
|
16
|
+
- **Working inside a real project** — import your own modules, call your own functions
|
|
17
|
+
- **Expensive setup** — ML model loading, database connections, API client initialization
|
|
18
|
+
|
|
19
|
+
## Quick Start
|
|
20
|
+
|
|
21
|
+
```ts skip
|
|
22
|
+
const python = container.feature('python', { dir: '/path/to/my-python-project' })
|
|
23
|
+
await python.enable()
|
|
24
|
+
await python.startSession()
|
|
25
|
+
|
|
26
|
+
// Everything below runs in the same Python process.
|
|
27
|
+
// Variables, imports, and state persist across calls.
|
|
28
|
+
|
|
29
|
+
await python.run('import pandas as pd')
|
|
30
|
+
await python.run('df = pd.read_csv("data/sales.csv")')
|
|
31
|
+
|
|
32
|
+
const result = await python.run('print(df.shape)')
|
|
33
|
+
console.log(result.stdout) // '(1000, 12)\n'
|
|
34
|
+
|
|
35
|
+
const total = await python.eval('df["revenue"].sum()')
|
|
36
|
+
console.log('Total revenue:', total)
|
|
37
|
+
|
|
38
|
+
await python.stopSession()
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Project Directory
|
|
42
|
+
|
|
43
|
+
The `dir` option tells Luca where the Python project lives. This determines:
|
|
44
|
+
|
|
45
|
+
1. **sys.path** — the bridge adds the project root (and `src/`, `lib/` if they exist) so your imports work
|
|
46
|
+
2. **Environment detection** — Luca looks for `uv.lock`, `pyproject.toml`, `venv/`, etc. in this directory
|
|
47
|
+
3. **Working directory** — the bridge process runs with `cwd` set to this path
|
|
48
|
+
|
|
49
|
+
```ts skip
|
|
50
|
+
// Explicit project directory
|
|
51
|
+
const python = container.feature('python', { dir: '/Users/me/projects/my-api' })
|
|
52
|
+
|
|
53
|
+
// Or defaults to wherever luca was invoked from
|
|
54
|
+
const python = container.feature('python')
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
If your project uses a `src/` layout (common in modern Python), the bridge automatically adds it to `sys.path`:
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
my-project/
|
|
61
|
+
src/
|
|
62
|
+
myapp/
|
|
63
|
+
__init__.py
|
|
64
|
+
models.py
|
|
65
|
+
pyproject.toml
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
```ts skip
|
|
69
|
+
await python.startSession()
|
|
70
|
+
// This works because src/ was added to sys.path
|
|
71
|
+
await python.importModule('myapp.models', 'models')
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Session Lifecycle
|
|
75
|
+
|
|
76
|
+
### Starting
|
|
77
|
+
|
|
78
|
+
`startSession()` spawns a Python bridge process that talks to Luca over stdin/stdout using a JSON-line protocol. The bridge sets up `sys.path` and signals when it's ready.
|
|
79
|
+
|
|
80
|
+
```ts skip
|
|
81
|
+
await python.enable()
|
|
82
|
+
await python.startSession()
|
|
83
|
+
|
|
84
|
+
console.log(python.state.get('sessionActive')) // true
|
|
85
|
+
console.log(python.state.get('sessionId')) // uuid
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Stopping
|
|
89
|
+
|
|
90
|
+
`stopSession()` kills the bridge process and cleans up. Any pending requests are rejected.
|
|
91
|
+
|
|
92
|
+
```ts skip
|
|
93
|
+
await python.stopSession()
|
|
94
|
+
console.log(python.state.get('sessionActive')) // false
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Crash Recovery
|
|
98
|
+
|
|
99
|
+
If the Python process dies unexpectedly (segfault, killed externally), the feature:
|
|
100
|
+
- Sets `sessionActive` to `false`
|
|
101
|
+
- Rejects all pending requests
|
|
102
|
+
- Emits a `sessionError` event
|
|
103
|
+
|
|
104
|
+
```ts skip
|
|
105
|
+
python.on('sessionError', ({ error, sessionId }) => {
|
|
106
|
+
console.error('Python session error:', error)
|
|
107
|
+
// You could restart: await python.startSession()
|
|
108
|
+
})
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## The Session API
|
|
112
|
+
|
|
113
|
+
### run(code, variables?)
|
|
114
|
+
|
|
115
|
+
Execute Python code in the persistent namespace. This is the workhorse method.
|
|
116
|
+
|
|
117
|
+
```ts skip
|
|
118
|
+
// Simple execution
|
|
119
|
+
const result = await python.run('print("hello")')
|
|
120
|
+
// result.ok === true
|
|
121
|
+
// result.stdout === 'hello\n'
|
|
122
|
+
|
|
123
|
+
// With variable injection
|
|
124
|
+
const result = await python.run('print(f"Processing {count} items")', { count: 42 })
|
|
125
|
+
|
|
126
|
+
// Errors don't crash the session
|
|
127
|
+
const bad = await python.run('raise ValueError("oops")')
|
|
128
|
+
// bad.ok === false
|
|
129
|
+
// bad.error === 'oops'
|
|
130
|
+
// bad.traceback === 'Traceback (most recent call last):\n...'
|
|
131
|
+
|
|
132
|
+
// Session still alive after error
|
|
133
|
+
const good = await python.run('print("still here")')
|
|
134
|
+
// good.ok === true
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### eval(expression)
|
|
138
|
+
|
|
139
|
+
Evaluate a Python expression and return its value to JavaScript.
|
|
140
|
+
|
|
141
|
+
```ts skip
|
|
142
|
+
await python.run('x = [1, 2, 3]')
|
|
143
|
+
const length = await python.eval('len(x)') // 3
|
|
144
|
+
const doubled = await python.eval('[i*2 for i in x]') // [2, 4, 6]
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Values are JSON-serialized. Complex types that can't be serialized come back as their `repr()` string.
|
|
148
|
+
|
|
149
|
+
### importModule(name, alias?)
|
|
150
|
+
|
|
151
|
+
Import a module into the session namespace. The alias defaults to the last segment of the module path.
|
|
152
|
+
|
|
153
|
+
```ts skip
|
|
154
|
+
await python.importModule('json') // import json
|
|
155
|
+
await python.importModule('myapp.models', 'models') // import myapp.models as models
|
|
156
|
+
await python.importModule('os.path') // import os.path (available as "path")
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### call(funcPath, args?, kwargs?)
|
|
160
|
+
|
|
161
|
+
Call a function by its dotted path in the namespace.
|
|
162
|
+
|
|
163
|
+
```ts skip
|
|
164
|
+
await python.importModule('json')
|
|
165
|
+
const encoded = await python.call('json.dumps', [{ a: 1 }], { indent: 2 })
|
|
166
|
+
// '{\n "a": 1\n}'
|
|
167
|
+
|
|
168
|
+
// Works with your own functions too
|
|
169
|
+
await python.run('def add(a, b): return a + b')
|
|
170
|
+
const sum = await python.call('add', [3, 4]) // 7
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### getLocals()
|
|
174
|
+
|
|
175
|
+
Inspect everything in the session namespace.
|
|
176
|
+
|
|
177
|
+
```ts skip
|
|
178
|
+
await python.run('x = 42')
|
|
179
|
+
await python.importModule('json')
|
|
180
|
+
const locals = await python.getLocals()
|
|
181
|
+
// { x: 42, json: '<module ...>' }
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### resetSession()
|
|
185
|
+
|
|
186
|
+
Clear all variables and imports without restarting the process.
|
|
187
|
+
|
|
188
|
+
```ts skip
|
|
189
|
+
await python.run('big_model = load_model()')
|
|
190
|
+
await python.resetSession()
|
|
191
|
+
// big_model is gone, but the session process is still running
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Real-World Patterns
|
|
195
|
+
|
|
196
|
+
### Data Analysis Pipeline
|
|
197
|
+
|
|
198
|
+
```ts skip
|
|
199
|
+
const python = container.feature('python', { dir: '/path/to/analytics' })
|
|
200
|
+
await python.enable()
|
|
201
|
+
await python.startSession()
|
|
202
|
+
|
|
203
|
+
// Setup
|
|
204
|
+
await python.run('import pandas as pd')
|
|
205
|
+
await python.run('import matplotlib')
|
|
206
|
+
await python.run('matplotlib.use("Agg")') // headless
|
|
207
|
+
await python.run('import matplotlib.pyplot as plt')
|
|
208
|
+
|
|
209
|
+
// Load and analyze
|
|
210
|
+
await python.run('df = pd.read_csv("data/events.csv")')
|
|
211
|
+
const shape = await python.eval('list(df.shape)')
|
|
212
|
+
console.log(`Loaded ${shape[0]} rows, ${shape[1]} columns`)
|
|
213
|
+
|
|
214
|
+
const columns = await python.eval('list(df.columns)')
|
|
215
|
+
console.log('Columns:', columns)
|
|
216
|
+
|
|
217
|
+
// Filter and aggregate
|
|
218
|
+
await python.run(`
|
|
219
|
+
filtered = df[df["status"] == "completed"]
|
|
220
|
+
summary = filtered.groupby("category")["amount"].agg(["sum", "mean", "count"])
|
|
221
|
+
`)
|
|
222
|
+
|
|
223
|
+
const summary = await python.eval('summary.to_dict()')
|
|
224
|
+
console.log('Summary:', summary)
|
|
225
|
+
|
|
226
|
+
// Generate a chart
|
|
227
|
+
await python.run(`
|
|
228
|
+
fig, ax = plt.subplots(figsize=(10, 6))
|
|
229
|
+
summary["sum"].plot(kind="bar", ax=ax)
|
|
230
|
+
ax.set_title("Revenue by Category")
|
|
231
|
+
fig.savefig("output/revenue.png", dpi=150, bbox_inches="tight")
|
|
232
|
+
plt.close(fig)
|
|
233
|
+
`)
|
|
234
|
+
|
|
235
|
+
await python.stopSession()
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Working with a Django Project
|
|
239
|
+
|
|
240
|
+
```ts skip
|
|
241
|
+
const python = container.feature('python', { dir: '/path/to/django-project' })
|
|
242
|
+
await python.enable()
|
|
243
|
+
await python.startSession()
|
|
244
|
+
|
|
245
|
+
// Django requires this before you can import models
|
|
246
|
+
await python.run(`
|
|
247
|
+
import os
|
|
248
|
+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings")
|
|
249
|
+
|
|
250
|
+
import django
|
|
251
|
+
django.setup()
|
|
252
|
+
`)
|
|
253
|
+
|
|
254
|
+
// Now you can work with the ORM
|
|
255
|
+
await python.run('from myapp.models import User, Order')
|
|
256
|
+
|
|
257
|
+
const userCount = await python.eval('User.objects.count()')
|
|
258
|
+
console.log(`${userCount} users in database`)
|
|
259
|
+
|
|
260
|
+
const recentOrders = await python.eval(`
|
|
261
|
+
list(Order.objects.filter(status="pending").values("id", "total", "created_at")[:10])
|
|
262
|
+
`)
|
|
263
|
+
console.log('Recent pending orders:', recentOrders)
|
|
264
|
+
|
|
265
|
+
await python.stopSession()
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### ML Model Interaction
|
|
269
|
+
|
|
270
|
+
```ts skip
|
|
271
|
+
const python = container.feature('python', { dir: '/path/to/ml-project' })
|
|
272
|
+
await python.enable()
|
|
273
|
+
await python.startSession()
|
|
274
|
+
|
|
275
|
+
// Expensive setup — only happens once
|
|
276
|
+
await python.run(`
|
|
277
|
+
from transformers import pipeline
|
|
278
|
+
classifier = pipeline("sentiment-analysis")
|
|
279
|
+
print("Model loaded")
|
|
280
|
+
`)
|
|
281
|
+
|
|
282
|
+
// Now you can call it cheaply many times
|
|
283
|
+
async function classify(text: string) {
|
|
284
|
+
return python.call('classifier', [text])
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
const results = await Promise.all([
|
|
288
|
+
classify('I love this product!'),
|
|
289
|
+
classify('Terrible experience.'),
|
|
290
|
+
classify('It was okay, nothing special.'),
|
|
291
|
+
])
|
|
292
|
+
|
|
293
|
+
console.log(results)
|
|
294
|
+
// [
|
|
295
|
+
// [{ label: 'POSITIVE', score: 0.9998 }],
|
|
296
|
+
// [{ label: 'NEGATIVE', score: 0.9994 }],
|
|
297
|
+
// [{ label: 'NEGATIVE', score: 0.7231 }],
|
|
298
|
+
// ]
|
|
299
|
+
|
|
300
|
+
await python.stopSession()
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### Luca Command That Uses Python
|
|
304
|
+
|
|
305
|
+
```ts skip
|
|
306
|
+
// commands/analyze.ts
|
|
307
|
+
import { z } from 'zod'
|
|
308
|
+
import type { ContainerContext } from '@soederpop/luca'
|
|
309
|
+
import { CommandOptionsSchema } from '@soederpop/luca/schemas'
|
|
310
|
+
|
|
311
|
+
export const positionals = ['target']
|
|
312
|
+
export const argsSchema = CommandOptionsSchema.extend({
|
|
313
|
+
target: z.string().describe('Path to CSV file to analyze'),
|
|
314
|
+
})
|
|
315
|
+
|
|
316
|
+
async function handler(options: z.infer<typeof argsSchema>, context: ContainerContext) {
|
|
317
|
+
const container = context.container as any
|
|
318
|
+
const python = container.feature('python')
|
|
319
|
+
await python.enable()
|
|
320
|
+
await python.startSession()
|
|
321
|
+
|
|
322
|
+
try {
|
|
323
|
+
await python.run('import pandas as pd')
|
|
324
|
+
await python.run(`df = pd.read_csv("${options.target}")`)
|
|
325
|
+
|
|
326
|
+
const shape = await python.eval('list(df.shape)')
|
|
327
|
+
const dtypes = await python.eval('dict(df.dtypes.astype(str))')
|
|
328
|
+
const nulls = await python.eval('dict(df.isnull().sum())')
|
|
329
|
+
|
|
330
|
+
console.log(`Rows: ${shape[0]}, Columns: ${shape[1]}`)
|
|
331
|
+
console.log('Column types:', dtypes)
|
|
332
|
+
console.log('Null counts:', nulls)
|
|
333
|
+
} finally {
|
|
334
|
+
await python.stopSession()
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
export default {
|
|
339
|
+
description: 'Analyze a CSV file using pandas',
|
|
340
|
+
argsSchema,
|
|
341
|
+
handler,
|
|
342
|
+
}
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
```bash
|
|
346
|
+
luca analyze data/sales.csv
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
## Stateless vs. Session: Choosing the Right Mode
|
|
350
|
+
|
|
351
|
+
| | `execute()` (stateless) | `run()` (session) |
|
|
352
|
+
|---|---|---|
|
|
353
|
+
| Process | Fresh per call | Shared, long-lived |
|
|
354
|
+
| State | None — each call starts clean | Persists across calls |
|
|
355
|
+
| Imports | Re-imported every time | Imported once, reused |
|
|
356
|
+
| Startup cost | ~50-200ms per call | ~200ms once, then ~1ms per call |
|
|
357
|
+
| Use case | One-off scripts, simple eval | Real projects, data pipelines, REPL-like |
|
|
358
|
+
| Error isolation | Perfect — crash is contained | Errors caught, session survives |
|
|
359
|
+
|
|
360
|
+
Both modes use the same environment detection (uv, conda, venv, system) and respect the same `dir` and `pythonPath` options.
|
|
361
|
+
|
|
362
|
+
## Environment Detection
|
|
363
|
+
|
|
364
|
+
The feature detects Python environments in this order:
|
|
365
|
+
|
|
366
|
+
1. **Explicit** — `pythonPath` option overrides everything
|
|
367
|
+
2. **uv** — `uv.lock` or `pyproject.toml` present, `uv run python` works
|
|
368
|
+
3. **conda** — `environment.yml` or `conda.yml` present
|
|
369
|
+
4. **venv** — `venv/` or `.venv/` directory with a Python binary inside
|
|
370
|
+
5. **system** — falls back to `python3` or `python` on PATH
|
|
371
|
+
|
|
372
|
+
```ts skip
|
|
373
|
+
const python = container.feature('python', { dir: '/path/to/project' })
|
|
374
|
+
await python.enable()
|
|
375
|
+
console.log(python.environmentType) // 'uv' | 'conda' | 'venv' | 'system'
|
|
376
|
+
console.log(python.pythonPath) // e.g. '/Users/me/.local/bin/uv run python'
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
## Events
|
|
380
|
+
|
|
381
|
+
The session emits events you can listen to for monitoring and debugging:
|
|
382
|
+
|
|
383
|
+
```ts skip
|
|
384
|
+
python.on('sessionStarted', ({ sessionId }) => {
|
|
385
|
+
console.log('Session started:', sessionId)
|
|
386
|
+
})
|
|
387
|
+
|
|
388
|
+
python.on('sessionStopped', ({ sessionId }) => {
|
|
389
|
+
console.log('Session stopped:', sessionId)
|
|
390
|
+
})
|
|
391
|
+
|
|
392
|
+
python.on('sessionError', ({ error, sessionId }) => {
|
|
393
|
+
console.error('Session error:', error)
|
|
394
|
+
})
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
## What's Next
|
|
398
|
+
|
|
399
|
+
- [Creating Features](./10-creating-features.md) — build your own feature that wraps a Python service
|
|
400
|
+
- [Commands](./08-commands.md) — create CLI commands that leverage Python
|
|
401
|
+
- [Servers and Endpoints](./06-servers.md) — expose Python-powered analysis via HTTP
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Browser: Import Luca from esm.sh"
|
|
3
|
+
tags:
|
|
4
|
+
- browser
|
|
5
|
+
- esm
|
|
6
|
+
- web
|
|
7
|
+
- quickstart
|
|
8
|
+
- cdn
|
|
9
|
+
---
|
|
10
|
+
# Browser: Import Luca from esm.sh
|
|
11
|
+
|
|
12
|
+
You can use Luca in any browser environment — no bundler, no build step. Import it from [esm.sh](https://esm.sh) and you get the singleton container on `window.luca`, ready to go. All the same APIs apply.
|
|
13
|
+
|
|
14
|
+
## Basic Setup
|
|
15
|
+
|
|
16
|
+
```html
|
|
17
|
+
<script type="module">
|
|
18
|
+
import "https://esm.sh/@soederpop/luca/web"
|
|
19
|
+
|
|
20
|
+
const container = window.luca
|
|
21
|
+
console.log(container.uuid) // unique container ID
|
|
22
|
+
console.log(container.features.available) // ['assetLoader', 'voice', 'speech', 'network', 'vault', 'vm', 'esbuild', 'helpers', 'containerLink']
|
|
23
|
+
</script>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The import triggers module evaluation, which creates the `WebContainer` singleton and attaches it to `window.luca`. That's it.
|
|
27
|
+
|
|
28
|
+
If you prefer a named import:
|
|
29
|
+
|
|
30
|
+
```html
|
|
31
|
+
<script type="module">
|
|
32
|
+
import container from "https://esm.sh/@soederpop/luca/web"
|
|
33
|
+
// container === window.luca
|
|
34
|
+
</script>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Using Features
|
|
38
|
+
|
|
39
|
+
Once you have the container, features work exactly like they do on the server — lazy-loaded via `container.feature()`.
|
|
40
|
+
|
|
41
|
+
```html
|
|
42
|
+
<script type="module">
|
|
43
|
+
import "https://esm.sh/@soederpop/luca/web"
|
|
44
|
+
const { luca: container } = window
|
|
45
|
+
|
|
46
|
+
// Load a script from a CDN
|
|
47
|
+
const assetLoader = container.feature('assetLoader')
|
|
48
|
+
await assetLoader.loadScript('https://cdn.jsdelivr.net/npm/chart.js')
|
|
49
|
+
|
|
50
|
+
// Load a stylesheet
|
|
51
|
+
await assetLoader.loadStylesheet('https://cdn.jsdelivr.net/npm/water.css@2/out/water.css')
|
|
52
|
+
|
|
53
|
+
// Text-to-speech
|
|
54
|
+
const speech = container.feature('speech')
|
|
55
|
+
speech.speak('Hello from Luca')
|
|
56
|
+
|
|
57
|
+
// Voice recognition
|
|
58
|
+
const voice = container.feature('voice')
|
|
59
|
+
voice.on('transcript', ({ text }) => console.log('Heard:', text))
|
|
60
|
+
voice.start()
|
|
61
|
+
</script>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## State and Events
|
|
65
|
+
|
|
66
|
+
The container is a state machine and event bus. This works identically to the server.
|
|
67
|
+
|
|
68
|
+
```html
|
|
69
|
+
<script type="module">
|
|
70
|
+
import container from "https://esm.sh/@soederpop/luca/web"
|
|
71
|
+
|
|
72
|
+
// Listen for state changes
|
|
73
|
+
container.on('stateChanged', ({ changes }) => {
|
|
74
|
+
console.log('State changed:', changes)
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
// Feature-level state and events
|
|
78
|
+
const voice = container.feature('voice')
|
|
79
|
+
voice.on('stateChanged', ({ changes }) => {
|
|
80
|
+
document.getElementById('status').textContent = changes.listening ? 'Listening...' : 'Idle'
|
|
81
|
+
})
|
|
82
|
+
</script>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## REST Client
|
|
86
|
+
|
|
87
|
+
Make HTTP requests with the built-in REST client. Methods return parsed JSON directly.
|
|
88
|
+
|
|
89
|
+
```html
|
|
90
|
+
<script type="module">
|
|
91
|
+
import container from "https://esm.sh/@soederpop/luca/web"
|
|
92
|
+
|
|
93
|
+
const api = container.client('rest', { baseURL: 'https://jsonplaceholder.typicode.com' })
|
|
94
|
+
const posts = await api.get('/posts')
|
|
95
|
+
console.log(posts) // array of post objects, not a Response wrapper
|
|
96
|
+
</script>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## WebSocket Client
|
|
100
|
+
|
|
101
|
+
Connect to a WebSocket server:
|
|
102
|
+
|
|
103
|
+
```html
|
|
104
|
+
<script type="module">
|
|
105
|
+
import container from "https://esm.sh/@soederpop/luca/web"
|
|
106
|
+
|
|
107
|
+
const socket = container.client('socket', { url: 'ws://localhost:3000' })
|
|
108
|
+
socket.on('message', (data) => console.log('Received:', data))
|
|
109
|
+
socket.send({ type: 'hello' })
|
|
110
|
+
</script>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Extending: Custom Features
|
|
114
|
+
|
|
115
|
+
The container exposes the `Feature` class directly, so you can create your own features without any additional imports.
|
|
116
|
+
|
|
117
|
+
```html
|
|
118
|
+
<script type="module">
|
|
119
|
+
import container from "https://esm.sh/@soederpop/luca/web"
|
|
120
|
+
|
|
121
|
+
const { Feature } = container
|
|
122
|
+
|
|
123
|
+
class Theme extends Feature {
|
|
124
|
+
static shortcut = 'features.theme'
|
|
125
|
+
static { Feature.register(this, 'theme') }
|
|
126
|
+
|
|
127
|
+
get current() {
|
|
128
|
+
return this.state.get('mode') || 'light'
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
toggle() {
|
|
132
|
+
const next = this.current === 'light' ? 'dark' : 'light'
|
|
133
|
+
this.state.set('mode', next)
|
|
134
|
+
document.documentElement.setAttribute('data-theme', next)
|
|
135
|
+
this.emit('themeChanged', { mode: next })
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const theme = container.feature('theme')
|
|
140
|
+
theme.on('themeChanged', ({ mode }) => console.log('Theme:', mode))
|
|
141
|
+
theme.toggle() // => Theme: dark
|
|
142
|
+
</script>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Utilities
|
|
146
|
+
|
|
147
|
+
The container's built-in utilities are available in the browser too.
|
|
148
|
+
|
|
149
|
+
```html
|
|
150
|
+
<script type="module">
|
|
151
|
+
import container from "https://esm.sh/@soederpop/luca/web"
|
|
152
|
+
|
|
153
|
+
// UUID generation
|
|
154
|
+
const id = container.utils.uuid()
|
|
155
|
+
|
|
156
|
+
// Lodash helpers
|
|
157
|
+
const { groupBy, keyBy, pick } = container.utils.lodash
|
|
158
|
+
|
|
159
|
+
// String utilities
|
|
160
|
+
const { camelCase, kebabCase } = container.utils.stringUtils
|
|
161
|
+
</script>
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Full Example: A Minimal App
|
|
165
|
+
|
|
166
|
+
```html
|
|
167
|
+
<!DOCTYPE html>
|
|
168
|
+
<html lang="en">
|
|
169
|
+
<head>
|
|
170
|
+
<meta charset="UTF-8">
|
|
171
|
+
<title>Luca Browser Demo</title>
|
|
172
|
+
</head>
|
|
173
|
+
<body>
|
|
174
|
+
<h1>Luca Browser Demo</h1>
|
|
175
|
+
<button id="speak">Speak</button>
|
|
176
|
+
<button id="theme">Toggle Theme</button>
|
|
177
|
+
<pre id="output"></pre>
|
|
178
|
+
|
|
179
|
+
<script type="module">
|
|
180
|
+
import container from "https://esm.sh/@soederpop/luca/web"
|
|
181
|
+
|
|
182
|
+
const log = (msg) => {
|
|
183
|
+
document.getElementById('output').textContent += msg + '\n'
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Load a stylesheet
|
|
187
|
+
const assets = container.feature('assetLoader')
|
|
188
|
+
await assets.loadStylesheet('https://cdn.jsdelivr.net/npm/water.css@2/out/water.css')
|
|
189
|
+
|
|
190
|
+
// Custom feature
|
|
191
|
+
const { Feature } = container
|
|
192
|
+
|
|
193
|
+
class Theme extends Feature {
|
|
194
|
+
static shortcut = 'features.theme'
|
|
195
|
+
static { Feature.register(this, 'theme') }
|
|
196
|
+
|
|
197
|
+
toggle() {
|
|
198
|
+
const next = (this.state.get('mode') || 'light') === 'light' ? 'dark' : 'light'
|
|
199
|
+
this.state.set('mode', next)
|
|
200
|
+
document.documentElement.style.colorScheme = next
|
|
201
|
+
this.emit('themeChanged', { mode: next })
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const theme = container.feature('theme')
|
|
206
|
+
theme.on('themeChanged', ({ mode }) => log(`Theme: ${mode}`))
|
|
207
|
+
|
|
208
|
+
// Speech
|
|
209
|
+
const speech = container.feature('speech')
|
|
210
|
+
|
|
211
|
+
document.getElementById('speak').onclick = () => speech.speak('Hello from Luca')
|
|
212
|
+
document.getElementById('theme').onclick = () => theme.toggle()
|
|
213
|
+
|
|
214
|
+
log(`Container ID: ${container.uuid}`)
|
|
215
|
+
log(`Features: ${container.features.available.join(', ')}`)
|
|
216
|
+
</script>
|
|
217
|
+
</body>
|
|
218
|
+
</html>
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Save this as an HTML file, open it in a browser, and everything works — no npm, no bundler, no build step.
|
|
222
|
+
|
|
223
|
+
## Gotchas
|
|
224
|
+
|
|
225
|
+
- **esm.sh caches aggressively.** Pin a version if you need stability: `https://esm.sh/@soederpop/luca@0.0.29/web`
|
|
226
|
+
- **Browser features only.** The web container doesn't include node-specific features like `fs`, `git`, `proc`, or `docker`. If you need server features, run Luca on the server and connect via the REST or WebSocket clients.
|
|
227
|
+
- **`window.luca` is the singleton.** Don't call `createContainer()` — it just warns and returns the same instance. If you need isolation, use `container.subcontainer()`.
|
|
228
|
+
- **CORS applies.** REST client requests from the browser are subject to browser CORS rules. Your API must send the right headers.
|
|
229
|
+
|
|
230
|
+
## What's Next
|
|
231
|
+
|
|
232
|
+
- [State and Events](./05-state-and-events.md) — deep dive into the state machine and event bus (works identically in the browser)
|
|
233
|
+
- [Creating Features](./10-creating-features.md) — full anatomy of a feature with schemas, state, and events
|
|
234
|
+
- [Clients](./09-clients.md) — REST and WebSocket client APIs
|