hjworktree-cli 2.0.0 → 2.2.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 (36) hide show
  1. package/.claude/settings.local.json +10 -0
  2. package/.context-snapshots/context-snapshot-20260106-180000.md +108 -0
  3. package/.context-snapshots/context-snapshot-20260106-235500.md +108 -0
  4. package/README.md +134 -0
  5. package/dist/server/routes/api.d.ts.map +1 -1
  6. package/dist/server/routes/api.js +45 -1
  7. package/dist/server/routes/api.js.map +1 -1
  8. package/dist/server/services/worktreeService.d.ts +23 -0
  9. package/dist/server/services/worktreeService.d.ts.map +1 -1
  10. package/dist/server/services/worktreeService.js +156 -14
  11. package/dist/server/services/worktreeService.js.map +1 -1
  12. package/dist/server/socketHandlers.d.ts.map +1 -1
  13. package/dist/server/socketHandlers.js +74 -1
  14. package/dist/server/socketHandlers.js.map +1 -1
  15. package/dist/shared/types/index.d.ts +36 -0
  16. package/dist/shared/types/index.d.ts.map +1 -1
  17. package/dist/web/assets/{index-C61yAbey.css → index-CsixHL-D.css} +1 -1
  18. package/dist/web/assets/index-D8dr9mJa.js +53 -0
  19. package/dist/web/assets/index-D8dr9mJa.js.map +1 -0
  20. package/dist/web/index.html +2 -2
  21. package/package.json +1 -1
  22. package/server/routes/api.ts +51 -2
  23. package/server/services/worktreeService.ts +181 -13
  24. package/server/socketHandlers.ts +91 -2
  25. package/shared/types/index.ts +45 -0
  26. package/web/src/App.tsx +3 -0
  27. package/web/src/components/Layout/LeftNavBar.tsx +290 -26
  28. package/web/src/components/Layout/MainLayout.tsx +2 -6
  29. package/web/src/components/Modals/AddWorktreeModal.tsx +87 -0
  30. package/web/src/components/Modals/ConfirmDeleteModal.tsx +114 -0
  31. package/web/src/components/Modals/ModalContainer.tsx +21 -0
  32. package/web/src/components/Terminal/TerminalPanel.tsx +32 -37
  33. package/web/src/stores/useAppStore.ts +200 -3
  34. package/web/src/styles/global.css +522 -0
  35. package/dist/web/assets/index-WEdVUKxb.js +0 -53
  36. package/dist/web/assets/index-WEdVUKxb.js.map +0 -1
@@ -1,6 +1,7 @@
1
1
  import { simpleGit } from 'simple-git';
2
2
  import path from 'path';
3
3
  import fs from 'fs/promises';
