@cloudcli-ai/cloudcli 1.36.3 → 1.37.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/index-D3jfzuKN.css +32 -0
- package/dist/assets/index-DTMWjJj8.js +1550 -0
- package/dist/index.html +2 -2
- package/dist-server/server/constants/config.js.map +1 -1
- package/dist-server/server/index.js +73 -1224
- package/dist-server/server/index.js.map +1 -1
- package/dist-server/server/load-env.js +17 -4
- package/dist-server/server/load-env.js.map +1 -1
- package/dist-server/server/modules/agent/agent.module.js +37 -0
- package/dist-server/server/modules/agent/agent.module.js.map +1 -0
- package/dist-server/server/modules/agent/agent.routes.js +1161 -0
- package/dist-server/server/modules/agent/agent.routes.js.map +1 -0
- package/dist-server/server/modules/agent/index.js +3 -0
- package/dist-server/server/modules/agent/index.js.map +1 -0
- package/dist-server/server/modules/agent/tests/agent.routes.test.js +176 -0
- package/dist-server/server/modules/agent/tests/agent.routes.test.js.map +1 -0
- package/dist-server/server/modules/assets/assets.routes.js +56 -15
- package/dist-server/server/modules/assets/assets.routes.js.map +1 -1
- package/dist-server/server/modules/assets/index.js +2 -2
- package/dist-server/server/modules/assets/index.js.map +1 -1
- package/dist-server/server/modules/assets/services/image-assets.service.js +39 -1
- package/dist-server/server/modules/assets/services/image-assets.service.js.map +1 -1
- package/dist-server/server/modules/assets/tests/image-assets.service.test.js +21 -1
- package/dist-server/server/modules/assets/tests/image-assets.service.test.js.map +1 -1
- package/dist-server/server/{middleware/auth.js → modules/auth/auth.middleware.js} +30 -8
- package/dist-server/server/modules/auth/auth.middleware.js.map +1 -0
- package/dist-server/server/modules/auth/auth.module.js +29 -0
- package/dist-server/server/modules/auth/auth.module.js.map +1 -0
- package/dist-server/server/modules/auth/auth.routes.js +45 -0
- package/dist-server/server/modules/auth/auth.routes.js.map +1 -0
- package/dist-server/server/modules/auth/auth.service.js +113 -0
- package/dist-server/server/modules/auth/auth.service.js.map +1 -0
- package/dist-server/server/modules/auth/index.js +9 -0
- package/dist-server/server/modules/auth/index.js.map +1 -0
- package/dist-server/server/modules/auth/tests/auth.service.test.js +80 -0
- package/dist-server/server/modules/auth/tests/auth.service.test.js.map +1 -0
- package/dist-server/server/{browser-use-mcp.js → modules/browser-use/browser-use-mcp.js} +3 -1
- package/dist-server/server/modules/browser-use/browser-use-mcp.js.map +1 -0
- package/dist-server/server/modules/browser-use/browser-use.service.js +3 -4
- package/dist-server/server/modules/browser-use/browser-use.service.js.map +1 -1
- package/dist-server/server/modules/browser-use/index.js +9 -0
- package/dist-server/server/modules/browser-use/index.js.map +1 -0
- package/dist-server/server/modules/cli/cli.js +11 -0
- package/dist-server/server/modules/cli/cli.js.map +1 -0
- package/dist-server/server/modules/cli/cli.module.js +86 -0
- package/dist-server/server/modules/cli/cli.module.js.map +1 -0
- package/dist-server/server/modules/cli/cli.service.js +244 -0
- package/dist-server/server/modules/cli/cli.service.js.map +1 -0
- package/dist-server/server/modules/cli/index.js +3 -0
- package/dist-server/server/modules/cli/index.js.map +1 -0
- package/dist-server/server/modules/cli/sandbox.service.js +332 -0
- package/dist-server/server/modules/cli/sandbox.service.js.map +1 -0
- package/dist-server/server/modules/cli/tests/cli.service.test.js +78 -0
- package/dist-server/server/modules/cli/tests/cli.service.test.js.map +1 -0
- package/dist-server/server/modules/cli/tests/sandbox.service.test.js +55 -0
- package/dist-server/server/modules/cli/tests/sandbox.service.test.js.map +1 -0
- package/dist-server/server/modules/commands/commands.module.js +20 -0
- package/dist-server/server/modules/commands/commands.module.js.map +1 -0
- package/dist-server/server/modules/commands/commands.routes.js +497 -0
- package/dist-server/server/modules/commands/commands.routes.js.map +1 -0
- package/dist-server/server/modules/commands/index.js +3 -0
- package/dist-server/server/modules/commands/index.js.map +1 -0
- package/dist-server/server/modules/commands/tests/commands.test.js +91 -0
- package/dist-server/server/modules/commands/tests/commands.test.js.map +1 -0
- package/dist-server/server/modules/database/index.js +3 -0
- package/dist-server/server/modules/database/index.js.map +1 -1
- package/dist-server/server/modules/database/migrations.js +31 -1
- package/dist-server/server/modules/database/migrations.js.map +1 -1
- package/dist-server/server/modules/database/repositories/provider-models.js +112 -0
- package/dist-server/server/modules/database/repositories/provider-models.js.map +1 -0
- package/dist-server/server/modules/database/repositories/sessions.db.js +76 -7
- package/dist-server/server/modules/database/repositories/sessions.db.js.map +1 -1
- package/dist-server/server/modules/database/schema.js +29 -0
- package/dist-server/server/modules/database/schema.js.map +1 -1
- package/dist-server/server/modules/database/tests/provider-models.db.integration.test.js +102 -0
- package/dist-server/server/modules/database/tests/provider-models.db.integration.test.js.map +1 -0
- package/dist-server/server/modules/database/tests/sessions-provider-mapping.test.js +2 -1
- package/dist-server/server/modules/database/tests/sessions-provider-mapping.test.js.map +1 -1
- package/dist-server/server/modules/database/tests/sessions.db.integration.test.js +22 -0
- package/dist-server/server/modules/database/tests/sessions.db.integration.test.js.map +1 -1
- package/dist-server/server/modules/file-tree/file-tree.module.js +95 -0
- package/dist-server/server/modules/file-tree/file-tree.module.js.map +1 -0
- package/dist-server/server/modules/file-tree/file-tree.routes.js +208 -0
- package/dist-server/server/modules/file-tree/file-tree.routes.js.map +1 -0
- package/dist-server/server/modules/file-tree/file-tree.service.js +576 -0
- package/dist-server/server/modules/file-tree/file-tree.service.js.map +1 -0
- package/dist-server/server/modules/file-tree/index.js +3 -0
- package/dist-server/server/modules/file-tree/index.js.map +1 -0
- package/dist-server/server/modules/file-tree/tests/file-tree.routes.test.js +123 -0
- package/dist-server/server/modules/file-tree/tests/file-tree.routes.test.js.map +1 -0
- package/dist-server/server/modules/file-tree/tests/file-tree.service.test.js +260 -0
- package/dist-server/server/modules/file-tree/tests/file-tree.service.test.js.map +1 -0
- package/dist-server/server/modules/git/git-parsing.service.js +61 -0
- package/dist-server/server/modules/git/git-parsing.service.js.map +1 -0
- package/dist-server/server/modules/git/git.module.js +14 -0
- package/dist-server/server/modules/git/git.module.js.map +1 -0
- package/dist-server/server/modules/git/git.routes.js +1339 -0
- package/dist-server/server/modules/git/git.routes.js.map +1 -0
- package/dist-server/server/modules/git/index.js +3 -0
- package/dist-server/server/modules/git/index.js.map +1 -0
- package/dist-server/server/modules/git/tests/git-init.routes.test.js +48 -0
- package/dist-server/server/modules/git/tests/git-init.routes.test.js.map +1 -0
- package/dist-server/server/{routes → modules/git/tests}/git.test.js +1 -1
- package/dist-server/server/modules/git/tests/git.test.js.map +1 -0
- package/dist-server/server/modules/notifications/index.js +15 -1
- package/dist-server/server/modules/notifications/index.js.map +1 -1
- package/dist-server/server/modules/notifications/tests/notification-orchestrator.integration.test.js +44 -0
- package/dist-server/server/modules/notifications/tests/notification-orchestrator.integration.test.js.map +1 -0
- package/dist-server/server/{services/vapid-keys.js → modules/notifications/vapid-keys.service.js} +3 -2
- package/dist-server/server/modules/notifications/vapid-keys.service.js.map +1 -0
- package/dist-server/server/modules/plugins/index.js +9 -0
- package/dist-server/server/modules/plugins/index.js.map +1 -0
- package/dist-server/server/{utils/plugin-process-manager.js → modules/plugins/plugin-process.service.js} +3 -2
- package/dist-server/server/modules/plugins/plugin-process.service.js.map +1 -0
- package/dist-server/server/{utils/plugin-loader.js → modules/plugins/plugin-registry.service.js} +2 -1
- package/dist-server/server/modules/plugins/plugin-registry.service.js.map +1 -0
- package/dist-server/server/modules/plugins/plugins.module.js +30 -0
- package/dist-server/server/modules/plugins/plugins.module.js.map +1 -0
- package/dist-server/server/modules/plugins/plugins.routes.js +70 -0
- package/dist-server/server/modules/plugins/plugins.routes.js.map +1 -0
- package/dist-server/server/modules/plugins/plugins.service.js +123 -0
- package/dist-server/server/modules/plugins/plugins.service.js.map +1 -0
- package/dist-server/server/modules/plugins/tests/plugins.service.test.js +28 -0
- package/dist-server/server/modules/plugins/tests/plugins.service.test.js.map +1 -0
- package/dist-server/server/modules/projects/index.js +5 -0
- package/dist-server/server/modules/projects/index.js.map +1 -1
- package/dist-server/server/modules/providers/index.js +3 -0
- package/dist-server/server/modules/providers/index.js.map +1 -1
- package/dist-server/server/modules/providers/list/claude/claude-auth.provider.js +6 -0
- package/dist-server/server/modules/providers/list/claude/claude-auth.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/claude/claude-models.provider.js +47 -18
- package/dist-server/server/modules/providers/list/claude/claude-models.provider.js.map +1 -1
- package/dist-server/server/{claude-sdk.js → modules/providers/list/claude/claude-runtime.provider.js} +69 -55
- package/dist-server/server/modules/providers/list/claude/claude-runtime.provider.js.map +1 -0
- package/dist-server/server/modules/providers/list/claude/claude-session-synchronizer.provider.js +6 -4
- package/dist-server/server/modules/providers/list/claude/claude-session-synchronizer.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js +23 -4
- package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/claude/claude.provider.js +2 -0
- package/dist-server/server/modules/providers/list/claude/claude.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-models.provider.js +59 -75
- package/dist-server/server/modules/providers/list/codex/codex-models.provider.js.map +1 -1
- package/dist-server/server/{openai-codex.js → modules/providers/list/codex/codex-runtime.provider.js} +48 -34
- package/dist-server/server/modules/providers/list/codex/codex-runtime.provider.js.map +1 -0
- package/dist-server/server/modules/providers/list/codex/codex-session-synchronizer.provider.js +1 -54
- package/dist-server/server/modules/providers/list/codex/codex-session-synchronizer.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js +290 -6
- package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-skills.provider.js +5 -0
- package/dist-server/server/modules/providers/list/codex/codex-skills.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex.provider.js +2 -0
- package/dist-server/server/modules/providers/list/codex/codex.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js +33 -673
- package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js.map +1 -1
- package/dist-server/server/{cursor-cli.js → modules/providers/list/cursor/cursor-runtime.provider.js} +40 -28
- package/dist-server/server/modules/providers/list/cursor/cursor-runtime.provider.js.map +1 -0
- package/dist-server/server/modules/providers/list/cursor/cursor-sessions.provider.js +21 -14
- package/dist-server/server/modules/providers/list/cursor/cursor-sessions.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/cursor/cursor.provider.js +2 -0
- package/dist-server/server/modules/providers/list/cursor/cursor.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js +112 -333
- package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js.map +1 -1
- package/dist-server/server/{opencode-cli.js → modules/providers/list/opencode/opencode-runtime.provider.js} +38 -25
- package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.js.map +1 -0
- package/dist-server/server/{opencode-cli.test.js → modules/providers/list/opencode/opencode-runtime.provider.test.js} +27 -4
- package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.test.js.map +1 -0
- package/dist-server/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.js +0 -12
- package/dist-server/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/opencode/opencode-sessions.provider.js +11 -5
- package/dist-server/server/modules/providers/list/opencode/opencode-sessions.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/opencode/opencode.provider.js +2 -0
- package/dist-server/server/modules/providers/list/opencode/opencode.provider.js.map +1 -1
- package/dist-server/server/modules/providers/provider.routes.js +169 -37
- package/dist-server/server/modules/providers/provider.routes.js.map +1 -1
- package/dist-server/server/modules/providers/services/provider-capabilities.service.js +5 -1
- package/dist-server/server/modules/providers/services/provider-capabilities.service.js.map +1 -1
- package/dist-server/server/modules/providers/services/provider-models.service.js +247 -184
- package/dist-server/server/modules/providers/services/provider-models.service.js.map +1 -1
- package/dist-server/server/modules/providers/services/provider-runtime.service.js +66 -0
- package/dist-server/server/modules/providers/services/provider-runtime.service.js.map +1 -0
- package/dist-server/server/modules/providers/services/provider-token-usage.service.js +268 -0
- package/dist-server/server/modules/providers/services/provider-token-usage.service.js.map +1 -0
- package/dist-server/server/modules/providers/services/session-conversations-search.service.js +12 -4
- package/dist-server/server/modules/providers/services/session-conversations-search.service.js.map +1 -1
- package/dist-server/server/modules/providers/services/sessions-watcher.service.js +2 -0
- package/dist-server/server/modules/providers/services/sessions-watcher.service.js.map +1 -1
- package/dist-server/server/modules/providers/services/sessions.service.js +116 -3
- package/dist-server/server/modules/providers/services/sessions.service.js.map +1 -1
- package/dist-server/server/modules/providers/shared/base/abstract.provider.js +2 -3
- package/dist-server/server/modules/providers/shared/base/abstract.provider.js.map +1 -1
- package/dist-server/server/modules/providers/tests/claude-auth.test.js +122 -0
- package/dist-server/server/modules/providers/tests/claude-auth.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/claude-sessions.test.js +44 -0
- package/dist-server/server/modules/providers/tests/claude-sessions.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/codex-sessions.test.js +76 -4
- package/dist-server/server/modules/providers/tests/codex-sessions.test.js.map +1 -1
- package/dist-server/server/modules/providers/tests/opencode-models.test.js +15 -126
- package/dist-server/server/modules/providers/tests/opencode-models.test.js.map +1 -1
- package/dist-server/server/modules/providers/tests/opencode-sessions.test.js +5 -5
- package/dist-server/server/modules/providers/tests/opencode-sessions.test.js.map +1 -1
- package/dist-server/server/modules/providers/tests/{provider-image-history.test.js → provider-attachment-history.test.js} +60 -2
- package/dist-server/server/modules/providers/tests/provider-attachment-history.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/provider-models.service.test.js +241 -271
- package/dist-server/server/modules/providers/tests/provider-models.service.test.js.map +1 -1
- package/dist-server/server/modules/providers/tests/provider-runtime.service.test.js +126 -0
- package/dist-server/server/modules/providers/tests/provider-runtime.service.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js +166 -0
- package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/provider.routes.test.js +126 -0
- package/dist-server/server/modules/providers/tests/provider.routes.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/sessions-details.test.js +62 -0
- package/dist-server/server/modules/providers/tests/sessions-details.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/sessions.service.test.js +87 -0
- package/dist-server/server/modules/providers/tests/sessions.service.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/skills.test.js +4 -2
- package/dist-server/server/modules/providers/tests/skills.test.js.map +1 -1
- package/dist-server/server/modules/settings/index.js +3 -0
- package/dist-server/server/modules/settings/index.js.map +1 -0
- package/dist-server/server/modules/settings/settings.module.js +35 -0
- package/dist-server/server/modules/settings/settings.module.js.map +1 -0
- package/dist-server/server/modules/settings/settings.routes.js +34 -0
- package/dist-server/server/modules/settings/settings.routes.js.map +1 -0
- package/dist-server/server/modules/settings/settings.service.js +116 -0
- package/dist-server/server/modules/settings/settings.service.js.map +1 -0
- package/dist-server/server/modules/settings/tests/settings.service.test.js +48 -0
- package/dist-server/server/modules/settings/tests/settings.service.test.js.map +1 -0
- package/dist-server/server/modules/system/index.js +3 -0
- package/dist-server/server/modules/system/index.js.map +1 -0
- package/dist-server/server/modules/system/system.module.js +44 -0
- package/dist-server/server/modules/system/system.module.js.map +1 -0
- package/dist-server/server/modules/system/system.routes.js +16 -0
- package/dist-server/server/modules/system/system.routes.js.map +1 -0
- package/dist-server/server/modules/system/system.service.js +45 -0
- package/dist-server/server/modules/system/system.service.js.map +1 -0
- package/dist-server/server/modules/system/tests/system.service.test.js +100 -0
- package/dist-server/server/modules/system/tests/system.service.test.js.map +1 -0
- package/dist-server/server/modules/taskmaster/index.js +3 -0
- package/dist-server/server/modules/taskmaster/index.js.map +1 -0
- package/dist-server/server/modules/taskmaster/taskmaster.module.js +20 -0
- package/dist-server/server/modules/taskmaster/taskmaster.module.js.map +1 -0
- package/dist-server/server/modules/taskmaster/taskmaster.routes.js +1372 -0
- package/dist-server/server/modules/taskmaster/taskmaster.routes.js.map +1 -0
- package/dist-server/server/modules/taskmaster/taskmaster.service.js +107 -0
- package/dist-server/server/modules/taskmaster/taskmaster.service.js.map +1 -0
- package/dist-server/server/modules/taskmaster/tests/taskmaster.routes.test.js +132 -0
- package/dist-server/server/modules/taskmaster/tests/taskmaster.routes.test.js.map +1 -0
- package/dist-server/server/modules/taskmaster/tests/taskmaster.service.test.js +85 -0
- package/dist-server/server/modules/taskmaster/tests/taskmaster.service.test.js.map +1 -0
- package/dist-server/server/modules/user/index.js +3 -0
- package/dist-server/server/modules/user/index.js.map +1 -0
- package/dist-server/server/modules/user/tests/user.service.test.js +53 -0
- package/dist-server/server/modules/user/tests/user.service.test.js.map +1 -0
- package/dist-server/server/modules/user/user.module.js +47 -0
- package/dist-server/server/modules/user/user.module.js.map +1 -0
- package/dist-server/server/modules/user/user.routes.js +44 -0
- package/dist-server/server/modules/user/user.routes.js.map +1 -0
- package/dist-server/server/modules/user/user.service.js +59 -0
- package/dist-server/server/modules/user/user.service.js.map +1 -0
- package/dist-server/server/modules/voice/index.js +3 -0
- package/dist-server/server/modules/voice/index.js.map +1 -0
- package/dist-server/server/modules/voice/tests/voice.service.test.js +86 -0
- package/dist-server/server/modules/voice/tests/voice.service.test.js.map +1 -0
- package/dist-server/server/modules/voice/voice.module.js +44 -0
- package/dist-server/server/modules/voice/voice.module.js.map +1 -0
- package/dist-server/server/modules/voice/voice.routes.js +87 -0
- package/dist-server/server/modules/voice/voice.routes.js.map +1 -0
- package/dist-server/server/modules/voice/voice.service.js +148 -0
- package/dist-server/server/modules/voice/voice.service.js.map +1 -0
- package/dist-server/server/modules/websocket/services/chat-session-writer.service.js +2 -2
- package/dist-server/server/modules/websocket/services/chat-websocket.service.js +44 -29
- package/dist-server/server/modules/websocket/services/chat-websocket.service.js.map +1 -1
- package/dist-server/server/modules/websocket/services/shell-websocket.service.js +76 -8
- package/dist-server/server/modules/websocket/services/shell-websocket.service.js.map +1 -1
- package/dist-server/server/modules/websocket/services/websocket-server.service.js +51 -20
- package/dist-server/server/modules/websocket/services/websocket-server.service.js.map +1 -1
- package/dist-server/server/modules/websocket/tests/{chat-image-filter.test.js → chat-attachment-filter.test.js} +10 -3
- package/dist-server/server/modules/websocket/tests/chat-attachment-filter.test.js.map +1 -0
- package/dist-server/server/modules/websocket/tests/shell-websocket.service.test.js +97 -0
- package/dist-server/server/modules/websocket/tests/shell-websocket.service.test.js.map +1 -0
- package/dist-server/server/modules/websocket/tests/websocket-heartbeat.service.test.js +61 -0
- package/dist-server/server/modules/websocket/tests/websocket-heartbeat.service.test.js.map +1 -0
- package/dist-server/server/modules/worktrees/index.js +3 -0
- package/dist-server/server/modules/worktrees/index.js.map +1 -0
- package/dist-server/server/modules/worktrees/services/worktree-create-and-open.service.js +37 -0
- package/dist-server/server/modules/worktrees/services/worktree-create-and-open.service.js.map +1 -0
- package/dist-server/server/modules/worktrees/services/worktree-create.service.js +67 -0
- package/dist-server/server/modules/worktrees/services/worktree-create.service.js.map +1 -0
- package/dist-server/server/modules/worktrees/services/worktree-git.service.js +172 -0
- package/dist-server/server/modules/worktrees/services/worktree-git.service.js.map +1 -0
- package/dist-server/server/modules/worktrees/services/worktree-list.service.js +91 -0
- package/dist-server/server/modules/worktrees/services/worktree-list.service.js.map +1 -0
- package/dist-server/server/modules/worktrees/services/worktree-merge.service.js +118 -0
- package/dist-server/server/modules/worktrees/services/worktree-merge.service.js.map +1 -0
- package/dist-server/server/modules/worktrees/services/worktree-open.service.js +58 -0
- package/dist-server/server/modules/worktrees/services/worktree-open.service.js.map +1 -0
- package/dist-server/server/modules/worktrees/services/worktree-remove.service.js +65 -0
- package/dist-server/server/modules/worktrees/services/worktree-remove.service.js.map +1 -0
- package/dist-server/server/modules/worktrees/tests/worktree-create-and-open.service.test.js +58 -0
- package/dist-server/server/modules/worktrees/tests/worktree-create-and-open.service.test.js.map +1 -0
- package/dist-server/server/modules/worktrees/tests/worktree-create.service.test.js +85 -0
- package/dist-server/server/modules/worktrees/tests/worktree-create.service.test.js.map +1 -0
- package/dist-server/server/modules/worktrees/tests/worktree-git.service.test.js +58 -0
- package/dist-server/server/modules/worktrees/tests/worktree-git.service.test.js.map +1 -0
- package/dist-server/server/modules/worktrees/tests/worktree-list.service.test.js +34 -0
- package/dist-server/server/modules/worktrees/tests/worktree-list.service.test.js.map +1 -0
- package/dist-server/server/modules/worktrees/tests/worktree-merge.service.test.js +137 -0
- package/dist-server/server/modules/worktrees/tests/worktree-merge.service.test.js.map +1 -0
- package/dist-server/server/modules/worktrees/tests/worktree-open.service.test.js +99 -0
- package/dist-server/server/modules/worktrees/tests/worktree-open.service.test.js.map +1 -0
- package/dist-server/server/modules/worktrees/tests/worktree-remove.service.test.js +157 -0
- package/dist-server/server/modules/worktrees/tests/worktree-remove.service.test.js.map +1 -0
- package/dist-server/server/modules/worktrees/tests/worktrees.routes.test.js +167 -0
- package/dist-server/server/modules/worktrees/tests/worktrees.routes.test.js.map +1 -0
- package/dist-server/server/modules/worktrees/worktrees.module.js +97 -0
- package/dist-server/server/modules/worktrees/worktrees.module.js.map +1 -0
- package/dist-server/server/modules/worktrees/worktrees.routes.js +84 -0
- package/dist-server/server/modules/worktrees/worktrees.routes.js.map +1 -0
- package/dist-server/server/shared/image-attachments.js +90 -17
- package/dist-server/server/shared/image-attachments.js.map +1 -1
- package/dist-server/server/shared/tests/image-attachments.test.js +43 -1
- package/dist-server/server/shared/tests/image-attachments.test.js.map +1 -1
- package/dist-server/server/shared/utils.js +66 -142
- package/dist-server/server/shared/utils.js.map +1 -1
- package/package.json +9 -5
- package/server/index.ts +401 -0
- package/server/{load-env.js → load-env.ts} +18 -5
- package/server/modules/agent/agent.module.ts +51 -0
- package/server/modules/agent/agent.routes.ts +1287 -0
- package/server/modules/agent/index.ts +2 -0
- package/server/modules/agent/tests/agent.routes.test.ts +205 -0
- package/server/modules/assets/assets.routes.ts +63 -16
- package/server/modules/assets/index.ts +2 -2
- package/server/modules/assets/services/image-assets.service.ts +46 -1
- package/server/modules/assets/tests/image-assets.service.test.ts +28 -0
- package/server/{middleware/auth.js → modules/auth/auth.middleware.ts} +38 -7
- package/server/modules/auth/auth.module.ts +38 -0
- package/server/modules/auth/auth.routes.ts +57 -0
- package/server/modules/auth/auth.service.ts +155 -0
- package/server/modules/auth/index.ts +9 -0
- package/server/modules/auth/tests/auth.service.test.ts +95 -0
- package/server/{browser-use-mcp.ts → modules/browser-use/browser-use-mcp.ts} +3 -1
- package/server/modules/browser-use/browser-use.service.ts +3 -4
- package/server/modules/browser-use/index.ts +8 -0
- package/server/modules/cli/cli.module.ts +96 -0
- package/server/modules/cli/cli.service.ts +281 -0
- package/server/modules/cli/cli.ts +13 -0
- package/server/modules/cli/index.ts +2 -0
- package/server/modules/cli/sandbox.service.ts +413 -0
- package/server/modules/cli/tests/cli.service.test.ts +91 -0
- package/server/modules/cli/tests/sandbox.service.test.ts +61 -0
- package/server/modules/commands/commands.module.ts +22 -0
- package/server/{routes/commands.js → modules/commands/commands.routes.ts} +46 -38
- package/server/modules/commands/index.ts +2 -0
- package/server/modules/commands/tests/commands.test.ts +114 -0
- package/server/modules/database/index.ts +3 -0
- package/server/modules/database/migrations.ts +35 -0
- package/server/modules/database/repositories/provider-models.ts +168 -0
- package/server/modules/database/repositories/sessions.db.ts +103 -8
- package/server/modules/database/schema.ts +30 -0
- package/server/modules/database/tests/provider-models.db.integration.test.ts +125 -0
- package/server/modules/database/tests/sessions-provider-mapping.test.ts +2 -1
- package/server/modules/database/tests/sessions.db.integration.test.ts +32 -0
- package/server/modules/file-tree/file-tree.module.ts +116 -0
- package/server/modules/file-tree/file-tree.routes.ts +258 -0
- package/server/modules/file-tree/file-tree.service.ts +664 -0
- package/server/modules/file-tree/index.ts +2 -0
- package/server/modules/file-tree/tests/file-tree.routes.test.ts +157 -0
- package/server/modules/file-tree/tests/file-tree.service.test.ts +317 -0
- package/server/modules/git/git-parsing.service.ts +66 -0
- package/server/modules/git/git.module.ts +22 -0
- package/server/{routes/git.js → modules/git/git.routes.ts} +91 -132
- package/server/modules/git/index.ts +2 -0
- package/server/modules/git/tests/git-init.routes.test.ts +52 -0
- package/server/{routes/git.test.js → modules/git/tests/git.test.ts} +3 -3
- package/server/modules/notifications/index.ts +9 -0
- package/server/modules/notifications/tests/notification-orchestrator.integration.test.ts +55 -0
- package/server/{services/vapid-keys.js → modules/notifications/vapid-keys.service.ts} +3 -1
- package/server/modules/plugins/index.ts +9 -0
- package/server/{utils/plugin-process-manager.js → modules/plugins/plugin-process.service.ts} +3 -1
- package/server/{utils/plugin-loader.js → modules/plugins/plugin-registry.service.ts} +1 -0
- package/server/modules/plugins/plugins.module.ts +33 -0
- package/server/modules/plugins/plugins.routes.ts +66 -0
- package/server/modules/plugins/plugins.service.ts +147 -0
- package/server/modules/plugins/tests/plugins.service.test.ts +32 -0
- package/server/modules/projects/index.ts +5 -0
- package/server/modules/providers/README.md +41 -9
- package/server/modules/providers/index.ts +4 -0
- package/server/modules/providers/list/claude/claude-auth.provider.ts +8 -0
- package/server/modules/providers/list/claude/claude-models.provider.ts +47 -26
- package/server/{claude-sdk.js → modules/providers/list/claude/claude-runtime.provider.js} +73 -59
- package/server/modules/providers/list/claude/claude-session-synchronizer.provider.ts +6 -4
- package/server/modules/providers/list/claude/claude-sessions.provider.ts +27 -4
- package/server/modules/providers/list/claude/claude.provider.ts +3 -0
- package/server/modules/providers/list/codex/codex-models.provider.ts +58 -108
- package/server/{openai-codex.js → modules/providers/list/codex/codex-runtime.provider.js} +54 -36
- package/server/modules/providers/list/codex/codex-session-synchronizer.provider.ts +1 -60
- package/server/modules/providers/list/codex/codex-sessions.provider.ts +331 -7
- package/server/modules/providers/list/codex/codex-skills.provider.ts +5 -0
- package/server/modules/providers/list/codex/codex.provider.ts +3 -0
- package/server/modules/providers/list/cursor/cursor-models.provider.ts +32 -719
- package/server/{cursor-cli.js → modules/providers/list/cursor/cursor-runtime.provider.js} +58 -27
- package/server/modules/providers/list/cursor/cursor-sessions.provider.ts +26 -15
- package/server/modules/providers/list/cursor/cursor.provider.ts +3 -0
- package/server/modules/providers/list/opencode/opencode-models.provider.ts +112 -423
- package/server/{opencode-cli.js → modules/providers/list/opencode/opencode-runtime.provider.js} +56 -28
- package/server/{opencode-cli.test.js → modules/providers/list/opencode/opencode-runtime.provider.test.js} +41 -3
- package/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.ts +0 -13
- package/server/modules/providers/list/opencode/opencode-sessions.provider.ts +13 -5
- package/server/modules/providers/list/opencode/opencode.provider.ts +3 -0
- package/server/modules/providers/provider.routes.ts +228 -39
- package/server/modules/providers/services/provider-capabilities.service.ts +7 -1
- package/server/modules/providers/services/provider-models.service.ts +312 -269
- package/server/modules/providers/services/provider-runtime.service.ts +108 -0
- package/server/modules/providers/services/provider-token-usage.service.ts +357 -0
- package/server/modules/providers/services/session-conversations-search.service.ts +12 -4
- package/server/modules/providers/services/sessions-watcher.service.ts +2 -0
- package/server/modules/providers/services/sessions.service.ts +166 -3
- package/server/modules/providers/shared/base/abstract.provider.ts +4 -3
- package/server/modules/providers/tests/claude-auth.test.ts +150 -0
- package/server/modules/providers/tests/claude-sessions.test.ts +61 -0
- package/server/modules/providers/tests/codex-sessions.test.ts +83 -4
- package/server/modules/providers/tests/opencode-models.test.ts +34 -135
- package/server/modules/providers/tests/opencode-sessions.test.ts +5 -5
- package/server/modules/providers/tests/{provider-image-history.test.ts → provider-attachment-history.test.ts} +68 -1
- package/server/modules/providers/tests/provider-models.service.test.ts +300 -296
- package/server/modules/providers/tests/provider-runtime.service.test.ts +138 -0
- package/server/modules/providers/tests/provider-token-usage.service.test.ts +186 -0
- package/server/modules/providers/tests/provider.routes.test.ts +183 -0
- package/server/modules/providers/tests/sessions-details.test.ts +73 -0
- package/server/modules/providers/tests/sessions.service.test.ts +127 -0
- package/server/modules/providers/tests/skills.test.ts +9 -2
- package/server/modules/settings/index.ts +2 -0
- package/server/modules/settings/settings.module.ts +50 -0
- package/server/modules/settings/settings.routes.ts +51 -0
- package/server/modules/settings/settings.service.ts +186 -0
- package/server/modules/settings/tests/settings.service.test.ts +54 -0
- package/server/modules/system/index.ts +2 -0
- package/server/modules/system/system.module.ts +62 -0
- package/server/modules/system/system.routes.ts +21 -0
- package/server/modules/system/system.service.ts +76 -0
- package/server/modules/system/tests/system.service.test.ts +118 -0
- package/server/modules/taskmaster/index.ts +2 -0
- package/server/modules/taskmaster/taskmaster.module.ts +24 -0
- package/server/modules/taskmaster/taskmaster.routes.ts +1482 -0
- package/server/modules/taskmaster/taskmaster.service.ts +132 -0
- package/server/modules/taskmaster/tests/taskmaster.routes.test.ts +144 -0
- package/server/modules/taskmaster/tests/taskmaster.service.test.ts +97 -0
- package/server/modules/user/index.ts +2 -0
- package/server/modules/user/tests/user.service.test.ts +61 -0
- package/server/modules/user/user.module.ts +58 -0
- package/server/modules/user/user.routes.ts +50 -0
- package/server/modules/user/user.service.ts +85 -0
- package/server/modules/voice/index.ts +2 -0
- package/server/modules/voice/tests/voice.service.test.ts +98 -0
- package/server/modules/voice/voice.module.ts +47 -0
- package/server/modules/voice/voice.routes.ts +113 -0
- package/server/modules/voice/voice.service.ts +192 -0
- package/server/modules/websocket/README.md +7 -7
- package/server/modules/websocket/services/chat-session-writer.service.ts +2 -2
- package/server/modules/websocket/services/chat-websocket.service.ts +77 -61
- package/server/modules/websocket/services/shell-websocket.service.ts +88 -12
- package/server/modules/websocket/services/websocket-server.service.ts +63 -19
- package/server/modules/websocket/tests/{chat-image-filter.test.ts → chat-attachment-filter.test.ts} +17 -2
- package/server/modules/websocket/tests/shell-websocket.service.test.ts +119 -0
- package/server/modules/websocket/tests/websocket-heartbeat.service.test.ts +78 -0
- package/server/modules/worktrees/index.ts +2 -0
- package/server/modules/worktrees/services/worktree-create-and-open.service.ts +53 -0
- package/server/modules/worktrees/services/worktree-create.service.ts +104 -0
- package/server/modules/worktrees/services/worktree-git.service.ts +207 -0
- package/server/modules/worktrees/services/worktree-list.service.ts +143 -0
- package/server/modules/worktrees/services/worktree-merge.service.ts +157 -0
- package/server/modules/worktrees/services/worktree-open.service.ts +85 -0
- package/server/modules/worktrees/services/worktree-remove.service.ts +88 -0
- package/server/modules/worktrees/tests/worktree-create-and-open.service.test.ts +68 -0
- package/server/modules/worktrees/tests/worktree-create.service.test.ts +142 -0
- package/server/modules/worktrees/tests/worktree-git.service.test.ts +84 -0
- package/server/modules/worktrees/tests/worktree-list.service.test.ts +45 -0
- package/server/modules/worktrees/tests/worktree-merge.service.test.ts +213 -0
- package/server/modules/worktrees/tests/worktree-open.service.test.ts +122 -0
- package/server/modules/worktrees/tests/worktree-remove.service.test.ts +227 -0
- package/server/modules/worktrees/tests/worktrees.routes.test.ts +199 -0
- package/server/modules/worktrees/worktrees.module.ts +113 -0
- package/server/modules/worktrees/worktrees.routes.ts +116 -0
- package/server/shared/image-attachments.ts +112 -18
- package/server/shared/interfaces.ts +33 -25
- package/server/shared/tests/image-attachments.test.ts +55 -0
- package/server/shared/types.ts +685 -36
- package/server/shared/utils.ts +77 -212
- package/dist/assets/index-CcCsKitq.js +0 -1423
- package/dist/assets/index-DLmhQ15L.css +0 -32
- package/dist-server/server/browser-use-mcp.js.map +0 -1
- package/dist-server/server/claude-sdk.js.map +0 -1
- package/dist-server/server/cli.js +0 -647
- package/dist-server/server/cli.js.map +0 -1
- package/dist-server/server/cursor-cli.js.map +0 -1
- package/dist-server/server/middleware/auth.js.map +0 -1
- package/dist-server/server/modules/providers/tests/provider-image-history.test.js.map +0 -1
- package/dist-server/server/modules/websocket/tests/chat-image-filter.test.js.map +0 -1
- package/dist-server/server/openai-codex.js.map +0 -1
- package/dist-server/server/opencode-cli.js.map +0 -1
- package/dist-server/server/opencode-cli.test.js.map +0 -1
- package/dist-server/server/routes/agent.js +0 -1155
- package/dist-server/server/routes/agent.js.map +0 -1
- package/dist-server/server/routes/auth.js +0 -119
- package/dist-server/server/routes/auth.js.map +0 -1
- package/dist-server/server/routes/commands.js +0 -492
- package/dist-server/server/routes/commands.js.map +0 -1
- package/dist-server/server/routes/cursor.js +0 -49
- package/dist-server/server/routes/cursor.js.map +0 -1
- package/dist-server/server/routes/git.js +0 -1389
- package/dist-server/server/routes/git.js.map +0 -1
- package/dist-server/server/routes/git.test.js.map +0 -1
- package/dist-server/server/routes/mcp-utils.js +0 -29
- package/dist-server/server/routes/mcp-utils.js.map +0 -1
- package/dist-server/server/routes/plugins.js +0 -266
- package/dist-server/server/routes/plugins.js.map +0 -1
- package/dist-server/server/routes/settings.js +0 -249
- package/dist-server/server/routes/settings.js.map +0 -1
- package/dist-server/server/routes/taskmaster.js +0 -1362
- package/dist-server/server/routes/taskmaster.js.map +0 -1
- package/dist-server/server/routes/tests/commands.test.js +0 -76
- package/dist-server/server/routes/tests/commands.test.js.map +0 -1
- package/dist-server/server/routes/user.js +0 -116
- package/dist-server/server/routes/user.js.map +0 -1
- package/dist-server/server/services/notification-orchestrator.js +0 -2
- package/dist-server/server/services/notification-orchestrator.js.map +0 -1
- package/dist-server/server/services/tests/notification-orchestrator.test.js +0 -64
- package/dist-server/server/services/tests/notification-orchestrator.test.js.map +0 -1
- package/dist-server/server/services/vapid-keys.js.map +0 -1
- package/dist-server/server/utils/colors.js +0 -20
- package/dist-server/server/utils/colors.js.map +0 -1
- package/dist-server/server/utils/commandParser.js +0 -255
- package/dist-server/server/utils/commandParser.js.map +0 -1
- package/dist-server/server/utils/gitConfig.js +0 -37
- package/dist-server/server/utils/gitConfig.js.map +0 -1
- package/dist-server/server/utils/mcp-detector.js +0 -134
- package/dist-server/server/utils/mcp-detector.js.map +0 -1
- package/dist-server/server/utils/plugin-loader.js.map +0 -1
- package/dist-server/server/utils/plugin-process-manager.js.map +0 -1
- package/dist-server/server/utils/runtime-paths.js +0 -30
- package/dist-server/server/utils/runtime-paths.js.map +0 -1
- package/dist-server/server/utils/taskmaster-websocket.js +0 -124
- package/dist-server/server/utils/taskmaster-websocket.js.map +0 -1
- package/dist-server/server/utils/url-detection.js +0 -58
- package/dist-server/server/utils/url-detection.js.map +0 -1
- package/dist-server/server/voice-proxy.js +0 -226
- package/dist-server/server/voice-proxy.js.map +0 -1
- package/server/cli.js +0 -695
- package/server/index.js +0 -1651
- package/server/routes/agent.js +0 -1257
- package/server/routes/auth.js +0 -137
- package/server/routes/cursor.js +0 -52
- package/server/routes/mcp-utils.js +0 -31
- package/server/routes/plugins.js +0 -307
- package/server/routes/settings.js +0 -282
- package/server/routes/taskmaster.js +0 -1470
- package/server/routes/tests/commands.test.js +0 -82
- package/server/routes/user.js +0 -124
- package/server/services/notification-orchestrator.js +0 -7
- package/server/services/tests/notification-orchestrator.test.js +0 -80
- package/server/utils/colors.js +0 -21
- package/server/utils/commandParser.js +0 -305
- package/server/utils/gitConfig.js +0 -35
- package/server/utils/mcp-detector.js +0 -147
- package/server/utils/runtime-paths.js +0 -37
- package/server/utils/taskmaster-websocket.js +0 -135
- package/server/utils/url-detection.js +0 -71
- package/server/voice-proxy.js +0 -224
- /package/server/constants/{config.js → config.ts} +0 -0
|
@@ -1,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
|
+
}
|