nikcli 0.0.6
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/.turbo/turbo-typecheck.log +1 -0
- package/AGENTS.md +27 -0
- package/Dockerfile +18 -0
- package/README.md +15 -0
- package/bin/nikcli +84 -0
- package/config.json +13 -0
- package/docs/tailscale-mobile/01-tailscale-setup.md +94 -0
- package/docs/tailscale-mobile/02-host-setup.md +115 -0
- package/docs/tailscale-mobile/03-phone-and-serve.md +134 -0
- package/docs/tailscale-mobile/README.md +59 -0
- package/examples/README.md +54 -0
- package/package.json +147 -0
- package/parsers-config.ts +253 -0
- package/script/build.ts +179 -0
- package/script/postinstall.mjs +125 -0
- package/script/publish-registries.ts +187 -0
- package/script/publish.ts +100 -0
- package/script/schema.ts +47 -0
- package/script/seed-e2e.ts +50 -0
- package/sequential-prancing-forest.md +373 -0
- package/src/acp/README.md +164 -0
- package/src/acp/agent.ts +1303 -0
- package/src/acp/session.ts +105 -0
- package/src/acp/types.ts +22 -0
- package/src/agent/agent.ts +528 -0
- package/src/agent/generate.txt +32 -0
- package/src/agent/prompt/compaction.txt +14 -0
- package/src/agent/prompt/explore.txt +18 -0
- package/src/agent/prompt/summary.txt +11 -0
- package/src/agent/prompt/title.txt +44 -0
- package/src/auth/index.ts +73 -0
- package/src/bun/index.ts +119 -0
- package/src/bun/registry.ts +54 -0
- package/src/bus/bus-event.ts +43 -0
- package/src/bus/global.ts +10 -0
- package/src/bus/index.ts +105 -0
- package/src/chatbot/handlers.ts +150 -0
- package/src/chatbot/index.ts +132 -0
- package/src/cli/bootstrap.ts +17 -0
- package/src/cli/cmd/acp.ts +69 -0
- package/src/cli/cmd/ads.ts +377 -0
- package/src/cli/cmd/agent.ts +259 -0
- package/src/cli/cmd/auth.ts +400 -0
- package/src/cli/cmd/chatbot.ts +420 -0
- package/src/cli/cmd/cmd.ts +7 -0
- package/src/cli/cmd/companion.ts +81 -0
- package/src/cli/cmd/connectors.ts +593 -0
- package/src/cli/cmd/debug/agent.ts +166 -0
- package/src/cli/cmd/debug/config.ts +16 -0
- package/src/cli/cmd/debug/file.ts +97 -0
- package/src/cli/cmd/debug/index.ts +48 -0
- package/src/cli/cmd/debug/lsp.ts +52 -0
- package/src/cli/cmd/debug/ripgrep.ts +87 -0
- package/src/cli/cmd/debug/scrap.ts +16 -0
- package/src/cli/cmd/debug/skill.ts +16 -0
- package/src/cli/cmd/debug/snapshot.ts +52 -0
- package/src/cli/cmd/export.ts +88 -0
- package/src/cli/cmd/generate.ts +38 -0
- package/src/cli/cmd/github.ts +412 -0
- package/src/cli/cmd/image-model.ts +128 -0
- package/src/cli/cmd/import.ts +201 -0
- package/src/cli/cmd/lovable.ts +128 -0
- package/src/cli/cmd/mcp.ts +738 -0
- package/src/cli/cmd/mobile.ts +223 -0
- package/src/cli/cmd/models.ts +77 -0
- package/src/cli/cmd/plug.ts +231 -0
- package/src/cli/cmd/pr.ts +104 -0
- package/src/cli/cmd/rag-model.ts +167 -0
- package/src/cli/cmd/remote.ts +416 -0
- package/src/cli/cmd/run.ts +589 -0
- package/src/cli/cmd/serve.ts +51 -0
- package/src/cli/cmd/session.ts +133 -0
- package/src/cli/cmd/speak-model.ts +204 -0
- package/src/cli/cmd/stats.ts +402 -0
- package/src/cli/cmd/tui/app.tsx +841 -0
- package/src/cli/cmd/tui/attach.ts +31 -0
- package/src/cli/cmd/tui/component/border.tsx +75 -0
- package/src/cli/cmd/tui/component/dialog-agent.tsx +31 -0
- package/src/cli/cmd/tui/component/dialog-command.tsx +172 -0
- package/src/cli/cmd/tui/component/dialog-config.tsx +291 -0
- package/src/cli/cmd/tui/component/dialog-connectors.tsx +440 -0
- package/src/cli/cmd/tui/component/dialog-image-model.tsx +97 -0
- package/src/cli/cmd/tui/component/dialog-mcp.tsx +86 -0
- package/src/cli/cmd/tui/component/dialog-model.tsx +234 -0
- package/src/cli/cmd/tui/component/dialog-provider.tsx +260 -0
- package/src/cli/cmd/tui/component/dialog-rag-model.tsx +217 -0
- package/src/cli/cmd/tui/component/dialog-remote.tsx +489 -0
- package/src/cli/cmd/tui/component/dialog-session-list.tsx +170 -0
- package/src/cli/cmd/tui/component/dialog-session-rename.tsx +31 -0
- package/src/cli/cmd/tui/component/dialog-settings/index.tsx +59 -0
- package/src/cli/cmd/tui/component/dialog-settings/prompt.tsx +40 -0
- package/src/cli/cmd/tui/component/dialog-settings/sidebar.tsx +39 -0
- package/src/cli/cmd/tui/component/dialog-settings/spinner.tsx +62 -0
- package/src/cli/cmd/tui/component/dialog-settings/ui.tsx +58 -0
- package/src/cli/cmd/tui/component/dialog-skills.tsx +117 -0
- package/src/cli/cmd/tui/component/dialog-speak-model.tsx +304 -0
- package/src/cli/cmd/tui/component/dialog-stash.tsx +87 -0
- package/src/cli/cmd/tui/component/dialog-status.tsx +165 -0
- package/src/cli/cmd/tui/component/dialog-tag.tsx +44 -0
- package/src/cli/cmd/tui/component/dialog-theme-create.tsx +717 -0
- package/src/cli/cmd/tui/component/dialog-theme-list.tsx +52 -0
- package/src/cli/cmd/tui/component/dialog-workspace-list.tsx +350 -0
- package/src/cli/cmd/tui/component/error-component.tsx +91 -0
- package/src/cli/cmd/tui/component/logo.tsx +103 -0
- package/src/cli/cmd/tui/component/plugin-route-missing.tsx +14 -0
- package/src/cli/cmd/tui/component/prompt/autocomplete.tsx +669 -0
- package/src/cli/cmd/tui/component/prompt/frecency.tsx +89 -0
- package/src/cli/cmd/tui/component/prompt/history.tsx +108 -0
- package/src/cli/cmd/tui/component/prompt/index.tsx +2165 -0
- package/src/cli/cmd/tui/component/prompt/stash.tsx +63 -0
- package/src/cli/cmd/tui/component/spinner.tsx +24 -0
- package/src/cli/cmd/tui/component/startup-loading.tsx +63 -0
- package/src/cli/cmd/tui/component/table/markdown-table.tsx +267 -0
- package/src/cli/cmd/tui/component/table-db/db/connections.ts +75 -0
- package/src/cli/cmd/tui/component/table-db/db/db-connection.ts +223 -0
- package/src/cli/cmd/tui/component/table-db/db/db-preview.ts +202 -0
- package/src/cli/cmd/tui/component/table-db/db/factory.ts +77 -0
- package/src/cli/cmd/tui/component/table-db/db/index.ts +9 -0
- package/src/cli/cmd/tui/component/table-db/db/mysql-connection.ts +330 -0
- package/src/cli/cmd/tui/component/table-db/db/postgres-connection.ts +338 -0
- package/src/cli/cmd/tui/component/table-db/db/sqlite-connection.ts +302 -0
- package/src/cli/cmd/tui/component/table-db/db/types.ts +108 -0
- package/src/cli/cmd/tui/component/table-db/table/dbedit-hooks.ts +74 -0
- package/src/cli/cmd/tui/component/table-db/table/index.ts +15 -0
- package/src/cli/cmd/tui/component/table-db/table/table-events.ts +54 -0
- package/src/cli/cmd/tui/component/table-db/table/table-formatters.ts +191 -0
- package/src/cli/cmd/tui/component/table-db/table/table-hooks.ts +105 -0
- package/src/cli/cmd/tui/component/table-db/table/table-keyboard-handler.ts +255 -0
- package/src/cli/cmd/tui/component/table-db/table/table-layout-engine.ts +208 -0
- package/src/cli/cmd/tui/component/table-db/table/table-renderable.ts +486 -0
- package/src/cli/cmd/tui/component/table-db/table/table-selection-manager.ts +136 -0
- package/src/cli/cmd/tui/component/table-db/table/table-state.ts +198 -0
- package/src/cli/cmd/tui/component/table-db/table/types.ts +69 -0
- package/src/cli/cmd/tui/component/table-db/ui/db-visualizer.tsx +71 -0
- package/src/cli/cmd/tui/component/table-db/ui/index.ts +2 -0
- package/src/cli/cmd/tui/component/table-db/ui/table-renderer.ts +607 -0
- package/src/cli/cmd/tui/component/textarea-keybindings.ts +73 -0
- package/src/cli/cmd/tui/component/tips.tsx +195 -0
- package/src/cli/cmd/tui/component/todo-item.tsx +32 -0
- package/src/cli/cmd/tui/context/args.tsx +14 -0
- package/src/cli/cmd/tui/context/directory.ts +13 -0
- package/src/cli/cmd/tui/context/exit.tsx +24 -0
- package/src/cli/cmd/tui/context/helper.tsx +25 -0
- package/src/cli/cmd/tui/context/keybind.tsx +102 -0
- package/src/cli/cmd/tui/context/kv.tsx +52 -0
- package/src/cli/cmd/tui/context/local.tsx +458 -0
- package/src/cli/cmd/tui/context/plugin-keybinds.ts +41 -0
- package/src/cli/cmd/tui/context/prompt.tsx +18 -0
- package/src/cli/cmd/tui/context/route.tsx +54 -0
- package/src/cli/cmd/tui/context/sdk.tsx +128 -0
- package/src/cli/cmd/tui/context/server.tsx +8 -0
- package/src/cli/cmd/tui/context/sync.tsx +510 -0
- package/src/cli/cmd/tui/context/theme/abyss.json +233 -0
- package/src/cli/cmd/tui/context/theme/apple.json +235 -0
- package/src/cli/cmd/tui/context/theme/arctic.json +232 -0
- package/src/cli/cmd/tui/context/theme/aura.json +69 -0
- package/src/cli/cmd/tui/context/theme/ayu.json +80 -0
- package/src/cli/cmd/tui/context/theme/ayuai.json +229 -0
- package/src/cli/cmd/tui/context/theme/blood.json +229 -0
- package/src/cli/cmd/tui/context/theme/carbonfox.json +248 -0
- package/src/cli/cmd/tui/context/theme/catmoe.json +235 -0
- package/src/cli/cmd/tui/context/theme/catppuccin-frappe.json +233 -0
- package/src/cli/cmd/tui/context/theme/catppuccin-latte.json +233 -0
- package/src/cli/cmd/tui/context/theme/catppuccin-macchiato.json +233 -0
- package/src/cli/cmd/tui/context/theme/catppuccin.json +259 -0
- package/src/cli/cmd/tui/context/theme/charcoal.json +230 -0
- package/src/cli/cmd/tui/context/theme/chromatic.json +235 -0
- package/src/cli/cmd/tui/context/theme/cobalt2.json +228 -0
- package/src/cli/cmd/tui/context/theme/cosmic.json +234 -0
- package/src/cli/cmd/tui/context/theme/cursor.json +249 -0
- package/src/cli/cmd/tui/context/theme/cyber.json +235 -0
- package/src/cli/cmd/tui/context/theme/dawnfox.json +229 -0
- package/src/cli/cmd/tui/context/theme/dimension.json +235 -0
- package/src/cli/cmd/tui/context/theme/dracula-official.json +222 -0
- package/src/cli/cmd/tui/context/theme/dracula.json +219 -0
- package/src/cli/cmd/tui/context/theme/dream.json +235 -0
- package/src/cli/cmd/tui/context/theme/duo.json +235 -0
- package/src/cli/cmd/tui/context/theme/dusk.json +235 -0
- package/src/cli/cmd/tui/context/theme/ebony.json +232 -0
- package/src/cli/cmd/tui/context/theme/equilibrium.json +232 -0
- package/src/cli/cmd/tui/context/theme/ethereal.json +235 -0
- package/src/cli/cmd/tui/context/theme/everforest.json +241 -0
- package/src/cli/cmd/tui/context/theme/flexoki.json +237 -0
- package/src/cli/cmd/tui/context/theme/fusion.json +235 -0
- package/src/cli/cmd/tui/context/theme/ghost.json +235 -0
- package/src/cli/cmd/tui/context/theme/github-dark.json +229 -0
- package/src/cli/cmd/tui/context/theme/github-dimmed.json +231 -0
- package/src/cli/cmd/tui/context/theme/github-light.json +229 -0
- package/src/cli/cmd/tui/context/theme/github.json +233 -0
- package/src/cli/cmd/tui/context/theme/glass.json +235 -0
- package/src/cli/cmd/tui/context/theme/gold.json +235 -0
- package/src/cli/cmd/tui/context/theme/gone.json +234 -0
- package/src/cli/cmd/tui/context/theme/greyscale.json +229 -0
- package/src/cli/cmd/tui/context/theme/gruvbox.json +242 -0
- package/src/cli/cmd/tui/context/theme/hacker.json +229 -0
- package/src/cli/cmd/tui/context/theme/holo.json +235 -0
- package/src/cli/cmd/tui/context/theme/ink.json +235 -0
- package/src/cli/cmd/tui/context/theme/jet.json +233 -0
- package/src/cli/cmd/tui/context/theme/kanagawa.json +227 -0
- package/src/cli/cmd/tui/context/theme/lavender.json +236 -0
- package/src/cli/cmd/tui/context/theme/lightph.json +235 -0
- package/src/cli/cmd/tui/context/theme/lucent-orng.json +237 -0
- package/src/cli/cmd/tui/context/theme/material-ocean.json +230 -0
- package/src/cli/cmd/tui/context/theme/material.json +235 -0
- package/src/cli/cmd/tui/context/theme/matrix.json +227 -0
- package/src/cli/cmd/tui/context/theme/mercury.json +245 -0
- package/src/cli/cmd/tui/context/theme/midnight.json +235 -0
- package/src/cli/cmd/tui/context/theme/modern.json +235 -0
- package/src/cli/cmd/tui/context/theme/monokai.json +221 -0
- package/src/cli/cmd/tui/context/theme/muted.json +229 -0
- package/src/cli/cmd/tui/context/theme/neon.json +229 -0
- package/src/cli/cmd/tui/context/theme/neonfusion.json +235 -0
- package/src/cli/cmd/tui/context/theme/neutral.json +235 -0
- package/src/cli/cmd/tui/context/theme/nightowl.json +221 -0
- package/src/cli/cmd/tui/context/theme/nikcli.json +245 -0
- package/src/cli/cmd/tui/context/theme/nord.json +223 -0
- package/src/cli/cmd/tui/context/theme/nordic.json +235 -0
- package/src/cli/cmd/tui/context/theme/nova.json +235 -0
- package/src/cli/cmd/tui/context/theme/obsidian.json +234 -0
- package/src/cli/cmd/tui/context/theme/one-dark.json +231 -0
- package/src/cli/cmd/tui/context/theme/one-pro.json +229 -0
- package/src/cli/cmd/tui/context/theme/onyx.json +233 -0
- package/src/cli/cmd/tui/context/theme/orng.json +249 -0
- package/src/cli/cmd/tui/context/theme/osaka-jade.json +240 -0
- package/src/cli/cmd/tui/context/theme/oxocarbon.json +229 -0
- package/src/cli/cmd/tui/context/theme/palenight.json +222 -0
- package/src/cli/cmd/tui/context/theme/poimandres.json +230 -0
- package/src/cli/cmd/tui/context/theme/prism.json +235 -0
- package/src/cli/cmd/tui/context/theme/radiant.json +235 -0
- package/src/cli/cmd/tui/context/theme/rosepine.json +234 -0
- package/src/cli/cmd/tui/context/theme/shadow.json +235 -0
- package/src/cli/cmd/tui/context/theme/silicon.json +235 -0
- package/src/cli/cmd/tui/context/theme/slate.json +233 -0
- package/src/cli/cmd/tui/context/theme/soft.json +235 -0
- package/src/cli/cmd/tui/context/theme/solarized.json +223 -0
- package/src/cli/cmd/tui/context/theme/spectrum.json +235 -0
- package/src/cli/cmd/tui/context/theme/starlight.json +233 -0
- package/src/cli/cmd/tui/context/theme/sunrise.json +235 -0
- package/src/cli/cmd/tui/context/theme/synthwave84.json +226 -0
- package/src/cli/cmd/tui/context/theme/tech.json +235 -0
- package/src/cli/cmd/tui/context/theme/tokyonight-storm.json +245 -0
- package/src/cli/cmd/tui/context/theme/tokyonight.json +243 -0
- package/src/cli/cmd/tui/context/theme/vapor.json +235 -0
- package/src/cli/cmd/tui/context/theme/vercel.json +245 -0
- package/src/cli/cmd/tui/context/theme/vesper.json +218 -0
- package/src/cli/cmd/tui/context/theme/vivid.json +232 -0
- package/src/cli/cmd/tui/context/theme/void.json +235 -0
- package/src/cli/cmd/tui/context/theme/vscode.json +235 -0
- package/src/cli/cmd/tui/context/theme/zenburn.json +223 -0
- package/src/cli/cmd/tui/context/theme/zinc.json +236 -0
- package/src/cli/cmd/tui/context/theme.tsx +1303 -0
- package/src/cli/cmd/tui/event.ts +48 -0
- package/src/cli/cmd/tui/feature-plugins/home/tips-view.tsx +152 -0
- package/src/cli/cmd/tui/feature-plugins/home/tips.tsx +50 -0
- package/src/cli/cmd/tui/feature-plugins/sidebar/context.tsx +63 -0
- package/src/cli/cmd/tui/feature-plugins/sidebar/files.tsx +62 -0
- package/src/cli/cmd/tui/feature-plugins/sidebar/footer.tsx +93 -0
- package/src/cli/cmd/tui/feature-plugins/sidebar/lsp.tsx +66 -0
- package/src/cli/cmd/tui/feature-plugins/sidebar/mcp.tsx +96 -0
- package/src/cli/cmd/tui/feature-plugins/sidebar/todo.tsx +48 -0
- package/src/cli/cmd/tui/feature-plugins/system/plugins.tsx +288 -0
- package/src/cli/cmd/tui/plugin/api.tsx +407 -0
- package/src/cli/cmd/tui/plugin/index.ts +3 -0
- package/src/cli/cmd/tui/plugin/internal.ts +25 -0
- package/src/cli/cmd/tui/plugin/runtime.ts +1048 -0
- package/src/cli/cmd/tui/plugin/slots.tsx +61 -0
- package/src/cli/cmd/tui/routes/home.tsx +153 -0
- package/src/cli/cmd/tui/routes/session/dbedit.tsx +474 -0
- package/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx +65 -0
- package/src/cli/cmd/tui/routes/session/dialog-message.tsx +110 -0
- package/src/cli/cmd/tui/routes/session/dialog-subagent.tsx +105 -0
- package/src/cli/cmd/tui/routes/session/dialog-timeline.tsx +47 -0
- package/src/cli/cmd/tui/routes/session/footer.tsx +75 -0
- package/src/cli/cmd/tui/routes/session/header.tsx +177 -0
- package/src/cli/cmd/tui/routes/session/index.tsx +2280 -0
- package/src/cli/cmd/tui/routes/session/permission.tsx +540 -0
- package/src/cli/cmd/tui/routes/session/question.tsx +435 -0
- package/src/cli/cmd/tui/routes/session/sidebar.tsx +313 -0
- package/src/cli/cmd/tui/thread.ts +174 -0
- package/src/cli/cmd/tui/ui/dialog-alert.tsx +57 -0
- package/src/cli/cmd/tui/ui/dialog-confirm.tsx +83 -0
- package/src/cli/cmd/tui/ui/dialog-export-options.tsx +204 -0
- package/src/cli/cmd/tui/ui/dialog-help.tsx +38 -0
- package/src/cli/cmd/tui/ui/dialog-prompt.tsx +102 -0
- package/src/cli/cmd/tui/ui/dialog-select.tsx +389 -0
- package/src/cli/cmd/tui/ui/dialog.tsx +180 -0
- package/src/cli/cmd/tui/ui/link.tsx +34 -0
- package/src/cli/cmd/tui/ui/spinner.ts +368 -0
- package/src/cli/cmd/tui/ui/toast.tsx +138 -0
- package/src/cli/cmd/tui/util/clipboard.ts +154 -0
- package/src/cli/cmd/tui/util/editor.ts +32 -0
- package/src/cli/cmd/tui/util/signal.ts +7 -0
- package/src/cli/cmd/tui/util/terminal.ts +114 -0
- package/src/cli/cmd/tui/util/transcript.ts +98 -0
- package/src/cli/cmd/tui/win32.ts +110 -0
- package/src/cli/cmd/tui/worker.ts +156 -0
- package/src/cli/cmd/uninstall.ts +357 -0
- package/src/cli/cmd/upgrade.ts +72 -0
- package/src/cli/cmd/web.ts +87 -0
- package/src/cli/cmd/workspace-serve.ts +16 -0
- package/src/cli/error.ts +57 -0
- package/src/cli/network.ts +55 -0
- package/src/cli/remote/index.ts +36 -0
- package/src/cli/remote/notifications.ts +104 -0
- package/src/cli/remote/qr-renderer.ts +86 -0
- package/src/cli/remote/remote-service.ts +757 -0
- package/src/cli/remote/session-manager.ts +284 -0
- package/src/cli/remote/subagent-hooks.ts +151 -0
- package/src/cli/remote/types.ts +121 -0
- package/src/cli/ui.ts +96 -0
- package/src/cli/upgrade.ts +25 -0
- package/src/command/index.ts +174 -0
- package/src/command/template/initialize.txt +10 -0
- package/src/command/template/review.txt +99 -0
- package/src/config/config.ts +1760 -0
- package/src/config/markdown.ts +88 -0
- package/src/config/migrate-tui-config.ts +155 -0
- package/src/config/paths.ts +174 -0
- package/src/config/tui-schema.ts +36 -0
- package/src/config/tui.ts +209 -0
- package/src/connectors/api/base.ts +75 -0
- package/src/connectors/api/figma.ts +103 -0
- package/src/connectors/api/github.ts +247 -0
- package/src/connectors/api/lovable.ts +126 -0
- package/src/connectors/api/slack.ts +137 -0
- package/src/connectors/auth.ts +68 -0
- package/src/connectors/cache.ts +119 -0
- package/src/connectors/credentials.ts +81 -0
- package/src/connectors/index.ts +202 -0
- package/src/connectors/registry.ts +358 -0
- package/src/docs/context.ts +120 -0
- package/src/docs/library.ts +189 -0
- package/src/env/index.ts +26 -0
- package/src/file/ignore.ts +83 -0
- package/src/file/index.ts +411 -0
- package/src/file/ripgrep.ts +402 -0
- package/src/file/time.ts +65 -0
- package/src/file/watcher.ts +127 -0
- package/src/flag/flag.ts +128 -0
- package/src/format/formatter.ts +356 -0
- package/src/format/index.ts +137 -0
- package/src/global/index.ts +57 -0
- package/src/id/id.ts +83 -0
- package/src/ide/index.ts +76 -0
- package/src/index.ts +184 -0
- package/src/installation/index.ts +246 -0
- package/src/lsp/client.ts +250 -0
- package/src/lsp/index.ts +483 -0
- package/src/lsp/language.ts +119 -0
- package/src/lsp/server.ts +2046 -0
- package/src/mcp/auth.ts +121 -0
- package/src/mcp/index.ts +860 -0
- package/src/mcp/oauth-callback.ts +198 -0
- package/src/mcp/oauth-provider.ts +148 -0
- package/src/mobile/auth.ts +97 -0
- package/src/mobile/github-repo.ts +185 -0
- package/src/patch/index.ts +631 -0
- package/src/permission/arity.ts +150 -0
- package/src/permission/dbedit.ts +236 -0
- package/src/permission/index.ts +210 -0
- package/src/permission/next.ts +287 -0
- package/src/plugin/codex.ts +493 -0
- package/src/plugin/copilot.ts +261 -0
- package/src/plugin/index.ts +714 -0
- package/src/plugin/install.ts +379 -0
- package/src/plugin/meta.ts +165 -0
- package/src/plugin/shared.ts +188 -0
- package/src/project/bootstrap.ts +35 -0
- package/src/project/instance.ts +84 -0
- package/src/project/project.ts +373 -0
- package/src/project/state.ts +66 -0
- package/src/project/vcs.ts +76 -0
- package/src/prompt/stash-store.ts +93 -0
- package/src/provider/auth.ts +147 -0
- package/src/provider/models-macro.ts +22 -0
- package/src/provider/models.ts +216 -0
- package/src/provider/provider.ts +1483 -0
- package/src/provider/sdk/openai-compatible/src/README.md +5 -0
- package/src/provider/sdk/openai-compatible/src/index.ts +2 -0
- package/src/provider/sdk/openai-compatible/src/openai-compatible-provider.ts +100 -0
- package/src/provider/sdk/openai-compatible/src/responses/convert-to-openai-responses-input.ts +303 -0
- package/src/provider/sdk/openai-compatible/src/responses/map-openai-responses-finish-reason.ts +22 -0
- package/src/provider/sdk/openai-compatible/src/responses/openai-config.ts +18 -0
- package/src/provider/sdk/openai-compatible/src/responses/openai-error.ts +22 -0
- package/src/provider/sdk/openai-compatible/src/responses/openai-responses-api-types.ts +207 -0
- package/src/provider/sdk/openai-compatible/src/responses/openai-responses-language-model.ts +1732 -0
- package/src/provider/sdk/openai-compatible/src/responses/openai-responses-prepare-tools.ts +177 -0
- package/src/provider/sdk/openai-compatible/src/responses/openai-responses-settings.ts +1 -0
- package/src/provider/sdk/openai-compatible/src/responses/tool/code-interpreter.ts +88 -0
- package/src/provider/sdk/openai-compatible/src/responses/tool/file-search.ts +128 -0
- package/src/provider/sdk/openai-compatible/src/responses/tool/image-generation.ts +115 -0
- package/src/provider/sdk/openai-compatible/src/responses/tool/local-shell.ts +65 -0
- package/src/provider/sdk/openai-compatible/src/responses/tool/web-search-preview.ts +104 -0
- package/src/provider/sdk/openai-compatible/src/responses/tool/web-search.ts +103 -0
- package/src/provider/transform.ts +828 -0
- package/src/pty/index.ts +241 -0
- package/src/question/index.ts +171 -0
- package/src/rag/chunk.ts +43 -0
- package/src/rag/embed.ts +179 -0
- package/src/rag/index.ts +376 -0
- package/src/rag/storage.ts +76 -0
- package/src/scheduler/index.ts +61 -0
- package/src/server/error.ts +36 -0
- package/src/server/event.ts +7 -0
- package/src/server/mdns.ts +59 -0
- package/src/server/routes/chatbot.ts +205 -0
- package/src/server/routes/companion.ts +729 -0
- package/src/server/routes/config.ts +92 -0
- package/src/server/routes/connectors.ts +121 -0
- package/src/server/routes/dbedit.ts +76 -0
- package/src/server/routes/experimental.ts +210 -0
- package/src/server/routes/file.ts +197 -0
- package/src/server/routes/global.ts +135 -0
- package/src/server/routes/mcp.ts +225 -0
- package/src/server/routes/mobile.ts +2044 -0
- package/src/server/routes/permission.ts +68 -0
- package/src/server/routes/project.ts +82 -0
- package/src/server/routes/provider.ts +235 -0
- package/src/server/routes/pty.ts +169 -0
- package/src/server/routes/question.ts +98 -0
- package/src/server/routes/session.ts +968 -0
- package/src/server/routes/tui.ts +379 -0
- package/src/server/routes/workspace.ts +104 -0
- package/src/server/server.ts +761 -0
- package/src/server/ssh.ts +207 -0
- package/src/session/auth.ts +402 -0
- package/src/session/compaction.ts +253 -0
- package/src/session/generate.ts +38 -0
- package/src/session/index.ts +598 -0
- package/src/session/llm.ts +273 -0
- package/src/session/message-v2.ts +836 -0
- package/src/session/message.ts +189 -0
- package/src/session/processor.ts +408 -0
- package/src/session/prompt/anthropic-20250930.txt +165 -0
- package/src/session/prompt/anthropic.txt +105 -0
- package/src/session/prompt/anthropic_spoof.txt +1 -0
- package/src/session/prompt/beast.txt +147 -0
- package/src/session/prompt/build-switch.txt +5 -0
- package/src/session/prompt/codex_header.txt +79 -0
- package/src/session/prompt/copilot-gpt-5.txt +143 -0
- package/src/session/prompt/gemini.txt +155 -0
- package/src/session/prompt/max-steps.txt +16 -0
- package/src/session/prompt/plan-reminder-anthropic.txt +67 -0
- package/src/session/prompt/plan.txt +25 -0
- package/src/session/prompt/qwen.txt +108 -0
- package/src/session/prompt.ts +1942 -0
- package/src/session/retry.ts +90 -0
- package/src/session/revert.ts +120 -0
- package/src/session/stats.ts +404 -0
- package/src/session/status.ts +84 -0
- package/src/session/summary.ts +184 -0
- package/src/session/system.ts +195 -0
- package/src/session/toast.tsx +105 -0
- package/src/session/todo.ts +258 -0
- package/src/session/uninstall.ts +357 -0
- package/src/share/share-next.ts +421 -0
- package/src/share/share.ts +92 -0
- package/src/shell/shell.ts +65 -0
- package/src/skill/index.ts +1 -0
- package/src/skill/skill.ts +232 -0
- package/src/snapshot/index.ts +297 -0
- package/src/storage/storage.ts +227 -0
- package/src/tool/apply_patch.ts +288 -0
- package/src/tool/apply_patch.txt +33 -0
- package/src/tool/bash.ts +252 -0
- package/src/tool/bash.txt +115 -0
- package/src/tool/batch.ts +175 -0
- package/src/tool/batch.txt +24 -0
- package/src/tool/codesearch.ts +132 -0
- package/src/tool/codesearch.txt +12 -0
- package/src/tool/context_collect.ts +152 -0
- package/src/tool/context_collect.txt +9 -0
- package/src/tool/context_diagnostics.ts +81 -0
- package/src/tool/context_diagnostics.txt +5 -0
- package/src/tool/context_related.ts +117 -0
- package/src/tool/context_related.txt +5 -0
- package/src/tool/context_search.ts +108 -0
- package/src/tool/context_search.txt +8 -0
- package/src/tool/db-diff.ts +434 -0
- package/src/tool/db-table.txt +15 -0
- package/src/tool/docs_add.ts +50 -0
- package/src/tool/docs_add.txt +5 -0
- package/src/tool/docs_context.ts +56 -0
- package/src/tool/docs_context.txt +4 -0
- package/src/tool/docs_gap_report.ts +79 -0
- package/src/tool/docs_gap_report.txt +7 -0
- package/src/tool/docs_load.ts +41 -0
- package/src/tool/docs_load.txt +4 -0
- package/src/tool/docs_request.ts +129 -0
- package/src/tool/docs_request.txt +7 -0
- package/src/tool/docs_search.ts +51 -0
- package/src/tool/docs_search.txt +6 -0
- package/src/tool/docs_unload.ts +38 -0
- package/src/tool/docs_unload.txt +5 -0
- package/src/tool/edit.ts +614 -0
- package/src/tool/edit.txt +10 -0
- package/src/tool/external-directory.ts +32 -0
- package/src/tool/generate_image.ts +174 -0
- package/src/tool/generate_image.txt +12 -0
- package/src/tool/glob.ts +79 -0
- package/src/tool/glob.txt +6 -0
- package/src/tool/grep.ts +153 -0
- package/src/tool/grep.txt +8 -0
- package/src/tool/invalid.ts +17 -0
- package/src/tool/ls.ts +116 -0
- package/src/tool/ls.txt +1 -0
- package/src/tool/lsp.ts +96 -0
- package/src/tool/lsp.txt +19 -0
- package/src/tool/memory_search.ts +141 -0
- package/src/tool/memory_search.txt +8 -0
- package/src/tool/multiedit.ts +46 -0
- package/src/tool/multiedit.txt +41 -0
- package/src/tool/plan-enter.txt +14 -0
- package/src/tool/plan-exit.txt +13 -0
- package/src/tool/plan.ts +130 -0
- package/src/tool/question.ts +33 -0
- package/src/tool/question.txt +10 -0
- package/src/tool/rag_index.ts +77 -0
- package/src/tool/rag_index.txt +10 -0
- package/src/tool/rag_reset.ts +26 -0
- package/src/tool/rag_reset.txt +4 -0
- package/src/tool/rag_search.ts +62 -0
- package/src/tool/rag_search.txt +6 -0
- package/src/tool/rag_status.ts +45 -0
- package/src/tool/rag_status.txt +4 -0
- package/src/tool/read.ts +203 -0
- package/src/tool/read.txt +12 -0
- package/src/tool/registry.ts +214 -0
- package/src/tool/skill.ts +169 -0
- package/src/tool/skill.txt +3 -0
- package/src/tool/smart_docs.ts +74 -0
- package/src/tool/smart_docs.txt +7 -0
- package/src/tool/speak/elevenlabs.ts +201 -0
- package/src/tool/speak/openrouter.ts +240 -0
- package/src/tool/speak/provider.ts +83 -0
- package/src/tool/speak.ts +440 -0
- package/src/tool/task.ts +194 -0
- package/src/tool/task.txt +60 -0
- package/src/tool/todo.ts +53 -0
- package/src/tool/todoread.txt +14 -0
- package/src/tool/todowrite.txt +167 -0
- package/src/tool/tool.ts +87 -0
- package/src/tool/tree.ts +218 -0
- package/src/tool/tree.txt +8 -0
- package/src/tool/truncation.ts +106 -0
- package/src/tool/use-connector.ts +47 -0
- package/src/tool/voice.ts +188 -0
- package/src/tool/webfetch.ts +205 -0
- package/src/tool/webfetch.txt +13 -0
- package/src/tool/websearch.ts +150 -0
- package/src/tool/websearch.txt +14 -0
- package/src/tool/write.ts +80 -0
- package/src/tool/write.txt +8 -0
- package/src/util/archive.ts +16 -0
- package/src/util/color.ts +19 -0
- package/src/util/context.ts +25 -0
- package/src/util/defer.ts +12 -0
- package/src/util/error.ts +77 -0
- package/src/util/eventloop.ts +20 -0
- package/src/util/filesystem.ts +125 -0
- package/src/util/flock.ts +329 -0
- package/src/util/fn.ts +11 -0
- package/src/util/format.ts +20 -0
- package/src/util/hash.ts +7 -0
- package/src/util/iife.ts +3 -0
- package/src/util/keybind.ts +103 -0
- package/src/util/lazy.ts +18 -0
- package/src/util/locale.ts +81 -0
- package/src/util/lock.ts +98 -0
- package/src/util/log.ts +180 -0
- package/src/util/network.ts +9 -0
- package/src/util/process.ts +15 -0
- package/src/util/queue.ts +32 -0
- package/src/util/record.ts +3 -0
- package/src/util/rpc.ts +66 -0
- package/src/util/scrap.ts +10 -0
- package/src/util/signal.ts +12 -0
- package/src/util/timeout.ts +14 -0
- package/src/util/token.ts +7 -0
- package/src/util/wildcard.ts +56 -0
- package/src/workspace/adaptors/index.ts +271 -0
- package/src/workspace/adaptors/types.ts +14 -0
- package/src/workspace/adaptors/worktree.ts +31 -0
- package/src/workspace/config.ts +19 -0
- package/src/workspace/index.ts +223 -0
- package/src/workspace/session-proxy-middleware.ts +97 -0
- package/src/workspace/sse.ts +66 -0
- package/src/workspace/workspace-context.ts +23 -0
- package/src/workspace/workspace-server/routes.ts +33 -0
- package/src/workspace/workspace-server/server.ts +47 -0
- package/src/worktree/index.ts +487 -0
- package/sst-env.d.ts +10 -0
- package/test/benchmark.test.ts +121 -0
- package/test/build-optimizations.test.ts +124 -0
- package/test/id-benchmark.test.ts +132 -0
- package/test/optimizations.test.ts +302 -0
- package/test/preload.ts +1 -0
- package/test/solidjs-benchmark.test.ts +262 -0
- package/test/solidjs-optimizations.test.ts +259 -0
- package/test/tui-benchmark.test.ts +230 -0
- package/test/wildcard-benchmark.test.ts +180 -0
- package/tsconfig.json +26 -0
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import { dynamicTool, type Tool, jsonSchema } from "ai"
|
|
2
|
+
import { Config } from "../config/config"
|
|
3
|
+
import { resolveCredential } from "./credentials"
|
|
4
|
+
import { FigmaApi } from "./api/figma"
|
|
5
|
+
import { SlackApi } from "./api/slack"
|
|
6
|
+
import { GithubApi } from "./api/github"
|
|
7
|
+
import { LovableApi } from "./api/lovable"
|
|
8
|
+
|
|
9
|
+
export interface OperationArg {
|
|
10
|
+
name: string
|
|
11
|
+
description: string
|
|
12
|
+
required?: boolean
|
|
13
|
+
type?: "string" | "number" | "boolean"
|
|
14
|
+
enum?: string[]
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface OperationSpec {
|
|
18
|
+
name: string
|
|
19
|
+
description: string
|
|
20
|
+
args: OperationArg[]
|
|
21
|
+
execute: (credential: string, args: Record<string, any>) => Promise<any>
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface ConnectorSpec {
|
|
25
|
+
type: string
|
|
26
|
+
credentialType: "token" | "botToken" | "apiKey"
|
|
27
|
+
operations: OperationSpec[]
|
|
28
|
+
healthCheck: (credential: string) => Promise<void>
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const FIGMA_OPERATIONS: OperationSpec[] = [
|
|
32
|
+
{
|
|
33
|
+
name: "figma_get_file",
|
|
34
|
+
description: "Get the contents of a Figma file including all pages and frames",
|
|
35
|
+
args: [{ name: "fileKey", description: "The Figma file key (found in Figma URL after /file/)", required: true }],
|
|
36
|
+
execute: (cred, args) => FigmaApi.getFile(cred, args.fileKey),
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: "figma_get_components",
|
|
40
|
+
description: "Get all components from a Figma file",
|
|
41
|
+
args: [{ name: "fileKey", description: "The Figma file key", required: true }],
|
|
42
|
+
execute: (cred, args) => FigmaApi.getFileComponents(cred, args.fileKey),
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: "figma_get_styles",
|
|
46
|
+
description: "Get all styles from a Figma file",
|
|
47
|
+
args: [{ name: "fileKey", description: "The Figma file key", required: true }],
|
|
48
|
+
execute: (cred, args) => FigmaApi.getFileStyles(cred, args.fileKey),
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: "figma_get_comments",
|
|
52
|
+
description: "Get all comments from a Figma file",
|
|
53
|
+
args: [{ name: "fileKey", description: "The Figma file key", required: true }],
|
|
54
|
+
execute: (cred, args) => FigmaApi.getComments(cred, args.fileKey),
|
|
55
|
+
},
|
|
56
|
+
]
|
|
57
|
+
|
|
58
|
+
const SLACK_OPERATIONS: OperationSpec[] = [
|
|
59
|
+
{
|
|
60
|
+
name: "slack_list_channels",
|
|
61
|
+
description: "List all channels in a Slack workspace",
|
|
62
|
+
args: [
|
|
63
|
+
{
|
|
64
|
+
name: "types",
|
|
65
|
+
description: "Comma-separated channel types: public_channel, private_channel, mpim, im",
|
|
66
|
+
type: "string",
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
execute: (cred, args) => SlackApi.listConversations(cred, args.types),
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: "slack_send_message",
|
|
73
|
+
description: "Send a message to a Slack channel",
|
|
74
|
+
args: [
|
|
75
|
+
{
|
|
76
|
+
name: "channel",
|
|
77
|
+
description: "The Slack channel ID (e.g., C01234567) or name (e.g., general)",
|
|
78
|
+
required: true,
|
|
79
|
+
},
|
|
80
|
+
{ name: "text", description: "The message text to send", required: true },
|
|
81
|
+
],
|
|
82
|
+
execute: (cred, args) => SlackApi.sendMessage(cred, args.channel, args.text),
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
name: "slack_search_messages",
|
|
86
|
+
description: "Search for messages in Slack",
|
|
87
|
+
args: [
|
|
88
|
+
{ name: "query", description: "The search query", required: true },
|
|
89
|
+
{ name: "count", description: "Maximum number of results (default 20)", type: "number" },
|
|
90
|
+
],
|
|
91
|
+
execute: (cred, args) => SlackApi.searchMessages(cred, args.query, args.count),
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: "slack_get_channel_info",
|
|
95
|
+
description: "Get information about a Slack channel",
|
|
96
|
+
args: [{ name: "channel", description: "The Slack channel ID", required: true }],
|
|
97
|
+
execute: (cred, args) => SlackApi.getConversationInfo(cred, args.channel),
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: "slack_reply_to_thread",
|
|
101
|
+
description: "Reply to a message thread in Slack",
|
|
102
|
+
args: [
|
|
103
|
+
{ name: "channel", description: "The Slack channel ID", required: true },
|
|
104
|
+
{ name: "threadTs", description: "The thread timestamp (ts) from the original message", required: true },
|
|
105
|
+
{ name: "text", description: "The reply text", required: true },
|
|
106
|
+
],
|
|
107
|
+
execute: (cred, args) => SlackApi.replyToMessage(cred, args.channel, args.threadTs, args.text),
|
|
108
|
+
},
|
|
109
|
+
]
|
|
110
|
+
|
|
111
|
+
const GITHUB_OPERATIONS: OperationSpec[] = [
|
|
112
|
+
{
|
|
113
|
+
name: "github_get_repo",
|
|
114
|
+
description: "Get information about a GitHub repository",
|
|
115
|
+
args: [
|
|
116
|
+
{ name: "owner", description: "Repository owner (username or organization)", required: true },
|
|
117
|
+
{ name: "repo", description: "Repository name", required: true },
|
|
118
|
+
],
|
|
119
|
+
execute: (cred, args) => GithubApi.getRepo(cred, args.owner, args.repo),
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
name: "github_get_file",
|
|
123
|
+
description: "Get the contents of a file from a GitHub repository",
|
|
124
|
+
args: [
|
|
125
|
+
{ name: "owner", description: "Repository owner", required: true },
|
|
126
|
+
{ name: "repo", description: "Repository name", required: true },
|
|
127
|
+
{ name: "path", description: "Path to the file in the repository", required: true },
|
|
128
|
+
{ name: "ref", description: "Branch, tag, or commit (optional)", type: "string" },
|
|
129
|
+
],
|
|
130
|
+
execute: (cred, args) => GithubApi.getFileContent(cred, args.owner, args.repo, args.path),
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: "github_create_issue",
|
|
134
|
+
description: "Create a new issue in a GitHub repository",
|
|
135
|
+
args: [
|
|
136
|
+
{ name: "owner", description: "Repository owner", required: true },
|
|
137
|
+
{ name: "repo", description: "Repository name", required: true },
|
|
138
|
+
{ name: "title", description: "Issue title", required: true },
|
|
139
|
+
{ name: "body", description: "Issue body (optional)", type: "string" },
|
|
140
|
+
],
|
|
141
|
+
execute: (cred, args) => GithubApi.createIssue(cred, args.owner, args.repo, args.title, args.body),
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
name: "github_list_issues",
|
|
145
|
+
description: "List issues in a GitHub repository",
|
|
146
|
+
args: [
|
|
147
|
+
{ name: "owner", description: "Repository owner", required: true },
|
|
148
|
+
{ name: "repo", description: "Repository name", required: true },
|
|
149
|
+
{ name: "state", description: "Issue state (default: open)", enum: ["open", "closed", "all"], type: "string" },
|
|
150
|
+
],
|
|
151
|
+
execute: (cred, args) => GithubApi.listIssues(cred, args.owner, args.repo, args.state),
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
name: "github_search_code",
|
|
155
|
+
description: "Search for code in GitHub",
|
|
156
|
+
args: [
|
|
157
|
+
{ name: "query", description: "Search query (supports GitHub code search syntax)", required: true },
|
|
158
|
+
{ name: "sort", description: "Sort by", enum: ["indexed"], type: "string" },
|
|
159
|
+
{ name: "order", description: "Order direction", enum: ["asc", "desc"], type: "string" },
|
|
160
|
+
],
|
|
161
|
+
execute: (cred, args) => GithubApi.searchCode(cred, args.query, args.sort, args.order),
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
name: "github_list_repos",
|
|
165
|
+
description: "List repositories for the authenticated user",
|
|
166
|
+
args: [
|
|
167
|
+
{
|
|
168
|
+
name: "type",
|
|
169
|
+
description: "Repository type (default: owner)",
|
|
170
|
+
enum: ["all", "owner", "member"],
|
|
171
|
+
type: "string",
|
|
172
|
+
},
|
|
173
|
+
{ name: "sort", description: "Sort by", enum: ["updated", "pushed", "full_name"], type: "string" },
|
|
174
|
+
],
|
|
175
|
+
execute: (cred, args) => GithubApi.listRepos(cred, args.type, args.sort),
|
|
176
|
+
},
|
|
177
|
+
]
|
|
178
|
+
|
|
179
|
+
const LOVABLE_OPERATIONS: OperationSpec[] = [
|
|
180
|
+
{
|
|
181
|
+
name: "lovable_get_projects",
|
|
182
|
+
description: "Get all Lovable projects",
|
|
183
|
+
args: [],
|
|
184
|
+
execute: (cred) => LovableApi.getProjects(cred),
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
name: "lovable_get_project",
|
|
188
|
+
description: "Get information about a Lovable project",
|
|
189
|
+
args: [{ name: "projectId", description: "The Lovable project ID", required: true }],
|
|
190
|
+
execute: (cred, args) => LovableApi.getProject(cred, args.projectId),
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
name: "lovable_get_chats",
|
|
194
|
+
description: "Get all chats for a Lovable project",
|
|
195
|
+
args: [{ name: "projectId", description: "The Lovable project ID", required: true }],
|
|
196
|
+
execute: (cred, args) => LovableApi.getChats(cred, args.projectId),
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
name: "lovable_send_message",
|
|
200
|
+
description: "Send a message to a Lovable project",
|
|
201
|
+
args: [
|
|
202
|
+
{ name: "projectId", description: "The Lovable project ID", required: true },
|
|
203
|
+
{ name: "message", description: "The message to send", required: true },
|
|
204
|
+
{ name: "chatId", description: "Existing chat ID (optional, creates new chat if not provided)", type: "string" },
|
|
205
|
+
],
|
|
206
|
+
execute: (cred, args) => LovableApi.sendMessage(cred, args.projectId, args.message, args.chatId),
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
name: "lovable_get_project_files",
|
|
210
|
+
description: "Get all files in a Lovable project",
|
|
211
|
+
args: [{ name: "projectId", description: "The Lovable project ID", required: true }],
|
|
212
|
+
execute: (cred, args) => LovableApi.getProjectFiles(cred, args.projectId),
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
name: "lovable_run_prompt",
|
|
216
|
+
description: "Run a prompt in a Lovable project",
|
|
217
|
+
args: [
|
|
218
|
+
{ name: "projectId", description: "The Lovable project ID", required: true },
|
|
219
|
+
{ name: "prompt", description: "The prompt to run", required: true },
|
|
220
|
+
],
|
|
221
|
+
execute: (cred, args) => LovableApi.runPrompt(cred, args.projectId, args.prompt),
|
|
222
|
+
},
|
|
223
|
+
]
|
|
224
|
+
|
|
225
|
+
const CONNECTOR_SPECS: Record<string, ConnectorSpec> = {
|
|
226
|
+
figma: {
|
|
227
|
+
type: "figma",
|
|
228
|
+
credentialType: "token",
|
|
229
|
+
operations: FIGMA_OPERATIONS,
|
|
230
|
+
healthCheck: (cred) => FigmaApi.getMe(cred),
|
|
231
|
+
},
|
|
232
|
+
slack: {
|
|
233
|
+
type: "slack",
|
|
234
|
+
credentialType: "botToken",
|
|
235
|
+
operations: SLACK_OPERATIONS,
|
|
236
|
+
healthCheck: (cred) => SlackApi.listUsers(cred),
|
|
237
|
+
},
|
|
238
|
+
github: {
|
|
239
|
+
type: "github",
|
|
240
|
+
credentialType: "token",
|
|
241
|
+
operations: GITHUB_OPERATIONS,
|
|
242
|
+
healthCheck: (cred) => GithubApi.getUser(cred),
|
|
243
|
+
},
|
|
244
|
+
lovable: {
|
|
245
|
+
type: "lovable",
|
|
246
|
+
credentialType: "token",
|
|
247
|
+
operations: LOVABLE_OPERATIONS,
|
|
248
|
+
healthCheck: (cred) => LovableApi.getProjects(cred),
|
|
249
|
+
},
|
|
250
|
+
discord: {
|
|
251
|
+
type: "discord",
|
|
252
|
+
credentialType: "botToken",
|
|
253
|
+
operations: [],
|
|
254
|
+
healthCheck: async () => {},
|
|
255
|
+
},
|
|
256
|
+
teams: {
|
|
257
|
+
type: "teams",
|
|
258
|
+
credentialType: "botToken",
|
|
259
|
+
operations: [],
|
|
260
|
+
healthCheck: async () => {},
|
|
261
|
+
},
|
|
262
|
+
gchat: {
|
|
263
|
+
type: "gchat",
|
|
264
|
+
credentialType: "botToken",
|
|
265
|
+
operations: [],
|
|
266
|
+
healthCheck: async () => {},
|
|
267
|
+
},
|
|
268
|
+
linear: {
|
|
269
|
+
type: "linear",
|
|
270
|
+
credentialType: "botToken",
|
|
271
|
+
operations: [],
|
|
272
|
+
healthCheck: async () => {},
|
|
273
|
+
},
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export function getConnectorSpec(type: string): ConnectorSpec | undefined {
|
|
277
|
+
return CONNECTOR_SPECS[type]
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export function listConnectorTypes(): string[] {
|
|
281
|
+
return Object.keys(CONNECTOR_SPECS)
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
export async function createTools(name: string, connector: Config.Connector): Promise<Record<string, Tool>> {
|
|
285
|
+
const spec = CONNECTOR_SPECS[connector.type]
|
|
286
|
+
if (!spec) return {}
|
|
287
|
+
|
|
288
|
+
const credential = await resolveCredential(name, connector)
|
|
289
|
+
if (!credential) return {}
|
|
290
|
+
|
|
291
|
+
const tools: Record<string, Tool> = {}
|
|
292
|
+
|
|
293
|
+
for (const operation of spec.operations) {
|
|
294
|
+
const toolName = `${name}_${operation.name}`
|
|
295
|
+
tools[toolName] = dynamicTool({
|
|
296
|
+
description: operation.description,
|
|
297
|
+
inputSchema: jsonSchema({
|
|
298
|
+
type: "object",
|
|
299
|
+
properties: Object.fromEntries(
|
|
300
|
+
operation.args.map((arg) => [
|
|
301
|
+
arg.name,
|
|
302
|
+
{
|
|
303
|
+
type: arg.type ?? "string",
|
|
304
|
+
description: arg.description,
|
|
305
|
+
...(arg.enum && { enum: arg.enum }),
|
|
306
|
+
},
|
|
307
|
+
]),
|
|
308
|
+
),
|
|
309
|
+
required: operation.args.filter((arg) => arg.required).map((arg) => arg.name),
|
|
310
|
+
additionalProperties: false,
|
|
311
|
+
}),
|
|
312
|
+
execute: async (args: unknown) => {
|
|
313
|
+
const typedArgs = args as Record<string, any>
|
|
314
|
+
const result = await operation.execute(credential, typedArgs)
|
|
315
|
+
return typeof result === "string" ? result : JSON.stringify(result, null, 2)
|
|
316
|
+
},
|
|
317
|
+
}) as Tool
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return tools
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
export async function executeOperation(
|
|
324
|
+
name: string,
|
|
325
|
+
connector: Config.Connector,
|
|
326
|
+
operationName: string,
|
|
327
|
+
args: Record<string, any>,
|
|
328
|
+
): Promise<any> {
|
|
329
|
+
const spec = CONNECTOR_SPECS[connector.type]
|
|
330
|
+
if (!spec) throw new Error(`Unknown connector type: ${connector.type}`)
|
|
331
|
+
|
|
332
|
+
const credential = await resolveCredential(name, connector)
|
|
333
|
+
if (!credential) throw new Error(`No credential for connector "${name}"`)
|
|
334
|
+
|
|
335
|
+
const operation = spec.operations.find((op) => op.name === operationName)
|
|
336
|
+
if (!operation) throw new Error(`Unknown operation: ${operationName}`)
|
|
337
|
+
|
|
338
|
+
return operation.execute(credential, args)
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
export function getHealthCheck(type: string): ((credential: string) => Promise<void>) | undefined {
|
|
342
|
+
return CONNECTOR_SPECS[type]?.healthCheck
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
export function getOperationSpec(type: string, operationName: string): OperationSpec | undefined {
|
|
346
|
+
return CONNECTOR_SPECS[type]?.operations.find((op) => op.name === operationName)
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
export function getPrompts(type: string): Array<{ name: string; description: string; args: OperationArg[] }> {
|
|
350
|
+
const spec = CONNECTOR_SPECS[type]
|
|
351
|
+
if (!spec) return []
|
|
352
|
+
|
|
353
|
+
return spec.operations.map((op) => ({
|
|
354
|
+
name: op.name,
|
|
355
|
+
description: op.description,
|
|
356
|
+
args: op.args,
|
|
357
|
+
}))
|
|
358
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import path from "path"
|
|
2
|
+
import { mkdir } from "fs/promises"
|
|
3
|
+
import { Global } from "@/global"
|
|
4
|
+
import { getAllDocs, type DocEntry } from "./library"
|
|
5
|
+
|
|
6
|
+
type DocsContext = {
|
|
7
|
+
ids: string[]
|
|
8
|
+
updatedAt: number
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const DIR = path.join(Global.Path.data, "docs")
|
|
12
|
+
const FILE = path.join(DIR, "context.json")
|
|
13
|
+
const MAX_SUMMARY_CHARS = 4000
|
|
14
|
+
const MAX_FULL_CHARS = 20000
|
|
15
|
+
|
|
16
|
+
async function ensureDir() {
|
|
17
|
+
await mkdir(DIR, { recursive: true })
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function readContext(): Promise<DocsContext> {
|
|
21
|
+
const file = Bun.file(FILE)
|
|
22
|
+
const exists = await file.exists()
|
|
23
|
+
if (!exists) return { ids: [], updatedAt: Date.now() }
|
|
24
|
+
const data = await file.json().catch(() => null)
|
|
25
|
+
if (!data || !Array.isArray(data.ids)) return { ids: [], updatedAt: Date.now() }
|
|
26
|
+
return {
|
|
27
|
+
ids: data.ids,
|
|
28
|
+
updatedAt: typeof data.updatedAt === "number" ? data.updatedAt : Date.now(),
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function writeContext(context: DocsContext): Promise<void> {
|
|
33
|
+
await ensureDir()
|
|
34
|
+
await Bun.write(FILE, JSON.stringify(context, null, 2))
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function unique(ids: string[]): string[] {
|
|
38
|
+
return Array.from(new Set(ids))
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export async function loadDocs(ids: string[]): Promise<{ loaded: DocEntry[]; missing: string[] }> {
|
|
42
|
+
const ctx = await readContext()
|
|
43
|
+
const all = await getAllDocs()
|
|
44
|
+
const valid = all.filter((entry) => ids.some((id) => matches(entry, id)))
|
|
45
|
+
const foundIds = valid.map((entry) => entry.id)
|
|
46
|
+
const missing = ids.filter((id) => !all.some((entry) => matches(entry, id)))
|
|
47
|
+
const next = unique([...ctx.ids, ...foundIds])
|
|
48
|
+
await writeContext({ ids: next, updatedAt: Date.now() })
|
|
49
|
+
return { loaded: valid, missing }
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export async function unloadDocs(ids?: string[]): Promise<{ removed: string[] }> {
|
|
53
|
+
const ctx = await readContext()
|
|
54
|
+
if (!ids || ids.length === 0) {
|
|
55
|
+
await writeContext({ ids: [], updatedAt: Date.now() })
|
|
56
|
+
return { removed: ctx.ids }
|
|
57
|
+
}
|
|
58
|
+
const all = await getAllDocs()
|
|
59
|
+
const loaded = ctx.ids
|
|
60
|
+
.map((id) => all.find((entry) => entry.id === id))
|
|
61
|
+
.filter((entry): entry is DocEntry => Boolean(entry))
|
|
62
|
+
const toRemove = loaded.filter((entry) => ids.some((id) => matches(entry, id))).map((entry) => entry.id)
|
|
63
|
+
const removed = ctx.ids.filter((id) => toRemove.includes(id))
|
|
64
|
+
const next = ctx.ids.filter((id) => !toRemove.includes(id))
|
|
65
|
+
await writeContext({ ids: next, updatedAt: Date.now() })
|
|
66
|
+
return { removed }
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export async function getLoadedDocs(): Promise<DocEntry[]> {
|
|
70
|
+
const ctx = await readContext()
|
|
71
|
+
if (ctx.ids.length === 0) return []
|
|
72
|
+
const docs = await getAllDocs()
|
|
73
|
+
const sorted = ctx.ids
|
|
74
|
+
.map((id) => docs.find((entry) => entry.id === id))
|
|
75
|
+
.filter((entry): entry is DocEntry => Boolean(entry))
|
|
76
|
+
return sorted
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function summaryLine(entry: DocEntry): string {
|
|
80
|
+
const tags = entry.tags.length > 0 ? ` tags: ${entry.tags.join(", ")}` : ""
|
|
81
|
+
return `- ${entry.title} (${entry.category})${tags}`
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function matches(entry: DocEntry, key: string): boolean {
|
|
85
|
+
const lower = key.toLowerCase()
|
|
86
|
+
if (entry.id === key) return true
|
|
87
|
+
if (entry.url.toLowerCase().includes(lower)) return true
|
|
88
|
+
if (entry.title.toLowerCase().includes(lower)) return true
|
|
89
|
+
if (entry.tags.some((tag) => tag.toLowerCase().includes(lower))) return true
|
|
90
|
+
return false
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export async function getContextSummary(): Promise<string> {
|
|
94
|
+
const docs = await getLoadedDocs()
|
|
95
|
+
if (docs.length === 0) return "No documentation loaded."
|
|
96
|
+
const lines = docs.map(summaryLine)
|
|
97
|
+
const summary = `Documentation context (${docs.length} docs)\n` + lines.join("\n")
|
|
98
|
+
if (summary.length <= MAX_SUMMARY_CHARS) return summary
|
|
99
|
+
return summary.slice(0, MAX_SUMMARY_CHARS) + "\n[summary truncated]"
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export async function getFullContext(): Promise<string> {
|
|
103
|
+
const docs = await getLoadedDocs()
|
|
104
|
+
if (docs.length === 0) return ""
|
|
105
|
+
const chunks = docs.map((entry) => {
|
|
106
|
+
return [
|
|
107
|
+
`## ${entry.title}`,
|
|
108
|
+
`Category: ${entry.category}`,
|
|
109
|
+
entry.tags.length > 0 ? `Tags: ${entry.tags.join(", ")}` : "",
|
|
110
|
+
entry.url ? `Source: ${entry.url}` : "",
|
|
111
|
+
"",
|
|
112
|
+
entry.content,
|
|
113
|
+
]
|
|
114
|
+
.filter(Boolean)
|
|
115
|
+
.join("\n")
|
|
116
|
+
})
|
|
117
|
+
const content = `# DOCUMENTATION CONTEXT\n\n` + chunks.join("\n\n---\n\n")
|
|
118
|
+
if (content.length <= MAX_FULL_CHARS) return content
|
|
119
|
+
return content.slice(0, MAX_FULL_CHARS) + "\n[context truncated]"
|
|
120
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import path from "path"
|
|
2
|
+
import { mkdir } from "fs/promises"
|
|
3
|
+
import { randomUUID } from "crypto"
|
|
4
|
+
import TurndownService from "turndown"
|
|
5
|
+
import { Global } from "@/global"
|
|
6
|
+
|
|
7
|
+
export type DocEntry = {
|
|
8
|
+
id: string
|
|
9
|
+
url: string
|
|
10
|
+
title: string
|
|
11
|
+
content: string
|
|
12
|
+
category: string
|
|
13
|
+
tags: string[]
|
|
14
|
+
addedAt: number
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type DocSearchResult = {
|
|
18
|
+
entry: DocEntry
|
|
19
|
+
score: number
|
|
20
|
+
snippet: string
|
|
21
|
+
terms: string[]
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const DIR = path.join(Global.Path.data, "docs")
|
|
25
|
+
const LIB = path.join(DIR, "library.json")
|
|
26
|
+
const MAX_CONTENT = 60000
|
|
27
|
+
const MIN_CONTENT = 200
|
|
28
|
+
|
|
29
|
+
const turndown = new TurndownService({
|
|
30
|
+
codeBlockStyle: "fenced",
|
|
31
|
+
headingStyle: "atx",
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
async function ensureDir() {
|
|
35
|
+
await mkdir(DIR, { recursive: true })
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function readAll(): Promise<DocEntry[]> {
|
|
39
|
+
const file = Bun.file(LIB)
|
|
40
|
+
const exists = await file.exists()
|
|
41
|
+
if (!exists) return []
|
|
42
|
+
const data = await file.json()
|
|
43
|
+
const list = Array.isArray(data) ? data : []
|
|
44
|
+
return list as DocEntry[]
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function writeAll(list: DocEntry[]): Promise<void> {
|
|
48
|
+
await ensureDir()
|
|
49
|
+
await Bun.write(LIB, JSON.stringify(list, null, 2))
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function cleanHtml(html: string): string {
|
|
53
|
+
const noScript = html.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, " ")
|
|
54
|
+
const noStyle = noScript.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, " ")
|
|
55
|
+
return noStyle
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function toText(html: string): string {
|
|
59
|
+
const cleaned = cleanHtml(html)
|
|
60
|
+
const text = turndown.turndown(cleaned)
|
|
61
|
+
return text.replace(/\n{3,}/g, "\n\n").trim()
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function getTitle(html: string, url: string): string {
|
|
65
|
+
const match = html.match(/<title[^>]*>([^<]+)<\/title>/i)
|
|
66
|
+
if (match?.[1]) return match[1].trim().slice(0, 120)
|
|
67
|
+
return url
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function normalize(text: string): string {
|
|
71
|
+
return text
|
|
72
|
+
.toLowerCase()
|
|
73
|
+
.replace(/[^a-z0-9\s]/g, " ")
|
|
74
|
+
.replace(/\s+/g, " ")
|
|
75
|
+
.trim()
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function terms(text: string): string[] {
|
|
79
|
+
const list = normalize(text).split(" ").filter(Boolean)
|
|
80
|
+
if (list.length === 0) return []
|
|
81
|
+
return Array.from(new Set(list))
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function score(entry: DocEntry, query: string): { score: number; terms: string[] } {
|
|
85
|
+
const items = terms(query)
|
|
86
|
+
if (items.length === 0) return { score: 0, terms: [] }
|
|
87
|
+
const title = normalize(entry.title)
|
|
88
|
+
const body = normalize(entry.content)
|
|
89
|
+
const tags = entry.tags.map((tag) => normalize(tag)).join(" ")
|
|
90
|
+
const base = items.reduce((sum, item) => {
|
|
91
|
+
const inTitle = title.includes(item) ? 2 : 0
|
|
92
|
+
const inBody = body.includes(item) ? 1 : 0
|
|
93
|
+
const inTags = tags.includes(item) ? 1 : 0
|
|
94
|
+
return sum + inTitle + inBody + inTags
|
|
95
|
+
}, 0)
|
|
96
|
+
const value = base / items.length
|
|
97
|
+
return { score: value, terms: items }
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function snippet(entry: DocEntry, query: string): string {
|
|
101
|
+
const items = terms(query)
|
|
102
|
+
const text = entry.content
|
|
103
|
+
const lower = text.toLowerCase()
|
|
104
|
+
const idx = items
|
|
105
|
+
.map((item) => lower.indexOf(item))
|
|
106
|
+
.filter((val) => val >= 0)
|
|
107
|
+
.sort((a, b) => a - b)[0]
|
|
108
|
+
if (idx === undefined) return text.slice(0, 200)
|
|
109
|
+
const start = Math.max(0, idx - 80)
|
|
110
|
+
const end = Math.min(text.length, idx + 140)
|
|
111
|
+
return text.slice(start, end).replace(/\s+/g, " ").trim()
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function match(entry: DocEntry, key: string): boolean {
|
|
115
|
+
const lower = key.toLowerCase()
|
|
116
|
+
if (entry.id === key) return true
|
|
117
|
+
if (entry.url.toLowerCase().includes(lower)) return true
|
|
118
|
+
if (entry.title.toLowerCase().includes(lower)) return true
|
|
119
|
+
if (entry.tags.some((tag) => tag.toLowerCase().includes(lower))) return true
|
|
120
|
+
return false
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export async function addDoc(input: { url: string; category?: string; tags?: string[] }): Promise<DocEntry> {
|
|
124
|
+
const res = await fetch(input.url)
|
|
125
|
+
if (!res.ok) {
|
|
126
|
+
throw new Error(`Docs fetch failed: ${res.status} ${res.statusText}`)
|
|
127
|
+
}
|
|
128
|
+
const html = await res.text()
|
|
129
|
+
const title = getTitle(html, input.url)
|
|
130
|
+
const text = toText(html)
|
|
131
|
+
if (text.length < MIN_CONTENT) {
|
|
132
|
+
throw new Error("Docs content too short to index")
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const entry: DocEntry = {
|
|
136
|
+
id: randomUUID(),
|
|
137
|
+
url: input.url,
|
|
138
|
+
title,
|
|
139
|
+
content: text.slice(0, MAX_CONTENT),
|
|
140
|
+
category: input.category || "general",
|
|
141
|
+
tags: (input.tags ?? []).filter(Boolean),
|
|
142
|
+
addedAt: Date.now(),
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
await ensureDir()
|
|
146
|
+
const list = await readAll()
|
|
147
|
+
const next = [entry, ...list]
|
|
148
|
+
await writeAll(next)
|
|
149
|
+
return entry
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export async function listDocs(category?: string): Promise<DocEntry[]> {
|
|
153
|
+
const list = await readAll()
|
|
154
|
+
if (!category) return list
|
|
155
|
+
return list.filter((item) => item.category === category)
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export async function getAllDocs(): Promise<DocEntry[]> {
|
|
159
|
+
return readAll()
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export async function getDoc(key: string): Promise<DocEntry | undefined> {
|
|
163
|
+
const list = await readAll()
|
|
164
|
+
return list.find((entry) => match(entry, key))
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export async function getDocs(keys: string[]): Promise<DocEntry[]> {
|
|
168
|
+
const list = await readAll()
|
|
169
|
+
return list.filter((entry) => keys.some((key) => match(entry, key)))
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export async function searchDocs(query: string, category?: string, limit = 5): Promise<DocSearchResult[]> {
|
|
173
|
+
const list = await readAll()
|
|
174
|
+
const items = category ? list.filter((item) => item.category === category) : list
|
|
175
|
+
const scored = items
|
|
176
|
+
.map((entry) => {
|
|
177
|
+
const result = score(entry, query)
|
|
178
|
+
return {
|
|
179
|
+
entry,
|
|
180
|
+
score: result.score,
|
|
181
|
+
snippet: snippet(entry, query),
|
|
182
|
+
terms: result.terms,
|
|
183
|
+
}
|
|
184
|
+
})
|
|
185
|
+
.filter((item) => item.score > 0)
|
|
186
|
+
.sort((a, b) => b.score - a.score)
|
|
187
|
+
.slice(0, limit)
|
|
188
|
+
return scored
|
|
189
|
+
}
|
package/src/env/index.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Instance } from "../project/instance"
|
|
2
|
+
|
|
3
|
+
export namespace Env {
|
|
4
|
+
const state = Instance.state(() => {
|
|
5
|
+
return process.env as Record<string, string | undefined>
|
|
6
|
+
})
|
|
7
|
+
|
|
8
|
+
export function get(key: string) {
|
|
9
|
+
const env = state()
|
|
10
|
+
return env[key]
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function all() {
|
|
14
|
+
return state()
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function set(key: string, value: string) {
|
|
18
|
+
const env = state()
|
|
19
|
+
env[key] = value
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function remove(key: string) {
|
|
23
|
+
const env = state()
|
|
24
|
+
delete env[key]
|
|
25
|
+
}
|
|
26
|
+
}
|