@cloudcli-ai/cloudcli 1.36.3 → 1.37.1
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-D3jfzuKN.css +32 -0
- package/dist/assets/index-DTMWjJj8.js +1550 -0
- 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 +91 -0
- package/dist-server/server/modules/commands/tests/commands.test.js.map +1 -0
- package/dist-server/server/modules/database/index.js +3 -0
- package/dist-server/server/modules/database/index.js.map +1 -1
- package/dist-server/server/modules/database/migrations.js +31 -1
- package/dist-server/server/modules/database/migrations.js.map +1 -1
- package/dist-server/server/modules/database/repositories/provider-models.js +112 -0
- package/dist-server/server/modules/database/repositories/provider-models.js.map +1 -0
- package/dist-server/server/modules/database/repositories/sessions.db.js +76 -7
- package/dist-server/server/modules/database/repositories/sessions.db.js.map +1 -1
- package/dist-server/server/modules/database/schema.js +29 -0
- package/dist-server/server/modules/database/schema.js.map +1 -1
- package/dist-server/server/modules/database/tests/provider-models.db.integration.test.js +102 -0
- package/dist-server/server/modules/database/tests/provider-models.db.integration.test.js.map +1 -0
- package/dist-server/server/modules/database/tests/sessions-provider-mapping.test.js +2 -1
- package/dist-server/server/modules/database/tests/sessions-provider-mapping.test.js.map +1 -1
- package/dist-server/server/modules/database/tests/sessions.db.integration.test.js +22 -0
- package/dist-server/server/modules/database/tests/sessions.db.integration.test.js.map +1 -1
- package/dist-server/server/modules/file-tree/file-tree.module.js +95 -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 +576 -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 +260 -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 +47 -18
- 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} +69 -55
- 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 +59 -75
- 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 +1 -54
- 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 +33 -673
- 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 +112 -333
- 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-session-synchronizer.provider.js +0 -12
- package/dist-server/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.js.map +1 -1
- 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 +169 -37
- 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 +247 -184
- 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/session-conversations-search.service.js +12 -4
- package/dist-server/server/modules/providers/services/session-conversations-search.service.js.map +1 -1
- 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 +116 -3
- 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 +76 -4
- package/dist-server/server/modules/providers/tests/codex-sessions.test.js.map +1 -1
- package/dist-server/server/modules/providers/tests/opencode-models.test.js +15 -126
- package/dist-server/server/modules/providers/tests/opencode-models.test.js.map +1 -1
- package/dist-server/server/modules/providers/tests/opencode-sessions.test.js +5 -5
- package/dist-server/server/modules/providers/tests/opencode-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 +241 -271
- 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 +126 -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 +166 -0
- package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/provider.routes.test.js +126 -0
- package/dist-server/server/modules/providers/tests/provider.routes.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/sessions.service.test.js +87 -0
- package/dist-server/server/modules/providers/tests/sessions.service.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 +44 -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/package.json +9 -5
- 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} +46 -38
- package/server/modules/commands/index.ts +2 -0
- package/server/modules/commands/tests/commands.test.ts +114 -0
- package/server/modules/database/index.ts +3 -0
- package/server/modules/database/migrations.ts +35 -0
- package/server/modules/database/repositories/provider-models.ts +168 -0
- package/server/modules/database/repositories/sessions.db.ts +103 -8
- package/server/modules/database/schema.ts +30 -0
- package/server/modules/database/tests/provider-models.db.integration.test.ts +125 -0
- package/server/modules/database/tests/sessions-provider-mapping.test.ts +2 -1
- package/server/modules/database/tests/sessions.db.integration.test.ts +32 -0
- package/server/modules/file-tree/file-tree.module.ts +116 -0
- package/server/modules/file-tree/file-tree.routes.ts +258 -0
- package/server/modules/file-tree/file-tree.service.ts +664 -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 +317 -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 +47 -26
- package/server/{claude-sdk.js → modules/providers/list/claude/claude-runtime.provider.js} +73 -59
- 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 +58 -108
- 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 +1 -60
- 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 +32 -719
- 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 +112 -423
- 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-session-synchronizer.provider.ts +0 -13
- 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 +228 -39
- package/server/modules/providers/services/provider-capabilities.service.ts +7 -1
- package/server/modules/providers/services/provider-models.service.ts +312 -269
- package/server/modules/providers/services/provider-runtime.service.ts +108 -0
- package/server/modules/providers/services/provider-token-usage.service.ts +357 -0
- package/server/modules/providers/services/session-conversations-search.service.ts +12 -4
- package/server/modules/providers/services/sessions-watcher.service.ts +2 -0
- package/server/modules/providers/services/sessions.service.ts +166 -3
- 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 +83 -4
- package/server/modules/providers/tests/opencode-models.test.ts +34 -135
- package/server/modules/providers/tests/opencode-sessions.test.ts +5 -5
- 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 +300 -296
- package/server/modules/providers/tests/provider-runtime.service.test.ts +138 -0
- package/server/modules/providers/tests/provider-token-usage.service.test.ts +186 -0
- package/server/modules/providers/tests/provider.routes.test.ts +183 -0
- package/server/modules/providers/tests/sessions-details.test.ts +73 -0
- package/server/modules/providers/tests/sessions.service.test.ts +127 -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 +77 -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 +33 -25
- package/server/shared/tests/image-attachments.test.ts +55 -0
- package/server/shared/types.ts +685 -36
- package/server/shared/utils.ts +77 -212
- package/dist/assets/index-CcCsKitq.js +0 -1423
- 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
|
@@ -1,18 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
import os from "os";
|
|
1
|
+
// @ts-nocheck -- temporary while command handlers are extracted into the injected service.
|
|
3
2
|
import path from "path";
|
|
4
3
|
|
|
5
4
|
import express from "express";
|
|
6
5
|
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
6
|
+
import { parseFrontMatter } from "../../shared/frontmatter.js";
|
|
7
|
+
|
|
8
|
+
type CommandsRouterDependencies = {
|
|
9
|
+
fileSystem: typeof import('node:fs/promises');
|
|
10
|
+
homeDirectory(): string;
|
|
11
|
+
appRoot: string;
|
|
12
|
+
models: typeof import('../providers/index.js').providerModelsService;
|
|
13
|
+
runtime: {
|
|
14
|
+
uptime(): number;
|
|
15
|
+
memoryUsage(): NodeJS.MemoryUsage;
|
|
16
|
+
version: string;
|
|
17
|
+
platform: NodeJS.Platform;
|
|
18
|
+
pid: number;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
15
21
|
|
|
22
|
+
/** Creates Commands routes around explicit filesystem, model-catalog, and runtime adapters. */
|
|
23
|
+
export function createCommandsRouter(dependencies: CommandsRouterDependencies): express.Router {
|
|
24
|
+
const fs = dependencies.fileSystem;
|
|
25
|
+
const os = { homedir: dependencies.homeDirectory };
|
|
26
|
+
const APP_ROOT = dependencies.appRoot;
|
|
27
|
+
const providerModelsService = dependencies.models;
|
|
28
|
+
const process = dependencies.runtime;
|
|
16
29
|
const router = express.Router();
|
|
17
30
|
|
|
18
31
|
const MODEL_PROVIDERS = ["claude", "cursor", "codex", "opencode"];
|
|
@@ -33,35 +46,32 @@ const readModelProvider = (value) => {
|
|
|
33
46
|
return MODEL_PROVIDERS.includes(normalized) ? normalized : "claude";
|
|
34
47
|
};
|
|
35
48
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
);
|
|
48
|
-
return
|
|
49
|
+
/**
|
|
50
|
+
* Resolves the model a command should report.
|
|
51
|
+
*
|
|
52
|
+
* `context.model` is what the composer would send right now, so it stands in
|
|
53
|
+
* for a chat that has no session row yet; the service prefers the session's own
|
|
54
|
+
* recorded model whenever there is one.
|
|
55
|
+
*/
|
|
56
|
+
const resolveCommandModel = async (modelsService, provider, context) => {
|
|
57
|
+
const resolved = await modelsService.resolveSessionModel(provider, {
|
|
58
|
+
sessionId: context?.sessionId,
|
|
59
|
+
requestedModel: context?.model,
|
|
60
|
+
});
|
|
61
|
+
return resolved.model;
|
|
49
62
|
};
|
|
50
63
|
|
|
51
|
-
|
|
64
|
+
const executeModelsCommand = async (args, context, modelsService) => {
|
|
52
65
|
const currentProvider = readModelProvider(context?.provider);
|
|
53
|
-
const
|
|
54
|
-
const
|
|
55
|
-
const currentModel = await resolveCommandModel(
|
|
56
|
-
currentProvider,
|
|
57
|
-
catalog,
|
|
58
|
-
context?.sessionId,
|
|
59
|
-
);
|
|
66
|
+
const catalog = await modelsService.getProviderModels(currentProvider);
|
|
67
|
+
const currentModel = await resolveCommandModel(modelsService, currentProvider, context);
|
|
60
68
|
const availableModels = catalog.OPTIONS.map((option) => option.value);
|
|
61
69
|
const availableOptions = catalog.OPTIONS.map((option) => ({
|
|
62
70
|
value: option.value,
|
|
63
71
|
label: option.label,
|
|
64
72
|
description: option.description,
|
|
73
|
+
recordId: option.recordId,
|
|
74
|
+
isCustom: option.isCustom,
|
|
65
75
|
}));
|
|
66
76
|
|
|
67
77
|
return {
|
|
@@ -79,7 +89,6 @@ export const executeModelsCommand = async (args, context) => {
|
|
|
79
89
|
availableModels,
|
|
80
90
|
availableOptions,
|
|
81
91
|
defaultModel: catalog.DEFAULT,
|
|
82
|
-
cache: result.cache,
|
|
83
92
|
message: `Current model: ${currentModel}`,
|
|
84
93
|
},
|
|
85
94
|
};
|
|
@@ -249,13 +258,12 @@ Custom commands can be created in:
|
|
|
249
258
|
};
|
|
250
259
|
},
|
|
251
260
|
|
|
252
|
-
"/models": executeModelsCommand,
|
|
261
|
+
"/models": (args, context) => executeModelsCommand(args, context, providerModelsService),
|
|
253
262
|
|
|
254
263
|
"/cost": async (args, context) => {
|
|
255
264
|
const tokenUsage = context?.tokenUsage || {};
|
|
256
265
|
const provider = readModelProvider(context?.provider);
|
|
257
|
-
const
|
|
258
|
-
const model = await resolveCommandModel(provider, catalog, context?.sessionId);
|
|
266
|
+
const model = await resolveCommandModel(providerModelsService, provider, context);
|
|
259
267
|
|
|
260
268
|
const reportedUsed =
|
|
261
269
|
Number(
|
|
@@ -357,8 +365,7 @@ Custom commands can be created in:
|
|
|
357
365
|
: `${uptimeMinutes}m`;
|
|
358
366
|
|
|
359
367
|
const statusProvider = readModelProvider(context?.provider);
|
|
360
|
-
const
|
|
361
|
-
const model = await resolveCommandModel(statusProvider, statusCatalog, context?.sessionId);
|
|
368
|
+
const model = await resolveCommandModel(providerModelsService, statusProvider, context);
|
|
362
369
|
const memoryUsage = process.memoryUsage();
|
|
363
370
|
|
|
364
371
|
return {
|
|
@@ -593,4 +600,5 @@ router.post("/execute", async (req, res) => {
|
|
|
593
600
|
}
|
|
594
601
|
});
|
|
595
602
|
|
|
596
|
-
|
|
603
|
+
return router;
|
|
604
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { once } from 'node:events';
|
|
3
|
+
import type { AddressInfo } from 'node:net';
|
|
4
|
+
import test from 'node:test';
|
|
5
|
+
|
|
6
|
+
import express from 'express';
|
|
7
|
+
|
|
8
|
+
import { createCommandsRouter } from '../commands.routes.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Stands in for `providerModelsService`. `resolveSessionModel` mirrors the real
|
|
12
|
+
* precedence closely enough for the command handlers: a model recorded for the
|
|
13
|
+
* session wins, otherwise the client's requested model, otherwise the catalog
|
|
14
|
+
* default.
|
|
15
|
+
*/
|
|
16
|
+
function createModelsService(sessionModels: Record<string, string> = {}) {
|
|
17
|
+
return {
|
|
18
|
+
getProviderModels: async () => ({
|
|
19
|
+
OPTIONS: [{ value: 'default', label: 'Default' }],
|
|
20
|
+
DEFAULT: 'default',
|
|
21
|
+
}),
|
|
22
|
+
getCurrentActiveModel: async () => ({ model: 'default' }),
|
|
23
|
+
setSessionModel: () => null,
|
|
24
|
+
resolveSessionModel: async (
|
|
25
|
+
provider: string,
|
|
26
|
+
options: { sessionId?: string | null; requestedModel?: string | null } = {},
|
|
27
|
+
) => {
|
|
28
|
+
const recorded = options.sessionId ? sessionModels[options.sessionId] : undefined;
|
|
29
|
+
const model = recorded || options.requestedModel || 'default';
|
|
30
|
+
return {
|
|
31
|
+
provider,
|
|
32
|
+
sessionId: options.sessionId ?? null,
|
|
33
|
+
model,
|
|
34
|
+
source: model === 'default' ? 'default' : 'session',
|
|
35
|
+
};
|
|
36
|
+
},
|
|
37
|
+
resolveResumeModel: async () => undefined,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async function executeCommand(
|
|
42
|
+
commandName: string,
|
|
43
|
+
context: Record<string, unknown>,
|
|
44
|
+
sessionModels: Record<string, string> = {},
|
|
45
|
+
): Promise<Record<string, unknown>> {
|
|
46
|
+
const router = createCommandsRouter({
|
|
47
|
+
fileSystem: {
|
|
48
|
+
readFile: async () => JSON.stringify({ name: 'claude-code-ui', version: '0.0.0-test' }),
|
|
49
|
+
} as unknown as typeof import('node:fs/promises'),
|
|
50
|
+
homeDirectory: () => '/home/test',
|
|
51
|
+
appRoot: '/app',
|
|
52
|
+
models: createModelsService(sessionModels) as never,
|
|
53
|
+
runtime: {
|
|
54
|
+
uptime: () => 0,
|
|
55
|
+
memoryUsage: () => ({ rss: 0, heapTotal: 0, heapUsed: 0, external: 0, arrayBuffers: 0 }),
|
|
56
|
+
version: 'v22', platform: 'linux', pid: 1,
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
const app = express().use(express.json()).use('/api/commands', router);
|
|
60
|
+
const server = app.listen(0, '127.0.0.1');
|
|
61
|
+
await once(server, 'listening');
|
|
62
|
+
try {
|
|
63
|
+
const address = server.address() as AddressInfo;
|
|
64
|
+
const response = await fetch(`http://127.0.0.1:${address.port}/api/commands/execute`, {
|
|
65
|
+
method: 'POST', headers: { 'content-type': 'application/json' },
|
|
66
|
+
body: JSON.stringify({ commandName, context }),
|
|
67
|
+
});
|
|
68
|
+
assert.equal(response.status, 200);
|
|
69
|
+
return await response.json() as Record<string, unknown>;
|
|
70
|
+
} finally {
|
|
71
|
+
await new Promise<void>((resolve) => server.close(() => resolve()));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
test('models command returns models only for the active provider using injected catalog', async () => {
|
|
76
|
+
const result = await executeCommand('/models', { provider: 'codex' });
|
|
77
|
+
const data = result.data as Record<string, unknown>;
|
|
78
|
+
assert.deepEqual(Object.keys(data.available as object), ['codex']);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test('models command falls back to claude for unsupported providers', async () => {
|
|
82
|
+
const result = await executeCommand('/models', { provider: 'unknown-provider' });
|
|
83
|
+
const data = result.data as { current: { provider: string } };
|
|
84
|
+
assert.equal(data.current.provider, 'claude');
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test('models command reports the model recorded for the session', async () => {
|
|
88
|
+
const result = await executeCommand(
|
|
89
|
+
'/models',
|
|
90
|
+
{ provider: 'claude', sessionId: 'session-1', model: 'sonnet' },
|
|
91
|
+
{ 'session-1': 'haiku' },
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
const data = result.data as { current: { model: string } };
|
|
95
|
+
assert.equal(data.current.model, 'haiku');
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test('models command reports the composer model for a chat with no session yet', async () => {
|
|
99
|
+
const result = await executeCommand('/models', { provider: 'claude', model: 'haiku' });
|
|
100
|
+
|
|
101
|
+
const data = result.data as { current: { model: string } };
|
|
102
|
+
assert.equal(data.current.model, 'haiku');
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test('cost and status commands report the same resolved model as /models', async () => {
|
|
106
|
+
const context = { provider: 'claude', sessionId: 'session-1', model: 'sonnet' };
|
|
107
|
+
const sessionModels = { 'session-1': 'haiku' };
|
|
108
|
+
|
|
109
|
+
const cost = await executeCommand('/cost', context, sessionModels);
|
|
110
|
+
const status = await executeCommand('/status', context, sessionModels);
|
|
111
|
+
|
|
112
|
+
assert.equal((cost.data as { model: string }).model, 'haiku');
|
|
113
|
+
assert.equal((status.data as { model: string }).model, 'haiku');
|
|
114
|
+
});
|
|
@@ -6,6 +6,9 @@ export { credentialsDb } from '@/modules/database/repositories/credentials.js';
|
|
|
6
6
|
export { githubTokensDb } from '@/modules/database/repositories/github-tokens.js';
|
|
7
7
|
export { notificationChannelEndpointsDb } from '@/modules/database/repositories/notification-channel-endpoints.js';
|
|
8
8
|
export { notificationPreferencesDb } from '@/modules/database/repositories/notification-preferences.js';
|
|
9
|
+
// providerModelsDb: used by Providers to persist user-managed custom model rows.
|
|
10
|
+
export { providerModelsDb } from '@/modules/database/repositories/provider-models.js';
|
|
11
|
+
// projectsDb: used by Projects, Worktrees, Git, WebSocket, and notification modules to persist and resolve project records.
|
|
9
12
|
export { projectsDb } from '@/modules/database/repositories/projects.db.js';
|
|
10
13
|
export { pushSubscriptionsDb } from '@/modules/database/repositories/push-subscriptions.js';
|
|
11
14
|
export { scanStateDb } from '@/modules/database/repositories/scan-state.db.js';
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
LAST_SCANNED_AT_SQL,
|
|
6
6
|
NOTIFICATION_CHANNEL_ENDPOINTS_TABLE_SCHEMA_SQL,
|
|
7
7
|
PROJECTS_TABLE_SCHEMA_SQL,
|
|
8
|
+
PROVIDER_MODELS_TABLE_SCHEMA_SQL,
|
|
8
9
|
PUSH_SUBSCRIPTIONS_TABLE_SCHEMA_SQL,
|
|
9
10
|
SESSIONS_TABLE_SCHEMA_SQL,
|
|
10
11
|
USER_NOTIFICATION_PREFERENCES_TABLE_SCHEMA_SQL,
|
|
@@ -402,6 +403,33 @@ const addProviderSessionIdMapping = (db: Database): void => {
|
|
|
402
403
|
`);
|
|
403
404
|
};
|
|
404
405
|
|
|
406
|
+
/**
|
|
407
|
+
* Adds the `model` column that records which model each session runs with.
|
|
408
|
+
*
|
|
409
|
+
* Left NULL for pre-existing rows on purpose: the model resolver falls back to
|
|
410
|
+
* the provider-native lookup for sessions the app has never sent on, so a
|
|
411
|
+
* backfilled guess would only mask the real value.
|
|
412
|
+
*/
|
|
413
|
+
const addSessionModelColumn = (db: Database): void => {
|
|
414
|
+
const sessionsTableInfo = getTableInfo(db, 'sessions');
|
|
415
|
+
const columnNames = sessionsTableInfo.map((column) => column.name);
|
|
416
|
+
|
|
417
|
+
addColumnToTableIfNotExists(db, 'sessions', columnNames, 'model', 'TEXT');
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* Adds the `effort` column that records a session's reasoning-effort choice.
|
|
422
|
+
*
|
|
423
|
+
* Existing rows stay NULL so clients can continue falling back to their
|
|
424
|
+
* per-provider preference until the user selects an effort or sends a turn.
|
|
425
|
+
*/
|
|
426
|
+
const addSessionEffortColumn = (db: Database): void => {
|
|
427
|
+
const sessionsTableInfo = getTableInfo(db, 'sessions');
|
|
428
|
+
const columnNames = sessionsTableInfo.map((column) => column.name);
|
|
429
|
+
|
|
430
|
+
addColumnToTableIfNotExists(db, 'sessions', columnNames, 'effort', 'TEXT');
|
|
431
|
+
};
|
|
432
|
+
|
|
405
433
|
const ensureProjectsForSessionPaths = (db: Database): void => {
|
|
406
434
|
if (!tableExists(db, 'sessions')) {
|
|
407
435
|
return;
|
|
@@ -444,6 +472,11 @@ export const runMigrations = (db: Database) => {
|
|
|
444
472
|
db.exec(NOTIFICATION_CHANNEL_ENDPOINTS_TABLE_SCHEMA_SQL);
|
|
445
473
|
db.exec('CREATE INDEX IF NOT EXISTS idx_notification_channel_endpoints_user_channel ON notification_channel_endpoints(user_id, channel)');
|
|
446
474
|
db.exec('CREATE INDEX IF NOT EXISTS idx_notification_channel_endpoints_enabled ON notification_channel_endpoints(enabled)');
|
|
475
|
+
db.exec(PROVIDER_MODELS_TABLE_SCHEMA_SQL);
|
|
476
|
+
db.exec(`
|
|
477
|
+
CREATE INDEX IF NOT EXISTS idx_provider_models_provider_order
|
|
478
|
+
ON provider_models(provider, sort_order, id)
|
|
479
|
+
`);
|
|
447
480
|
|
|
448
481
|
db.exec(PROJECTS_TABLE_SCHEMA_SQL);
|
|
449
482
|
rebuildProjectsTableWithPrimaryKeySchema(db);
|
|
@@ -452,6 +485,8 @@ export const runMigrations = (db: Database) => {
|
|
|
452
485
|
rebuildSessionsTableWithProjectSchema(db);
|
|
453
486
|
migrateLegacySessionNames(db);
|
|
454
487
|
addProviderSessionIdMapping(db);
|
|
488
|
+
addSessionModelColumn(db);
|
|
489
|
+
addSessionEffortColumn(db);
|
|
455
490
|
ensureProjectsForSessionPaths(db);
|
|
456
491
|
|
|
457
492
|
db.exec('CREATE INDEX IF NOT EXISTS idx_session_ids_lookup ON sessions(session_id)');
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { getConnection } from '@/modules/database/connection.js';
|
|
2
|
+
import type {
|
|
3
|
+
CustomProviderModelInput,
|
|
4
|
+
CustomProviderModelRecord,
|
|
5
|
+
LLMProvider,
|
|
6
|
+
} from '@/shared/types.js';
|
|
7
|
+
|
|
8
|
+
type CustomProviderModelRow = {
|
|
9
|
+
id: number;
|
|
10
|
+
provider: LLMProvider;
|
|
11
|
+
model_id: string;
|
|
12
|
+
model_name: string;
|
|
13
|
+
sort_order: number;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const toCustomProviderModelRecord = (
|
|
17
|
+
row: CustomProviderModelRow,
|
|
18
|
+
): CustomProviderModelRecord => ({
|
|
19
|
+
recordId: row.id,
|
|
20
|
+
provider: row.provider,
|
|
21
|
+
modelId: row.model_id,
|
|
22
|
+
model: row.model_name,
|
|
23
|
+
sortOrder: row.sort_order,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const readCustomProviderModelRow = (
|
|
27
|
+
provider: LLMProvider,
|
|
28
|
+
recordId: number,
|
|
29
|
+
): CustomProviderModelRow | null => {
|
|
30
|
+
const row = getConnection().prepare(`
|
|
31
|
+
SELECT id, provider, model_id, model_name, sort_order
|
|
32
|
+
FROM provider_models
|
|
33
|
+
WHERE provider = ? AND id = ?
|
|
34
|
+
`).get(provider, recordId) as CustomProviderModelRow | undefined;
|
|
35
|
+
|
|
36
|
+
return row ?? null;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Custom provider-model persistence API consumed by the Providers module.
|
|
41
|
+
*
|
|
42
|
+
* Every row in this repository is user-created. Predefined models are owned by
|
|
43
|
+
* provider adapters and never enter this table. Model-id changes are propagated
|
|
44
|
+
* to stored sessions, while deletion replaces affected session selections with
|
|
45
|
+
* the predefined default supplied by the Providers service.
|
|
46
|
+
*/
|
|
47
|
+
export const providerModelsDb = {
|
|
48
|
+
listCustomProviderModels(provider: LLMProvider): CustomProviderModelRecord[] {
|
|
49
|
+
const rows = getConnection().prepare(`
|
|
50
|
+
SELECT id, provider, model_id, model_name, sort_order
|
|
51
|
+
FROM provider_models
|
|
52
|
+
WHERE provider = ?
|
|
53
|
+
ORDER BY sort_order ASC, lower(model_name) ASC, id ASC
|
|
54
|
+
`).all(provider) as CustomProviderModelRow[];
|
|
55
|
+
|
|
56
|
+
return rows.map(toCustomProviderModelRecord);
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
getCustomProviderModel(
|
|
60
|
+
provider: LLMProvider,
|
|
61
|
+
recordId: number,
|
|
62
|
+
): CustomProviderModelRecord | null {
|
|
63
|
+
const row = readCustomProviderModelRow(provider, recordId);
|
|
64
|
+
return row ? toCustomProviderModelRecord(row) : null;
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
findCustomProviderModelByModelId(
|
|
68
|
+
provider: LLMProvider,
|
|
69
|
+
modelId: string,
|
|
70
|
+
): CustomProviderModelRecord | null {
|
|
71
|
+
const row = getConnection().prepare(`
|
|
72
|
+
SELECT id, provider, model_id, model_name, sort_order
|
|
73
|
+
FROM provider_models
|
|
74
|
+
WHERE provider = ? AND model_id = ?
|
|
75
|
+
`).get(provider, modelId) as CustomProviderModelRow | undefined;
|
|
76
|
+
|
|
77
|
+
return row ? toCustomProviderModelRecord(row) : null;
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
createCustomProviderModel(
|
|
81
|
+
provider: LLMProvider,
|
|
82
|
+
input: CustomProviderModelInput,
|
|
83
|
+
): CustomProviderModelRecord {
|
|
84
|
+
const db = getConnection();
|
|
85
|
+
const nextOrder = db.prepare(`
|
|
86
|
+
SELECT COALESCE(MAX(sort_order), -1) + 1 AS next_order
|
|
87
|
+
FROM provider_models
|
|
88
|
+
WHERE provider = ?
|
|
89
|
+
`).get(provider) as { next_order: number };
|
|
90
|
+
|
|
91
|
+
const result = db.prepare(`
|
|
92
|
+
INSERT INTO provider_models (provider, model_id, model_name, sort_order)
|
|
93
|
+
VALUES (?, ?, ?, ?)
|
|
94
|
+
`).run(provider, input.id, input.model, nextOrder.next_order);
|
|
95
|
+
|
|
96
|
+
const row = readCustomProviderModelRow(provider, Number(result.lastInsertRowid));
|
|
97
|
+
if (!row) {
|
|
98
|
+
throw new Error('Created provider model could not be read back.');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return toCustomProviderModelRecord(row);
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
updateCustomProviderModel(
|
|
105
|
+
provider: LLMProvider,
|
|
106
|
+
recordId: number,
|
|
107
|
+
input: CustomProviderModelInput,
|
|
108
|
+
): CustomProviderModelRecord | null {
|
|
109
|
+
const db = getConnection();
|
|
110
|
+
const update = db.transaction(() => {
|
|
111
|
+
const previous = readCustomProviderModelRow(provider, recordId);
|
|
112
|
+
if (!previous) {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
db.prepare(`
|
|
117
|
+
UPDATE provider_models
|
|
118
|
+
SET model_id = ?, model_name = ?, updated_at = CURRENT_TIMESTAMP
|
|
119
|
+
WHERE provider = ? AND id = ?
|
|
120
|
+
`).run(input.id, input.model, provider, recordId);
|
|
121
|
+
|
|
122
|
+
if (previous.model_id !== input.id) {
|
|
123
|
+
db.prepare(`
|
|
124
|
+
UPDATE sessions
|
|
125
|
+
SET model = ?, updated_at = CURRENT_TIMESTAMP
|
|
126
|
+
WHERE provider = ? AND model = ?
|
|
127
|
+
`).run(input.id, provider, previous.model_id);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return readCustomProviderModelRow(provider, recordId);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const row = update();
|
|
134
|
+
return row ? toCustomProviderModelRecord(row) : null;
|
|
135
|
+
},
|
|
136
|
+
|
|
137
|
+
deleteCustomProviderModel(
|
|
138
|
+
provider: LLMProvider,
|
|
139
|
+
recordId: number,
|
|
140
|
+
fallbackModelId: string,
|
|
141
|
+
): CustomProviderModelRecord | null {
|
|
142
|
+
const db = getConnection();
|
|
143
|
+
const remove = db.transaction(() => {
|
|
144
|
+
const row = readCustomProviderModelRow(provider, recordId);
|
|
145
|
+
if (!row) {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// The effort is cleared alongside the model because it was chosen for the
|
|
150
|
+
// deleted model; replaced sessions resume on the fallback model's default.
|
|
151
|
+
db.prepare(`
|
|
152
|
+
UPDATE sessions
|
|
153
|
+
SET model = ?, effort = NULL, updated_at = CURRENT_TIMESTAMP
|
|
154
|
+
WHERE provider = ? AND model = ?
|
|
155
|
+
`).run(fallbackModelId, provider, row.model_id);
|
|
156
|
+
|
|
157
|
+
db.prepare(`
|
|
158
|
+
DELETE FROM provider_models
|
|
159
|
+
WHERE provider = ? AND id = ?
|
|
160
|
+
`).run(provider, recordId);
|
|
161
|
+
|
|
162
|
+
return row;
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
const row = remove();
|
|
166
|
+
return row ? toCustomProviderModelRecord(row) : null;
|
|
167
|
+
},
|
|
168
|
+
};
|
|
@@ -9,13 +9,22 @@ type SessionRow = {
|
|
|
9
9
|
project_path: string | null;
|
|
10
10
|
jsonl_path: string | null;
|
|
11
11
|
custom_name: string | null;
|
|
12
|
+
/** Model this session runs with; NULL until the app records one for it. */
|
|
13
|
+
model: string | null;
|
|
14
|
+
/** Reasoning effort this session runs with; NULL until the app records one. */
|
|
15
|
+
effort: string | null;
|
|
12
16
|
isArchived: number;
|
|
13
17
|
created_at: string;
|
|
14
18
|
updated_at: string;
|
|
15
19
|
};
|
|
16
20
|
|
|
21
|
+
type RecentSessionsPage = {
|
|
22
|
+
sessions: SessionRow[];
|
|
23
|
+
total: number;
|
|
24
|
+
};
|
|
25
|
+
|
|
17
26
|
const SESSION_ROW_COLUMNS =
|
|
18
|
-
'session_id, provider, provider_session_id, project_path, jsonl_path, custom_name, isArchived, created_at, updated_at';
|
|
27
|
+
'session_id, provider, provider_session_id, project_path, jsonl_path, custom_name, model, effort, isArchived, created_at, updated_at';
|
|
19
28
|
|
|
20
29
|
const SQLITE_UTC_TIMESTAMP_REGEX = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/;
|
|
21
30
|
|
|
@@ -65,7 +74,9 @@ export const sessionsDb = {
|
|
|
65
74
|
* The given id is the provider-native session id. Rows are keyed by
|
|
66
75
|
* `provider_session_id` so a session that was first created by the app
|
|
67
76
|
* (with an app-allocated `session_id`) is updated in place once its
|
|
68
|
-
* transcript shows up on disk, instead of producing a duplicate row.
|
|
77
|
+
* transcript shows up on disk, instead of producing a duplicate row. An
|
|
78
|
+
* app-created row keeps its existing name; synchronizer names only update
|
|
79
|
+
* rows that were themselves created by indexing provider storage.
|
|
69
80
|
*/
|
|
70
81
|
createSession(
|
|
71
82
|
providerSessionId: string,
|
|
@@ -101,7 +112,10 @@ export const sessionsDb = {
|
|
|
101
112
|
project_path = ?,
|
|
102
113
|
jsonl_path = ?,
|
|
103
114
|
isArchived = 0,
|
|
104
|
-
custom_name =
|
|
115
|
+
custom_name = CASE
|
|
116
|
+
WHEN session_id <> provider_session_id AND custom_name IS NOT NULL THEN custom_name
|
|
117
|
+
ELSE COALESCE(?, custom_name)
|
|
118
|
+
END
|
|
105
119
|
WHERE session_id = ?`
|
|
106
120
|
).run(
|
|
107
121
|
provider,
|
|
@@ -128,7 +142,11 @@ export const sessionsDb = {
|
|
|
128
142
|
project_path = excluded.project_path,
|
|
129
143
|
jsonl_path = excluded.jsonl_path,
|
|
130
144
|
isArchived = 0,
|
|
131
|
-
custom_name =
|
|
145
|
+
custom_name = CASE
|
|
146
|
+
WHEN sessions.session_id <> sessions.provider_session_id AND sessions.custom_name IS NOT NULL
|
|
147
|
+
THEN sessions.custom_name
|
|
148
|
+
ELSE COALESCE(excluded.custom_name, sessions.custom_name)
|
|
149
|
+
END`
|
|
132
150
|
).run(
|
|
133
151
|
providerSessionId,
|
|
134
152
|
provider,
|
|
@@ -149,9 +167,15 @@ export const sessionsDb = {
|
|
|
149
167
|
* The session gateway uses this when the frontend starts a brand-new chat:
|
|
150
168
|
* `session_id` is the stable app-facing id, while `provider_session_id`
|
|
151
169
|
* stays NULL until the provider runtime announces its own id and
|
|
152
|
-
* `assignProviderSessionId` records the mapping.
|
|
170
|
+
* `assignProviderSessionId` records the mapping. `customName` is derived
|
|
171
|
+
* from the first visible CloudCLI message by the sessions service.
|
|
153
172
|
*/
|
|
154
|
-
createAppSession(
|
|
173
|
+
createAppSession(
|
|
174
|
+
sessionId: string,
|
|
175
|
+
provider: string,
|
|
176
|
+
projectPath: string,
|
|
177
|
+
customName?: string,
|
|
178
|
+
): string {
|
|
155
179
|
const db = getConnection();
|
|
156
180
|
const normalizedProjectPath = normalizeProjectPathForProvider(provider, projectPath);
|
|
157
181
|
|
|
@@ -159,8 +183,8 @@ export const sessionsDb = {
|
|
|
159
183
|
|
|
160
184
|
db.prepare(
|
|
161
185
|
`INSERT INTO sessions (session_id, provider, provider_session_id, custom_name, project_path, jsonl_path, isArchived, created_at, updated_at)
|
|
162
|
-
VALUES (?, ?, NULL,
|
|
163
|
-
).run(sessionId, provider, normalizedProjectPath);
|
|
186
|
+
VALUES (?, ?, NULL, ?, ?, NULL, 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)`
|
|
187
|
+
).run(sessionId, provider, customName ?? null, normalizedProjectPath);
|
|
164
188
|
|
|
165
189
|
return sessionId;
|
|
166
190
|
},
|
|
@@ -211,6 +235,37 @@ export const sessionsDb = {
|
|
|
211
235
|
merge();
|
|
212
236
|
},
|
|
213
237
|
|
|
238
|
+
/**
|
|
239
|
+
* Records the model one session runs with.
|
|
240
|
+
*
|
|
241
|
+
* Called both when the user picks a model for the session and on every send,
|
|
242
|
+
* so the row always reflects what the session last ran with and reopening it
|
|
243
|
+
* restores that model instead of a catalog default.
|
|
244
|
+
*/
|
|
245
|
+
setSessionModel(sessionId: string, model: string): void {
|
|
246
|
+
const db = getConnection();
|
|
247
|
+
db.prepare(
|
|
248
|
+
`UPDATE sessions
|
|
249
|
+
SET model = ?
|
|
250
|
+
WHERE session_id = ?`
|
|
251
|
+
).run(model, sessionId);
|
|
252
|
+
},
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Records the reasoning effort one session runs with.
|
|
256
|
+
*
|
|
257
|
+
* `default` is stored as an explicit choice rather than NULL so reopening
|
|
258
|
+
* the session does not inherit a later per-provider effort preference.
|
|
259
|
+
*/
|
|
260
|
+
setSessionEffort(sessionId: string, effort: string): void {
|
|
261
|
+
const db = getConnection();
|
|
262
|
+
db.prepare(
|
|
263
|
+
`UPDATE sessions
|
|
264
|
+
SET effort = ?
|
|
265
|
+
WHERE session_id = ?`
|
|
266
|
+
).run(effort, sessionId);
|
|
267
|
+
},
|
|
268
|
+
|
|
214
269
|
updateSessionCustomName(sessionId: string, customName: string): void {
|
|
215
270
|
const db = getConnection();
|
|
216
271
|
db.prepare(
|
|
@@ -307,6 +362,46 @@ export const sessionsDb = {
|
|
|
307
362
|
return normalizeSessionRows(rows);
|
|
308
363
|
},
|
|
309
364
|
|
|
365
|
+
/**
|
|
366
|
+
* Returns one globally ordered page of visible conversations.
|
|
367
|
+
*
|
|
368
|
+
* Pagination happens after archived sessions and sessions belonging to an
|
|
369
|
+
* archived project have been excluded. This keeps the sidebar feed complete
|
|
370
|
+
* and correctly ordered across projects instead of flattening only the
|
|
371
|
+
* per-project slices already loaded by the client.
|
|
372
|
+
*/
|
|
373
|
+
getRecentSessionsPage(limit: number, offset: number): RecentSessionsPage {
|
|
374
|
+
const db = getConnection();
|
|
375
|
+
const visibilityClause = `
|
|
376
|
+
sessions.isArchived = 0
|
|
377
|
+
AND (projects.isArchived IS NULL OR projects.isArchived = 0)
|
|
378
|
+
`;
|
|
379
|
+
const rows = db
|
|
380
|
+
.prepare(
|
|
381
|
+
`SELECT sessions.*
|
|
382
|
+
FROM sessions
|
|
383
|
+
LEFT JOIN projects ON projects.project_path = sessions.project_path
|
|
384
|
+
WHERE ${visibilityClause}
|
|
385
|
+
ORDER BY julianday(COALESCE(sessions.updated_at, sessions.created_at)) DESC,
|
|
386
|
+
sessions.session_id DESC
|
|
387
|
+
LIMIT ? OFFSET ?`
|
|
388
|
+
)
|
|
389
|
+
.all(limit, offset) as SessionRow[];
|
|
390
|
+
const countRow = db
|
|
391
|
+
.prepare(
|
|
392
|
+
`SELECT COUNT(*) AS count
|
|
393
|
+
FROM sessions
|
|
394
|
+
LEFT JOIN projects ON projects.project_path = sessions.project_path
|
|
395
|
+
WHERE ${visibilityClause}`
|
|
396
|
+
)
|
|
397
|
+
.get() as { count: number } | undefined;
|
|
398
|
+
|
|
399
|
+
return {
|
|
400
|
+
sessions: normalizeSessionRows(rows),
|
|
401
|
+
total: Number(countRow?.count ?? 0),
|
|
402
|
+
};
|
|
403
|
+
},
|
|
404
|
+
|
|
310
405
|
/**
|
|
311
406
|
* Archived rows are intentionally queried separately so the caller can render
|
|
312
407
|
* them in a dedicated view without reintroducing them into active session lists.
|