@cloudcli-ai/cloudcli 1.36.2 → 1.37.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/dist/assets/index-DSlds633.css +32 -0
- package/dist/assets/{index-CDGzV0LN.js → index-eGqPeIEu.js} +375 -267
- package/dist/index.html +2 -2
- package/dist-server/server/constants/config.js.map +1 -1
- package/dist-server/server/index.js +73 -1224
- package/dist-server/server/index.js.map +1 -1
- package/dist-server/server/load-env.js +17 -4
- package/dist-server/server/load-env.js.map +1 -1
- package/dist-server/server/modules/agent/agent.module.js +37 -0
- package/dist-server/server/modules/agent/agent.module.js.map +1 -0
- package/dist-server/server/modules/agent/agent.routes.js +1161 -0
- package/dist-server/server/modules/agent/agent.routes.js.map +1 -0
- package/dist-server/server/modules/agent/index.js +3 -0
- package/dist-server/server/modules/agent/index.js.map +1 -0
- package/dist-server/server/modules/agent/tests/agent.routes.test.js +176 -0
- package/dist-server/server/modules/agent/tests/agent.routes.test.js.map +1 -0
- package/dist-server/server/modules/assets/assets.routes.js +56 -15
- package/dist-server/server/modules/assets/assets.routes.js.map +1 -1
- package/dist-server/server/modules/assets/index.js +2 -2
- package/dist-server/server/modules/assets/index.js.map +1 -1
- package/dist-server/server/modules/assets/services/image-assets.service.js +39 -1
- package/dist-server/server/modules/assets/services/image-assets.service.js.map +1 -1
- package/dist-server/server/modules/assets/tests/image-assets.service.test.js +21 -1
- package/dist-server/server/modules/assets/tests/image-assets.service.test.js.map +1 -1
- package/dist-server/server/{middleware/auth.js → modules/auth/auth.middleware.js} +30 -8
- package/dist-server/server/modules/auth/auth.middleware.js.map +1 -0
- package/dist-server/server/modules/auth/auth.module.js +29 -0
- package/dist-server/server/modules/auth/auth.module.js.map +1 -0
- package/dist-server/server/modules/auth/auth.routes.js +45 -0
- package/dist-server/server/modules/auth/auth.routes.js.map +1 -0
- package/dist-server/server/modules/auth/auth.service.js +113 -0
- package/dist-server/server/modules/auth/auth.service.js.map +1 -0
- package/dist-server/server/modules/auth/index.js +9 -0
- package/dist-server/server/modules/auth/index.js.map +1 -0
- package/dist-server/server/modules/auth/tests/auth.service.test.js +80 -0
- package/dist-server/server/modules/auth/tests/auth.service.test.js.map +1 -0
- package/dist-server/server/{browser-use-mcp.js → modules/browser-use/browser-use-mcp.js} +3 -1
- package/dist-server/server/modules/browser-use/browser-use-mcp.js.map +1 -0
- package/dist-server/server/modules/browser-use/browser-use.service.js +3 -4
- package/dist-server/server/modules/browser-use/browser-use.service.js.map +1 -1
- package/dist-server/server/modules/browser-use/index.js +9 -0
- package/dist-server/server/modules/browser-use/index.js.map +1 -0
- package/dist-server/server/modules/cli/cli.js +11 -0
- package/dist-server/server/modules/cli/cli.js.map +1 -0
- package/dist-server/server/modules/cli/cli.module.js +86 -0
- package/dist-server/server/modules/cli/cli.module.js.map +1 -0
- package/dist-server/server/modules/cli/cli.service.js +244 -0
- package/dist-server/server/modules/cli/cli.service.js.map +1 -0
- package/dist-server/server/modules/cli/index.js +3 -0
- package/dist-server/server/modules/cli/index.js.map +1 -0
- package/dist-server/server/modules/cli/sandbox.service.js +332 -0
- package/dist-server/server/modules/cli/sandbox.service.js.map +1 -0
- package/dist-server/server/modules/cli/tests/cli.service.test.js +78 -0
- package/dist-server/server/modules/cli/tests/cli.service.test.js.map +1 -0
- package/dist-server/server/modules/cli/tests/sandbox.service.test.js +55 -0
- package/dist-server/server/modules/cli/tests/sandbox.service.test.js.map +1 -0
- package/dist-server/server/modules/commands/commands.module.js +20 -0
- package/dist-server/server/modules/commands/commands.module.js.map +1 -0
- package/dist-server/server/modules/commands/commands.routes.js +497 -0
- package/dist-server/server/modules/commands/commands.routes.js.map +1 -0
- package/dist-server/server/modules/commands/index.js +3 -0
- package/dist-server/server/modules/commands/index.js.map +1 -0
- package/dist-server/server/modules/commands/tests/commands.test.js +96 -0
- package/dist-server/server/modules/commands/tests/commands.test.js.map +1 -0
- package/dist-server/server/modules/database/index.js +1 -0
- package/dist-server/server/modules/database/index.js.map +1 -1
- package/dist-server/server/modules/database/migrations.js +13 -0
- package/dist-server/server/modules/database/migrations.js.map +1 -1
- package/dist-server/server/modules/database/repositories/sessions.db.js +14 -1
- package/dist-server/server/modules/database/repositories/sessions.db.js.map +1 -1
- package/dist-server/server/modules/database/schema.js +4 -0
- package/dist-server/server/modules/database/schema.js.map +1 -1
- package/dist-server/server/modules/file-tree/file-tree.module.js +91 -0
- package/dist-server/server/modules/file-tree/file-tree.module.js.map +1 -0
- package/dist-server/server/modules/file-tree/file-tree.routes.js +208 -0
- package/dist-server/server/modules/file-tree/file-tree.routes.js.map +1 -0
- package/dist-server/server/modules/file-tree/file-tree.service.js +544 -0
- package/dist-server/server/modules/file-tree/file-tree.service.js.map +1 -0
- package/dist-server/server/modules/file-tree/index.js +3 -0
- package/dist-server/server/modules/file-tree/index.js.map +1 -0
- package/dist-server/server/modules/file-tree/tests/file-tree.routes.test.js +123 -0
- package/dist-server/server/modules/file-tree/tests/file-tree.routes.test.js.map +1 -0
- package/dist-server/server/modules/file-tree/tests/file-tree.service.test.js +184 -0
- package/dist-server/server/modules/file-tree/tests/file-tree.service.test.js.map +1 -0
- package/dist-server/server/modules/git/git-parsing.service.js +61 -0
- package/dist-server/server/modules/git/git-parsing.service.js.map +1 -0
- package/dist-server/server/modules/git/git.module.js +14 -0
- package/dist-server/server/modules/git/git.module.js.map +1 -0
- package/dist-server/server/modules/git/git.routes.js +1339 -0
- package/dist-server/server/modules/git/git.routes.js.map +1 -0
- package/dist-server/server/modules/git/index.js +3 -0
- package/dist-server/server/modules/git/index.js.map +1 -0
- package/dist-server/server/modules/git/tests/git-init.routes.test.js +48 -0
- package/dist-server/server/modules/git/tests/git-init.routes.test.js.map +1 -0
- package/dist-server/server/{routes → modules/git/tests}/git.test.js +1 -1
- package/dist-server/server/modules/git/tests/git.test.js.map +1 -0
- package/dist-server/server/modules/notifications/index.js +15 -1
- package/dist-server/server/modules/notifications/index.js.map +1 -1
- package/dist-server/server/modules/notifications/tests/notification-orchestrator.integration.test.js +44 -0
- package/dist-server/server/modules/notifications/tests/notification-orchestrator.integration.test.js.map +1 -0
- package/dist-server/server/{services/vapid-keys.js → modules/notifications/vapid-keys.service.js} +3 -2
- package/dist-server/server/modules/notifications/vapid-keys.service.js.map +1 -0
- package/dist-server/server/modules/plugins/index.js +9 -0
- package/dist-server/server/modules/plugins/index.js.map +1 -0
- package/dist-server/server/{utils/plugin-process-manager.js → modules/plugins/plugin-process.service.js} +3 -2
- package/dist-server/server/modules/plugins/plugin-process.service.js.map +1 -0
- package/dist-server/server/{utils/plugin-loader.js → modules/plugins/plugin-registry.service.js} +2 -1
- package/dist-server/server/modules/plugins/plugin-registry.service.js.map +1 -0
- package/dist-server/server/modules/plugins/plugins.module.js +30 -0
- package/dist-server/server/modules/plugins/plugins.module.js.map +1 -0
- package/dist-server/server/modules/plugins/plugins.routes.js +70 -0
- package/dist-server/server/modules/plugins/plugins.routes.js.map +1 -0
- package/dist-server/server/modules/plugins/plugins.service.js +123 -0
- package/dist-server/server/modules/plugins/plugins.service.js.map +1 -0
- package/dist-server/server/modules/plugins/tests/plugins.service.test.js +28 -0
- package/dist-server/server/modules/plugins/tests/plugins.service.test.js.map +1 -0
- package/dist-server/server/modules/projects/index.js +5 -0
- package/dist-server/server/modules/projects/index.js.map +1 -1
- package/dist-server/server/modules/providers/index.js +3 -0
- package/dist-server/server/modules/providers/index.js.map +1 -1
- package/dist-server/server/modules/providers/list/claude/claude-auth.provider.js +6 -0
- package/dist-server/server/modules/providers/list/claude/claude-auth.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/claude/claude-models.provider.js +1 -4
- package/dist-server/server/modules/providers/list/claude/claude-models.provider.js.map +1 -1
- package/dist-server/server/{claude-sdk.js → modules/providers/list/claude/claude-runtime.provider.js} +62 -41
- package/dist-server/server/modules/providers/list/claude/claude-runtime.provider.js.map +1 -0
- package/dist-server/server/modules/providers/list/claude/claude-session-synchronizer.provider.js +6 -4
- package/dist-server/server/modules/providers/list/claude/claude-session-synchronizer.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js +23 -4
- package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/claude/claude.provider.js +2 -0
- package/dist-server/server/modules/providers/list/claude/claude.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-models.provider.js +1 -4
- package/dist-server/server/modules/providers/list/codex/codex-models.provider.js.map +1 -1
- package/dist-server/server/{openai-codex.js → modules/providers/list/codex/codex-runtime.provider.js} +48 -34
- package/dist-server/server/modules/providers/list/codex/codex-runtime.provider.js.map +1 -0
- package/dist-server/server/modules/providers/list/codex/codex-session-synchronizer.provider.js +19 -1
- package/dist-server/server/modules/providers/list/codex/codex-session-synchronizer.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js +290 -6
- package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-skills.provider.js +5 -0
- package/dist-server/server/modules/providers/list/codex/codex-skills.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex.provider.js +2 -0
- package/dist-server/server/modules/providers/list/codex/codex.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js +1 -4
- package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js.map +1 -1
- package/dist-server/server/{cursor-cli.js → modules/providers/list/cursor/cursor-runtime.provider.js} +40 -28
- package/dist-server/server/modules/providers/list/cursor/cursor-runtime.provider.js.map +1 -0
- package/dist-server/server/modules/providers/list/cursor/cursor-sessions.provider.js +21 -14
- package/dist-server/server/modules/providers/list/cursor/cursor-sessions.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/cursor/cursor.provider.js +2 -0
- package/dist-server/server/modules/providers/list/cursor/cursor.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js +7 -5
- package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js.map +1 -1
- package/dist-server/server/{opencode-cli.js → modules/providers/list/opencode/opencode-runtime.provider.js} +38 -25
- package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.js.map +1 -0
- package/dist-server/server/{opencode-cli.test.js → modules/providers/list/opencode/opencode-runtime.provider.test.js} +27 -4
- package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.test.js.map +1 -0
- package/dist-server/server/modules/providers/list/opencode/opencode-sessions.provider.js +11 -5
- package/dist-server/server/modules/providers/list/opencode/opencode-sessions.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/opencode/opencode.provider.js +2 -0
- package/dist-server/server/modules/providers/list/opencode/opencode.provider.js.map +1 -1
- package/dist-server/server/modules/providers/provider.routes.js +33 -9
- package/dist-server/server/modules/providers/provider.routes.js.map +1 -1
- package/dist-server/server/modules/providers/services/provider-capabilities.service.js +5 -1
- package/dist-server/server/modules/providers/services/provider-capabilities.service.js.map +1 -1
- package/dist-server/server/modules/providers/services/provider-models.service.js +110 -15
- package/dist-server/server/modules/providers/services/provider-models.service.js.map +1 -1
- package/dist-server/server/modules/providers/services/provider-runtime.service.js +66 -0
- package/dist-server/server/modules/providers/services/provider-runtime.service.js.map +1 -0
- package/dist-server/server/modules/providers/services/provider-token-usage.service.js +268 -0
- package/dist-server/server/modules/providers/services/provider-token-usage.service.js.map +1 -0
- package/dist-server/server/modules/providers/services/sessions-watcher.service.js +2 -0
- package/dist-server/server/modules/providers/services/sessions-watcher.service.js.map +1 -1
- package/dist-server/server/modules/providers/services/sessions.service.js +54 -0
- package/dist-server/server/modules/providers/services/sessions.service.js.map +1 -1
- package/dist-server/server/modules/providers/shared/base/abstract.provider.js +2 -3
- package/dist-server/server/modules/providers/shared/base/abstract.provider.js.map +1 -1
- package/dist-server/server/modules/providers/tests/claude-auth.test.js +122 -0
- package/dist-server/server/modules/providers/tests/claude-auth.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/claude-sessions.test.js +44 -0
- package/dist-server/server/modules/providers/tests/claude-sessions.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/codex-sessions.test.js +70 -0
- package/dist-server/server/modules/providers/tests/codex-sessions.test.js.map +1 -1
- package/dist-server/server/modules/providers/tests/{provider-image-history.test.js → provider-attachment-history.test.js} +60 -2
- package/dist-server/server/modules/providers/tests/provider-attachment-history.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/provider-models.service.test.js +148 -61
- package/dist-server/server/modules/providers/tests/provider-models.service.test.js.map +1 -1
- package/dist-server/server/modules/providers/tests/provider-runtime.service.test.js +130 -0
- package/dist-server/server/modules/providers/tests/provider-runtime.service.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js +165 -0
- package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/sessions-details.test.js +62 -0
- package/dist-server/server/modules/providers/tests/sessions-details.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/skills.test.js +4 -2
- package/dist-server/server/modules/providers/tests/skills.test.js.map +1 -1
- package/dist-server/server/modules/settings/index.js +3 -0
- package/dist-server/server/modules/settings/index.js.map +1 -0
- package/dist-server/server/modules/settings/settings.module.js +35 -0
- package/dist-server/server/modules/settings/settings.module.js.map +1 -0
- package/dist-server/server/modules/settings/settings.routes.js +34 -0
- package/dist-server/server/modules/settings/settings.routes.js.map +1 -0
- package/dist-server/server/modules/settings/settings.service.js +116 -0
- package/dist-server/server/modules/settings/settings.service.js.map +1 -0
- package/dist-server/server/modules/settings/tests/settings.service.test.js +48 -0
- package/dist-server/server/modules/settings/tests/settings.service.test.js.map +1 -0
- package/dist-server/server/modules/system/index.js +3 -0
- package/dist-server/server/modules/system/index.js.map +1 -0
- package/dist-server/server/modules/system/system.module.js +44 -0
- package/dist-server/server/modules/system/system.module.js.map +1 -0
- package/dist-server/server/modules/system/system.routes.js +16 -0
- package/dist-server/server/modules/system/system.routes.js.map +1 -0
- package/dist-server/server/modules/system/system.service.js +45 -0
- package/dist-server/server/modules/system/system.service.js.map +1 -0
- package/dist-server/server/modules/system/tests/system.service.test.js +100 -0
- package/dist-server/server/modules/system/tests/system.service.test.js.map +1 -0
- package/dist-server/server/modules/taskmaster/index.js +3 -0
- package/dist-server/server/modules/taskmaster/index.js.map +1 -0
- package/dist-server/server/modules/taskmaster/taskmaster.module.js +20 -0
- package/dist-server/server/modules/taskmaster/taskmaster.module.js.map +1 -0
- package/dist-server/server/modules/taskmaster/taskmaster.routes.js +1372 -0
- package/dist-server/server/modules/taskmaster/taskmaster.routes.js.map +1 -0
- package/dist-server/server/modules/taskmaster/taskmaster.service.js +107 -0
- package/dist-server/server/modules/taskmaster/taskmaster.service.js.map +1 -0
- package/dist-server/server/modules/taskmaster/tests/taskmaster.routes.test.js +132 -0
- package/dist-server/server/modules/taskmaster/tests/taskmaster.routes.test.js.map +1 -0
- package/dist-server/server/modules/taskmaster/tests/taskmaster.service.test.js +85 -0
- package/dist-server/server/modules/taskmaster/tests/taskmaster.service.test.js.map +1 -0
- package/dist-server/server/modules/user/index.js +3 -0
- package/dist-server/server/modules/user/index.js.map +1 -0
- package/dist-server/server/modules/user/tests/user.service.test.js +53 -0
- package/dist-server/server/modules/user/tests/user.service.test.js.map +1 -0
- package/dist-server/server/modules/user/user.module.js +47 -0
- package/dist-server/server/modules/user/user.module.js.map +1 -0
- package/dist-server/server/modules/user/user.routes.js +44 -0
- package/dist-server/server/modules/user/user.routes.js.map +1 -0
- package/dist-server/server/modules/user/user.service.js +59 -0
- package/dist-server/server/modules/user/user.service.js.map +1 -0
- package/dist-server/server/modules/voice/index.js +3 -0
- package/dist-server/server/modules/voice/index.js.map +1 -0
- package/dist-server/server/modules/voice/tests/voice.service.test.js +86 -0
- package/dist-server/server/modules/voice/tests/voice.service.test.js.map +1 -0
- package/dist-server/server/modules/voice/voice.module.js +44 -0
- package/dist-server/server/modules/voice/voice.module.js.map +1 -0
- package/dist-server/server/modules/voice/voice.routes.js +87 -0
- package/dist-server/server/modules/voice/voice.routes.js.map +1 -0
- package/dist-server/server/modules/voice/voice.service.js +148 -0
- package/dist-server/server/modules/voice/voice.service.js.map +1 -0
- package/dist-server/server/modules/websocket/services/chat-session-writer.service.js +2 -2
- package/dist-server/server/modules/websocket/services/chat-websocket.service.js +40 -29
- package/dist-server/server/modules/websocket/services/chat-websocket.service.js.map +1 -1
- package/dist-server/server/modules/websocket/services/shell-websocket.service.js +76 -8
- package/dist-server/server/modules/websocket/services/shell-websocket.service.js.map +1 -1
- package/dist-server/server/modules/websocket/services/websocket-server.service.js +51 -20
- package/dist-server/server/modules/websocket/services/websocket-server.service.js.map +1 -1
- package/dist-server/server/modules/websocket/tests/{chat-image-filter.test.js → chat-attachment-filter.test.js} +10 -3
- package/dist-server/server/modules/websocket/tests/chat-attachment-filter.test.js.map +1 -0
- package/dist-server/server/modules/websocket/tests/shell-websocket.service.test.js +97 -0
- package/dist-server/server/modules/websocket/tests/shell-websocket.service.test.js.map +1 -0
- package/dist-server/server/modules/websocket/tests/websocket-heartbeat.service.test.js +61 -0
- package/dist-server/server/modules/websocket/tests/websocket-heartbeat.service.test.js.map +1 -0
- package/dist-server/server/modules/worktrees/index.js +3 -0
- package/dist-server/server/modules/worktrees/index.js.map +1 -0
- package/dist-server/server/modules/worktrees/services/worktree-create-and-open.service.js +37 -0
- package/dist-server/server/modules/worktrees/services/worktree-create-and-open.service.js.map +1 -0
- package/dist-server/server/modules/worktrees/services/worktree-create.service.js +67 -0
- package/dist-server/server/modules/worktrees/services/worktree-create.service.js.map +1 -0
- package/dist-server/server/modules/worktrees/services/worktree-git.service.js +172 -0
- package/dist-server/server/modules/worktrees/services/worktree-git.service.js.map +1 -0
- package/dist-server/server/modules/worktrees/services/worktree-list.service.js +91 -0
- package/dist-server/server/modules/worktrees/services/worktree-list.service.js.map +1 -0
- package/dist-server/server/modules/worktrees/services/worktree-merge.service.js +118 -0
- package/dist-server/server/modules/worktrees/services/worktree-merge.service.js.map +1 -0
- package/dist-server/server/modules/worktrees/services/worktree-open.service.js +58 -0
- package/dist-server/server/modules/worktrees/services/worktree-open.service.js.map +1 -0
- package/dist-server/server/modules/worktrees/services/worktree-remove.service.js +65 -0
- package/dist-server/server/modules/worktrees/services/worktree-remove.service.js.map +1 -0
- package/dist-server/server/modules/worktrees/tests/worktree-create-and-open.service.test.js +58 -0
- package/dist-server/server/modules/worktrees/tests/worktree-create-and-open.service.test.js.map +1 -0
- package/dist-server/server/modules/worktrees/tests/worktree-create.service.test.js +85 -0
- package/dist-server/server/modules/worktrees/tests/worktree-create.service.test.js.map +1 -0
- package/dist-server/server/modules/worktrees/tests/worktree-git.service.test.js +58 -0
- package/dist-server/server/modules/worktrees/tests/worktree-git.service.test.js.map +1 -0
- package/dist-server/server/modules/worktrees/tests/worktree-list.service.test.js +34 -0
- package/dist-server/server/modules/worktrees/tests/worktree-list.service.test.js.map +1 -0
- package/dist-server/server/modules/worktrees/tests/worktree-merge.service.test.js +137 -0
- package/dist-server/server/modules/worktrees/tests/worktree-merge.service.test.js.map +1 -0
- package/dist-server/server/modules/worktrees/tests/worktree-open.service.test.js +99 -0
- package/dist-server/server/modules/worktrees/tests/worktree-open.service.test.js.map +1 -0
- package/dist-server/server/modules/worktrees/tests/worktree-remove.service.test.js +157 -0
- package/dist-server/server/modules/worktrees/tests/worktree-remove.service.test.js.map +1 -0
- package/dist-server/server/modules/worktrees/tests/worktrees.routes.test.js +167 -0
- package/dist-server/server/modules/worktrees/tests/worktrees.routes.test.js.map +1 -0
- package/dist-server/server/modules/worktrees/worktrees.module.js +97 -0
- package/dist-server/server/modules/worktrees/worktrees.module.js.map +1 -0
- package/dist-server/server/modules/worktrees/worktrees.routes.js +84 -0
- package/dist-server/server/modules/worktrees/worktrees.routes.js.map +1 -0
- package/dist-server/server/shared/image-attachments.js +90 -17
- package/dist-server/server/shared/image-attachments.js.map +1 -1
- package/dist-server/server/shared/tests/image-attachments.test.js +43 -1
- package/dist-server/server/shared/tests/image-attachments.test.js.map +1 -1
- package/dist-server/server/shared/utils.js +66 -142
- package/dist-server/server/shared/utils.js.map +1 -1
- package/electron/localServer.js +1 -2
- package/package.json +8 -4
- package/server/index.ts +401 -0
- package/server/{load-env.js → load-env.ts} +18 -5
- package/server/modules/agent/agent.module.ts +51 -0
- package/server/modules/agent/agent.routes.ts +1287 -0
- package/server/modules/agent/index.ts +2 -0
- package/server/modules/agent/tests/agent.routes.test.ts +205 -0
- package/server/modules/assets/assets.routes.ts +63 -16
- package/server/modules/assets/index.ts +2 -2
- package/server/modules/assets/services/image-assets.service.ts +46 -1
- package/server/modules/assets/tests/image-assets.service.test.ts +28 -0
- package/server/{middleware/auth.js → modules/auth/auth.middleware.ts} +38 -7
- package/server/modules/auth/auth.module.ts +38 -0
- package/server/modules/auth/auth.routes.ts +57 -0
- package/server/modules/auth/auth.service.ts +155 -0
- package/server/modules/auth/index.ts +9 -0
- package/server/modules/auth/tests/auth.service.test.ts +95 -0
- package/server/{browser-use-mcp.ts → modules/browser-use/browser-use-mcp.ts} +3 -1
- package/server/modules/browser-use/browser-use.service.ts +3 -4
- package/server/modules/browser-use/index.ts +8 -0
- package/server/modules/cli/cli.module.ts +96 -0
- package/server/modules/cli/cli.service.ts +281 -0
- package/server/modules/cli/cli.ts +13 -0
- package/server/modules/cli/index.ts +2 -0
- package/server/modules/cli/sandbox.service.ts +413 -0
- package/server/modules/cli/tests/cli.service.test.ts +91 -0
- package/server/modules/cli/tests/sandbox.service.test.ts +61 -0
- package/server/modules/commands/commands.module.ts +22 -0
- package/server/{routes/commands.js → modules/commands/commands.routes.ts} +44 -36
- package/server/modules/commands/index.ts +2 -0
- package/server/modules/commands/tests/commands.test.ts +119 -0
- package/server/modules/database/index.ts +1 -0
- package/server/modules/database/migrations.ts +15 -0
- package/server/modules/database/repositories/sessions.db.ts +19 -1
- package/server/modules/database/schema.ts +4 -0
- package/server/modules/file-tree/file-tree.module.ts +112 -0
- package/server/modules/file-tree/file-tree.routes.ts +258 -0
- package/server/modules/file-tree/file-tree.service.ts +616 -0
- package/server/modules/file-tree/index.ts +2 -0
- package/server/modules/file-tree/tests/file-tree.routes.test.ts +157 -0
- package/server/modules/file-tree/tests/file-tree.service.test.ts +220 -0
- package/server/modules/git/git-parsing.service.ts +66 -0
- package/server/modules/git/git.module.ts +22 -0
- package/server/{routes/git.js → modules/git/git.routes.ts} +91 -132
- package/server/modules/git/index.ts +2 -0
- package/server/modules/git/tests/git-init.routes.test.ts +52 -0
- package/server/{routes/git.test.js → modules/git/tests/git.test.ts} +3 -3
- package/server/modules/notifications/index.ts +9 -0
- package/server/modules/notifications/tests/notification-orchestrator.integration.test.ts +55 -0
- package/server/{services/vapid-keys.js → modules/notifications/vapid-keys.service.ts} +3 -1
- package/server/modules/plugins/index.ts +9 -0
- package/server/{utils/plugin-process-manager.js → modules/plugins/plugin-process.service.ts} +3 -1
- package/server/{utils/plugin-loader.js → modules/plugins/plugin-registry.service.ts} +1 -0
- package/server/modules/plugins/plugins.module.ts +33 -0
- package/server/modules/plugins/plugins.routes.ts +66 -0
- package/server/modules/plugins/plugins.service.ts +147 -0
- package/server/modules/plugins/tests/plugins.service.test.ts +32 -0
- package/server/modules/projects/index.ts +5 -0
- package/server/modules/providers/README.md +41 -9
- package/server/modules/providers/index.ts +4 -0
- package/server/modules/providers/list/claude/claude-auth.provider.ts +8 -0
- package/server/modules/providers/list/claude/claude-models.provider.ts +1 -12
- package/server/{claude-sdk.js → modules/providers/list/claude/claude-runtime.provider.js} +66 -44
- package/server/modules/providers/list/claude/claude-session-synchronizer.provider.ts +6 -4
- package/server/modules/providers/list/claude/claude-sessions.provider.ts +27 -4
- package/server/modules/providers/list/claude/claude.provider.ts +3 -0
- package/server/modules/providers/list/codex/codex-models.provider.ts +0 -9
- package/server/{openai-codex.js → modules/providers/list/codex/codex-runtime.provider.js} +54 -36
- package/server/modules/providers/list/codex/codex-session-synchronizer.provider.ts +21 -1
- package/server/modules/providers/list/codex/codex-sessions.provider.ts +331 -7
- package/server/modules/providers/list/codex/codex-skills.provider.ts +5 -0
- package/server/modules/providers/list/codex/codex.provider.ts +3 -0
- package/server/modules/providers/list/cursor/cursor-models.provider.ts +0 -9
- package/server/{cursor-cli.js → modules/providers/list/cursor/cursor-runtime.provider.js} +58 -27
- package/server/modules/providers/list/cursor/cursor-sessions.provider.ts +26 -15
- package/server/modules/providers/list/cursor/cursor.provider.ts +3 -0
- package/server/modules/providers/list/opencode/opencode-models.provider.ts +7 -10
- package/server/{opencode-cli.js → modules/providers/list/opencode/opencode-runtime.provider.js} +56 -28
- package/server/{opencode-cli.test.js → modules/providers/list/opencode/opencode-runtime.provider.test.js} +41 -3
- package/server/modules/providers/list/opencode/opencode-sessions.provider.ts +13 -5
- package/server/modules/providers/list/opencode/opencode.provider.ts +3 -0
- package/server/modules/providers/provider.routes.ts +47 -10
- package/server/modules/providers/services/provider-capabilities.service.ts +7 -1
- package/server/modules/providers/services/provider-models.service.ts +131 -23
- package/server/modules/providers/services/provider-runtime.service.ts +109 -0
- package/server/modules/providers/services/provider-token-usage.service.ts +357 -0
- package/server/modules/providers/services/sessions-watcher.service.ts +2 -0
- package/server/modules/providers/services/sessions.service.ts +79 -0
- package/server/modules/providers/shared/base/abstract.provider.ts +4 -3
- package/server/modules/providers/tests/claude-auth.test.ts +150 -0
- package/server/modules/providers/tests/claude-sessions.test.ts +61 -0
- package/server/modules/providers/tests/codex-sessions.test.ts +81 -0
- package/server/modules/providers/tests/{provider-image-history.test.ts → provider-attachment-history.test.ts} +68 -1
- package/server/modules/providers/tests/provider-models.service.test.ts +450 -349
- package/server/modules/providers/tests/provider-runtime.service.test.ts +142 -0
- package/server/modules/providers/tests/provider-token-usage.service.test.ts +185 -0
- package/server/modules/providers/tests/sessions-details.test.ts +73 -0
- package/server/modules/providers/tests/skills.test.ts +9 -2
- package/server/modules/settings/index.ts +2 -0
- package/server/modules/settings/settings.module.ts +50 -0
- package/server/modules/settings/settings.routes.ts +51 -0
- package/server/modules/settings/settings.service.ts +186 -0
- package/server/modules/settings/tests/settings.service.test.ts +54 -0
- package/server/modules/system/index.ts +2 -0
- package/server/modules/system/system.module.ts +62 -0
- package/server/modules/system/system.routes.ts +21 -0
- package/server/modules/system/system.service.ts +76 -0
- package/server/modules/system/tests/system.service.test.ts +118 -0
- package/server/modules/taskmaster/index.ts +2 -0
- package/server/modules/taskmaster/taskmaster.module.ts +24 -0
- package/server/modules/taskmaster/taskmaster.routes.ts +1482 -0
- package/server/modules/taskmaster/taskmaster.service.ts +132 -0
- package/server/modules/taskmaster/tests/taskmaster.routes.test.ts +144 -0
- package/server/modules/taskmaster/tests/taskmaster.service.test.ts +97 -0
- package/server/modules/user/index.ts +2 -0
- package/server/modules/user/tests/user.service.test.ts +61 -0
- package/server/modules/user/user.module.ts +58 -0
- package/server/modules/user/user.routes.ts +50 -0
- package/server/modules/user/user.service.ts +85 -0
- package/server/modules/voice/index.ts +2 -0
- package/server/modules/voice/tests/voice.service.test.ts +98 -0
- package/server/modules/voice/voice.module.ts +47 -0
- package/server/modules/voice/voice.routes.ts +113 -0
- package/server/modules/voice/voice.service.ts +192 -0
- package/server/modules/websocket/README.md +7 -7
- package/server/modules/websocket/services/chat-session-writer.service.ts +2 -2
- package/server/modules/websocket/services/chat-websocket.service.ts +73 -61
- package/server/modules/websocket/services/shell-websocket.service.ts +88 -12
- package/server/modules/websocket/services/websocket-server.service.ts +63 -19
- package/server/modules/websocket/tests/{chat-image-filter.test.ts → chat-attachment-filter.test.ts} +17 -2
- package/server/modules/websocket/tests/shell-websocket.service.test.ts +119 -0
- package/server/modules/websocket/tests/websocket-heartbeat.service.test.ts +78 -0
- package/server/modules/worktrees/index.ts +2 -0
- package/server/modules/worktrees/services/worktree-create-and-open.service.ts +53 -0
- package/server/modules/worktrees/services/worktree-create.service.ts +104 -0
- package/server/modules/worktrees/services/worktree-git.service.ts +207 -0
- package/server/modules/worktrees/services/worktree-list.service.ts +143 -0
- package/server/modules/worktrees/services/worktree-merge.service.ts +157 -0
- package/server/modules/worktrees/services/worktree-open.service.ts +85 -0
- package/server/modules/worktrees/services/worktree-remove.service.ts +88 -0
- package/server/modules/worktrees/tests/worktree-create-and-open.service.test.ts +68 -0
- package/server/modules/worktrees/tests/worktree-create.service.test.ts +142 -0
- package/server/modules/worktrees/tests/worktree-git.service.test.ts +84 -0
- package/server/modules/worktrees/tests/worktree-list.service.test.ts +45 -0
- package/server/modules/worktrees/tests/worktree-merge.service.test.ts +213 -0
- package/server/modules/worktrees/tests/worktree-open.service.test.ts +122 -0
- package/server/modules/worktrees/tests/worktree-remove.service.test.ts +227 -0
- package/server/modules/worktrees/tests/worktrees.routes.test.ts +199 -0
- package/server/modules/worktrees/worktrees.module.ts +113 -0
- package/server/modules/worktrees/worktrees.routes.ts +116 -0
- package/server/shared/image-attachments.ts +112 -18
- package/server/shared/interfaces.ts +29 -19
- package/server/shared/tests/image-attachments.test.ts +55 -0
- package/server/shared/types.ts +658 -21
- package/server/shared/utils.ts +77 -212
- package/dist/assets/index-DLmhQ15L.css +0 -32
- package/dist-server/server/browser-use-mcp.js.map +0 -1
- package/dist-server/server/claude-sdk.js.map +0 -1
- package/dist-server/server/cli.js +0 -647
- package/dist-server/server/cli.js.map +0 -1
- package/dist-server/server/cursor-cli.js.map +0 -1
- package/dist-server/server/middleware/auth.js.map +0 -1
- package/dist-server/server/modules/providers/tests/provider-image-history.test.js.map +0 -1
- package/dist-server/server/modules/websocket/tests/chat-image-filter.test.js.map +0 -1
- package/dist-server/server/openai-codex.js.map +0 -1
- package/dist-server/server/opencode-cli.js.map +0 -1
- package/dist-server/server/opencode-cli.test.js.map +0 -1
- package/dist-server/server/routes/agent.js +0 -1155
- package/dist-server/server/routes/agent.js.map +0 -1
- package/dist-server/server/routes/auth.js +0 -119
- package/dist-server/server/routes/auth.js.map +0 -1
- package/dist-server/server/routes/commands.js +0 -492
- package/dist-server/server/routes/commands.js.map +0 -1
- package/dist-server/server/routes/cursor.js +0 -49
- package/dist-server/server/routes/cursor.js.map +0 -1
- package/dist-server/server/routes/git.js +0 -1389
- package/dist-server/server/routes/git.js.map +0 -1
- package/dist-server/server/routes/git.test.js.map +0 -1
- package/dist-server/server/routes/mcp-utils.js +0 -29
- package/dist-server/server/routes/mcp-utils.js.map +0 -1
- package/dist-server/server/routes/plugins.js +0 -266
- package/dist-server/server/routes/plugins.js.map +0 -1
- package/dist-server/server/routes/settings.js +0 -249
- package/dist-server/server/routes/settings.js.map +0 -1
- package/dist-server/server/routes/taskmaster.js +0 -1362
- package/dist-server/server/routes/taskmaster.js.map +0 -1
- package/dist-server/server/routes/tests/commands.test.js +0 -76
- package/dist-server/server/routes/tests/commands.test.js.map +0 -1
- package/dist-server/server/routes/user.js +0 -116
- package/dist-server/server/routes/user.js.map +0 -1
- package/dist-server/server/services/notification-orchestrator.js +0 -2
- package/dist-server/server/services/notification-orchestrator.js.map +0 -1
- package/dist-server/server/services/tests/notification-orchestrator.test.js +0 -64
- package/dist-server/server/services/tests/notification-orchestrator.test.js.map +0 -1
- package/dist-server/server/services/vapid-keys.js.map +0 -1
- package/dist-server/server/utils/colors.js +0 -20
- package/dist-server/server/utils/colors.js.map +0 -1
- package/dist-server/server/utils/commandParser.js +0 -255
- package/dist-server/server/utils/commandParser.js.map +0 -1
- package/dist-server/server/utils/gitConfig.js +0 -37
- package/dist-server/server/utils/gitConfig.js.map +0 -1
- package/dist-server/server/utils/mcp-detector.js +0 -134
- package/dist-server/server/utils/mcp-detector.js.map +0 -1
- package/dist-server/server/utils/plugin-loader.js.map +0 -1
- package/dist-server/server/utils/plugin-process-manager.js.map +0 -1
- package/dist-server/server/utils/runtime-paths.js +0 -30
- package/dist-server/server/utils/runtime-paths.js.map +0 -1
- package/dist-server/server/utils/taskmaster-websocket.js +0 -124
- package/dist-server/server/utils/taskmaster-websocket.js.map +0 -1
- package/dist-server/server/utils/url-detection.js +0 -58
- package/dist-server/server/utils/url-detection.js.map +0 -1
- package/dist-server/server/voice-proxy.js +0 -226
- package/dist-server/server/voice-proxy.js.map +0 -1
- package/server/cli.js +0 -695
- package/server/index.js +0 -1651
- package/server/routes/agent.js +0 -1257
- package/server/routes/auth.js +0 -137
- package/server/routes/cursor.js +0 -52
- package/server/routes/mcp-utils.js +0 -31
- package/server/routes/plugins.js +0 -307
- package/server/routes/settings.js +0 -282
- package/server/routes/taskmaster.js +0 -1470
- package/server/routes/tests/commands.test.js +0 -82
- package/server/routes/user.js +0 -124
- package/server/services/notification-orchestrator.js +0 -7
- package/server/services/tests/notification-orchestrator.test.js +0 -80
- package/server/utils/colors.js +0 -21
- package/server/utils/commandParser.js +0 -305
- package/server/utils/gitConfig.js +0 -35
- package/server/utils/mcp-detector.js +0 -147
- package/server/utils/runtime-paths.js +0 -37
- package/server/utils/taskmaster-websocket.js +0 -135
- package/server/utils/url-detection.js +0 -71
- package/server/voice-proxy.js +0 -224
- /package/server/constants/{config.js → config.ts} +0 -0
|
@@ -2,7 +2,7 @@ import crypto from 'node:crypto';
|
|
|
2
2
|
import os from 'node:os';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
|
|
5
|
-
import { parseImagesInputTag } from '@/shared/image-attachments.js';
|
|
5
|
+
import { parseFilesInputTag, parseImagesInputTag } from '@/shared/image-attachments.js';
|
|
6
6
|
import type { IProviderSessions } from '@/shared/interfaces.js';
|
|
7
7
|
import type { AnyRecord, FetchHistoryOptions, FetchHistoryResult, NormalizedMessage } from '@/shared/types.js';
|
|
8
8
|
import {
|
|
@@ -85,16 +85,22 @@ function unwrapUserQueryText(value: string, role: 'user' | 'assistant'): string
|
|
|
85
85
|
function extractUserTextAndImages(
|
|
86
86
|
value: string,
|
|
87
87
|
role: 'user' | 'assistant',
|
|
88
|
-
): {
|
|
88
|
+
): {
|
|
89
|
+
text: string;
|
|
90
|
+
images?: Array<{ path: string; name?: string }>;
|
|
91
|
+
files?: Array<{ path: string; name?: string }>;
|
|
92
|
+
} {
|
|
89
93
|
const unwrapped = unwrapUserQueryText(value, role);
|
|
90
94
|
if (role !== 'user') {
|
|
91
95
|
return { text: unwrapped };
|
|
92
96
|
}
|
|
93
97
|
|
|
94
|
-
const
|
|
98
|
+
const parsedImages = parseImagesInputTag(unwrapped);
|
|
99
|
+
const parsedFiles = parseFilesInputTag(parsedImages.text);
|
|
95
100
|
return {
|
|
96
|
-
text,
|
|
97
|
-
images: attachments.length > 0 ? attachments : undefined,
|
|
101
|
+
text: parsedFiles.text,
|
|
102
|
+
images: parsedImages.attachments.length > 0 ? parsedImages.attachments : undefined,
|
|
103
|
+
files: parsedFiles.attachments.length > 0 ? parsedFiles.attachments : undefined,
|
|
98
104
|
};
|
|
99
105
|
}
|
|
100
106
|
|
|
@@ -471,16 +477,18 @@ export class CursorSessionsProvider implements IProviderSessions {
|
|
|
471
477
|
text = unwrapUserQueryText(content.message.content, role);
|
|
472
478
|
}
|
|
473
479
|
}
|
|
474
|
-
const { text: cleanText, images } = role === 'user'
|
|
480
|
+
const { text: cleanText, images, files } = role === 'user'
|
|
475
481
|
? (() => {
|
|
476
|
-
const
|
|
482
|
+
const parsedImages = parseImagesInputTag(text);
|
|
483
|
+
const parsedFiles = parseFilesInputTag(parsedImages.text);
|
|
477
484
|
return {
|
|
478
|
-
text:
|
|
479
|
-
images:
|
|
485
|
+
text: parsedFiles.text,
|
|
486
|
+
images: parsedImages.attachments.length > 0 ? parsedImages.attachments : undefined,
|
|
487
|
+
files: parsedFiles.attachments.length > 0 ? parsedFiles.attachments : undefined,
|
|
480
488
|
};
|
|
481
489
|
})()
|
|
482
|
-
: { text, images: undefined };
|
|
483
|
-
if (cleanText?.trim() || images) {
|
|
490
|
+
: { text, images: undefined, files: undefined };
|
|
491
|
+
if (cleanText?.trim() || images || files) {
|
|
484
492
|
messages.push(createNormalizedMessage({
|
|
485
493
|
id: baseId,
|
|
486
494
|
sessionId,
|
|
@@ -490,6 +498,7 @@ export class CursorSessionsProvider implements IProviderSessions {
|
|
|
490
498
|
role,
|
|
491
499
|
content: cleanText,
|
|
492
500
|
images,
|
|
501
|
+
files,
|
|
493
502
|
sequence: blob.sequence,
|
|
494
503
|
rowid: blob.rowid,
|
|
495
504
|
}));
|
|
@@ -541,8 +550,8 @@ export class CursorSessionsProvider implements IProviderSessions {
|
|
|
541
550
|
}
|
|
542
551
|
|
|
543
552
|
if (part?.type === 'text' && part?.text) {
|
|
544
|
-
const { text: normalizedPartText, images } = extractUserTextAndImages(part.text, role);
|
|
545
|
-
if (!normalizedPartText && !images) {
|
|
553
|
+
const { text: normalizedPartText, images, files } = extractUserTextAndImages(part.text, role);
|
|
554
|
+
if (!normalizedPartText && !images && !files) {
|
|
546
555
|
continue;
|
|
547
556
|
}
|
|
548
557
|
messages.push(createNormalizedMessage({
|
|
@@ -554,6 +563,7 @@ export class CursorSessionsProvider implements IProviderSessions {
|
|
|
554
563
|
role,
|
|
555
564
|
content: normalizedPartText,
|
|
556
565
|
images,
|
|
566
|
+
files,
|
|
557
567
|
sequence: blob.sequence,
|
|
558
568
|
rowid: blob.rowid,
|
|
559
569
|
}));
|
|
@@ -593,8 +603,8 @@ export class CursorSessionsProvider implements IProviderSessions {
|
|
|
593
603
|
&& content.content.trim()
|
|
594
604
|
&& !isInternalCursorText(content.content)
|
|
595
605
|
) {
|
|
596
|
-
const { text: normalizedText, images } = extractUserTextAndImages(content.content, role);
|
|
597
|
-
if (!normalizedText && !images) {
|
|
606
|
+
const { text: normalizedText, images, files } = extractUserTextAndImages(content.content, role);
|
|
607
|
+
if (!normalizedText && !images && !files) {
|
|
598
608
|
continue;
|
|
599
609
|
}
|
|
600
610
|
messages.push(createNormalizedMessage({
|
|
@@ -606,6 +616,7 @@ export class CursorSessionsProvider implements IProviderSessions {
|
|
|
606
616
|
role,
|
|
607
617
|
content: normalizedText,
|
|
608
618
|
images,
|
|
619
|
+
files,
|
|
609
620
|
sequence: blob.sequence,
|
|
610
621
|
rowid: blob.rowid,
|
|
611
622
|
}));
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { AbstractProvider } from '@/modules/providers/shared/base/abstract.provider.js';
|
|
2
2
|
import { CursorProviderAuth } from '@/modules/providers/list/cursor/cursor-auth.provider.js';
|
|
3
3
|
import { CursorProviderModels } from '@/modules/providers/list/cursor/cursor-models.provider.js';
|
|
4
|
+
import { cursorRuntime } from '@/modules/providers/list/cursor/cursor-runtime.provider.js';
|
|
4
5
|
import { CursorMcpProvider } from '@/modules/providers/list/cursor/cursor-mcp.provider.js';
|
|
5
6
|
import { CursorSessionSynchronizer } from '@/modules/providers/list/cursor/cursor-session-synchronizer.provider.js';
|
|
6
7
|
import { CursorSessionsProvider } from '@/modules/providers/list/cursor/cursor-sessions.provider.js';
|
|
@@ -8,12 +9,14 @@ import { CursorSkillsProvider } from '@/modules/providers/list/cursor/cursor-ski
|
|
|
8
9
|
import type {
|
|
9
10
|
IProviderAuth,
|
|
10
11
|
IProviderModels,
|
|
12
|
+
IProviderRuntime,
|
|
11
13
|
IProviderSessionSynchronizer,
|
|
12
14
|
IProviderSkills,
|
|
13
15
|
IProviderSessions,
|
|
14
16
|
} from '@/shared/interfaces.js';
|
|
15
17
|
|
|
16
18
|
export class CursorProvider extends AbstractProvider {
|
|
19
|
+
readonly runtime: IProviderRuntime = cursorRuntime;
|
|
17
20
|
readonly models: IProviderModels = new CursorProviderModels();
|
|
18
21
|
readonly mcp = new CursorMcpProvider();
|
|
19
22
|
readonly auth: IProviderAuth = new CursorProviderAuth();
|
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
import Database from 'better-sqlite3';
|
|
2
2
|
import crossSpawn from 'cross-spawn';
|
|
3
3
|
|
|
4
|
+
import { sessionsDb } from '@/modules/database/index.js';
|
|
4
5
|
import type { IProviderModels } from '@/shared/interfaces.js';
|
|
5
6
|
import type {
|
|
6
|
-
ProviderChangeActiveModelInput,
|
|
7
7
|
ProviderCurrentActiveModel,
|
|
8
8
|
ProviderModelOption,
|
|
9
9
|
ProviderModelsDefinition,
|
|
10
|
-
ProviderSessionActiveModelChange,
|
|
11
10
|
} from '@/shared/types.js';
|
|
12
11
|
import {
|
|
13
12
|
buildDefaultProviderCurrentActiveModel,
|
|
14
13
|
getOpenCodeDatabasePath,
|
|
15
14
|
readObjectRecord,
|
|
16
15
|
readOptionalString,
|
|
17
|
-
writeProviderSessionActiveModelChange,
|
|
18
16
|
} from '@/shared/utils.js';
|
|
19
17
|
|
|
20
18
|
export const OPENCODE_FALLBACK_MODELS: ProviderModelsDefinition = {
|
|
@@ -464,6 +462,11 @@ export class OpenCodeProviderModels implements IProviderModels {
|
|
|
464
462
|
return buildDefaultProviderCurrentActiveModel(await this.getSupportedModels());
|
|
465
463
|
}
|
|
466
464
|
|
|
465
|
+
// OpenCode's `session` table is keyed by its own session id, so the stable
|
|
466
|
+
// app id has to be translated first; sessions discovered on disk store the
|
|
467
|
+
// provider id in both columns and resolve to themselves.
|
|
468
|
+
const providerSessionId = sessionsDb.getSessionById(sessionId)?.provider_session_id ?? sessionId;
|
|
469
|
+
|
|
467
470
|
try {
|
|
468
471
|
const dbPath = getOpenCodeDatabasePath();
|
|
469
472
|
const db = new Database(dbPath, { readonly: true, fileMustExist: true });
|
|
@@ -481,7 +484,7 @@ export class OpenCodeProviderModels implements IProviderModels {
|
|
|
481
484
|
WHERE s.id = ?
|
|
482
485
|
ORDER BY COALESCE(s.time_updated, s.time_created, 0) DESC
|
|
483
486
|
LIMIT 1
|
|
484
|
-
`).get(
|
|
487
|
+
`).get(providerSessionId) as {
|
|
485
488
|
sessionId?: string;
|
|
486
489
|
model?: unknown;
|
|
487
490
|
agent?: string | null;
|
|
@@ -505,10 +508,4 @@ export class OpenCodeProviderModels implements IProviderModels {
|
|
|
505
508
|
|
|
506
509
|
return buildDefaultProviderCurrentActiveModel(await this.getSupportedModels());
|
|
507
510
|
}
|
|
508
|
-
|
|
509
|
-
async changeActiveModel(
|
|
510
|
-
input: ProviderChangeActiveModelInput,
|
|
511
|
-
): Promise<ProviderSessionActiveModelChange> {
|
|
512
|
-
return writeProviderSessionActiveModelChange('opencode', input);
|
|
513
|
-
}
|
|
514
511
|
}
|
package/server/{opencode-cli.js → modules/providers/list/opencode/opencode-runtime.provider.js}
RENAMED
|
@@ -3,12 +3,13 @@ import fsSync from 'node:fs';
|
|
|
3
3
|
import crossSpawn from 'cross-spawn';
|
|
4
4
|
import Database from 'better-sqlite3';
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
appendFilesInputTag,
|
|
8
|
+
appendImagesInputTag,
|
|
9
|
+
normalizeAttachmentDescriptors
|
|
10
|
+
} from '@/shared/image-attachments.js';
|
|
11
|
+
import { notifyRunFailed, notifyRunStopped } from '@/modules/notifications/index.js';
|
|
12
|
+
import { createCompleteMessage, createNormalizedMessage, flattenPromptForWindowsShell, getOpenCodeDatabasePath } from '@/shared/utils.js';
|
|
12
13
|
|
|
13
14
|
// cross-spawn resolves .cmd shims/PATHEXT on Windows and delegates to
|
|
14
15
|
// child_process.spawn everywhere else.
|
|
@@ -122,12 +123,27 @@ function readOpenCodeTokenUsage(sessionId) {
|
|
|
122
123
|
}
|
|
123
124
|
}
|
|
124
125
|
|
|
125
|
-
async function spawnOpenCode(command, options = {}, ws) {
|
|
126
|
+
async function spawnOpenCode(command, options = {}, ws, context) {
|
|
126
127
|
return new Promise((resolve, reject) => {
|
|
127
|
-
const {
|
|
128
|
+
const {
|
|
129
|
+
sessionId,
|
|
130
|
+
projectPath,
|
|
131
|
+
cwd,
|
|
132
|
+
model,
|
|
133
|
+
effort,
|
|
134
|
+
sessionSummary,
|
|
135
|
+
images,
|
|
136
|
+
files,
|
|
137
|
+
permissionMode
|
|
138
|
+
} = options;
|
|
139
|
+
// Callers pass the stable app session id; the CLI resumes with the
|
|
140
|
+
// provider-native id recorded on the session row.
|
|
141
|
+
const providerSessionId = context.resolveProviderSessionId(sessionId);
|
|
128
142
|
const workingDir = cwd || projectPath || process.cwd();
|
|
143
|
+
// Process-map key: the app session id when the caller supplied one, so
|
|
144
|
+
// abort-by-app-id always works.
|
|
129
145
|
const processKey = sessionId || Date.now().toString();
|
|
130
|
-
let capturedSessionId =
|
|
146
|
+
let capturedSessionId = providerSessionId;
|
|
131
147
|
let sessionCreatedSent = false;
|
|
132
148
|
let stdoutLineBuffer = '';
|
|
133
149
|
let terminalNotificationSent = false;
|
|
@@ -142,7 +158,8 @@ async function spawnOpenCode(command, options = {}, ws) {
|
|
|
142
158
|
}
|
|
143
159
|
|
|
144
160
|
terminalNotificationSent = true;
|
|
145
|
-
|
|
161
|
+
// Notifications are app-facing, so they carry the app session id.
|
|
162
|
+
const finalSessionId = sessionId || capturedSessionId || processKey;
|
|
146
163
|
if (code === 0 && !error) {
|
|
147
164
|
notifyRunStopped({
|
|
148
165
|
userId: ws?.userId || null,
|
|
@@ -169,7 +186,9 @@ async function spawnOpenCode(command, options = {}, ws) {
|
|
|
169
186
|
}
|
|
170
187
|
|
|
171
188
|
capturedSessionId = nextSessionId;
|
|
172
|
-
|
|
189
|
+
// Legacy/direct callers without an app session id re-key the process
|
|
190
|
+
// under the provider-native id once it is known.
|
|
191
|
+
if (!sessionId && processKey !== capturedSessionId && opencodeProcess) {
|
|
173
192
|
activeOpenCodeProcesses.delete(processKey);
|
|
174
193
|
activeOpenCodeProcesses.set(capturedSessionId, opencodeProcess);
|
|
175
194
|
}
|
|
@@ -181,7 +200,7 @@ async function spawnOpenCode(command, options = {}, ws) {
|
|
|
181
200
|
ws.setSessionId(capturedSessionId);
|
|
182
201
|
}
|
|
183
202
|
|
|
184
|
-
if (!
|
|
203
|
+
if (!providerSessionId && !sessionCreatedSent) {
|
|
185
204
|
sessionCreatedSent = true;
|
|
186
205
|
ws.send(createNormalizedMessage({
|
|
187
206
|
kind: 'session_created',
|
|
@@ -212,11 +231,7 @@ async function spawnOpenCode(command, options = {}, ws) {
|
|
|
212
231
|
|
|
213
232
|
try {
|
|
214
233
|
registerSession(readOpenCodeSessionId(response));
|
|
215
|
-
const normalized =
|
|
216
|
-
'opencode',
|
|
217
|
-
response,
|
|
218
|
-
capturedSessionId || sessionId || null,
|
|
219
|
-
);
|
|
234
|
+
const normalized = context.normalizeMessage(response, capturedSessionId || sessionId || null);
|
|
220
235
|
for (const msg of normalized) {
|
|
221
236
|
ws.send(msg);
|
|
222
237
|
}
|
|
@@ -232,10 +247,10 @@ async function spawnOpenCode(command, options = {}, ws) {
|
|
|
232
247
|
}
|
|
233
248
|
};
|
|
234
249
|
|
|
235
|
-
void
|
|
250
|
+
void context.resolveResumeModel(sessionId, model).then(async (resolvedModel) => {
|
|
236
251
|
let effortModels = null;
|
|
237
252
|
try {
|
|
238
|
-
effortModels =
|
|
253
|
+
effortModels = await context.getProviderModels();
|
|
239
254
|
} catch (error) {
|
|
240
255
|
console.warn('[OpenCode] Unable to load provider models for effort validation:', error);
|
|
241
256
|
}
|
|
@@ -246,8 +261,8 @@ async function spawnOpenCode(command, options = {}, ws) {
|
|
|
246
261
|
// Relying on the child-process cwd alone is not enough on Linux, where
|
|
247
262
|
// the CLI can still resolve the session under the server install dir.
|
|
248
263
|
args.push('--dir', workingDir);
|
|
249
|
-
if (
|
|
250
|
-
args.push('--session',
|
|
264
|
+
if (providerSessionId) {
|
|
265
|
+
args.push('--session', providerSessionId);
|
|
251
266
|
}
|
|
252
267
|
if (resolvedModel) {
|
|
253
268
|
args.push('--model', resolvedModel);
|
|
@@ -257,12 +272,19 @@ async function spawnOpenCode(command, options = {}, ws) {
|
|
|
257
272
|
}
|
|
258
273
|
const permissionOptions = resolveOpenCodePermissionOptions(permissionMode);
|
|
259
274
|
args.push(...permissionOptions.args);
|
|
260
|
-
|
|
275
|
+
const hasAttachments =
|
|
276
|
+
normalizeAttachmentDescriptors(images).length > 0
|
|
277
|
+
|| normalizeAttachmentDescriptors(files).length > 0;
|
|
278
|
+
if ((command && command.trim()) || hasAttachments) {
|
|
261
279
|
// Image attachments ride along as an <images_input> path list appended
|
|
262
280
|
// to the prompt; the session history reader strips the tag back out.
|
|
263
281
|
// opencode is a .cmd shim on Windows, so the whole argument must be
|
|
264
282
|
// newline-free or cmd.exe silently truncates it at the first newline.
|
|
265
|
-
|
|
283
|
+
const promptWithAttachments = appendFilesInputTag(
|
|
284
|
+
appendImagesInputTag(command?.trim() || '', images),
|
|
285
|
+
files
|
|
286
|
+
);
|
|
287
|
+
args.push(flattenPromptForWindowsShell(promptWithAttachments));
|
|
266
288
|
}
|
|
267
289
|
|
|
268
290
|
opencodeProcess = spawnFunction('opencode', args, {
|
|
@@ -300,7 +322,7 @@ async function spawnOpenCode(command, options = {}, ws) {
|
|
|
300
322
|
});
|
|
301
323
|
|
|
302
324
|
opencodeProcess.on('close', async (code) => {
|
|
303
|
-
const finalSessionId =
|
|
325
|
+
const finalSessionId = sessionId || capturedSessionId || processKey;
|
|
304
326
|
activeOpenCodeProcesses.delete(finalSessionId);
|
|
305
327
|
activeOpenCodeProcesses.delete(processKey);
|
|
306
328
|
|
|
@@ -309,7 +331,8 @@ async function spawnOpenCode(command, options = {}, ws) {
|
|
|
309
331
|
stdoutLineBuffer = '';
|
|
310
332
|
}
|
|
311
333
|
|
|
312
|
-
|
|
334
|
+
// OpenCode's own database is keyed by the provider-native id.
|
|
335
|
+
const tokenBudget = readOpenCodeTokenUsage(capturedSessionId);
|
|
313
336
|
if (tokenBudget) {
|
|
314
337
|
ws.send(createNormalizedMessage({
|
|
315
338
|
kind: 'status',
|
|
@@ -334,7 +357,7 @@ async function spawnOpenCode(command, options = {}, ws) {
|
|
|
334
357
|
}
|
|
335
358
|
|
|
336
359
|
if (code === 127 || code === null) {
|
|
337
|
-
const installed = await
|
|
360
|
+
const installed = await context.isProviderInstalled();
|
|
338
361
|
if (!installed) {
|
|
339
362
|
ws.send(createNormalizedMessage({
|
|
340
363
|
kind: 'error',
|
|
@@ -350,11 +373,11 @@ async function spawnOpenCode(command, options = {}, ws) {
|
|
|
350
373
|
});
|
|
351
374
|
|
|
352
375
|
opencodeProcess.on('error', async (error) => {
|
|
353
|
-
const finalSessionId =
|
|
376
|
+
const finalSessionId = sessionId || capturedSessionId || processKey;
|
|
354
377
|
activeOpenCodeProcesses.delete(finalSessionId);
|
|
355
378
|
activeOpenCodeProcesses.delete(processKey);
|
|
356
379
|
|
|
357
|
-
const installed = await
|
|
380
|
+
const installed = await context.isProviderInstalled();
|
|
358
381
|
const errorContent = !installed
|
|
359
382
|
? 'OpenCode CLI is not installed. Install it from https://opencode.ai/docs/'
|
|
360
383
|
: error.message;
|
|
@@ -398,6 +421,11 @@ function getActiveOpenCodeSessions() {
|
|
|
398
421
|
return Array.from(activeOpenCodeProcesses.keys());
|
|
399
422
|
}
|
|
400
423
|
|
|
424
|
+
export const opencodeRuntime = {
|
|
425
|
+
run: spawnOpenCode,
|
|
426
|
+
abort: abortOpenCodeSession,
|
|
427
|
+
};
|
|
428
|
+
|
|
401
429
|
export {
|
|
402
430
|
spawnOpenCode,
|
|
403
431
|
abortOpenCodeSession,
|
|
@@ -4,7 +4,20 @@ import os from 'node:os';
|
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import test from 'node:test';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
opencodeRuntime,
|
|
9
|
+
resolveOpenCodePermissionOptions,
|
|
10
|
+
} from './opencode-runtime.provider.js';
|
|
11
|
+
import { OpenCodeSessionsProvider } from './opencode-sessions.provider.js';
|
|
12
|
+
|
|
13
|
+
const sessionsProvider = new OpenCodeSessionsProvider();
|
|
14
|
+
const runtimeContext = {
|
|
15
|
+
resolveProviderSessionId: (sessionId) => sessionId || null,
|
|
16
|
+
resolveResumeModel: async (_sessionId, requestedModel) => requestedModel || undefined,
|
|
17
|
+
getProviderModels: async () => ({ OPTIONS: [], DEFAULT: '' }),
|
|
18
|
+
normalizeMessage: (raw, sessionId) => sessionsProvider.normalizeMessage(raw, sessionId),
|
|
19
|
+
isProviderInstalled: async () => true,
|
|
20
|
+
};
|
|
8
21
|
|
|
9
22
|
const findEnvKey = (name) =>
|
|
10
23
|
Object.keys(process.env).find((key) => key.toLowerCase() === name.toLowerCase()) || name;
|
|
@@ -71,7 +84,7 @@ test('spawnOpenCode emits session_created before normalized live messages for ne
|
|
|
71
84
|
: `.COM;.EXE;.BAT;.CMD${previousPathExt ? `;${previousPathExt}` : ''}`;
|
|
72
85
|
}
|
|
73
86
|
|
|
74
|
-
await
|
|
87
|
+
await opencodeRuntime.run('Hi', { cwd: tempRoot }, writer, runtimeContext);
|
|
75
88
|
|
|
76
89
|
const sessionCreatedIndex = messages.findIndex((message) => message.kind === 'session_created');
|
|
77
90
|
const assistantDeltaIndex = messages.findIndex((message) =>
|
|
@@ -98,6 +111,26 @@ test('spawnOpenCode emits session_created before normalized live messages for ne
|
|
|
98
111
|
assert.equal(launchedArgs.includes('--auto'), false);
|
|
99
112
|
assert.equal(launchedArgs.includes('--agent'), false);
|
|
100
113
|
assert.equal(capture.permissionEnv, null);
|
|
114
|
+
|
|
115
|
+
const attachmentOnlyCapturePath = path.join(tempRoot, 'opencode-attachment-only.json');
|
|
116
|
+
process.env.OPENCODE_ARGS_CAPTURE = attachmentOnlyCapturePath;
|
|
117
|
+
await opencodeRuntime.run(
|
|
118
|
+
'',
|
|
119
|
+
{
|
|
120
|
+
cwd: tempRoot,
|
|
121
|
+
files: [{
|
|
122
|
+
path: path.join(tempRoot, 'brief.pdf'),
|
|
123
|
+
name: 'brief.pdf',
|
|
124
|
+
mimeType: 'application/pdf',
|
|
125
|
+
}],
|
|
126
|
+
},
|
|
127
|
+
writer,
|
|
128
|
+
runtimeContext,
|
|
129
|
+
);
|
|
130
|
+
const attachmentOnlyCapture = JSON.parse(await readFile(attachmentOnlyCapturePath, 'utf8'));
|
|
131
|
+
const attachmentPrompt = attachmentOnlyCapture.args[attachmentOnlyCapture.args.length - 1];
|
|
132
|
+
assert.match(attachmentPrompt, /<files_input>/);
|
|
133
|
+
assert.match(attachmentPrompt, /brief\.pdf/);
|
|
101
134
|
} finally {
|
|
102
135
|
if (previousPath === undefined) {
|
|
103
136
|
delete process.env[pathKey];
|
|
@@ -186,7 +219,12 @@ test('spawnOpenCode passes permission mode flags and env to the CLI', async () =
|
|
|
186
219
|
const argsCapturePath = path.join(tempRoot, `opencode-args-${scenario.permissionMode}.json`);
|
|
187
220
|
process.env.OPENCODE_ARGS_CAPTURE = argsCapturePath;
|
|
188
221
|
|
|
189
|
-
await
|
|
222
|
+
await opencodeRuntime.run(
|
|
223
|
+
'Hi',
|
|
224
|
+
{ cwd: tempRoot, permissionMode: scenario.permissionMode },
|
|
225
|
+
writer,
|
|
226
|
+
runtimeContext,
|
|
227
|
+
);
|
|
190
228
|
|
|
191
229
|
const capture = JSON.parse(await readFile(argsCapturePath, 'utf8'));
|
|
192
230
|
for (const expectedArg of scenario.expectArgs) {
|
|
@@ -2,7 +2,7 @@ import fsSync from 'node:fs';
|
|
|
2
2
|
|
|
3
3
|
import Database from 'better-sqlite3';
|
|
4
4
|
|
|
5
|
-
import { parseImagesInputTag } from '@/shared/image-attachments.js';
|
|
5
|
+
import { parseFilesInputTag, parseImagesInputTag } from '@/shared/image-attachments.js';
|
|
6
6
|
import type { IProviderSessions } from '@/shared/interfaces.js';
|
|
7
7
|
import type { AnyRecord, FetchHistoryOptions, FetchHistoryResult, NormalizedMessage } from '@/shared/types.js';
|
|
8
8
|
import {
|
|
@@ -404,10 +404,17 @@ export class OpenCodeSessionsProvider implements IProviderSessions {
|
|
|
404
404
|
const rawContent = extractText(partData);
|
|
405
405
|
// User prompts sent with attachments carry an <images_input> path
|
|
406
406
|
// list; strip it for display and surface the paths as images.
|
|
407
|
-
const
|
|
407
|
+
const parsedImages = messageRole === 'user'
|
|
408
408
|
? parseImagesInputTag(rawContent)
|
|
409
409
|
: { text: rawContent, attachments: [] };
|
|
410
|
-
|
|
410
|
+
const parsedFiles = messageRole === 'user'
|
|
411
|
+
? parseFilesInputTag(parsedImages.text)
|
|
412
|
+
: { text: rawContent, attachments: [] };
|
|
413
|
+
if (
|
|
414
|
+
parsedFiles.text.trim()
|
|
415
|
+
|| parsedImages.attachments.length > 0
|
|
416
|
+
|| parsedFiles.attachments.length > 0
|
|
417
|
+
) {
|
|
411
418
|
normalized.push(createNormalizedMessage({
|
|
412
419
|
id: baseId,
|
|
413
420
|
sessionId,
|
|
@@ -415,8 +422,9 @@ export class OpenCodeSessionsProvider implements IProviderSessions {
|
|
|
415
422
|
provider: PROVIDER,
|
|
416
423
|
kind: 'text',
|
|
417
424
|
role: messageRole === 'user' ? 'user' : 'assistant',
|
|
418
|
-
content,
|
|
419
|
-
images: attachments.length > 0 ? attachments : undefined,
|
|
425
|
+
content: parsedFiles.text,
|
|
426
|
+
images: parsedImages.attachments.length > 0 ? parsedImages.attachments : undefined,
|
|
427
|
+
files: parsedFiles.attachments.length > 0 ? parsedFiles.attachments : undefined,
|
|
420
428
|
}));
|
|
421
429
|
}
|
|
422
430
|
continue;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { OpenCodeProviderAuth } from '@/modules/providers/list/opencode/opencode-auth.provider.js';
|
|
2
2
|
import { OpenCodeProviderModels } from '@/modules/providers/list/opencode/opencode-models.provider.js';
|
|
3
|
+
import { opencodeRuntime } from '@/modules/providers/list/opencode/opencode-runtime.provider.js';
|
|
3
4
|
import { OpenCodeMcpProvider } from '@/modules/providers/list/opencode/opencode-mcp.provider.js';
|
|
4
5
|
import { OpenCodeSessionSynchronizer } from '@/modules/providers/list/opencode/opencode-session-synchronizer.provider.js';
|
|
5
6
|
import { OpenCodeSessionsProvider } from '@/modules/providers/list/opencode/opencode-sessions.provider.js';
|
|
@@ -8,12 +9,14 @@ import { AbstractProvider } from '@/modules/providers/shared/base/abstract.provi
|
|
|
8
9
|
import type {
|
|
9
10
|
IProviderAuth,
|
|
10
11
|
IProviderModels,
|
|
12
|
+
IProviderRuntime,
|
|
11
13
|
IProviderSessionSynchronizer,
|
|
12
14
|
IProviderSkills,
|
|
13
15
|
IProviderSessions,
|
|
14
16
|
} from '@/shared/interfaces.js';
|
|
15
17
|
|
|
16
18
|
export class OpenCodeProvider extends AbstractProvider {
|
|
19
|
+
readonly runtime: IProviderRuntime = opencodeRuntime;
|
|
17
20
|
readonly models: IProviderModels = new OpenCodeProviderModels();
|
|
18
21
|
readonly mcp = new OpenCodeMcpProvider();
|
|
19
22
|
readonly auth: IProviderAuth = new OpenCodeProviderAuth();
|
|
@@ -4,6 +4,7 @@ import { providerAuthService } from '@/modules/providers/services/provider-auth.
|
|
|
4
4
|
import { providerCapabilitiesService } from '@/modules/providers/services/provider-capabilities.service.js';
|
|
5
5
|
import { providerMcpService } from '@/modules/providers/services/mcp.service.js';
|
|
6
6
|
import { providerModelsService } from '@/modules/providers/services/provider-models.service.js';
|
|
7
|
+
import { providerTokenUsageService } from '@/modules/providers/services/provider-token-usage.service.js';
|
|
7
8
|
import { providerSkillsService } from '@/modules/providers/services/skills.service.js';
|
|
8
9
|
import { sessionConversationsSearchService } from '@/modules/providers/services/session-conversations-search.service.js';
|
|
9
10
|
import { sessionsService } from '@/modules/providers/services/sessions.service.js';
|
|
@@ -11,7 +12,6 @@ import type {
|
|
|
11
12
|
LLMProvider,
|
|
12
13
|
McpScope,
|
|
13
14
|
McpTransport,
|
|
14
|
-
ProviderChangeActiveModelInput,
|
|
15
15
|
ProviderSkillCreateFile,
|
|
16
16
|
ProviderSkillCreateInput,
|
|
17
17
|
UpsertProviderMcpServerInput,
|
|
@@ -352,7 +352,7 @@ const parseSessionSearchLimit = (value: unknown): number => {
|
|
|
352
352
|
return Math.max(1, Math.min(parsed, 100));
|
|
353
353
|
};
|
|
354
354
|
|
|
355
|
-
const
|
|
355
|
+
const parseSessionModelPayload = (payload: unknown): string => {
|
|
356
356
|
if (!payload || typeof payload !== 'object') {
|
|
357
357
|
throw new AppError('Request body must be an object.', {
|
|
358
358
|
code: 'INVALID_REQUEST_BODY',
|
|
@@ -369,10 +369,7 @@ const parseChangeActiveModelPayload = (payload: unknown): ProviderChangeActiveMo
|
|
|
369
369
|
});
|
|
370
370
|
}
|
|
371
371
|
|
|
372
|
-
return
|
|
373
|
-
sessionId: '',
|
|
374
|
-
model,
|
|
375
|
-
};
|
|
372
|
+
return model;
|
|
376
373
|
};
|
|
377
374
|
|
|
378
375
|
router.get(
|
|
@@ -394,20 +391,40 @@ router.get(
|
|
|
394
391
|
}),
|
|
395
392
|
);
|
|
396
393
|
|
|
397
|
-
|
|
394
|
+
/**
|
|
395
|
+
* Reports which model one session is using. `requestedModel` lets the client
|
|
396
|
+
* pass the default it would otherwise send, so a session that has not been
|
|
397
|
+
* sent on yet resolves to that instead of the catalog default.
|
|
398
|
+
*/
|
|
399
|
+
router.get(
|
|
398
400
|
'/:provider/sessions/:sessionId/active-model',
|
|
399
401
|
asyncHandler(async (req: Request, res: Response) => {
|
|
400
402
|
const provider = parseProvider(req.params.provider);
|
|
401
403
|
const sessionId = parseSessionId(req.params.sessionId);
|
|
402
|
-
const
|
|
403
|
-
const result = await providerModelsService.
|
|
404
|
-
...payload,
|
|
404
|
+
const requestedModel = readOptionalQueryString(req.query.requestedModel);
|
|
405
|
+
const result = await providerModelsService.resolveSessionModel(provider, {
|
|
405
406
|
sessionId,
|
|
407
|
+
requestedModel,
|
|
406
408
|
});
|
|
407
409
|
res.json(createApiSuccessResponse(result));
|
|
408
410
|
}),
|
|
409
411
|
);
|
|
410
412
|
|
|
413
|
+
router.post(
|
|
414
|
+
'/:provider/sessions/:sessionId/active-model',
|
|
415
|
+
asyncHandler(async (req: Request, res: Response) => {
|
|
416
|
+
const provider = parseProvider(req.params.provider);
|
|
417
|
+
const sessionId = parseSessionId(req.params.sessionId);
|
|
418
|
+
const model = parseSessionModelPayload(req.body);
|
|
419
|
+
const stored = providerModelsService.setSessionModel(provider, sessionId, model);
|
|
420
|
+
// A session row only exists once the gateway has allocated one. Report the
|
|
421
|
+
// selection back either way so the client can hold it until the first send.
|
|
422
|
+
res.json(createApiSuccessResponse(
|
|
423
|
+
stored ?? { provider, sessionId, model, source: 'session' as const },
|
|
424
|
+
));
|
|
425
|
+
}),
|
|
426
|
+
);
|
|
427
|
+
|
|
411
428
|
// ----------------- Skills routes -----------------
|
|
412
429
|
router.get(
|
|
413
430
|
'/:provider/skills',
|
|
@@ -556,6 +573,26 @@ router.get(
|
|
|
556
573
|
}),
|
|
557
574
|
);
|
|
558
575
|
|
|
576
|
+
router.get(
|
|
577
|
+
'/sessions/:sessionId/token-usage',
|
|
578
|
+
asyncHandler(async (req: Request, res: Response) => {
|
|
579
|
+
const sessionId = parseSessionId(req.params.sessionId);
|
|
580
|
+
const result = await providerTokenUsageService.getSessionTokenUsage(sessionId);
|
|
581
|
+
res.json(createApiSuccessResponse(result));
|
|
582
|
+
}),
|
|
583
|
+
);
|
|
584
|
+
|
|
585
|
+
// Must stay registered after the static `/sessions/running` and
|
|
586
|
+
// `/sessions/archived` routes so those literals never match `:sessionId`.
|
|
587
|
+
router.get(
|
|
588
|
+
'/sessions/:sessionId',
|
|
589
|
+
asyncHandler(async (req: Request, res: Response) => {
|
|
590
|
+
const sessionId = parseSessionId(req.params.sessionId);
|
|
591
|
+
const result = sessionsService.getSessionDetailsById(sessionId);
|
|
592
|
+
res.json(createApiSuccessResponse(result));
|
|
593
|
+
}),
|
|
594
|
+
);
|
|
595
|
+
|
|
559
596
|
router.delete(
|
|
560
597
|
'/sessions/:sessionId',
|
|
561
598
|
asyncHandler(async (req: Request, res: Response) => {
|
|
@@ -15,6 +15,8 @@ type ProviderCapabilities = {
|
|
|
15
15
|
defaultPermissionMode: string;
|
|
16
16
|
/** Whether image attachments can be included in a chat.send. */
|
|
17
17
|
supportsImages: boolean;
|
|
18
|
+
/** Whether general file attachments can be included in a chat.send. */
|
|
19
|
+
supportsFiles: boolean;
|
|
18
20
|
/** Whether an in-flight run can be cancelled via chat.abort. */
|
|
19
21
|
supportsAbort: boolean;
|
|
20
22
|
/** Whether interactive tool permission prompts can reach the UI. */
|
|
@@ -37,6 +39,7 @@ const PROVIDER_CAPABILITIES: Record<LLMProvider, ProviderCapabilities> = {
|
|
|
37
39
|
permissionModes: ['default', 'auto', 'acceptEdits', 'bypassPermissions', 'plan'],
|
|
38
40
|
defaultPermissionMode: 'default',
|
|
39
41
|
supportsImages: true,
|
|
42
|
+
supportsFiles: true,
|
|
40
43
|
supportsAbort: true,
|
|
41
44
|
supportsPermissionRequests: true,
|
|
42
45
|
supportsTokenUsage: true,
|
|
@@ -47,6 +50,7 @@ const PROVIDER_CAPABILITIES: Record<LLMProvider, ProviderCapabilities> = {
|
|
|
47
50
|
permissionModes: ['default', 'acceptEdits', 'bypassPermissions', 'plan'],
|
|
48
51
|
defaultPermissionMode: 'default',
|
|
49
52
|
supportsImages: true,
|
|
53
|
+
supportsFiles: true,
|
|
50
54
|
supportsAbort: true,
|
|
51
55
|
supportsPermissionRequests: false,
|
|
52
56
|
supportsTokenUsage: false,
|
|
@@ -57,6 +61,7 @@ const PROVIDER_CAPABILITIES: Record<LLMProvider, ProviderCapabilities> = {
|
|
|
57
61
|
permissionModes: ['default', 'acceptEdits', 'bypassPermissions'],
|
|
58
62
|
defaultPermissionMode: 'default',
|
|
59
63
|
supportsImages: true,
|
|
64
|
+
supportsFiles: true,
|
|
60
65
|
supportsAbort: true,
|
|
61
66
|
supportsPermissionRequests: false,
|
|
62
67
|
supportsTokenUsage: true,
|
|
@@ -66,10 +71,11 @@ const PROVIDER_CAPABILITIES: Record<LLMProvider, ProviderCapabilities> = {
|
|
|
66
71
|
provider: 'opencode',
|
|
67
72
|
// Mapped by the runtime onto OpenCode's controls: `--agent plan` (plan),
|
|
68
73
|
// `--auto` (bypassPermissions) and the OPENCODE_PERMISSION env var
|
|
69
|
-
// (acceptEdits). See resolveOpenCodePermissionOptions in
|
|
74
|
+
// (acceptEdits). See resolveOpenCodePermissionOptions in the OpenCode runtime adapter.
|
|
70
75
|
permissionModes: ['default', 'acceptEdits', 'bypassPermissions', 'plan'],
|
|
71
76
|
defaultPermissionMode: 'default',
|
|
72
77
|
supportsImages: true,
|
|
78
|
+
supportsFiles: true,
|
|
73
79
|
supportsAbort: true,
|
|
74
80
|
supportsPermissionRequests: false,
|
|
75
81
|
supportsTokenUsage: true,
|