rimuru-ai 1.19.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/.rimuru/AGENTS.md +30 -0
- package/.rimuru/agents/backend.md +27 -0
- package/.rimuru/agents/database.md +31 -0
- package/.rimuru/agents/devops.md +30 -0
- package/.rimuru/agents/document-prep.md +49 -0
- package/.rimuru/agents/erp-architect.md +41 -0
- package/.rimuru/agents/ethical-hacking.md +49 -0
- package/.rimuru/agents/frontend.md +31 -0
- package/.rimuru/agents/fullstack.md +24 -0
- package/.rimuru/agents/system-engineer.md +31 -0
- package/.rimuru/agents/veldora-agent-tool-dev.md +30 -0
- package/.rimuru/agents/veldora-backend-dev.md +32 -0
- package/.rimuru/agents/veldora-cicd.md +32 -0
- package/.rimuru/agents/veldora-database.md +32 -0
- package/.rimuru/agents/veldora-doc.md +87 -0
- package/.rimuru/agents/veldora-frontend-dev.md +32 -0
- package/.rimuru/agents/veldora-great-sage.md +33 -0
- package/.rimuru/agents/veldora-mcp-creator.md +30 -0
- package/.rimuru/agents/veldora-pro.md +224 -0
- package/.rimuru/agents/veldora-prompt-enhancer.md +27 -0
- package/.rimuru/agents/veldora-skill-creator.md +28 -0
- package/.rimuru/agents/veldora.md +225 -0
- package/.rimuru/agents/veldorapro-agent-tool-dev.md +29 -0
- package/.rimuru/agents/veldorapro-backend-dev.md +29 -0
- package/.rimuru/agents/veldorapro-cicd.md +29 -0
- package/.rimuru/agents/veldorapro-database.md +29 -0
- package/.rimuru/agents/veldorapro-frontend-dev.md +29 -0
- package/.rimuru/agents/veldorapro-great-sage.md +33 -0
- package/.rimuru/agents/veldorapro-mcp-creator.md +27 -0
- package/.rimuru/agents/veldorapro-prompt-enhancer.md +25 -0
- package/.rimuru/agents/veldorapro-skill-creator.md +27 -0
- package/.rimuru/command/ai-deps.md +24 -0
- package/.rimuru/command/changelog.md +49 -0
- package/.rimuru/command/commit.md +37 -0
- package/.rimuru/command/issues.md +23 -0
- package/.rimuru/command/learn.md +42 -0
- package/.rimuru/command/rmslop.md +15 -0
- package/.rimuru/command/spellcheck.md +5 -0
- package/.rimuru/command/translate.md +14 -0
- package/.rimuru/glossary/README.md +63 -0
- package/.rimuru/glossary/ar.md +28 -0
- package/.rimuru/glossary/br.md +34 -0
- package/.rimuru/glossary/bs.md +33 -0
- package/.rimuru/glossary/da.md +27 -0
- package/.rimuru/glossary/de.md +27 -0
- package/.rimuru/glossary/es.md +27 -0
- package/.rimuru/glossary/fr.md +27 -0
- package/.rimuru/glossary/ja.md +33 -0
- package/.rimuru/glossary/ko.md +27 -0
- package/.rimuru/glossary/no.md +38 -0
- package/.rimuru/glossary/pl.md +27 -0
- package/.rimuru/glossary/ru.md +27 -0
- package/.rimuru/glossary/th.md +34 -0
- package/.rimuru/glossary/tr.md +38 -0
- package/.rimuru/glossary/zh-cn.md +42 -0
- package/.rimuru/glossary/zh-tw.md +42 -0
- package/.rimuru/improver/changelog.md +250 -0
- package/.rimuru/improver/knowledge.md +172 -0
- package/.rimuru/improver/plugins.md +21 -0
- package/.rimuru/improver/skills.md +60 -0
- package/.rimuru/improver/token-audit.md +21 -0
- package/.rimuru/opencode.jsonc +140 -0
- package/.rimuru/plugins/smoke-theme.json +223 -0
- package/.rimuru/plugins/tui-smoke.tsx +1019 -0
- package/.rimuru/skills/effect/SKILL.md +38 -0
- package/.rimuru/themes/mytheme.json +223 -0
- package/.rimuru/tool/github-pr-search.ts +64 -0
- package/.rimuru/tool/github-triage.ts +60 -0
- package/README.md +31 -0
- package/package.json +167 -0
- package/src/account/account.ts +463 -0
- package/src/account/repo.ts +173 -0
- package/src/account/schema.ts +99 -0
- package/src/account/url.ts +8 -0
- package/src/acp/agent.ts +95 -0
- package/src/acp/config-option.ts +203 -0
- package/src/acp/content.ts +250 -0
- package/src/acp/directory.ts +210 -0
- package/src/acp/error.ts +90 -0
- package/src/acp/event.ts +342 -0
- package/src/acp/permission.ts +124 -0
- package/src/acp/profile.ts +42 -0
- package/src/acp/service.ts +1048 -0
- package/src/acp/session.ts +231 -0
- package/src/acp/tool.ts +367 -0
- package/src/acp/usage.ts +232 -0
- package/src/agent/agent.ts +459 -0
- package/src/agent/generate.txt +75 -0
- package/src/agent/prompt/compaction.txt +9 -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/agent/subagent-permissions.ts +27 -0
- package/src/audio.d.ts +14 -0
- package/src/auth/index.ts +99 -0
- package/src/background/job.ts +39 -0
- package/src/bus/global.ts +22 -0
- package/src/cli/bootstrap.ts +11 -0
- package/src/cli/cmd/account.ts +264 -0
- package/src/cli/cmd/acp.ts +73 -0
- package/src/cli/cmd/agent.ts +259 -0
- package/src/cli/cmd/attach.ts +97 -0
- package/src/cli/cmd/cmd.ts +7 -0
- package/src/cli/cmd/db.ts +62 -0
- package/src/cli/cmd/debug/agent.handler.ts +193 -0
- package/src/cli/cmd/debug/agent.ts +27 -0
- package/src/cli/cmd/debug/config.ts +14 -0
- package/src/cli/cmd/debug/file.ts +73 -0
- package/src/cli/cmd/debug/index.ts +87 -0
- package/src/cli/cmd/debug/lsp.ts +50 -0
- package/src/cli/cmd/debug/ripgrep.ts +79 -0
- package/src/cli/cmd/debug/scrap.ts +15 -0
- package/src/cli/cmd/debug/skill.ts +15 -0
- package/src/cli/cmd/debug/snapshot.ts +50 -0
- package/src/cli/cmd/debug/startup.ts +11 -0
- package/src/cli/cmd/debug/v2.ts +49 -0
- package/src/cli/cmd/export.ts +292 -0
- package/src/cli/cmd/generate.ts +54 -0
- package/src/cli/cmd/github.handler.ts +1593 -0
- package/src/cli/cmd/github.shared.ts +30 -0
- package/src/cli/cmd/github.ts +42 -0
- package/src/cli/cmd/import.ts +224 -0
- package/src/cli/cmd/mcp.ts +850 -0
- package/src/cli/cmd/models.ts +66 -0
- package/src/cli/cmd/plug.ts +230 -0
- package/src/cli/cmd/pr.ts +115 -0
- package/src/cli/cmd/prompt-display.ts +1 -0
- package/src/cli/cmd/providers.ts +534 -0
- package/src/cli/cmd/run/demo.ts +1274 -0
- package/src/cli/cmd/run/entry.body.ts +205 -0
- package/src/cli/cmd/run/footer.command.tsx +1064 -0
- package/src/cli/cmd/run/footer.menu.tsx +351 -0
- package/src/cli/cmd/run/footer.permission.tsx +472 -0
- package/src/cli/cmd/run/footer.prompt.tsx +1306 -0
- package/src/cli/cmd/run/footer.question.tsx +573 -0
- package/src/cli/cmd/run/footer.subagent.tsx +173 -0
- package/src/cli/cmd/run/footer.ts +1129 -0
- package/src/cli/cmd/run/footer.view.tsx +943 -0
- package/src/cli/cmd/run/footer.width.ts +27 -0
- package/src/cli/cmd/run/permission.shared.ts +256 -0
- package/src/cli/cmd/run/prompt.editor.ts +157 -0
- package/src/cli/cmd/run/prompt.shared.ts +153 -0
- package/src/cli/cmd/run/question.shared.ts +340 -0
- package/src/cli/cmd/run/runtime.boot.ts +202 -0
- package/src/cli/cmd/run/runtime.lifecycle.ts +406 -0
- package/src/cli/cmd/run/runtime.queue.ts +349 -0
- package/src/cli/cmd/run/runtime.shared.ts +17 -0
- package/src/cli/cmd/run/runtime.stdin.ts +37 -0
- package/src/cli/cmd/run/runtime.ts +814 -0
- package/src/cli/cmd/run/scrollback.shared.ts +92 -0
- package/src/cli/cmd/run/scrollback.surface.ts +431 -0
- package/src/cli/cmd/run/scrollback.writer.tsx +352 -0
- package/src/cli/cmd/run/session-data.ts +1113 -0
- package/src/cli/cmd/run/session-replay.ts +374 -0
- package/src/cli/cmd/run/session.shared.ts +196 -0
- package/src/cli/cmd/run/splash.ts +280 -0
- package/src/cli/cmd/run/stream.transport.ts +1462 -0
- package/src/cli/cmd/run/stream.ts +175 -0
- package/src/cli/cmd/run/subagent-data.ts +876 -0
- package/src/cli/cmd/run/theme.ts +690 -0
- package/src/cli/cmd/run/tool.ts +1489 -0
- package/src/cli/cmd/run/trace.ts +94 -0
- package/src/cli/cmd/run/turn-summary.ts +47 -0
- package/src/cli/cmd/run/types.ts +350 -0
- package/src/cli/cmd/run/variant.shared.ts +215 -0
- package/src/cli/cmd/run.ts +894 -0
- package/src/cli/cmd/serve.ts +24 -0
- package/src/cli/cmd/session.ts +147 -0
- package/src/cli/cmd/stats.ts +393 -0
- package/src/cli/cmd/tui.ts +224 -0
- package/src/cli/cmd/uninstall.ts +353 -0
- package/src/cli/cmd/upgrade.ts +74 -0
- package/src/cli/cmd/web.ts +84 -0
- package/src/cli/effect/prompt.ts +37 -0
- package/src/cli/effect-cmd.ts +96 -0
- package/src/cli/error.ts +130 -0
- package/src/cli/heap.ts +45 -0
- package/src/cli/logo.ts +1 -0
- package/src/cli/network.ts +64 -0
- package/src/cli/tui/layer.ts +7 -0
- package/src/cli/tui/validate-session.ts +29 -0
- package/src/cli/tui/worker.ts +71 -0
- package/src/cli/ui.ts +98 -0
- package/src/cli/upgrade.ts +53 -0
- package/src/command/index.ts +184 -0
- package/src/command/template/initialize.txt +66 -0
- package/src/command/template/review.txt +101 -0
- package/src/config/agent.ts +59 -0
- package/src/config/command.ts +39 -0
- package/src/config/config.ts +686 -0
- package/src/config/entry-name.ts +19 -0
- package/src/config/managed.ts +69 -0
- package/src/config/markdown.ts +36 -0
- package/src/config/parse.ts +79 -0
- package/src/config/paths.ts +45 -0
- package/src/config/plugin.ts +79 -0
- package/src/config/tui-cwd.ts +5 -0
- package/src/config/tui-host-attention.ts +21 -0
- package/src/config/tui-migrate.ts +132 -0
- package/src/config/tui.ts +274 -0
- package/src/config/variable.ts +91 -0
- package/src/control-plane/adapters/index.ts +41 -0
- package/src/control-plane/adapters/worktree.ts +96 -0
- package/src/control-plane/dev/README.md +19 -0
- package/src/control-plane/dev/debug-workspace-plugin.ts +73 -0
- package/src/control-plane/types.ts +59 -0
- package/src/control-plane/util.ts +39 -0
- package/src/control-plane/workspace-adapter-runtime.ts +51 -0
- package/src/control-plane/workspace-context.ts +26 -0
- package/src/control-plane/workspace.ts +989 -0
- package/src/effect/app-runtime.ts +132 -0
- package/src/effect/bootstrap-runtime.ts +23 -0
- package/src/effect/bridge.ts +84 -0
- package/src/effect/config-service.ts +67 -0
- package/src/effect/instance-ref.ts +11 -0
- package/src/effect/instance-registry.ts +12 -0
- package/src/effect/instance-state.ts +69 -0
- package/src/effect/promise.ts +17 -0
- package/src/effect/run-service.ts +47 -0
- package/src/effect/runner.ts +217 -0
- package/src/effect/runtime-flags.ts +79 -0
- package/src/env/index.ts +43 -0
- package/src/event-v2-bridge.ts +79 -0
- package/src/format/formatter.ts +404 -0
- package/src/format/index.ts +205 -0
- package/src/git/index.ts +350 -0
- package/src/id/id.ts +80 -0
- package/src/ide/index.ts +61 -0
- package/src/image/image.ts +174 -0
- package/src/index.ts +142 -0
- package/src/installation/index.ts +350 -0
- package/src/lsp/client.ts +650 -0
- package/src/lsp/diagnostic.ts +29 -0
- package/src/lsp/language.ts +121 -0
- package/src/lsp/launch.ts +21 -0
- package/src/lsp/lsp.ts +511 -0
- package/src/lsp/server.ts +1983 -0
- package/src/markdown.d.ts +4 -0
- package/src/mcp/auth.ts +174 -0
- package/src/mcp/catalog.ts +153 -0
- package/src/mcp/index.ts +946 -0
- package/src/mcp/oauth-callback.ts +233 -0
- package/src/mcp/oauth-provider.ts +206 -0
- package/src/node.ts +4 -0
- package/src/patch/index.ts +686 -0
- package/src/permission/arity.ts +163 -0
- package/src/permission/evaluate.ts +1 -0
- package/src/permission/index.ts +230 -0
- package/src/plugin/azure.ts +26 -0
- package/src/plugin/cloudflare.ts +76 -0
- package/src/plugin/digitalocean.ts +383 -0
- package/src/plugin/github-copilot/copilot.ts +413 -0
- package/src/plugin/github-copilot/models.ts +246 -0
- package/src/plugin/index.ts +316 -0
- package/src/plugin/install.ts +439 -0
- package/src/plugin/loader.ts +237 -0
- package/src/plugin/meta.ts +188 -0
- package/src/plugin/openai/README.md +31 -0
- package/src/plugin/openai/codex.ts +641 -0
- package/src/plugin/openai/ws-pool.ts +270 -0
- package/src/plugin/openai/ws.ts +381 -0
- package/src/plugin/pty-environment.ts +24 -0
- package/src/plugin/shared.ts +323 -0
- package/src/plugin/snowflake-cortex.ts +529 -0
- package/src/plugin/tui/internal.ts +10 -0
- package/src/plugin/tui/runtime.ts +1130 -0
- package/src/plugin/xai.ts +716 -0
- package/src/project/bootstrap-service.ts +9 -0
- package/src/project/bootstrap.ts +76 -0
- package/src/project/instance-context.ts +24 -0
- package/src/project/instance-layer.ts +11 -0
- package/src/project/instance-runtime.ts +16 -0
- package/src/project/instance-store.ts +209 -0
- package/src/project/project.ts +519 -0
- package/src/project/vcs.ts +431 -0
- package/src/provider/auth.ts +233 -0
- package/src/provider/error.ts +188 -0
- package/src/provider/model-status.ts +8 -0
- package/src/provider/provider.ts +1979 -0
- package/src/provider/transform.ts +1426 -0
- package/src/question/index.ts +229 -0
- package/src/question/schema.ts +10 -0
- package/src/server/auth.ts +48 -0
- package/src/server/event.ts +13 -0
- package/src/server/global-lifecycle.ts +28 -0
- package/src/server/init-projectors.ts +3 -0
- package/src/server/mdns.ts +47 -0
- package/src/server/projectors.ts +1 -0
- package/src/server/proxy-util.ts +48 -0
- package/src/server/routes/instance/httpapi/AGENTS.md +39 -0
- package/src/server/routes/instance/httpapi/api.ts +78 -0
- package/src/server/routes/instance/httpapi/errors.ts +193 -0
- package/src/server/routes/instance/httpapi/groups/config.ts +65 -0
- package/src/server/routes/instance/httpapi/groups/control-plane.ts +35 -0
- package/src/server/routes/instance/httpapi/groups/control.ts +76 -0
- package/src/server/routes/instance/httpapi/groups/event.ts +29 -0
- package/src/server/routes/instance/httpapi/groups/experimental.ts +260 -0
- package/src/server/routes/instance/httpapi/groups/file.ts +185 -0
- package/src/server/routes/instance/httpapi/groups/global.ts +138 -0
- package/src/server/routes/instance/httpapi/groups/instance.ts +206 -0
- package/src/server/routes/instance/httpapi/groups/mcp.ts +156 -0
- package/src/server/routes/instance/httpapi/groups/metadata.ts +18 -0
- package/src/server/routes/instance/httpapi/groups/permission.ts +61 -0
- package/src/server/routes/instance/httpapi/groups/project-copy.ts +32 -0
- package/src/server/routes/instance/httpapi/groups/project.ts +93 -0
- package/src/server/routes/instance/httpapi/groups/provider.ts +101 -0
- package/src/server/routes/instance/httpapi/groups/pty.ts +172 -0
- package/src/server/routes/instance/httpapi/groups/query.ts +12 -0
- package/src/server/routes/instance/httpapi/groups/question.ts +74 -0
- package/src/server/routes/instance/httpapi/groups/session.ts +462 -0
- package/src/server/routes/instance/httpapi/groups/sync.ts +113 -0
- package/src/server/routes/instance/httpapi/groups/tui.ts +208 -0
- package/src/server/routes/instance/httpapi/groups/workspace.ts +141 -0
- package/src/server/routes/instance/httpapi/handlers/config.ts +34 -0
- package/src/server/routes/instance/httpapi/handlers/control-plane.ts +37 -0
- package/src/server/routes/instance/httpapi/handlers/control.ts +43 -0
- package/src/server/routes/instance/httpapi/handlers/event.ts +99 -0
- package/src/server/routes/instance/httpapi/handlers/experimental.ts +187 -0
- package/src/server/routes/instance/httpapi/handlers/file.ts +139 -0
- package/src/server/routes/instance/httpapi/handlers/global.ts +156 -0
- package/src/server/routes/instance/httpapi/handlers/instance.ts +110 -0
- package/src/server/routes/instance/httpapi/handlers/mcp.ts +111 -0
- package/src/server/routes/instance/httpapi/handlers/permission.ts +41 -0
- package/src/server/routes/instance/httpapi/handlers/project-copy.ts +83 -0
- package/src/server/routes/instance/httpapi/handlers/project.ts +63 -0
- package/src/server/routes/instance/httpapi/handlers/provider.ts +113 -0
- package/src/server/routes/instance/httpapi/handlers/pty.ts +273 -0
- package/src/server/routes/instance/httpapi/handlers/question.ts +54 -0
- package/src/server/routes/instance/httpapi/handlers/session-errors.ts +21 -0
- package/src/server/routes/instance/httpapi/handlers/session.ts +440 -0
- package/src/server/routes/instance/httpapi/handlers/sync.ts +89 -0
- package/src/server/routes/instance/httpapi/handlers/tui.ts +131 -0
- package/src/server/routes/instance/httpapi/handlers/workspace.ts +102 -0
- package/src/server/routes/instance/httpapi/lifecycle.ts +54 -0
- package/src/server/routes/instance/httpapi/middleware/authorization.ts +150 -0
- package/src/server/routes/instance/httpapi/middleware/compression.ts +64 -0
- package/src/server/routes/instance/httpapi/middleware/cors-vary.ts +29 -0
- package/src/server/routes/instance/httpapi/middleware/error.ts +43 -0
- package/src/server/routes/instance/httpapi/middleware/fence.ts +25 -0
- package/src/server/routes/instance/httpapi/middleware/instance-context.ts +43 -0
- package/src/server/routes/instance/httpapi/middleware/proxy.ts +108 -0
- package/src/server/routes/instance/httpapi/middleware/schema-error.ts +41 -0
- package/src/server/routes/instance/httpapi/middleware/workspace-routing.ts +250 -0
- package/src/server/routes/instance/httpapi/public.ts +535 -0
- package/src/server/routes/instance/httpapi/server.ts +298 -0
- package/src/server/routes/instance/httpapi/websocket-tracker.ts +57 -0
- package/src/server/server.ts +225 -0
- package/src/server/shared/fence.ts +60 -0
- package/src/server/shared/pty-ticket.ts +15 -0
- package/src/server/shared/public-ui.ts +12 -0
- package/src/server/shared/tui-control.ts +28 -0
- package/src/server/shared/ui.ts +122 -0
- package/src/server/shared/workspace-routing.ts +38 -0
- package/src/server/tui-event.ts +53 -0
- package/src/session/compaction.ts +620 -0
- package/src/session/instruction.ts +241 -0
- package/src/session/llm/AGENTS.md +90 -0
- package/src/session/llm/ai-sdk.ts +288 -0
- package/src/session/llm/native-request.ts +196 -0
- package/src/session/llm/native-runtime.ts +196 -0
- package/src/session/llm/request.ts +218 -0
- package/src/session/llm.ts +415 -0
- package/src/session/message-error.ts +14 -0
- package/src/session/message-v2.ts +744 -0
- package/src/session/message.ts +148 -0
- package/src/session/overflow.ts +34 -0
- package/src/session/processor.ts +1084 -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 +95 -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-mode.txt +70 -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 +1722 -0
- package/src/session/reminders.ts +92 -0
- package/src/session/retry.ts +201 -0
- package/src/session/revert.ts +160 -0
- package/src/session/run-state.ts +156 -0
- package/src/session/schema.ts +26 -0
- package/src/session/session.ts +1119 -0
- package/src/session/status.ts +97 -0
- package/src/session/summary.ts +165 -0
- package/src/session/system.ts +117 -0
- package/src/session/todo.ts +90 -0
- package/src/session/tools.ts +207 -0
- package/src/share/session.ts +61 -0
- package/src/share/share-next.ts +385 -0
- package/src/skill/discovery.ts +109 -0
- package/src/skill/index.ts +366 -0
- package/src/snapshot/index.ts +808 -0
- package/src/sql.d.ts +4 -0
- package/src/storage/schema.ts +5 -0
- package/src/storage/storage.ts +329 -0
- package/src/sync/README.md +179 -0
- package/src/sync/schema.ts +11 -0
- package/src/temporary.ts +31 -0
- package/src/tool/apply_patch.ts +313 -0
- package/src/tool/apply_patch.txt +33 -0
- package/src/tool/edit.ts +737 -0
- package/src/tool/edit.txt +10 -0
- package/src/tool/external-directory.ts +49 -0
- package/src/tool/glob.ts +76 -0
- package/src/tool/glob.txt +6 -0
- package/src/tool/grep.ts +112 -0
- package/src/tool/grep.txt +8 -0
- package/src/tool/invalid.ts +21 -0
- package/src/tool/json-schema.ts +164 -0
- package/src/tool/lsp.ts +113 -0
- package/src/tool/lsp.txt +24 -0
- package/src/tool/mcp-websearch.ts +96 -0
- package/src/tool/plan-enter.txt +14 -0
- package/src/tool/plan-exit.txt +13 -0
- package/src/tool/plan.ts +79 -0
- package/src/tool/question.ts +44 -0
- package/src/tool/question.txt +10 -0
- package/src/tool/read.ts +386 -0
- package/src/tool/read.txt +14 -0
- package/src/tool/registry.ts +440 -0
- package/src/tool/schema.ts +14 -0
- package/src/tool/shell/id.ts +19 -0
- package/src/tool/shell/prompt.ts +307 -0
- package/src/tool/shell/shell.txt +21 -0
- package/src/tool/shell.ts +657 -0
- package/src/tool/skill.ts +71 -0
- package/src/tool/skill.txt +5 -0
- package/src/tool/task.ts +346 -0
- package/src/tool/task.txt +19 -0
- package/src/tool/todo.ts +57 -0
- package/src/tool/todowrite.txt +44 -0
- package/src/tool/tool.ts +183 -0
- package/src/tool/truncate.ts +158 -0
- package/src/tool/truncation-dir.ts +4 -0
- package/src/tool/webfetch.ts +192 -0
- package/src/tool/webfetch.txt +13 -0
- package/src/tool/websearch.ts +143 -0
- package/src/tool/websearch.txt +14 -0
- package/src/tool/write.ts +104 -0
- package/src/tool/write.txt +8 -0
- package/src/util/archive.ts +17 -0
- package/src/util/bom.ts +27 -0
- package/src/util/data-url.ts +9 -0
- package/src/util/defer.ts +10 -0
- package/src/util/effect-http-client.ts +11 -0
- package/src/util/error.ts +1 -0
- package/src/util/filesystem.ts +251 -0
- package/src/util/html.ts +8 -0
- package/src/util/iife.ts +3 -0
- package/src/util/lazy.ts +20 -0
- package/src/util/local-context.ts +25 -0
- package/src/util/locale.ts +2 -0
- package/src/util/media.ts +26 -0
- package/src/util/process.ts +177 -0
- package/src/util/proxy-env.ts +72 -0
- package/src/util/queue.ts +32 -0
- package/src/util/record.ts +1 -0
- package/src/util/repository.ts +232 -0
- package/src/util/rpc.ts +66 -0
- package/src/util/signal.ts +12 -0
- package/src/util/timeout.ts +13 -0
- package/src/util/token.ts +1 -0
- package/src/util/wildcard.ts +59 -0
- package/src/worktree/index.ts +654 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// Dev-only JSONL event trace for direct interactive mode.
|
|
2
|
+
//
|
|
3
|
+
// Enable with OPENCODE_DIRECT_TRACE=1. Writes one JSON line per event to
|
|
4
|
+
// ~/.local/share/rimuru/log/direct/<timestamp>-<pid>.jsonl. Also writes
|
|
5
|
+
// a latest.json pointer so you can quickly find the most recent trace.
|
|
6
|
+
//
|
|
7
|
+
// The trace captures the full closed loop: outbound prompts, inbound SDK
|
|
8
|
+
// events, reducer output, footer commits, and turn lifecycle markers.
|
|
9
|
+
// Useful for debugging stream ordering, permission behavior, and
|
|
10
|
+
// footer/transcript mismatches.
|
|
11
|
+
//
|
|
12
|
+
// Lazy-initialized: the first call to trace() decides whether tracing is
|
|
13
|
+
// active based on the env var, and subsequent calls return the cached result.
|
|
14
|
+
import fs from "fs"
|
|
15
|
+
import path from "path"
|
|
16
|
+
import { Global } from "@rimurucode-ai/core/global"
|
|
17
|
+
|
|
18
|
+
export type Trace = {
|
|
19
|
+
write(type: string, data?: unknown): void
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let state: Trace | false | undefined
|
|
23
|
+
|
|
24
|
+
function stamp() {
|
|
25
|
+
return new Date()
|
|
26
|
+
.toISOString()
|
|
27
|
+
.replace(/[-:]/g, "")
|
|
28
|
+
.replace(/\.\d+Z$/, "Z")
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function file() {
|
|
32
|
+
return path.join(Global.Path.log, "direct", `${stamp()}-${process.pid}.jsonl`)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function latest() {
|
|
36
|
+
return path.join(Global.Path.log, "direct", "latest.json")
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function text(data: unknown) {
|
|
40
|
+
return JSON.stringify(
|
|
41
|
+
data,
|
|
42
|
+
(_key, value) => {
|
|
43
|
+
if (typeof value === "bigint") {
|
|
44
|
+
return String(value)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return value
|
|
48
|
+
},
|
|
49
|
+
0,
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function trace(): Trace | undefined {
|
|
54
|
+
if (state !== undefined) {
|
|
55
|
+
return state || undefined
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (!process.env.OPENCODE_DIRECT_TRACE) {
|
|
59
|
+
state = false
|
|
60
|
+
return undefined
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const target = file()
|
|
64
|
+
fs.mkdirSync(path.dirname(target), { recursive: true })
|
|
65
|
+
fs.writeFileSync(
|
|
66
|
+
latest(),
|
|
67
|
+
text({
|
|
68
|
+
time: new Date().toISOString(),
|
|
69
|
+
pid: process.pid,
|
|
70
|
+
cwd: process.cwd(),
|
|
71
|
+
argv: process.argv.slice(2),
|
|
72
|
+
path: target,
|
|
73
|
+
}) + "\n",
|
|
74
|
+
)
|
|
75
|
+
state = {
|
|
76
|
+
write(type: string, data?: unknown) {
|
|
77
|
+
fs.appendFileSync(
|
|
78
|
+
target,
|
|
79
|
+
text({
|
|
80
|
+
time: new Date().toISOString(),
|
|
81
|
+
pid: process.pid,
|
|
82
|
+
type,
|
|
83
|
+
data,
|
|
84
|
+
}) + "\n",
|
|
85
|
+
)
|
|
86
|
+
},
|
|
87
|
+
}
|
|
88
|
+
state.write("trace.start", {
|
|
89
|
+
argv: process.argv.slice(2),
|
|
90
|
+
cwd: process.cwd(),
|
|
91
|
+
path: target,
|
|
92
|
+
})
|
|
93
|
+
return state
|
|
94
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import * as Locale from "@/util/locale"
|
|
2
|
+
import type { SessionMessages } from "./session.shared"
|
|
3
|
+
import type { RunProvider, StreamCommit } from "./types"
|
|
4
|
+
|
|
5
|
+
export function turnSummaryCommit(input: {
|
|
6
|
+
agent: string
|
|
7
|
+
model: string
|
|
8
|
+
duration: string
|
|
9
|
+
messageID?: string
|
|
10
|
+
}): StreamCommit {
|
|
11
|
+
return {
|
|
12
|
+
kind: "system",
|
|
13
|
+
text: `▣ ${input.agent} · ${input.model} · ${input.duration}`,
|
|
14
|
+
phase: "final",
|
|
15
|
+
source: "system",
|
|
16
|
+
summary: {
|
|
17
|
+
agent: input.agent,
|
|
18
|
+
model: input.model,
|
|
19
|
+
duration: input.duration,
|
|
20
|
+
},
|
|
21
|
+
messageID: input.messageID,
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function messageTurnSummaryCommit(
|
|
26
|
+
message: SessionMessages[number],
|
|
27
|
+
providers?: RunProvider[],
|
|
28
|
+
): StreamCommit | undefined {
|
|
29
|
+
const info = message.info
|
|
30
|
+
if (info.role !== "assistant") {
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const completed = info.time.completed
|
|
35
|
+
if (typeof completed !== "number" || completed <= info.time.created) {
|
|
36
|
+
return
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const model = providers?.find((item) => item.id === info.providerID)?.models[info.modelID]?.name
|
|
40
|
+
|
|
41
|
+
return turnSummaryCommit({
|
|
42
|
+
agent: Locale.titlecase(info.agent),
|
|
43
|
+
model: model ?? info.modelID,
|
|
44
|
+
duration: Locale.duration(completed - info.time.created),
|
|
45
|
+
messageID: info.id,
|
|
46
|
+
})
|
|
47
|
+
}
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
// Shared type vocabulary for the direct interactive mode (`run --interactive`).
|
|
2
|
+
//
|
|
3
|
+
// Direct mode uses a split-footer terminal layout: immutable scrollback for the
|
|
4
|
+
// session transcript, and a mutable footer for prompt input, status, and
|
|
5
|
+
// permission/question UI. Every module in run/* shares these types to stay
|
|
6
|
+
// aligned on that two-lane model.
|
|
7
|
+
//
|
|
8
|
+
// Data flow through the system:
|
|
9
|
+
//
|
|
10
|
+
// SDK events → session-data reducer → StreamCommit[] + FooterOutput
|
|
11
|
+
// → stream.ts bridges to footer API
|
|
12
|
+
// → footer.ts queues commits and patches the footer view
|
|
13
|
+
// → OpenTUI split-footer renderer writes to terminal
|
|
14
|
+
import type { RimuruClient, PermissionRequest, QuestionRequest, ToolPart } from "@rimurucode-ai/sdk/v2"
|
|
15
|
+
import type { TuiConfig } from "@rimurucode-ai/tui/config"
|
|
16
|
+
|
|
17
|
+
export type RunFilePart = {
|
|
18
|
+
type: "file"
|
|
19
|
+
url: string
|
|
20
|
+
filename: string
|
|
21
|
+
mime: string
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
type PromptModel = Parameters<RimuruClient["session"]["prompt"]>[0]["model"]
|
|
25
|
+
type PromptInput = Parameters<RimuruClient["session"]["prompt"]>[0]
|
|
26
|
+
|
|
27
|
+
export type RunPromptPart = NonNullable<PromptInput["parts"]>[number]
|
|
28
|
+
|
|
29
|
+
export type RunCommand = NonNullable<Awaited<ReturnType<RimuruClient["command"]["list"]>>["data"]>[number]
|
|
30
|
+
|
|
31
|
+
export type RunProvider = NonNullable<Awaited<ReturnType<RimuruClient["provider"]["list"]>>["data"]>["all"][number]
|
|
32
|
+
|
|
33
|
+
export type RunPrompt = {
|
|
34
|
+
messageID?: string
|
|
35
|
+
partID?: string
|
|
36
|
+
text: string
|
|
37
|
+
parts: RunPromptPart[]
|
|
38
|
+
mode?: "shell"
|
|
39
|
+
command?: {
|
|
40
|
+
name: string
|
|
41
|
+
arguments: string
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export type FooterQueuedPrompt = {
|
|
46
|
+
messageID: string
|
|
47
|
+
partID: string
|
|
48
|
+
prompt: RunPrompt
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export type RunAgent = NonNullable<Awaited<ReturnType<RimuruClient["app"]["agents"]>>["data"]>[number]
|
|
52
|
+
|
|
53
|
+
type RunResourceMap = NonNullable<Awaited<ReturnType<RimuruClient["experimental"]["resource"]["list"]>>["data"]>
|
|
54
|
+
|
|
55
|
+
export type RunResource = RunResourceMap[string]
|
|
56
|
+
|
|
57
|
+
export type RunInput = {
|
|
58
|
+
sdk: RimuruClient
|
|
59
|
+
directory: string
|
|
60
|
+
sessionID: string
|
|
61
|
+
sessionTitle?: string
|
|
62
|
+
resume?: boolean
|
|
63
|
+
replay?: boolean
|
|
64
|
+
replayLimit?: number
|
|
65
|
+
agent: string | undefined
|
|
66
|
+
model: PromptModel | undefined
|
|
67
|
+
variant: string | undefined
|
|
68
|
+
files: RunFilePart[]
|
|
69
|
+
initialInput?: string
|
|
70
|
+
thinking: boolean
|
|
71
|
+
backgroundSubagents: boolean
|
|
72
|
+
demo?: boolean
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// The semantic role of a scrollback entry. Maps 1:1 to theme colors.
|
|
76
|
+
export type EntryKind = "system" | "user" | "assistant" | "reasoning" | "tool" | "error"
|
|
77
|
+
|
|
78
|
+
// Whether the assistant is actively processing a turn.
|
|
79
|
+
export type FooterPhase = "idle" | "running"
|
|
80
|
+
|
|
81
|
+
// Full snapshot of footer status bar state. Every update replaces the whole
|
|
82
|
+
// object in the SolidJS signal so the view re-renders atomically.
|
|
83
|
+
export type FooterState = {
|
|
84
|
+
phase: FooterPhase
|
|
85
|
+
status: string
|
|
86
|
+
queue: number
|
|
87
|
+
model: string
|
|
88
|
+
duration: string
|
|
89
|
+
usage: string
|
|
90
|
+
first: boolean
|
|
91
|
+
interrupt: number
|
|
92
|
+
exit: number
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// A partial update to FooterState. The footer merges this onto the current state.
|
|
96
|
+
export type FooterPatch = Partial<FooterState>
|
|
97
|
+
|
|
98
|
+
export type RunDiffStyle = "auto" | "stacked"
|
|
99
|
+
|
|
100
|
+
export type TurnSummary = {
|
|
101
|
+
agent: string
|
|
102
|
+
model: string
|
|
103
|
+
duration: string
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export type ScrollbackOptions = {
|
|
107
|
+
diffStyle?: RunDiffStyle
|
|
108
|
+
suppressBackgrounds?: boolean
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export type ToolCodeSnapshot = {
|
|
112
|
+
kind: "code"
|
|
113
|
+
title: string
|
|
114
|
+
content: string
|
|
115
|
+
file?: string
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export type ToolDiffSnapshot = {
|
|
119
|
+
kind: "diff"
|
|
120
|
+
items: Array<{
|
|
121
|
+
title: string
|
|
122
|
+
diff: string
|
|
123
|
+
file?: string
|
|
124
|
+
deletions?: number
|
|
125
|
+
}>
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export type ToolTaskSnapshot = {
|
|
129
|
+
kind: "task"
|
|
130
|
+
title: string
|
|
131
|
+
rows: string[]
|
|
132
|
+
tail: string
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export type ToolTodoSnapshot = {
|
|
136
|
+
kind: "todo"
|
|
137
|
+
items: Array<{
|
|
138
|
+
status: string
|
|
139
|
+
content: string
|
|
140
|
+
}>
|
|
141
|
+
tail: string
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export type ToolQuestionSnapshot = {
|
|
145
|
+
kind: "question"
|
|
146
|
+
items: Array<{
|
|
147
|
+
question: string
|
|
148
|
+
answer: string
|
|
149
|
+
}>
|
|
150
|
+
tail: string
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export type ToolSnapshot =
|
|
154
|
+
| ToolCodeSnapshot
|
|
155
|
+
| ToolDiffSnapshot
|
|
156
|
+
| ToolTaskSnapshot
|
|
157
|
+
| ToolTodoSnapshot
|
|
158
|
+
| ToolQuestionSnapshot
|
|
159
|
+
|
|
160
|
+
export type EntryLayout = "inline" | "block"
|
|
161
|
+
|
|
162
|
+
export type RunEntryBody =
|
|
163
|
+
| { type: "none" }
|
|
164
|
+
| { type: "text"; content: string }
|
|
165
|
+
| { type: "code"; content: string; filetype?: string }
|
|
166
|
+
| { type: "markdown"; content: string }
|
|
167
|
+
| { type: "structured"; snapshot: ToolSnapshot }
|
|
168
|
+
|
|
169
|
+
// Which interactive surface the footer is showing. Only one view is active at
|
|
170
|
+
// a time. The reducer drives transitions: when a permission arrives the view
|
|
171
|
+
// switches to "permission", and when the permission resolves it falls back to
|
|
172
|
+
// "prompt".
|
|
173
|
+
export type FooterView =
|
|
174
|
+
| { type: "prompt" }
|
|
175
|
+
| { type: "permission"; request: PermissionRequest }
|
|
176
|
+
| { type: "question"; request: QuestionRequest }
|
|
177
|
+
|
|
178
|
+
export type FooterPromptRoute =
|
|
179
|
+
| { type: "composer" }
|
|
180
|
+
| { type: "queued-menu" }
|
|
181
|
+
| { type: "subagent-menu" }
|
|
182
|
+
| { type: "subagent"; sessionID: string }
|
|
183
|
+
| { type: "command" }
|
|
184
|
+
| { type: "skill" }
|
|
185
|
+
| { type: "model" }
|
|
186
|
+
| { type: "variant" }
|
|
187
|
+
|
|
188
|
+
export type FooterSubagentTab = {
|
|
189
|
+
sessionID: string
|
|
190
|
+
partID: string
|
|
191
|
+
callID: string
|
|
192
|
+
label: string
|
|
193
|
+
description: string
|
|
194
|
+
status: "running" | "completed" | "cancelled" | "error"
|
|
195
|
+
background?: boolean
|
|
196
|
+
title?: string
|
|
197
|
+
toolCalls?: number
|
|
198
|
+
lastUpdatedAt: number
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export type FooterSubagentDetail = {
|
|
202
|
+
sessionID: string
|
|
203
|
+
commits: StreamCommit[]
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export type FooterSubagentState = {
|
|
207
|
+
tabs: FooterSubagentTab[]
|
|
208
|
+
details: Record<string, FooterSubagentDetail>
|
|
209
|
+
permissions: PermissionRequest[]
|
|
210
|
+
questions: QuestionRequest[]
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// The reducer emits this alongside scrollback commits so the footer can update in the same frame.
|
|
214
|
+
export type FooterOutput = {
|
|
215
|
+
patch?: FooterPatch
|
|
216
|
+
view?: FooterView
|
|
217
|
+
subagent?: FooterSubagentState
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Typed messages sent to RunFooter.event(). The prompt queue and stream
|
|
221
|
+
// transport both emit these to update footer state without reaching into
|
|
222
|
+
// internal signals directly.
|
|
223
|
+
export type FooterEvent =
|
|
224
|
+
| {
|
|
225
|
+
type: "catalog"
|
|
226
|
+
agents: RunAgent[]
|
|
227
|
+
resources: RunResource[]
|
|
228
|
+
commands?: RunCommand[]
|
|
229
|
+
}
|
|
230
|
+
| {
|
|
231
|
+
type: "models"
|
|
232
|
+
providers: RunProvider[]
|
|
233
|
+
}
|
|
234
|
+
| {
|
|
235
|
+
type: "variants"
|
|
236
|
+
variants: string[]
|
|
237
|
+
current: string | undefined
|
|
238
|
+
}
|
|
239
|
+
| {
|
|
240
|
+
type: "queue"
|
|
241
|
+
queue: number
|
|
242
|
+
}
|
|
243
|
+
| {
|
|
244
|
+
type: "queued.prompts"
|
|
245
|
+
prompts: FooterQueuedPrompt[]
|
|
246
|
+
}
|
|
247
|
+
| {
|
|
248
|
+
type: "first"
|
|
249
|
+
first: boolean
|
|
250
|
+
}
|
|
251
|
+
| {
|
|
252
|
+
type: "model"
|
|
253
|
+
model: string
|
|
254
|
+
}
|
|
255
|
+
| {
|
|
256
|
+
type: "turn.send"
|
|
257
|
+
queue: number
|
|
258
|
+
}
|
|
259
|
+
| {
|
|
260
|
+
type: "turn.wait"
|
|
261
|
+
}
|
|
262
|
+
| {
|
|
263
|
+
type: "turn.idle"
|
|
264
|
+
queue: number
|
|
265
|
+
}
|
|
266
|
+
| {
|
|
267
|
+
type: "turn.duration"
|
|
268
|
+
duration: string
|
|
269
|
+
}
|
|
270
|
+
| {
|
|
271
|
+
type: "stream.patch"
|
|
272
|
+
patch: FooterPatch
|
|
273
|
+
}
|
|
274
|
+
| {
|
|
275
|
+
type: "stream.view"
|
|
276
|
+
view: FooterView
|
|
277
|
+
}
|
|
278
|
+
| {
|
|
279
|
+
type: "stream.subagent"
|
|
280
|
+
state: FooterSubagentState
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
export type PermissionReply = Parameters<RimuruClient["permission"]["reply"]>[0]
|
|
284
|
+
|
|
285
|
+
export type QuestionReply = Parameters<RimuruClient["question"]["reply"]>[0]
|
|
286
|
+
|
|
287
|
+
export type QuestionReject = Parameters<RimuruClient["question"]["reject"]>[0]
|
|
288
|
+
|
|
289
|
+
export type RunTuiConfig = Pick<TuiConfig.Resolved, "keybinds" | "leader_timeout" | "diff_style">
|
|
290
|
+
|
|
291
|
+
// Lifecycle phase of a scrollback entry. "start" opens the entry, "progress"
|
|
292
|
+
// appends content (coalesced in the footer queue), "final" closes it.
|
|
293
|
+
export type StreamPhase = "start" | "progress" | "final"
|
|
294
|
+
|
|
295
|
+
export type StreamSource = "assistant" | "reasoning" | "tool" | "system"
|
|
296
|
+
|
|
297
|
+
export type StreamToolState = "running" | "completed" | "error"
|
|
298
|
+
|
|
299
|
+
// A single append-only commit to scrollback. The session-data reducer produces
|
|
300
|
+
// these from SDK events, and RunFooter.append() queues them for the next
|
|
301
|
+
// microtask flush. Once flushed, they become immutable terminal scrollback
|
|
302
|
+
// rows -- they cannot be rewritten.
|
|
303
|
+
export type StreamCommit = {
|
|
304
|
+
kind: EntryKind
|
|
305
|
+
text: string
|
|
306
|
+
phase: StreamPhase
|
|
307
|
+
source: StreamSource
|
|
308
|
+
summary?: TurnSummary
|
|
309
|
+
messageID?: string
|
|
310
|
+
partID?: string
|
|
311
|
+
tool?: string
|
|
312
|
+
part?: ToolPart
|
|
313
|
+
interrupted?: boolean
|
|
314
|
+
toolState?: StreamToolState
|
|
315
|
+
toolError?: string
|
|
316
|
+
shell?: {
|
|
317
|
+
callID: string
|
|
318
|
+
command: string
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
export type LocalReplayAnchor = {
|
|
323
|
+
kind: EntryKind
|
|
324
|
+
text: string
|
|
325
|
+
phase: StreamPhase
|
|
326
|
+
messageID?: string
|
|
327
|
+
partID?: string
|
|
328
|
+
toolState?: StreamToolState
|
|
329
|
+
visible?: string
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
export type LocalReplayRow = {
|
|
333
|
+
commit: StreamCommit
|
|
334
|
+
after?: LocalReplayAnchor
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// The public contract between the stream transport / prompt queue and
|
|
338
|
+
// the footer. RunFooter implements this. The transport and queue never
|
|
339
|
+
// touch the renderer directly -- they go through this interface.
|
|
340
|
+
export type FooterApi = {
|
|
341
|
+
readonly isClosed: boolean
|
|
342
|
+
onPrompt(fn: (input: RunPrompt) => void): () => void
|
|
343
|
+
onQueuedRemove(fn: (messageID: string) => boolean | Promise<boolean>): () => void
|
|
344
|
+
onClose(fn: () => void): () => void
|
|
345
|
+
event(next: FooterEvent): void
|
|
346
|
+
append(commit: StreamCommit): void
|
|
347
|
+
idle(): Promise<void>
|
|
348
|
+
close(): void
|
|
349
|
+
destroy(): void
|
|
350
|
+
}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
// Model variant resolution and persistence.
|
|
2
|
+
//
|
|
3
|
+
// Variants are provider-specific reasoning effort levels (e.g., "high", "max").
|
|
4
|
+
// Resolution priority: CLI --variant flag > saved preference > session history.
|
|
5
|
+
//
|
|
6
|
+
// The saved variant persists across sessions in ~/.local/state/rimuru/model.json
|
|
7
|
+
// so your last-used variant sticks. Cycling (ctrl+t) updates both the active
|
|
8
|
+
// variant and the persisted file.
|
|
9
|
+
import path from "path"
|
|
10
|
+
import { FSUtil } from "@rimurucode-ai/core/fs-util"
|
|
11
|
+
import { Context, Effect, Layer } from "effect"
|
|
12
|
+
import { makeRuntime } from "@/effect/run-service"
|
|
13
|
+
import { Global } from "@rimurucode-ai/core/global"
|
|
14
|
+
import { isRecord } from "@/util/record"
|
|
15
|
+
import { createSession, sessionVariant, type RunSession, type SessionMessages } from "./session.shared"
|
|
16
|
+
import type { RunInput, RunProvider } from "./types"
|
|
17
|
+
|
|
18
|
+
const MODEL_FILE = path.join(Global.Path.state, "model.json")
|
|
19
|
+
|
|
20
|
+
type ModelState = Record<string, unknown> & {
|
|
21
|
+
variant?: Record<string, string | undefined>
|
|
22
|
+
}
|
|
23
|
+
type VariantService = {
|
|
24
|
+
readonly resolveSavedVariant: (model: RunInput["model"]) => Effect.Effect<string | undefined>
|
|
25
|
+
readonly saveVariant: (model: RunInput["model"], variant: string | undefined) => Effect.Effect<void>
|
|
26
|
+
}
|
|
27
|
+
type VariantRuntime = {
|
|
28
|
+
resolveSavedVariant(model: RunInput["model"]): Promise<string | undefined>
|
|
29
|
+
saveVariant(model: RunInput["model"], variant: string | undefined): Promise<void>
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
class Service extends Context.Service<Service, VariantService>()("@rimuru/RunVariant") {}
|
|
33
|
+
|
|
34
|
+
function modelKey(provider: string, model: string): string {
|
|
35
|
+
return `${provider}/${model}`
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function variantKey(model: NonNullable<RunInput["model"]>): string {
|
|
39
|
+
return modelKey(model.providerID, model.modelID)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function modelInfo(providers: RunProvider[] | undefined, model: NonNullable<RunInput["model"]>) {
|
|
43
|
+
const provider = providers?.find((item) => item.id === model.providerID)
|
|
44
|
+
return {
|
|
45
|
+
provider: provider?.name ?? model.providerID,
|
|
46
|
+
model: provider?.models[model.modelID]?.name ?? model.modelID,
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function formatModelLabel(
|
|
51
|
+
model: NonNullable<RunInput["model"]>,
|
|
52
|
+
variant: string | undefined,
|
|
53
|
+
providers?: RunProvider[],
|
|
54
|
+
): string {
|
|
55
|
+
const names = modelInfo(providers, model)
|
|
56
|
+
const label = variant ? ` · ${variant}` : ""
|
|
57
|
+
return `${names.model} · ${names.provider}${label}`
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function cycleVariant(current: string | undefined, variants: string[]): string | undefined {
|
|
61
|
+
if (variants.length === 0) {
|
|
62
|
+
return undefined
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (!current) {
|
|
66
|
+
return variants[0]
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const idx = variants.indexOf(current)
|
|
70
|
+
if (idx === -1 || idx === variants.length - 1) {
|
|
71
|
+
return undefined
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return variants[idx + 1]
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function pickVariant(model: RunInput["model"], input: RunSession | SessionMessages): string | undefined {
|
|
78
|
+
return sessionVariant(Array.isArray(input) ? createSession(input) : input, model)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function fitVariant(value: string | undefined, variants: string[]): string | undefined {
|
|
82
|
+
if (!value) {
|
|
83
|
+
return undefined
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (variants.length === 0 || variants.includes(value)) {
|
|
87
|
+
return value
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return undefined
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Picks the active variant. CLI flag wins, then saved preference, then session
|
|
94
|
+
// history. fitVariant() checks saved and session values against the available
|
|
95
|
+
// variants list -- if the provider doesn't offer a variant, it drops.
|
|
96
|
+
export function resolveVariant(
|
|
97
|
+
input: string | undefined,
|
|
98
|
+
session: string | undefined,
|
|
99
|
+
saved: string | undefined,
|
|
100
|
+
variants: string[],
|
|
101
|
+
): string | undefined {
|
|
102
|
+
if (input !== undefined) {
|
|
103
|
+
return input
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const fallback = fitVariant(saved, variants)
|
|
107
|
+
const current = fitVariant(session, variants)
|
|
108
|
+
if (current !== undefined) {
|
|
109
|
+
return current
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return fallback
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function state(value: unknown): ModelState {
|
|
116
|
+
if (!isRecord(value)) {
|
|
117
|
+
return {}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const variant = isRecord(value.variant)
|
|
121
|
+
? Object.fromEntries(
|
|
122
|
+
Object.entries(value.variant).flatMap(([key, item]) => {
|
|
123
|
+
if (typeof item !== "string") {
|
|
124
|
+
return []
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return [[key, item] as const]
|
|
128
|
+
}),
|
|
129
|
+
)
|
|
130
|
+
: undefined
|
|
131
|
+
|
|
132
|
+
return {
|
|
133
|
+
...value,
|
|
134
|
+
variant,
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function createLayer(fs = FSUtil.defaultLayer) {
|
|
139
|
+
return Layer.fresh(
|
|
140
|
+
Layer.effect(
|
|
141
|
+
Service,
|
|
142
|
+
Effect.gen(function* () {
|
|
143
|
+
const file = yield* FSUtil.Service
|
|
144
|
+
|
|
145
|
+
const read = Effect.fn("RunVariant.read")(function* () {
|
|
146
|
+
return yield* file.readJson(MODEL_FILE).pipe(
|
|
147
|
+
Effect.map(state),
|
|
148
|
+
Effect.catchCause(() => Effect.succeed(state(undefined))),
|
|
149
|
+
)
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
const resolveSavedVariant = Effect.fn("RunVariant.resolveSavedVariant")(function* (model: RunInput["model"]) {
|
|
153
|
+
if (!model) {
|
|
154
|
+
return undefined
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return (yield* read()).variant?.[variantKey(model)]
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
const saveVariant = Effect.fn("RunVariant.saveVariant")(function* (
|
|
161
|
+
model: RunInput["model"],
|
|
162
|
+
variant: string | undefined,
|
|
163
|
+
) {
|
|
164
|
+
if (!model) {
|
|
165
|
+
return
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const current = yield* read()
|
|
169
|
+
const next = {
|
|
170
|
+
...current.variant,
|
|
171
|
+
}
|
|
172
|
+
const key = variantKey(model)
|
|
173
|
+
if (variant) {
|
|
174
|
+
next[key] = variant
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (!variant) {
|
|
178
|
+
delete next[key]
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
yield* file
|
|
182
|
+
.writeJson(MODEL_FILE, {
|
|
183
|
+
...current,
|
|
184
|
+
variant: next,
|
|
185
|
+
})
|
|
186
|
+
.pipe(Effect.orElseSucceed(() => undefined))
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
return Service.of({
|
|
190
|
+
resolveSavedVariant,
|
|
191
|
+
saveVariant,
|
|
192
|
+
})
|
|
193
|
+
}),
|
|
194
|
+
).pipe(Layer.provide(fs)),
|
|
195
|
+
)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/** @internal Exported for testing. */
|
|
199
|
+
export function createVariantRuntime(fs = FSUtil.defaultLayer): VariantRuntime {
|
|
200
|
+
const runtime = makeRuntime(Service, createLayer(fs))
|
|
201
|
+
return {
|
|
202
|
+
resolveSavedVariant: (model) => runtime.runPromise((svc) => svc.resolveSavedVariant(model)).catch(() => undefined),
|
|
203
|
+
saveVariant: (model, variant) => runtime.runPromise((svc) => svc.saveVariant(model, variant)).catch(() => {}),
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const runtime = createVariantRuntime()
|
|
208
|
+
|
|
209
|
+
export async function resolveSavedVariant(model: RunInput["model"]): Promise<string | undefined> {
|
|
210
|
+
return runtime.resolveSavedVariant(model)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export function saveVariant(model: RunInput["model"], variant: string | undefined): void {
|
|
214
|
+
void runtime.saveVariant(model, variant)
|
|
215
|
+
}
|