@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
|
@@ -0,0 +1,199 @@
|
|
|
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, {
|
|
7
|
+
type NextFunction,
|
|
8
|
+
type Request,
|
|
9
|
+
type Response,
|
|
10
|
+
} from 'express';
|
|
11
|
+
|
|
12
|
+
import { createWorktreesRouter } from '@/modules/worktrees/worktrees.routes.js';
|
|
13
|
+
import type {
|
|
14
|
+
CreateWorktreeInput,
|
|
15
|
+
WorktreeServices,
|
|
16
|
+
} from '@/shared/types.js';
|
|
17
|
+
import { AppError } from '@/shared/utils.js';
|
|
18
|
+
|
|
19
|
+
function createFakeServices(overrides: Partial<WorktreeServices> = {}): WorktreeServices {
|
|
20
|
+
const unused = async (): Promise<never> => {
|
|
21
|
+
throw new Error('Unexpected Worktrees service call');
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
resolveProjectPath: () => {
|
|
26
|
+
throw new Error('Unexpected project resolution');
|
|
27
|
+
},
|
|
28
|
+
list: unused,
|
|
29
|
+
create: unused,
|
|
30
|
+
createAndOpen: unused,
|
|
31
|
+
open: unused,
|
|
32
|
+
merge: unused,
|
|
33
|
+
remove: unused,
|
|
34
|
+
...overrides,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function withWorktreesServer(
|
|
39
|
+
services: WorktreeServices,
|
|
40
|
+
run: (baseUrl: string) => Promise<void>,
|
|
41
|
+
): Promise<void> {
|
|
42
|
+
const app = express();
|
|
43
|
+
app.use(express.json());
|
|
44
|
+
app.use('/api/worktrees', createWorktreesRouter(services));
|
|
45
|
+
app.use((error: unknown, _req: Request, res: Response, _next: NextFunction) => {
|
|
46
|
+
if (error instanceof AppError) {
|
|
47
|
+
res.status(error.statusCode).json({ error: error.code });
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
res.status(500).json({ error: 'INTERNAL_ERROR' });
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const server = app.listen(0, '127.0.0.1');
|
|
55
|
+
await once(server, 'listening');
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
const address = server.address() as AddressInfo;
|
|
59
|
+
await run(`http://127.0.0.1:${address.port}`);
|
|
60
|
+
} finally {
|
|
61
|
+
await new Promise<void>((resolve, reject) => {
|
|
62
|
+
server.close((error) => error ? reject(error) : resolve());
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
test('create route parses input and invokes the create-and-open application service', async () => {
|
|
68
|
+
const createInputs: CreateWorktreeInput[] = [];
|
|
69
|
+
const services = createFakeServices({
|
|
70
|
+
resolveProjectPath: (projectId) => {
|
|
71
|
+
assert.equal(projectId, 'project-1');
|
|
72
|
+
return '/workspace/repo';
|
|
73
|
+
},
|
|
74
|
+
createAndOpen: async (input) => {
|
|
75
|
+
createInputs.push(input);
|
|
76
|
+
return {
|
|
77
|
+
worktreePath: '/workspace/repo-worktrees/feature-login',
|
|
78
|
+
branch: input.branch,
|
|
79
|
+
createdBranch: true,
|
|
80
|
+
project: {
|
|
81
|
+
projectId: 'worktree-project-1',
|
|
82
|
+
path: '/workspace/repo-worktrees/feature-login',
|
|
83
|
+
fullPath: '/workspace/repo-worktrees/feature-login',
|
|
84
|
+
displayName: 'repo worktree',
|
|
85
|
+
isStarred: false,
|
|
86
|
+
sessions: [],
|
|
87
|
+
sessionMeta: { hasMore: false, total: 0 },
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
await withWorktreesServer(services, async (baseUrl) => {
|
|
94
|
+
const response = await fetch(`${baseUrl}/api/worktrees/create`, {
|
|
95
|
+
method: 'POST',
|
|
96
|
+
headers: { 'content-type': 'application/json' },
|
|
97
|
+
body: JSON.stringify({
|
|
98
|
+
project: ' project-1 ',
|
|
99
|
+
branch: ' feature/login ',
|
|
100
|
+
baseBranch: 'main',
|
|
101
|
+
}),
|
|
102
|
+
});
|
|
103
|
+
const payload = await response.json() as {
|
|
104
|
+
success: boolean;
|
|
105
|
+
data: { project: { projectId: string } };
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
assert.equal(response.status, 200);
|
|
109
|
+
assert.equal(payload.success, true);
|
|
110
|
+
assert.equal(payload.data.project.projectId, 'worktree-project-1');
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
assert.deepEqual(createInputs, [{
|
|
114
|
+
projectPath: '/workspace/repo',
|
|
115
|
+
branch: 'feature/login',
|
|
116
|
+
baseBranch: 'main',
|
|
117
|
+
}]);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
test('create route rejects missing branch before calling a mutation service', async () => {
|
|
121
|
+
let createCalled = false;
|
|
122
|
+
const services = createFakeServices({
|
|
123
|
+
resolveProjectPath: () => '/workspace/repo',
|
|
124
|
+
createAndOpen: async () => {
|
|
125
|
+
createCalled = true;
|
|
126
|
+
throw new Error('create should not run for invalid input');
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
await withWorktreesServer(services, async (baseUrl) => {
|
|
131
|
+
const response = await fetch(`${baseUrl}/api/worktrees/create`, {
|
|
132
|
+
method: 'POST',
|
|
133
|
+
headers: { 'content-type': 'application/json' },
|
|
134
|
+
body: JSON.stringify({ project: 'project-1' }),
|
|
135
|
+
});
|
|
136
|
+
const payload = await response.json() as { error: string };
|
|
137
|
+
|
|
138
|
+
assert.equal(response.status, 400);
|
|
139
|
+
assert.equal(payload.error, 'INVALID_REQUEST_BODY');
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
assert.equal(createCalled, false);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
test('merge and remove routes do not coerce string booleans to true', async () => {
|
|
146
|
+
const mergeInputs: Array<{ squash?: boolean; removeAfterMerge?: boolean }> = [];
|
|
147
|
+
const removeInputs: Array<{ force?: boolean; deleteBranch?: boolean }> = [];
|
|
148
|
+
const services = createFakeServices({
|
|
149
|
+
resolveProjectPath: () => '/workspace/repo',
|
|
150
|
+
merge: async (input) => {
|
|
151
|
+
mergeInputs.push(input);
|
|
152
|
+
return {
|
|
153
|
+
mergedBranch: 'feature/login',
|
|
154
|
+
targetBranch: 'main',
|
|
155
|
+
squash: false,
|
|
156
|
+
removedWorktree: null,
|
|
157
|
+
cleanupError: null,
|
|
158
|
+
};
|
|
159
|
+
},
|
|
160
|
+
remove: async (input) => {
|
|
161
|
+
removeInputs.push(input);
|
|
162
|
+
return {
|
|
163
|
+
removedPath: input.worktreePath,
|
|
164
|
+
branch: 'feature/login',
|
|
165
|
+
branchDeleted: false,
|
|
166
|
+
archivedProjectId: null,
|
|
167
|
+
archivalError: null,
|
|
168
|
+
};
|
|
169
|
+
},
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
await withWorktreesServer(services, async (baseUrl) => {
|
|
173
|
+
const body = {
|
|
174
|
+
project: 'project-1',
|
|
175
|
+
worktreePath: '/workspace/repo-worktrees/feature-login',
|
|
176
|
+
squash: 'false',
|
|
177
|
+
removeAfterMerge: 'false',
|
|
178
|
+
force: 'false',
|
|
179
|
+
deleteBranch: 'false',
|
|
180
|
+
};
|
|
181
|
+
const mergeResponse = await fetch(`${baseUrl}/api/worktrees/merge`, {
|
|
182
|
+
method: 'POST',
|
|
183
|
+
headers: { 'content-type': 'application/json' },
|
|
184
|
+
body: JSON.stringify(body),
|
|
185
|
+
});
|
|
186
|
+
const removeResponse = await fetch(`${baseUrl}/api/worktrees/remove`, {
|
|
187
|
+
method: 'POST',
|
|
188
|
+
headers: { 'content-type': 'application/json' },
|
|
189
|
+
body: JSON.stringify(body),
|
|
190
|
+
});
|
|
191
|
+
assert.equal(mergeResponse.status, 200);
|
|
192
|
+
assert.equal(removeResponse.status, 200);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
assert.equal(mergeInputs[0].squash, false);
|
|
196
|
+
assert.equal(mergeInputs[0].removeAfterMerge, false);
|
|
197
|
+
assert.equal(removeInputs[0].force, false);
|
|
198
|
+
assert.equal(removeInputs[0].deleteBranch, false);
|
|
199
|
+
});
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { access } from 'node:fs/promises';
|
|
2
|
+
|
|
3
|
+
import { projectsDb } from '@/modules/database/index.js';
|
|
4
|
+
import {
|
|
5
|
+
createProject,
|
|
6
|
+
deleteOrArchiveProject,
|
|
7
|
+
restoreArchivedProject,
|
|
8
|
+
} from '@/modules/projects/index.js';
|
|
9
|
+
import type {
|
|
10
|
+
WorktreeFileSystem,
|
|
11
|
+
WorktreeProjectGateway,
|
|
12
|
+
WorktreeServices,
|
|
13
|
+
} from '@/shared/types.js';
|
|
14
|
+
import { AppError } from '@/shared/utils.js';
|
|
15
|
+
import { createWorktree } from '@/modules/worktrees/services/worktree-create.service.js';
|
|
16
|
+
import { createAndOpenWorktree } from '@/modules/worktrees/services/worktree-create-and-open.service.js';
|
|
17
|
+
import { runGitCommand } from '@/modules/worktrees/services/worktree-git.service.js';
|
|
18
|
+
import { listWorktrees } from '@/modules/worktrees/services/worktree-list.service.js';
|
|
19
|
+
import { mergeWorktree } from '@/modules/worktrees/services/worktree-merge.service.js';
|
|
20
|
+
import { openWorktreeAsProject } from '@/modules/worktrees/services/worktree-open.service.js';
|
|
21
|
+
import { removeWorktree } from '@/modules/worktrees/services/worktree-remove.service.js';
|
|
22
|
+
import { createWorktreesRouter } from '@/modules/worktrees/worktrees.routes.js';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Real filesystem adapter used only by Worktrees production composition.
|
|
26
|
+
*
|
|
27
|
+
* Services depend on the shared capability type and therefore cannot touch a
|
|
28
|
+
* developer's filesystem unless this adapter is explicitly supplied.
|
|
29
|
+
*/
|
|
30
|
+
const worktreeFileSystem: WorktreeFileSystem = {
|
|
31
|
+
async pathExists(candidatePath: string): Promise<boolean> {
|
|
32
|
+
try {
|
|
33
|
+
await access(candidatePath);
|
|
34
|
+
return true;
|
|
35
|
+
} catch {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Projects boundary for Worktrees production workflows.
|
|
43
|
+
*
|
|
44
|
+
* Imports are deliberately restricted to the Database and Projects barrel
|
|
45
|
+
* files. No Worktrees service knows which repository or project service backs
|
|
46
|
+
* these operations.
|
|
47
|
+
*/
|
|
48
|
+
const worktreeProjects: WorktreeProjectGateway = {
|
|
49
|
+
getProjectPathById: (projectId) => projectsDb.getProjectPathById(projectId),
|
|
50
|
+
getProjectByPath: (projectPath) => projectsDb.getProjectPath(projectPath),
|
|
51
|
+
createProject: (input) => createProject(input),
|
|
52
|
+
restoreProject: (projectId) => restoreArchivedProject(projectId),
|
|
53
|
+
archiveProject: (projectId) => deleteOrArchiveProject(projectId, false),
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const remove: WorktreeServices['remove'] = (input) => removeWorktree(input, {
|
|
57
|
+
runGit: runGitCommand,
|
|
58
|
+
projects: worktreeProjects,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const create: WorktreeServices['create'] = (input) => createWorktree(input, {
|
|
62
|
+
runGit: runGitCommand,
|
|
63
|
+
fileSystem: worktreeFileSystem,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const open: WorktreeServices['open'] = (input) => openWorktreeAsProject(input, {
|
|
67
|
+
runGit: runGitCommand,
|
|
68
|
+
projects: worktreeProjects,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Production Worktrees application-service surface.
|
|
73
|
+
*
|
|
74
|
+
* This is the module's composition root: it is the only location that combines
|
|
75
|
+
* concrete adapters with the independently testable workflow functions.
|
|
76
|
+
*/
|
|
77
|
+
const worktreeServices: WorktreeServices = {
|
|
78
|
+
resolveProjectPath(projectId) {
|
|
79
|
+
const projectPath = worktreeProjects.getProjectPathById(projectId);
|
|
80
|
+
if (!projectPath) {
|
|
81
|
+
throw new AppError(`Unable to resolve project path for "${projectId}"`, {
|
|
82
|
+
code: 'PROJECT_NOT_FOUND',
|
|
83
|
+
statusCode: 404,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return projectPath;
|
|
88
|
+
},
|
|
89
|
+
list: (input) => listWorktrees(input, {
|
|
90
|
+
runGit: runGitCommand,
|
|
91
|
+
getProjectByPath: worktreeProjects.getProjectByPath,
|
|
92
|
+
}),
|
|
93
|
+
create,
|
|
94
|
+
createAndOpen: (input) => createAndOpenWorktree(input, {
|
|
95
|
+
createWorktree: create,
|
|
96
|
+
openWorktree: open,
|
|
97
|
+
removeWorktree: remove,
|
|
98
|
+
}),
|
|
99
|
+
open,
|
|
100
|
+
merge: (input) => mergeWorktree(input, {
|
|
101
|
+
runGit: runGitCommand,
|
|
102
|
+
removeWorktree: remove,
|
|
103
|
+
}),
|
|
104
|
+
remove,
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Worktrees router mounted by the server entrypoint at `/api/worktrees`.
|
|
109
|
+
*
|
|
110
|
+
* It is assembled here so other modules consume only the Worktrees barrel and
|
|
111
|
+
* cannot depend on route or service implementation files.
|
|
112
|
+
*/
|
|
113
|
+
export const worktreesRoutes = createWorktreesRouter(worktreeServices);
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
|
|
3
|
+
import type { WorktreeServices } from '@/shared/types.js';
|
|
4
|
+
import { AppError, asyncHandler, createApiSuccessResponse } from '@/shared/utils.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Parses the project identifier shared by all Worktrees routes.
|
|
8
|
+
*
|
|
9
|
+
* Path resolution intentionally remains in the injected application service so
|
|
10
|
+
* this transport layer never reaches into the Database module.
|
|
11
|
+
*/
|
|
12
|
+
function readProjectId(projectIdValue: unknown): string {
|
|
13
|
+
const projectId = typeof projectIdValue === 'string' ? projectIdValue.trim() : '';
|
|
14
|
+
if (!projectId) {
|
|
15
|
+
throw new AppError('project is required', {
|
|
16
|
+
code: 'PROJECT_ID_REQUIRED',
|
|
17
|
+
statusCode: 400,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return projectId;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function readRequiredString(value: unknown, name: string): string {
|
|
25
|
+
const parsed = typeof value === 'string' ? value.trim() : '';
|
|
26
|
+
if (!parsed) {
|
|
27
|
+
throw new AppError(`${name} is required`, {
|
|
28
|
+
code: 'INVALID_REQUEST_BODY',
|
|
29
|
+
statusCode: 400,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return parsed;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Builds the Worktrees HTTP router around an injected application-service API.
|
|
37
|
+
*
|
|
38
|
+
* Keeping construction explicit lets route tests supply deterministic services
|
|
39
|
+
* and ensures parsing remains the route layer's only responsibility.
|
|
40
|
+
*/
|
|
41
|
+
export function createWorktreesRouter(services: WorktreeServices): express.Router {
|
|
42
|
+
const router = express.Router();
|
|
43
|
+
|
|
44
|
+
router.get(
|
|
45
|
+
'/',
|
|
46
|
+
asyncHandler(async (req, res) => {
|
|
47
|
+
const projectPath = services.resolveProjectPath(readProjectId(req.query.project));
|
|
48
|
+
const result = await services.list({ projectPath });
|
|
49
|
+
res.json(createApiSuccessResponse(result));
|
|
50
|
+
}),
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
router.post(
|
|
54
|
+
'/create',
|
|
55
|
+
asyncHandler(async (req, res) => {
|
|
56
|
+
const body = req.body as Record<string, unknown>;
|
|
57
|
+
const projectPath = services.resolveProjectPath(readProjectId(body.project));
|
|
58
|
+
const branch = readRequiredString(body.branch, 'branch');
|
|
59
|
+
const baseBranch = typeof body.baseBranch === 'string' ? body.baseBranch : null;
|
|
60
|
+
|
|
61
|
+
const result = await services.createAndOpen({ projectPath, branch, baseBranch });
|
|
62
|
+
res.json(createApiSuccessResponse(result));
|
|
63
|
+
}),
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
router.post(
|
|
67
|
+
'/open',
|
|
68
|
+
asyncHandler(async (req, res) => {
|
|
69
|
+
const body = req.body as Record<string, unknown>;
|
|
70
|
+
const projectPath = services.resolveProjectPath(readProjectId(body.project));
|
|
71
|
+
const worktreePath = readRequiredString(body.worktreePath, 'worktreePath');
|
|
72
|
+
|
|
73
|
+
const project = await services.open({ projectPath, worktreePath });
|
|
74
|
+
res.json(createApiSuccessResponse({ project }));
|
|
75
|
+
}),
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
router.post(
|
|
79
|
+
'/merge',
|
|
80
|
+
asyncHandler(async (req, res) => {
|
|
81
|
+
const body = req.body as Record<string, unknown>;
|
|
82
|
+
const projectPath = services.resolveProjectPath(readProjectId(body.project));
|
|
83
|
+
const worktreePath = readRequiredString(body.worktreePath, 'worktreePath');
|
|
84
|
+
|
|
85
|
+
const result = await services.merge({
|
|
86
|
+
projectPath,
|
|
87
|
+
worktreePath,
|
|
88
|
+
squash: typeof body.squash === 'boolean' ? body.squash : false,
|
|
89
|
+
message: typeof body.message === 'string' ? body.message : null,
|
|
90
|
+
removeAfterMerge: typeof body.removeAfterMerge === 'boolean' ? body.removeAfterMerge : false,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
res.json(createApiSuccessResponse(result));
|
|
94
|
+
}),
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
router.post(
|
|
98
|
+
'/remove',
|
|
99
|
+
asyncHandler(async (req, res) => {
|
|
100
|
+
const body = req.body as Record<string, unknown>;
|
|
101
|
+
const projectPath = services.resolveProjectPath(readProjectId(body.project));
|
|
102
|
+
const worktreePath = readRequiredString(body.worktreePath, 'worktreePath');
|
|
103
|
+
|
|
104
|
+
const result = await services.remove({
|
|
105
|
+
projectPath,
|
|
106
|
+
worktreePath,
|
|
107
|
+
force: typeof body.force === 'boolean' ? body.force : false,
|
|
108
|
+
deleteBranch: typeof body.deleteBranch === 'boolean' ? body.deleteBranch : false,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
res.json(createApiSuccessResponse(result));
|
|
112
|
+
}),
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
return router;
|
|
116
|
+
}
|
|
@@ -3,17 +3,18 @@ import os from 'node:os';
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* Shared
|
|
6
|
+
* Shared chat-attachment plumbing for every provider runtime.
|
|
7
7
|
*
|
|
8
|
-
* Uploaded chat
|
|
8
|
+
* Uploaded chat files are persisted once in the global `~/.cloudcli/assets`
|
|
9
9
|
* folder and referenced by absolute path everywhere else:
|
|
10
10
|
* - Claude: paths are read back into base64 `image` content blocks.
|
|
11
11
|
* - Codex: paths become `local_image` input items.
|
|
12
|
-
* -
|
|
13
|
-
*
|
|
12
|
+
* - General files: verified paths are appended inside a `<files_input>` tag,
|
|
13
|
+
* which every provider history adapter strips back out for display.
|
|
14
|
+
* - Cursor/OpenCode images: paths use the equivalent `<images_input>` tag.
|
|
14
15
|
*
|
|
15
|
-
* The chat UI loads them through
|
|
16
|
-
*
|
|
16
|
+
* The chat UI loads them through dedicated `/api/assets/images/:filename` and
|
|
17
|
+
* `/api/assets/files/:filename` routes, which serve only from this folder.
|
|
17
18
|
*/
|
|
18
19
|
|
|
19
20
|
/** Global storage folder for uploaded chat image attachments. */
|
|
@@ -26,8 +27,12 @@ export type ImageAttachmentDescriptor = {
|
|
|
26
27
|
path: string;
|
|
27
28
|
name?: string;
|
|
28
29
|
mimeType?: string;
|
|
30
|
+
size?: number;
|
|
29
31
|
};
|
|
30
32
|
|
|
33
|
+
/** Provider-neutral descriptor used for both image and non-image chat attachments. */
|
|
34
|
+
export type ChatAttachmentDescriptor = ImageAttachmentDescriptor;
|
|
35
|
+
|
|
31
36
|
/** Media types the Claude Messages API accepts for base64 image blocks. */
|
|
32
37
|
const CLAUDE_IMAGE_MEDIA_TYPES = new Set([
|
|
33
38
|
'image/jpeg',
|
|
@@ -46,17 +51,17 @@ const EXTENSION_TO_MEDIA_TYPE: Record<string, string> = {
|
|
|
46
51
|
};
|
|
47
52
|
|
|
48
53
|
/**
|
|
49
|
-
* Accepts
|
|
50
|
-
*
|
|
51
|
-
*
|
|
54
|
+
* Accepts a loosely typed chat attachment payload and returns only well-formed
|
|
55
|
+
* descriptors. The websocket gateway and provider adapters use this to handle
|
|
56
|
+
* current `attachments` payloads and legacy image path arrays consistently.
|
|
52
57
|
*/
|
|
53
|
-
export function
|
|
54
|
-
if (!Array.isArray(
|
|
58
|
+
export function normalizeAttachmentDescriptors(attachments: unknown): ChatAttachmentDescriptor[] {
|
|
59
|
+
if (!Array.isArray(attachments)) {
|
|
55
60
|
return [];
|
|
56
61
|
}
|
|
57
62
|
|
|
58
|
-
const descriptors:
|
|
59
|
-
for (const entry of
|
|
63
|
+
const descriptors: ChatAttachmentDescriptor[] = [];
|
|
64
|
+
for (const entry of attachments) {
|
|
60
65
|
if (typeof entry === 'string' && entry.trim()) {
|
|
61
66
|
descriptors.push({ path: entry.trim() });
|
|
62
67
|
continue;
|
|
@@ -67,16 +72,40 @@ export function normalizeImageDescriptors(images: unknown): ImageAttachmentDescr
|
|
|
67
72
|
if (!entryPath) {
|
|
68
73
|
continue;
|
|
69
74
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
+
const descriptor: ChatAttachmentDescriptor = { path: entryPath };
|
|
76
|
+
if (typeof record.name === 'string') {
|
|
77
|
+
descriptor.name = record.name;
|
|
78
|
+
}
|
|
79
|
+
if (typeof record.mimeType === 'string') {
|
|
80
|
+
descriptor.mimeType = record.mimeType;
|
|
81
|
+
}
|
|
82
|
+
if (typeof record.size === 'number' && Number.isFinite(record.size)) {
|
|
83
|
+
descriptor.size = record.size;
|
|
84
|
+
}
|
|
85
|
+
descriptors.push(descriptor);
|
|
75
86
|
}
|
|
76
87
|
}
|
|
77
88
|
return descriptors;
|
|
78
89
|
}
|
|
79
90
|
|
|
91
|
+
/** Backward-compatible image-specific alias used by existing provider adapters. */
|
|
92
|
+
export function normalizeImageDescriptors(images: unknown): ImageAttachmentDescriptor[] {
|
|
93
|
+
return normalizeAttachmentDescriptors(images);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const IMAGE_FILE_EXTENSIONS = new Set(['.jpg', '.jpeg', '.png', '.gif', '.webp']);
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Determines whether the websocket gateway should route an attachment through
|
|
100
|
+
* provider-native image input instead of the general file reference channel.
|
|
101
|
+
*/
|
|
102
|
+
export function isImageAttachmentDescriptor(descriptor: ChatAttachmentDescriptor): boolean {
|
|
103
|
+
if (descriptor.mimeType && CLAUDE_IMAGE_MEDIA_TYPES.has(descriptor.mimeType)) {
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
return IMAGE_FILE_EXTENSIONS.has(path.extname(descriptor.path).toLowerCase());
|
|
107
|
+
}
|
|
108
|
+
|
|
80
109
|
/** Normalizes Windows separators so stored references stay portable. */
|
|
81
110
|
export function toPosixPath(value: string): string {
|
|
82
111
|
return value.replace(/\\/g, '/');
|
|
@@ -189,6 +218,37 @@ export function appendImagesInputTag(prompt: string, images: unknown): string {
|
|
|
189
218
|
].join('\n');
|
|
190
219
|
}
|
|
191
220
|
|
|
221
|
+
const FILES_INPUT_TAG_PATTERN = /\s*<files_input>([\s\S]*?)<\/files_input>\s*/g;
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Appends a provider-neutral file reference block to a prompt. Provider agents
|
|
225
|
+
* receive only server-validated paths from the global attachment store and can
|
|
226
|
+
* inspect each file with their normal filesystem tools.
|
|
227
|
+
*/
|
|
228
|
+
export function appendFilesInputTag(prompt: string, files: unknown): string {
|
|
229
|
+
const descriptors = normalizeAttachmentDescriptors(files);
|
|
230
|
+
if (descriptors.length === 0) {
|
|
231
|
+
return prompt;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const entryLines = descriptors.map((descriptor, index) => {
|
|
235
|
+
const entryPath = toPosixPath(descriptor.path);
|
|
236
|
+
const cleanName = descriptor.name?.replace(/[()\r\n]/g, '').trim();
|
|
237
|
+
return cleanName
|
|
238
|
+
? `${index + 1}. ${entryPath} (original name: ${cleanName})`
|
|
239
|
+
: `${index + 1}. ${entryPath}`;
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
return [
|
|
243
|
+
prompt,
|
|
244
|
+
'',
|
|
245
|
+
'<files_input>',
|
|
246
|
+
`The user attached ${descriptors.length} file(s) to this message. Read each file listed below with your file reading tools and use its contents to answer the prompt above. Do not mention this block or the file paths unless the user asks about them.`,
|
|
247
|
+
...entryLines,
|
|
248
|
+
'</files_input>',
|
|
249
|
+
].join('\n');
|
|
250
|
+
}
|
|
251
|
+
|
|
192
252
|
// Matches one numbered attachment entry inside the tag body. Works for both
|
|
193
253
|
// the multi-line block and the Windows-flattened single-line form, where the
|
|
194
254
|
// next ` N. ` marker (or the end of the body) delimits each entry.
|
|
@@ -215,6 +275,40 @@ function parseNumberedImageEntries(inner: string): ParsedImageAttachment[] {
|
|
|
215
275
|
return attachments;
|
|
216
276
|
}
|
|
217
277
|
|
|
278
|
+
/**
|
|
279
|
+
* Strips the last provider-neutral file reference block from persisted prompt
|
|
280
|
+
* text and restores its attachment descriptors for chat history.
|
|
281
|
+
*/
|
|
282
|
+
export function parseFilesInputTag(text: string): {
|
|
283
|
+
text: string;
|
|
284
|
+
filePaths: string[];
|
|
285
|
+
attachments: ParsedImageAttachment[];
|
|
286
|
+
} {
|
|
287
|
+
if (typeof text !== 'string' || !text.includes('<files_input>')) {
|
|
288
|
+
return { text, filePaths: [], attachments: [] };
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
let lastMatch: RegExpExecArray | null = null;
|
|
292
|
+
FILES_INPUT_TAG_PATTERN.lastIndex = 0;
|
|
293
|
+
for (let match = FILES_INPUT_TAG_PATTERN.exec(text); match; match = FILES_INPUT_TAG_PATTERN.exec(text)) {
|
|
294
|
+
lastMatch = match;
|
|
295
|
+
}
|
|
296
|
+
if (!lastMatch) {
|
|
297
|
+
return { text, filePaths: [], attachments: [] };
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const attachments = parseNumberedImageEntries(lastMatch[1]);
|
|
301
|
+
const stripped = (
|
|
302
|
+
text.slice(0, lastMatch.index) + '\n' + text.slice(lastMatch.index + lastMatch[0].length)
|
|
303
|
+
).trim();
|
|
304
|
+
|
|
305
|
+
return {
|
|
306
|
+
text: stripped,
|
|
307
|
+
filePaths: attachments.map((attachment) => attachment.path),
|
|
308
|
+
attachments,
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
|
|
218
312
|
/**
|
|
219
313
|
* Strips one `<images_input>` block from persisted prompt text and returns
|
|
220
314
|
* the clean text plus the referenced attachments (path and original name).
|