@happy-creative/iroder 1.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/.qwen/settings.json +8 -0
- package/.qwen/settings.json.orig +7 -0
- package/AGENTS.md +69 -0
- package/BUN_SHELL_MIGRATION_PLAN.md +136 -0
- package/Dockerfile +20 -0
- package/README.md +15 -0
- package/bin/iroder +182 -0
- package/docker-compose.iroder.yml +18 -0
- package/drizzle.config.ts +10 -0
- package/git +0 -0
- package/migration/20260127222353_familiar_lady_ursula/migration.sql +90 -0
- package/migration/20260127222353_familiar_lady_ursula/snapshot.json +796 -0
- package/migration/20260211171708_add_project_commands/migration.sql +1 -0
- package/migration/20260211171708_add_project_commands/snapshot.json +806 -0
- package/migration/20260213144116_wakeful_the_professor/migration.sql +11 -0
- package/migration/20260213144116_wakeful_the_professor/snapshot.json +897 -0
- package/migration/20260225215848_workspace/migration.sql +7 -0
- package/migration/20260225215848_workspace/snapshot.json +959 -0
- package/migration/20260227213759_add_session_workspace_id/migration.sql +2 -0
- package/migration/20260227213759_add_session_workspace_id/snapshot.json +983 -0
- package/migration/20260228203230_blue_harpoon/migration.sql +17 -0
- package/migration/20260228203230_blue_harpoon/snapshot.json +1102 -0
- package/migration/20260303231226_add_workspace_fields/migration.sql +5 -0
- package/migration/20260303231226_add_workspace_fields/snapshot.json +1013 -0
- package/migration/20260309230000_move_org_to_state/migration.sql +3 -0
- package/migration/20260309230000_move_org_to_state/snapshot.json +1156 -0
- package/migration/20260312043431_session_message_cursor/migration.sql +4 -0
- package/migration/20260312043431_session_message_cursor/snapshot.json +1168 -0
- package/migration/20260323234822_events/migration.sql +13 -0
- package/migration/20260323234822_events/snapshot.json +1271 -0
- package/package.json +180 -0
- package/parsers-config.ts +290 -0
- package/script/build-node.ts +60 -0
- package/script/build.ts +281 -0
- package/script/check-migrations.ts +16 -0
- package/script/e2e-local-real-key.ts +197 -0
- package/script/fix-node-pty.ts +28 -0
- package/script/postinstall.mjs +131 -0
- package/script/publish-all.sh +68 -0
- package/script/publish.ts +181 -0
- package/script/schema.ts +63 -0
- package/script/seed-e2e.ts +60 -0
- package/script/upgrade-opentui.ts +64 -0
- package/specs/effect-migration.md +310 -0
- package/specs/tui-plugins.md +436 -0
- package/specs/v2/keymappings.md +10 -0
- package/specs/v2/message-shape.md +136 -0
- package/src/account/account.sql.ts +39 -0
- package/src/account/index.ts +488 -0
- package/src/account/repo.ts +166 -0
- package/src/account/schema.ts +119 -0
- package/src/account/url.ts +8 -0
- package/src/acp/README.md +174 -0
- package/src/acp/agent.ts +1847 -0
- package/src/acp/session.ts +116 -0
- package/src/acp/types.ts +24 -0
- package/src/agent/agent.ts +422 -0
- package/src/agent/generate.txt +75 -0
- package/src/agent/prompt/compaction.txt +15 -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 +110 -0
- package/src/bus/bus-event.ts +40 -0
- package/src/bus/global.ts +10 -0
- package/src/bus/index.ts +185 -0
- package/src/cli/bootstrap.ts +17 -0
- package/src/cli/cmd/account.ts +257 -0
- package/src/cli/cmd/acp.ts +72 -0
- package/src/cli/cmd/agent.ts +245 -0
- package/src/cli/cmd/cmd.ts +7 -0
- package/src/cli/cmd/db.ts +120 -0
- package/src/cli/cmd/debug/agent.ts +170 -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 +53 -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 +89 -0
- package/src/cli/cmd/generate.ts +38 -0
- package/src/cli/cmd/github.ts +1647 -0
- package/src/cli/cmd/import.ts +207 -0
- package/src/cli/cmd/mcp.ts +754 -0
- package/src/cli/cmd/models.ts +78 -0
- package/src/cli/cmd/plug.ts +233 -0
- package/src/cli/cmd/pr.ts +127 -0
- package/src/cli/cmd/providers.ts +480 -0
- package/src/cli/cmd/run.ts +692 -0
- package/src/cli/cmd/serve.ts +23 -0
- package/src/cli/cmd/session.ts +159 -0
- package/src/cli/cmd/stats.ts +410 -0
- package/src/cli/cmd/tui/app.tsx +940 -0
- package/src/cli/cmd/tui/attach.ts +88 -0
- package/src/cli/cmd/tui/component/border.tsx +21 -0
- package/src/cli/cmd/tui/component/dialog-agent.tsx +31 -0
- package/src/cli/cmd/tui/component/dialog-command.tsx +171 -0
- package/src/cli/cmd/tui/component/dialog-console-org.tsx +103 -0
- package/src/cli/cmd/tui/component/dialog-go-upsell.tsx +100 -0
- package/src/cli/cmd/tui/component/dialog-mcp.tsx +86 -0
- package/src/cli/cmd/tui/component/dialog-model.tsx +183 -0
- package/src/cli/cmd/tui/component/dialog-provider.tsx +360 -0
- package/src/cli/cmd/tui/component/dialog-session-list.tsx +108 -0
- package/src/cli/cmd/tui/component/dialog-session-rename.tsx +31 -0
- package/src/cli/cmd/tui/component/dialog-skill.tsx +36 -0
- package/src/cli/cmd/tui/component/dialog-stash.tsx +87 -0
- package/src/cli/cmd/tui/component/dialog-status.tsx +168 -0
- package/src/cli/cmd/tui/component/dialog-tag.tsx +44 -0
- package/src/cli/cmd/tui/component/dialog-theme-list.tsx +50 -0
- package/src/cli/cmd/tui/component/dialog-variant.tsx +39 -0
- package/src/cli/cmd/tui/component/dialog-workspace-list.tsx +320 -0
- package/src/cli/cmd/tui/component/error-component.tsx +93 -0
- package/src/cli/cmd/tui/component/logo.tsx +85 -0
- package/src/cli/cmd/tui/component/plugin-route-missing.tsx +14 -0
- package/src/cli/cmd/tui/component/prompt/autocomplete.tsx +672 -0
- package/src/cli/cmd/tui/component/prompt/frecency.tsx +90 -0
- package/src/cli/cmd/tui/component/prompt/history.tsx +108 -0
- package/src/cli/cmd/tui/component/prompt/index.tsx +1261 -0
- package/src/cli/cmd/tui/component/prompt/part.ts +16 -0
- package/src/cli/cmd/tui/component/prompt/stash.tsx +101 -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/textarea-keybindings.ts +73 -0
- package/src/cli/cmd/tui/component/todo-item.tsx +32 -0
- package/src/cli/cmd/tui/component/workspace/dialog-session-list.tsx +151 -0
- package/src/cli/cmd/tui/context/args.tsx +15 -0
- package/src/cli/cmd/tui/context/directory.ts +13 -0
- package/src/cli/cmd/tui/context/exit.tsx +60 -0
- package/src/cli/cmd/tui/context/helper.tsx +25 -0
- package/src/cli/cmd/tui/context/keybind.tsx +105 -0
- package/src/cli/cmd/tui/context/kv.tsx +52 -0
- package/src/cli/cmd/tui/context/local.tsx +412 -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 +52 -0
- package/src/cli/cmd/tui/context/sdk.tsx +115 -0
- package/src/cli/cmd/tui/context/sync.tsx +516 -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/carbonfox.json +248 -0
- package/src/cli/cmd/tui/context/theme/catppuccin-frappe.json +233 -0
- package/src/cli/cmd/tui/context/theme/catppuccin-macchiato.json +233 -0
- package/src/cli/cmd/tui/context/theme/catppuccin.json +112 -0
- package/src/cli/cmd/tui/context/theme/cobalt2.json +228 -0
- package/src/cli/cmd/tui/context/theme/cursor.json +249 -0
- package/src/cli/cmd/tui/context/theme/dracula.json +219 -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/github.json +233 -0
- package/src/cli/cmd/tui/context/theme/gruvbox.json +242 -0
- package/src/cli/cmd/tui/context/theme/iroder.json +245 -0
- package/src/cli/cmd/tui/context/theme/kanagawa.json +77 -0
- package/src/cli/cmd/tui/context/theme/lucent-orng.json +237 -0
- package/src/cli/cmd/tui/context/theme/material.json +235 -0
- package/src/cli/cmd/tui/context/theme/matrix.json +77 -0
- package/src/cli/cmd/tui/context/theme/mercury.json +252 -0
- package/src/cli/cmd/tui/context/theme/monokai.json +221 -0
- package/src/cli/cmd/tui/context/theme/nightowl.json +221 -0
- package/src/cli/cmd/tui/context/theme/nord.json +223 -0
- package/src/cli/cmd/tui/context/theme/one-dark.json +84 -0
- package/src/cli/cmd/tui/context/theme/opencode.json +245 -0
- package/src/cli/cmd/tui/context/theme/orng.json +249 -0
- package/src/cli/cmd/tui/context/theme/osaka-jade.json +93 -0
- package/src/cli/cmd/tui/context/theme/palenight.json +222 -0
- package/src/cli/cmd/tui/context/theme/rosepine.json +234 -0
- package/src/cli/cmd/tui/context/theme/solarized.json +223 -0
- package/src/cli/cmd/tui/context/theme/synthwave84.json +226 -0
- package/src/cli/cmd/tui/context/theme/tokyonight.json +243 -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/zenburn.json +223 -0
- package/src/cli/cmd/tui/context/theme.tsx +1236 -0
- package/src/cli/cmd/tui/context/tui-config.tsx +9 -0
- package/src/cli/cmd/tui/event.ts +49 -0
- package/src/cli/cmd/tui/feature-plugins/home/footer.tsx +93 -0
- package/src/cli/cmd/tui/feature-plugins/home/tips-view.tsx +155 -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 +270 -0
- package/src/cli/cmd/tui/plugin/api.tsx +397 -0
- package/src/cli/cmd/tui/plugin/index.ts +3 -0
- package/src/cli/cmd/tui/plugin/internal.ts +27 -0
- package/src/cli/cmd/tui/plugin/runtime.ts +1031 -0
- package/src/cli/cmd/tui/plugin/slots.tsx +60 -0
- package/src/cli/cmd/tui/routes/home.tsx +84 -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 +26 -0
- package/src/cli/cmd/tui/routes/session/dialog-timeline.tsx +47 -0
- package/src/cli/cmd/tui/routes/session/footer.tsx +91 -0
- package/src/cli/cmd/tui/routes/session/index.tsx +2281 -0
- package/src/cli/cmd/tui/routes/session/permission.tsx +691 -0
- package/src/cli/cmd/tui/routes/session/question.tsx +468 -0
- package/src/cli/cmd/tui/routes/session/sidebar.tsx +74 -0
- package/src/cli/cmd/tui/routes/session/subagent-footer.tsx +131 -0
- package/src/cli/cmd/tui/thread.ts +241 -0
- package/src/cli/cmd/tui/ui/dialog-alert.tsx +59 -0
- package/src/cli/cmd/tui/ui/dialog-confirm.tsx +89 -0
- package/src/cli/cmd/tui/ui/dialog-export-options.tsx +211 -0
- package/src/cli/cmd/tui/ui/dialog-help.tsx +40 -0
- package/src/cli/cmd/tui/ui/dialog-prompt.tsx +115 -0
- package/src/cli/cmd/tui/ui/dialog-select.tsx +417 -0
- package/src/cli/cmd/tui/ui/dialog.tsx +192 -0
- package/src/cli/cmd/tui/ui/link.tsx +28 -0
- package/src/cli/cmd/tui/ui/spinner.ts +368 -0
- package/src/cli/cmd/tui/ui/toast.tsx +100 -0
- package/src/cli/cmd/tui/util/clipboard.ts +192 -0
- package/src/cli/cmd/tui/util/editor.ts +37 -0
- package/src/cli/cmd/tui/util/model.ts +23 -0
- package/src/cli/cmd/tui/util/provider-origin.ts +7 -0
- package/src/cli/cmd/tui/util/scroll.ts +23 -0
- package/src/cli/cmd/tui/util/selection.ts +25 -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 +112 -0
- package/src/cli/cmd/tui/win32.ts +129 -0
- package/src/cli/cmd/tui/worker.ts +195 -0
- package/src/cli/cmd/uninstall.ts +353 -0
- package/src/cli/cmd/upgrade.ts +73 -0
- package/src/cli/cmd/web.ts +83 -0
- package/src/cli/commands.ts +58 -0
- package/src/cli/effect/prompt.ts +25 -0
- package/src/cli/error.ts +50 -0
- package/src/cli/heap.ts +59 -0
- package/src/cli/llm-ready.ts +22 -0
- package/src/cli/logo.ts +8 -0
- package/src/cli/network.ts +60 -0
- package/src/cli/ui.ts +132 -0
- package/src/cli/upgrade.ts +31 -0
- package/src/command/index.ts +195 -0
- package/src/command/template/initialize.txt +66 -0
- package/src/command/template/review.txt +101 -0
- package/src/config/config.ts +1659 -0
- package/src/config/console-state.ts +15 -0
- package/src/config/markdown.ts +99 -0
- package/src/config/paths.ts +167 -0
- package/src/config/tui-migrate.ts +156 -0
- package/src/config/tui-schema.ts +37 -0
- package/src/config/tui.ts +179 -0
- package/src/control-plane/adaptors/index.ts +23 -0
- package/src/control-plane/adaptors/remote-acp.ts +35 -0
- package/src/control-plane/adaptors/remote-http.ts +35 -0
- package/src/control-plane/adaptors/worktree.ts +42 -0
- package/src/control-plane/schema.ts +17 -0
- package/src/control-plane/sse.ts +66 -0
- package/src/control-plane/types.ts +32 -0
- package/src/control-plane/workspace.sql.ts +17 -0
- package/src/control-plane/workspace.ts +169 -0
- package/src/effect/cross-spawn-spawner.ts +502 -0
- package/src/effect/instance-ref.ts +6 -0
- package/src/effect/instance-registry.ts +12 -0
- package/src/effect/instance-state.ts +82 -0
- package/src/effect/oltp.ts +34 -0
- package/src/effect/run-service.ts +34 -0
- package/src/effect/runner.ts +216 -0
- package/src/env/index.ts +28 -0
- package/src/file/ignore.ts +82 -0
- package/src/file/index.ts +686 -0
- package/src/file/protected.ts +59 -0
- package/src/file/ripgrep.ts +376 -0
- package/src/file/time.ts +133 -0
- package/src/file/watcher.ts +171 -0
- package/src/filesystem/index.ts +236 -0
- package/src/flag/flag.ts +171 -0
- package/src/format/formatter.ts +413 -0
- package/src/format/index.ts +203 -0
- package/src/git/index.ts +303 -0
- package/src/global/index.ts +54 -0
- package/src/id/id.ts +85 -0
- package/src/ide/index.ts +74 -0
- package/src/index.ts +202 -0
- package/src/installation/index.ts +356 -0
- package/src/installation/meta.ts +7 -0
- package/src/lsp/client.ts +252 -0
- package/src/lsp/index.ts +558 -0
- package/src/lsp/language.ts +120 -0
- package/src/lsp/launch.ts +21 -0
- package/src/lsp/server.ts +1968 -0
- package/src/mcp/auth.ts +173 -0
- package/src/mcp/index.ts +921 -0
- package/src/mcp/oauth-callback.ts +216 -0
- package/src/mcp/oauth-provider.ts +186 -0
- package/src/node.ts +6 -0
- package/src/npm/index.ts +188 -0
- package/src/patch/index.ts +680 -0
- package/src/permission/arity.ts +163 -0
- package/src/permission/evaluate.ts +15 -0
- package/src/permission/index.ts +325 -0
- package/src/permission/schema.ts +17 -0
- package/src/plugin/cloudflare.ts +67 -0
- package/src/plugin/codex.ts +608 -0
- package/src/plugin/github-copilot/copilot.ts +361 -0
- package/src/plugin/github-copilot/models.ts +144 -0
- package/src/plugin/index.ts +293 -0
- package/src/plugin/install.ts +439 -0
- package/src/plugin/loader.ts +174 -0
- package/src/plugin/meta.ts +188 -0
- package/src/plugin/shared.ts +323 -0
- package/src/project/bootstrap.ts +31 -0
- package/src/project/instance.ts +175 -0
- package/src/project/project.sql.ts +16 -0
- package/src/project/project.ts +519 -0
- package/src/project/schema.ts +16 -0
- package/src/project/state.ts +70 -0
- package/src/project/vcs.ts +254 -0
- package/src/provider/auth.ts +253 -0
- package/src/provider/error.ts +197 -0
- package/src/provider/models.ts +159 -0
- package/src/provider/provider.ts +1748 -0
- package/src/provider/schema.ts +38 -0
- package/src/provider/sdk/copilot/README.md +5 -0
- package/src/provider/sdk/copilot/chat/convert-to-openai-compatible-chat-messages.ts +170 -0
- package/src/provider/sdk/copilot/chat/get-response-metadata.ts +15 -0
- package/src/provider/sdk/copilot/chat/map-openai-compatible-finish-reason.ts +19 -0
- package/src/provider/sdk/copilot/chat/openai-compatible-api-types.ts +64 -0
- package/src/provider/sdk/copilot/chat/openai-compatible-chat-language-model.ts +815 -0
- package/src/provider/sdk/copilot/chat/openai-compatible-chat-options.ts +28 -0
- package/src/provider/sdk/copilot/chat/openai-compatible-metadata-extractor.ts +44 -0
- package/src/provider/sdk/copilot/chat/openai-compatible-prepare-tools.ts +83 -0
- package/src/provider/sdk/copilot/copilot-provider.ts +100 -0
- package/src/provider/sdk/copilot/index.ts +2 -0
- package/src/provider/sdk/copilot/openai-compatible-error.ts +27 -0
- package/src/provider/sdk/copilot/responses/convert-to-openai-responses-input.ts +335 -0
- package/src/provider/sdk/copilot/responses/map-openai-responses-finish-reason.ts +22 -0
- package/src/provider/sdk/copilot/responses/openai-config.ts +18 -0
- package/src/provider/sdk/copilot/responses/openai-error.ts +22 -0
- package/src/provider/sdk/copilot/responses/openai-responses-api-types.ts +214 -0
- package/src/provider/sdk/copilot/responses/openai-responses-language-model.ts +1769 -0
- package/src/provider/sdk/copilot/responses/openai-responses-prepare-tools.ts +173 -0
- package/src/provider/sdk/copilot/responses/openai-responses-settings.ts +1 -0
- package/src/provider/sdk/copilot/responses/tool/code-interpreter.ts +87 -0
- package/src/provider/sdk/copilot/responses/tool/file-search.ts +127 -0
- package/src/provider/sdk/copilot/responses/tool/image-generation.ts +114 -0
- package/src/provider/sdk/copilot/responses/tool/local-shell.ts +64 -0
- package/src/provider/sdk/copilot/responses/tool/web-search-preview.ts +103 -0
- package/src/provider/sdk/copilot/responses/tool/web-search.ts +102 -0
- package/src/provider/transform.ts +1051 -0
- package/src/pty/index.ts +397 -0
- package/src/pty/pty.bun.ts +26 -0
- package/src/pty/pty.node.ts +27 -0
- package/src/pty/pty.ts +25 -0
- package/src/pty/schema.ts +17 -0
- package/src/question/index.ts +224 -0
- package/src/question/schema.ts +17 -0
- package/src/runtime/adapters/acp/index.ts +127 -0
- package/src/runtime/adapters/local/index.ts +6 -0
- package/src/runtime/core/agent.ts +13 -0
- package/src/runtime/core/mcp.ts +10 -0
- package/src/runtime/core/ports.ts +16 -0
- package/src/runtime/core/service.ts +19 -0
- package/src/runtime/core/session-summarize.ts +52 -0
- package/src/runtime/core/session.ts +110 -0
- package/src/runtime/core/skill.ts +10 -0
- package/src/runtime/core/transport.ts +10 -0
- package/src/runtime/factory.ts +20 -0
- package/src/runtime/ports.ts +74 -0
- package/src/server/error.ts +36 -0
- package/src/server/event.ts +7 -0
- package/src/server/instance.ts +322 -0
- package/src/server/mdns.ts +60 -0
- package/src/server/middleware.ts +33 -0
- package/src/server/projectors.ts +28 -0
- package/src/server/proxy.ts +134 -0
- package/src/server/router.ts +161 -0
- package/src/server/routes/config.ts +92 -0
- package/src/server/routes/event.ts +83 -0
- package/src/server/routes/experimental.ts +379 -0
- package/src/server/routes/file.ts +197 -0
- package/src/server/routes/global.ts +312 -0
- package/src/server/routes/mcp.ts +226 -0
- package/src/server/routes/permission.ts +69 -0
- package/src/server/routes/project.ts +118 -0
- package/src/server/routes/provider.ts +171 -0
- package/src/server/routes/pty.ts +210 -0
- package/src/server/routes/question.ts +99 -0
- package/src/server/routes/session.ts +1011 -0
- package/src/server/routes/tui.ts +379 -0
- package/src/server/routes/workspace.ts +94 -0
- package/src/server/server.ts +367 -0
- package/src/session/compaction.ts +425 -0
- package/src/session/index.ts +887 -0
- package/src/session/instruction.ts +258 -0
- package/src/session/llm.ts +412 -0
- package/src/session/message-v2.ts +1038 -0
- package/src/session/message.ts +191 -0
- package/src/session/overflow.ts +22 -0
- package/src/session/processor.ts +515 -0
- package/src/session/projectors.ts +135 -0
- package/src/session/prompt/anthropic.txt +105 -0
- package/src/session/prompt/beast.txt +147 -0
- package/src/session/prompt/build-switch.txt +5 -0
- package/src/session/prompt/codex.txt +79 -0
- package/src/session/prompt/copilot-gpt-5.txt +143 -0
- package/src/session/prompt/default.txt +105 -0
- package/src/session/prompt/gemini.txt +155 -0
- package/src/session/prompt/gpt.txt +107 -0
- package/src/session/prompt/kimi.txt +95 -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 +26 -0
- package/src/session/prompt/trinity.txt +97 -0
- package/src/session/prompt.ts +1908 -0
- package/src/session/retry.ts +123 -0
- package/src/session/revert.ts +176 -0
- package/src/session/schema.ts +38 -0
- package/src/session/session.sql.ts +103 -0
- package/src/session/status.ts +102 -0
- package/src/session/summary.ts +177 -0
- package/src/session/system.ts +76 -0
- package/src/session/todo.ts +95 -0
- package/src/share/share-next.ts +370 -0
- package/src/share/share.sql.ts +13 -0
- package/src/shell/shell.ts +110 -0
- package/src/skill/discovery.ts +116 -0
- package/src/skill/index.ts +289 -0
- package/src/snapshot/index.ts +723 -0
- package/src/sql.d.ts +4 -0
- package/src/storage/db.bun.ts +8 -0
- package/src/storage/db.node.ts +8 -0
- package/src/storage/db.ts +174 -0
- package/src/storage/json-migration.ts +425 -0
- package/src/storage/schema.sql.ts +10 -0
- package/src/storage/schema.ts +5 -0
- package/src/storage/storage.ts +353 -0
- package/src/sync/README.md +179 -0
- package/src/sync/event.sql.ts +16 -0
- package/src/sync/index.ts +263 -0
- package/src/sync/schema.ts +14 -0
- package/src/testing/llm-server.ts +2 -0
- package/src/tool/apply_patch.ts +279 -0
- package/src/tool/apply_patch.txt +33 -0
- package/src/tool/bash.ts +498 -0
- package/src/tool/bash.txt +117 -0
- package/src/tool/codesearch.ts +133 -0
- package/src/tool/codesearch.txt +12 -0
- package/src/tool/edit.ts +666 -0
- package/src/tool/edit.txt +10 -0
- package/src/tool/external-directory.ts +46 -0
- package/src/tool/glob.ts +78 -0
- package/src/tool/glob.txt +6 -0
- package/src/tool/grep.ts +156 -0
- package/src/tool/grep.txt +8 -0
- package/src/tool/invalid.ts +17 -0
- package/src/tool/ls.ts +121 -0
- package/src/tool/ls.txt +1 -0
- package/src/tool/lsp.ts +97 -0
- package/src/tool/lsp.txt +19 -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 +131 -0
- package/src/tool/question.ts +46 -0
- package/src/tool/question.txt +10 -0
- package/src/tool/read.ts +330 -0
- package/src/tool/read.txt +14 -0
- package/src/tool/registry.ts +303 -0
- package/src/tool/schema.ts +17 -0
- package/src/tool/skill.ts +120 -0
- package/src/tool/task.ts +192 -0
- package/src/tool/task.txt +57 -0
- package/src/tool/todo.ts +48 -0
- package/src/tool/todowrite.txt +167 -0
- package/src/tool/tool.ts +137 -0
- package/src/tool/truncate.ts +144 -0
- package/src/tool/truncation-dir.ts +4 -0
- package/src/tool/webfetch.ts +210 -0
- package/src/tool/webfetch.txt +13 -0
- package/src/tool/websearch.ts +151 -0
- package/src/tool/websearch.txt +14 -0
- package/src/tool/write.ts +84 -0
- package/src/tool/write.txt +8 -0
- package/src/url/site.ts +118 -0
- package/src/util/abort.ts +35 -0
- package/src/util/archive.ts +17 -0
- package/src/util/color.ts +19 -0
- package/src/util/context.ts +25 -0
- package/src/util/data-url.ts +9 -0
- package/src/util/defer.ts +12 -0
- package/src/util/effect-http-client.ts +11 -0
- package/src/util/effect-zod.ts +98 -0
- package/src/util/error.ts +77 -0
- package/src/util/filesystem.ts +245 -0
- package/src/util/flock.ts +333 -0
- package/src/util/fn.ts +21 -0
- package/src/util/format.ts +20 -0
- package/src/util/glob.ts +34 -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 +23 -0
- package/src/util/locale.ts +81 -0
- package/src/util/lock.ts +98 -0
- package/src/util/log.ts +182 -0
- package/src/util/network.ts +9 -0
- package/src/util/process.ts +176 -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/schema.ts +53 -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/update-schema.ts +13 -0
- package/src/util/which.ts +14 -0
- package/src/util/wildcard.ts +59 -0
- package/src/worktree/index.ts +612 -0
- package/sst-env.d.ts +10 -0
- package/test/AGENTS.md +81 -0
- package/test/account/repo.test.ts +352 -0
- package/test/account/service.test.ts +456 -0
- package/test/acp/agent-interface.test.ts +51 -0
- package/test/acp/event-subscription.test.ts +685 -0
- package/test/agent/agent.test.ts +717 -0
- package/test/auth/auth.test.ts +58 -0
- package/test/bus/bus-effect.test.ts +164 -0
- package/test/bus/bus-integration.test.ts +87 -0
- package/test/bus/bus.test.ts +219 -0
- package/test/cli/account.test.ts +26 -0
- package/test/cli/cmd/tui/prompt-part.test.ts +47 -0
- package/test/cli/commands.test.ts +49 -0
- package/test/cli/error.test.ts +18 -0
- package/test/cli/github-action.test.ts +198 -0
- package/test/cli/github-remote.test.ts +80 -0
- package/test/cli/import.test.ts +54 -0
- package/test/cli/llm-ready.test.ts +49 -0
- package/test/cli/plugin-auth-picker.test.ts +120 -0
- package/test/cli/tui/keybind-plugin.test.ts +90 -0
- package/test/cli/tui/plugin-add.test.ts +107 -0
- package/test/cli/tui/plugin-install.test.ts +89 -0
- package/test/cli/tui/plugin-lifecycle.test.ts +225 -0
- package/test/cli/tui/plugin-loader-entrypoint.test.ts +492 -0
- package/test/cli/tui/plugin-loader-pure.test.ts +72 -0
- package/test/cli/tui/plugin-loader.test.ts +752 -0
- package/test/cli/tui/plugin-toggle.test.ts +159 -0
- package/test/cli/tui/slot-replace.test.tsx +47 -0
- package/test/cli/tui/theme-store.test.ts +51 -0
- package/test/cli/tui/thread.test.ts +128 -0
- package/test/cli/tui/transcript.test.ts +426 -0
- package/test/config/agent-color.test.ts +71 -0
- package/test/config/config.test.ts +2364 -0
- package/test/config/fixtures/empty-frontmatter.md +4 -0
- package/test/config/fixtures/frontmatter.md +28 -0
- package/test/config/fixtures/markdown-header.md +11 -0
- package/test/config/fixtures/no-frontmatter.md +1 -0
- package/test/config/fixtures/weird-model-id.md +13 -0
- package/test/config/markdown.test.ts +228 -0
- package/test/config/tui.test.ts +800 -0
- package/test/control-plane/sse.test.ts +56 -0
- package/test/effect/cross-spawn-spawner.test.ts +412 -0
- package/test/effect/instance-state.test.ts +482 -0
- package/test/effect/run-service.test.ts +46 -0
- package/test/effect/runner.test.ts +523 -0
- package/test/fake/provider.ts +81 -0
- package/test/file/fsmonitor.test.ts +62 -0
- package/test/file/ignore.test.ts +10 -0
- package/test/file/index.test.ts +946 -0
- package/test/file/path-traversal.test.ts +198 -0
- package/test/file/ripgrep.test.ts +54 -0
- package/test/file/time.test.ts +445 -0
- package/test/file/watcher.test.ts +247 -0
- package/test/filesystem/filesystem.test.ts +319 -0
- package/test/fixture/db.ts +11 -0
- package/test/fixture/fixture.test.ts +26 -0
- package/test/fixture/fixture.ts +174 -0
- package/test/fixture/flock-worker.ts +72 -0
- package/test/fixture/lsp/fake-lsp-server.js +77 -0
- package/test/fixture/plug-worker.ts +93 -0
- package/test/fixture/plugin-meta-worker.ts +26 -0
- package/test/fixture/skills/agents-sdk/SKILL.md +152 -0
- package/test/fixture/skills/agents-sdk/references/callable.md +92 -0
- package/test/fixture/skills/cloudflare/SKILL.md +211 -0
- package/test/fixture/skills/index.json +6 -0
- package/test/fixture/tui-plugin.ts +328 -0
- package/test/fixture/tui-runtime.ts +27 -0
- package/test/format/format.test.ts +171 -0
- package/test/git/git.test.ts +128 -0
- package/test/ide/ide.test.ts +82 -0
- package/test/installation/installation.test.ts +151 -0
- package/test/keybind.test.ts +421 -0
- package/test/lib/effect.ts +53 -0
- package/test/lib/filesystem.ts +10 -0
- package/test/lib/llm-server.ts +795 -0
- package/test/lsp/client.test.ts +95 -0
- package/test/lsp/index.test.ts +138 -0
- package/test/lsp/launch.test.ts +22 -0
- package/test/lsp/lifecycle.test.ts +147 -0
- package/test/mcp/headers.test.ts +153 -0
- package/test/mcp/lifecycle.test.ts +750 -0
- package/test/mcp/oauth-auto-connect.test.ts +199 -0
- package/test/mcp/oauth-browser.test.ts +249 -0
- package/test/memory/abort-leak.test.ts +151 -0
- package/test/npm.test.ts +18 -0
- package/test/patch/patch.test.ts +348 -0
- package/test/permission/arity.test.ts +33 -0
- package/test/permission/next.test.ts +1148 -0
- package/test/permission-task.test.ts +323 -0
- package/test/plugin/auth-override.test.ts +74 -0
- package/test/plugin/codex.test.ts +123 -0
- package/test/plugin/github-copilot-models.test.ts +117 -0
- package/test/plugin/install-concurrency.test.ts +140 -0
- package/test/plugin/install.test.ts +570 -0
- package/test/plugin/loader-shared.test.ts +1136 -0
- package/test/plugin/meta.test.ts +137 -0
- package/test/plugin/shared.test.ts +88 -0
- package/test/plugin/trigger.test.ts +111 -0
- package/test/preload.ts +90 -0
- package/test/project/migrate-global.test.ts +141 -0
- package/test/project/project.test.ts +459 -0
- package/test/project/state.test.ts +115 -0
- package/test/project/vcs.test.ts +228 -0
- package/test/project/worktree-remove.test.ts +96 -0
- package/test/project/worktree.test.ts +173 -0
- package/test/provider/amazon-bedrock.test.ts +447 -0
- package/test/provider/copilot/convert-to-copilot-messages.test.ts +523 -0
- package/test/provider/copilot/copilot-chat-model.test.ts +592 -0
- package/test/provider/gitlab-duo.test.ts +412 -0
- package/test/provider/provider.test.ts +2494 -0
- package/test/provider/transform.test.ts +2839 -0
- package/test/pty/pty-output-isolation.test.ts +141 -0
- package/test/pty/pty-session.test.ts +92 -0
- package/test/pty/pty-shell.test.ts +59 -0
- package/test/question/question.test.ts +453 -0
- package/test/runtime/acp-adapter.test.ts +84 -0
- package/test/runtime/core-service.test.ts +16 -0
- package/test/runtime/session-summarize.test.ts +104 -0
- package/test/server/global-session-list.test.ts +89 -0
- package/test/server/project-init-git.test.ts +121 -0
- package/test/server/router.test.ts +52 -0
- package/test/server/session-actions.test.ts +83 -0
- package/test/server/session-list.test.ts +98 -0
- package/test/server/session-messages.test.ts +159 -0
- package/test/server/session-select.test.ts +84 -0
- package/test/session/compaction.test.ts +1239 -0
- package/test/session/instruction.test.ts +286 -0
- package/test/session/llm.test.ts +1093 -0
- package/test/session/message-v2.test.ts +957 -0
- package/test/session/messages-pagination.test.ts +885 -0
- package/test/session/processor-effect.test.ts +741 -0
- package/test/session/prompt-effect.test.ts +1339 -0
- package/test/session/prompt.test.ts +533 -0
- package/test/session/retry.test.ts +251 -0
- package/test/session/revert-compact.test.ts +621 -0
- package/test/session/session.test.ts +142 -0
- package/test/session/snapshot-tool-race.test.ts +242 -0
- package/test/session/structured-output-integration.test.ts +233 -0
- package/test/session/structured-output.test.ts +391 -0
- package/test/session/system.test.ts +59 -0
- package/test/share/share-next.test.ts +332 -0
- package/test/shell/shell.test.ts +73 -0
- package/test/skill/discovery.test.ts +116 -0
- package/test/skill/skill.test.ts +428 -0
- package/test/snapshot/snapshot.test.ts +1397 -0
- package/test/storage/db.test.ts +14 -0
- package/test/storage/json-migration.test.ts +832 -0
- package/test/storage/storage.test.ts +295 -0
- package/test/sync/index.test.ts +191 -0
- package/test/tool/apply_patch.test.ts +565 -0
- package/test/tool/bash.test.ts +1099 -0
- package/test/tool/edit.test.ts +681 -0
- package/test/tool/external-directory.test.ts +198 -0
- package/test/tool/fixtures/large-image.png +0 -0
- package/test/tool/fixtures/models-api.json +65179 -0
- package/test/tool/grep.test.ts +111 -0
- package/test/tool/question.test.ts +126 -0
- package/test/tool/read.test.ts +468 -0
- package/test/tool/registry.test.ts +157 -0
- package/test/tool/skill.test.ts +170 -0
- package/test/tool/task.test.ts +412 -0
- package/test/tool/tool-define.test.ts +49 -0
- package/test/tool/truncation.test.ts +161 -0
- package/test/tool/webfetch.test.ts +96 -0
- package/test/tool/write.test.ts +353 -0
- package/test/util/data-url.test.ts +14 -0
- package/test/util/effect-zod.test.ts +61 -0
- package/test/util/error.test.ts +38 -0
- package/test/util/filesystem.test.ts +656 -0
- package/test/util/flock.test.ts +383 -0
- package/test/util/format.test.ts +59 -0
- package/test/util/glob.test.ts +164 -0
- package/test/util/iife.test.ts +36 -0
- package/test/util/lazy.test.ts +50 -0
- package/test/util/lock.test.ts +72 -0
- package/test/util/module.test.ts +59 -0
- package/test/util/process.test.ts +128 -0
- package/test/util/timeout.test.ts +21 -0
- package/test/util/which.test.ts +100 -0
- package/test/util/wildcard.test.ts +90 -0
- package/tsconfig.json +23 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
You are a title generator. You output ONLY a thread title. Nothing else.
|
|
2
|
+
|
|
3
|
+
<task>
|
|
4
|
+
Generate a brief title that would help the user find this conversation later.
|
|
5
|
+
|
|
6
|
+
Follow all rules in <rules>
|
|
7
|
+
Use the <examples> so you know what a good title looks like.
|
|
8
|
+
Your output must be:
|
|
9
|
+
- A single line
|
|
10
|
+
- ≤50 characters
|
|
11
|
+
- No explanations
|
|
12
|
+
</task>
|
|
13
|
+
|
|
14
|
+
<rules>
|
|
15
|
+
- you MUST use the same language as the user message you are summarizing
|
|
16
|
+
- Title must be grammatically correct and read naturally - no word salad
|
|
17
|
+
- Never include tool names in the title (e.g. "read tool", "bash tool", "edit tool")
|
|
18
|
+
- Focus on the main topic or question the user needs to retrieve
|
|
19
|
+
- Vary your phrasing - avoid repetitive patterns like always starting with "Analyzing"
|
|
20
|
+
- When a file is mentioned, focus on WHAT the user wants to do WITH the file, not just that they shared it
|
|
21
|
+
- Keep exact: technical terms, numbers, filenames, HTTP codes
|
|
22
|
+
- Remove: the, this, my, a, an
|
|
23
|
+
- Never assume tech stack
|
|
24
|
+
- Never use tools
|
|
25
|
+
- NEVER respond to questions, just generate a title for the conversation
|
|
26
|
+
- The title should NEVER include "summarizing" or "generating" when generating a title
|
|
27
|
+
- DO NOT SAY YOU CANNOT GENERATE A TITLE OR COMPLAIN ABOUT THE INPUT
|
|
28
|
+
- Always output something meaningful, even if the input is minimal.
|
|
29
|
+
- If the user message is short or conversational (e.g. "hello", "lol", "what's up", "hey"):
|
|
30
|
+
→ create a title that reflects the user's tone or intent (such as Greeting, Quick check-in, Light chat, Intro message, etc.)
|
|
31
|
+
</rules>
|
|
32
|
+
|
|
33
|
+
<examples>
|
|
34
|
+
"debug 500 errors in production" → Debugging production 500 errors
|
|
35
|
+
"refactor user service" → Refactoring user service
|
|
36
|
+
"why is app.js failing" → app.js failure investigation
|
|
37
|
+
"implement rate limiting" → Rate limiting implementation
|
|
38
|
+
"how do I connect postgres to my API" → Postgres API connection
|
|
39
|
+
"best practices for React hooks" → React hooks best practices
|
|
40
|
+
"@src/auth.ts can you add refresh token support" → Auth refresh token support
|
|
41
|
+
"@utils/parser.ts this is broken" → Parser bug fix
|
|
42
|
+
"look at @config.json" → Config review
|
|
43
|
+
"@App.tsx add dark mode toggle" → Dark mode toggle in App
|
|
44
|
+
</examples>
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import path from "path"
|
|
2
|
+
import { Effect, Layer, Record, Result, Schema, ServiceMap } from "effect"
|
|
3
|
+
import { makeRuntime } from "@/effect/run-service"
|
|
4
|
+
import { zod } from "@/util/effect-zod"
|
|
5
|
+
import { Global } from "../global"
|
|
6
|
+
import { AppFileSystem } from "../filesystem"
|
|
7
|
+
|
|
8
|
+
export const OAUTH_DUMMY_KEY = "iroder-oauth-dummy-key"
|
|
9
|
+
|
|
10
|
+
const file = path.join(Global.Path.data, "auth.json")
|
|
11
|
+
|
|
12
|
+
const fail = (message: string) => (cause: unknown) => new Auth.AuthError({ message, cause })
|
|
13
|
+
|
|
14
|
+
export namespace Auth {
|
|
15
|
+
export class Oauth extends Schema.Class<Oauth>("OAuth")({
|
|
16
|
+
type: Schema.Literal("oauth"),
|
|
17
|
+
refresh: Schema.String,
|
|
18
|
+
access: Schema.String,
|
|
19
|
+
expires: Schema.Number,
|
|
20
|
+
accountId: Schema.optional(Schema.String),
|
|
21
|
+
enterpriseUrl: Schema.optional(Schema.String),
|
|
22
|
+
}) {}
|
|
23
|
+
|
|
24
|
+
export class Api extends Schema.Class<Api>("ApiAuth")({
|
|
25
|
+
type: Schema.Literal("api"),
|
|
26
|
+
key: Schema.String,
|
|
27
|
+
metadata: Schema.optional(Schema.Record(Schema.String, Schema.String)),
|
|
28
|
+
}) {}
|
|
29
|
+
|
|
30
|
+
export class WellKnown extends Schema.Class<WellKnown>("WellKnownAuth")({
|
|
31
|
+
type: Schema.Literal("wellknown"),
|
|
32
|
+
key: Schema.String,
|
|
33
|
+
token: Schema.String,
|
|
34
|
+
}) {}
|
|
35
|
+
|
|
36
|
+
const _Info = Schema.Union([Oauth, Api, WellKnown]).annotate({ discriminator: "type", identifier: "Auth" })
|
|
37
|
+
export const Info = Object.assign(_Info, { zod: zod(_Info) })
|
|
38
|
+
export type Info = Schema.Schema.Type<typeof _Info>
|
|
39
|
+
|
|
40
|
+
export class AuthError extends Schema.TaggedErrorClass<AuthError>()("AuthError", {
|
|
41
|
+
message: Schema.String,
|
|
42
|
+
cause: Schema.optional(Schema.Defect),
|
|
43
|
+
}) {}
|
|
44
|
+
|
|
45
|
+
export interface Interface {
|
|
46
|
+
readonly get: (providerID: string) => Effect.Effect<Info | undefined, AuthError>
|
|
47
|
+
readonly all: () => Effect.Effect<Record<string, Info>, AuthError>
|
|
48
|
+
readonly set: (key: string, info: Info) => Effect.Effect<void, AuthError>
|
|
49
|
+
readonly remove: (key: string) => Effect.Effect<void, AuthError>
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export class Service extends ServiceMap.Service<Service, Interface>()("@iroder/Auth") {}
|
|
53
|
+
|
|
54
|
+
export const layer = Layer.effect(
|
|
55
|
+
Service,
|
|
56
|
+
Effect.gen(function* () {
|
|
57
|
+
const fsys = yield* AppFileSystem.Service
|
|
58
|
+
const decode = Schema.decodeUnknownOption(Info)
|
|
59
|
+
|
|
60
|
+
const all = Effect.fn("Auth.all")(function* () {
|
|
61
|
+
const data = (yield* fsys.readJson(file).pipe(Effect.orElseSucceed(() => ({})))) as Record<string, unknown>
|
|
62
|
+
return Record.filterMap(data, (value) => Result.fromOption(decode(value), () => undefined))
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
const get = Effect.fn("Auth.get")(function* (providerID: string) {
|
|
66
|
+
return (yield* all())[providerID]
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
const set = Effect.fn("Auth.set")(function* (key: string, info: Info) {
|
|
70
|
+
const norm = key.replace(/\/+$/, "")
|
|
71
|
+
const data = yield* all()
|
|
72
|
+
if (norm !== key) delete data[key]
|
|
73
|
+
delete data[norm + "/"]
|
|
74
|
+
yield* fsys
|
|
75
|
+
.writeJson(file, { ...data, [norm]: info }, 0o600)
|
|
76
|
+
.pipe(Effect.mapError(fail("Failed to write auth data")))
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
const remove = Effect.fn("Auth.remove")(function* (key: string) {
|
|
80
|
+
const norm = key.replace(/\/+$/, "")
|
|
81
|
+
const data = yield* all()
|
|
82
|
+
delete data[key]
|
|
83
|
+
delete data[norm]
|
|
84
|
+
yield* fsys.writeJson(file, data, 0o600).pipe(Effect.mapError(fail("Failed to write auth data")))
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
return Service.of({ get, all, set, remove })
|
|
88
|
+
}),
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
export const defaultLayer = layer.pipe(Layer.provide(AppFileSystem.defaultLayer))
|
|
92
|
+
|
|
93
|
+
const { runPromise } = makeRuntime(Service, defaultLayer)
|
|
94
|
+
|
|
95
|
+
export async function get(providerID: string) {
|
|
96
|
+
return runPromise((service) => service.get(providerID))
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export async function all(): Promise<Record<string, Info>> {
|
|
100
|
+
return runPromise((service) => service.all())
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export async function set(key: string, info: Info) {
|
|
104
|
+
return runPromise((service) => service.set(key, info))
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export async function remove(key: string) {
|
|
108
|
+
return runPromise((service) => service.remove(key))
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import z from "zod"
|
|
2
|
+
import type { ZodType } from "zod"
|
|
3
|
+
|
|
4
|
+
export namespace BusEvent {
|
|
5
|
+
export type Definition = ReturnType<typeof define>
|
|
6
|
+
|
|
7
|
+
const registry = new Map<string, Definition>()
|
|
8
|
+
|
|
9
|
+
export function define<Type extends string, Properties extends ZodType>(type: Type, properties: Properties) {
|
|
10
|
+
const result = {
|
|
11
|
+
type,
|
|
12
|
+
properties,
|
|
13
|
+
}
|
|
14
|
+
registry.set(type, result)
|
|
15
|
+
return result
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function payloads() {
|
|
19
|
+
return z
|
|
20
|
+
.discriminatedUnion(
|
|
21
|
+
"type",
|
|
22
|
+
registry
|
|
23
|
+
.entries()
|
|
24
|
+
.map(([type, def]) => {
|
|
25
|
+
return z
|
|
26
|
+
.object({
|
|
27
|
+
type: z.literal(type),
|
|
28
|
+
properties: def.properties,
|
|
29
|
+
})
|
|
30
|
+
.meta({
|
|
31
|
+
ref: "Event" + "." + def.type,
|
|
32
|
+
})
|
|
33
|
+
})
|
|
34
|
+
.toArray() as any,
|
|
35
|
+
)
|
|
36
|
+
.meta({
|
|
37
|
+
ref: "Event",
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
}
|
package/src/bus/index.ts
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import z from "zod"
|
|
2
|
+
import { Effect, Exit, Layer, PubSub, Scope, ServiceMap, Stream } from "effect"
|
|
3
|
+
import { Log } from "../util/log"
|
|
4
|
+
import { Instance } from "../project/instance"
|
|
5
|
+
import { BusEvent } from "./bus-event"
|
|
6
|
+
import { GlobalBus } from "./global"
|
|
7
|
+
import { InstanceState } from "@/effect/instance-state"
|
|
8
|
+
import { makeRuntime } from "@/effect/run-service"
|
|
9
|
+
|
|
10
|
+
export namespace Bus {
|
|
11
|
+
const log = Log.create({ service: "bus" })
|
|
12
|
+
|
|
13
|
+
export const InstanceDisposed = BusEvent.define(
|
|
14
|
+
"server.instance.disposed",
|
|
15
|
+
z.object({
|
|
16
|
+
directory: z.string(),
|
|
17
|
+
}),
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
type Payload<D extends BusEvent.Definition = BusEvent.Definition> = {
|
|
21
|
+
type: D["type"]
|
|
22
|
+
properties: z.infer<D["properties"]>
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
type State = {
|
|
26
|
+
wildcard: PubSub.PubSub<Payload>
|
|
27
|
+
typed: Map<string, PubSub.PubSub<Payload>>
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface Interface {
|
|
31
|
+
readonly publish: <D extends BusEvent.Definition>(
|
|
32
|
+
def: D,
|
|
33
|
+
properties: z.output<D["properties"]>,
|
|
34
|
+
) => Effect.Effect<void>
|
|
35
|
+
readonly subscribe: <D extends BusEvent.Definition>(def: D) => Stream.Stream<Payload<D>>
|
|
36
|
+
readonly subscribeAll: () => Stream.Stream<Payload>
|
|
37
|
+
readonly subscribeCallback: <D extends BusEvent.Definition>(
|
|
38
|
+
def: D,
|
|
39
|
+
callback: (event: Payload<D>) => unknown,
|
|
40
|
+
) => Effect.Effect<() => void>
|
|
41
|
+
readonly subscribeAllCallback: (callback: (event: any) => unknown) => Effect.Effect<() => void>
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export class Service extends ServiceMap.Service<Service, Interface>()("@iroder/Bus") {}
|
|
45
|
+
|
|
46
|
+
export const layer = Layer.effect(
|
|
47
|
+
Service,
|
|
48
|
+
Effect.gen(function* () {
|
|
49
|
+
const state = yield* InstanceState.make<State>(
|
|
50
|
+
Effect.fn("Bus.state")(function* (ctx) {
|
|
51
|
+
const wildcard = yield* PubSub.unbounded<Payload>()
|
|
52
|
+
const typed = new Map<string, PubSub.PubSub<Payload>>()
|
|
53
|
+
|
|
54
|
+
yield* Effect.addFinalizer(() =>
|
|
55
|
+
Effect.gen(function* () {
|
|
56
|
+
// Publish InstanceDisposed before shutting down so subscribers see it
|
|
57
|
+
yield* PubSub.publish(wildcard, {
|
|
58
|
+
type: InstanceDisposed.type,
|
|
59
|
+
properties: { directory: ctx.directory },
|
|
60
|
+
})
|
|
61
|
+
yield* PubSub.shutdown(wildcard)
|
|
62
|
+
for (const ps of typed.values()) {
|
|
63
|
+
yield* PubSub.shutdown(ps)
|
|
64
|
+
}
|
|
65
|
+
}),
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
return { wildcard, typed }
|
|
69
|
+
}),
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
function getOrCreate<D extends BusEvent.Definition>(state: State, def: D) {
|
|
73
|
+
return Effect.gen(function* () {
|
|
74
|
+
let ps = state.typed.get(def.type)
|
|
75
|
+
if (!ps) {
|
|
76
|
+
ps = yield* PubSub.unbounded<Payload>()
|
|
77
|
+
state.typed.set(def.type, ps)
|
|
78
|
+
}
|
|
79
|
+
return ps as unknown as PubSub.PubSub<Payload<D>>
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function publish<D extends BusEvent.Definition>(def: D, properties: z.output<D["properties"]>) {
|
|
84
|
+
return Effect.gen(function* () {
|
|
85
|
+
const s = yield* InstanceState.get(state)
|
|
86
|
+
const payload: Payload = { type: def.type, properties }
|
|
87
|
+
log.info("publishing", { type: def.type })
|
|
88
|
+
|
|
89
|
+
const ps = s.typed.get(def.type)
|
|
90
|
+
if (ps) yield* PubSub.publish(ps, payload)
|
|
91
|
+
yield* PubSub.publish(s.wildcard, payload)
|
|
92
|
+
|
|
93
|
+
const dir = yield* InstanceState.directory
|
|
94
|
+
GlobalBus.emit("event", {
|
|
95
|
+
directory: dir,
|
|
96
|
+
payload,
|
|
97
|
+
})
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function subscribe<D extends BusEvent.Definition>(def: D): Stream.Stream<Payload<D>> {
|
|
102
|
+
log.info("subscribing", { type: def.type })
|
|
103
|
+
return Stream.unwrap(
|
|
104
|
+
Effect.gen(function* () {
|
|
105
|
+
const s = yield* InstanceState.get(state)
|
|
106
|
+
const ps = yield* getOrCreate(s, def)
|
|
107
|
+
return Stream.fromPubSub(ps)
|
|
108
|
+
}),
|
|
109
|
+
).pipe(Stream.ensuring(Effect.sync(() => log.info("unsubscribing", { type: def.type }))))
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function subscribeAll(): Stream.Stream<Payload> {
|
|
113
|
+
log.info("subscribing", { type: "*" })
|
|
114
|
+
return Stream.unwrap(
|
|
115
|
+
Effect.gen(function* () {
|
|
116
|
+
const s = yield* InstanceState.get(state)
|
|
117
|
+
return Stream.fromPubSub(s.wildcard)
|
|
118
|
+
}),
|
|
119
|
+
).pipe(Stream.ensuring(Effect.sync(() => log.info("unsubscribing", { type: "*" }))))
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function on<T>(pubsub: PubSub.PubSub<T>, type: string, callback: (event: T) => unknown) {
|
|
123
|
+
return Effect.gen(function* () {
|
|
124
|
+
log.info("subscribing", { type })
|
|
125
|
+
const scope = yield* Scope.make()
|
|
126
|
+
const subscription = yield* Scope.provide(scope)(PubSub.subscribe(pubsub))
|
|
127
|
+
|
|
128
|
+
yield* Scope.provide(scope)(
|
|
129
|
+
Stream.fromSubscription(subscription).pipe(
|
|
130
|
+
Stream.runForEach((msg) =>
|
|
131
|
+
Effect.tryPromise({
|
|
132
|
+
try: () => Promise.resolve().then(() => callback(msg)),
|
|
133
|
+
catch: (cause) => {
|
|
134
|
+
log.error("subscriber failed", { type, cause })
|
|
135
|
+
},
|
|
136
|
+
}).pipe(Effect.ignore),
|
|
137
|
+
),
|
|
138
|
+
Effect.forkScoped,
|
|
139
|
+
),
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
return () => {
|
|
143
|
+
log.info("unsubscribing", { type })
|
|
144
|
+
Effect.runFork(Scope.close(scope, Exit.void))
|
|
145
|
+
}
|
|
146
|
+
})
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const subscribeCallback = Effect.fn("Bus.subscribeCallback")(function* <D extends BusEvent.Definition>(
|
|
150
|
+
def: D,
|
|
151
|
+
callback: (event: Payload<D>) => unknown,
|
|
152
|
+
) {
|
|
153
|
+
const s = yield* InstanceState.get(state)
|
|
154
|
+
const ps = yield* getOrCreate(s, def)
|
|
155
|
+
return yield* on(ps, def.type, callback)
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
const subscribeAllCallback = Effect.fn("Bus.subscribeAllCallback")(function* (callback: (event: any) => unknown) {
|
|
159
|
+
const s = yield* InstanceState.get(state)
|
|
160
|
+
return yield* on(s.wildcard, "*", callback)
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
return Service.of({ publish, subscribe, subscribeAll, subscribeCallback, subscribeAllCallback })
|
|
164
|
+
}),
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
const { runPromise, runSync } = makeRuntime(Service, layer)
|
|
168
|
+
|
|
169
|
+
// runSync is safe here because the subscribe chain (InstanceState.get, PubSub.subscribe,
|
|
170
|
+
// Scope.make, Effect.forkScoped) is entirely synchronous. If any step becomes async, this will throw.
|
|
171
|
+
export async function publish<D extends BusEvent.Definition>(def: D, properties: z.output<D["properties"]>) {
|
|
172
|
+
return runPromise((svc) => svc.publish(def, properties))
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export function subscribe<D extends BusEvent.Definition>(
|
|
176
|
+
def: D,
|
|
177
|
+
callback: (event: { type: D["type"]; properties: z.infer<D["properties"]> }) => unknown,
|
|
178
|
+
) {
|
|
179
|
+
return runSync((svc) => svc.subscribeCallback(def, callback))
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export function subscribeAll(callback: (event: any) => unknown) {
|
|
183
|
+
return runSync((svc) => svc.subscribeAllCallback(callback))
|
|
184
|
+
}
|
|
185
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { InstanceBootstrap } from "../project/bootstrap"
|
|
2
|
+
import { Instance } from "../project/instance"
|
|
3
|
+
|
|
4
|
+
export async function bootstrap<T>(directory: string, cb: () => Promise<T>) {
|
|
5
|
+
return Instance.provide({
|
|
6
|
+
directory,
|
|
7
|
+
init: InstanceBootstrap,
|
|
8
|
+
fn: async () => {
|
|
9
|
+
try {
|
|
10
|
+
const result = await cb()
|
|
11
|
+
return result
|
|
12
|
+
} finally {
|
|
13
|
+
await Instance.dispose()
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
})
|
|
17
|
+
}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import { cmd } from "./cmd"
|
|
2
|
+
import { Duration, Effect, Match, Option } from "effect"
|
|
3
|
+
import { UI } from "../ui"
|
|
4
|
+
import { AccountID, Account, OrgID, PollExpired, type PollResult } from "@/account"
|
|
5
|
+
import { type AccountError } from "@/account/schema"
|
|
6
|
+
import * as Prompt from "../effect/prompt"
|
|
7
|
+
import open from "open"
|
|
8
|
+
|
|
9
|
+
const openBrowser = (url: string) => Effect.promise(() => open(url).catch(() => undefined))
|
|
10
|
+
|
|
11
|
+
const println = (msg: string) => Effect.sync(() => UI.println(msg))
|
|
12
|
+
|
|
13
|
+
const dim = (value: string) => UI.Style.TEXT_DIM + value + UI.Style.TEXT_NORMAL
|
|
14
|
+
|
|
15
|
+
const activeSuffix = (isActive: boolean) => (isActive ? dim(" (active)") : "")
|
|
16
|
+
|
|
17
|
+
export const formatAccountLabel = (account: { email: string; url: string }, isActive: boolean) =>
|
|
18
|
+
`${account.email} ${dim(account.url)}${activeSuffix(isActive)}`
|
|
19
|
+
|
|
20
|
+
const formatOrgChoiceLabel = (account: { email: string }, org: { name: string }, isActive: boolean) =>
|
|
21
|
+
`${org.name} (${account.email})${activeSuffix(isActive)}`
|
|
22
|
+
|
|
23
|
+
export const formatOrgLine = (
|
|
24
|
+
account: { email: string; url: string },
|
|
25
|
+
org: { id: string; name: string },
|
|
26
|
+
isActive: boolean,
|
|
27
|
+
) => {
|
|
28
|
+
const dot = isActive ? UI.Style.TEXT_SUCCESS + "●" + UI.Style.TEXT_NORMAL : " "
|
|
29
|
+
const name = isActive ? UI.Style.TEXT_HIGHLIGHT_BOLD + org.name + UI.Style.TEXT_NORMAL : org.name
|
|
30
|
+
return ` ${dot} ${name} ${dim(account.email)} ${dim(account.url)} ${dim(org.id)}`
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const isActiveOrgChoice = (
|
|
34
|
+
active: Option.Option<{ id: AccountID; active_org_id: OrgID | null }>,
|
|
35
|
+
choice: { accountID: AccountID; orgID: OrgID },
|
|
36
|
+
) => Option.isSome(active) && active.value.id === choice.accountID && active.value.active_org_id === choice.orgID
|
|
37
|
+
|
|
38
|
+
const loginEffect = Effect.fn("login")(function* (url: string) {
|
|
39
|
+
const service = yield* Account.Service
|
|
40
|
+
|
|
41
|
+
yield* Prompt.intro("Log in")
|
|
42
|
+
const login = yield* service.login(url)
|
|
43
|
+
|
|
44
|
+
yield* Prompt.log.info("Go to: " + login.url)
|
|
45
|
+
yield* Prompt.log.info("Enter code: " + login.user)
|
|
46
|
+
yield* openBrowser(login.url)
|
|
47
|
+
|
|
48
|
+
const s = Prompt.spinner()
|
|
49
|
+
yield* s.start("Waiting for authorization...")
|
|
50
|
+
|
|
51
|
+
const poll = (wait: Duration.Duration): Effect.Effect<PollResult, AccountError> =>
|
|
52
|
+
Effect.gen(function* () {
|
|
53
|
+
yield* Effect.sleep(wait)
|
|
54
|
+
const result = yield* service.poll(login)
|
|
55
|
+
if (result._tag === "PollPending") return yield* poll(wait)
|
|
56
|
+
if (result._tag === "PollSlow") return yield* poll(Duration.sum(wait, Duration.seconds(5)))
|
|
57
|
+
return result
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
const result = yield* poll(login.interval).pipe(
|
|
61
|
+
Effect.timeout(login.expiry),
|
|
62
|
+
Effect.catchTag("TimeoutError", () => Effect.succeed(new PollExpired())),
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
yield* Match.valueTags(result, {
|
|
66
|
+
PollSuccess: (r) =>
|
|
67
|
+
Effect.gen(function* () {
|
|
68
|
+
yield* s.stop("Logged in as " + r.email)
|
|
69
|
+
yield* Prompt.outro("Done")
|
|
70
|
+
}),
|
|
71
|
+
PollExpired: () => s.stop("Device code expired", 1),
|
|
72
|
+
PollDenied: () => s.stop("Authorization denied", 1),
|
|
73
|
+
PollError: (r) => s.stop("Error: " + String(r.cause), 1),
|
|
74
|
+
PollPending: () => s.stop("Unexpected state", 1),
|
|
75
|
+
PollSlow: () => s.stop("Unexpected state", 1),
|
|
76
|
+
})
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
const logoutEffect = Effect.fn("logout")(function* (email?: string) {
|
|
80
|
+
const service = yield* Account.Service
|
|
81
|
+
const accounts = yield* service.list()
|
|
82
|
+
if (accounts.length === 0) return yield* println("Not logged in")
|
|
83
|
+
|
|
84
|
+
if (email) {
|
|
85
|
+
const match = accounts.find((a) => a.email === email)
|
|
86
|
+
if (!match) return yield* println("Account not found: " + email)
|
|
87
|
+
yield* service.remove(match.id)
|
|
88
|
+
yield* Prompt.outro("Logged out from " + email)
|
|
89
|
+
return
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const active = yield* service.active()
|
|
93
|
+
const activeID = Option.map(active, (a) => a.id)
|
|
94
|
+
|
|
95
|
+
yield* Prompt.intro("Log out")
|
|
96
|
+
|
|
97
|
+
const opts = accounts.map((a) => {
|
|
98
|
+
const isActive = Option.isSome(activeID) && activeID.value === a.id
|
|
99
|
+
return {
|
|
100
|
+
value: a,
|
|
101
|
+
label: formatAccountLabel(a, isActive),
|
|
102
|
+
}
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
const selected = yield* Prompt.select({ message: "Select account to log out", options: opts })
|
|
106
|
+
if (Option.isNone(selected)) return
|
|
107
|
+
|
|
108
|
+
yield* service.remove(selected.value.id)
|
|
109
|
+
yield* Prompt.outro("Logged out from " + selected.value.email)
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
interface OrgChoice {
|
|
113
|
+
orgID: OrgID
|
|
114
|
+
accountID: AccountID
|
|
115
|
+
label: string
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const switchEffect = Effect.fn("switch")(function* () {
|
|
119
|
+
const service = yield* Account.Service
|
|
120
|
+
|
|
121
|
+
const groups = yield* service.orgsByAccount()
|
|
122
|
+
if (groups.length === 0) return yield* println("Not logged in")
|
|
123
|
+
|
|
124
|
+
const active = yield* service.active()
|
|
125
|
+
|
|
126
|
+
const opts = groups.flatMap((group) =>
|
|
127
|
+
group.orgs.map((org) => {
|
|
128
|
+
const isActive = isActiveOrgChoice(active, { accountID: group.account.id, orgID: org.id })
|
|
129
|
+
return {
|
|
130
|
+
value: { orgID: org.id, accountID: group.account.id, label: org.name },
|
|
131
|
+
label: formatOrgChoiceLabel(group.account, org, isActive),
|
|
132
|
+
}
|
|
133
|
+
}),
|
|
134
|
+
)
|
|
135
|
+
if (opts.length === 0) return yield* println("No orgs found")
|
|
136
|
+
|
|
137
|
+
yield* Prompt.intro("Switch org")
|
|
138
|
+
|
|
139
|
+
const selected = yield* Prompt.select<OrgChoice>({ message: "Select org", options: opts })
|
|
140
|
+
if (Option.isNone(selected)) return
|
|
141
|
+
|
|
142
|
+
const choice = selected.value
|
|
143
|
+
yield* service.use(choice.accountID, Option.some(choice.orgID))
|
|
144
|
+
yield* Prompt.outro("Switched to " + choice.label)
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
const orgsEffect = Effect.fn("orgs")(function* () {
|
|
148
|
+
const service = yield* Account.Service
|
|
149
|
+
|
|
150
|
+
const groups = yield* service.orgsByAccount()
|
|
151
|
+
if (groups.length === 0) return yield* println("No accounts found")
|
|
152
|
+
if (!groups.some((group) => group.orgs.length > 0)) return yield* println("No orgs found")
|
|
153
|
+
|
|
154
|
+
const active = yield* service.active()
|
|
155
|
+
|
|
156
|
+
for (const group of groups) {
|
|
157
|
+
for (const org of group.orgs) {
|
|
158
|
+
const isActive = isActiveOrgChoice(active, { accountID: group.account.id, orgID: org.id })
|
|
159
|
+
yield* println(formatOrgLine(group.account, org, isActive))
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
const openEffect = Effect.fn("open")(function* () {
|
|
165
|
+
const service = yield* Account.Service
|
|
166
|
+
const active = yield* service.active()
|
|
167
|
+
if (Option.isNone(active)) return yield* println("No active account")
|
|
168
|
+
|
|
169
|
+
const url = active.value.url
|
|
170
|
+
yield* openBrowser(url)
|
|
171
|
+
yield* Prompt.outro("Opened " + url)
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
export const LoginCommand = cmd({
|
|
175
|
+
command: "login <url>",
|
|
176
|
+
describe: false,
|
|
177
|
+
builder: (yargs) =>
|
|
178
|
+
yargs.positional("url", {
|
|
179
|
+
describe: "server URL",
|
|
180
|
+
type: "string",
|
|
181
|
+
demandOption: true,
|
|
182
|
+
}),
|
|
183
|
+
async handler(args) {
|
|
184
|
+
UI.empty()
|
|
185
|
+
await Account.runPromise((_svc) => loginEffect(args.url))
|
|
186
|
+
},
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
export const LogoutCommand = cmd({
|
|
190
|
+
command: "logout [email]",
|
|
191
|
+
describe: false,
|
|
192
|
+
builder: (yargs) =>
|
|
193
|
+
yargs.positional("email", {
|
|
194
|
+
describe: "account email to log out from",
|
|
195
|
+
type: "string",
|
|
196
|
+
}),
|
|
197
|
+
async handler(args) {
|
|
198
|
+
UI.empty()
|
|
199
|
+
await Account.runPromise((_svc) => logoutEffect(args.email))
|
|
200
|
+
},
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
export const SwitchCommand = cmd({
|
|
204
|
+
command: "switch",
|
|
205
|
+
describe: false,
|
|
206
|
+
async handler() {
|
|
207
|
+
UI.empty()
|
|
208
|
+
await Account.runPromise((_svc) => switchEffect())
|
|
209
|
+
},
|
|
210
|
+
})
|
|
211
|
+
|
|
212
|
+
export const OrgsCommand = cmd({
|
|
213
|
+
command: "orgs",
|
|
214
|
+
describe: false,
|
|
215
|
+
async handler() {
|
|
216
|
+
UI.empty()
|
|
217
|
+
await Account.runPromise((_svc) => orgsEffect())
|
|
218
|
+
},
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
export const OpenCommand = cmd({
|
|
222
|
+
command: "open",
|
|
223
|
+
describe: false,
|
|
224
|
+
async handler() {
|
|
225
|
+
UI.empty()
|
|
226
|
+
await Account.runPromise((_svc) => openEffect())
|
|
227
|
+
},
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
export const ConsoleCommand = cmd({
|
|
231
|
+
command: "console",
|
|
232
|
+
describe: false,
|
|
233
|
+
builder: (yargs) =>
|
|
234
|
+
yargs
|
|
235
|
+
.command({
|
|
236
|
+
...LoginCommand,
|
|
237
|
+
describe: "log in to console",
|
|
238
|
+
})
|
|
239
|
+
.command({
|
|
240
|
+
...LogoutCommand,
|
|
241
|
+
describe: "log out from console",
|
|
242
|
+
})
|
|
243
|
+
.command({
|
|
244
|
+
...SwitchCommand,
|
|
245
|
+
describe: "switch active org",
|
|
246
|
+
})
|
|
247
|
+
.command({
|
|
248
|
+
...OrgsCommand,
|
|
249
|
+
describe: "list orgs",
|
|
250
|
+
})
|
|
251
|
+
.command({
|
|
252
|
+
...OpenCommand,
|
|
253
|
+
describe: "open active console account",
|
|
254
|
+
})
|
|
255
|
+
.demandCommand(),
|
|
256
|
+
async handler() {},
|
|
257
|
+
})
|