4
+ import { realpathSync, statSync } from 'fs';
4
5
  export class WorktreeService {
5
6
  git;
6
7
  rootDir;
@@ -9,20 +10,68 @@ export class WorktreeService {
9
10
  this.rootDir = cwd;
10
11
  this.git = simpleGit(cwd);
11
12
  }
13
+ /**
14
+ * Safely resolves a path to its real path, handling symlinks.
15
+ * Returns null if path cannot be resolved.
16
+ */
17
+ safeRealpath(targetPath) {
18
+ try {
19
+ return realpathSync(targetPath);
20
+ }
21
+ catch {
22
+ return null;
23
+ }
24
+ }
25
+ /**
26
+ * Checks if a path is a linked worktree (has .git file) vs main repo (has .git directory).
27
+ * Linked worktrees have a .git FILE that points to the main .git directory.
28
+ * Main repo has a .git DIRECTORY.
29
+ */
30
+ isLinkedWorktree(worktreePath) {
31
+ const gitPath = path.join(worktreePath, '.git');
32
+ try {
33
+ const stat = statSync(gitPath);
34
+ // .git is a directory = main repository
35
+ // .git is a file = linked worktree
36
+ return !stat.isDirectory();
37
+ }
38
+ catch {
39
+ return false;
40
+ }
41
+ }
42
+ /**
43
+ * Checks if the given path is the main repository.
44
+ */
45
+ isMainRepository(targetPath) {
46
+ const resolvedTarget = this.safeRealpath(targetPath);
47
+ const resolvedRoot = this.safeRealpath(this.rootDir);
48
+ if (!resolvedTarget || !resolvedRoot) {
49
+ // If we can't resolve paths, assume it might be main repo (fail safe)
50
+ return true;
51
+ }
52
+ return resolvedTarget === resolvedRoot;
53
+ }
12
54
  async listWorktrees() {
13
55
  const result = await this.git.raw(['worktree', 'list', '--porcelain']);
14
56
  const worktrees = [];
15
57
  const entries = result.trim().split('\n\n').filter(Boolean);
58
+ const resolvedRootDir = this.safeRealpath(this.rootDir);
16
59
  for (const entry of entries) {
17
60
  const lines = entry.split('\n');
18
61
  const worktreePath = lines.find((l) => l.startsWith('worktree '))?.replace('worktree ', '');
19
62
  const branchLine = lines.find((l) => l.startsWith('branch '));
20
63
  const branch = branchLine?.replace('branch refs/heads/', '');
21
64
  if (worktreePath) {
65
+ // Determine if this is the main worktree using realpath comparison
66
+ const resolvedWorktreePath = this.safeRealpath(worktreePath);
67
+ const isMainWorktree = resolvedWorktreePath !== null &&
68
+ resolvedRootDir !== null &&
69
+ resolvedWorktreePath === resolvedRootDir;
22
70
  worktrees.push({
23
71
  path: worktreePath,
24
72
  branch: branch || 'detached',
25
73
  name: path.basename(worktreePath),
74
+ isMainWorktree,
26
75
  });
27
76
  }
28
77
  }
@@ -60,6 +109,7 @@ export class WorktreeService {
60
109
  path: worktreePath,
61
110
  branch: newBranchName,
62
111
  name: worktreeName,
112
+ isMainWorktree: false, // Created worktrees are always linked, not main
63
113
  };
64
114
  }
65
115
  async createMultipleWorktrees(baseBranch, count) {
@@ -88,28 +138,58 @@ export class WorktreeService {
88
138
  }
89
139
  }
90
140
  async removeWorktree(worktreePath) {
141
+ // SECURITY GUARD 1: Use realpathSync for symlink resolution
142
+ const resolvedWorktreePath = this.safeRealpath(worktreePath);
143
+ const resolvedRootDir = this.safeRealpath(this.rootDir);
144
+ // If we cannot resolve paths, abort for safety
145
+ if (!resolvedWorktreePath) {
146
+ console.warn(`[SECURITY] Cannot resolve worktree path: ${worktreePath}. Aborting deletion.`);
147
+ return;
148
+ }
149
+ if (!resolvedRootDir) {
150
+ console.warn(`[SECURITY] Cannot resolve root directory path. Aborting deletion.`);
151
+ return;
152
+ }
153
+ // SECURITY GUARD 2: Check exact match with main repo
154
+ if (resolvedWorktreePath === resolvedRootDir) {
155
+ console.warn(`[SECURITY] Attempted to remove main repository: ${worktreePath}. Ignoring.`);
156
+ return;
157
+ }
158
+ // SECURITY GUARD 3: Check if path is inside main repo
159
+ if (resolvedWorktreePath.startsWith(resolvedRootDir + path.sep)) {
160
+ console.warn(`[SECURITY] Attempted to remove path inside main repository: ${worktreePath}. Ignoring.`);
161
+ return;
162
+ }
163
+ // SECURITY GUARD 4: Check if main repo is inside target path (catastrophic prevention)
164
+ if (resolvedRootDir.startsWith(resolvedWorktreePath + path.sep)) {
165
+ console.warn(`[SECURITY] Attempted to remove parent of main repository: ${worktreePath}. Ignoring.`);
166
+ return;
167
+ }
168
+ // SECURITY GUARD 5: Verify it's actually a linked worktree (has .git FILE, not directory)
169
+ const isLinked = this.isLinkedWorktree(worktreePath);
170
+ if (!isLinked) {
171
+ console.warn(`[SECURITY] Path is not a linked worktree (missing .git file or has .git directory): ${worktreePath}. Ignoring.`);
172
+ return;
173
+ }
91
174
  const branchName = path.basename(worktreePath);
175
+ // CRITICAL: Only use git worktree remove - NEVER use fs.rm() as fallback
92
176
  try {
93
- // 1. Force remove worktree
94
177
  await this.git.raw(['worktree', 'remove', worktreePath, '--force']);
95
178
  }
96
- catch {
97
- // 2. If worktree remove fails, try to remove directory manually
98
- try {
99
- await fs.rm(worktreePath, { recursive: true, force: true });
100
- }
101
- catch {
102
- // Ignore errors
103
- }
179
+ catch (error) {
180
+ // Log the error but DO NOT fall back to fs.rm
181
+ console.error(`[SECURITY] Failed to remove worktree via git: ${worktreePath}`, error);
182
+ // Propagate error instead of dangerous fallback
183
+ throw new Error(`Failed to remove worktree: ${error instanceof Error ? error.message : 'Unknown error'}`);
104
184
  }
105
- // 3. CRITICAL: Prune orphan worktree references
185
+ // Prune orphan worktree references
106
186
  try {
107
187
  await this.git.raw(['worktree', 'prune']);
108
188
  }
109
189
  catch {
110
- // Ignore prune errors
190
+ // Ignore prune errors - non-critical
111
191
  }
112
- // 4. Now we can safely delete the branch
192
+ // Delete the branch
113
193
  try {
114
194
  await this.git.branch(['-D', branchName]);
115
195
  }
@@ -120,8 +200,22 @@ export class WorktreeService {
120
200
  }
121
201
  async removeAllWorktrees() {
122
202
  const worktrees = await this.listWorktrees();
123
- // Filter out the main worktree (usually the first one / the main repo)
124
- const additionalWorktrees = worktrees.filter(wt => wt.path !== this.rootDir);
203
+ // Filter out the main worktree using the isMainWorktree flag and path comparison
204
+ const additionalWorktrees = worktrees.filter(wt => {
205
+ // Primary check: use isMainWorktree flag
206
+ if (wt.isMainWorktree) {
207
+ console.log(`[SECURITY] Skipping main worktree in removeAll: ${wt.path}`);
208
+ return false;
209
+ }
210
+ // Secondary check: realpath comparison as defense in depth
211
+ const resolvedPath = this.safeRealpath(wt.path);
212
+ const resolvedRoot = this.safeRealpath(this.rootDir);
213
+ if (resolvedPath && resolvedRoot && resolvedPath === resolvedRoot) {
214
+ console.warn(`[SECURITY] Detected main worktree via realpath (flag was false): ${wt.path}`);
215
+ return false;
216
+ }
217
+ return true;
218
+ });
125
219
  for (const worktree of additionalWorktrees) {
126
220
  try {
127
221
  await this.removeWorktree(worktree.path);
@@ -131,6 +225,54 @@ export class WorktreeService {
131
225
  }
132
226
  }
133
227
  }
228
+ async createSingleWorktree(baseBranch) {
229
+ // Find next available index for this branch
230
+ const existingWorktrees = await this.listWorktrees();
231
+ const branchWorktrees = existingWorktrees.filter(wt => wt.name.startsWith(`${baseBranch}-project-`));
232
+ // Find the highest index used
233
+ let maxIndex = 0;
234
+ for (const wt of branchWorktrees) {
235
+ const match = wt.name.match(/-project-(\d+)$/);
236
+ if (match) {
237
+ const index = parseInt(match[1], 10);
238
+ if (index > maxIndex)
239
+ maxIndex = index;
240
+ }
241
+ }
242
+ const nextIndex = maxIndex + 1;
243
+ return this.createWorktree(baseBranch, nextIndex);
244
+ }
245
+ async removeWorktreesByNames(names) {
246
+ const worktrees = await this.listWorktrees();
247
+ const results = {
248
+ deleted: [],
249
+ failed: [],
250
+ };
251
+ for (const name of names) {
252
+ const worktree = worktrees.find(wt => wt.name === name);
253
+ if (!worktree) {
254
+ results.failed.push({ name, error: 'Worktree not found' });
255
+ continue;
256
+ }
257
+ // SECURITY: Never delete main worktree
258
+ if (worktree.isMainWorktree) {
259
+ console.warn(`[SECURITY] Blocked attempt to delete main worktree by name: ${name}`);
260
+ results.failed.push({ name, error: 'Cannot delete main worktree' });
261
+ continue;
262
+ }
263
+ try {
264
+ await this.removeWorktree(worktree.path);
265
+ results.deleted.push(name);
266
+ }
267
+ catch (error) {
268
+ results.failed.push({
269
+ name,
270
+ error: error instanceof Error ? error.message : 'Unknown error',
271
+ });
272
+ }
273
+ }
274
+ return results;
275
+ }
134
276
  async cleanup() {
135
277
  // Remove all worktrees created in this session
136
278
  for (const worktreePath of this.createdWorktrees) {
@@ -1 +1 @@
1
- {"version":3,"file":"worktreeService.js","sourceRoot":"","sources":["../../../server/services/worktreeService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAa,MAAM,YAAY,CAAC;AAClD,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,aAAa,CAAC;AAG7B,MAAM,OAAO,eAAe;IAClB,GAAG,CAAY;IACf,OAAO,CAAS;IAChB,gBAAgB,GAAgB,IAAI,GAAG,EAAE,CAAC;IAElD,YAAY,MAAc,OAAO,CAAC,GAAG,EAAE;QACrC,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC;QACnB,IAAI,CAAC,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;QACvE,MAAM,SAAS,GAAe,EAAE,CAAC;QAEjC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAE5D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAChC,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,EAAE,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;YAC5F,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;YAC9D,MAAM,MAAM,GAAG,UAAU,EAAE,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;YAE7D,IAAI,YAAY,EAAE,CAAC;gBACjB,SAAS,CAAC,IAAI,CAAC;oBACb,IAAI,EAAE,YAAY;oBAClB,MAAM,EAAE,MAAM,IAAI,UAAU;oBAC5B,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;iBAClC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,UAAkB,EAAE,KAAa;QACpD,MAAM,YAAY,GAAG,GAAG,UAAU,YAAY,KAAK,EAAE,CAAC;QACtD,uDAAuD;QACvD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC,CAAC;QACzE,MAAM,aAAa,GAAG,YAAY,CAAC;QAEnC,oCAAoC;QACpC,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;YAC9B,2CAA2C;YAC3C,MAAM,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;QAC1C,CAAC;QAAC,MAAM,CAAC;YACP,yCAAyC;QAC3C,CAAC;QAED,iCAAiC;QACjC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;YACzC,IAAI,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;gBACzC,iCAAiC;gBACjC,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,sCAAsC;QACxC,CAAC;QAED,+DAA+D;QAC/D,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC;QAEvF,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAExC,OAAO;YACL,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,aAAa;YACrB,IAAI,EAAE,YAAY;SACnB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,uBAAuB,CAAC,UAAkB,EAAE,KAAa;QAC7D,MAAM,SAAS,GAAe,EAAE,CAAC;QACjC,MAAM,YAAY,GAAa,EAAE,CAAC;QAElC,IAAI,CAAC;YACH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;gBAChC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;gBAC1D,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACzB,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACnC,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,6CAA6C;YAC7C,OAAO,CAAC,KAAK,CAAC,6BAA6B,YAAY,CAAC,MAAM,GAAG,CAAC,mBAAmB,CAAC,CAAC;YAEvF,KAAK,MAAM,YAAY,IAAI,YAAY,EAAE,CAAC;gBACxC,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;gBAC1C,CAAC;gBAAC,OAAO,aAAa,EAAE,CAAC;oBACvB,OAAO,CAAC,KAAK,CAAC,gCAAgC,YAAY,EAAE,EAAE,aAAa,CAAC,CAAC;gBAC/E,CAAC;YACH,CAAC;YAED,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,YAAoB;QACvC,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QAE/C,IAAI,CAAC;YACH,2BAA2B;YAC3B,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC;QACtE,CAAC;QAAC,MAAM,CAAC;YACP,gEAAgE;YAChE,IAAI,CAAC;gBACH,MAAM,EAAE,CAAC,EAAE,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9D,CAAC;YAAC,MAAM,CAAC;gBACP,gBAAgB;YAClB,CAAC;QACH,CAAC;QAED,gDAAgD;QAChD,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;QAC5C,CAAC;QAAC,MAAM,CAAC;YACP,sBAAsB;QACxB,CAAC;QAED,yCAAyC;QACzC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC;QAC5C,CAAC;QAAC,MAAM,CAAC;YACP,wCAAwC;QAC1C,CAAC;QAED,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,kBAAkB;QACtB,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAE7C,uEAAuE;QACvE,MAAM,mBAAmB,GAAG,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,OAAO,CAAC,CAAC;QAE7E,KAAK,MAAM,QAAQ,IAAI,mBAAmB,EAAE,CAAC;YAC3C,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC3C,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,QAAQ,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC;YACtE,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAO;QACX,+CAA+C;QAC/C,KAAK,MAAM,YAAY,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACjD,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;YAC1C,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,+BAA+B,YAAY,EAAE,EAAE,KAAK,CAAC,CAAC;YACtE,CAAC;QACH,CAAC;QACD,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;IAChC,CAAC;IAED,mBAAmB;QACjB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC3C,CAAC;IAED,UAAU;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;CACF;AAED,qBAAqB;AACrB,IAAI,uBAAuB,GAA2B,IAAI,CAAC;AAE3D,MAAM,UAAU,kBAAkB,CAAC,GAAY;IAC7C,IAAI,CAAC,uBAAuB,IAAI,CAAC,GAAG,IAAI,uBAAuB,CAAC,UAAU,EAAE,KAAK,GAAG,CAAC,EAAE,CAAC;QACtF,uBAAuB,GAAG,IAAI,eAAe,CAAC,GAAG,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,uBAAuB,CAAC;AACjC,CAAC"}
1
+ {"version":3,"file":"worktreeService.js","sourceRoot":"","sources":["../../../server/services/worktreeService.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"socketHandlers.d.ts","sourceRoot":"","sources":["../../server/socketHandlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAU,MAAM,WAAW,CAAC;AA8B3C,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,QAsH1D;AAED,wBAAgB,eAAe,IAAI,IAAI,CAMtC"}
1
+ {"version":3,"file":"socketHandlers.d.ts","sourceRoot":"","sources":["../../server/socketHandlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAU,MAAM,WAAW,CAAC;AAwG3C,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,QAqI1D;AAED,wBAAgB,eAAe,IAAI,IAAI,CAMtC"}
@@ -1,5 +1,66 @@
1
1
  import * as pty from 'node-pty';
2
2
  import { AI_AGENTS } from '../shared/constants.js';
3
+ import fs from 'fs';
4
+ import { promisify } from 'util';
5
+ const access = promisify(fs.access);
6
+ // Validation utilities
7
+ async function validatePath(pathToCheck) {
8
+ try {
9
+ await access(pathToCheck, fs.constants.R_OK | fs.constants.X_OK);
10
+ return { valid: true };
11
+ }
12
+ catch (error) {
13
+ return {
14
+ valid: false,
15
+ error: error instanceof Error ? error.message : 'Path not accessible'
16
+ };
17
+ }
18
+ }
19
+ async function validateShell(shell) {
20
+ if (process.platform === 'win32') {
21
+ return { valid: true };
22
+ }
23
+ try {
24
+ await access(shell, fs.constants.X_OK);
25
+ return { valid: true };
26
+ }
27
+ catch (error) {
28
+ return {
29
+ valid: false,
30
+ error: `Shell not executable: ${shell}`
31
+ };
32
+ }
33
+ }
34
+ // PTY spawn with retry logic
35
+ async function spawnWithRetry(shell, args, options, maxRetries = 3) {
36
+ let lastError = null;
37
+ for (let attempt = 0; attempt < maxRetries; attempt++) {
38
+ try {
39
+ const ptyProcess = pty.spawn(shell, args, options);
40
+ return ptyProcess;
41
+ }
42
+ catch (error) {
43
+ lastError = error instanceof Error ? error : new Error(String(error));
44
+ console.error(`[PTY] Spawn attempt ${attempt + 1}/${maxRetries} failed:`, lastError.message);
45
+ if (attempt < maxRetries - 1) {
46
+ const delay = Math.pow(2, attempt) * 100;
47
+ await new Promise(resolve => setTimeout(resolve, delay));
48
+ }
49
+ }
50
+ }
51
+ throw lastError || new Error('Failed to spawn PTY after retries');
52
+ }
53
+ // Spawn interval control to prevent resource contention
54
+ let lastSpawnTime = 0;
55
+ const MIN_SPAWN_INTERVAL = 150;
56
+ async function waitForSpawnInterval() {
57
+ const now = Date.now();
58
+ const elapsed = now - lastSpawnTime;
59
+ if (elapsed < MIN_SPAWN_INTERVAL) {
60
+ await new Promise(resolve => setTimeout(resolve, MIN_SPAWN_INTERVAL - elapsed));
61
+ }
62
+ lastSpawnTime = Date.now();
63
+ }
3
64
  const sessions = new Map();
4
65
  function getAgentCommand(agentType) {
5
66
  const agent = AI_AGENTS.find(a => a.id === agentType);
@@ -18,7 +79,19 @@ export function setupSocketHandlers(io, cwd) {
18
79
  try {
19
80
  const shell = getShell();
20
81
  const agentCommand = getAgentCommand(agentType);
21
- const ptyProcess = pty.spawn(shell, [], {
82
+ // Validate path before spawning
83
+ const pathValidation = await validatePath(worktreePath);
84
+ if (!pathValidation.valid) {
85
+ throw new Error(`Invalid worktree path: ${pathValidation.error}`);
86
+ }
87
+ // Validate shell before spawning
88
+ const shellValidation = await validateShell(shell);
89
+ if (!shellValidation.valid) {
90
+ throw new Error(`Invalid shell: ${shellValidation.error}`);
91
+ }
92
+ // Wait for spawn interval to prevent resource contention
93
+ await waitForSpawnInterval();
94
+ const ptyProcess = await spawnWithRetry(shell, [], {
22
95
  name: 'xterm-256color',
23
96
  cols: 120,
24
97
  rows: 30,
@@ -1 +1 @@
1
- {"version":3,"file":"socketHandlers.js","sourceRoot":"","sources":["../../server/socketHandlers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"socketHandlers.js","sourceRoot":"","sources":["../../server/socketHandlers.ts"],"names":[],"mappings":"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"}
@@ -34,6 +34,7 @@ export interface Worktree {
34
34
  path: string;
35
35
  branch: string;
36
36
  name: string;
37
+ isMainWorktree: boolean;
37
38
  }
38
39
  export interface TerminalCreateData {
39
40
  sessionId: string;
@@ -64,4 +65,39 @@ export interface CreateWorktreesRequest {
64
65
  export interface CreateWorktreesResponse {
65
66
  worktrees: Worktree[];
66
67
  }
68
+ export interface CreateSingleWorktreeRequest {
69
+ branch: string;
70
+ agentType: AgentId;
71
+ }
72
+ export interface CreateSingleWorktreeResponse {
73
+ worktree: Worktree;
74
+ }
75
+ export interface BatchDeleteRequest {
76
+ names: string[];
77
+ }
78
+ export interface BatchDeleteResponse {
79
+ success: boolean;
80
+ deleted: string[];
81
+ failed: {
82
+ name: string;
83
+ error: string;
84
+ }[];
85
+ }
86
+ export interface WorktreeSession extends TerminalInfo {
87
+ id: string;
88
+ createdAt: number;
89
+ }
90
+ export interface SessionGroup {
91
+ branchName: string;
92
+ sessions: WorktreeSession[];
93
+ isCollapsed: boolean;
94
+ }
95
+ export type ModalType = 'addWorktree' | 'confirmDelete' | null;
96
+ export interface ModalState {
97
+ type: ModalType;
98
+ data?: {
99
+ sessionIds?: string[];
100
+ branchName?: string;
101
+ };
102
+ }
67
103
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../shared/types/index.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,CAAC;AAGzE,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,CAAC;AAG7D,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,cAAc,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAGD,eAAO,MAAM,UAAU,EAAE,cAAc,EAA+C,CAAC;AAGvF,MAAM,MAAM,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEpD,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACrB;AAGD,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAGD,MAAM,MAAM,WAAW,GAAG,cAAc,GAAG,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAE1F,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,WAAW,CAAC;CACrB;AAGD,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAGD,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;CACnB;AAGD,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,QAAQ,EAAE,CAAC;CACvB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../shared/types/index.ts"],"names":[],"mappings":"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"}
@@ -29,4 +29,4 @@
29
29
  * The original design remains. The terminal itself
30
30
  * has been extended to include xterm CSI codes, among
31
31
  * other features.
32
- */.xterm{cursor:text;position:relative;user-select:none;-ms-user-select:none;-webkit-user-select:none}.xterm.focus,.xterm:focus{outline:none}.xterm .xterm-helpers{position:absolute;top:0;z-index:5}.xterm .xterm-helper-textarea{padding:0;border:0;margin:0;position:absolute;opacity:0;left:-9999em;top:0;width:0;height:0;z-index:-5;white-space:nowrap;overflow:hidden;resize:none}.xterm .composition-view{background:#000;color:#fff;display:none;position:absolute;white-space:nowrap;z-index:1}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{background-color:#000;overflow-y:scroll;cursor:default;position:absolute;right:0;left:0;top:0;bottom:0}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;left:0;top:0}.xterm .xterm-scroll-area{visibility:hidden}.xterm-char-measure-element{display:inline-block;visibility:hidden;position:absolute;top:0;left:-9999em;line-height:normal}.xterm.enable-mouse-events{cursor:default}.xterm.xterm-cursor-pointer,.xterm .xterm-cursor-pointer{cursor:pointer}.xterm.column-select.focus{cursor:crosshair}.xterm .xterm-accessibility:not(.debug),.xterm .xterm-message{position:absolute;left:0;top:0;bottom:0;right:0;z-index:10;color:transparent;pointer-events:none}.xterm .xterm-accessibility-tree:not(.debug) *::selection{color:transparent}.xterm .xterm-accessibility-tree{-webkit-user-select:text;user-select:text;white-space:pre}.xterm .live-region{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}.xterm-dim{opacity:1!important}.xterm-underline-1{text-decoration:underline}.xterm-underline-2{text-decoration:double underline}.xterm-underline-3{text-decoration:wavy underline}.xterm-underline-4{text-decoration:dotted underline}.xterm-underline-5{text-decoration:dashed underline}.xterm-overline{text-decoration:overline}.xterm-overline.xterm-underline-1{text-decoration:overline underline}.xterm-overline.xterm-underline-2{text-decoration:overline double underline}.xterm-overline.xterm-underline-3{text-decoration:overline wavy underline}.xterm-overline.xterm-underline-4{text-decoration:overline dotted underline}.xterm-overline.xterm-underline-5{text-decoration:overline dashed underline}.xterm-strikethrough{text-decoration:line-through}.xterm-screen .xterm-decoration-container .xterm-decoration{z-index:6;position:absolute}.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer{z-index:7}.xterm-decoration-overview-ruler{z-index:8;position:absolute;top:0;right:0;pointer-events:none}.xterm-decoration-top{z-index:2;position:relative}*{margin:0;padding:0;box-sizing:border-box}:root{--bg-primary: #0d1117;--bg-secondary: #161b22;--bg-tertiary: #21262d;--border-color: #30363d;--text-primary: #c9d1d9;--text-secondary: #8b949e;--text-muted: #6e7681;--accent-blue: #58a6ff;--accent-green: #3fb950;--accent-yellow: #d29922;--accent-red: #f85149;--accent-purple: #a371f7}html,body,#root{height:100%;width:100%}body{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;background-color:var(--bg-primary);color:var(--text-primary);line-height:1.5}.app{display:flex;flex-direction:column;height:100vh;overflow:hidden}.header{display:flex;align-items:center;justify-content:space-between;padding:12px 24px;background-color:var(--bg-secondary);border-bottom:1px solid var(--border-color)}.header h1{font-size:18px;font-weight:600;color:var(--text-primary)}.header .project-info{display:flex;align-items:center;gap:12px;color:var(--text-secondary);font-size:13px}.header .project-info .branch{display:flex;align-items:center;gap:4px;color:var(--accent-green)}.main-content{flex:1;display:flex;flex-direction:column;overflow:hidden}.setup-panel{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px;gap:32px}.setup-panel h2{font-size:24px;font-weight:600;margin-bottom:8px}.setup-panel p{color:var(--text-secondary);font-size:14px}.setup-section{width:100%;max-width:500px;background:var(--bg-secondary);border:1px solid var(--border-color);border-radius:8px;padding:20px}.setup-section label{display:block;font-size:14px;font-weight:500;margin-bottom:8px;color:var(--text-primary)}.setup-section select,.setup-section input{width:100%;padding:10px 12px;border:1px solid var(--border-color);border-radius:6px;background-color:var(--bg-tertiary);color:var(--text-primary);font-size:14px;font-family:inherit}.setup-section select:focus,.setup-section input:focus{outline:none;border-color:var(--accent-blue)}.setup-section .counter{display:flex;align-items:center;gap:16px}.setup-section .counter button{width:40px;height:40px;border:1px solid var(--border-color);border-radius:6px;background-color:var(--bg-tertiary);color:var(--text-primary);font-size:20px;cursor:pointer;transition:all .2s}.setup-section .counter button:hover{background-color:var(--bg-primary);border-color:var(--accent-blue)}.setup-section .counter button:disabled{opacity:.5;cursor:not-allowed}.setup-section .counter span{font-size:24px;font-weight:600;min-width:60px;text-align:center}.agent-cards{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}.agent-card{padding:16px;border:2px solid var(--border-color);border-radius:8px;background-color:var(--bg-tertiary);cursor:pointer;transition:all .2s}.agent-card:hover{border-color:var(--accent-blue)}.agent-card.selected{border-color:var(--accent-blue);background-color:#58a6ff1a}.agent-card h4{font-size:14px;font-weight:600;margin-bottom:4px}.agent-card p{font-size:12px;color:var(--text-muted)}.execute-button{padding:14px 48px;background-color:var(--accent-green);color:var(--bg-primary);border:none;border-radius:8px;font-size:16px;font-weight:600;cursor:pointer;transition:all .2s}.execute-button:hover{filter:brightness(1.1)}.execute-button:disabled{background-color:var(--bg-tertiary);color:var(--text-muted);cursor:not-allowed}.terminal-panel{display:flex;flex-direction:column;height:100%;overflow:hidden}.terminal-tabs{display:flex;align-items:center;gap:4px;padding:8px 16px;background-color:var(--bg-secondary);border-bottom:1px solid var(--border-color);overflow-x:auto}.terminal-tab{display:flex;align-items:center;gap:8px;padding:8px 16px;background-color:transparent;border:1px solid transparent;border-radius:6px;color:var(--text-secondary);font-size:13px;cursor:pointer;transition:all .2s;white-space:nowrap}.terminal-tab:hover{background-color:var(--bg-tertiary)}.terminal-tab.active{background-color:var(--bg-tertiary);border-color:var(--border-color);color:var(--text-primary)}.terminal-tab .status{width:8px;height:8px;border-radius:50%}.terminal-tab .status.running{background-color:var(--accent-green)}.terminal-tab .status.initializing{background-color:var(--accent-yellow)}.terminal-tab .status.stopped{background-color:var(--text-muted)}.terminal-tab .status.error{background-color:var(--accent-red)}.terminal-tab .close-btn{padding:2px 4px;background:transparent;border:none;color:var(--text-muted);cursor:pointer;border-radius:4px;line-height:1}.terminal-tab .close-btn:hover{background-color:var(--bg-primary);color:var(--accent-red)}.terminal-actions{display:flex;align-items:center;gap:8px;margin-left:auto;padding-left:16px}.terminal-actions button{padding:6px 12px;background-color:transparent;border:1px solid var(--border-color);border-radius:6px;color:var(--text-secondary);font-size:12px;cursor:pointer;transition:all .2s}.terminal-actions button:hover{background-color:var(--bg-tertiary);color:var(--text-primary)}.terminal-actions button.danger:hover{border-color:var(--accent-red);color:var(--accent-red)}.terminal-container{flex:1;position:relative;overflow:hidden}.terminal-wrapper{position:absolute;top:0;left:0;right:0;bottom:0;padding:8px}.terminal-wrapper.hidden{visibility:hidden}.terminal{height:100%;width:100%}.loading-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background-color:#0d1117e6;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;z-index:1000}.loading-spinner{width:48px;height:48px;border:3px solid var(--border-color);border-top-color:var(--accent-blue);border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.loading-overlay p{color:var(--text-secondary);font-size:14px}.connection-status{position:fixed;bottom:16px;right:16px;display:flex;align-items:center;gap:8px;padding:8px 12px;background-color:var(--bg-secondary);border:1px solid var(--border-color);border-radius:6px;font-size:12px;color:var(--text-secondary)}.connection-status .dot{width:8px;height:8px;border-radius:50%}.connection-status .dot.connected{background-color:var(--accent-green)}.connection-status .dot.disconnected{background-color:var(--accent-red)}.error-banner{padding:12px 16px;background-color:#f851491a;border:1px solid var(--accent-red);border-radius:6px;color:var(--accent-red);font-size:14px;text-align:center}.main-layout{display:flex;flex:1;overflow:hidden}.main-content-area{flex:1;display:flex;flex-direction:column;overflow:hidden}.main-content-area.with-lnb{margin-left:0}.main-content-area.full-width{width:100%}.left-nav-bar{width:260px;background-color:var(--bg-secondary);border-right:1px solid var(--border-color);display:flex;flex-direction:column;flex-shrink:0}.lnb-header{padding:20px;border-bottom:1px solid var(--border-color);font-size:14px;font-weight:600;color:var(--text-secondary);text-transform:uppercase;letter-spacing:.5px}.lnb-steps{padding:16px;display:flex;flex-direction:column;gap:8px}.lnb-step{display:flex;align-items:center;gap:12px;padding:14px 16px;background:transparent;border:1px solid transparent;border-radius:8px;text-align:left;cursor:pointer;transition:all .2s ease;width:100%;font-family:inherit}.lnb-step:hover:not(:disabled){background-color:var(--bg-tertiary)}.lnb-step:disabled{cursor:not-allowed;opacity:.5}.step-number{width:28px;height:28px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:600;flex-shrink:0;transition:all .2s ease}.lnb-step.pending .step-number{background-color:var(--bg-tertiary);color:var(--text-muted);border:2px solid var(--border-color)}.lnb-step.pending .step-label{color:var(--text-muted)}.lnb-step.current{background-color:#58a6ff1a;border-color:var(--accent-blue)}.lnb-step.current .step-number{background-color:var(--accent-blue);color:var(--bg-primary)}.lnb-step.current .step-label{color:var(--text-primary);font-weight:500}.lnb-step.completed .step-number{background-color:var(--accent-green);color:var(--bg-primary)}.lnb-step.completed .step-label{color:var(--text-primary)}.step-label{font-size:14px;flex:1}.step-container{flex:1;display:flex;flex-direction:column;padding:40px;max-width:600px;margin:0 auto;width:100%}.step-header{text-align:center;margin-bottom:32px}.step-header h2{font-size:24px;font-weight:600;margin-bottom:8px;color:var(--text-primary)}.step-header p{color:var(--text-secondary);font-size:14px}.step-content{flex:1;display:flex;flex-direction:column;gap:24px}.step-navigation{display:flex;justify-content:space-between;padding-top:32px;margin-top:auto;border-top:1px solid var(--border-color)}.nav-button{padding:12px 32px;border-radius:8px;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s ease;font-family:inherit}.nav-button.prev{background:transparent;border:1px solid var(--border-color);color:var(--text-secondary)}.nav-button.prev:hover:not(:disabled){background-color:var(--bg-tertiary);color:var(--text-primary)}.nav-button.prev:disabled{opacity:.3;cursor:not-allowed}.nav-button.next{background-color:var(--accent-blue);border:none;color:#fff}.nav-button.next:hover:not(:disabled){filter:brightness(1.1)}.nav-button.next:disabled{background-color:var(--bg-tertiary);color:var(--text-muted);cursor:not-allowed}.execution-summary{background-color:var(--bg-secondary);border:1px solid var(--border-color);border-radius:8px;padding:20px}.execution-summary h4{font-size:14px;font-weight:600;margin-bottom:16px;color:var(--text-primary);padding-bottom:12px;border-bottom:1px solid var(--border-color)}.summary-item{display:flex;justify-content:space-between;align-items:center;padding:8px 0}.summary-label{font-size:13px;color:var(--text-secondary)}.summary-value{font-size:13px;font-weight:500;color:var(--text-primary)}
32
+ */.xterm{cursor:text;position:relative;user-select:none;-ms-user-select:none;-webkit-user-select:none}.xterm.focus,.xterm:focus{outline:none}.xterm .xterm-helpers{position:absolute;top:0;z-index:5}.xterm .xterm-helper-textarea{padding:0;border:0;margin:0;position:absolute;opacity:0;left:-9999em;top:0;width:0;height:0;z-index:-5;white-space:nowrap;overflow:hidden;resize:none}.xterm .composition-view{background:#000;color:#fff;display:none;position:absolute;white-space:nowrap;z-index:1}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{background-color:#000;overflow-y:scroll;cursor:default;position:absolute;right:0;left:0;top:0;bottom:0}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;left:0;top:0}.xterm .xterm-scroll-area{visibility:hidden}.xterm-char-measure-element{display:inline-block;visibility:hidden;position:absolute;top:0;left:-9999em;line-height:normal}.xterm.enable-mouse-events{cursor:default}.xterm.xterm-cursor-pointer,.xterm .xterm-cursor-pointer{cursor:pointer}.xterm.column-select.focus{cursor:crosshair}.xterm .xterm-accessibility:not(.debug),.xterm .xterm-message{position:absolute;left:0;top:0;bottom:0;right:0;z-index:10;color:transparent;pointer-events:none}.xterm .xterm-accessibility-tree:not(.debug) *::selection{color:transparent}.xterm .xterm-accessibility-tree{-webkit-user-select:text;user-select:text;white-space:pre}.xterm .live-region{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}.xterm-dim{opacity:1!important}.xterm-underline-1{text-decoration:underline}.xterm-underline-2{text-decoration:double underline}.xterm-underline-3{text-decoration:wavy underline}.xterm-underline-4{text-decoration:dotted underline}.xterm-underline-5{text-decoration:dashed underline}.xterm-overline{text-decoration:overline}.xterm-overline.xterm-underline-1{text-decoration:overline underline}.xterm-overline.xterm-underline-2{text-decoration:overline double underline}.xterm-overline.xterm-underline-3{text-decoration:overline wavy underline}.xterm-overline.xterm-underline-4{text-decoration:overline dotted underline}.xterm-overline.xterm-underline-5{text-decoration:overline dashed underline}.xterm-strikethrough{text-decoration:line-through}.xterm-screen .xterm-decoration-container .xterm-decoration{z-index:6;position:absolute}.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer{z-index:7}.xterm-decoration-overview-ruler{z-index:8;position:absolute;top:0;right:0;pointer-events:none}.xterm-decoration-top{z-index:2;position:relative}*{margin:0;padding:0;box-sizing:border-box}:root{--bg-primary: #0d1117;--bg-secondary: #161b22;--bg-tertiary: #21262d;--border-color: #30363d;--text-primary: #c9d1d9;--text-secondary: #8b949e;--text-muted: #6e7681;--accent-blue: #58a6ff;--accent-green: #3fb950;--accent-yellow: #d29922;--accent-red: #f85149;--accent-purple: #a371f7}html,body,#root{height:100%;width:100%}body{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;background-color:var(--bg-primary);color:var(--text-primary);line-height:1.5}.app{display:flex;flex-direction:column;height:100vh;overflow:hidden}.header{display:flex;align-items:center;justify-content:space-between;padding:12px 24px;background-color:var(--bg-secondary);border-bottom:1px solid var(--border-color)}.header h1{font-size:18px;font-weight:600;color:var(--text-primary)}.header .project-info{display:flex;align-items:center;gap:12px;color:var(--text-secondary);font-size:13px}.header .project-info .branch{display:flex;align-items:center;gap:4px;color:var(--accent-green)}.main-content{flex:1;display:flex;flex-direction:column;overflow:hidden}.setup-panel{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px;gap:32px}.setup-panel h2{font-size:24px;font-weight:600;margin-bottom:8px}.setup-panel p{color:var(--text-secondary);font-size:14px}.setup-section{width:100%;max-width:500px;background:var(--bg-secondary);border:1px solid var(--border-color);border-radius:8px;padding:20px}.setup-section label{display:block;font-size:14px;font-weight:500;margin-bottom:8px;color:var(--text-primary)}.setup-section select,.setup-section input{width:100%;padding:10px 12px;border:1px solid var(--border-color);border-radius:6px;background-color:var(--bg-tertiary);color:var(--text-primary);font-size:14px;font-family:inherit}.setup-section select:focus,.setup-section input:focus{outline:none;border-color:var(--accent-blue)}.setup-section .counter{display:flex;align-items:center;gap:16px}.setup-section .counter button{width:40px;height:40px;border:1px solid var(--border-color);border-radius:6px;background-color:var(--bg-tertiary);color:var(--text-primary);font-size:20px;cursor:pointer;transition:all .2s}.setup-section .counter button:hover{background-color:var(--bg-primary);border-color:var(--accent-blue)}.setup-section .counter button:disabled{opacity:.5;cursor:not-allowed}.setup-section .counter span{font-size:24px;font-weight:600;min-width:60px;text-align:center}.agent-cards{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}.agent-card{padding:16px;border:2px solid var(--border-color);border-radius:8px;background-color:var(--bg-tertiary);cursor:pointer;transition:all .2s}.agent-card:hover{border-color:var(--accent-blue)}.agent-card.selected{border-color:var(--accent-blue);background-color:#58a6ff1a}.agent-card h4{font-size:14px;font-weight:600;margin-bottom:4px}.agent-card p{font-size:12px;color:var(--text-muted)}.execute-button{padding:14px 48px;background-color:var(--accent-green);color:var(--bg-primary);border:none;border-radius:8px;font-size:16px;font-weight:600;cursor:pointer;transition:all .2s}.execute-button:hover{filter:brightness(1.1)}.execute-button:disabled{background-color:var(--bg-tertiary);color:var(--text-muted);cursor:not-allowed}.terminal-panel{display:flex;flex-direction:column;height:100%;overflow:hidden}.terminal-tabs{display:flex;align-items:center;gap:4px;padding:8px 16px;background-color:var(--bg-secondary);border-bottom:1px solid var(--border-color);overflow-x:auto}.terminal-tab{display:flex;align-items:center;gap:8px;padding:8px 16px;background-color:transparent;border:1px solid transparent;border-radius:6px;color:var(--text-secondary);font-size:13px;cursor:pointer;transition:all .2s;white-space:nowrap}.terminal-tab:hover{background-color:var(--bg-tertiary)}.terminal-tab.active{background-color:var(--bg-tertiary);border-color:var(--border-color);color:var(--text-primary)}.terminal-tab .status{width:8px;height:8px;border-radius:50%}.terminal-tab .status.running{background-color:var(--accent-green)}.terminal-tab .status.initializing{background-color:var(--accent-yellow)}.terminal-tab .status.stopped{background-color:var(--text-muted)}.terminal-tab .status.error{background-color:var(--accent-red)}.terminal-tab .close-btn{padding:2px 4px;background:transparent;border:none;color:var(--text-muted);cursor:pointer;border-radius:4px;line-height:1}.terminal-tab .close-btn:hover{background-color:var(--bg-primary);color:var(--accent-red)}.terminal-actions{display:flex;align-items:center;gap:8px;margin-left:auto;padding-left:16px}.terminal-actions button{padding:6px 12px;background-color:transparent;border:1px solid var(--border-color);border-radius:6px;color:var(--text-secondary);font-size:12px;cursor:pointer;transition:all .2s}.terminal-actions button:hover{background-color:var(--bg-tertiary);color:var(--text-primary)}.terminal-actions button.danger:hover{border-color:var(--accent-red);color:var(--accent-red)}.terminal-container{flex:1;position:relative;overflow:hidden}.terminal-wrapper{position:absolute;top:0;left:0;right:0;bottom:0;padding:8px}.terminal-wrapper.hidden{visibility:hidden}.terminal{height:100%;width:100%}.loading-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background-color:#0d1117e6;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;z-index:1000}.loading-spinner{width:48px;height:48px;border:3px solid var(--border-color);border-top-color:var(--accent-blue);border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.loading-overlay p{color:var(--text-secondary);font-size:14px}.connection-status{position:fixed;bottom:16px;right:16px;display:flex;align-items:center;gap:8px;padding:8px 12px;background-color:var(--bg-secondary);border:1px solid var(--border-color);border-radius:6px;font-size:12px;color:var(--text-secondary)}.connection-status .dot{width:8px;height:8px;border-radius:50%}.connection-status .dot.connected{background-color:var(--accent-green)}.connection-status .dot.disconnected{background-color:var(--accent-red)}.error-banner{padding:12px 16px;background-color:#f851491a;border:1px solid var(--accent-red);border-radius:6px;color:var(--accent-red);font-size:14px;text-align:center}.main-layout{display:flex;flex:1;overflow:hidden}.main-content-area{flex:1;display:flex;flex-direction:column;overflow:hidden}.main-content-area.with-lnb{margin-left:0}.main-content-area.full-width{width:100%}.left-nav-bar{width:260px;background-color:var(--bg-secondary);border-right:1px solid var(--border-color);display:flex;flex-direction:column;flex-shrink:0}.lnb-header{padding:20px;border-bottom:1px solid var(--border-color);font-size:14px;font-weight:600;color:var(--text-secondary);text-transform:uppercase;letter-spacing:.5px}.lnb-steps{padding:16px;display:flex;flex-direction:column;gap:8px}.lnb-step{display:flex;align-items:center;gap:12px;padding:14px 16px;background:transparent;border:1px solid transparent;border-radius:8px;text-align:left;cursor:pointer;transition:all .2s ease;width:100%;font-family:inherit}.lnb-step:hover:not(:disabled){background-color:var(--bg-tertiary)}.lnb-step:disabled{cursor:not-allowed;opacity:.5}.step-number{width:28px;height:28px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:600;flex-shrink:0;transition:all .2s ease}.lnb-step.pending .step-number{background-color:var(--bg-tertiary);color:var(--text-muted);border:2px solid var(--border-color)}.lnb-step.pending .step-label{color:var(--text-muted)}.lnb-step.current{background-color:#58a6ff1a;border-color:var(--accent-blue)}.lnb-step.current .step-number{background-color:var(--accent-blue);color:var(--bg-primary)}.lnb-step.current .step-label{color:var(--text-primary);font-weight:500}.lnb-step.completed .step-number{background-color:var(--accent-green);color:var(--bg-primary)}.lnb-step.completed .step-label{color:var(--text-primary)}.step-label{font-size:14px;flex:1}.step-container{flex:1;display:flex;flex-direction:column;padding:40px;max-width:600px;margin:0 auto;width:100%}.step-header{text-align:center;margin-bottom:32px}.step-header h2{font-size:24px;font-weight:600;margin-bottom:8px;color:var(--text-primary)}.step-header p{color:var(--text-secondary);font-size:14px}.step-content{flex:1;display:flex;flex-direction:column;gap:24px}.step-navigation{display:flex;justify-content:space-between;padding-top:32px;margin-top:auto;border-top:1px solid var(--border-color)}.nav-button{padding:12px 32px;border-radius:8px;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s ease;font-family:inherit}.nav-button.prev{background:transparent;border:1px solid var(--border-color);color:var(--text-secondary)}.nav-button.prev:hover:not(:disabled){background-color:var(--bg-tertiary);color:var(--text-primary)}.nav-button.prev:disabled{opacity:.3;cursor:not-allowed}.nav-button.next{background-color:var(--accent-blue);border:none;color:#fff}.nav-button.next:hover:not(:disabled){filter:brightness(1.1)}.nav-button.next:disabled{background-color:var(--bg-tertiary);color:var(--text-muted);cursor:not-allowed}.execution-summary{background-color:var(--bg-secondary);border:1px solid var(--border-color);border-radius:8px;padding:20px}.execution-summary h4{font-size:14px;font-weight:600;margin-bottom:16px;color:var(--text-primary);padding-bottom:12px;border-bottom:1px solid var(--border-color)}.summary-item{display:flex;justify-content:space-between;align-items:center;padding:8px 0}.summary-label{font-size:13px;color:var(--text-secondary)}.summary-value{font-size:13px;font-weight:500;color:var(--text-primary)}.left-nav-bar{width:280px;background-color:var(--bg-secondary);border-right:1px solid var(--border-color);display:flex;flex-direction:column;flex-shrink:0;overflow-y:auto}.lnb-section{border-bottom:1px solid var(--border-color)}.lnb-section-header{display:flex;align-items:center;justify-content:space-between;padding:16px;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .2s}.lnb-section-header:hover{background-color:var(--bg-tertiary)}.section-title{font-size:11px;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:.5px}.collapse-icon{font-size:14px;color:var(--text-muted)}.sessions-section{flex:1;display:flex;flex-direction:column;min-height:0}.session-count{font-size:11px;background-color:var(--bg-tertiary);color:var(--text-secondary);padding:2px 8px;border-radius:10px;margin-left:8px}.session-list{flex:1;overflow-y:auto;padding:8px}.session-group{margin-bottom:8px}.session-group-header{display:flex;align-items:center;gap:8px;padding:8px 12px;cursor:pointer;border-radius:6px;transition:background-color .2s}.session-group-header:hover{background-color:var(--bg-tertiary)}.group-collapse-icon{font-size:10px;color:var(--text-muted)}.group-name{font-size:12px;font-weight:500;color:var(--text-secondary);flex:1}.group-count{font-size:11px;color:var(--text-muted)}.session-group-items{padding-left:12px}.session-item{display:flex;align-items:center;gap:8px;padding:8px 12px;cursor:pointer;border-radius:6px;margin:2px 0;border:1px solid transparent;transition:all .2s}.session-item:hover{background-color:var(--bg-tertiary)}.session-item.active{background-color:#58a6ff1a;border-color:var(--accent-blue)}.session-item.selected{background-color:#58a6ff0d}.session-checkbox{width:14px;height:14px;cursor:pointer;accent-color:var(--accent-blue)}.status-indicator{width:8px;height:8px;border-radius:50%;flex-shrink:0}.session-name{flex:1;font-size:12px;color:var(--text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.session-agent{font-size:10px;font-weight:600;color:var(--text-muted);background-color:var(--bg-tertiary);padding:2px 6px;border-radius:4px}.session-close{padding:2px 6px;background:transparent;border:none;color:var(--text-muted);cursor:pointer;border-radius:4px;font-size:14px;line-height:1;opacity:0;transition:all .2s}.session-item:hover .session-close{opacity:1}.session-close:hover{background-color:var(--bg-primary);color:var(--accent-red)}.add-session-btn{margin:8px 16px 16px;padding:10px;background-color:transparent;border:1px dashed var(--border-color);border-radius:6px;color:var(--text-secondary);font-size:12px;cursor:pointer;transition:all .2s}.add-session-btn:hover{border-color:var(--accent-blue);color:var(--accent-blue);background-color:#58a6ff0d}.bulk-actions-bar{display:flex;align-items:center;gap:12px;padding:12px 16px;background-color:var(--bg-tertiary);border-top:1px solid var(--border-color)}.selected-count{font-size:12px;color:var(--text-secondary);flex:1}.bulk-delete-btn{padding:6px 12px;background-color:var(--accent-red);border:none;border-radius:4px;color:#fff;font-size:11px;font-weight:500;cursor:pointer;transition:filter .2s}.bulk-delete-btn:hover{filter:brightness(1.1)}.bulk-cancel-btn{padding:6px 12px;background-color:transparent;border:1px solid var(--border-color);border-radius:4px;color:var(--text-secondary);font-size:11px;cursor:pointer;transition:all .2s}.bulk-cancel-btn:hover{background-color:var(--bg-primary);color:var(--text-primary)}.modal-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background-color:#000000b3;display:flex;align-items:center;justify-content:center;z-index:1000}.modal-content{background-color:var(--bg-secondary);border:1px solid var(--border-color);border-radius:12px;width:100%;max-width:440px;max-height:90vh;overflow:hidden;display:flex;flex-direction:column}.modal-confirm{max-width:400px}.modal-header{display:flex;align-items:center;justify-content:space-between;padding:20px 24px;border-bottom:1px solid var(--border-color)}.modal-header h2{font-size:16px;font-weight:600;color:var(--text-primary)}.modal-close{padding:4px 8px;background:transparent;border:none;color:var(--text-muted);font-size:20px;cursor:pointer;border-radius:4px;line-height:1}.modal-close:hover{background-color:var(--bg-tertiary);color:var(--text-primary)}.modal-body{padding:24px;overflow-y:auto}.modal-footer{display:flex;justify-content:flex-end;gap:12px;padding:16px 24px;border-top:1px solid var(--border-color)}.form-group{margin-bottom:20px}.form-group:last-child{margin-bottom:0}.form-group label{display:block;font-size:13px;font-weight:500;color:var(--text-primary);margin-bottom:8px}.form-group select{width:100%;padding:10px 12px;background-color:var(--bg-tertiary);border:1px solid var(--border-color);border-radius:6px;color:var(--text-primary);font-size:14px;font-family:inherit}.form-group select:focus{outline:none;border-color:var(--accent-blue)}.agent-options{display:flex;gap:8px}.agent-option{flex:1;padding:12px;background-color:var(--bg-tertiary);border:2px solid var(--border-color);border-radius:6px;cursor:pointer;transition:all .2s;text-align:center}.agent-option:hover{border-color:var(--accent-blue)}.agent-option.selected{border-color:var(--accent-blue);background-color:#58a6ff1a}.agent-option .agent-name{font-size:12px;font-weight:500;color:var(--text-primary)}.btn-primary{padding:10px 20px;background-color:var(--accent-blue);border:none;border-radius:6px;color:#fff;font-size:13px;font-weight:500;cursor:pointer;transition:filter .2s;font-family:inherit}.btn-primary:hover:not(:disabled){filter:brightness(1.1)}.btn-primary:disabled{background-color:var(--bg-tertiary);color:var(--text-muted);cursor:not-allowed}.btn-secondary{padding:10px 20px;background-color:transparent;border:1px solid var(--border-color);border-radius:6px;color:var(--text-secondary);font-size:13px;font-weight:500;cursor:pointer;transition:all .2s;font-family:inherit}.btn-secondary:hover:not(:disabled){background-color:var(--bg-tertiary);color:var(--text-primary)}.btn-danger{padding:10px 20px;background-color:var(--accent-red);border:none;border-radius:6px;color:#fff;font-size:13px;font-weight:500;cursor:pointer;transition:filter .2s;font-family:inherit}.btn-danger:hover:not(:disabled){filter:brightness(1.1)}.btn-danger:disabled{opacity:.5;cursor:not-allowed}.confirm-message{font-size:14px;color:var(--text-primary);margin-bottom:16px}.delete-list{list-style:none;padding:12px;background-color:var(--bg-tertiary);border-radius:6px;margin-bottom:16px;max-height:150px;overflow-y:auto}.delete-list li{display:flex;align-items:center;gap:8px;padding:6px 0;font-size:13px;color:var(--text-secondary)}.delete-list .status{width:6px;height:6px;border-radius:50%}.warning-text{font-size:12px;color:var(--accent-yellow);padding:12px;background-color:#d299221a;border-radius:6px}.terminal-panel.empty{display:flex;align-items:center;justify-content:center}.empty-message{text-align:center;color:var(--text-muted)}.empty-message p{margin:8px 0}.empty-message p:first-child{font-size:16px;color:var(--text-secondary)}