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,289 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
import { Database } from 'bun:sqlite'
|
|
3
|
+
import { Feature } from '../feature.js'
|
|
4
|
+
import { FeatureStateSchema, FeatureOptionsSchema, FeatureEventsSchema } from '../../schemas/base.js'
|
|
5
|
+
import type { ContainerContext } from '../../container.js'
|
|
6
|
+
|
|
7
|
+
type SqlValue = string | number | boolean | bigint | Uint8Array | Buffer | null
|
|
8
|
+
|
|
9
|
+
export const SqliteStateSchema = FeatureStateSchema.extend({
|
|
10
|
+
connected: z.boolean().default(false).describe('Whether the sqlite database is currently open'),
|
|
11
|
+
path: z.string().default(':memory:').describe('Path to the sqlite database file'),
|
|
12
|
+
lastQuery: z.string().optional().describe('Most recent SQL query string that was executed'),
|
|
13
|
+
lastChanges: z.number().optional().describe('Number of rows changed by the most recent execute call'),
|
|
14
|
+
lastInsertRowid: z.union([z.number(), z.bigint()]).optional().describe('Last inserted row id from the most recent execute call'),
|
|
15
|
+
lastError: z.string().optional().describe('Most recent sqlite error message, if any'),
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
export const SqliteOptionsSchema = FeatureOptionsSchema.extend({
|
|
19
|
+
path: z.string().optional().describe('Path to sqlite file. Use :memory: for in-memory database'),
|
|
20
|
+
readonly: z.boolean().optional().describe('Open sqlite database in readonly mode'),
|
|
21
|
+
readwrite: z.boolean().optional().describe('Open sqlite database in readwrite mode (defaults to true when readonly is false)'),
|
|
22
|
+
create: z.boolean().optional().describe('Create the sqlite database file if it does not exist'),
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
export type SqliteState = z.infer<typeof SqliteStateSchema>
|
|
26
|
+
export type SqliteOptions = z.infer<typeof SqliteOptionsSchema>
|
|
27
|
+
|
|
28
|
+
export const SqliteEventsSchema = FeatureEventsSchema.extend({
|
|
29
|
+
query: z.tuple([
|
|
30
|
+
z.string().describe('The SQL query text that was executed'),
|
|
31
|
+
z.array(z.any()).describe('Bound parameter values'),
|
|
32
|
+
z.number().describe('Number of rows returned'),
|
|
33
|
+
]).describe('Emitted after a SELECT-like query completes successfully'),
|
|
34
|
+
execute: z.tuple([
|
|
35
|
+
z.string().describe('The SQL statement text that was executed'),
|
|
36
|
+
z.array(z.any()).describe('Bound parameter values'),
|
|
37
|
+
z.number().describe('Number of rows changed'),
|
|
38
|
+
]).describe('Emitted after a write/update/delete statement completes successfully'),
|
|
39
|
+
error: z.tuple([
|
|
40
|
+
z.any().describe('The error that occurred'),
|
|
41
|
+
]).describe('Emitted when a SQL operation fails'),
|
|
42
|
+
closed: z.tuple([]).describe('Emitted when the database connection is closed'),
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* SQLite feature for safe SQL execution through Bun's native sqlite binding.
|
|
47
|
+
*
|
|
48
|
+
* Supports:
|
|
49
|
+
* - parameterized query execution (`query` / `execute`)
|
|
50
|
+
* - tagged-template query execution (`sql`) to avoid manual placeholder wiring
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* const sqlite = container.feature('sqlite', { path: 'data/app.db' })
|
|
55
|
+
*
|
|
56
|
+
* await sqlite.execute(
|
|
57
|
+
* 'create table if not exists users (id integer primary key, email text not null unique)'
|
|
58
|
+
* )
|
|
59
|
+
*
|
|
60
|
+
* await sqlite.execute('insert into users (email) values (?)', ['hello@example.com'])
|
|
61
|
+
*
|
|
62
|
+
* const users = await sqlite.sql<{ id: number; email: string }>`
|
|
63
|
+
* select id, email from users where email = ${'hello@example.com'}
|
|
64
|
+
* `
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export class Sqlite extends Feature<SqliteState, SqliteOptions> {
|
|
68
|
+
static override shortcut = 'features.sqlite' as const
|
|
69
|
+
static override stateSchema = SqliteStateSchema
|
|
70
|
+
static override optionsSchema = SqliteOptionsSchema
|
|
71
|
+
static override eventsSchema = SqliteEventsSchema
|
|
72
|
+
static { Feature.register(this, 'sqlite') }
|
|
73
|
+
|
|
74
|
+
private _db: Database
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Default state for the SQLite feature before a database is opened.
|
|
78
|
+
* @returns The initial SqliteState with `connected: false` and in-memory path
|
|
79
|
+
*/
|
|
80
|
+
override get initialState(): SqliteState {
|
|
81
|
+
return {
|
|
82
|
+
enabled: false,
|
|
83
|
+
connected: false,
|
|
84
|
+
path: ':memory:',
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
constructor(options: SqliteOptions, context: ContainerContext) {
|
|
89
|
+
super(options, context)
|
|
90
|
+
|
|
91
|
+
const path = options.path || ':memory:'
|
|
92
|
+
const openOptions = options.readonly
|
|
93
|
+
? { readonly: true }
|
|
94
|
+
: { readwrite: options.readwrite ?? true, create: options.create ?? true }
|
|
95
|
+
|
|
96
|
+
this._db = new Database(path, openOptions)
|
|
97
|
+
|
|
98
|
+
this.hide('_db')
|
|
99
|
+
this.setState({
|
|
100
|
+
connected: true,
|
|
101
|
+
path,
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Returns the underlying Bun sqlite database instance. */
|
|
106
|
+
get db() {
|
|
107
|
+
return this._db
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Executes a SELECT-like query and returns result rows.
|
|
112
|
+
*
|
|
113
|
+
* Use sqlite placeholders (`?`) for `params`.
|
|
114
|
+
*
|
|
115
|
+
* @param queryText - The SQL query string with optional `?` placeholders
|
|
116
|
+
* @param params - Ordered array of values to bind to the placeholders
|
|
117
|
+
* @returns Promise resolving to an array of typed result rows
|
|
118
|
+
* @throws {Error} When query text is empty or params contain `undefined`
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```typescript
|
|
122
|
+
* const db = container.feature('sqlite', { path: 'app.db' })
|
|
123
|
+
* const users = await db.query<{ id: number; email: string }>(
|
|
124
|
+
* 'SELECT id, email FROM users WHERE active = ?',
|
|
125
|
+
* [1]
|
|
126
|
+
* )
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
129
|
+
async query<T extends object = Record<string, unknown>>(queryText: string, params: SqlValue[] = []): Promise<T[]> {
|
|
130
|
+
assertQueryText(queryText)
|
|
131
|
+
assertParams(params)
|
|
132
|
+
|
|
133
|
+
try {
|
|
134
|
+
const statement = this.db.query(queryText)
|
|
135
|
+
const rows = statement.all(...params) as T[]
|
|
136
|
+
|
|
137
|
+
this.setState({
|
|
138
|
+
lastQuery: queryText,
|
|
139
|
+
lastError: undefined,
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
this.emit('query', queryText, params, rows.length)
|
|
143
|
+
return rows
|
|
144
|
+
} catch (error: any) {
|
|
145
|
+
this.setState({
|
|
146
|
+
lastQuery: queryText,
|
|
147
|
+
lastError: error?.message || String(error),
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
this.emit('error', error)
|
|
151
|
+
throw error
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Executes a write/update/delete statement and returns metadata.
|
|
157
|
+
*
|
|
158
|
+
* Use sqlite placeholders (`?`) for `params`.
|
|
159
|
+
*
|
|
160
|
+
* @param queryText - The SQL statement string with optional `?` placeholders
|
|
161
|
+
* @param params - Ordered array of values to bind to the placeholders
|
|
162
|
+
* @returns Promise resolving to `{ changes, lastInsertRowid }` metadata
|
|
163
|
+
* @throws {Error} When query text is empty or params contain `undefined`
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* ```typescript
|
|
167
|
+
* const db = container.feature('sqlite', { path: 'app.db' })
|
|
168
|
+
* const { changes, lastInsertRowid } = await db.execute(
|
|
169
|
+
* 'INSERT INTO users (email) VALUES (?)',
|
|
170
|
+
* ['hello@example.com']
|
|
171
|
+
* )
|
|
172
|
+
* console.log(`Inserted row ${lastInsertRowid}, ${changes} change(s)`)
|
|
173
|
+
* ```
|
|
174
|
+
*/
|
|
175
|
+
async execute(queryText: string, params: SqlValue[] = []): Promise<{ changes: number; lastInsertRowid: number | bigint | null }> {
|
|
176
|
+
assertQueryText(queryText)
|
|
177
|
+
assertParams(params)
|
|
178
|
+
|
|
179
|
+
try {
|
|
180
|
+
const statement = this.db.query(queryText)
|
|
181
|
+
const result = statement.run(...params) as { changes: number; lastInsertRowid: number | bigint }
|
|
182
|
+
|
|
183
|
+
this.setState({
|
|
184
|
+
lastQuery: queryText,
|
|
185
|
+
lastChanges: result.changes,
|
|
186
|
+
lastInsertRowid: result.lastInsertRowid,
|
|
187
|
+
lastError: undefined,
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
this.emit('execute', queryText, params, result.changes)
|
|
191
|
+
return {
|
|
192
|
+
changes: result.changes,
|
|
193
|
+
lastInsertRowid: result.lastInsertRowid ?? null,
|
|
194
|
+
}
|
|
195
|
+
} catch (error: any) {
|
|
196
|
+
this.setState({
|
|
197
|
+
lastQuery: queryText,
|
|
198
|
+
lastError: error?.message || String(error),
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
this.emit('error', error)
|
|
202
|
+
throw error
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Safe tagged-template SQL helper.
|
|
208
|
+
*
|
|
209
|
+
* Values become bound parameters automatically, preventing SQL injection.
|
|
210
|
+
*
|
|
211
|
+
* @param strings - Template literal string segments
|
|
212
|
+
* @param values - Interpolated values that become bound `?` parameters
|
|
213
|
+
* @returns Promise resolving to an array of typed result rows
|
|
214
|
+
*
|
|
215
|
+
* @example
|
|
216
|
+
* ```typescript
|
|
217
|
+
* const db = container.feature('sqlite', { path: 'app.db' })
|
|
218
|
+
* const email = 'hello@example.com'
|
|
219
|
+
* const rows = await db.sql<{ id: number }>`
|
|
220
|
+
* SELECT id FROM users WHERE email = ${email}
|
|
221
|
+
* `
|
|
222
|
+
* ```
|
|
223
|
+
*/
|
|
224
|
+
async sql<T extends object = Record<string, unknown>>(strings: TemplateStringsArray, ...values: SqlValue[]): Promise<T[]> {
|
|
225
|
+
const built = buildQuestionQuery(strings, values)
|
|
226
|
+
return this.query<T>(built.text, built.params)
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Closes the sqlite database and updates feature state.
|
|
231
|
+
*
|
|
232
|
+
* Emits `closed` after the database handle is released.
|
|
233
|
+
*
|
|
234
|
+
* @returns This Sqlite feature instance for method chaining
|
|
235
|
+
*
|
|
236
|
+
* @example
|
|
237
|
+
* ```typescript
|
|
238
|
+
* const db = container.feature('sqlite', { path: 'app.db' })
|
|
239
|
+
* // ... run queries ...
|
|
240
|
+
* db.close()
|
|
241
|
+
* ```
|
|
242
|
+
*/
|
|
243
|
+
close() {
|
|
244
|
+
this.db.close()
|
|
245
|
+
this.setState({ connected: false })
|
|
246
|
+
this.emit('closed')
|
|
247
|
+
return this
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export default Sqlite
|
|
252
|
+
declare module '../../feature.js' {
|
|
253
|
+
interface AvailableFeatures {
|
|
254
|
+
sqlite: typeof Sqlite
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function assertQueryText(queryText: string) {
|
|
259
|
+
if (typeof queryText !== 'string' || queryText.trim().length === 0) {
|
|
260
|
+
throw new Error('SQL query text must be a non-empty string')
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function assertParams(params: SqlValue[]) {
|
|
265
|
+
if (!Array.isArray(params)) {
|
|
266
|
+
throw new Error('SQL params must be an array')
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if (params.some((param) => param === undefined)) {
|
|
270
|
+
throw new Error('SQL params cannot contain undefined values. Use null instead.')
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function buildQuestionQuery(strings: TemplateStringsArray, values: SqlValue[]) {
|
|
275
|
+
if (strings.length !== values.length + 1) {
|
|
276
|
+
throw new Error('Invalid SQL template literal input')
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
const chunks: string[] = []
|
|
280
|
+
|
|
281
|
+
for (let i = 0; i < strings.length; i++) {
|
|
282
|
+
chunks.push(strings[i]!)
|
|
283
|
+
if (i < values.length) {
|
|
284
|
+
chunks.push('?')
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
return { text: chunks.join(''), params: values }
|
|
289
|
+
}
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
import { FeatureStateSchema, FeatureOptionsSchema, FeatureEventsSchema } from '../../schemas/base.js'
|
|
3
|
+
import { Feature } from '../feature.js'
|
|
4
|
+
import { Bot, webhookCallback, type Context, type Middleware } from 'grammy'
|
|
5
|
+
|
|
6
|
+
type UserFromGetMe = Awaited<ReturnType<Bot['api']['getMe']>>
|
|
7
|
+
|
|
8
|
+
export const TelegramBotInfoSchema = z.object({
|
|
9
|
+
id: z.number().describe('Bot user ID'),
|
|
10
|
+
firstName: z.string().describe('Bot first name'),
|
|
11
|
+
username: z.string().optional().describe('Bot username'),
|
|
12
|
+
canJoinGroups: z.boolean().optional().describe('Whether the bot can be added to groups'),
|
|
13
|
+
canReadAllGroupMessages: z.boolean().optional().describe('Whether the bot can read all group messages'),
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
export const TelegramStateSchema = FeatureStateSchema.extend({
|
|
17
|
+
mode: z.enum(['polling', 'webhook', 'idle']).default('idle')
|
|
18
|
+
.describe('Current operation mode'),
|
|
19
|
+
isRunning: z.boolean().default(false)
|
|
20
|
+
.describe('Whether the bot is currently receiving updates'),
|
|
21
|
+
webhookUrl: z.string().optional()
|
|
22
|
+
.describe('Active webhook URL if in webhook mode'),
|
|
23
|
+
commandsRegistered: z.array(z.string()).default([])
|
|
24
|
+
.describe('List of registered command names'),
|
|
25
|
+
lastError: z.string().optional()
|
|
26
|
+
.describe('Last error message'),
|
|
27
|
+
botInfo: TelegramBotInfoSchema.optional()
|
|
28
|
+
.describe('Bot user information from Telegram API'),
|
|
29
|
+
})
|
|
30
|
+
export type TelegramState = z.infer<typeof TelegramStateSchema>
|
|
31
|
+
|
|
32
|
+
export const TelegramOptionsSchema = FeatureOptionsSchema.extend({
|
|
33
|
+
token: z.string().optional()
|
|
34
|
+
.describe('Bot token from @BotFather (falls back to TELEGRAM_BOT_TOKEN env var)'),
|
|
35
|
+
mode: z.enum(['polling', 'webhook']).default('polling')
|
|
36
|
+
.describe('Update mode: polling for long-polling, webhook for HTTP callbacks'),
|
|
37
|
+
webhookUrl: z.string().optional()
|
|
38
|
+
.describe('Public HTTPS URL for webhook mode'),
|
|
39
|
+
webhookPath: z.string().default('/telegram/webhook')
|
|
40
|
+
.describe('HTTP path for the webhook endpoint'),
|
|
41
|
+
webhookPort: z.number().optional()
|
|
42
|
+
.describe('Port for webhook Express server'),
|
|
43
|
+
autoStart: z.boolean().optional()
|
|
44
|
+
.describe('Automatically start the bot when enabled'),
|
|
45
|
+
dropPendingUpdates: z.boolean().optional()
|
|
46
|
+
.describe('Drop pending updates on start (polling mode)'),
|
|
47
|
+
pollingTimeout: z.number().min(0).default(1)
|
|
48
|
+
.describe('Long-polling timeout in seconds. Lower = faster response. 0 = short polling (fastest, testing only). Default 1s.'),
|
|
49
|
+
pollingLimit: z.number().min(1).max(100).optional()
|
|
50
|
+
.describe('Max updates per polling request (1-100, default 100)'),
|
|
51
|
+
allowedUpdates: z.array(z.string()).optional()
|
|
52
|
+
.describe('Update types to receive (e.g. ["message", "callback_query"])'),
|
|
53
|
+
})
|
|
54
|
+
export type TelegramOptions = z.infer<typeof TelegramOptionsSchema>
|
|
55
|
+
|
|
56
|
+
export const TelegramEventsSchema = FeatureEventsSchema.extend({
|
|
57
|
+
started: z.tuple([z.object({ mode: z.string() })]).describe('Bot started receiving updates'),
|
|
58
|
+
stopped: z.tuple([]).describe('Bot stopped'),
|
|
59
|
+
error: z.tuple([z.any()]).describe('Error occurred'),
|
|
60
|
+
command: z.tuple([z.string(), z.any()]).describe('Command triggered: [name, Context]'),
|
|
61
|
+
webhook_ready: z.tuple([z.string()]).describe('Webhook registered and ready'),
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Telegram bot feature powered by grammY.
|
|
66
|
+
*
|
|
67
|
+
* Supports both long-polling and webhook modes. Exposes the grammY Bot instance
|
|
68
|
+
* directly for full API access while bridging events to Luca's event bus.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```typescript
|
|
72
|
+
* const tg = container.feature('telegram', { autoStart: true })
|
|
73
|
+
* tg.command('start', (ctx) => ctx.reply('Hello!'))
|
|
74
|
+
* tg.handle('message:text', (ctx) => ctx.reply(`Echo: ${ctx.message.text}`))
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
export class Telegram extends Feature<TelegramState, TelegramOptions> {
|
|
78
|
+
static override shortcut = 'features.telegram' as const
|
|
79
|
+
static override envVars = ['TELEGRAM_BOT_TOKEN']
|
|
80
|
+
static override stateSchema = TelegramStateSchema
|
|
81
|
+
static override optionsSchema = TelegramOptionsSchema
|
|
82
|
+
static override eventsSchema = TelegramEventsSchema
|
|
83
|
+
static { Feature.register(this, 'telegram') }
|
|
84
|
+
|
|
85
|
+
private _bot?: Bot
|
|
86
|
+
|
|
87
|
+
override get initialState(): TelegramState {
|
|
88
|
+
return {
|
|
89
|
+
...super.initialState,
|
|
90
|
+
mode: 'idle',
|
|
91
|
+
isRunning: false,
|
|
92
|
+
commandsRegistered: [],
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Bot token from options or TELEGRAM_BOT_TOKEN env var. */
|
|
97
|
+
get token(): string {
|
|
98
|
+
const token = this.options.token || process.env.TELEGRAM_BOT_TOKEN
|
|
99
|
+
if (!token) {
|
|
100
|
+
throw new Error('Telegram bot token required. Set options.token or TELEGRAM_BOT_TOKEN env var.')
|
|
101
|
+
}
|
|
102
|
+
return token
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** The grammY Bot instance. Created lazily on first access. */
|
|
106
|
+
get bot(): Bot {
|
|
107
|
+
if (!this._bot) {
|
|
108
|
+
this._bot = new Bot(this.token)
|
|
109
|
+
this._setupErrorHandling()
|
|
110
|
+
}
|
|
111
|
+
return this._bot
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** Whether the bot is currently receiving updates. */
|
|
115
|
+
get isRunning(): boolean {
|
|
116
|
+
return this.state.get('isRunning') || false
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** Current operation mode: 'polling', 'webhook', or 'idle'. */
|
|
120
|
+
get mode(): 'polling' | 'webhook' | 'idle' {
|
|
121
|
+
return this.state.get('mode') || 'idle'
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** Access chalk colors via the container's UI feature. */
|
|
125
|
+
private get c() {
|
|
126
|
+
return this.container.feature('ui').colors
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
override async enable(options: any = {}): Promise<this> {
|
|
130
|
+
await super.enable(options)
|
|
131
|
+
|
|
132
|
+
const c = this.c
|
|
133
|
+
console.log(c.cyan.bold('\n🤖 Telegram Bot'))
|
|
134
|
+
console.log(c.dim('─'.repeat(40)))
|
|
135
|
+
|
|
136
|
+
try {
|
|
137
|
+
const me = await this.bot.api.getMe()
|
|
138
|
+
this.setState({
|
|
139
|
+
botInfo: {
|
|
140
|
+
id: me.id,
|
|
141
|
+
firstName: me.first_name,
|
|
142
|
+
username: me.username,
|
|
143
|
+
canJoinGroups: me.can_join_groups,
|
|
144
|
+
canReadAllGroupMessages: me.can_read_all_group_messages,
|
|
145
|
+
}
|
|
146
|
+
})
|
|
147
|
+
console.log(`${c.green('✓')} Authenticated as ${c.bold(`@${me.username}`)} ${c.dim(`(id: ${me.id})`)}`)
|
|
148
|
+
} catch (err: any) {
|
|
149
|
+
this.setState({ lastError: err.message })
|
|
150
|
+
console.log(`${c.red('✗')} Auth failed: ${c.red(err.message)}`)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
console.log(`${c.dim(' mode:')} ${this.options.mode || 'polling'}`)
|
|
154
|
+
|
|
155
|
+
if (this.options.autoStart) {
|
|
156
|
+
await this.start()
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return this
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** Start the bot in the configured mode (polling or webhook). */
|
|
163
|
+
async start(): Promise<this> {
|
|
164
|
+
if (this.isRunning) return this
|
|
165
|
+
|
|
166
|
+
if (this.options.mode === 'webhook') {
|
|
167
|
+
await this.setupWebhook()
|
|
168
|
+
} else {
|
|
169
|
+
await this.startPolling()
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return this
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/** Stop the bot gracefully. */
|
|
176
|
+
async stop(): Promise<this> {
|
|
177
|
+
if (!this.isRunning) return this
|
|
178
|
+
|
|
179
|
+
const c = this.c
|
|
180
|
+
if (this.mode === 'polling') {
|
|
181
|
+
await this.bot.stop()
|
|
182
|
+
} else if (this.mode === 'webhook') {
|
|
183
|
+
await this.deleteWebhook()
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
this.setState({ isRunning: false, mode: 'idle' })
|
|
187
|
+
this.emit('stopped')
|
|
188
|
+
console.log(`${c.yellow('⏹')} Bot stopped`)
|
|
189
|
+
return this
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/** Register a command handler. Also emits 'command' on the Luca event bus. */
|
|
193
|
+
command(name: string, handler: (ctx: Context) => any): this {
|
|
194
|
+
this.bot.command(name, async (ctx) => {
|
|
195
|
+
this.emit('command', name, ctx)
|
|
196
|
+
await handler(ctx)
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
const registered = this.state.get('commandsRegistered') || []
|
|
200
|
+
if (!registered.includes(name)) {
|
|
201
|
+
this.setState({ commandsRegistered: [...registered, name] })
|
|
202
|
+
}
|
|
203
|
+
return this
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Register a grammY update handler (filter query).
|
|
208
|
+
* Named 'handle' to avoid collision with the inherited on() event bus method.
|
|
209
|
+
*
|
|
210
|
+
* @example
|
|
211
|
+
* ```typescript
|
|
212
|
+
* tg.handle('message:text', (ctx) => ctx.reply('Got text'))
|
|
213
|
+
* tg.handle('callback_query:data', (ctx) => ctx.answerCallbackQuery('Clicked'))
|
|
214
|
+
* ```
|
|
215
|
+
*/
|
|
216
|
+
handle(filter: Parameters<Bot['on']>[0], handler: (ctx: any) => any): this {
|
|
217
|
+
this.bot.on(filter, handler)
|
|
218
|
+
return this
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/** Add grammY middleware. */
|
|
222
|
+
use(...middleware: Middleware[]): this {
|
|
223
|
+
for (const mw of middleware) {
|
|
224
|
+
this.bot.use(mw)
|
|
225
|
+
}
|
|
226
|
+
return this
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/** Start long-polling mode. */
|
|
230
|
+
async startPolling(dropPendingUpdates?: boolean): Promise<this> {
|
|
231
|
+
const drop = dropPendingUpdates ?? this.options.dropPendingUpdates ?? false
|
|
232
|
+
const c = this.c
|
|
233
|
+
|
|
234
|
+
const timeout = this.options.pollingTimeout ?? 1
|
|
235
|
+
const limit = this.options.pollingLimit
|
|
236
|
+
|
|
237
|
+
// bot.start() is non-blocking internally (starts polling loop)
|
|
238
|
+
this.bot.start({
|
|
239
|
+
drop_pending_updates: drop,
|
|
240
|
+
allowed_updates: this.options.allowedUpdates as any,
|
|
241
|
+
timeout,
|
|
242
|
+
...(limit ? { limit } : {}),
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
this.setState({ isRunning: true, mode: 'polling' })
|
|
246
|
+
this.emit('started', { mode: 'polling' })
|
|
247
|
+
|
|
248
|
+
const cmds = this.state.get('commandsRegistered') || []
|
|
249
|
+
console.log(`${c.green('▶')} Polling for updates ${c.dim(`(timeout: ${timeout}s)`)}${drop ? c.dim(' (dropped pending)') : ''}`)
|
|
250
|
+
if (cmds.length) {
|
|
251
|
+
console.log(`${c.dim(' commands:')} ${cmds.map(cmd => c.cyan(`/${cmd}`)).join(', ')}`)
|
|
252
|
+
}
|
|
253
|
+
console.log(c.dim('─'.repeat(40)))
|
|
254
|
+
return this
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/** Set up webhook mode with an Express server. */
|
|
258
|
+
async setupWebhook(url?: string, path?: string): Promise<this> {
|
|
259
|
+
const webhookUrl = url || this.options.webhookUrl
|
|
260
|
+
const webhookPath = path || this.options.webhookPath || '/telegram/webhook'
|
|
261
|
+
|
|
262
|
+
if (!webhookUrl) {
|
|
263
|
+
throw new Error('webhookUrl required for webhook mode. Set options.webhookUrl or pass it to setupWebhook().')
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
const server = this.container.server('express', {
|
|
267
|
+
port: this.options.webhookPort,
|
|
268
|
+
}) as any
|
|
269
|
+
|
|
270
|
+
server.app.use(webhookPath, webhookCallback(this.bot, 'express'))
|
|
271
|
+
|
|
272
|
+
if (!server.isListening) {
|
|
273
|
+
const port = this.options.webhookPort || await this.container.networking.findOpenPort(3000)
|
|
274
|
+
await server.start({ port })
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const fullUrl = `${webhookUrl.replace(/\/$/, '')}${webhookPath}`
|
|
278
|
+
await this.bot.api.setWebhook(fullUrl, {
|
|
279
|
+
allowed_updates: this.options.allowedUpdates as any,
|
|
280
|
+
})
|
|
281
|
+
|
|
282
|
+
this.setState({ isRunning: true, mode: 'webhook', webhookUrl: fullUrl })
|
|
283
|
+
this.emit('webhook_ready', fullUrl)
|
|
284
|
+
this.emit('started', { mode: 'webhook' })
|
|
285
|
+
|
|
286
|
+
const c = this.c
|
|
287
|
+
const cmds = this.state.get('commandsRegistered') || []
|
|
288
|
+
console.log(`${c.green('▶')} Webhook active at ${c.underline(fullUrl)}`)
|
|
289
|
+
if (cmds.length) {
|
|
290
|
+
console.log(`${c.dim(' commands:')} ${cmds.map(cmd => c.cyan(`/${cmd}`)).join(', ')}`)
|
|
291
|
+
}
|
|
292
|
+
console.log(c.dim('─'.repeat(40)))
|
|
293
|
+
return this
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/** Remove the webhook from Telegram. */
|
|
297
|
+
async deleteWebhook(): Promise<this> {
|
|
298
|
+
await this.bot.api.deleteWebhook()
|
|
299
|
+
this.setState({ webhookUrl: undefined })
|
|
300
|
+
return this
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/** Get bot info from Telegram API. */
|
|
304
|
+
async getMe(): Promise<UserFromGetMe> {
|
|
305
|
+
return await this.bot.api.getMe()
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/** Print a diagnostic summary of the bot's current state. */
|
|
309
|
+
diagnostics(): this {
|
|
310
|
+
const c = this.c
|
|
311
|
+
const info = this.state.get('botInfo')
|
|
312
|
+
const cmds = this.state.get('commandsRegistered') || []
|
|
313
|
+
const err = this.state.get('lastError')
|
|
314
|
+
|
|
315
|
+
console.log(c.cyan.bold('\n🤖 Telegram Bot Diagnostics'))
|
|
316
|
+
console.log(c.dim('─'.repeat(40)))
|
|
317
|
+
console.log(` ${c.dim('bot:')} ${info ? `@${info.username} ${c.dim(`(${info.id})`)}` : c.yellow('not authenticated')}`)
|
|
318
|
+
console.log(` ${c.dim('status:')} ${this.isRunning ? c.green('running') : c.yellow('stopped')}`)
|
|
319
|
+
console.log(` ${c.dim('mode:')} ${this.mode}`)
|
|
320
|
+
if (this.mode === 'webhook') {
|
|
321
|
+
console.log(` ${c.dim('webhook:')} ${this.state.get('webhookUrl') || 'n/a'}`)
|
|
322
|
+
}
|
|
323
|
+
console.log(` ${c.dim('commands:')} ${cmds.length ? cmds.map(cmd => c.cyan(`/${cmd}`)).join(', ') : c.dim('none')}`)
|
|
324
|
+
if (info?.canJoinGroups) {
|
|
325
|
+
console.log(` ${c.dim('groups:')} ${c.green('can join')}`)
|
|
326
|
+
}
|
|
327
|
+
if (err) {
|
|
328
|
+
console.log(` ${c.dim('error:')} ${c.red(err)}`)
|
|
329
|
+
}
|
|
330
|
+
console.log(c.dim('─'.repeat(40)))
|
|
331
|
+
return this
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
private _setupErrorHandling(): void {
|
|
335
|
+
this.bot.catch((err) => {
|
|
336
|
+
this.setState({ lastError: err.message })
|
|
337
|
+
this.emit('error', err)
|
|
338
|
+
})
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
export default Telegram
|