clitrigger 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.
Files changed (201) hide show
  1. package/.env.example +9 -0
  2. package/LICENSE +21 -0
  3. package/README.md +186 -0
  4. package/bin/clitrigger.js +106 -0
  5. package/dist/client/assets/index-BkOCv65b.css +1 -0
  6. package/dist/client/assets/index-Fbf16Lh1.js +129 -0
  7. package/dist/client/index.html +24 -0
  8. package/dist/server/db/connection.d.ts +4 -0
  9. package/dist/server/db/connection.d.ts.map +1 -0
  10. package/dist/server/db/connection.js +24 -0
  11. package/dist/server/db/connection.js.map +1 -0
  12. package/dist/server/db/queries.d.ts +265 -0
  13. package/dist/server/db/queries.d.ts.map +1 -0
  14. package/dist/server/db/queries.js +836 -0
  15. package/dist/server/db/queries.js.map +1 -0
  16. package/dist/server/db/schema.d.ts +3 -0
  17. package/dist/server/db/schema.d.ts.map +1 -0
  18. package/dist/server/db/schema.js +325 -0
  19. package/dist/server/db/schema.js.map +1 -0
  20. package/dist/server/index.d.ts +5 -0
  21. package/dist/server/index.d.ts.map +1 -0
  22. package/dist/server/index.js +207 -0
  23. package/dist/server/index.js.map +1 -0
  24. package/dist/server/middleware/auth.d.ts +5 -0
  25. package/dist/server/middleware/auth.d.ts.map +1 -0
  26. package/dist/server/middleware/auth.js +45 -0
  27. package/dist/server/middleware/auth.js.map +1 -0
  28. package/dist/server/plugins/github/index.d.ts +3 -0
  29. package/dist/server/plugins/github/index.d.ts.map +1 -0
  30. package/dist/server/plugins/github/index.js +18 -0
  31. package/dist/server/plugins/github/index.js.map +1 -0
  32. package/dist/server/plugins/github/router.d.ts +4 -0
  33. package/dist/server/plugins/github/router.d.ts.map +1 -0
  34. package/dist/server/plugins/github/router.js +250 -0
  35. package/dist/server/plugins/github/router.js.map +1 -0
  36. package/dist/server/plugins/gstack/index.d.ts +3 -0
  37. package/dist/server/plugins/gstack/index.d.ts.map +1 -0
  38. package/dist/server/plugins/gstack/index.js +36 -0
  39. package/dist/server/plugins/gstack/index.js.map +1 -0
  40. package/dist/server/plugins/jira/index.d.ts +3 -0
  41. package/dist/server/plugins/jira/index.d.ts.map +1 -0
  42. package/dist/server/plugins/jira/index.js +19 -0
  43. package/dist/server/plugins/jira/index.js.map +1 -0
  44. package/dist/server/plugins/jira/router.d.ts +4 -0
  45. package/dist/server/plugins/jira/router.d.ts.map +1 -0
  46. package/dist/server/plugins/jira/router.js +332 -0
  47. package/dist/server/plugins/jira/router.js.map +1 -0
  48. package/dist/server/plugins/notion/index.d.ts +3 -0
  49. package/dist/server/plugins/notion/index.d.ts.map +1 -0
  50. package/dist/server/plugins/notion/index.js +17 -0
  51. package/dist/server/plugins/notion/index.js.map +1 -0
  52. package/dist/server/plugins/notion/router.d.ts +4 -0
  53. package/dist/server/plugins/notion/router.d.ts.map +1 -0
  54. package/dist/server/plugins/notion/router.js +313 -0
  55. package/dist/server/plugins/notion/router.js.map +1 -0
  56. package/dist/server/plugins/registry.d.ts +8 -0
  57. package/dist/server/plugins/registry.d.ts.map +1 -0
  58. package/dist/server/plugins/registry.js +31 -0
  59. package/dist/server/plugins/registry.js.map +1 -0
  60. package/dist/server/plugins/types.d.ts +32 -0
  61. package/dist/server/plugins/types.d.ts.map +1 -0
  62. package/dist/server/plugins/types.js +2 -0
  63. package/dist/server/plugins/types.js.map +1 -0
  64. package/dist/server/resources/gstack-skills/LICENSE +21 -0
  65. package/dist/server/resources/gstack-skills/benchmark/SKILL.md +528 -0
  66. package/dist/server/resources/gstack-skills/careful/SKILL.md +59 -0
  67. package/dist/server/resources/gstack-skills/cso/SKILL.md +898 -0
  68. package/dist/server/resources/gstack-skills/investigate/SKILL.md +474 -0
  69. package/dist/server/resources/gstack-skills/qa/SKILL.md +1055 -0
  70. package/dist/server/resources/gstack-skills/qa-only/SKILL.md +672 -0
  71. package/dist/server/resources/gstack-skills/review/SKILL.md +1044 -0
  72. package/dist/server/resources/gstack-skills/skills-manifest.d.ts +9 -0
  73. package/dist/server/resources/gstack-skills/skills-manifest.d.ts.map +1 -0
  74. package/dist/server/resources/gstack-skills/skills-manifest.js +52 -0
  75. package/dist/server/resources/gstack-skills/skills-manifest.js.map +1 -0
  76. package/dist/server/resources/gstack-skills/skills-manifest.ts +59 -0
  77. package/dist/server/routes/auth.d.ts +3 -0
  78. package/dist/server/routes/auth.d.ts.map +1 -0
  79. package/dist/server/routes/auth.js +70 -0
  80. package/dist/server/routes/auth.js.map +1 -0
  81. package/dist/server/routes/debug-logs.d.ts +3 -0
  82. package/dist/server/routes/debug-logs.d.ts.map +1 -0
  83. package/dist/server/routes/debug-logs.js +43 -0
  84. package/dist/server/routes/debug-logs.js.map +1 -0
  85. package/dist/server/routes/discussions.d.ts +3 -0
  86. package/dist/server/routes/discussions.d.ts.map +1 -0
  87. package/dist/server/routes/discussions.js +544 -0
  88. package/dist/server/routes/discussions.js.map +1 -0
  89. package/dist/server/routes/execution.d.ts +3 -0
  90. package/dist/server/routes/execution.d.ts.map +1 -0
  91. package/dist/server/routes/execution.js +339 -0
  92. package/dist/server/routes/execution.js.map +1 -0
  93. package/dist/server/routes/github.d.ts +3 -0
  94. package/dist/server/routes/github.d.ts.map +1 -0
  95. package/dist/server/routes/github.js +251 -0
  96. package/dist/server/routes/github.js.map +1 -0
  97. package/dist/server/routes/images.d.ts +17 -0
  98. package/dist/server/routes/images.d.ts.map +1 -0
  99. package/dist/server/routes/images.js +152 -0
  100. package/dist/server/routes/images.js.map +1 -0
  101. package/dist/server/routes/jira.d.ts +3 -0
  102. package/dist/server/routes/jira.d.ts.map +1 -0
  103. package/dist/server/routes/jira.js +333 -0
  104. package/dist/server/routes/jira.js.map +1 -0
  105. package/dist/server/routes/logs.d.ts +3 -0
  106. package/dist/server/routes/logs.d.ts.map +1 -0
  107. package/dist/server/routes/logs.js +156 -0
  108. package/dist/server/routes/logs.js.map +1 -0
  109. package/dist/server/routes/models.d.ts +3 -0
  110. package/dist/server/routes/models.d.ts.map +1 -0
  111. package/dist/server/routes/models.js +65 -0
  112. package/dist/server/routes/models.js.map +1 -0
  113. package/dist/server/routes/notion.d.ts +3 -0
  114. package/dist/server/routes/notion.d.ts.map +1 -0
  115. package/dist/server/routes/notion.js +312 -0
  116. package/dist/server/routes/notion.js.map +1 -0
  117. package/dist/server/routes/pipelines.d.ts +3 -0
  118. package/dist/server/routes/pipelines.d.ts.map +1 -0
  119. package/dist/server/routes/pipelines.js +315 -0
  120. package/dist/server/routes/pipelines.js.map +1 -0
  121. package/dist/server/routes/plugins.d.ts +3 -0
  122. package/dist/server/routes/plugins.d.ts.map +1 -0
  123. package/dist/server/routes/plugins.js +71 -0
  124. package/dist/server/routes/plugins.js.map +1 -0
  125. package/dist/server/routes/projects.d.ts +3 -0
  126. package/dist/server/routes/projects.d.ts.map +1 -0
  127. package/dist/server/routes/projects.js +557 -0
  128. package/dist/server/routes/projects.js.map +1 -0
  129. package/dist/server/routes/schedules.d.ts +3 -0
  130. package/dist/server/routes/schedules.d.ts.map +1 -0
  131. package/dist/server/routes/schedules.js +247 -0
  132. package/dist/server/routes/schedules.js.map +1 -0
  133. package/dist/server/routes/todos.d.ts +3 -0
  134. package/dist/server/routes/todos.d.ts.map +1 -0
  135. package/dist/server/routes/todos.js +103 -0
  136. package/dist/server/routes/todos.js.map +1 -0
  137. package/dist/server/routes/tunnel.d.ts +3 -0
  138. package/dist/server/routes/tunnel.d.ts.map +1 -0
  139. package/dist/server/routes/tunnel.js +44 -0
  140. package/dist/server/routes/tunnel.js.map +1 -0
  141. package/dist/server/services/claude-manager.d.ts +42 -0
  142. package/dist/server/services/claude-manager.d.ts.map +1 -0
  143. package/dist/server/services/claude-manager.js +275 -0
  144. package/dist/server/services/claude-manager.js.map +1 -0
  145. package/dist/server/services/cli-adapters.d.ts +35 -0
  146. package/dist/server/services/cli-adapters.d.ts.map +1 -0
  147. package/dist/server/services/cli-adapters.js +139 -0
  148. package/dist/server/services/cli-adapters.js.map +1 -0
  149. package/dist/server/services/debug-logger.d.ts +35 -0
  150. package/dist/server/services/debug-logger.d.ts.map +1 -0
  151. package/dist/server/services/debug-logger.js +168 -0
  152. package/dist/server/services/debug-logger.js.map +1 -0
  153. package/dist/server/services/discussion-orchestrator.d.ts +47 -0
  154. package/dist/server/services/discussion-orchestrator.d.ts.map +1 -0
  155. package/dist/server/services/discussion-orchestrator.js +599 -0
  156. package/dist/server/services/discussion-orchestrator.js.map +1 -0
  157. package/dist/server/services/log-streamer.d.ts +45 -0
  158. package/dist/server/services/log-streamer.d.ts.map +1 -0
  159. package/dist/server/services/log-streamer.js +348 -0
  160. package/dist/server/services/log-streamer.js.map +1 -0
  161. package/dist/server/services/orchestrator.d.ts +69 -0
  162. package/dist/server/services/orchestrator.d.ts.map +1 -0
  163. package/dist/server/services/orchestrator.js +642 -0
  164. package/dist/server/services/orchestrator.js.map +1 -0
  165. package/dist/server/services/pipeline-orchestrator.d.ts +43 -0
  166. package/dist/server/services/pipeline-orchestrator.d.ts.map +1 -0
  167. package/dist/server/services/pipeline-orchestrator.js +503 -0
  168. package/dist/server/services/pipeline-orchestrator.js.map +1 -0
  169. package/dist/server/services/prompt-guard.d.ts +19 -0
  170. package/dist/server/services/prompt-guard.d.ts.map +1 -0
  171. package/dist/server/services/prompt-guard.js +43 -0
  172. package/dist/server/services/prompt-guard.js.map +1 -0
  173. package/dist/server/services/scheduler.d.ts +43 -0
  174. package/dist/server/services/scheduler.d.ts.map +1 -0
  175. package/dist/server/services/scheduler.js +199 -0
  176. package/dist/server/services/scheduler.js.map +1 -0
  177. package/dist/server/services/skill-injector.d.ts +17 -0
  178. package/dist/server/services/skill-injector.d.ts.map +1 -0
  179. package/dist/server/services/skill-injector.js +60 -0
  180. package/dist/server/services/skill-injector.js.map +1 -0
  181. package/dist/server/services/tunnel-manager.d.ts +42 -0
  182. package/dist/server/services/tunnel-manager.d.ts.map +1 -0
  183. package/dist/server/services/tunnel-manager.js +265 -0
  184. package/dist/server/services/tunnel-manager.js.map +1 -0
  185. package/dist/server/services/worktree-manager.d.ts +117 -0
  186. package/dist/server/services/worktree-manager.d.ts.map +1 -0
  187. package/dist/server/services/worktree-manager.js +400 -0
  188. package/dist/server/services/worktree-manager.js.map +1 -0
  189. package/dist/server/websocket/broadcaster.d.ts +12 -0
  190. package/dist/server/websocket/broadcaster.d.ts.map +1 -0
  191. package/dist/server/websocket/broadcaster.js +23 -0
  192. package/dist/server/websocket/broadcaster.js.map +1 -0
  193. package/dist/server/websocket/events.d.ts +94 -0
  194. package/dist/server/websocket/events.d.ts.map +1 -0
  195. package/dist/server/websocket/events.js +2 -0
  196. package/dist/server/websocket/events.js.map +1 -0
  197. package/dist/server/websocket/index.d.ts +3 -0
  198. package/dist/server/websocket/index.d.ts.map +1 -0
  199. package/dist/server/websocket/index.js +82 -0
  200. package/dist/server/websocket/index.js.map +1 -0
  201. package/package.json +68 -0
