agent-tower 0.1.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/app.d.ts +2 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +62 -0
- package/dist/app.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +131 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/container.d.ts +11 -0
- package/dist/core/container.d.ts.map +1 -0
- package/dist/core/container.js +66 -0
- package/dist/core/container.js.map +1 -0
- package/dist/core/event-bus.d.ts +58 -0
- package/dist/core/event-bus.d.ts.map +1 -0
- package/dist/core/event-bus.js +29 -0
- package/dist/core/event-bus.js.map +1 -0
- package/dist/errors.d.ts +22 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +36 -0
- package/dist/errors.js.map +1 -0
- package/dist/executors/base.executor.d.ts +160 -0
- package/dist/executors/base.executor.d.ts.map +1 -0
- package/dist/executors/base.executor.js +122 -0
- package/dist/executors/base.executor.js.map +1 -0
- package/dist/executors/claude-code.executor.d.ts +78 -0
- package/dist/executors/claude-code.executor.d.ts.map +1 -0
- package/dist/executors/claude-code.executor.js +160 -0
- package/dist/executors/claude-code.executor.js.map +1 -0
- package/dist/executors/command-builder.d.ts +64 -0
- package/dist/executors/command-builder.d.ts.map +1 -0
- package/dist/executors/command-builder.js +144 -0
- package/dist/executors/command-builder.js.map +1 -0
- package/dist/executors/cursor-agent.executor.d.ts +57 -0
- package/dist/executors/cursor-agent.executor.d.ts.map +1 -0
- package/dist/executors/cursor-agent.executor.js +109 -0
- package/dist/executors/cursor-agent.executor.js.map +1 -0
- package/dist/executors/default-profiles.json +29 -0
- package/dist/executors/execution-env.d.ts +64 -0
- package/dist/executors/execution-env.d.ts.map +1 -0
- package/dist/executors/execution-env.js +97 -0
- package/dist/executors/execution-env.js.map +1 -0
- package/dist/executors/gemini-cli.executor.d.ts +55 -0
- package/dist/executors/gemini-cli.executor.d.ts.map +1 -0
- package/dist/executors/gemini-cli.executor.js +117 -0
- package/dist/executors/gemini-cli.executor.js.map +1 -0
- package/dist/executors/index.d.ts +49 -0
- package/dist/executors/index.d.ts.map +1 -0
- package/dist/executors/index.js +95 -0
- package/dist/executors/index.js.map +1 -0
- package/dist/executors/profiles.d.ts +61 -0
- package/dist/executors/profiles.d.ts.map +1 -0
- package/dist/executors/profiles.js +192 -0
- package/dist/executors/profiles.js.map +1 -0
- package/dist/git/git-cli.d.ts +59 -0
- package/dist/git/git-cli.d.ts.map +1 -0
- package/dist/git/git-cli.js +156 -0
- package/dist/git/git-cli.js.map +1 -0
- package/dist/git/worktree.manager.d.ts +166 -0
- package/dist/git/worktree.manager.d.ts.map +1 -0
- package/dist/git/worktree.manager.js +481 -0
- package/dist/git/worktree.manager.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/context.d.ts +15 -0
- package/dist/mcp/context.d.ts.map +1 -0
- package/dist/mcp/context.js +19 -0
- package/dist/mcp/context.js.map +1 -0
- package/dist/mcp/http-client.d.ts +46 -0
- package/dist/mcp/http-client.d.ts.map +1 -0
- package/dist/mcp/http-client.js +100 -0
- package/dist/mcp/http-client.js.map +1 -0
- package/dist/mcp/index.d.ts +3 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +36 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server.d.ts +6 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +32 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/projects.d.ts +7 -0
- package/dist/mcp/tools/projects.d.ts.map +1 -0
- package/dist/mcp/tools/projects.js +12 -0
- package/dist/mcp/tools/projects.js.map +1 -0
- package/dist/mcp/tools/sessions.d.ts +7 -0
- package/dist/mcp/tools/sessions.d.ts.map +1 -0
- package/dist/mcp/tools/sessions.js +22 -0
- package/dist/mcp/tools/sessions.js.map +1 -0
- package/dist/mcp/tools/tasks.d.ts +7 -0
- package/dist/mcp/tools/tasks.d.ts.map +1 -0
- package/dist/mcp/tools/tasks.js +68 -0
- package/dist/mcp/tools/tasks.js.map +1 -0
- package/dist/mcp/tools/workspaces.d.ts +7 -0
- package/dist/mcp/tools/workspaces.d.ts.map +1 -0
- package/dist/mcp/tools/workspaces.js +45 -0
- package/dist/mcp/tools/workspaces.js.map +1 -0
- package/dist/mcp/types.d.ts +109 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +55 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/middleware/tunnel-auth.d.ts +13 -0
- package/dist/middleware/tunnel-auth.d.ts.map +1 -0
- package/dist/middleware/tunnel-auth.js +39 -0
- package/dist/middleware/tunnel-auth.js.map +1 -0
- package/dist/output/__tests__/claude-code-parser-token.test.d.ts +2 -0
- package/dist/output/__tests__/claude-code-parser-token.test.d.ts.map +1 -0
- package/dist/output/__tests__/claude-code-parser-token.test.js +233 -0
- package/dist/output/__tests__/claude-code-parser-token.test.js.map +1 -0
- package/dist/output/__tests__/cursor-agent-parser-token.test.d.ts +2 -0
- package/dist/output/__tests__/cursor-agent-parser-token.test.d.ts.map +1 -0
- package/dist/output/__tests__/cursor-agent-parser-token.test.js +95 -0
- package/dist/output/__tests__/cursor-agent-parser-token.test.js.map +1 -0
- package/dist/output/__tests__/msg-store-token.test.d.ts +2 -0
- package/dist/output/__tests__/msg-store-token.test.d.ts.map +1 -0
- package/dist/output/__tests__/msg-store-token.test.js +38 -0
- package/dist/output/__tests__/msg-store-token.test.js.map +1 -0
- package/dist/output/claude-code-parser.d.ts +96 -0
- package/dist/output/claude-code-parser.d.ts.map +1 -0
- package/dist/output/claude-code-parser.js +498 -0
- package/dist/output/claude-code-parser.js.map +1 -0
- package/dist/output/cursor-agent-parser.d.ts +87 -0
- package/dist/output/cursor-agent-parser.d.ts.map +1 -0
- package/dist/output/cursor-agent-parser.js +476 -0
- package/dist/output/cursor-agent-parser.js.map +1 -0
- package/dist/output/index.d.ts +9 -0
- package/dist/output/index.d.ts.map +1 -0
- package/dist/output/index.js +13 -0
- package/dist/output/index.js.map +1 -0
- package/dist/output/msg-store.d.ts +110 -0
- package/dist/output/msg-store.d.ts.map +1 -0
- package/dist/output/msg-store.js +274 -0
- package/dist/output/msg-store.js.map +1 -0
- package/dist/output/types.d.ts +90 -0
- package/dist/output/types.d.ts.map +1 -0
- package/dist/output/types.js +93 -0
- package/dist/output/types.js.map +1 -0
- package/dist/output/utils/ansi.d.ts +8 -0
- package/dist/output/utils/ansi.d.ts.map +1 -0
- package/dist/output/utils/ansi.js +17 -0
- package/dist/output/utils/ansi.js.map +1 -0
- package/dist/output/utils/patch.d.ts +57 -0
- package/dist/output/utils/patch.d.ts.map +1 -0
- package/dist/output/utils/patch.js +113 -0
- package/dist/output/utils/patch.js.map +1 -0
- package/dist/pipeline/agent-pipeline.d.ts +28 -0
- package/dist/pipeline/agent-pipeline.d.ts.map +1 -0
- package/dist/pipeline/agent-pipeline.js +76 -0
- package/dist/pipeline/agent-pipeline.js.map +1 -0
- package/dist/routes/attachments.d.ts +3 -0
- package/dist/routes/attachments.d.ts.map +1 -0
- package/dist/routes/attachments.js +141 -0
- package/dist/routes/attachments.js.map +1 -0
- package/dist/routes/demo.d.ts +3 -0
- package/dist/routes/demo.d.ts.map +1 -0
- package/dist/routes/demo.js +152 -0
- package/dist/routes/demo.js.map +1 -0
- package/dist/routes/files.d.ts +3 -0
- package/dist/routes/files.d.ts.map +1 -0
- package/dist/routes/files.js +313 -0
- package/dist/routes/files.js.map +1 -0
- package/dist/routes/filesystem.d.ts +3 -0
- package/dist/routes/filesystem.d.ts.map +1 -0
- package/dist/routes/filesystem.js +126 -0
- package/dist/routes/filesystem.js.map +1 -0
- package/dist/routes/git.d.ts +3 -0
- package/dist/routes/git.d.ts.map +1 -0
- package/dist/routes/git.js +170 -0
- package/dist/routes/git.js.map +1 -0
- package/dist/routes/index.d.ts +3 -0
- package/dist/routes/index.d.ts.map +1 -0
- package/dist/routes/index.js +45 -0
- package/dist/routes/index.js.map +1 -0
- package/dist/routes/notifications.d.ts +10 -0
- package/dist/routes/notifications.d.ts.map +1 -0
- package/dist/routes/notifications.js +54 -0
- package/dist/routes/notifications.js.map +1 -0
- package/dist/routes/profiles.d.ts +12 -0
- package/dist/routes/profiles.d.ts.map +1 -0
- package/dist/routes/profiles.js +76 -0
- package/dist/routes/profiles.js.map +1 -0
- package/dist/routes/projects.d.ts +3 -0
- package/dist/routes/projects.d.ts.map +1 -0
- package/dist/routes/projects.js +94 -0
- package/dist/routes/projects.js.map +1 -0
- package/dist/routes/sessions.d.ts +12 -0
- package/dist/routes/sessions.d.ts.map +1 -0
- package/dist/routes/sessions.js +109 -0
- package/dist/routes/sessions.js.map +1 -0
- package/dist/routes/system.d.ts +3 -0
- package/dist/routes/system.d.ts.map +1 -0
- package/dist/routes/system.js +42 -0
- package/dist/routes/system.js.map +1 -0
- package/dist/routes/tasks.d.ts +3 -0
- package/dist/routes/tasks.d.ts.map +1 -0
- package/dist/routes/tasks.js +136 -0
- package/dist/routes/tasks.js.map +1 -0
- package/dist/routes/terminals.d.ts +3 -0
- package/dist/routes/terminals.d.ts.map +1 -0
- package/dist/routes/terminals.js +54 -0
- package/dist/routes/terminals.js.map +1 -0
- package/dist/routes/tunnel.d.ts +3 -0
- package/dist/routes/tunnel.d.ts.map +1 -0
- package/dist/routes/tunnel.js +36 -0
- package/dist/routes/tunnel.js.map +1 -0
- package/dist/routes/workspaces.d.ts +3 -0
- package/dist/routes/workspaces.d.ts.map +1 -0
- package/dist/routes/workspaces.js +171 -0
- package/dist/routes/workspaces.js.map +1 -0
- package/dist/services/commit-message.service.d.ts +32 -0
- package/dist/services/commit-message.service.d.ts.map +1 -0
- package/dist/services/commit-message.service.js +202 -0
- package/dist/services/commit-message.service.js.map +1 -0
- package/dist/services/notifications/feishu-channel.d.ts +9 -0
- package/dist/services/notifications/feishu-channel.d.ts.map +1 -0
- package/dist/services/notifications/feishu-channel.js +51 -0
- package/dist/services/notifications/feishu-channel.js.map +1 -0
- package/dist/services/notifications/index.d.ts +3 -0
- package/dist/services/notifications/index.d.ts.map +1 -0
- package/dist/services/notifications/index.js +2 -0
- package/dist/services/notifications/index.js.map +1 -0
- package/dist/services/notifications/notification.service.d.ts +10 -0
- package/dist/services/notifications/notification.service.d.ts.map +1 -0
- package/dist/services/notifications/notification.service.js +85 -0
- package/dist/services/notifications/notification.service.js.map +1 -0
- package/dist/services/notifications/os-channel.d.ts +8 -0
- package/dist/services/notifications/os-channel.d.ts.map +1 -0
- package/dist/services/notifications/os-channel.js +38 -0
- package/dist/services/notifications/os-channel.js.map +1 -0
- package/dist/services/notifications/types.d.ts +11 -0
- package/dist/services/notifications/types.d.ts.map +1 -0
- package/dist/services/notifications/types.js +2 -0
- package/dist/services/notifications/types.js.map +1 -0
- package/dist/services/project.service.d.ts +91 -0
- package/dist/services/project.service.d.ts.map +1 -0
- package/dist/services/project.service.js +138 -0
- package/dist/services/project.service.js.map +1 -0
- package/dist/services/session-manager.d.ts +164 -0
- package/dist/services/session-manager.d.ts.map +1 -0
- package/dist/services/session-manager.js +569 -0
- package/dist/services/session-manager.js.map +1 -0
- package/dist/services/task.service.d.ts +179 -0
- package/dist/services/task.service.d.ts.map +1 -0
- package/dist/services/task.service.js +281 -0
- package/dist/services/task.service.js.map +1 -0
- package/dist/services/terminal-manager.d.ts +64 -0
- package/dist/services/terminal-manager.d.ts.map +1 -0
- package/dist/services/terminal-manager.js +217 -0
- package/dist/services/terminal-manager.js.map +1 -0
- package/dist/services/tunnel.service.d.ts +16 -0
- package/dist/services/tunnel.service.d.ts.map +1 -0
- package/dist/services/tunnel.service.js +77 -0
- package/dist/services/tunnel.service.js.map +1 -0
- package/dist/services/workspace.service.d.ts +219 -0
- package/dist/services/workspace.service.d.ts.map +1 -0
- package/dist/services/workspace.service.js +351 -0
- package/dist/services/workspace.service.js.map +1 -0
- package/dist/socket/events.d.ts +2 -0
- package/dist/socket/events.d.ts.map +1 -0
- package/dist/socket/events.js +3 -0
- package/dist/socket/events.js.map +1 -0
- package/dist/socket/index.d.ts +20 -0
- package/dist/socket/index.d.ts.map +1 -0
- package/dist/socket/index.js +77 -0
- package/dist/socket/index.js.map +1 -0
- package/dist/socket/middleware/auth.d.ts +13 -0
- package/dist/socket/middleware/auth.d.ts.map +1 -0
- package/dist/socket/middleware/auth.js +29 -0
- package/dist/socket/middleware/auth.js.map +1 -0
- package/dist/socket/middleware/error-handler.d.ts +11 -0
- package/dist/socket/middleware/error-handler.d.ts.map +1 -0
- package/dist/socket/middleware/error-handler.js +39 -0
- package/dist/socket/middleware/error-handler.js.map +1 -0
- package/dist/socket/middleware/index.d.ts +3 -0
- package/dist/socket/middleware/index.d.ts.map +1 -0
- package/dist/socket/middleware/index.js +3 -0
- package/dist/socket/middleware/index.js.map +1 -0
- package/dist/socket/rooms.d.ts +30 -0
- package/dist/socket/rooms.d.ts.map +1 -0
- package/dist/socket/rooms.js +39 -0
- package/dist/socket/rooms.js.map +1 -0
- package/dist/socket/socket-gateway.d.ts +21 -0
- package/dist/socket/socket-gateway.d.ts.map +1 -0
- package/dist/socket/socket-gateway.js +173 -0
- package/dist/socket/socket-gateway.js.map +1 -0
- package/dist/types/index.d.ts +41 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +41 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/index.d.ts +12 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +25 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/web/assets/AgentDemoPage-WdWEQtyU.js +1 -0
- package/dist/web/assets/DemoPage-C4Z_ftHI.js +4 -0
- package/dist/web/assets/NotificationSettingsPage-FrLfgt9y.js +1 -0
- package/dist/web/assets/ProfileSettingsPage-Cs93rTRr.js +3 -0
- package/dist/web/assets/ProjectKanbanPage-BmlRVfzo.js +75 -0
- package/dist/web/assets/ProjectKanbanPage-G5OQeJvU.css +1 -0
- package/dist/web/assets/api-client-CEBkg5lt.js +1 -0
- package/dist/web/assets/circle-alert-BEozlsMd.js +1 -0
- package/dist/web/assets/code-block-OCS4YCEC-CGgYYS4A.js +2 -0
- package/dist/web/assets/folder-picker-BP3x3phB.js +1 -0
- package/dist/web/assets/index-BuAijQvi.js +13 -0
- package/dist/web/assets/index-CxV866Yg.css +1 -0
- package/dist/web/assets/loader-circle-yEIqsdJ1.js +1 -0
- package/dist/web/assets/mermaid-NOHMQCX5-CIqtI2jF.js +123 -0
- package/dist/web/assets/mermaid-NOHMQCX5-lI9o3AWT.css +1 -0
- package/dist/web/assets/modal-BoX2RXaV.js +1 -0
- package/dist/web/assets/query-keys-BD_s_Etj.js +1 -0
- package/dist/web/assets/use-profiles-Rh8rBsAt.js +1 -0
- package/dist/web/index.html +14 -0
- package/dist/web/vite.svg +1 -0
- package/node_modules/@agent-tower/shared/dist/dev-port.d.ts +12 -0
- package/node_modules/@agent-tower/shared/dist/dev-port.d.ts.map +1 -0
- package/node_modules/@agent-tower/shared/dist/dev-port.js +31 -0
- package/node_modules/@agent-tower/shared/dist/dev-port.js.map +1 -0
- package/node_modules/@agent-tower/shared/dist/index.d.ts +5 -0
- package/node_modules/@agent-tower/shared/dist/index.d.ts.map +1 -0
- package/node_modules/@agent-tower/shared/dist/index.js +5 -0
- package/node_modules/@agent-tower/shared/dist/index.js.map +1 -0
- package/node_modules/@agent-tower/shared/dist/log-adapter.d.ts +72 -0
- package/node_modules/@agent-tower/shared/dist/log-adapter.d.ts.map +1 -0
- package/node_modules/@agent-tower/shared/dist/log-adapter.js +144 -0
- package/node_modules/@agent-tower/shared/dist/log-adapter.js.map +1 -0
- package/node_modules/@agent-tower/shared/dist/socket/events.d.ts +133 -0
- package/node_modules/@agent-tower/shared/dist/socket/events.d.ts.map +1 -0
- package/node_modules/@agent-tower/shared/dist/socket/events.js +32 -0
- package/node_modules/@agent-tower/shared/dist/socket/events.js.map +1 -0
- package/node_modules/@agent-tower/shared/dist/socket/index.d.ts +2 -0
- package/node_modules/@agent-tower/shared/dist/socket/index.d.ts.map +1 -0
- package/node_modules/@agent-tower/shared/dist/socket/index.js +2 -0
- package/node_modules/@agent-tower/shared/dist/socket/index.js.map +1 -0
- package/node_modules/@agent-tower/shared/dist/types.d.ts +168 -0
- package/node_modules/@agent-tower/shared/dist/types.d.ts.map +1 -0
- package/node_modules/@agent-tower/shared/dist/types.js +53 -0
- package/node_modules/@agent-tower/shared/dist/types.js.map +1 -0
- package/node_modules/@agent-tower/shared/package.json +38 -0
- package/package.json +46 -0
- package/prisma/schema.prisma +130 -0
- package/scripts/postinstall.js +120 -0
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fs from 'fs/promises';
|
|
3
|
+
import { ConflictOp } from '@agent-tower/shared';
|
|
4
|
+
import { execGit, isValidBranchName, GitError, BranchExistsError, BranchNotFoundError, InvalidBranchNameError, WorktreeDirtyError, MergeConflictError, BranchesDivergedError, RebaseInProgressError, } from './git-cli.js';
|
|
5
|
+
// Re-export error types for consumers
|
|
6
|
+
export { GitError, BranchExistsError, BranchNotFoundError, InvalidBranchNameError, WorktreeDirtyError, MergeConflictError, BranchesDivergedError, RebaseInProgressError, } from './git-cli.js';
|
|
7
|
+
// ─── WorktreeManager ──────────────────────────────────────────────────────────
|
|
8
|
+
export class WorktreeManager {
|
|
9
|
+
repoPath;
|
|
10
|
+
worktreeBaseDir;
|
|
11
|
+
constructor(repoPath) {
|
|
12
|
+
this.repoPath = repoPath;
|
|
13
|
+
this.worktreeBaseDir = path.join(repoPath, '..', '.worktrees');
|
|
14
|
+
}
|
|
15
|
+
// ── Read-only Queries ───────────────────────────────────────────────────────
|
|
16
|
+
/**
|
|
17
|
+
* List all worktrees with parsed metadata.
|
|
18
|
+
* Parses `git worktree list --porcelain` output.
|
|
19
|
+
*/
|
|
20
|
+
async listWorktrees() {
|
|
21
|
+
const result = await execGit(this.repoPath, ['worktree', 'list', '--porcelain']);
|
|
22
|
+
return this.parseWorktreeListOutput(result);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get branch divergence status (ahead/behind) relative to a base branch.
|
|
26
|
+
*/
|
|
27
|
+
async getBranchStatus(branchName, baseBranch) {
|
|
28
|
+
await this.ensureBranchExists(branchName);
|
|
29
|
+
await this.ensureBranchExists(baseBranch);
|
|
30
|
+
const output = await execGit(this.repoPath, [
|
|
31
|
+
'rev-list',
|
|
32
|
+
'--left-right',
|
|
33
|
+
'--count',
|
|
34
|
+
`${baseBranch}...${branchName}`,
|
|
35
|
+
]);
|
|
36
|
+
const parts = output.trim().split(/\s+/);
|
|
37
|
+
const behind = parseInt(parts[0] ?? '0', 10);
|
|
38
|
+
const ahead = parseInt(parts[1] ?? '0', 10);
|
|
39
|
+
return { ahead, behind };
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get the working tree status of a worktree (changed + untracked file counts).
|
|
43
|
+
*/
|
|
44
|
+
async getWorktreeStatus(worktreePath) {
|
|
45
|
+
const output = await execGit(worktreePath, ['status', '--porcelain']);
|
|
46
|
+
const lines = output.split('\n').filter((l) => l.length > 0);
|
|
47
|
+
let changedFiles = 0;
|
|
48
|
+
let untrackedFiles = 0;
|
|
49
|
+
for (const line of lines) {
|
|
50
|
+
if (line.startsWith('??')) {
|
|
51
|
+
untrackedFiles++;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
changedFiles++;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return { changedFiles, untrackedFiles };
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Check whether a worktree has no uncommitted changes.
|
|
61
|
+
*/
|
|
62
|
+
async isWorktreeClean(worktreePath) {
|
|
63
|
+
const status = await this.getWorktreeStatus(worktreePath);
|
|
64
|
+
return status.changedFiles === 0 && status.untrackedFiles === 0;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Check whether a branch exists (local).
|
|
68
|
+
*/
|
|
69
|
+
async checkBranchExists(branchName) {
|
|
70
|
+
try {
|
|
71
|
+
await execGit(this.repoPath, ['rev-parse', '--verify', `refs/heads/${branchName}`]);
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// ── Write Operations ────────────────────────────────────────────────────────
|
|
79
|
+
/**
|
|
80
|
+
* Create a new worktree with a new branch.
|
|
81
|
+
*
|
|
82
|
+
* - Validates branch name
|
|
83
|
+
* - Checks branch does not already exist
|
|
84
|
+
* - Creates the worktree base directory if needed
|
|
85
|
+
*/
|
|
86
|
+
async create(branchName) {
|
|
87
|
+
// Validate branch name
|
|
88
|
+
const validation = isValidBranchName(branchName);
|
|
89
|
+
if (!validation.valid) {
|
|
90
|
+
throw new InvalidBranchNameError(branchName, validation.reason);
|
|
91
|
+
}
|
|
92
|
+
// Check branch does not already exist
|
|
93
|
+
const exists = await this.checkBranchExists(branchName);
|
|
94
|
+
if (exists) {
|
|
95
|
+
throw new BranchExistsError(branchName);
|
|
96
|
+
}
|
|
97
|
+
const worktreePath = path.join(this.worktreeBaseDir, branchName);
|
|
98
|
+
await fs.mkdir(this.worktreeBaseDir, { recursive: true });
|
|
99
|
+
try {
|
|
100
|
+
await execGit(this.repoPath, ['worktree', 'add', '-b', branchName, worktreePath]);
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
// Wrap with more context
|
|
104
|
+
if (err instanceof GitError) {
|
|
105
|
+
throw new GitError(`Failed to create worktree for branch '${branchName}': ${err.message}`, 'WORKTREE_CREATE_FAILED');
|
|
106
|
+
}
|
|
107
|
+
throw err;
|
|
108
|
+
}
|
|
109
|
+
return worktreePath;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Remove a worktree. If the worktree does not exist, this is a no-op.
|
|
113
|
+
*/
|
|
114
|
+
async remove(worktreePath) {
|
|
115
|
+
// Check if the worktree path actually exists on disk
|
|
116
|
+
const pathExists = await fs
|
|
117
|
+
.access(worktreePath)
|
|
118
|
+
.then(() => true)
|
|
119
|
+
.catch(() => false);
|
|
120
|
+
if (!pathExists) {
|
|
121
|
+
// Worktree directory doesn't exist — run prune to clean up stale refs, then return
|
|
122
|
+
await this.prune();
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
await execGit(this.repoPath, ['worktree', 'remove', worktreePath, '--force']);
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
// If the error indicates the worktree is not registered, treat as no-op
|
|
130
|
+
if (err instanceof GitError && err.message.includes('is not a working tree')) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
throw err;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Ensure a worktree exists for an existing branch. If the worktree directory
|
|
138
|
+
* is already valid, return its path. Otherwise, recreate it.
|
|
139
|
+
*
|
|
140
|
+
* Used when reactivating a MERGED workspace — the branch was preserved via
|
|
141
|
+
* update-ref but the worktree directory was removed.
|
|
142
|
+
*
|
|
143
|
+
* 参考: vibe-kanban crates/services/src/services/worktree_manager.rs:93-123
|
|
144
|
+
*/
|
|
145
|
+
async ensureWorktreeExists(branchName) {
|
|
146
|
+
await this.ensureBranchExists(branchName);
|
|
147
|
+
const worktreePath = path.join(this.worktreeBaseDir, branchName);
|
|
148
|
+
// Check if worktree already exists and is valid
|
|
149
|
+
const pathExists = await fs.access(worktreePath).then(() => true).catch(() => false);
|
|
150
|
+
if (pathExists) {
|
|
151
|
+
const gitFileExists = await fs.access(path.join(worktreePath, '.git')).then(() => true).catch(() => false);
|
|
152
|
+
if (gitFileExists) {
|
|
153
|
+
return worktreePath;
|
|
154
|
+
}
|
|
155
|
+
// Invalid directory — clean up first
|
|
156
|
+
await this.remove(worktreePath);
|
|
157
|
+
}
|
|
158
|
+
// Prune stale worktree references
|
|
159
|
+
await this.prune();
|
|
160
|
+
// Create worktree from existing branch (no -b flag)
|
|
161
|
+
await fs.mkdir(this.worktreeBaseDir, { recursive: true });
|
|
162
|
+
try {
|
|
163
|
+
await execGit(this.repoPath, ['worktree', 'add', worktreePath, branchName]);
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
if (err instanceof GitError) {
|
|
167
|
+
throw new GitError(`Failed to recreate worktree for branch '${branchName}': ${err.message}`, 'WORKTREE_RECREATE_FAILED');
|
|
168
|
+
}
|
|
169
|
+
throw err;
|
|
170
|
+
}
|
|
171
|
+
return worktreePath;
|
|
172
|
+
}
|
|
173
|
+
async getDiff(worktreePath, baseBranch, options) {
|
|
174
|
+
const diff = await execGit(worktreePath, ['diff', baseBranch]);
|
|
175
|
+
if (options?.withStat) {
|
|
176
|
+
const stat = await execGit(worktreePath, ['diff', '--stat', baseBranch]);
|
|
177
|
+
return { diff, stat };
|
|
178
|
+
}
|
|
179
|
+
return diff;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Squash-merge a worktree branch into the target branch.
|
|
183
|
+
*
|
|
184
|
+
* Performs the following steps:
|
|
185
|
+
* 1. Verify the worktree is clean
|
|
186
|
+
* 2. Check branch divergence — fail if base branch has advanced
|
|
187
|
+
* 3. Checkout target branch in the main repo
|
|
188
|
+
* 4. Execute `git merge --squash --no-commit <task_branch>`
|
|
189
|
+
* 5. Commit the squash merge
|
|
190
|
+
* 6. Remove the worktree and delete the task branch
|
|
191
|
+
*/
|
|
192
|
+
async merge(worktreePath, targetBranch, options) {
|
|
193
|
+
// Determine the current branch of the worktree
|
|
194
|
+
const currentBranchRaw = await execGit(worktreePath, ['rev-parse', '--abbrev-ref', 'HEAD']);
|
|
195
|
+
const taskBranch = currentBranchRaw.trim();
|
|
196
|
+
// 1. Check worktree is clean
|
|
197
|
+
const clean = await this.isWorktreeClean(worktreePath);
|
|
198
|
+
if (!clean) {
|
|
199
|
+
throw new WorktreeDirtyError(worktreePath);
|
|
200
|
+
}
|
|
201
|
+
// 2. Check branch divergence
|
|
202
|
+
const status = await this.getBranchStatus(taskBranch, targetBranch);
|
|
203
|
+
if (status.behind > 0) {
|
|
204
|
+
throw new BranchesDivergedError(taskBranch, targetBranch, status.ahead, status.behind);
|
|
205
|
+
}
|
|
206
|
+
// 3. Checkout target branch in main repo
|
|
207
|
+
await execGit(this.repoPath, ['checkout', targetBranch]);
|
|
208
|
+
// 4. Squash merge (no commit yet)
|
|
209
|
+
try {
|
|
210
|
+
await execGit(this.repoPath, [
|
|
211
|
+
'merge',
|
|
212
|
+
'--squash',
|
|
213
|
+
'--no-commit',
|
|
214
|
+
taskBranch,
|
|
215
|
+
]);
|
|
216
|
+
}
|
|
217
|
+
catch (err) {
|
|
218
|
+
if (err instanceof GitError) {
|
|
219
|
+
// Check for merge conflicts
|
|
220
|
+
const conflictedFiles = await this.getConflictedFiles();
|
|
221
|
+
if (conflictedFiles.length > 0) {
|
|
222
|
+
// Abort the merge to leave the repo clean
|
|
223
|
+
await execGit(this.repoPath, ['merge', '--abort']).catch(() => {
|
|
224
|
+
// merge --abort may fail if no merge in progress, ignore
|
|
225
|
+
});
|
|
226
|
+
throw new MergeConflictError(conflictedFiles, ConflictOp.MERGE);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
throw err;
|
|
230
|
+
}
|
|
231
|
+
// 5. Commit the squash
|
|
232
|
+
const message = options?.commitMessage ?? `squash merge branch '${taskBranch}'`;
|
|
233
|
+
await execGit(this.repoPath, ['commit', '-m', message]);
|
|
234
|
+
// 6. Get the merge commit SHA
|
|
235
|
+
const sha = (await execGit(this.repoPath, ['rev-parse', 'HEAD'])).trim();
|
|
236
|
+
// 7. Update task branch ref to point to the merge commit.
|
|
237
|
+
// This allows future work to continue from the merged state without conflicts.
|
|
238
|
+
// 参考: vibe-kanban crates/git/src/lib.rs:873-879
|
|
239
|
+
await execGit(this.repoPath, ['update-ref', `refs/heads/${taskBranch}`, sha]);
|
|
240
|
+
// 8. Remove worktree (but keep the branch for future reuse)
|
|
241
|
+
await this.remove(worktreePath);
|
|
242
|
+
return { sha, taskBranch };
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Prune stale worktree references.
|
|
246
|
+
*/
|
|
247
|
+
async prune() {
|
|
248
|
+
await execGit(this.repoPath, ['worktree', 'prune']);
|
|
249
|
+
}
|
|
250
|
+
// ── Rebase & Git Operation Status ──────────────────────────────────────────
|
|
251
|
+
/**
|
|
252
|
+
* Rebase the current branch in the worktree onto the latest base branch.
|
|
253
|
+
* Uses `git rebase --onto <baseBranch> <mergeBase> <taskBranch>`.
|
|
254
|
+
*
|
|
255
|
+
* - If a rebase is already in progress, throws RebaseInProgressError
|
|
256
|
+
* - On conflict, throws MergeConflictError with ConflictOp.REBASE (preserves rebase state)
|
|
257
|
+
* - On non-conflict failure, auto-aborts to keep repo clean
|
|
258
|
+
*/
|
|
259
|
+
async rebase(worktreePath, baseBranch) {
|
|
260
|
+
// Pre-check 1: worktree must be clean (no uncommitted tracked changes)
|
|
261
|
+
if (!(await this.isWorktreeClean(worktreePath))) {
|
|
262
|
+
throw new WorktreeDirtyError(worktreePath);
|
|
263
|
+
}
|
|
264
|
+
// Pre-check 2: no rebase already in progress
|
|
265
|
+
if (await this.isRebaseInProgress(worktreePath)) {
|
|
266
|
+
throw new RebaseInProgressError();
|
|
267
|
+
}
|
|
268
|
+
// Get current branch name
|
|
269
|
+
const currentBranchRaw = await execGit(worktreePath, ['rev-parse', '--abbrev-ref', 'HEAD']);
|
|
270
|
+
const taskBranch = currentBranchRaw.trim();
|
|
271
|
+
// Calculate merge-base
|
|
272
|
+
const mergeBaseRaw = await execGit(worktreePath, ['merge-base', baseBranch, taskBranch]);
|
|
273
|
+
const mergeBase = mergeBaseRaw.trim();
|
|
274
|
+
try {
|
|
275
|
+
await execGit(worktreePath, ['rebase', '--onto', baseBranch, mergeBase, taskBranch]);
|
|
276
|
+
}
|
|
277
|
+
catch (err) {
|
|
278
|
+
// Check if it's a conflict
|
|
279
|
+
if (await this.isRebaseInProgress(worktreePath)) {
|
|
280
|
+
const conflictedFiles = await this.getConflictedFilesIn(worktreePath);
|
|
281
|
+
if (conflictedFiles.length > 0) {
|
|
282
|
+
throw new MergeConflictError(conflictedFiles, ConflictOp.REBASE);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
// Non-conflict failure: auto-abort to keep repo clean
|
|
286
|
+
try {
|
|
287
|
+
await execGit(worktreePath, ['rebase', '--abort']);
|
|
288
|
+
}
|
|
289
|
+
catch {
|
|
290
|
+
// ignore abort failure
|
|
291
|
+
}
|
|
292
|
+
throw err;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Get the current Git operation status of a worktree.
|
|
297
|
+
*/
|
|
298
|
+
async getGitOperationStatus(worktreePath, baseBranch) {
|
|
299
|
+
const rebaseInProgress = await this.isRebaseInProgress(worktreePath);
|
|
300
|
+
const mergeInProgress = await this.isMergeInProgress(worktreePath);
|
|
301
|
+
let operation = 'idle';
|
|
302
|
+
let conflictOp = null;
|
|
303
|
+
if (rebaseInProgress) {
|
|
304
|
+
operation = 'rebase';
|
|
305
|
+
conflictOp = ConflictOp.REBASE;
|
|
306
|
+
}
|
|
307
|
+
else if (mergeInProgress) {
|
|
308
|
+
operation = 'merge';
|
|
309
|
+
conflictOp = ConflictOp.MERGE;
|
|
310
|
+
}
|
|
311
|
+
let conflictedFiles = [];
|
|
312
|
+
if (operation !== 'idle') {
|
|
313
|
+
conflictedFiles = await this.getConflictedFilesIn(worktreePath);
|
|
314
|
+
}
|
|
315
|
+
// Get branch divergence info
|
|
316
|
+
let ahead = 0;
|
|
317
|
+
let behind = 0;
|
|
318
|
+
try {
|
|
319
|
+
const currentBranchRaw = await execGit(worktreePath, ['rev-parse', '--abbrev-ref', 'HEAD']);
|
|
320
|
+
const currentBranch = currentBranchRaw.trim();
|
|
321
|
+
const status = await this.getBranchStatus(currentBranch, baseBranch);
|
|
322
|
+
ahead = status.ahead;
|
|
323
|
+
behind = status.behind;
|
|
324
|
+
}
|
|
325
|
+
catch {
|
|
326
|
+
// If branch status fails (e.g. during rebase with detached HEAD), use defaults
|
|
327
|
+
}
|
|
328
|
+
// Get uncommitted changes info
|
|
329
|
+
let uncommittedCount = 0;
|
|
330
|
+
let untrackedCount = 0;
|
|
331
|
+
try {
|
|
332
|
+
const wtStatus = await this.getWorktreeStatus(worktreePath);
|
|
333
|
+
uncommittedCount = wtStatus.changedFiles;
|
|
334
|
+
untrackedCount = wtStatus.untrackedFiles;
|
|
335
|
+
}
|
|
336
|
+
catch {
|
|
337
|
+
// ignore
|
|
338
|
+
}
|
|
339
|
+
return {
|
|
340
|
+
operation,
|
|
341
|
+
conflictedFiles,
|
|
342
|
+
conflictOp,
|
|
343
|
+
ahead,
|
|
344
|
+
behind,
|
|
345
|
+
hasUncommittedChanges: uncommittedCount > 0,
|
|
346
|
+
uncommittedCount,
|
|
347
|
+
untrackedCount,
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Abort the current in-progress Git operation (rebase or merge).
|
|
352
|
+
* If no operation is in progress, this is a no-op.
|
|
353
|
+
*/
|
|
354
|
+
async abortOperation(worktreePath) {
|
|
355
|
+
if (await this.isRebaseInProgress(worktreePath)) {
|
|
356
|
+
await execGit(worktreePath, ['rebase', '--abort']);
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
if (await this.isMergeInProgress(worktreePath)) {
|
|
360
|
+
await execGit(worktreePath, ['merge', '--abort']);
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
// No operation in progress — no-op
|
|
364
|
+
}
|
|
365
|
+
// ── Backward-compatible aliases ─────────────────────────────────────────────
|
|
366
|
+
/**
|
|
367
|
+
* Alias for `listWorktrees()`, returns just the paths.
|
|
368
|
+
* Kept for backward compatibility with existing callers.
|
|
369
|
+
*/
|
|
370
|
+
async list() {
|
|
371
|
+
const worktrees = await this.listWorktrees();
|
|
372
|
+
return worktrees.map((w) => w.path);
|
|
373
|
+
}
|
|
374
|
+
// ── Private Helpers ─────────────────────────────────────────────────────────
|
|
375
|
+
/**
|
|
376
|
+
* Assert that a branch exists; throw BranchNotFoundError if not.
|
|
377
|
+
*/
|
|
378
|
+
async ensureBranchExists(branchName) {
|
|
379
|
+
const exists = await this.checkBranchExists(branchName);
|
|
380
|
+
if (!exists) {
|
|
381
|
+
throw new BranchNotFoundError(branchName);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Parse the porcelain output of `git worktree list --porcelain`.
|
|
386
|
+
*
|
|
387
|
+
* Format:
|
|
388
|
+
* ```
|
|
389
|
+
* worktree /path/to/main
|
|
390
|
+
* HEAD abc123
|
|
391
|
+
* branch refs/heads/main
|
|
392
|
+
*
|
|
393
|
+
* worktree /path/to/wt
|
|
394
|
+
* HEAD def456
|
|
395
|
+
* branch refs/heads/feature
|
|
396
|
+
* ```
|
|
397
|
+
*/
|
|
398
|
+
parseWorktreeListOutput(output) {
|
|
399
|
+
const worktrees = [];
|
|
400
|
+
const blocks = output.split('\n\n').filter((b) => b.trim().length > 0);
|
|
401
|
+
for (const block of blocks) {
|
|
402
|
+
const lines = block.split('\n');
|
|
403
|
+
let wtPath = '';
|
|
404
|
+
let head = '';
|
|
405
|
+
let branch = '';
|
|
406
|
+
let bare = false;
|
|
407
|
+
for (const line of lines) {
|
|
408
|
+
if (line.startsWith('worktree ')) {
|
|
409
|
+
wtPath = line.slice('worktree '.length);
|
|
410
|
+
}
|
|
411
|
+
else if (line.startsWith('HEAD ')) {
|
|
412
|
+
head = line.slice('HEAD '.length);
|
|
413
|
+
}
|
|
414
|
+
else if (line.startsWith('branch ')) {
|
|
415
|
+
// Strip refs/heads/ prefix
|
|
416
|
+
branch = line.slice('branch '.length).replace('refs/heads/', '');
|
|
417
|
+
}
|
|
418
|
+
else if (line === 'bare') {
|
|
419
|
+
bare = true;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
if (wtPath) {
|
|
423
|
+
worktrees.push({ path: wtPath, head, branch, bare });
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
return worktrees;
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Get the list of conflicted files from a failed merge.
|
|
430
|
+
*/
|
|
431
|
+
async getConflictedFiles() {
|
|
432
|
+
return this.getConflictedFilesIn(this.repoPath);
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Get the list of conflicted files in a specific worktree path.
|
|
436
|
+
*/
|
|
437
|
+
async getConflictedFilesIn(worktreePath) {
|
|
438
|
+
try {
|
|
439
|
+
const output = await execGit(worktreePath, ['diff', '--name-only', '--diff-filter=U']);
|
|
440
|
+
return output
|
|
441
|
+
.split('\n')
|
|
442
|
+
.map((f) => f.trim())
|
|
443
|
+
.filter((f) => f.length > 0);
|
|
444
|
+
}
|
|
445
|
+
catch {
|
|
446
|
+
return [];
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Check if a rebase is in progress in the given worktree.
|
|
451
|
+
* Detects by checking for rebase-merge or rebase-apply directories.
|
|
452
|
+
*/
|
|
453
|
+
async isRebaseInProgress(worktreePath) {
|
|
454
|
+
try {
|
|
455
|
+
const rebaseMergePath = (await execGit(worktreePath, ['rev-parse', '--git-path', 'rebase-merge'])).trim();
|
|
456
|
+
const rebaseApplyPath = (await execGit(worktreePath, ['rev-parse', '--git-path', 'rebase-apply'])).trim();
|
|
457
|
+
const [mergeExists, applyExists] = await Promise.all([
|
|
458
|
+
fs.access(rebaseMergePath).then(() => true).catch(() => false),
|
|
459
|
+
fs.access(rebaseApplyPath).then(() => true).catch(() => false),
|
|
460
|
+
]);
|
|
461
|
+
return mergeExists || applyExists;
|
|
462
|
+
}
|
|
463
|
+
catch {
|
|
464
|
+
return false;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* Check if a merge is in progress in the given worktree.
|
|
469
|
+
* Detects by verifying MERGE_HEAD exists.
|
|
470
|
+
*/
|
|
471
|
+
async isMergeInProgress(worktreePath) {
|
|
472
|
+
try {
|
|
473
|
+
await execGit(worktreePath, ['rev-parse', '--verify', 'MERGE_HEAD']);
|
|
474
|
+
return true;
|
|
475
|
+
}
|
|
476
|
+
catch {
|
|
477
|
+
return false;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
//# sourceMappingURL=worktree.manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worktree.manager.js","sourceRoot":"","sources":["../../src/git/worktree.manager.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { fileURLToPath } from 'url';
|
|
3
|
+
import { buildApp } from './app.js';
|
|
4
|
+
import { getDevPort } from '@agent-tower/shared/dev-port';
|
|
5
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
const monorepoRoot = path.resolve(__dirname, '../../..');
|
|
7
|
+
const PORT = getDevPort(monorepoRoot);
|
|
8
|
+
async function main() {
|
|
9
|
+
const app = await buildApp();
|
|
10
|
+
// 优雅关闭处理
|
|
11
|
+
const shutdown = async (signal) => {
|
|
12
|
+
console.log(`\n${signal} received, shutting down gracefully...`);
|
|
13
|
+
try {
|
|
14
|
+
await app.close();
|
|
15
|
+
console.log('Server closed');
|
|
16
|
+
// 等待 OS 释放端口
|
|
17
|
+
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
18
|
+
process.exit(0);
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
console.error('Error during shutdown:', err);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
|
26
|
+
process.on('SIGINT', () => shutdown('SIGINT'));
|
|
27
|
+
try {
|
|
28
|
+
await app.listen({ port: PORT, host: '0.0.0.0' });
|
|
29
|
+
console.log(`Server is running on http://localhost:${PORT}`);
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
app.log.error(err);
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
main();
|
|
37
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAE1D,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;AACzD,MAAM,IAAI,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;AAEtC,KAAK,UAAU,IAAI;IACjB,MAAM,GAAG,GAAG,MAAM,QAAQ,EAAE,CAAC;IAE7B,SAAS;IACT,MAAM,QAAQ,GAAG,KAAK,EAAE,MAAc,EAAE,EAAE;QACxC,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,wCAAwC,CAAC,CAAC;QACjE,IAAI,CAAC;YACH,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAC7B,aAAa;YACb,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;YACzD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,GAAG,CAAC,CAAC;YAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;IACjD,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;IAE/C,IAAI,CAAC;QACH,MAAM,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;QAClD,OAAO,CAAC,GAAG,CAAC,yCAAyC,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 工作空间上下文检测
|
|
3
|
+
* 启动时根据 cwd 查询后端,判断当前目录是否在某个 workspace 的 worktree 中
|
|
4
|
+
*/
|
|
5
|
+
import type { AgentTowerClient } from './http-client.js';
|
|
6
|
+
export interface McpContext {
|
|
7
|
+
projectId: string;
|
|
8
|
+
projectName: string;
|
|
9
|
+
taskId: string;
|
|
10
|
+
taskTitle: string;
|
|
11
|
+
workspaceId: string;
|
|
12
|
+
workspaceBranch: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function fetchContext(client: AgentTowerClient): Promise<McpContext | null>;
|
|
15
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/mcp/context.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAevF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export async function fetchContext(client) {
|
|
2
|
+
try {
|
|
3
|
+
const result = await client.getWorkspaceContext(process.cwd());
|
|
4
|
+
if (!result)
|
|
5
|
+
return null;
|
|
6
|
+
return {
|
|
7
|
+
projectId: result.projectId,
|
|
8
|
+
projectName: result.projectName,
|
|
9
|
+
taskId: result.taskId,
|
|
10
|
+
taskTitle: result.taskTitle,
|
|
11
|
+
workspaceId: result.workspaceId,
|
|
12
|
+
workspaceBranch: result.workspaceBranch,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/mcp/context.ts"],"names":[],"mappings":"AAeA,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAwB;IACzD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAC/D,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QACzB,OAAO;YACL,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,eAAe,EAAE,MAAM,CAAC,eAAe;SACxC,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agent-tower 后端 API HTTP 客户端
|
|
3
|
+
* MCP 服务器通过此客户端代理调用后端 REST API
|
|
4
|
+
*/
|
|
5
|
+
export declare class AgentTowerClient {
|
|
6
|
+
private baseUrl;
|
|
7
|
+
constructor(baseUrl: string);
|
|
8
|
+
private url;
|
|
9
|
+
private request;
|
|
10
|
+
listProjects(params?: {
|
|
11
|
+
page?: number;
|
|
12
|
+
limit?: number;
|
|
13
|
+
}): Promise<any>;
|
|
14
|
+
listTasks(projectId: string, params?: {
|
|
15
|
+
status?: string;
|
|
16
|
+
limit?: number;
|
|
17
|
+
page?: number;
|
|
18
|
+
}): Promise<any>;
|
|
19
|
+
createTask(projectId: string, input: {
|
|
20
|
+
title: string;
|
|
21
|
+
description?: string;
|
|
22
|
+
priority?: number;
|
|
23
|
+
}): Promise<any>;
|
|
24
|
+
getTask(taskId: string): Promise<any>;
|
|
25
|
+
updateTask(taskId: string, input: {
|
|
26
|
+
title?: string;
|
|
27
|
+
description?: string;
|
|
28
|
+
priority?: number;
|
|
29
|
+
}): Promise<any>;
|
|
30
|
+
updateTaskStatus(taskId: string, status: string): Promise<any>;
|
|
31
|
+
deleteTask(taskId: string): Promise<void>;
|
|
32
|
+
createWorkspace(taskId: string, branchName?: string): Promise<any>;
|
|
33
|
+
getWorkspaceDiff(workspaceId: string): Promise<{
|
|
34
|
+
diff: string;
|
|
35
|
+
}>;
|
|
36
|
+
mergeWorkspace(workspaceId: string): Promise<{
|
|
37
|
+
success: boolean;
|
|
38
|
+
sha: string;
|
|
39
|
+
}>;
|
|
40
|
+
createSession(workspaceId: string, agentType: string, prompt: string, variant?: string): Promise<any>;
|
|
41
|
+
startSession(sessionId: string): Promise<any>;
|
|
42
|
+
stopSession(sessionId: string): Promise<any>;
|
|
43
|
+
sendMessage(sessionId: string, message: string): Promise<any>;
|
|
44
|
+
getWorkspaceContext(cwdPath: string): Promise<any>;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=http-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-client.d.ts","sourceRoot":"","sources":["../../src/mcp/http-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,qBAAa,gBAAgB;IACf,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,MAAM;IAEnC,OAAO,CAAC,GAAG;YAIG,OAAO;IA0Bf,YAAY,CAAC,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;IASvD,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE;IAQxF,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE;IAI/F,OAAO,CAAC,MAAM,EAAE,MAAM;IAItB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE;IAI7F,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAI/C,UAAU,CAAC,MAAM,EAAE,MAAM;IAMzB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM;IAInD,gBAAgB,CAAC,WAAW,EAAE,MAAM;cACZ,MAAM;;IAG9B,cAAc,CAAC,WAAW,EAAE,MAAM;iBACP,OAAO;aAAO,MAAM;;IAK/C,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;IAQtF,YAAY,CAAC,SAAS,EAAE,MAAM;IAI9B,WAAW,CAAC,SAAS,EAAE,MAAM;IAI7B,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAM9C,mBAAmB,CAAC,OAAO,EAAE,MAAM;CAG1C"}
|