@cleocode/worktree 2026.4.117

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 (41) hide show
  1. package/dist/compat.d.ts +126 -0
  2. package/dist/compat.d.ts.map +1 -0
  3. package/dist/compat.js +160 -0
  4. package/dist/compat.js.map +1 -0
  5. package/dist/git.d.ts +53 -0
  6. package/dist/git.d.ts.map +1 -0
  7. package/dist/git.js +90 -0
  8. package/dist/git.js.map +1 -0
  9. package/dist/index.d.ts +32 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +30 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/paths.d.ts +51 -0
  14. package/dist/paths.d.ts.map +1 -0
  15. package/dist/paths.js +66 -0
  16. package/dist/paths.js.map +1 -0
  17. package/dist/worktree-create.d.ts +36 -0
  18. package/dist/worktree-create.d.ts.map +1 -0
  19. package/dist/worktree-create.js +127 -0
  20. package/dist/worktree-create.js.map +1 -0
  21. package/dist/worktree-destroy.d.ts +30 -0
  22. package/dist/worktree-destroy.d.ts.map +1 -0
  23. package/dist/worktree-destroy.js +110 -0
  24. package/dist/worktree-destroy.js.map +1 -0
  25. package/dist/worktree-hooks.d.ts +32 -0
  26. package/dist/worktree-hooks.d.ts.map +1 -0
  27. package/dist/worktree-hooks.js +67 -0
  28. package/dist/worktree-hooks.js.map +1 -0
  29. package/dist/worktree-include.d.ts +54 -0
  30. package/dist/worktree-include.d.ts.map +1 -0
  31. package/dist/worktree-include.js +99 -0
  32. package/dist/worktree-include.js.map +1 -0
  33. package/dist/worktree-list.d.ts +40 -0
  34. package/dist/worktree-list.d.ts.map +1 -0
  35. package/dist/worktree-list.js +110 -0
  36. package/dist/worktree-list.js.map +1 -0
  37. package/dist/worktree-prune.d.ts +27 -0
  38. package/dist/worktree-prune.d.ts.map +1 -0
  39. package/dist/worktree-prune.js +91 -0
  40. package/dist/worktree-prune.js.map +1 -0
  41. package/package.json +49 -0
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Worktree creation operation for @cleocode/worktree.
3
+ *
4
+ * Creates a git worktree at the canonical XDG path per D029:
5
+ * `~/.local/share/cleo/worktrees/<projectHash>/<taskId>/`
6
+ *
7
+ * Also:
8
+ * - Applies git worktree lock to prevent accidental pruning.
9
+ * - Runs declarative `post-create` hooks (D030 native lift).
10
+ * - Applies `.cleo/worktree-include` patterns (D030 native lift).
11
+ * - Constructs the agent env-var block and prompt preamble.
12
+ *
13
+ * @task T1161
14
+ */
15
+ import type { CreateWorktreeOptions, CreateWorktreeResult } from '@cleocode/contracts';
16
+ /**
17
+ * Create a git worktree for an agent task.
18
+ *
19
+ * Steps:
20
+ * 1. Resolve paths and project hash from the project root.
21
+ * 2. Remove stale worktree at the same path if it exists.
22
+ * 3. Run `git worktree add <path> -b <branch> <baseRef>`.
23
+ * 4. Optionally apply `git worktree lock` to prevent pruning.
24
+ * 5. Run declarative `post-create` hooks.
25
+ * 6. Apply `.cleo/worktree-include` glob patterns (symlinks).
26
+ * 7. Build and return the {@link CreateWorktreeResult}.
27
+ *
28
+ * @param projectRoot - Absolute path to the project root directory.
29
+ * @param options - Options controlling the worktree creation.
30
+ * @returns The created worktree result with env vars and preamble.
31
+ * @throws Error if git worktree add fails.
32
+ *
33
+ * @task T1161
34
+ */
35
+ export declare function createWorktree(projectRoot: string, options: CreateWorktreeOptions): Promise<CreateWorktreeResult>;
36
+ //# sourceMappingURL=worktree-create.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree-create.d.ts","sourceRoot":"","sources":["../src/worktree-create.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAUvF;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CAkG/B"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Worktree creation operation for @cleocode/worktree.
3
+ *
4
+ * Creates a git worktree at the canonical XDG path per D029:
5
+ * `~/.local/share/cleo/worktrees/<projectHash>/<taskId>/`
6
+ *
7
+ * Also:
8
+ * - Applies git worktree lock to prevent accidental pruning.
9
+ * - Runs declarative `post-create` hooks (D030 native lift).
10
+ * - Applies `.cleo/worktree-include` patterns (D030 native lift).
11
+ * - Constructs the agent env-var block and prompt preamble.
12
+ *
13
+ * @task T1161
14
+ */
15
+ import { existsSync, mkdirSync, rmSync } from 'node:fs';
16
+ import { join } from 'node:path';
17
+ import { getGitRoot, gitSilent, gitSync, resolveHeadRef } from './git.js';
18
+ import { computeProjectHash, resolveTaskWorktreePath, resolveWorktreeRootForHash, } from './paths.js';
19
+ import { runWorktreeHooks } from './worktree-hooks.js';
20
+ import { applyIncludePatterns, loadWorktreeIncludePatterns } from './worktree-include.js';
21
+ /**
22
+ * Create a git worktree for an agent task.
23
+ *
24
+ * Steps:
25
+ * 1. Resolve paths and project hash from the project root.
26
+ * 2. Remove stale worktree at the same path if it exists.
27
+ * 3. Run `git worktree add <path> -b <branch> <baseRef>`.
28
+ * 4. Optionally apply `git worktree lock` to prevent pruning.
29
+ * 5. Run declarative `post-create` hooks.
30
+ * 6. Apply `.cleo/worktree-include` glob patterns (symlinks).
31
+ * 7. Build and return the {@link CreateWorktreeResult}.
32
+ *
33
+ * @param projectRoot - Absolute path to the project root directory.
34
+ * @param options - Options controlling the worktree creation.
35
+ * @returns The created worktree result with env vars and preamble.
36
+ * @throws Error if git worktree add fails.
37
+ *
38
+ * @task T1161
39
+ */
40
+ export async function createWorktree(projectRoot, options) {
41
+ const { taskId, hooks = [], lockWorktree = true } = options;
42
+ const applyInclude = options.applyIncludePatterns !== false;
43
+ const gitRoot = getGitRoot(projectRoot);
44
+ const projectHash = computeProjectHash(projectRoot);
45
+ const worktreeRoot = resolveWorktreeRootForHash(projectHash);
46
+ mkdirSync(worktreeRoot, { recursive: true });
47
+ const branch = options.branchName ?? `task/${taskId}`;
48
+ const baseRef = options.baseRef ?? resolveHeadRef(gitRoot);
49
+ const worktreePath = resolveTaskWorktreePath(projectHash, taskId);
50
+ // Remove stale worktree at this path if it exists (left from a prior run).
51
+ if (existsSync(worktreePath)) {
52
+ gitSilent(['worktree', 'unlock', worktreePath], gitRoot);
53
+ if (!gitSilent(['worktree', 'remove', '--force', worktreePath], gitRoot)) {
54
+ rmSync(worktreePath, { recursive: true, force: true });
55
+ }
56
+ // Best-effort: delete the stale branch.
57
+ gitSilent(['branch', '-D', branch], gitRoot);
58
+ }
59
+ // Create the worktree with a new branch.
60
+ gitSync(['worktree', 'add', worktreePath, '-b', branch, baseRef], gitRoot);
61
+ // Apply git worktree lock to prevent accidental pruning.
62
+ let locked = false;
63
+ if (lockWorktree) {
64
+ // Try with --reason (git >= 2.37), fall back without.
65
+ if (gitSilent(['worktree', 'lock', '--reason', `cleo-agent-${taskId}`, worktreePath], gitRoot)) {
66
+ locked = true;
67
+ }
68
+ else if (gitSilent(['worktree', 'lock', worktreePath], gitRoot)) {
69
+ locked = true;
70
+ }
71
+ }
72
+ const createdAt = new Date().toISOString();
73
+ // Run post-create hooks before returning the handle.
74
+ const hookResults = await runWorktreeHooks(hooks, 'post-create', worktreePath);
75
+ // Apply .cleo/worktree-include patterns.
76
+ let appliedPatterns = [];
77
+ if (applyInclude) {
78
+ const patterns = loadWorktreeIncludePatterns(projectRoot);
79
+ appliedPatterns = applyIncludePatterns(patterns, projectRoot, worktreePath);
80
+ }
81
+ // Build env vars for agent spawn.
82
+ const currentPath = process.env['PATH'] ?? '';
83
+ const shimDir = join(projectRoot, '.cleo', 'bin', 'git-shim');
84
+ const envVars = {
85
+ CLEO_AGENT_ROLE: 'worker',
86
+ CLEO_AGENT_CWD: worktreePath,
87
+ CLEO_WORKTREE_ROOT: worktreePath,
88
+ CLEO_WORKTREE_BRANCH: branch,
89
+ CLEO_PROJECT_HASH: projectHash,
90
+ CLEO_BRANCH_PROTECTION: 'strict',
91
+ CLEO_SHIM_MARKER: '.cleo/bin/git-shim',
92
+ PATH: `${shimDir}:${currentPath}`,
93
+ };
94
+ // Build the preamble text for agent context isolation (per acceptance criterion).
95
+ const preamble = [
96
+ '## BRANCH ISOLATION PROTOCOL (MANDATORY)',
97
+ '',
98
+ `CLEO_AGENT_CWD=${worktreePath}`,
99
+ '',
100
+ `FIRST ACTION: cd ${worktreePath}`,
101
+ '',
102
+ `You are working on branch: ${branch}`,
103
+ 'You MUST NOT run any of these git commands:',
104
+ ' git checkout, git switch, git branch -b/-D, git reset --hard,',
105
+ ' git worktree add/remove, git rebase, git stash pop, git push --force',
106
+ '',
107
+ 'A git shim is active on your PATH that will exit 77 if you attempt these.',
108
+ `Your working directory is: ${worktreePath}`,
109
+ `You are authorized only within \`${worktreePath}\``,
110
+ 'All your commits must land on YOUR branch only.',
111
+ '',
112
+ ].join('\n');
113
+ return {
114
+ path: worktreePath,
115
+ branch,
116
+ baseRef,
117
+ taskId,
118
+ projectHash,
119
+ createdAt,
120
+ locked,
121
+ envVars,
122
+ preamble,
123
+ hookResults,
124
+ appliedPatterns,
125
+ };
126
+ }
127
+ //# sourceMappingURL=worktree-create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree-create.js","sourceRoot":"","sources":["../src/worktree-create.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Worktree destroy operation for @cleocode/worktree.
3
+ *
4
+ * Removes the git worktree for a completed task. Optionally cherry-picks
5
+ * commits from the task branch back to the orchestrator's current branch
6
+ * before destroying.
7
+ *
8
+ * @task T1161
9
+ */
10
+ import type { DestroyWorktreeOptions, DestroyWorktreeResult } from '@cleocode/contracts';
11
+ /**
12
+ * Destroy the git worktree for a task.
13
+ *
14
+ * Steps:
15
+ * 1. Optionally cherry-pick commits from the task branch to the base ref.
16
+ * 2. Unlock the worktree (`git worktree unlock`).
17
+ * 3. Remove the worktree directory (`git worktree remove --force`).
18
+ * 4. Optionally delete the task branch.
19
+ *
20
+ * Non-fatal errors are captured in the result's `error` field. The caller
21
+ * decides whether to propagate them.
22
+ *
23
+ * @param projectRoot - Absolute path to the project root directory.
24
+ * @param options - Destroy options including task ID and optional cherry-pick.
25
+ * @returns Structured result of the destroy operation.
26
+ *
27
+ * @task T1161
28
+ */
29
+ export declare function destroyWorktree(projectRoot: string, options: DestroyWorktreeOptions): DestroyWorktreeResult;
30
+ //# sourceMappingURL=worktree-destroy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree-destroy.d.ts","sourceRoot":"","sources":["../src/worktree-destroy.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAIzF;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAC7B,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,sBAAsB,GAC9B,qBAAqB,CA8EvB"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Worktree destroy operation for @cleocode/worktree.
3
+ *
4
+ * Removes the git worktree for a completed task. Optionally cherry-picks
5
+ * commits from the task branch back to the orchestrator's current branch
6
+ * before destroying.
7
+ *
8
+ * @task T1161
9
+ */
10
+ import { existsSync, rmSync } from 'node:fs';
11
+ import { getGitRoot, gitSilent, gitSync, resolveHeadRef } from './git.js';
12
+ import { computeProjectHash, resolveTaskWorktreePath } from './paths.js';
13
+ /**
14
+ * Destroy the git worktree for a task.
15
+ *
16
+ * Steps:
17
+ * 1. Optionally cherry-pick commits from the task branch to the base ref.
18
+ * 2. Unlock the worktree (`git worktree unlock`).
19
+ * 3. Remove the worktree directory (`git worktree remove --force`).
20
+ * 4. Optionally delete the task branch.
21
+ *
22
+ * Non-fatal errors are captured in the result's `error` field. The caller
23
+ * decides whether to propagate them.
24
+ *
25
+ * @param projectRoot - Absolute path to the project root directory.
26
+ * @param options - Destroy options including task ID and optional cherry-pick.
27
+ * @returns Structured result of the destroy operation.
28
+ *
29
+ * @task T1161
30
+ */
31
+ export function destroyWorktree(projectRoot, options) {
32
+ const { taskId, deleteBranch = true, cherryPickFirst = false } = options;
33
+ const gitRoot = getGitRoot(projectRoot);
34
+ const projectHash = computeProjectHash(projectRoot);
35
+ const worktreePath = resolveTaskWorktreePath(projectHash, taskId);
36
+ const branch = `task/${taskId}`;
37
+ const baseRef = resolveHeadRef(gitRoot);
38
+ let cherryPicked = false;
39
+ let commitCount = 0;
40
+ let worktreeRemoved = false;
41
+ let branchDeleted = false;
42
+ let error;
43
+ // Step 1: Cherry-pick if requested.
44
+ if (cherryPickFirst) {
45
+ try {
46
+ const branchExists = gitSync(['branch', '--list', branch], gitRoot);
47
+ if (branchExists) {
48
+ const log = gitSync(['log', '--reverse', '--format=%H', `${baseRef}..${branch}`], gitRoot);
49
+ const commits = log
50
+ .split('\n')
51
+ .map((s) => s.trim())
52
+ .filter(Boolean);
53
+ if (commits.length > 0) {
54
+ gitSync(['cherry-pick', ...commits], gitRoot);
55
+ cherryPicked = true;
56
+ commitCount = commits.length;
57
+ }
58
+ else {
59
+ cherryPicked = true;
60
+ commitCount = 0;
61
+ }
62
+ }
63
+ }
64
+ catch (err) {
65
+ gitSilent(['cherry-pick', '--abort'], gitRoot);
66
+ error = `Cherry-pick failed: ${err instanceof Error ? err.message : String(err)}`;
67
+ }
68
+ }
69
+ // Step 2: Unlock + remove the worktree (even if cherry-pick failed — caller decided).
70
+ if (existsSync(worktreePath)) {
71
+ gitSilent(['worktree', 'unlock', worktreePath], gitRoot);
72
+ if (gitSilent(['worktree', 'remove', '--force', worktreePath], gitRoot)) {
73
+ worktreeRemoved = true;
74
+ }
75
+ else {
76
+ try {
77
+ rmSync(worktreePath, { recursive: true, force: true });
78
+ worktreeRemoved = true;
79
+ }
80
+ catch (err2) {
81
+ if (!error) {
82
+ error = `Failed to remove worktree: ${err2 instanceof Error ? err2.message : String(err2)}`;
83
+ }
84
+ }
85
+ }
86
+ }
87
+ else {
88
+ worktreeRemoved = true; // already gone
89
+ }
90
+ // Step 3: Optionally delete the branch.
91
+ if (deleteBranch) {
92
+ try {
93
+ const branchExists = gitSync(['branch', '--list', branch], gitRoot);
94
+ if (branchExists) {
95
+ gitSync(['branch', '-D', branch], gitRoot);
96
+ }
97
+ branchDeleted = true;
98
+ }
99
+ catch (err) {
100
+ if (!error) {
101
+ error = `Failed to delete branch: ${err instanceof Error ? err.message : String(err)}`;
102
+ }
103
+ }
104
+ }
105
+ else {
106
+ branchDeleted = false;
107
+ }
108
+ return { taskId, cherryPicked, commitCount, worktreeRemoved, branchDeleted, error };
109
+ }
110
+ //# sourceMappingURL=worktree-destroy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree-destroy.js","sourceRoot":"","sources":["../src/worktree-destroy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Declarative worktree hooks framework — native lift of worktrunk's hooks
3
+ * feature per D030.
4
+ *
5
+ * Executes `post-create` and `post-start` hooks in the worktree directory.
6
+ * Each hook runs via `sh -c <command>` with the worktree path as CWD.
7
+ *
8
+ * @task T1161
9
+ */
10
+ import type { WorktreeHook, WorktreeHookResult } from '@cleocode/contracts';
11
+ /**
12
+ * Execute a single declarative hook in the given worktree directory.
13
+ *
14
+ * @param hook - The hook definition to execute.
15
+ * @param worktreePath - Absolute path to the worktree directory (CWD for hook).
16
+ * @returns Hook execution result.
17
+ */
18
+ export declare function runSingleHook(hook: WorktreeHook, worktreePath: string): Promise<WorktreeHookResult>;
19
+ /**
20
+ * Run all hooks matching a given lifecycle event in order.
21
+ *
22
+ * Hooks are run sequentially. If a hook has `failOnError: true` and exits
23
+ * non-zero, execution stops immediately and the error is propagated.
24
+ *
25
+ * @param hooks - All hook definitions (may include hooks for other events).
26
+ * @param event - The lifecycle event to filter and run.
27
+ * @param worktreePath - Absolute path to the worktree directory.
28
+ * @returns Array of results for hooks that were executed.
29
+ * @throws Error if a `failOnError` hook fails.
30
+ */
31
+ export declare function runWorktreeHooks(hooks: readonly WorktreeHook[], event: WorktreeHook['event'], worktreePath: string): Promise<WorktreeHookResult[]>;
32
+ //# sourceMappingURL=worktree-hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree-hooks.d.ts","sourceRoot":"","sources":["../src/worktree-hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAI5E;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,YAAY,EAClB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,kBAAkB,CAAC,CA6B7B;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,SAAS,YAAY,EAAE,EAC9B,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,EAC5B,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAiB/B"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Declarative worktree hooks framework — native lift of worktrunk's hooks
3
+ * feature per D030.
4
+ *
5
+ * Executes `post-create` and `post-start` hooks in the worktree directory.
6
+ * Each hook runs via `sh -c <command>` with the worktree path as CWD.
7
+ *
8
+ * @task T1161
9
+ */
10
+ import { execFile } from 'node:child_process';
11
+ const DEFAULT_HOOK_TIMEOUT_MS = 30_000;
12
+ /**
13
+ * Execute a single declarative hook in the given worktree directory.
14
+ *
15
+ * @param hook - The hook definition to execute.
16
+ * @param worktreePath - Absolute path to the worktree directory (CWD for hook).
17
+ * @returns Hook execution result.
18
+ */
19
+ export async function runSingleHook(hook, worktreePath) {
20
+ const timeoutMs = hook.timeoutMs ?? DEFAULT_HOOK_TIMEOUT_MS;
21
+ const start = Date.now();
22
+ return new Promise((resolve) => {
23
+ const child = execFile('sh', ['-c', hook.command], {
24
+ cwd: worktreePath,
25
+ timeout: timeoutMs,
26
+ encoding: 'utf-8',
27
+ }, (_err, stdout, stderr) => {
28
+ const durationMs = Date.now() - start;
29
+ const exitCode = child.exitCode;
30
+ const timedOut = exitCode === null && durationMs >= timeoutMs;
31
+ resolve({
32
+ hook,
33
+ success: exitCode === 0,
34
+ stdout: (typeof stdout === 'string' ? stdout : '').trim(),
35
+ stderr: (typeof stderr === 'string' ? stderr : '').trim(),
36
+ exitCode: timedOut ? null : (exitCode ?? 0),
37
+ durationMs,
38
+ });
39
+ });
40
+ });
41
+ }
42
+ /**
43
+ * Run all hooks matching a given lifecycle event in order.
44
+ *
45
+ * Hooks are run sequentially. If a hook has `failOnError: true` and exits
46
+ * non-zero, execution stops immediately and the error is propagated.
47
+ *
48
+ * @param hooks - All hook definitions (may include hooks for other events).
49
+ * @param event - The lifecycle event to filter and run.
50
+ * @param worktreePath - Absolute path to the worktree directory.
51
+ * @returns Array of results for hooks that were executed.
52
+ * @throws Error if a `failOnError` hook fails.
53
+ */
54
+ export async function runWorktreeHooks(hooks, event, worktreePath) {
55
+ const results = [];
56
+ const filtered = hooks.filter((h) => h.event === event);
57
+ for (const hook of filtered) {
58
+ const result = await runSingleHook(hook, worktreePath);
59
+ results.push(result);
60
+ if (!result.success && hook.failOnError) {
61
+ throw new Error(`Worktree hook failed (failOnError=true): ${hook.command}\n` +
62
+ `exit: ${result.exitCode}\nstderr: ${result.stderr}`);
63
+ }
64
+ }
65
+ return results;
66
+ }
67
+ //# sourceMappingURL=worktree-hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree-hooks.js","sourceRoot":"","sources":["../src/worktree-hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG9C,MAAM,uBAAuB,GAAG,MAAM,CAAC;AAEvC;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAAkB,EAClB,YAAoB;IAEpB,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,uBAAuB,CAAC;IAC5D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEzB,OAAO,IAAI,OAAO,CAAqB,CAAC,OAAO,EAAE,EAAE;QACjD,MAAM,KAAK,GAAG,QAAQ,CACpB,IAAI,EACJ,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,EACpB;YACE,GAAG,EAAE,YAAY;YACjB,OAAO,EAAE,SAAS;YAClB,QAAQ,EAAE,OAAO;SAClB,EACD,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YACvB,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;YACtC,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;YAChC,MAAM,QAAQ,GAAG,QAAQ,KAAK,IAAI,IAAI,UAAU,IAAI,SAAS,CAAC;YAE9D,OAAO,CAAC;gBACN,IAAI;gBACJ,OAAO,EAAE,QAAQ,KAAK,CAAC;gBACvB,MAAM,EAAE,CAAC,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE;gBACzD,MAAM,EAAE,CAAC,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE;gBACzD,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC;gBAC3C,UAAU;aACX,CAAC,CAAC;QACL,CAAC,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,KAA8B,EAC9B,KAA4B,EAC5B,YAAoB;IAEpB,MAAM,OAAO,GAAyB,EAAE,CAAC;IACzC,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;IAExD,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QACvD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAErB,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CACb,4CAA4C,IAAI,CAAC,OAAO,IAAI;gBAC1D,SAAS,MAAM,CAAC,QAAQ,aAAa,MAAM,CAAC,MAAM,EAAE,CACvD,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * `.cleo/worktree-include` glob pattern support — native lift of worktrunk's
3
+ * worktree-include feature per D030.
4
+ *
5
+ * The file `.cleo/worktree-include` in the project root contains glob patterns
6
+ * (one per line, `#`-prefixed comments stripped, blank lines ignored) that
7
+ * control which files/directories from the main project tree are symlinked
8
+ * into a newly created worktree.
9
+ *
10
+ * Lines prefixed with `!` are negated patterns (exclusions).
11
+ *
12
+ * Example `.cleo/worktree-include`:
13
+ * ```
14
+ * # Include pnpm store to avoid re-downloading in each worktree
15
+ * node_modules/.pnpm
16
+ * # Include shared config
17
+ * .env.local
18
+ * # Exclude secrets
19
+ * !.env.production
20
+ * ```
21
+ *
22
+ * @task T1161
23
+ */
24
+ import type { WorktreeIncludePattern } from '@cleocode/contracts';
25
+ /**
26
+ * Load and parse the `.cleo/worktree-include` file from the project root.
27
+ *
28
+ * Returns an empty array if the file does not exist. Comments (lines starting
29
+ * with `#`) and blank lines are ignored. Lines starting with `!` are parsed
30
+ * as negated patterns.
31
+ *
32
+ * @param projectRoot - Absolute path to the project root.
33
+ * @returns Parsed include patterns, or empty array if file is absent.
34
+ */
35
+ export declare function loadWorktreeIncludePatterns(projectRoot: string): WorktreeIncludePattern[];
36
+ /**
37
+ * Apply include patterns to a newly created worktree by creating symlinks
38
+ * from the worktree directory back to the main project tree.
39
+ *
40
+ * Only non-negated patterns are symlinked. Negated patterns are recorded for
41
+ * audit purposes but do not cause any filesystem action.
42
+ *
43
+ * Symlinks are created as: `<worktreePath>/<pattern>` → `<projectRoot>/<pattern>`
44
+ *
45
+ * Already-existing paths in the worktree are skipped (not overwritten) — git
46
+ * worktree add may have already created them.
47
+ *
48
+ * @param patterns - Parsed include patterns from {@link loadWorktreeIncludePatterns}.
49
+ * @param projectRoot - Absolute path to the project root (symlink target base).
50
+ * @param worktreePath - Absolute path to the worktree directory.
51
+ * @returns Array of patterns that were successfully symlinked.
52
+ */
53
+ export declare function applyIncludePatterns(patterns: readonly WorktreeIncludePattern[], projectRoot: string, worktreePath: string): WorktreeIncludePattern[];
54
+ //# sourceMappingURL=worktree-include.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree-include.d.ts","sourceRoot":"","sources":["../src/worktree-include.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAIlE;;;;;;;;;GASG;AACH,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,MAAM,GAAG,sBAAsB,EAAE,CAoBzF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,SAAS,sBAAsB,EAAE,EAC3C,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GACnB,sBAAsB,EAAE,CA2B1B"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * `.cleo/worktree-include` glob pattern support — native lift of worktrunk's
3
+ * worktree-include feature per D030.
4
+ *
5
+ * The file `.cleo/worktree-include` in the project root contains glob patterns
6
+ * (one per line, `#`-prefixed comments stripped, blank lines ignored) that
7
+ * control which files/directories from the main project tree are symlinked
8
+ * into a newly created worktree.
9
+ *
10
+ * Lines prefixed with `!` are negated patterns (exclusions).
11
+ *
12
+ * Example `.cleo/worktree-include`:
13
+ * ```
14
+ * # Include pnpm store to avoid re-downloading in each worktree
15
+ * node_modules/.pnpm
16
+ * # Include shared config
17
+ * .env.local
18
+ * # Exclude secrets
19
+ * !.env.production
20
+ * ```
21
+ *
22
+ * @task T1161
23
+ */
24
+ import { existsSync, readFileSync, symlinkSync } from 'node:fs';
25
+ import { join, resolve } from 'node:path';
26
+ const INCLUDE_FILE_NAME = 'worktree-include';
27
+ /**
28
+ * Load and parse the `.cleo/worktree-include` file from the project root.
29
+ *
30
+ * Returns an empty array if the file does not exist. Comments (lines starting
31
+ * with `#`) and blank lines are ignored. Lines starting with `!` are parsed
32
+ * as negated patterns.
33
+ *
34
+ * @param projectRoot - Absolute path to the project root.
35
+ * @returns Parsed include patterns, or empty array if file is absent.
36
+ */
37
+ export function loadWorktreeIncludePatterns(projectRoot) {
38
+ const filePath = join(projectRoot, '.cleo', INCLUDE_FILE_NAME);
39
+ if (!existsSync(filePath))
40
+ return [];
41
+ const raw = readFileSync(filePath, 'utf-8');
42
+ const patterns = [];
43
+ for (const line of raw.split('\n')) {
44
+ const trimmed = line.trim();
45
+ // Skip blank lines and comments
46
+ if (!trimmed || trimmed.startsWith('#'))
47
+ continue;
48
+ const negated = trimmed.startsWith('!');
49
+ const pattern = negated ? trimmed.slice(1).trim() : trimmed;
50
+ if (pattern) {
51
+ patterns.push({ pattern, negated });
52
+ }
53
+ }
54
+ return patterns;
55
+ }
56
+ /**
57
+ * Apply include patterns to a newly created worktree by creating symlinks
58
+ * from the worktree directory back to the main project tree.
59
+ *
60
+ * Only non-negated patterns are symlinked. Negated patterns are recorded for
61
+ * audit purposes but do not cause any filesystem action.
62
+ *
63
+ * Symlinks are created as: `<worktreePath>/<pattern>` → `<projectRoot>/<pattern>`
64
+ *
65
+ * Already-existing paths in the worktree are skipped (not overwritten) — git
66
+ * worktree add may have already created them.
67
+ *
68
+ * @param patterns - Parsed include patterns from {@link loadWorktreeIncludePatterns}.
69
+ * @param projectRoot - Absolute path to the project root (symlink target base).
70
+ * @param worktreePath - Absolute path to the worktree directory.
71
+ * @returns Array of patterns that were successfully symlinked.
72
+ */
73
+ export function applyIncludePatterns(patterns, projectRoot, worktreePath) {
74
+ const applied = [];
75
+ for (const entry of patterns) {
76
+ // Negated patterns are exclusions — no filesystem action needed.
77
+ if (entry.negated)
78
+ continue;
79
+ const sourcePath = resolve(projectRoot, entry.pattern);
80
+ const targetPath = resolve(worktreePath, entry.pattern);
81
+ // Skip if the source does not exist in the project tree.
82
+ if (!existsSync(sourcePath))
83
+ continue;
84
+ // Skip if a file/dir/symlink already exists at this path in the worktree.
85
+ if (existsSync(targetPath))
86
+ continue;
87
+ try {
88
+ symlinkSync(sourcePath, targetPath);
89
+ applied.push(entry);
90
+ }
91
+ catch {
92
+ // Non-fatal: log and continue. Callers can inspect applied[] to see
93
+ // which patterns succeeded.
94
+ process.stderr.write(`[worktree] include-pattern symlink failed: ${entry.pattern}\n`);
95
+ }
96
+ }
97
+ return applied;
98
+ }
99
+ //# sourceMappingURL=worktree-include.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree-include.js","sourceRoot":"","sources":["../src/worktree-include.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAG1C,MAAM,iBAAiB,GAAG,kBAAkB,CAAC;AAE7C;;;;;;;;;GASG;AACH,MAAM,UAAU,2BAA2B,CAAC,WAAmB;IAC7D,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,iBAAiB,CAAC,CAAC;IAC/D,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,EAAE,CAAC;IAErC,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAA6B,EAAE,CAAC;IAE9C,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,gCAAgC;QAChC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAElD,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACxC,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QAC5D,IAAI,OAAO,EAAE,CAAC;YACZ,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,oBAAoB,CAClC,QAA2C,EAC3C,WAAmB,EACnB,YAAoB;IAEpB,MAAM,OAAO,GAA6B,EAAE,CAAC;IAE7C,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC7B,iEAAiE;QACjE,IAAI,KAAK,CAAC,OAAO;YAAE,SAAS;QAE5B,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QACvD,MAAM,UAAU,GAAG,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAExD,yDAAyD;QACzD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;YAAE,SAAS;QAEtC,0EAA0E;QAC1E,IAAI,UAAU,CAAC,UAAU,CAAC;YAAE,SAAS;QAErC,IAAI,CAAC;YACH,WAAW,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YACpC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;QAAC,MAAM,CAAC;YACP,oEAAoE;YACpE,4BAA4B;YAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8CAA8C,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;QACxF,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Worktree listing operations for @cleocode/worktree.
3
+ *
4
+ * `listWorktrees` and `listWorktreesByProjectRoot` scan the CLEO XDG worktrees
5
+ * directory to return structured entries.
6
+ *
7
+ * @task T1161
8
+ */
9
+ import type { ListWorktreesOptions, WorktreeListEntry } from '@cleocode/contracts';
10
+ /**
11
+ * Resolve the worktree root directory for a given project hash.
12
+ *
13
+ * Exported so callers can inspect the canonical path without creating a worktree.
14
+ *
15
+ * @param projectHash - 16-char project hash.
16
+ * @param worktreeRoot - Optional explicit override for the root path.
17
+ * @returns Absolute path to the worktrees root directory for this project.
18
+ */
19
+ export declare function resolveWorktreeRoot(projectHash: string, worktreeRoot?: string): string;
20
+ /**
21
+ * List all active CLEO worktrees scoped to a specific project hash.
22
+ *
23
+ * Scans the XDG worktrees filesystem directory. Entries without a valid
24
+ * worktree path on disk are omitted.
25
+ *
26
+ * @param options - Listing options including optional project hash filter.
27
+ * @returns Array of worktree entries.
28
+ */
29
+ export declare function listWorktrees(options?: ListWorktreesOptions): WorktreeListEntry[];
30
+ /**
31
+ * List all active CLEO worktrees for a specific project root.
32
+ *
33
+ * Computes the project hash from the project root, then delegates to
34
+ * {@link listWorktrees} with the computed hash as filter.
35
+ *
36
+ * @param projectRoot - Absolute path to the project root directory.
37
+ * @returns Array of worktree list entries for this project.
38
+ */
39
+ export declare function listWorktreesByProjectRoot(projectRoot: string): WorktreeListEntry[];
40
+ //# sourceMappingURL=worktree-list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree-list.d.ts","sourceRoot":"","sources":["../src/worktree-list.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAMnF;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAEtF;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,iBAAiB,EAAE,CA2CrF;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAGnF"}