@@ -0,0 +1,400 @@
1
+ import simpleGit from 'simple-git';
2
+ import path from 'path';
3
+ import fs from 'fs';
4
+ import { execSync } from 'child_process';
5
+ export class WorktreeManager {
6
+ /**
7
+ * Sanitize a todo title into a valid branch name.
8
+ * Converts Korean/special chars to a safe slug, prefixed with "feature/".
9
+ */
10
+ sanitizeBranchName(title) {
11
+ const slug = title
12
+ .toLowerCase()
13
+ .replace(/[^a-z0-9\s-]/g, '') // remove non-alphanumeric (Korean, etc.) except spaces and hyphens
14
+ .replace(/\s+/g, '-') // spaces to hyphens
15
+ .replace(/-+/g, '-') // collapse multiple hyphens
16
+ .replace(/^-|-$/g, '') // trim leading/trailing hyphens
17
+ .slice(0, 40); // limit length
18
+ // If slug is too short (e.g. Korean-only title), use a short random ID
19
+ const safeName = slug.length >= 3
20
+ ? slug
21
+ : `task-${Math.random().toString(36).substring(2, 8)}`;
22
+ return `feature/${safeName}`;
23
+ }
24
+ /**
25
+ * Check if a directory is inside a git repository.
26
+ */
27
+ async isGitRepository(dirPath) {
28
+ try {
29
+ const git = simpleGit(dirPath);
30
+ return await git.checkIsRepo();
31
+ }
32
+ catch {
33
+ return false;
34
+ }
35
+ }
36
+ /**
37
+ * Check if a directory is a valid git worktree (has .git file and can run git status).
38
+ */
39
+ async isValidWorktree(worktreePath) {
40
+ try {
41
+ const gitPath = path.join(worktreePath, '.git');
42
+ if (!fs.existsSync(gitPath))
43
+ return false;
44
+ const git = simpleGit(worktreePath);
45
+ await git.status();
46
+ return true;
47
+ }
48
+ catch {
49
+ return false;
50
+ }
51
+ }
52
+ /**
53
+ * Create a worktree for a todo item.
54
+ * Worktree path: <projectPath>/../worktrees/<branchName>
55
+ * Returns the absolute worktree path.
56
+ */
57
+ async createWorktree(projectPath, branchName) {
58
+ const git = simpleGit(projectPath);
59
+ // Compute worktree directory
60
+ const worktreeBase = path.resolve(projectPath, '.worktrees');
61
+ // Use the part after "feature/" for the directory name, or the whole branch name
62
+ const baseDirName = branchName.replace(/\//g, '-');
63
+ // Ensure the worktrees base directory exists
64
+ if (!fs.existsSync(worktreeBase)) {
65
+ fs.mkdirSync(worktreeBase, { recursive: true });
66
+ }
67
+ // Find a unique directory name (append -2, -3, etc. if already exists)
68
+ let dirName = baseDirName;
69
+ let worktreePath = path.resolve(worktreeBase, dirName);
70
+ let suffix = 1;
71
+ while (fs.existsSync(worktreePath)) {
72
+ suffix++;
73
+ dirName = `${baseDirName}-${suffix}`;
74
+ worktreePath = path.resolve(worktreeBase, dirName);
75
+ }
76
+ // Also deduplicate branch name if directory needed a suffix
77
+ let actualBranch = branchName;
78
+ if (suffix > 1) {
79
+ actualBranch = `${branchName}-${suffix}`;
80
+ }
81
+ // Create a new branch and worktree
82
+ // First, check if the branch already exists
83
+ const branchSummary = await git.branchLocal();
84
+ if (branchSummary.all.includes(actualBranch)) {
85
+ // Branch exists, create worktree using existing branch
86
+ await git.raw(['worktree', 'add', worktreePath, actualBranch]);
87
+ }
88
+ else {
89
+ // Create new branch with worktree
90
+ await git.raw(['worktree', 'add', '-b', actualBranch, worktreePath]);
91
+ }
92
+ // Auto-install dependencies in the background (non-blocking)
93
+ this.installDependencies(worktreePath).catch((err) => {
94
+ console.warn(`[worktree] dependency install failed:`, err);
95
+ });
96
+ return worktreePath;
97
+ }
98
+ /**
99
+ * Install npm dependencies in a worktree (root + client).
100
+ * Failures are logged but do not block worktree creation.
101
+ */
102
+ async installDependencies(worktreePath) {
103
+ // Root-level dependencies
104
+ if (fs.existsSync(path.join(worktreePath, 'package.json'))) {
105
+ try {
106
+ execSync('npm install', { cwd: worktreePath, stdio: 'ignore', timeout: 120_000 });
107
+ }
108
+ catch (err) {
109
+ console.warn(`[worktree] npm install failed at root: ${err.message}`);
110
+ }
111
+ }
112
+ // Client-level dependencies (monorepo sub-package)
113
+ const clientDir = path.join(worktreePath, 'src', 'client');
114
+ if (fs.existsSync(path.join(clientDir, 'package.json'))) {
115
+ try {
116
+ execSync('npm install', { cwd: clientDir, stdio: 'ignore', timeout: 120_000 });
117
+ }
118
+ catch (err) {
119
+ console.warn(`[worktree] npm install failed at src/client: ${err.message}`);
120
+ }
121
+ }
122
+ }
123
+ /**
124
+ * Remove a worktree and prune.
125
+ */
126
+ async removeWorktree(projectPath, worktreePath) {
127
+ const git = simpleGit(projectPath);
128
+ try {
129
+ await git.raw(['worktree', 'remove', worktreePath, '--force']);
130
+ }
131
+ catch {
132
+ // If the worktree directory was already removed, just prune
133
+ await git.raw(['worktree', 'prune']);
134
+ }
135
+ }
136
+ /**
137
+ * Remove a worktree, delete its branch, and clean up the DB record.
138
+ * Returns info about what was cleaned up.
139
+ */
140
+ async cleanupWorktree(projectPath, worktreePath, branchName) {
141
+ const result = { worktreeRemoved: false, branchDeleted: false };
142
+ const git = simpleGit(projectPath);
143
+ // 1. Remove worktree
144
+ try {
145
+ if (fs.existsSync(worktreePath)) {
146
+ await git.raw(['worktree', 'remove', worktreePath, '--force']);
147
+ result.worktreeRemoved = true;
148
+ }
149
+ else {
150
+ // Directory already gone, just prune
151
+ await git.raw(['worktree', 'prune']);
152
+ result.worktreeRemoved = true;
153
+ }
154
+ }
155
+ catch {
156
+ // Fallback: prune stale worktrees
157
+ try {
158
+ await git.raw(['worktree', 'prune']);
159
+ result.worktreeRemoved = true;
160
+ }
161
+ catch {
162
+ // Ignore
163
+ }
164
+ }
165
+ // 2. Delete the branch
166
+ if (branchName) {
167
+ try {
168
+ await git.raw(['branch', '-D', branchName]);
169
+ result.branchDeleted = true;
170
+ }
171
+ catch {
172
+ // Branch may already be deleted or not exist
173
+ }
174
+ }
175
+ return result;
176
+ }
177
+ /**
178
+ * Squash merge a source branch into a target worktree's branch.
179
+ * This takes all commits from sourceBranch and applies them as a single commit on the target.
180
+ */
181
+ async squashMergeBranch(targetWorktreePath, sourceBranch) {
182
+ const git = simpleGit(targetWorktreePath);
183
+ await git.raw(['merge', '--squash', sourceBranch]);
184
+ await git.commit(`Squash merge from ${sourceBranch}`);
185
+ }
186
+ /**
187
+ * List all worktrees for a project.
188
+ */
189
+ async listWorktrees(projectPath) {
190
+ const git = simpleGit(projectPath);
191
+ const result = await git.raw(['worktree', 'list', '--porcelain']);
192
+ const worktrees = [];
193
+ const entries = result.split('\n\n').filter(Boolean);
194
+ for (const entry of entries) {
195
+ const lines = entry.split('\n');
196
+ let wtPath = '';
197
+ let branch = '';
198
+ for (const line of lines) {
199
+ if (line.startsWith('worktree ')) {
200
+ wtPath = line.substring('worktree '.length);
201
+ }
202
+ if (line.startsWith('branch ')) {
203
+ branch = line.substring('branch '.length).replace('refs/heads/', '');
204
+ }
205
+ }
206
+ if (wtPath && branch) {
207
+ worktrees.push({ path: wtPath, branch });
208
+ }
209
+ }
210
+ return worktrees;
211
+ }
212
+ /**
213
+ * Get git status for a directory (repo or worktree).
214
+ * Returns branch info and file statuses.
215
+ */
216
+ /**
217
+ * Get git log (commit history) for a directory.
218
+ */
219
+ async getGitLog(dirPath, options = {}) {
220
+ const skip = options.skip ?? 0;
221
+ const limit = options.limit ?? 50;
222
+ const git = simpleGit(dirPath);
223
+ const raw = await git.raw([
224
+ 'log', '--all', '--topo-order',
225
+ `--format=%H%x1E%P%x1E%D%x1E%s%x1E%an%x1E%aI`,
226
+ `--max-count=${limit + 1}`,
227
+ `--skip=${skip}`,
228
+ ]);
229
+ const lines = raw.trim().split('\n').filter(Boolean);
230
+ const hasMore = lines.length > limit;
231
+ const entries = hasMore ? lines.slice(0, limit) : lines;
232
+ const commits = entries.map((line) => {
233
+ const [hash, parents, refsStr, message, author, date] = line.split('\x1E');
234
+ return {
235
+ hash,
236
+ parentHashes: parents ? parents.split(' ').filter(Boolean) : [],
237
+ refs: refsStr ? refsStr.split(', ').filter(Boolean) : [],
238
+ message,
239
+ author,
240
+ date,
241
+ };
242
+ });
243
+ return { commits, hasMore };
244
+ }
245
+ /**
246
+ * Get git refs (branches, tags, stash count) for a directory.
247
+ */
248
+ async getGitRefs(dirPath) {
249
+ const git = simpleGit(dirPath);
250
+ const branchResult = await git.branch(['-a']);
251
+ const branches = Object.values(branchResult.branches).map((b) => ({
252
+ name: b.name,
253
+ current: b.current,
254
+ remote: b.name.startsWith('remotes/'),
255
+ }));
256
+ const tagResult = await git.tags();
257
+ const tags = tagResult.all;
258
+ let stashCount = 0;
259
+ try {
260
+ const stashResult = await git.stashList();
261
+ stashCount = stashResult.total;
262
+ }
263
+ catch {
264
+ // No stash support or empty
265
+ }
266
+ return { branches, tags, stashCount };
267
+ }
268
+ // --- Git action methods ---
269
+ async gitStage(dirPath, files) {
270
+ const git = simpleGit(dirPath);
271
+ await git.add(files);
272
+ }
273
+ async gitUnstage(dirPath, files) {
274
+ const git = simpleGit(dirPath);
275
+ await git.reset(files.map(f => ['--', f]).flat());
276
+ }
277
+ async gitCommit(dirPath, message) {
278
+ const git = simpleGit(dirPath);
279
+ const result = await git.commit(message);
280
+ return result.commit;
281
+ }
282
+ async gitPull(dirPath, remote = 'origin', branch) {
283
+ const git = simpleGit(dirPath);
284
+ const args = [remote];
285
+ if (branch)
286
+ args.push(branch);
287
+ const result = await git.pull(args);
288
+ return `${result.summary.changes} changes, ${result.summary.insertions} insertions, ${result.summary.deletions} deletions`;
289
+ }
290
+ async gitPush(dirPath, remote = 'origin', branch, setUpstream = false) {
291
+ const git = simpleGit(dirPath);
292
+ const args = [remote];
293
+ if (branch)
294
+ args.push(branch);
295
+ if (setUpstream) {
296
+ await git.raw(['push', '-u', ...args]);
297
+ }
298
+ else {
299
+ await git.push(args);
300
+ }
301
+ return 'ok';
302
+ }
303
+ async gitFetch(dirPath, remote = 'origin', prune = false) {
304
+ const git = simpleGit(dirPath);
305
+ const args = ['fetch', remote];
306
+ if (prune)
307
+ args.push('--prune');
308
+ await git.raw(args);
309
+ }
310
+ async gitCreateBranch(dirPath, branchName, startPoint) {
311
+ const git = simpleGit(dirPath);
312
+ if (startPoint) {
313
+ await git.checkoutBranch(branchName, startPoint);
314
+ }
315
+ else {
316
+ await git.checkoutLocalBranch(branchName);
317
+ }
318
+ }
319
+ async gitDeleteBranch(dirPath, branchName, force = false) {
320
+ const git = simpleGit(dirPath);
321
+ await git.branch([force ? '-D' : '-d', branchName]);
322
+ }
323
+ async gitCheckout(dirPath, branchName) {
324
+ const git = simpleGit(dirPath);
325
+ await git.checkout(branchName);
326
+ }
327
+ async gitMerge(dirPath, sourceBranch) {
328
+ const git = simpleGit(dirPath);
329
+ const result = await git.merge([sourceBranch]);
330
+ return result.result ?? 'ok';
331
+ }
332
+ async gitStashPush(dirPath, message) {
333
+ const git = simpleGit(dirPath);
334
+ const args = ['stash', 'push'];
335
+ if (message)
336
+ args.push('-m', message);
337
+ await git.raw(args);
338
+ }
339
+ async gitStashPop(dirPath, index = 0) {
340
+ const git = simpleGit(dirPath);
341
+ await git.raw(['stash', 'pop', `stash@{${index}}`]);
342
+ }
343
+ async gitStashList(dirPath) {
344
+ const git = simpleGit(dirPath);
345
+ const result = await git.stashList();
346
+ return result.all.map((s, i) => ({ index: i, message: s.message }));
347
+ }
348
+ async gitDiscard(dirPath, files) {
349
+ const git = simpleGit(dirPath);
350
+ await git.checkout(['--', ...files]);
351
+ }
352
+ async gitDiscardAll(dirPath) {
353
+ const git = simpleGit(dirPath);
354
+ await git.checkout(['.']);
355
+ await git.clean('f', ['-d']);
356
+ }
357
+ async gitCreateTag(dirPath, tagName, message, commit) {
358
+ const git = simpleGit(dirPath);
359
+ const args = ['tag'];
360
+ if (message) {
361
+ args.push('-a', tagName, '-m', message);
362
+ }
363
+ else {
364
+ args.push(tagName);
365
+ }
366
+ if (commit)
367
+ args.push(commit);
368
+ await git.raw(args);
369
+ }
370
+ async gitDeleteTag(dirPath, tagName) {
371
+ const git = simpleGit(dirPath);
372
+ await git.raw(['tag', '-d', tagName]);
373
+ }
374
+ async gitDiff(dirPath, file, staged = false) {
375
+ const git = simpleGit(dirPath);
376
+ const args = [];
377
+ if (staged)
378
+ args.push('--cached');
379
+ if (file)
380
+ args.push('--', file);
381
+ return await git.diff(args);
382
+ }
383
+ async getGitStatus(dirPath) {
384
+ const git = simpleGit(dirPath);
385
+ const status = await git.status();
386
+ return {
387
+ branch: status.current ?? '',
388
+ tracking: status.tracking ?? null,
389
+ ahead: status.ahead,
390
+ behind: status.behind,
391
+ files: status.files.map((f) => ({
392
+ path: f.path,
393
+ index: f.index ?? ' ',
394
+ working_dir: f.working_dir ?? ' ',
395
+ })),
396
+ };
397
+ }
398
+ }
399
+ export const worktreeManager = new WorktreeManager();
400
+ //# sourceMappingURL=worktree-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree-manager.js","sourceRoot":"","sources":["../../../src/server/services/worktree-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { WebSocket } from 'ws';
2
+ import type { WSEvent } from './events.js';
3
+ declare class Broadcaster {
4
+ private clients;
5
+ addClient(ws: WebSocket): void;
6
+ removeClient(ws: WebSocket): void;
7
+ broadcast(event: WSEvent): void;
8
+ getClientCount(): number;
9
+ }
10
+ export declare const broadcaster: Broadcaster;
11
+ export {};
12
+ //# sourceMappingURL=broadcaster.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broadcaster.d.ts","sourceRoot":"","sources":["../../../src/server/websocket/broadcaster.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,cAAM,WAAW;IACf,OAAO,CAAC,OAAO,CAA6B;IAE5C,SAAS,CAAC,EAAE,EAAE,SAAS,GAAG,IAAI;IAI9B,YAAY,CAAC,EAAE,EAAE,SAAS,GAAG,IAAI;IAIjC,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAS/B,cAAc,IAAI,MAAM;CAGzB;AAED,eAAO,MAAM,WAAW,aAAoB,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { WebSocket } from 'ws';
2
+ class Broadcaster {
3
+ clients = new Set();
4
+ addClient(ws) {
5
+ this.clients.add(ws);
6
+ }
7
+ removeClient(ws) {
8
+ this.clients.delete(ws);
9
+ }
10
+ broadcast(event) {
11
+ const data = JSON.stringify(event);
12
+ for (const client of this.clients) {
13
+ if (client.readyState === WebSocket.OPEN) {
14
+ client.send(data);
15
+ }
16
+ }
17
+ }
18
+ getClientCount() {
19
+ return this.clients.size;
20
+ }
21
+ }
22
+ export const broadcaster = new Broadcaster();
23
+ //# sourceMappingURL=broadcaster.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broadcaster.js","sourceRoot":"","sources":["../../../src/server/websocket/broadcaster.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAG/B,MAAM,WAAW;IACP,OAAO,GAAmB,IAAI,GAAG,EAAE,CAAC;IAE5C,SAAS,CAAC,EAAa;QACrB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACvB,CAAC;IAED,YAAY,CAAC,EAAa;QACxB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC1B,CAAC;IAED,SAAS,CAAC,KAAc;QACtB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACnC,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClC,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;gBACzC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpB,CAAC;QACH,CAAC;IACH,CAAC;IAED,cAAc;QACZ,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IAC3B,CAAC;CACF;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC"}
@@ -0,0 +1,94 @@
1
+ export type WSEvent = {
2
+ type: 'todo:status-changed';
3
+ todoId: string;
4
+ status: string;
5
+ mode?: string;
6
+ worktree_path?: string | null;
7
+ branch_name?: string | null;
8
+ } | {
9
+ type: 'todo:log';
10
+ todoId: string;
11
+ message: string;
12
+ logType: string;
13
+ } | {
14
+ type: 'project:status-changed';
15
+ projectId: string;
16
+ running: number;
17
+ completed: number;
18
+ total: number;
19
+ } | {
20
+ type: 'todo:commit';
21
+ todoId: string;
22
+ commitHash: string;
23
+ message: string;
24
+ } | {
25
+ type: 'pipeline:status-changed';
26
+ pipelineId: string;
27
+ status: string;
28
+ currentPhase: string | null;
29
+ } | {
30
+ type: 'pipeline:phase-changed';
31
+ pipelineId: string;
32
+ phaseType: string;
33
+ status: string;
34
+ } | {
35
+ type: 'pipeline:log';
36
+ pipelineId: string;
37
+ phaseType: string;
38
+ message: string;
39
+ logType: string;
40
+ } | {
41
+ type: 'pipeline:commit';
42
+ pipelineId: string;
43
+ phaseType: string;
44
+ commitHash: string;
45
+ message: string;
46
+ } | {
47
+ type: 'schedule:status-changed';
48
+ scheduleId: string;
49
+ isActive: boolean;
50
+ } | {
51
+ type: 'schedule:run-triggered';
52
+ scheduleId: string;
53
+ runId: string;
54
+ todoId: string;
55
+ } | {
56
+ type: 'schedule:run-skipped';
57
+ scheduleId: string;
58
+ runId: string;
59
+ reason: string;
60
+ } | {
61
+ type: 'todo:context-switch';
62
+ todoId: string;
63
+ fromCli: string;
64
+ toCli: string;
65
+ switchCount: number;
66
+ } | {
67
+ type: 'discussion:status-changed';
68
+ discussionId: string;
69
+ status: string;
70
+ currentRound: number;
71
+ currentAgentId: string | null;
72
+ } | {
73
+ type: 'discussion:message-changed';
74
+ discussionId: string;
75
+ messageId: string;
76
+ agentId: string;
77
+ agentName: string;
78
+ round: number;
79
+ status: string;
80
+ } | {
81
+ type: 'discussion:log';
82
+ discussionId: string;
83
+ messageId: string;
84
+ message: string;
85
+ logType: string;
86
+ agentName: string;
87
+ } | {
88
+ type: 'discussion:commit';
89
+ discussionId: string;
90
+ messageId: string;
91
+ commitHash: string;
92
+ message: string;
93
+ };
94
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../src/server/websocket/events.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../../src/server/websocket/events.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import type { Server } from 'http';
2
+ export declare function initWebSocket(server: Server): void;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/websocket/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAOnC,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAqFlD"}
@@ -0,0 +1,82 @@
1
+ import { WebSocketServer } from 'ws';
2
+ import { broadcaster } from './broadcaster.js';
3
+ import { sessionMiddleware } from '../middleware/auth.js';
4
+ import { claudeManager } from '../services/claude-manager.js';
5
+ import { getTodoById, createTaskLog } from '../db/queries.js';
6
+ export function initWebSocket(server) {
7
+ const wss = new WebSocketServer({ noServer: true });
8
+ // Handle upgrade manually to validate session auth
9
+ server.on('upgrade', (req, socket, head) => {
10
+ // Only handle /ws path
11
+ if (req.url !== '/ws') {
12
+ socket.destroy();
13
+ return;
14
+ }
15
+ // Validate Origin header to prevent cross-origin WebSocket hijacking
16
+ const origin = req.headers.origin;
17
+ const allowedOrigins = process.env.CORS_ORIGIN
18
+ ? process.env.CORS_ORIGIN.split(',').map(o => o.trim())
19
+ : ['http://localhost:5173', 'http://localhost:3000'];
20
+ if (origin && !allowedOrigins.includes(origin)) {
21
+ socket.write('HTTP/1.1 403 Forbidden\r\n\r\n');
22
+ socket.destroy();
23
+ return;
24
+ }
25
+ // Use the session middleware to parse the session cookie
26
+ // We create a minimal mock response to satisfy express-session
27
+ const res = Object.create(null);
28
+ res.end = () => { };
29
+ res.writeHead = () => { };
30
+ res.setHeader = () => res;
31
+ res.getHeader = () => undefined;
32
+ sessionMiddleware(req, res, () => {
33
+ const session = req.session;
34
+ if (!session || !session.authenticated) {
35
+ socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n');
36
+ socket.destroy();
37
+ return;
38
+ }
39
+ wss.handleUpgrade(req, socket, head, (ws) => {
40
+ wss.emit('connection', ws, req);
41
+ });
42
+ });
43
+ });
44
+ wss.on('connection', (ws) => {
45
+ broadcaster.addClient(ws);
46
+ ws.on('close', () => {
47
+ broadcaster.removeClient(ws);
48
+ });
49
+ ws.on('error', (err) => {
50
+ console.error('WebSocket error:', err);
51
+ broadcaster.removeClient(ws);
52
+ });
53
+ // Handle incoming messages (stdin for interactive mode)
54
+ ws.on('message', (raw) => {
55
+ try {
56
+ const msg = JSON.parse(raw.toString());
57
+ if (msg.type === 'todo:stdin' && msg.todoId && typeof msg.input === 'string') {
58
+ const todo = getTodoById(msg.todoId);
59
+ if (todo && todo.process_pid && todo.status === 'running') {
60
+ const written = claudeManager.writeToStdin(todo.process_pid, msg.input + '\n');
61
+ if (written) {
62
+ createTaskLog(msg.todoId, 'input', msg.input);
63
+ broadcaster.broadcast({
64
+ type: 'todo:log',
65
+ todoId: msg.todoId,
66
+ message: msg.input,
67
+ logType: 'input',
68
+ });
69
+ }
70
+ }
71
+ }
72
+ }
73
+ catch {
74
+ // Ignore malformed messages
75
+ }
76
+ });
77
+ // Send welcome message
78
+ ws.send(JSON.stringify({ type: 'connected', clientCount: broadcaster.getClientCount() }));
79
+ });
80
+ console.log('WebSocket server initialized on /ws');
81
+ }
82
+ //# sourceMappingURL=index.js.map