@made-by-moonlight/athene-plugin-workspace-worktree 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,613 @@
1
+ import { execFile } from "node:child_process";
2
+ import { promisify } from "node:util";
3
+ import * as fs from "node:fs";
4
+ import { existsSync, lstatSync, statSync, symlinkSync, linkSync, rmSync, mkdirSync, readdirSync, } from "node:fs";
5
+ import { join, resolve, basename, dirname, sep } from "node:path";
6
+ import { homedir } from "node:os";
7
+ import { getShell, isWindows, recordActivityEvent, } from "@made-by-moonlight/athene-core";
8
+ /** Timeout for git commands (30 seconds) */
9
+ const GIT_TIMEOUT = 30_000;
10
+ const execFileAsync = promisify(execFile);
11
+ export const manifest = {
12
+ name: "worktree",
13
+ slot: "workspace",
14
+ description: "Workspace plugin: git worktrees",
15
+ version: "0.1.0",
16
+ };
17
+ /** Run a git command in a given directory */
18
+ async function git(cwd, ...args) {
19
+ const { stdout } = await execFileAsync("git", args, {
20
+ cwd,
21
+ windowsHide: true,
22
+ timeout: GIT_TIMEOUT,
23
+ });
24
+ return stdout.trimEnd();
25
+ }
26
+ /**
27
+ * Normalize a path for cross-platform comparison. `git worktree list --porcelain`
28
+ * emits forward-slash paths on Windows even when callers constructed the
29
+ * directory with backslashes via `path.join`. Lowercase the drive letter so
30
+ * `C:` and `c:` match.
31
+ */
32
+ function toComparablePath(p) {
33
+ const slash = p.replace(/\\/g, "/");
34
+ return slash.replace(/^([a-zA-Z]):/, (_, d) => d.toLowerCase() + ":");
35
+ }
36
+ /**
37
+ * Remove a directory, retrying on Windows when file handles haven't drained yet.
38
+ *
39
+ * On Windows, killing a pty-host with node-pty leaves a small window where
40
+ * child processes (conpty_console_list_agent.exe, the agent's spawned shell,
41
+ * .git/index.lock) still hold handles inside the worktree. rmSync(force: true)
42
+ * deletes individual files but the directory rmdir blocks with EBUSY/ENOTEMPTY/EPERM
43
+ * until the kernel drains those handles — typically 100 ms–2 min. Without retry,
44
+ * AO leaves an empty orphan directory that confuses the next git worktree
45
+ * operation and shows up as residue under the project's worktrees directory.
46
+ */
47
+ async function removeDirWithRetry(target) {
48
+ if (!isWindows()) {
49
+ rmSync(target, { recursive: true, force: true });
50
+ return;
51
+ }
52
+ const backoffsMs = [0, 100, 250, 500, 1000, 2000];
53
+ let lastErr;
54
+ for (const delay of backoffsMs) {
55
+ if (delay > 0)
56
+ await new Promise((r) => setTimeout(r, delay));
57
+ try {
58
+ rmSync(target, { recursive: true, force: true });
59
+ if (!existsSync(target))
60
+ return;
61
+ }
62
+ catch (err) {
63
+ lastErr = err;
64
+ }
65
+ }
66
+ if (existsSync(target)) {
67
+ throw new Error(`Failed to remove "${target}" after ${backoffsMs.length} attempts (Windows file-handle drain). ` +
68
+ `Last error: ${lastErr instanceof Error ? lastErr.message : String(lastErr)}`);
69
+ }
70
+ }
71
+ async function hasOriginRemote(cwd) {
72
+ try {
73
+ await git(cwd, "remote", "get-url", "origin");
74
+ return true;
75
+ }
76
+ catch {
77
+ return false;
78
+ }
79
+ }
80
+ async function refExists(cwd, ref) {
81
+ try {
82
+ await git(cwd, "rev-parse", "--verify", "--quiet", ref);
83
+ return true;
84
+ }
85
+ catch {
86
+ return false;
87
+ }
88
+ }
89
+ async function resolveBaseRef(repoPath, defaultBranch, options) {
90
+ const hasOrigin = options?.hasOrigin ?? (await hasOriginRemote(repoPath));
91
+ if (hasOrigin) {
92
+ if (options?.branch) {
93
+ const remoteBranch = `origin/${options.branch}`;
94
+ if (await refExists(repoPath, remoteBranch))
95
+ return remoteBranch;
96
+ }
97
+ const remoteDefaultBranch = `origin/${defaultBranch}`;
98
+ if (await refExists(repoPath, remoteDefaultBranch))
99
+ return remoteDefaultBranch;
100
+ }
101
+ const localDefaultBranch = `refs/heads/${defaultBranch}`;
102
+ if (await refExists(repoPath, localDefaultBranch))
103
+ return localDefaultBranch;
104
+ throw new Error(`Unable to resolve base ref for default branch "${defaultBranch}"`);
105
+ }
106
+ async function isRegisteredWorktree(repoPath, worktreePath) {
107
+ try {
108
+ const output = await git(repoPath, "worktree", "list", "--porcelain");
109
+ // Normalize both sides so non-canonical inputs don't false-negative
110
+ // and let a subsequent rmSync delete a still-registered worktree
111
+ // (data loss). resolve() collapses trailing-slash / ".." segments;
112
+ // toComparablePath handles Windows backslashes and drive case.
113
+ const target = toComparablePath(resolve(worktreePath));
114
+ return output
115
+ .split("\n")
116
+ .some((line) => line.startsWith("worktree ") &&
117
+ toComparablePath(resolve(line.slice("worktree ".length))) === target);
118
+ }
119
+ catch {
120
+ return false;
121
+ }
122
+ }
123
+ async function clearStaleWorktreePath(repoPath, worktreePath) {
124
+ if (!existsSync(worktreePath))
125
+ return;
126
+ try {
127
+ await git(repoPath, "worktree", "prune");
128
+ }
129
+ catch {
130
+ // Best-effort prune before checking whether the path is still registered.
131
+ }
132
+ if (await isRegisteredWorktree(repoPath, worktreePath)) {
133
+ throw new Error(`Worktree path "${worktreePath}" already exists and is still registered with git`);
134
+ }
135
+ rmSync(worktreePath, { recursive: true, force: true });
136
+ }
137
+ /**
138
+ * Restore recovery: clear any stale worktree registration and/or stale
139
+ * directory at `workspacePath` so a subsequent `git worktree add` can
140
+ * succeed. Both restore branches (re-attach existing branch, create from
141
+ * base) need this — without it, an `<path> already exists` failure repeats.
142
+ *
143
+ * Refuses to rmSync the path if it's still a registered worktree, which
144
+ * would silently destroy the user's work. The entry-point `worktree prune`
145
+ * in restore() already ran, so we don't prune again here.
146
+ */
147
+ async function cleanupStaleWorkspacePath(repoPath, workspacePath) {
148
+ // Force-remove any registered worktree at this path. Best-effort — the
149
+ // path may not be registered, in which case git errors and we fall
150
+ // through to the dir cleanup.
151
+ try {
152
+ await git(repoPath, "worktree", "remove", "--force", workspacePath);
153
+ }
154
+ catch {
155
+ // Best-effort
156
+ }
157
+ if (existsSync(workspacePath)) {
158
+ if (await isRegisteredWorktree(repoPath, workspacePath)) {
159
+ throw new Error(`Worktree path "${workspacePath}" already exists and is still registered with git`);
160
+ }
161
+ // Use removeDirWithRetry for Windows file-handle drain races (matches
162
+ // destroy()'s fallback). On Unix this is just rmSync.
163
+ await removeDirWithRetry(workspacePath);
164
+ }
165
+ }
166
+ /**
167
+ * Restore recovery: re-attach an existing local branch to a worktree at
168
+ * `workspacePath`. Used when the branch is already present (destroy()
169
+ * preserves it) but the first `git worktree add <path> <branch>` failed
170
+ * — typically because `workspacePath` has a stale registry entry, a
171
+ * stale directory, or both.
172
+ *
173
+ * Never uses -b/-B: -b would fail with "branch already exists", and -B
174
+ * would force-reset the branch to a base ref and silently discard the
175
+ * session's commits, which is the opposite of restore's intent.
176
+ */
177
+ async function reattachExistingBranch(repoPath, workspacePath, branch) {
178
+ await cleanupStaleWorkspacePath(repoPath, workspacePath);
179
+ await git(repoPath, "worktree", "add", workspacePath, branch);
180
+ }
181
+ /**
182
+ * Restore recovery: create a fresh branch at `workspacePath` from the
183
+ * appropriate base ref. Used when the local branch is missing — typically
184
+ * because only `origin/<branch>` exists and we need to materialize the
185
+ * local ref. Tries the remote ref first, then falls back to the local
186
+ * default branch.
187
+ *
188
+ * Runs the same stale-path cleanup as reattachExistingBranch so this path
189
+ * also recovers when `workspacePath` has a stale registry entry / dir.
190
+ */
191
+ async function createBranchFromBase(repoPath, workspacePath, branch, defaultBranch, hasOrigin) {
192
+ await cleanupStaleWorkspacePath(repoPath, workspacePath);
193
+ const baseRef = await resolveBaseRef(repoPath, defaultBranch, { branch, hasOrigin });
194
+ if (!baseRef.startsWith("origin/")) {
195
+ // No remote available — create from the local default branch
196
+ await git(repoPath, "worktree", "add", "-b", branch, workspacePath, baseRef);
197
+ return;
198
+ }
199
+ // Branch might not exist locally — try the remote ref first, then fall
200
+ // back to the local default branch if the remote ref is unavailable.
201
+ try {
202
+ await git(repoPath, "worktree", "add", "-b", branch, workspacePath, baseRef);
203
+ }
204
+ catch {
205
+ await git(repoPath, "worktree", "add", "-b", branch, workspacePath, `refs/heads/${defaultBranch}`);
206
+ }
207
+ }
208
+ function parseWorktreeList(output) {
209
+ const normalized = output.replace(/\r\n/g, "\n").trim();
210
+ if (!normalized)
211
+ return [];
212
+ return normalized
213
+ .split("\n\n")
214
+ .map((block) => {
215
+ let path = "";
216
+ let branch = null;
217
+ for (const line of block.split("\n")) {
218
+ if (line.startsWith("worktree ")) {
219
+ path = resolve(line.slice("worktree ".length));
220
+ }
221
+ else if (line.startsWith("branch ")) {
222
+ branch = line.slice("branch ".length).replace("refs/heads/", "");
223
+ }
224
+ }
225
+ return { path, branch };
226
+ })
227
+ .filter((entry) => entry.path.length > 0);
228
+ }
229
+ /** Only allow safe characters in path segments to prevent directory traversal */
230
+ const SAFE_PATH_SEGMENT = /^[a-zA-Z0-9_-]+$/;
231
+ function assertSafePathSegment(value, label) {
232
+ if (!SAFE_PATH_SEGMENT.test(value)) {
233
+ throw new Error(`Invalid ${label} "${value}": must match ${SAFE_PATH_SEGMENT}`);
234
+ }
235
+ }
236
+ /** Expand ~ to home directory */
237
+ function expandPath(p) {
238
+ if (p.startsWith("~/")) {
239
+ return join(homedir(), p.slice(2));
240
+ }
241
+ return p;
242
+ }
243
+ export function create(config) {
244
+ const worktreeBaseDir = config?.worktreeDir
245
+ ? expandPath(config.worktreeDir)
246
+ : join(homedir(), ".worktrees");
247
+ return {
248
+ name: "worktree",
249
+ async create(cfg) {
250
+ assertSafePathSegment(cfg.projectId, "projectId");
251
+ assertSafePathSegment(cfg.sessionId, "sessionId");
252
+ const repoPath = expandPath(cfg.project.path);
253
+ const effectiveBaseDir = cfg.worktreeDir ?? worktreeBaseDir;
254
+ const projectWorktreeDir = cfg.worktreeDir
255
+ ? effectiveBaseDir
256
+ : join(effectiveBaseDir, cfg.projectId);
257
+ const worktreePath = join(projectWorktreeDir, cfg.sessionId);
258
+ mkdirSync(projectWorktreeDir, { recursive: true });
259
+ await clearStaleWorktreePath(repoPath, worktreePath);
260
+ const hasOrigin = await hasOriginRemote(repoPath);
261
+ // Fetch latest from remote when origin exists
262
+ if (hasOrigin) {
263
+ try {
264
+ await git(repoPath, "fetch", "origin", "--quiet");
265
+ }
266
+ catch {
267
+ // Fetch may fail if offline — continue anyway
268
+ }
269
+ }
270
+ const baseRef = await resolveBaseRef(repoPath, cfg.project.defaultBranch, { hasOrigin });
271
+ // Create worktree with a new branch
272
+ try {
273
+ await git(repoPath, "worktree", "add", "-b", cfg.branch, worktreePath, baseRef);
274
+ }
275
+ catch (err) {
276
+ // Only retry if the error is "branch already exists"
277
+ const msg = err instanceof Error ? err.message : String(err);
278
+ if (!msg.includes("already exists")) {
279
+ throw new Error(`Failed to create worktree for branch "${cfg.branch}": ${msg}`, {
280
+ cause: err,
281
+ });
282
+ }
283
+ // Branch already exists. It may be a stale session branch left behind
284
+ // from an earlier spawn, so compare it with the freshly-resolved base
285
+ // before reusing it. Surface the collision shape for RCA before the
286
+ // recovery path decides whether to reuse or reset the local branch.
287
+ recordActivityEvent({
288
+ projectId: cfg.projectId,
289
+ sessionId: cfg.sessionId,
290
+ source: "workspace",
291
+ kind: "workspace.branch_collision",
292
+ level: "warn",
293
+ summary: `branch "${cfg.branch}" already exists; falling back to worktree recovery`,
294
+ data: {
295
+ plugin: "workspace-worktree",
296
+ branch: cfg.branch,
297
+ errorMessage: msg,
298
+ },
299
+ });
300
+ const baseSha = await git(repoPath, "rev-parse", baseRef);
301
+ const branchRef = `refs/heads/${cfg.branch}`;
302
+ const existingBranchSha = (await refExists(repoPath, branchRef))
303
+ ? await git(repoPath, "rev-parse", branchRef)
304
+ : undefined;
305
+ try {
306
+ if (existingBranchSha === baseSha) {
307
+ await git(repoPath, "worktree", "add", worktreePath, cfg.branch);
308
+ }
309
+ else {
310
+ await git(repoPath, "worktree", "add", "-B", cfg.branch, worktreePath, baseRef);
311
+ }
312
+ }
313
+ catch (retryErr) {
314
+ // Retry failed — remove any orphaned worktree before rethrowing
315
+ try {
316
+ await git(repoPath, "worktree", "remove", "--force", worktreePath);
317
+ }
318
+ catch {
319
+ // Best-effort cleanup
320
+ }
321
+ const retryMsg = retryErr instanceof Error ? retryErr.message : String(retryErr);
322
+ throw new Error(`Failed to create worktree for branch "${cfg.branch}": ${retryMsg}`, {
323
+ cause: retryErr,
324
+ });
325
+ }
326
+ }
327
+ return {
328
+ path: worktreePath,
329
+ branch: cfg.branch,
330
+ sessionId: cfg.sessionId,
331
+ projectId: cfg.projectId,
332
+ };
333
+ },
334
+ async findManagedWorkspace(cfg) {
335
+ assertSafePathSegment(cfg.projectId, "projectId");
336
+ assertSafePathSegment(cfg.sessionId, "sessionId");
337
+ const repoPath = expandPath(cfg.project.path);
338
+ const effectiveBaseDir = cfg.worktreeDir ?? worktreeBaseDir;
339
+ const projectWorktreeDir = cfg.worktreeDir
340
+ ? effectiveBaseDir
341
+ : join(effectiveBaseDir, cfg.projectId);
342
+ const currentManagedPath = resolve(join(projectWorktreeDir, cfg.sessionId));
343
+ const legacyManagedPath = resolve(join(worktreeBaseDir, cfg.projectId, cfg.sessionId));
344
+ const allowedPaths = new Set([currentManagedPath, legacyManagedPath]);
345
+ const worktrees = parseWorktreeList(await git(repoPath, "worktree", "list", "--porcelain"));
346
+ const matches = worktrees.filter((entry) => entry.branch === cfg.branch && existsSync(entry.path));
347
+ if (matches.length === 0)
348
+ return null;
349
+ if (matches.length > 1) {
350
+ throw new Error(`Found multiple worktrees for orchestrator branch "${cfg.branch}". Reuse one workspace or remove the extras before starting the orchestrator.`);
351
+ }
352
+ const match = matches[0];
353
+ if (!allowedPaths.has(match.path)) {
354
+ throw new Error(`Found existing worktree for orchestrator branch "${cfg.branch}" at "${match.path}", but it is outside AO-managed worktree directories. Reuse it manually or remove it and try again.`);
355
+ }
356
+ return {
357
+ path: match.path,
358
+ branch: cfg.branch,
359
+ sessionId: cfg.sessionId,
360
+ projectId: cfg.projectId,
361
+ };
362
+ },
363
+ async destroy(workspacePath) {
364
+ try {
365
+ const gitCommonDir = await git(workspacePath, "rev-parse", "--path-format=absolute", "--git-common-dir");
366
+ // git-common-dir returns something like /path/to/repo/.git
367
+ const repoPath = resolve(gitCommonDir, "..");
368
+ await git(repoPath, "worktree", "remove", "--force", workspacePath);
369
+ // NOTE: We intentionally do NOT delete the branch here. The worktree
370
+ // removal is sufficient. Auto-deleting branches risks removing
371
+ // pre-existing local branches unrelated to this workspace (any branch
372
+ // containing "/" would have been deleted). Stale branches can be
373
+ // cleaned up separately via `git branch --merged` or similar.
374
+ }
375
+ catch (err) {
376
+ // If git commands fail, try to clean up the directory.
377
+ // The worktree metadata may be left stale in `git worktree list`
378
+ // because we couldn't run `worktree remove`. Surface so RCA can
379
+ // explain why a path was deleted but `git worktree list` still
380
+ // references it.
381
+ const errorMessage = err instanceof Error ? err.message : String(err);
382
+ recordActivityEvent({
383
+ source: "workspace",
384
+ kind: "workspace.destroy_fell_back",
385
+ level: "warn",
386
+ summary: "destroy fell back to rmSync; git worktree metadata may be stale",
387
+ data: {
388
+ plugin: "workspace-worktree",
389
+ workspacePath,
390
+ errorMessage,
391
+ },
392
+ });
393
+ // On Windows, retry with backoff for the file-handle drain race
394
+ // (just-killed pty-host children still hold handles inside the worktree).
395
+ if (existsSync(workspacePath)) {
396
+ await removeDirWithRetry(workspacePath);
397
+ }
398
+ }
399
+ },
400
+ async list(projectId) {
401
+ assertSafePathSegment(projectId, "projectId");
402
+ const projectWorktreeDir = join(worktreeBaseDir, projectId);
403
+ if (!existsSync(projectWorktreeDir))
404
+ return [];
405
+ const entries = readdirSync(projectWorktreeDir, { withFileTypes: true });
406
+ const dirs = entries
407
+ .filter((e) => e.isDirectory())
408
+ .map((e) => join(projectWorktreeDir, e.name));
409
+ if (dirs.length === 0)
410
+ return [];
411
+ // Use first valid worktree to get the list
412
+ let worktreeListOutput = "";
413
+ for (const dir of dirs) {
414
+ try {
415
+ worktreeListOutput = await git(dir, "worktree", "list", "--porcelain");
416
+ break;
417
+ }
418
+ catch {
419
+ continue;
420
+ }
421
+ }
422
+ if (!worktreeListOutput)
423
+ return [];
424
+ // Parse porcelain output — only include worktrees within our project directory
425
+ const infos = [];
426
+ const blocks = worktreeListOutput.split("\n\n");
427
+ const projectDirCmp = toComparablePath(projectWorktreeDir);
428
+ for (const block of blocks) {
429
+ const lines = block.trim().split("\n");
430
+ let path = "";
431
+ let branch = "";
432
+ for (const line of lines) {
433
+ if (line.startsWith("worktree ")) {
434
+ path = line.slice("worktree ".length);
435
+ }
436
+ else if (line.startsWith("branch ")) {
437
+ // branch refs/heads/feat/INT-1234 → feat/INT-1234
438
+ branch = line.slice("branch ".length).replace("refs/heads/", "");
439
+ }
440
+ }
441
+ const pathCmp = path ? toComparablePath(path) : "";
442
+ if (path && (pathCmp === projectDirCmp || pathCmp.startsWith(projectDirCmp + "/"))) {
443
+ const sessionId = basename(path);
444
+ infos.push({
445
+ path,
446
+ branch: branch || "detached",
447
+ sessionId,
448
+ projectId,
449
+ });
450
+ }
451
+ }
452
+ return infos;
453
+ },
454
+ async exists(workspacePath) {
455
+ if (!existsSync(workspacePath))
456
+ return false;
457
+ try {
458
+ await execFileAsync("git", ["rev-parse", "--is-inside-work-tree"], {
459
+ cwd: workspacePath,
460
+ timeout: GIT_TIMEOUT,
461
+ windowsHide: true,
462
+ });
463
+ return true;
464
+ }
465
+ catch {
466
+ return false;
467
+ }
468
+ },
469
+ async restore(cfg, workspacePath) {
470
+ const repoPath = expandPath(cfg.project.path);
471
+ // Prune stale worktree entries
472
+ try {
473
+ await git(repoPath, "worktree", "prune");
474
+ }
475
+ catch {
476
+ // Best effort
477
+ }
478
+ // Fetch latest
479
+ const hasOrigin = await hasOriginRemote(repoPath);
480
+ if (hasOrigin) {
481
+ try {
482
+ await git(repoPath, "fetch", "origin", "--quiet");
483
+ }
484
+ catch {
485
+ // May fail if offline
486
+ }
487
+ }
488
+ // Try to create worktree on the existing branch.
489
+ try {
490
+ await git(repoPath, "worktree", "add", workspacePath, cfg.branch);
491
+ }
492
+ catch {
493
+ if (await refExists(repoPath, `refs/heads/${cfg.branch}`)) {
494
+ await reattachExistingBranch(repoPath, workspacePath, cfg.branch);
495
+ }
496
+ else {
497
+ await createBranchFromBase(repoPath, workspacePath, cfg.branch, cfg.project.defaultBranch, hasOrigin);
498
+ }
499
+ }
500
+ return {
501
+ path: workspacePath,
502
+ branch: cfg.branch,
503
+ sessionId: cfg.sessionId,
504
+ projectId: cfg.projectId,
505
+ };
506
+ },
507
+ async postCreate(info, project) {
508
+ const repoPath = expandPath(project.path);
509
+ // Symlink shared resources
510
+ if (project.symlinks) {
511
+ for (const symlinkPath of project.symlinks) {
512
+ // Guard against absolute paths (Unix: leading "/", Windows: drive letter "C:\"
513
+ // or UNC "\\server\share") and directory traversal
514
+ if (symlinkPath.startsWith("/") ||
515
+ symlinkPath.includes("..") ||
516
+ /^[a-zA-Z]:[\\/]/.test(symlinkPath) ||
517
+ symlinkPath.startsWith("\\\\")) {
518
+ throw new Error(`Invalid symlink path "${symlinkPath}": must be a relative path without ".." segments`);
519
+ }
520
+ const sourcePath = join(repoPath, symlinkPath);
521
+ const targetPath = resolve(info.path, symlinkPath);
522
+ const normalizedBase = resolve(info.path);
523
+ // Verify resolved target is still within the workspace
524
+ if (!targetPath.startsWith(normalizedBase + sep) && targetPath !== normalizedBase) {
525
+ throw new Error(`Symlink target "${symlinkPath}" resolves outside workspace: ${targetPath}`);
526
+ }
527
+ if (!existsSync(sourcePath))
528
+ continue;
529
+ // Remove existing target if it exists
530
+ try {
531
+ const stat = lstatSync(targetPath);
532
+ if (stat.isSymbolicLink() || stat.isFile() || stat.isDirectory()) {
533
+ rmSync(targetPath, { recursive: true, force: true });
534
+ }
535
+ }
536
+ catch {
537
+ // Target doesn't exist — that's fine
538
+ }
539
+ // Ensure parent directory exists for nested symlink targets
540
+ mkdirSync(dirname(targetPath), { recursive: true });
541
+ try {
542
+ symlinkSync(sourcePath, targetPath);
543
+ }
544
+ catch (err) {
545
+ if (isWindows()) {
546
+ // Symlinks need admin/Developer Mode on Windows. Try unprivileged
547
+ // alternatives first — junctions for dirs, hardlinks for files —
548
+ // before falling back to a recursive copy (slow + bloats every
549
+ // worktree, especially for node_modules).
550
+ const isDir = (() => {
551
+ try {
552
+ return statSync(sourcePath).isDirectory();
553
+ }
554
+ catch {
555
+ return false;
556
+ }
557
+ })();
558
+ try {
559
+ if (isDir) {
560
+ symlinkSync(sourcePath, targetPath, "junction");
561
+ }
562
+ else {
563
+ linkSync(sourcePath, targetPath);
564
+ }
565
+ }
566
+ catch {
567
+ fs.cpSync(sourcePath, targetPath, { recursive: true });
568
+ }
569
+ }
570
+ else {
571
+ throw err;
572
+ }
573
+ }
574
+ }
575
+ }
576
+ // Run postCreate hooks
577
+ // NOTE: commands run with full shell privileges — they come from trusted YAML config
578
+ if (project.postCreate) {
579
+ const shell = getShell();
580
+ for (const command of project.postCreate) {
581
+ try {
582
+ await execFileAsync(shell.cmd, shell.args(command), {
583
+ cwd: info.path,
584
+ windowsHide: true,
585
+ });
586
+ }
587
+ catch (err) {
588
+ // Surface which postCreate command failed. Lifecycle records
589
+ // a generic spawn_failed but loses the specific command and
590
+ // its sanitized error output.
591
+ const errorMessage = err instanceof Error ? err.message : String(err);
592
+ recordActivityEvent({
593
+ projectId: info.projectId,
594
+ sessionId: info.sessionId,
595
+ source: "workspace",
596
+ kind: "workspace.post_create_failed",
597
+ level: "error",
598
+ summary: `postCreate command failed for session ${info.sessionId}`,
599
+ data: {
600
+ plugin: "workspace-worktree",
601
+ command,
602
+ errorMessage,
603
+ },
604
+ });
605
+ throw err;
606
+ }
607
+ }
608
+ }
609
+ },
610
+ };
611
+ }
612
+ export default { manifest, create };
613
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}