@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
|
@@ -1,12 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
// cross-spawn: drop-in spawn with Windows .cmd/PATHEXT resolution.
|
|
3
|
-
import spawn from 'cross-spawn';
|
|
1
|
+
// @ts-nocheck -- temporary while Git workflows are extracted into the injected service.
|
|
4
2
|
import path from 'path';
|
|
5
|
-
import { promises as fs } from 'fs';
|
|
6
|
-
import { projectsDb } from '../modules/database/index.js';
|
|
7
|
-
import { queryClaudeSDK } from '../claude-sdk.js';
|
|
8
|
-
import { spawnCursor } from '../cursor-cli.js';
|
|
9
3
|
|
|
4
|
+
import express from 'express';
|
|
5
|
+
|
|
6
|
+
import type { ProviderRunFunction } from '@/shared/types.js';
|
|
7
|
+
import { AppError } from '@/shared/utils.js';
|
|
8
|
+
|
|
9
|
+
// cross-spawn: drop-in spawn with Windows .cmd/PATHEXT resolution.
|
|
10
|
+
import { parseGitLogWithStats, parseGitStatusOutput } from './git-parsing.service.js';
|
|
11
|
+
|
|
12
|
+
type GitRouterDependencies = {
|
|
13
|
+
fileSystem: typeof import('node:fs/promises');
|
|
14
|
+
spawnProcess: typeof import('cross-spawn').default;
|
|
15
|
+
resolveProjectPathById(projectId: string): string | null;
|
|
16
|
+
queryClaude: ProviderRunFunction;
|
|
17
|
+
queryCursor: ProviderRunFunction;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/** Creates Git routes around explicit repository, filesystem, subprocess, and AI adapters. */
|
|
21
|
+
export function createGitRouter(dependencies: GitRouterDependencies): express.Router {
|
|
22
|
+
const fs = dependencies.fileSystem;
|
|
23
|
+
const spawn = dependencies.spawnProcess;
|
|
24
|
+
const projectsDb = { getProjectPathById: dependencies.resolveProjectPathById };
|
|
25
|
+
const queryClaudeSDK = dependencies.queryClaude;
|
|
26
|
+
const spawnCursor = dependencies.queryCursor;
|
|
10
27
|
const router = express.Router();
|
|
11
28
|
const COMMIT_DIFF_CHARACTER_LIMIT = 500_000;
|
|
12
29
|
|
|
@@ -162,13 +179,30 @@ async function validateGitRepository(projectPath) {
|
|
|
162
179
|
const { stdout: insideWorkTreeOutput } = await spawnAsync('git', ['rev-parse', '--is-inside-work-tree'], { cwd: projectPath });
|
|
163
180
|
const isInsideWorkTree = insideWorkTreeOutput.trim() === 'true';
|
|
164
181
|
if (!isInsideWorkTree) {
|
|
165
|
-
throw new
|
|
182
|
+
throw new AppError('Not a git repository', {
|
|
183
|
+
code: 'NOT_A_GIT_REPOSITORY',
|
|
184
|
+
statusCode: 400,
|
|
185
|
+
});
|
|
166
186
|
}
|
|
167
187
|
|
|
168
188
|
// Ensure git can resolve the repository root for this directory.
|
|
169
189
|
await spawnAsync('git', ['rev-parse', '--show-toplevel'], { cwd: projectPath });
|
|
170
|
-
} catch {
|
|
171
|
-
|
|
190
|
+
} catch (error) {
|
|
191
|
+
if (
|
|
192
|
+
error instanceof AppError
|
|
193
|
+
&& error.code === 'NOT_A_GIT_REPOSITORY'
|
|
194
|
+
) {
|
|
195
|
+
throw error;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (/not a git repository/i.test(getGitErrorDetails(error))) {
|
|
199
|
+
throw new AppError('Not a git repository. Initialize a git repository with "git init" to use source control features.', {
|
|
200
|
+
code: 'NOT_A_GIT_REPOSITORY',
|
|
201
|
+
statusCode: 400,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
throw error;
|
|
172
206
|
}
|
|
173
207
|
}
|
|
174
208
|
|
|
@@ -293,77 +327,7 @@ async function resolveRepositoryFilePath(projectPath, filePath) {
|
|
|
293
327
|
};
|
|
294
328
|
}
|
|
295
329
|
|
|
296
|
-
// Get
|
|
297
|
-
/**
|
|
298
|
-
* Parses `git status --porcelain=v1 -z` output into the response shape the
|
|
299
|
-
* git panel consumes. NUL-separated entries carry no path quoting, so names
|
|
300
|
-
* with spaces/unicode survive intact (the plain porcelain output quotes and
|
|
301
|
-
* escapes them, which broke the old line-based parser).
|
|
302
|
-
*
|
|
303
|
-
* `staged` lists paths with index-side changes. The UI renders its "Staged"
|
|
304
|
-
* section from this list so it always mirrors the real git index (including
|
|
305
|
-
* files staged outside the app, e.g. via VSCode or the terminal).
|
|
306
|
-
*
|
|
307
|
-
* Exported for tests.
|
|
308
|
-
*/
|
|
309
|
-
export function parseGitStatusOutput(statusOutput) {
|
|
310
|
-
const modified = [];
|
|
311
|
-
const added = [];
|
|
312
|
-
const deleted = [];
|
|
313
|
-
const untracked = [];
|
|
314
|
-
const staged = [];
|
|
315
|
-
|
|
316
|
-
const statusEntries = statusOutput.split('\0');
|
|
317
|
-
for (let entryIndex = 0; entryIndex < statusEntries.length; entryIndex++) {
|
|
318
|
-
const entry = statusEntries[entryIndex];
|
|
319
|
-
if (!entry || entry.length < 4) continue;
|
|
320
|
-
|
|
321
|
-
// Porcelain v1: X = index (staged) status, Y = worktree (unstaged) status.
|
|
322
|
-
const indexStatus = entry[0];
|
|
323
|
-
const worktreeStatus = entry[1];
|
|
324
|
-
const file = entry.slice(3);
|
|
325
|
-
|
|
326
|
-
// Renames/copies carry the original path as the following NUL entry;
|
|
327
|
-
// the UI tracks the post-rename path only.
|
|
328
|
-
if (indexStatus === 'R' || indexStatus === 'C') {
|
|
329
|
-
entryIndex += 1;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
if (indexStatus === '?') {
|
|
333
|
-
untracked.push(file);
|
|
334
|
-
continue;
|
|
335
|
-
}
|
|
336
|
-
if (indexStatus === '!') {
|
|
337
|
-
continue; // ignored files are never reported
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
const isConflict =
|
|
341
|
-
indexStatus === 'U' || worktreeStatus === 'U' ||
|
|
342
|
-
(indexStatus === 'A' && worktreeStatus === 'A') ||
|
|
343
|
-
(indexStatus === 'D' && worktreeStatus === 'D');
|
|
344
|
-
if (isConflict) {
|
|
345
|
-
// Merge conflicts must be resolved in the worktree first; surface them
|
|
346
|
-
// as modified and never as staged.
|
|
347
|
-
modified.push(file);
|
|
348
|
-
continue;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
if (indexStatus !== ' ') {
|
|
352
|
-
staged.push(file);
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
if (indexStatus === 'D' || worktreeStatus === 'D') {
|
|
356
|
-
deleted.push(file);
|
|
357
|
-
} else if (indexStatus === 'A' || worktreeStatus === 'A') {
|
|
358
|
-
added.push(file);
|
|
359
|
-
} else {
|
|
360
|
-
modified.push(file);
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
return { modified, added, deleted, untracked, staged };
|
|
365
|
-
}
|
|
366
|
-
|
|
330
|
+
// Get Git status for a project; parsing is isolated in git-parsing.service.ts.
|
|
367
331
|
router.get('/status', async (req, res) => {
|
|
368
332
|
const { project } = req.query;
|
|
369
333
|
|
|
@@ -393,18 +357,55 @@ router.get('/status', async (req, res) => {
|
|
|
393
357
|
staged
|
|
394
358
|
});
|
|
395
359
|
} catch (error) {
|
|
396
|
-
|
|
360
|
+
// Case-insensitive so "Not a git repository..." from validateGitRepository
|
|
361
|
+
// matches; `notGitRepository` lets the UI offer a one-click `git init`.
|
|
362
|
+
const isNotGitRepository = error instanceof AppError && error.code === 'NOT_A_GIT_REPOSITORY';
|
|
363
|
+
// A project without a repository is an expected state, not a failure.
|
|
364
|
+
if (!isNotGitRepository) {
|
|
365
|
+
console.error('Git status error:', error);
|
|
366
|
+
}
|
|
397
367
|
res.json({
|
|
398
|
-
error:
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
details: error.message.includes('not a git repository') || error.message.includes('Project directory is not a git repository')
|
|
402
|
-
? error.message
|
|
403
|
-
: `Failed to get git status: ${error.message}`
|
|
368
|
+
error: isNotGitRepository ? 'Not a git repository' : 'Git operation failed',
|
|
369
|
+
details: isNotGitRepository ? error.message : `Failed to get git status: ${error.message}`,
|
|
370
|
+
notGitRepository: isNotGitRepository
|
|
404
371
|
});
|
|
405
372
|
}
|
|
406
373
|
});
|
|
407
374
|
|
|
375
|
+
// Initialize a new git repository in the project directory
|
|
376
|
+
router.post('/init', async (req, res) => {
|
|
377
|
+
const { project } = req.body;
|
|
378
|
+
|
|
379
|
+
if (!project) {
|
|
380
|
+
return res.status(400).json({ error: 'Project id is required' });
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
try {
|
|
384
|
+
const projectPath = await getActualProjectPath(project);
|
|
385
|
+
|
|
386
|
+
let isAlreadyRepository = false;
|
|
387
|
+
try {
|
|
388
|
+
await validateGitRepository(projectPath);
|
|
389
|
+
isAlreadyRepository = true;
|
|
390
|
+
} catch (error) {
|
|
391
|
+
if (!(error instanceof AppError) || error.code !== 'NOT_A_GIT_REPOSITORY') {
|
|
392
|
+
throw error;
|
|
393
|
+
}
|
|
394
|
+
// Not a repository yet — proceed with git init.
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
if (isAlreadyRepository) {
|
|
398
|
+
return res.json({ success: true, output: 'Repository already initialized' });
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
const { stdout, stderr } = await spawnAsync('git', ['init'], { cwd: projectPath });
|
|
402
|
+
res.json({ success: true, output: stdout.trim() || stderr.trim() });
|
|
403
|
+
} catch (error) {
|
|
404
|
+
console.error('Git init error:', error);
|
|
405
|
+
res.json({ success: false, error: error.stderr?.trim() || error.message });
|
|
406
|
+
}
|
|
407
|
+
});
|
|
408
|
+
|
|
408
409
|
// Get diff for a specific file
|
|
409
410
|
router.get('/diff', async (req, res) => {
|
|
410
411
|
const { project, file } = req.query;
|
|
@@ -864,51 +865,8 @@ router.post('/delete-branch', async (req, res) => {
|
|
|
864
865
|
|
|
865
866
|
// Fields are joined with the ASCII unit separator so pipes (or anything else
|
|
866
867
|
// typed into a commit subject) cannot break parsing.
|
|
867
|
-
const GIT_LOG_FIELD_SEPARATOR = '\u001f';
|
|
868
868
|
const GIT_LOG_PRETTY_FORMAT = '%H%x1f%P%x1f%D%x1f%an%x1f%ae%x1f%ad%x1f%s';
|
|
869
869
|
|
|
870
|
-
/**
|
|
871
|
-
* Parses `git log --shortstat` output produced with GIT_LOG_PRETTY_FORMAT.
|
|
872
|
-
*
|
|
873
|
-
* Each commit is one format line (hash, parent hashes, ref decorations,
|
|
874
|
-
* author, email, date, subject) optionally followed by its `--shortstat`
|
|
875
|
-
* summary line ("N files changed, ..."). Parents and refs feed the commit
|
|
876
|
-
* graph rendered by the History view; merge commits carry no shortstat line,
|
|
877
|
-
* so their `stats` stays empty.
|
|
878
|
-
*
|
|
879
|
-
* Exported for tests.
|
|
880
|
-
*/
|
|
881
|
-
export function parseGitLogWithStats(stdout) {
|
|
882
|
-
const commits = [];
|
|
883
|
-
|
|
884
|
-
for (const rawLine of stdout.split('\n')) {
|
|
885
|
-
const line = rawLine.trimEnd();
|
|
886
|
-
if (!line.trim()) continue;
|
|
887
|
-
|
|
888
|
-
if (line.includes(GIT_LOG_FIELD_SEPARATOR)) {
|
|
889
|
-
const [hash, parents, refs, author, email, date, ...messageParts] = line.split(GIT_LOG_FIELD_SEPARATOR);
|
|
890
|
-
commits.push({
|
|
891
|
-
hash,
|
|
892
|
-
parents: parents ? parents.split(' ').filter(Boolean) : [],
|
|
893
|
-
// `%D` decorations, e.g. "HEAD -> main", "origin/main", "tag: v1.0".
|
|
894
|
-
refs: refs ? refs.split(', ').filter(Boolean) : [],
|
|
895
|
-
author,
|
|
896
|
-
email,
|
|
897
|
-
date,
|
|
898
|
-
message: messageParts.join(GIT_LOG_FIELD_SEPARATOR),
|
|
899
|
-
stats: ''
|
|
900
|
-
});
|
|
901
|
-
continue;
|
|
902
|
-
}
|
|
903
|
-
|
|
904
|
-
if (commits.length > 0 && /files? changed/.test(line)) {
|
|
905
|
-
commits[commits.length - 1].stats = line.trim();
|
|
906
|
-
}
|
|
907
|
-
}
|
|
908
|
-
|
|
909
|
-
return commits;
|
|
910
|
-
}
|
|
911
|
-
|
|
912
870
|
// Get recent commits (across all branches, in graph order)
|
|
913
871
|
router.get('/commits', async (req, res) => {
|
|
914
872
|
const { project, limit = 10 } = req.query;
|
|
@@ -1631,4 +1589,5 @@ router.post('/delete-untracked', async (req, res) => {
|
|
|
1631
1589
|
}
|
|
1632
1590
|
});
|
|
1633
1591
|
|
|
1634
|
-
|
|
1592
|
+
return router;
|
|
1593
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { EventEmitter, once } from 'node:events';
|
|
3
|
+
import type { AddressInfo } from 'node:net';
|
|
4
|
+
import { PassThrough } from 'node:stream';
|
|
5
|
+
import test from 'node:test';
|
|
6
|
+
|
|
7
|
+
import express from 'express';
|
|
8
|
+
|
|
9
|
+
import { createGitRouter } from '@/modules/git/git.routes.js';
|
|
10
|
+
|
|
11
|
+
test('git init does not run when repository validation fails for an execution error', async () => {
|
|
12
|
+
const commands: string[][] = [];
|
|
13
|
+
const spawnProcess = ((_command: string, args: string[]) => {
|
|
14
|
+
commands.push(args);
|
|
15
|
+
const child = new EventEmitter() as EventEmitter & { stdout: PassThrough; stderr: PassThrough };
|
|
16
|
+
child.stdout = new PassThrough();
|
|
17
|
+
child.stderr = new PassThrough();
|
|
18
|
+
process.nextTick(() => child.emit('error', Object.assign(new Error('permission denied'), {
|
|
19
|
+
code: 'EACCES',
|
|
20
|
+
})));
|
|
21
|
+
return child;
|
|
22
|
+
}) as Parameters<typeof createGitRouter>[0]['spawnProcess'];
|
|
23
|
+
const unexpectedProvider = async (): Promise<never> => { throw new Error('unexpected provider call'); };
|
|
24
|
+
const router = createGitRouter({
|
|
25
|
+
fileSystem: { access: async () => undefined } as unknown as Parameters<typeof createGitRouter>[0]['fileSystem'],
|
|
26
|
+
spawnProcess,
|
|
27
|
+
resolveProjectPathById: () => '/workspace/repo',
|
|
28
|
+
queryClaude: unexpectedProvider,
|
|
29
|
+
queryCursor: unexpectedProvider,
|
|
30
|
+
});
|
|
31
|
+
const app = express();
|
|
32
|
+
app.use(express.json());
|
|
33
|
+
app.use('/api/git', router);
|
|
34
|
+
const server = app.listen(0, '127.0.0.1');
|
|
35
|
+
await once(server, 'listening');
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
const address = server.address() as AddressInfo;
|
|
39
|
+
const response = await fetch(`http://127.0.0.1:${address.port}/api/git/init`, {
|
|
40
|
+
method: 'POST',
|
|
41
|
+
headers: { 'content-type': 'application/json' },
|
|
42
|
+
body: JSON.stringify({ project: 'project-1' }),
|
|
43
|
+
});
|
|
44
|
+
const body = await response.json() as { success: boolean; error: string };
|
|
45
|
+
assert.equal(body.success, false);
|
|
46
|
+
assert.match(body.error, /permission denied/);
|
|
47
|
+
} finally {
|
|
48
|
+
await new Promise<void>((resolve) => server.close(() => resolve()));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
assert.deepEqual(commands, [['rev-parse', '--is-inside-work-tree']]);
|
|
52
|
+
});
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import assert from 'node:assert/strict';
|
|
2
2
|
import test from 'node:test';
|
|
3
3
|
|
|
4
|
-
import { parseGitLogWithStats, parseGitStatusOutput } from '
|
|
4
|
+
import { parseGitLogWithStats, parseGitStatusOutput } from '../git-parsing.service.js';
|
|
5
5
|
|
|
6
6
|
// Builds `git status --porcelain=v1 -z` output: NUL-separated entries with a
|
|
7
7
|
// trailing NUL, exactly as git emits it.
|
|
8
|
-
const porcelain = (...entries) => entries.join('\0') + '\0';
|
|
8
|
+
const porcelain = (...entries: string[]) => entries.join('\0') + '\0';
|
|
9
9
|
|
|
10
10
|
test('parseGitStatusOutput buckets files and reports index-side staging', () => {
|
|
11
11
|
const output = porcelain(
|
|
@@ -69,7 +69,7 @@ test('parseGitStatusOutput handles empty output', () => {
|
|
|
69
69
|
|
|
70
70
|
// Builds one `git log --pretty=format:%H%x1f%P%x1f%D%x1f%an%x1f%ae%x1f%ad%x1f%s` line.
|
|
71
71
|
const US = '';
|
|
72
|
-
const logLine = (hash, parents, refs, subject) =>
|
|
72
|
+
const logLine = (hash: string, parents: string, refs: string, subject: string) =>
|
|
73
73
|
[hash, parents, refs, 'Alice', 'a@x.com', '2026-07-06T10:00:00+03:00', subject].join(US);
|
|
74
74
|
|
|
75
75
|
test('parseGitLogWithStats parses commits with parents, refs, and shortstat lines', () => {
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
export {
|
|
2
|
+
// Used by notification tests and delivery workflows to create channel payloads.
|
|
2
3
|
buildNotificationPayload,
|
|
4
|
+
// Used by provider runtimes and Settings to create normalized notification events.
|
|
3
5
|
createNotificationEvent,
|
|
6
|
+
// Used by provider runtimes and Settings to deliver events through enabled channels.
|
|
4
7
|
notifyUserIfEnabled,
|
|
8
|
+
// Used by provider runtimes to report failed agent runs.
|
|
5
9
|
notifyRunFailed,
|
|
10
|
+
// Used by provider runtimes to report stopped or completed agent runs.
|
|
6
11
|
notifyRunStopped,
|
|
7
12
|
} from '@/modules/notifications/services/notification-orchestrator.service.js';
|
|
8
13
|
export {
|
|
@@ -11,3 +16,7 @@ export {
|
|
|
11
16
|
unregisterDesktopNotificationClient,
|
|
12
17
|
} from '@/modules/notifications/services/desktop-notification-clients.service.js';
|
|
13
18
|
export { handleDesktopNotificationsConnection } from '@/modules/notifications/websocket/desktop-notifications-websocket.service.js';
|
|
19
|
+
// getPublicKey: used by Settings to expose the Web Push subscription key.
|
|
20
|
+
export { getPublicKey } from './vapid-keys.service.js';
|
|
21
|
+
// configureWebPush: used by the server entrypoint during notification startup.
|
|
22
|
+
export { configureWebPush } from './vapid-keys.service.js';
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { mkdtemp, rm } from 'node:fs/promises';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import test from 'node:test';
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
closeConnection,
|
|
9
|
+
initializeDatabase,
|
|
10
|
+
sessionsDb,
|
|
11
|
+
} from '@/modules/database/index.js';
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
buildNotificationPayload,
|
|
15
|
+
} from '../services/notification-orchestrator.service.js';
|
|
16
|
+
|
|
17
|
+
async function withIsolatedDatabase(runTest: () => void | Promise<void>): Promise<void> {
|
|
18
|
+
const previousDatabasePath = process.env.DATABASE_PATH;
|
|
19
|
+
const temporaryDirectory = await mkdtemp(path.join(tmpdir(), 'notification-orchestrator-'));
|
|
20
|
+
const databasePath = path.join(temporaryDirectory, 'auth.db');
|
|
21
|
+
|
|
22
|
+
closeConnection();
|
|
23
|
+
process.env.DATABASE_PATH = databasePath;
|
|
24
|
+
await initializeDatabase();
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
await runTest();
|
|
28
|
+
} finally {
|
|
29
|
+
closeConnection();
|
|
30
|
+
if (previousDatabasePath === undefined) {
|
|
31
|
+
delete process.env.DATABASE_PATH;
|
|
32
|
+
} else {
|
|
33
|
+
process.env.DATABASE_PATH = previousDatabasePath;
|
|
34
|
+
}
|
|
35
|
+
await rm(temporaryDirectory, { recursive: true, force: true });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
test('notification payload uses the app session id for a provider session id', async () => {
|
|
40
|
+
await withIsolatedDatabase(() => {
|
|
41
|
+
sessionsDb.createAppSession('app-session-1', 'claude', '/workspace/demo');
|
|
42
|
+
sessionsDb.assignProviderSessionId('app-session-1', 'claude-native-1');
|
|
43
|
+
|
|
44
|
+
const payload = buildNotificationPayload({
|
|
45
|
+
provider: 'claude',
|
|
46
|
+
sessionId: 'claude-native-1',
|
|
47
|
+
kind: 'stop',
|
|
48
|
+
code: 'run.stopped',
|
|
49
|
+
meta: { stopReason: 'completed' },
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
assert.equal(payload.data.sessionId, 'app-session-1');
|
|
53
|
+
assert.match(payload.data.tag, /app-session-1/);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
// @ts-nocheck -- web-push does not provide declarations in this project.
|
|
1
2
|
import webPush from 'web-push';
|
|
2
|
-
|
|
3
|
+
|
|
4
|
+
import { getConnection } from '../database/index.js';
|
|
3
5
|
|
|
4
6
|
let cachedKeys = null;
|
|
5
7
|
const db = getConnection();
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// pluginsRoutes: used by the server entrypoint to mount protected plugin-management endpoints.
|
|
2
|
+
export { pluginsRoutes } from './plugins.module.js';
|
|
3
|
+
|
|
4
|
+
// startEnabledPluginServers: used by the server entrypoint to start enabled plugin subprocesses.
|
|
5
|
+
export { startEnabledPluginServers } from './plugin-process.service.js';
|
|
6
|
+
// stopAllPlugins: used by the server entrypoint to stop plugin subprocesses during shutdown.
|
|
7
|
+
export { stopAllPlugins } from './plugin-process.service.js';
|
|
8
|
+
// getPluginPort: used by WebSocket setup in the server entrypoint to proxy plugin connections.
|
|
9
|
+
export { getPluginPort } from './plugin-process.service.js';
|
package/server/{utils/plugin-process-manager.js → modules/plugins/plugin-process.service.ts}
RENAMED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
// @ts-nocheck -- subprocess records are narrowed at the Plugins composition boundary.
|
|
1
2
|
import path from 'path';
|
|
2
3
|
|
|
3
4
|
// cross-spawn: drop-in spawn with Windows .cmd/PATHEXT resolution.
|
|
4
5
|
import spawn from 'cross-spawn';
|
|
5
|
-
|
|
6
|
+
|
|
7
|
+
import { scanPlugins, getPluginsConfig, getPluginDir } from './plugin-registry.service.js';
|
|
6
8
|
|
|
7
9
|
// Map<pluginName, { process, port }>
|
|
8
10
|
const runningPlugins = new Map();
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
|
|
4
|
+
import mime from 'mime-types';
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
getPluginDir, getPluginsConfig, getPluginsDir, installPluginFromGit,
|
|
8
|
+
resolvePluginAssetPath, savePluginsConfig, scanPlugins, uninstallPlugin, updatePluginFromGit,
|
|
9
|
+
} from './plugin-registry.service.js';
|
|
10
|
+
import {
|
|
11
|
+
getPluginPort, isPluginRunning, startPluginServer, stopPluginServer,
|
|
12
|
+
} from './plugin-process.service.js';
|
|
13
|
+
import { createPluginsRouter } from './plugins.routes.js';
|
|
14
|
+
import { createPluginsService } from './plugins.service.js';
|
|
15
|
+
|
|
16
|
+
const pluginsService = createPluginsService({
|
|
17
|
+
scanPlugins, readConfig: getPluginsConfig, saveConfig: savePluginsConfig,
|
|
18
|
+
getPluginDirectory: getPluginDir, getPluginsDirectory: getPluginsDir,
|
|
19
|
+
resolveAsset: resolvePluginAssetPath,
|
|
20
|
+
assetIsFile: (assetPath) => { try { return fs.statSync(assetPath).isFile(); } catch { return false; } },
|
|
21
|
+
contentType: (assetPath) => mime.lookup(assetPath) || 'application/octet-stream',
|
|
22
|
+
install: installPluginFromGit,
|
|
23
|
+
update: updatePluginFromGit,
|
|
24
|
+
uninstall: async (pluginName) => { await uninstallPlugin(pluginName); },
|
|
25
|
+
startServer: startPluginServer,
|
|
26
|
+
stopServer: async (pluginName) => { await stopPluginServer(pluginName); },
|
|
27
|
+
getServerPort: getPluginPort, isServerRunning: isPluginRunning,
|
|
28
|
+
joinPath: path.join,
|
|
29
|
+
logError: (message, error) => console.error(message, error),
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
/** Plugin router assembled with filesystem, loader, and process adapters. */
|
|
33
|
+
export const pluginsRoutes = createPluginsRouter(pluginsService);
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import http from 'node:http';
|
|
3
|
+
|
|
4
|
+
import express from 'express';
|
|
5
|
+
|
|
6
|
+
import type { createPluginsService } from './plugins.service.js';
|
|
7
|
+
|
|
8
|
+
function wildcardPath(req: express.Request): string {
|
|
9
|
+
return ((req.params as Record<string, string>)['0'] ?? '').trim();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function routeParameter(value: string | string[]): string {
|
|
13
|
+
return Array.isArray(value) ? value[0] ?? '' : value;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** Creates plugin routes; transport streaming remains here while decisions live in the service. */
|
|
17
|
+
export function createPluginsRouter(service: ReturnType<typeof createPluginsService>): express.Router {
|
|
18
|
+
const router = express.Router();
|
|
19
|
+
const respond = (operation: (req: express.Request) => unknown | Promise<unknown>) =>
|
|
20
|
+
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
|
21
|
+
try { res.json(await operation(req)); } catch (error) { next(error); }
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
router.get('/', respond(() => service.list()));
|
|
25
|
+
router.get('/:name/manifest', respond((req) => service.getManifest(routeParameter(req.params.name))));
|
|
26
|
+
router.get('/:name/assets/*', async (req, res, next) => {
|
|
27
|
+
try {
|
|
28
|
+
const asset = service.resolveAsset(routeParameter(req.params.name), wildcardPath(req));
|
|
29
|
+
res.setHeader('Content-Type', asset.contentType);
|
|
30
|
+
res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate');
|
|
31
|
+
const stream = fs.createReadStream(asset.path);
|
|
32
|
+
stream.on('error', next);
|
|
33
|
+
stream.pipe(res);
|
|
34
|
+
} catch (error) { next(error); }
|
|
35
|
+
});
|
|
36
|
+
router.put('/:name/enable', respond((req) => service.setEnabled(routeParameter(req.params.name), req.body?.enabled)));
|
|
37
|
+
router.post('/install', respond((req) => service.install(req.body?.url)));
|
|
38
|
+
router.post('/:name/update', respond((req) => service.update(routeParameter(req.params.name))));
|
|
39
|
+
router.all('/:name/rpc/*', async (req, res, next) => {
|
|
40
|
+
try {
|
|
41
|
+
const { port, secrets } = await service.prepareRpc(routeParameter(req.params.name));
|
|
42
|
+
const headers: Record<string, string> = {
|
|
43
|
+
'content-type': String(req.headers['content-type'] ?? 'application/json'),
|
|
44
|
+
};
|
|
45
|
+
for (const [key, value] of Object.entries(secrets)) {
|
|
46
|
+
headers[`x-plugin-secret-${key.toLowerCase()}`] = String(value);
|
|
47
|
+
}
|
|
48
|
+
const query = req.url.includes('?') ? `?${req.url.split('?').slice(1).join('?')}` : '';
|
|
49
|
+
const proxyRequest = http.request({
|
|
50
|
+
hostname: '127.0.0.1', port, path: `/${wildcardPath(req)}${query}`, method: req.method, headers,
|
|
51
|
+
}, (proxyResponse) => {
|
|
52
|
+
res.writeHead(proxyResponse.statusCode ?? 502, proxyResponse.headers);
|
|
53
|
+
proxyResponse.pipe(res);
|
|
54
|
+
});
|
|
55
|
+
proxyRequest.on('error', next);
|
|
56
|
+
if (req.headers['content-length'] && req.body !== undefined) {
|
|
57
|
+
const body = JSON.stringify(req.body);
|
|
58
|
+
proxyRequest.setHeader('content-length', Buffer.byteLength(body));
|
|
59
|
+
proxyRequest.write(body);
|
|
60
|
+
}
|
|
61
|
+
proxyRequest.end();
|
|
62
|
+
} catch (error) { next(error); }
|
|
63
|
+
});
|
|
64
|
+
router.delete('/:name', respond((req) => service.uninstall(routeParameter(req.params.name))));
|
|
65
|
+
return router;
|
|
66
|
+
}
|