luca 1.1.2 → 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 -8
- 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 -0
- 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 -66
- 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/index.d.ts +0 -2
- package/dist/cli/index.js +0 -5
- package/dist/cli/run.d.ts +0 -12
- package/dist/cli/run.js +0 -42
- package/dist/config/consts.d.ts +0 -2
- package/dist/config/consts.js +0 -29
- package/dist/config/default.d.ts +0 -8
- package/dist/config/default.js +0 -15
- package/dist/config/initConfig.d.ts +0 -1
- package/dist/config/initConfig.js +0 -52
- package/dist/config/openConfig.d.ts +0 -2
- package/dist/config/openConfig.js +0 -24
- package/dist/config/runConfig.d.ts +0 -3
- package/dist/config/runConfig.js +0 -117
- package/dist/config/types.d.ts +0 -13
- package/dist/config/types.js +0 -2
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -5
- package/dist/utils/common.d.ts +0 -2
- package/dist/utils/common.js +0 -52
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/index.js +0 -17
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# Building a Feature
|
|
2
|
+
|
|
3
|
+
A feature is a container-managed capability — something your application needs that lives on the machine (file I/O, caching, encryption, etc). Features are lazy-loaded, observable, and self-documenting.
|
|
4
|
+
|
|
5
|
+
When to build a feature:
|
|
6
|
+
- You need a reusable local capability (not a network call — that's a client)
|
|
7
|
+
- You want state management, events, and introspection for free
|
|
8
|
+
- You're wrapping a library so the rest of the codebase uses a uniform interface
|
|
9
|
+
|
|
10
|
+
## Imports
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import { z } from 'zod'
|
|
14
|
+
import { FeatureStateSchema, FeatureOptionsSchema, FeatureEventsSchema } from '@soederpop/luca'
|
|
15
|
+
import { Feature } from '@soederpop/luca'
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
These are the only imports your feature file needs from luca. If your feature wraps a third-party library, import it here too — feature implementations are the ONE place where direct library imports are allowed.
|
|
19
|
+
|
|
20
|
+
The use of dynamic imports is encouraged here, only import libraries you need when the feature is used, and only when necessary in the lifecycle of the feature if it can be done.
|
|
21
|
+
|
|
22
|
+
feature's have built in ways to check if their requirements are supported and can be enabled cautiously.
|
|
23
|
+
|
|
24
|
+
## Schemas
|
|
25
|
+
|
|
26
|
+
Define the shape of your feature's state, options, and events using Zod. Every field must have a `.describe()` — this becomes the documentation.
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
export const {{PascalName}}StateSchema = FeatureStateSchema.extend({
|
|
30
|
+
// Add your state fields here. These are observable — changes emit events.
|
|
31
|
+
// Example: itemCount: z.number().default(0).describe('Number of items stored'),
|
|
32
|
+
})
|
|
33
|
+
export type {{PascalName}}State = z.infer<typeof {{PascalName}}StateSchema>
|
|
34
|
+
|
|
35
|
+
export const {{PascalName}}OptionsSchema = FeatureOptionsSchema.extend({
|
|
36
|
+
// Add constructor options here. Validated when the feature is created.
|
|
37
|
+
// Example: directory: z.string().optional().describe('Storage directory path'),
|
|
38
|
+
})
|
|
39
|
+
export type {{PascalName}}Options = z.infer<typeof {{PascalName}}OptionsSchema>
|
|
40
|
+
|
|
41
|
+
export const {{PascalName}}EventsSchema = FeatureEventsSchema.extend({
|
|
42
|
+
// Each key is an event name. Value is z.tuple() of listener arguments.
|
|
43
|
+
// Example: itemAdded: z.tuple([z.string().describe('Item key')]).describe('Emitted when an item is added'),
|
|
44
|
+
})
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Class
|
|
48
|
+
|
|
49
|
+
The class extends `Feature` with your state and options types. Static properties drive registration and introspection. Every public method needs a JSDoc block with `@param`, `@returns`, and `@example`.
|
|
50
|
+
|
|
51
|
+
Running `luca introspect` captures JSDoc blocks and Zod schemas and includes them in the description whenever somebody calls `container.features.describe('{{camelName}}')` or `luca describe {{camelName}}`.
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
/**
|
|
55
|
+
* {{description}}
|
|
56
|
+
* ```typescript
|
|
57
|
+
* const {{camelName}} = container.feature('{{camelName}}')
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* @extends Feature
|
|
61
|
+
*/
|
|
62
|
+
export class {{PascalName}} extends Feature<{{PascalName}}State, {{PascalName}}Options> {
|
|
63
|
+
static override shortcut = 'features.{{camelName}}' as const
|
|
64
|
+
static override stateSchema = {{PascalName}}StateSchema
|
|
65
|
+
static override optionsSchema = {{PascalName}}OptionsSchema
|
|
66
|
+
static override eventsSchema = {{PascalName}}EventsSchema
|
|
67
|
+
|
|
68
|
+
static { Feature.register(this, '{{camelName}}') }
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Called after the feature is initialized. Use this for any setup logic
|
|
72
|
+
* instead of overriding the constructor.
|
|
73
|
+
*/
|
|
74
|
+
async afterInitialize() {
|
|
75
|
+
// Set up initial state, start background tasks, etc.
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Important**: You almost never need to override the constructor. Use `afterInitialize()` for any setup logic — it runs after the feature is fully wired into the container and has access to `this.container`, `this.options`, `this.state`, etc.
|
|
81
|
+
|
|
82
|
+
## Module Augmentation
|
|
83
|
+
|
|
84
|
+
This is what gives `container.feature('yourName')` TypeScript autocomplete. Without it, the feature works but TypeScript won't know about it.
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
declare module '@soederpop/luca' {
|
|
88
|
+
interface AvailableFeatures {
|
|
89
|
+
{{camelName}}: typeof {{PascalName}}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Registration
|
|
95
|
+
|
|
96
|
+
Registration happens inside the class body using a static block. The default export is just the class itself.
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
// Inside the class:
|
|
100
|
+
static { Feature.register(this, '{{camelName}}') }
|
|
101
|
+
|
|
102
|
+
// At module level:
|
|
103
|
+
export default {{PascalName}}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Complete Example
|
|
107
|
+
|
|
108
|
+
Here's a minimal but complete feature. This is what a real feature file looks like:
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
import { z } from 'zod'
|
|
112
|
+
import { FeatureStateSchema, FeatureOptionsSchema } from '@soederpop/luca'
|
|
113
|
+
import { Feature } from '@soederpop/luca'
|
|
114
|
+
|
|
115
|
+
declare module '@soederpop/luca' {
|
|
116
|
+
interface AvailableFeatures {
|
|
117
|
+
{{camelName}}: typeof {{PascalName}}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export const {{PascalName}}StateSchema = FeatureStateSchema.extend({})
|
|
122
|
+
export type {{PascalName}}State = z.infer<typeof {{PascalName}}StateSchema>
|
|
123
|
+
|
|
124
|
+
export const {{PascalName}}OptionsSchema = FeatureOptionsSchema.extend({})
|
|
125
|
+
export type {{PascalName}}Options = z.infer<typeof {{PascalName}}OptionsSchema>
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* {{description}}
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```typescript
|
|
132
|
+
* const {{camelName}} = container.feature('{{camelName}}')
|
|
133
|
+
* ```
|
|
134
|
+
*
|
|
135
|
+
* @extends Feature
|
|
136
|
+
*/
|
|
137
|
+
export class {{PascalName}} extends Feature<{{PascalName}}State, {{PascalName}}Options> {
|
|
138
|
+
static override shortcut = 'features.{{camelName}}' as const
|
|
139
|
+
static override stateSchema = {{PascalName}}StateSchema
|
|
140
|
+
static override optionsSchema = {{PascalName}}OptionsSchema
|
|
141
|
+
static { Feature.register(this, '{{camelName}}') }
|
|
142
|
+
|
|
143
|
+
async afterInitialize() {
|
|
144
|
+
// Setup logic goes here — not in the constructor
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export default {{PascalName}}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Conventions
|
|
152
|
+
|
|
153
|
+
- **Naming**: PascalCase for class, camelCase for registration ID. The file name should be kebab-case (e.g. `disk-cache.ts`).
|
|
154
|
+
- **JSDoc**: Every public method, getter, and the class itself needs a JSDoc block. Include `@example` with working code.
|
|
155
|
+
- **Describe everything**: Every Zod field needs `.describe()`. Every event tuple argument needs `.describe()`. This IS the documentation.
|
|
156
|
+
- **No Node builtins in consumer code**: If your feature wraps `fs` or `crypto`, that's fine inside the feature. But code that USES your feature should never import those directly.
|
|
157
|
+
- **State is observable**: Use `this.state.set()` and `this.state.get()`. Don't use plain instance properties for data that should be reactive.
|
|
158
|
+
- **Events for lifecycle**: Emit events for significant state changes so consumers can react.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Building a Selector
|
|
2
|
+
|
|
3
|
+
A selector returns data. Where commands perform actions, selectors query and return structured results with built-in caching. Selectors live in a project's `selectors/` folder and are automatically discovered.
|
|
4
|
+
|
|
5
|
+
When to build a selector:
|
|
6
|
+
- You need to query project data (package info, file listings, config values)
|
|
7
|
+
- The result benefits from caching (keyed by git SHA or custom key)
|
|
8
|
+
- You want the data available via `container.select('name')` or `luca select name`
|
|
9
|
+
|
|
10
|
+
## Imports
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import { z } from 'zod'
|
|
14
|
+
import type { ContainerContext } from '@soederpop/luca'
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Args Schema
|
|
18
|
+
|
|
19
|
+
Define the selector's input arguments with Zod.
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
export const argsSchema = z.object({
|
|
23
|
+
// Add your input arguments here.
|
|
24
|
+
// Example: field: z.string().optional().describe('Specific field to return'),
|
|
25
|
+
})
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Description
|
|
29
|
+
|
|
30
|
+
Export a description string for discoverability:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
export const description = '{{description}}'
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Caching
|
|
37
|
+
|
|
38
|
+
Selectors cache by default. The default cache key is `hashObject({ selectorName, args, gitSha })` — same args + same commit = cache hit.
|
|
39
|
+
|
|
40
|
+
To customize the cache key:
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
export function cacheKey(args: z.infer<typeof argsSchema>, context: ContainerContext) {
|
|
44
|
+
return context.container.git.currentCommitSha
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
To disable caching:
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
export const cacheable = false
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Handler
|
|
55
|
+
|
|
56
|
+
Export a `run` function that returns data. It receives parsed args and the container context.
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
export async function run(args: z.infer<typeof argsSchema>, context: ContainerContext) {
|
|
60
|
+
const { container } = context
|
|
61
|
+
// Query and return your data
|
|
62
|
+
return { /* your data */ }
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Complete Example
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
import { z } from 'zod'
|
|
70
|
+
import type { ContainerContext } from '@soederpop/luca'
|
|
71
|
+
|
|
72
|
+
export const description = '{{description}}'
|
|
73
|
+
|
|
74
|
+
export const argsSchema = z.object({})
|
|
75
|
+
|
|
76
|
+
export async function run(args: z.infer<typeof argsSchema>, context: ContainerContext) {
|
|
77
|
+
const { container } = context
|
|
78
|
+
|
|
79
|
+
// Return your data here
|
|
80
|
+
return {}
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Conventions
|
|
85
|
+
|
|
86
|
+
- **File location**: `selectors/{{kebabName}}.ts` in the project root. Discovered automatically.
|
|
87
|
+
- **Naming**: kebab-case for filename. `luca select {{kebabName}}` maps to `selectors/{{kebabName}}.ts`.
|
|
88
|
+
- **Use the container**: Never import `fs`, `path` directly. Use `container.feature('fs')`, `container.paths`.
|
|
89
|
+
- **Return data**: The `run` function must return the data. It gets wrapped in `{ data, cached, cacheKey }` by the framework.
|
|
90
|
+
- **Caching**: On by default. Override `cacheKey()` for custom invalidation, or set `cacheable = false` to skip.
|
|
91
|
+
- **CLI**: `luca select {{kebabName}}` runs the selector and prints JSON. Use `--json` for data only, `--no-cache` to force fresh.
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# Building a Server
|
|
2
|
+
|
|
3
|
+
A server is a container-managed listener — something that accepts connections and handles requests. Servers manage their own lifecycle (configure, start, stop) and expose observable state.
|
|
4
|
+
|
|
5
|
+
When to build a server:
|
|
6
|
+
- You need to accept incoming connections (HTTP, WebSocket, custom protocol)
|
|
7
|
+
- You want lifecycle management, port handling, and observability for free
|
|
8
|
+
- You're wrapping a server library so the codebase uses `container.server('name')`
|
|
9
|
+
|
|
10
|
+
## Imports
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import { z } from 'zod'
|
|
14
|
+
import { Server } from '@soederpop/luca'
|
|
15
|
+
import { ServerStateSchema, ServerOptionsSchema, ServerEventsSchema } from '@soederpop/luca'
|
|
16
|
+
import type { NodeContainer } from '@soederpop/luca'
|
|
17
|
+
import type { ServersInterface } from '@soederpop/luca'
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Schemas
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
export const {{PascalName}}StateSchema = ServerStateSchema.extend({
|
|
24
|
+
// Add your state fields here.
|
|
25
|
+
// Example: connectionCount: z.number().default(0).describe('Active connections'),
|
|
26
|
+
})
|
|
27
|
+
export type {{PascalName}}State = z.infer<typeof {{PascalName}}StateSchema>
|
|
28
|
+
|
|
29
|
+
export const {{PascalName}}OptionsSchema = ServerOptionsSchema.extend({
|
|
30
|
+
// Add constructor options here. port and host come from ServerOptionsSchema.
|
|
31
|
+
// Example: cors: z.boolean().default(true).describe('Enable CORS'),
|
|
32
|
+
})
|
|
33
|
+
export type {{PascalName}}Options = z.infer<typeof {{PascalName}}OptionsSchema>
|
|
34
|
+
|
|
35
|
+
export const {{PascalName}}EventsSchema = ServerEventsSchema.extend({
|
|
36
|
+
// Add your events here.
|
|
37
|
+
// Example: connection: z.tuple([z.string().describe('Client ID')]).describe('New client connected'),
|
|
38
|
+
})
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Class
|
|
42
|
+
|
|
43
|
+
Running `luca introspect` captures JSDoc blocks and Zod schemas and includes them in the description whenever somebody calls `container.servers.describe('{{camelName}}')` or `luca describe {{camelName}}`.
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
/**
|
|
47
|
+
* {{description}}
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```typescript
|
|
51
|
+
* const {{camelName}} = container.server('{{camelName}}', { port: 3000 })
|
|
52
|
+
* await {{camelName}}.start()
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* @extends Server
|
|
56
|
+
*/
|
|
57
|
+
export class {{PascalName}} extends Server<{{PascalName}}State, {{PascalName}}Options> {
|
|
58
|
+
static override shortcut = 'servers.{{camelName}}' as const
|
|
59
|
+
static override stateSchema = {{PascalName}}StateSchema
|
|
60
|
+
static override optionsSchema = {{PascalName}}OptionsSchema
|
|
61
|
+
static override eventsSchema = {{PascalName}}EventsSchema
|
|
62
|
+
static { Server.register(this, '{{camelName}}') }
|
|
63
|
+
|
|
64
|
+
static override attach(container: NodeContainer & ServersInterface) {
|
|
65
|
+
return container
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
override async configure() {
|
|
69
|
+
if (this.isConfigured) return this
|
|
70
|
+
// Set up the underlying server here
|
|
71
|
+
this.state.set('configured', true)
|
|
72
|
+
return this
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
override async start(options?: { port?: number }) {
|
|
76
|
+
if (this.isListening) return this
|
|
77
|
+
if (!this.isConfigured) await this.configure()
|
|
78
|
+
|
|
79
|
+
const port = options?.port || this.options.port || 3000
|
|
80
|
+
// Start listening here
|
|
81
|
+
this.state.set('port', port)
|
|
82
|
+
this.state.set('listening', true)
|
|
83
|
+
return this
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
override async stop() {
|
|
87
|
+
if (this.isStopped) return this
|
|
88
|
+
// Clean up connections here
|
|
89
|
+
this.state.set('listening', false)
|
|
90
|
+
this.state.set('stopped', true)
|
|
91
|
+
return this
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Module Augmentation
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
declare module '@soederpop/luca' {
|
|
100
|
+
interface AvailableServers {
|
|
101
|
+
{{camelName}}: typeof {{PascalName}}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Registration
|
|
107
|
+
|
|
108
|
+
Registration happens inside the class body using a static block. The default export is just the class itself.
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
// Inside the class:
|
|
112
|
+
static { Server.register(this, '{{camelName}}') }
|
|
113
|
+
|
|
114
|
+
// At module level:
|
|
115
|
+
export default {{PascalName}}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Complete Example
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
import { z } from 'zod'
|
|
122
|
+
import { Server } from '@soederpop/luca'
|
|
123
|
+
import { ServerStateSchema, ServerOptionsSchema, ServerEventsSchema } from '@soederpop/luca'
|
|
124
|
+
import type { NodeContainer } from '@soederpop/luca'
|
|
125
|
+
import type { ServersInterface } from '@soederpop/luca'
|
|
126
|
+
|
|
127
|
+
declare module '@soederpop/luca' {
|
|
128
|
+
interface AvailableServers {
|
|
129
|
+
{{camelName}}: typeof {{PascalName}}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export const {{PascalName}}StateSchema = ServerStateSchema.extend({})
|
|
134
|
+
export type {{PascalName}}State = z.infer<typeof {{PascalName}}StateSchema>
|
|
135
|
+
|
|
136
|
+
export const {{PascalName}}OptionsSchema = ServerOptionsSchema.extend({})
|
|
137
|
+
export type {{PascalName}}Options = z.infer<typeof {{PascalName}}OptionsSchema>
|
|
138
|
+
|
|
139
|
+
export const {{PascalName}}EventsSchema = ServerEventsSchema.extend({})
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* {{description}}
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* ```typescript
|
|
146
|
+
* const {{camelName}} = container.server('{{camelName}}', { port: 3000 })
|
|
147
|
+
* await {{camelName}}.start()
|
|
148
|
+
* ```
|
|
149
|
+
*
|
|
150
|
+
* @extends Server
|
|
151
|
+
*/
|
|
152
|
+
export class {{PascalName}} extends Server<{{PascalName}}State, {{PascalName}}Options> {
|
|
153
|
+
static override shortcut = 'servers.{{camelName}}' as const
|
|
154
|
+
static override stateSchema = {{PascalName}}StateSchema
|
|
155
|
+
static override optionsSchema = {{PascalName}}OptionsSchema
|
|
156
|
+
static override eventsSchema = {{PascalName}}EventsSchema
|
|
157
|
+
static { Server.register(this, '{{camelName}}') }
|
|
158
|
+
|
|
159
|
+
static override attach(container: NodeContainer & ServersInterface) {
|
|
160
|
+
return container
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
override async configure() {
|
|
164
|
+
if (this.isConfigured) return this
|
|
165
|
+
this.state.set('configured', true)
|
|
166
|
+
return this
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
override async start(options?: { port?: number }) {
|
|
170
|
+
if (this.isListening) return this
|
|
171
|
+
if (!this.isConfigured) await this.configure()
|
|
172
|
+
const port = options?.port || this.options.port || 3000
|
|
173
|
+
this.state.set('port', port)
|
|
174
|
+
this.state.set('listening', true)
|
|
175
|
+
return this
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
override async stop() {
|
|
179
|
+
if (this.isStopped) return this
|
|
180
|
+
this.state.set('listening', false)
|
|
181
|
+
this.state.set('stopped', true)
|
|
182
|
+
return this
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export default {{PascalName}}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Conventions
|
|
190
|
+
|
|
191
|
+
- **Lifecycle**: Implement `configure()`, `start()`, and `stop()`. Check guards (`isConfigured`, `isListening`, `isStopped`) at the top of each.
|
|
192
|
+
- **Use `afterInitialize()`**: For any setup logic instead of overriding the constructor. Lifecycle methods (`configure`, `start`, `stop`) handle the server's runtime phases.
|
|
193
|
+
- **State tracking**: Set `configured`, `listening`, `stopped`, and `port` on the state. This powers the introspection system.
|
|
194
|
+
- **attach() is static**: It runs when the container first loads the server class. Use it for container-level setup if needed.
|
|
195
|
+
- **Port from options**: Accept port via options schema and respect it in `start()`. Allow override via start options.
|
|
196
|
+
- **JSDoc everything**: Every public method needs `@param`, `@returns`, `@example`. Run `luca introspect` after changes to update generated docs.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Selector System
|
|
2
|
+
|
|
3
|
+
## Vision
|
|
4
|
+
|
|
5
|
+
Commands perform actions. Selectors return data. Together they form a complete agent tool interface — pick which commands and selectors you need and you get free assistant tools. Agents only need to know the external APIs of features, servers, and clients already in the container (which can be learned from `luca describe`).
|
|
6
|
+
|
|
7
|
+
## What Is a Selector?
|
|
8
|
+
|
|
9
|
+
A Selector is a new helper type (like Feature, Client, Server, Command) that:
|
|
10
|
+
|
|
11
|
+
- Extends `Helper` with a `select(options)` method that **returns data**
|
|
12
|
+
- Lives in a `SelectorsRegistry`, queryable via `container.selectors`
|
|
13
|
+
- Is instantiated via `container.selector('name', options)` factory
|
|
14
|
+
- Supports **caching** via `diskCache` — many selector values don't change if git SHAs don't change, so SHA makes a great cache key
|
|
15
|
+
- Is discoverable from a `selectors/` folder in projects, just like `commands/`
|
|
16
|
+
- Supports both **class-based** and **module-based** (export a `select` function) patterns
|
|
17
|
+
|
|
18
|
+
## Architecture — How It Maps to Existing Patterns
|
|
19
|
+
|
|
20
|
+
The implementation follows the exact same pattern as `Command`:
|
|
21
|
+
|
|
22
|
+
### Files to Create/Modify
|
|
23
|
+
|
|
24
|
+
1. **`src/schemas/base.ts`** — Add `SelectorStateSchema`, `SelectorOptionsSchema`, `SelectorEventsSchema`
|
|
25
|
+
2. **`src/selector.ts`** — New file mirroring `src/command.ts`:
|
|
26
|
+
- `Selector` class extending `Helper` with `select()` method
|
|
27
|
+
- `SelectorsRegistry` extending `Registry` with `discover()` support
|
|
28
|
+
- `selectors` singleton, `helperCache`, `Selector.register()`, `Selector.attach()`
|
|
29
|
+
- `AvailableSelectors` interface, `SelectorsInterface`, `SelectorFactory` type
|
|
30
|
+
- Module-based pattern: `SimpleSelector` type for graft compatibility
|
|
31
|
+
3. **`src/node/container.ts`** — Import `Selector` + `SelectorsInterface`, add to `ClientsAndServersInterface`, wire `this.use(Selector)`
|
|
32
|
+
4. **`src/node/features/helpers.ts`** — Add `selectors` to `registryMap` and `RegistryType`, add to `discoverAll()` iteration
|
|
33
|
+
|
|
34
|
+
### Selector Base Class Shape
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
class Selector<T, K> extends Helper<T, K> {
|
|
38
|
+
static shortcut = 'selectors.base'
|
|
39
|
+
static argsSchema: z.ZodType // schema for select() input
|
|
40
|
+
static cacheable: boolean = true // opt-out of caching
|
|
41
|
+
|
|
42
|
+
// The core method — override in subclass or graft from module export
|
|
43
|
+
async select(args, context): Promise<any> {}
|
|
44
|
+
|
|
45
|
+
// Dispatch normalizer (like Command.execute)
|
|
46
|
+
async resolve(args?, source?): Promise<SelectorResult> {}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Module-Based Pattern (selectors/ folder)
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
// selectors/package-info.ts
|
|
54
|
+
export const description = 'Returns parsed package.json data'
|
|
55
|
+
export const argsSchema = z.object({ field: z.string().optional() })
|
|
56
|
+
export const cacheable = true
|
|
57
|
+
|
|
58
|
+
export function cacheKey(args, context) {
|
|
59
|
+
// return a string key — if unchanged, cached value is returned
|
|
60
|
+
return context.container.git.sha
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export async function select(args, context) {
|
|
64
|
+
const manifest = context.container.manifest
|
|
65
|
+
return args.field ? manifest[args.field] : manifest
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Caching Strategy
|
|
70
|
+
|
|
71
|
+
- Built into the `Selector` base class, powered by `diskCache` feature
|
|
72
|
+
- Subclasses/modules can export a `cacheKey(args, context)` function
|
|
73
|
+
- Default cache key strategy: `hashObject({ selectorName, args, gitSha })`
|
|
74
|
+
- `cacheable: false` opts out entirely
|
|
75
|
+
- Cache is key-invalidated (key changes = miss), no TTL by default
|
|
76
|
+
- The `resolve()` method checks cache before calling `select()`
|
|
77
|
+
|
|
78
|
+
## Open Questions (Needs Decision)
|
|
79
|
+
|
|
80
|
+
### 1. Return Shape
|
|
81
|
+
Should `select()` return data directly, or a wrapped result like `{ data, metadata, cached }`?
|
|
82
|
+
|
|
83
|
+
**Leaning toward:** data directly from `select()`, but `resolve()` (the dispatch method) returns `{ data, cached, cacheKey }` so callers know if it was a cache hit.
|
|
84
|
+
|
|
85
|
+
### 2. CLI Integration
|
|
86
|
+
Should there be a `luca select <name>` CLI command? Would make selectors usable from the terminal, printing JSON output.
|
|
87
|
+
|
|
88
|
+
### 3. Cache TTL
|
|
89
|
+
Is pure key-invalidation enough, or do some selectors need time-based expiry?
|
|
90
|
+
|
|
91
|
+
### 4. Scope of First Delivery
|
|
92
|
+
|
|
93
|
+
Proposed skateboard:
|
|
94
|
+
- `Selector` base class with `select()` and `resolve()` (cached dispatch)
|
|
95
|
+
- `SelectorsRegistry` with `discover()`
|
|
96
|
+
- Container wiring (`container.selectors`, `container.selector()`)
|
|
97
|
+
- Schemas in `schemas/base.ts`
|
|
98
|
+
- `selectors/` folder discovery via `Helpers` feature
|
|
99
|
+
- Caching integration with `diskCache`
|
|
100
|
+
- Module-based pattern support (export `select` + optional `cacheKey`)
|
|
101
|
+
- `Selector` + `selectors` exported from `@soederpop/luca` barrel + seeded in VM virtual modules
|
|
102
|
+
|
|
103
|
+
## Codebase Exploration Notes
|
|
104
|
+
|
|
105
|
+
These are the key files that were studied to inform this design:
|
|
106
|
+
|
|
107
|
+
- `src/command.ts` — The primary pattern to mirror. `Command` extends `Helper`, has `CommandsRegistry`, `commands` singleton, `Command.register()`, `Command.attach()`, `execute()`/`run()` split, headless capture, `graftModule` support.
|
|
108
|
+
- `src/helper.ts` — Base class providing state, events, options (Zod-validated), introspection, `afterInitialize()` hook.
|
|
109
|
+
- `src/registry.ts` — Abstract `Registry<T>` with `register()`, `lookup()`, `has()`, `available`, `describe()`, `describeAll()`, event bus.
|
|
110
|
+
- `src/graft.ts` — `graftModule()` synthesizes a class from plain module exports. `RESERVED_EXPORTS` list determines what becomes static vs prototype methods.
|
|
111
|
+
- `src/schemas/base.ts` — All Zod schemas. Each helper type has State/Options/Events schemas.
|
|
112
|
+
- `src/node/container.ts` — `NodeContainer` wires everything: side-effect imports, `NodeFeatures` interface, `ClientsAndServersInterface`, `this.use(Command)` pattern.
|
|
113
|
+
- `src/node/features/helpers.ts` — `Helpers` feature: `registryMap`, `RegistryType`, `discoverAll()`, class-based vs config-based discovery, VM module seeding.
|
|
114
|
+
- `src/node/features/disk-cache.ts` — `DiskCache` feature: `get/set/has/rm`, `cacache`-backed, per-project cache dir, `container.utils.hashObject()` for keys.
|
|
115
|
+
- `src/container.ts` — Base `Container`: `createHelperInstance()` with `helperCache` Map, `use()` plugin system, `registerHelperType()`.
|