@agentteams/cli 0.1.71 → 0.1.73

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 (87) hide show
  1. package/.prettierrc.json +2 -1
  2. package/README.md +10 -13
  3. package/dist/api/changeSet.d.ts +8 -0
  4. package/dist/api/changeSet.d.ts.map +1 -0
  5. package/dist/api/changeSet.js +41 -0
  6. package/dist/api/changeSet.js.map +1 -0
  7. package/dist/api/codeReview.d.ts +1 -0
  8. package/dist/api/codeReview.d.ts.map +1 -1
  9. package/dist/api/codeReview.js +6 -0
  10. package/dist/api/codeReview.js.map +1 -1
  11. package/dist/api/comment.d.ts +8 -0
  12. package/dist/api/comment.d.ts.map +1 -1
  13. package/dist/api/comment.js +23 -0
  14. package/dist/api/comment.js.map +1 -1
  15. package/dist/api/task.d.ts +1 -0
  16. package/dist/api/task.d.ts.map +1 -1
  17. package/dist/api/task.js +8 -0
  18. package/dist/api/task.js.map +1 -1
  19. package/dist/commands/agentConfig.js +2 -2
  20. package/dist/commands/agentConfig.js.map +1 -1
  21. package/dist/commands/changeSet.d.ts +14 -0
  22. package/dist/commands/changeSet.d.ts.map +1 -0
  23. package/dist/commands/changeSet.js +52 -0
  24. package/dist/commands/changeSet.js.map +1 -0
  25. package/dist/commands/changeSetCommand.d.ts +8 -0
  26. package/dist/commands/changeSetCommand.d.ts.map +1 -0
  27. package/dist/commands/changeSetCommand.js +62 -0
  28. package/dist/commands/changeSetCommand.js.map +1 -0
  29. package/dist/commands/codeReview.d.ts.map +1 -1
  30. package/dist/commands/codeReview.js +13 -3
  31. package/dist/commands/codeReview.js.map +1 -1
  32. package/dist/commands/comment.d.ts.map +1 -1
  33. package/dist/commands/comment.js +42 -8
  34. package/dist/commands/comment.js.map +1 -1
  35. package/dist/commands/convention.js +2 -2
  36. package/dist/commands/convention.js.map +1 -1
  37. package/dist/commands/dependency.js +2 -2
  38. package/dist/commands/dependency.js.map +1 -1
  39. package/dist/commands/doctor.d.ts +38 -0
  40. package/dist/commands/doctor.d.ts.map +1 -0
  41. package/dist/commands/doctor.js +246 -0
  42. package/dist/commands/doctor.js.map +1 -0
  43. package/dist/commands/feedback.d.ts.map +1 -1
  44. package/dist/commands/feedback.js +5 -2
  45. package/dist/commands/feedback.js.map +1 -1
  46. package/dist/commands/index.d.ts.map +1 -1
  47. package/dist/commands/index.js +13 -2
  48. package/dist/commands/index.js.map +1 -1
  49. package/dist/commands/init.d.ts +9 -1
  50. package/dist/commands/init.d.ts.map +1 -1
  51. package/dist/commands/init.js +71 -39
  52. package/dist/commands/init.js.map +1 -1
  53. package/dist/commands/task.d.ts.map +1 -1
  54. package/dist/commands/task.js +12 -6
  55. package/dist/commands/task.js.map +1 -1
  56. package/dist/index.js +95 -33
  57. package/dist/index.js.map +1 -1
  58. package/dist/utils/config.d.ts +1 -0
  59. package/dist/utils/config.d.ts.map +1 -1
  60. package/dist/utils/config.js +19 -0
  61. package/dist/utils/config.js.map +1 -1
  62. package/dist/utils/conventionLink.d.ts +79 -0
  63. package/dist/utils/conventionLink.d.ts.map +1 -0
  64. package/dist/utils/conventionLink.js +567 -0
  65. package/dist/utils/conventionLink.js.map +1 -0
  66. package/dist/utils/doctorOutput.d.ts +5 -0
  67. package/dist/utils/doctorOutput.d.ts.map +1 -0
  68. package/dist/utils/doctorOutput.js +47 -0
  69. package/dist/utils/doctorOutput.js.map +1 -0
  70. package/dist/utils/entityId.d.ts.map +1 -1
  71. package/dist/utils/entityId.js +3 -2
  72. package/dist/utils/entityId.js.map +1 -1
  73. package/dist/utils/initOutput.d.ts.map +1 -1
  74. package/dist/utils/initOutput.js +29 -2
  75. package/dist/utils/initOutput.js.map +1 -1
  76. package/dist/utils/interactiveCommand.d.ts +7 -0
  77. package/dist/utils/interactiveCommand.d.ts.map +1 -0
  78. package/dist/utils/interactiveCommand.js +13 -0
  79. package/dist/utils/interactiveCommand.js.map +1 -0
  80. package/dist/utils/outputPolicy.d.ts.map +1 -1
  81. package/dist/utils/outputPolicy.js +1 -23
  82. package/dist/utils/outputPolicy.js.map +1 -1
  83. package/dist/utils/projectLayout.d.ts +19 -0
  84. package/dist/utils/projectLayout.d.ts.map +1 -0
  85. package/dist/utils/projectLayout.js +65 -0
  86. package/dist/utils/projectLayout.js.map +1 -0
  87. package/package.json +2 -2
@@ -0,0 +1,79 @@
1
+ export declare const DEFAULT_CONVENTION_REFERENCE = "---\nalwaysApply: true\n---\n\n# AGENT_RULES\n\n**Before starting any task, always refer to `.agentteams/convention.md`.**\n";
2
+ export declare const POST_CHECKOUT_HOOK_MARKER = "# AgentTeams managed post-checkout hook";
3
+ export declare const POST_CHECKOUT_HOOK_SCRIPT = "#!/bin/sh\n# AgentTeams managed post-checkout hook\n# Materializes AgentTeams convention entry points in a fresh linked worktree.\n# This hook must never fail the checkout: it always exits 0.\n\nprevious_head=\"$1\"\nbranch_checkout=\"$3\"\n\nif [ \"$branch_checkout\" != \"1\" ]; then\n exit 0\nfi\n\n# git worktree add reports the previous HEAD as the all-zero object id; a\n# regular branch checkout reports the real previous commit, which must not\n# trigger a bootstrap.\ncase \"$previous_head\" in\n 0000000000000000000000000000000000000000 | 0000000000000000000000000000000000000000000000000000000000000000) ;;\n *)\n exit 0\n ;;\nesac\n\nif ! command -v agentteams >/dev/null 2>&1; then\n echo \"agentteams: skipped worktree bootstrap (agentteams CLI not found in PATH)\" >&2\n exit 0\nfi\n\nif ! agentteams init --format json >/dev/null 2>&1; then\n echo \"agentteams: worktree bootstrap failed (agentteams init exited non-zero)\" >&2\nfi\n\nexit 0\n";
4
+ export type ConventionLinkState = 'absent' | 'ready' | 'broken' | 'wrong-target' | 'occupied';
5
+ export type ConventionIssueCode = 'not-a-git-repo' | 'root-agentteams-missing' | 'link-broken' | 'link-wrong-target' | 'link-occupied' | 'link-create-failed' | 'exclude-read-failed' | 'exclude-write-failed' | 'exclude-unsafe-path' | 'entry-point-write-failed' | 'entry-point-conflict' | 'hook-custom' | 'hook-hookspath' | 'hook-read-failed' | 'hook-write-failed' | 'hook-unsafe-path';
6
+ export interface ConventionIssue {
7
+ code: ConventionIssueCode;
8
+ path: string;
9
+ message: string;
10
+ }
11
+ export interface EnsureConventionLinkResult {
12
+ status: 'ready' | 'blocked';
13
+ state: ConventionLinkState;
14
+ changed: boolean;
15
+ linkPath: string;
16
+ issue?: ConventionIssue;
17
+ }
18
+ export interface EnsureLocalExcludeResult {
19
+ status: 'ready' | 'blocked';
20
+ changed: boolean;
21
+ excludePath: string | null;
22
+ addedPatterns: string[];
23
+ issue?: ConventionIssue;
24
+ }
25
+ export interface EnsurePostCheckoutHookResult {
26
+ status: 'ready' | 'blocked';
27
+ changed: boolean;
28
+ hookPath: string | null;
29
+ issue?: ConventionIssue;
30
+ }
31
+ export type ConventionEntryPointState = 'created' | 'tracked' | 'existing' | 'blocked';
32
+ export interface ConventionEntryPointEntry {
33
+ relativePath: string;
34
+ state: ConventionEntryPointState;
35
+ compatible: boolean;
36
+ }
37
+ export interface EnsureConventionEntryPointsResult {
38
+ entries: ConventionEntryPointEntry[];
39
+ issues: ConventionIssue[];
40
+ changedCount: number;
41
+ ready: boolean;
42
+ }
43
+ /** Anchored pattern for `git-common-dir/info/exclude` (repo-root relative). */
44
+ export declare function toAnchoredExcludePattern(relativePath: string): string;
45
+ export declare function isReadableRegularFile(path: string): boolean;
46
+ export declare function ensureConventionEntryPoints(repoDir: string, relativePaths: string[], options: {
47
+ allowCreate: boolean;
48
+ validateExistingReference: boolean;
49
+ }): EnsureConventionEntryPointsResult;
50
+ /**
51
+ * Classify the `.agentteams` entry of a member repository. Correctness is
52
+ * judged by the canonical target — not the raw link string — so both POSIX
53
+ * relative symlinks and Windows junctions count as `ready` when they resolve
54
+ * to the convention root's `.agentteams`.
55
+ */
56
+ export declare function inspectConventionLink(rootDir: string, repoDir: string): ConventionLinkState;
57
+ /**
58
+ * Create the `.agentteams` link only when nothing exists at the path yet.
59
+ * Existing entries — broken links, links to another target, or real files and
60
+ * directories — are preserved and surfaced as issues. A copy fallback is
61
+ * intentionally not offered because copies break the sync guarantee.
62
+ */
63
+ export declare function ensureConventionLink(rootDir: string, repoDir: string): EnsureConventionLinkResult;
64
+ /**
65
+ * Register anchored patterns in `git-common-dir/info/exclude`. The exclude
66
+ * file is shared by every linked worktree, unlike the tracked `.gitignore`,
67
+ * which must never be modified. Existing content and line endings are
68
+ * preserved; each pattern is appended at most once (exact-line match).
69
+ */
70
+ export declare function ensureLocalExclude(repoDir: string, patterns: string[]): EnsureLocalExcludeResult;
71
+ /**
72
+ * Install or refresh the managed `post-checkout` hook in
73
+ * `git-common-dir/hooks`. A hook is only written when no hook exists or the
74
+ * existing hook carries the exact managed marker on its second line. A
75
+ * non-empty `core.hooksPath` or an unmanaged hook blocks installation —
76
+ * silently redirecting user-managed hook infrastructure is never safe.
77
+ */
78
+ export declare function ensurePostCheckoutHook(repoDir: string): EnsurePostCheckoutHookResult;
79
+ //# sourceMappingURL=conventionLink.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conventionLink.d.ts","sourceRoot":"","sources":["../../src/utils/conventionLink.ts"],"names":[],"mappings":"AAsBA,eAAO,MAAM,4BAA4B,iIAOxC,CAAC;AAEF,eAAO,MAAM,yBAAyB,4CAA4C,CAAC;AAKnF,eAAO,MAAM,yBAAyB,g9BAgCrC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,cAAc,GAAG,UAAU,CAAC;AAE9F,MAAM,MAAM,mBAAmB,GAC3B,gBAAgB,GAChB,yBAAyB,GACzB,aAAa,GACb,mBAAmB,GACnB,eAAe,GACf,oBAAoB,GACpB,qBAAqB,GACrB,sBAAsB,GACtB,qBAAqB,GACrB,0BAA0B,GAC1B,sBAAsB,GACtB,aAAa,GACb,gBAAgB,GAChB,kBAAkB,GAClB,mBAAmB,GACnB,kBAAkB,CAAC;AAEvB,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,KAAK,EAAE,mBAAmB,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,eAAe,CAAC;CACzB;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,eAAe,CAAC;CACzB;AAED,MAAM,WAAW,4BAA4B;IAC3C,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,CAAC,EAAE,eAAe,CAAC;CACzB;AAED,MAAM,MAAM,yBAAyB,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;AAEvF,MAAM,WAAW,yBAAyB;IACxC,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,yBAAyB,CAAC;IACjC,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,iCAAiC;IAChD,OAAO,EAAE,yBAAyB,EAAE,CAAC;IACrC,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,+EAA+E;AAC/E,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAErE;AA4ID,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAS3D;AAkCD,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,MAAM,EAAE,EACvB,OAAO,EAAE;IAAE,WAAW,EAAE,OAAO,CAAC;IAAC,yBAAyB,EAAE,OAAO,CAAA;CAAE,GACpE,iCAAiC,CAwEnC;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,mBAAmB,CAoB3F;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,0BAA0B,CAqEjG;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,wBAAwB,CA2EhG;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,4BAA4B,CAoGpF"}
@@ -0,0 +1,567 @@
1
+ import { chmodSync, closeSync, constants as fsConstants, existsSync, fsyncSync, lstatSync, mkdirSync, openSync, readFileSync, realpathSync, renameSync, rmSync, statSync, symlinkSync, writeFileSync, } from 'node:fs';
2
+ import { execFileSync } from 'node:child_process';
3
+ import { basename, dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';
4
+ const CONFIG_DIR = '.agentteams';
5
+ export const DEFAULT_CONVENTION_REFERENCE = `---
6
+ alwaysApply: true
7
+ ---
8
+
9
+ # AGENT_RULES
10
+
11
+ **Before starting any task, always refer to \`.agentteams/convention.md\`.**
12
+ `;
13
+ export const POST_CHECKOUT_HOOK_MARKER = '# AgentTeams managed post-checkout hook';
14
+ // The marker must stay on the exact second line (the first line has to be the
15
+ // shebang) — ensurePostCheckoutHook uses it to tell managed hooks from user
16
+ // hooks it must never overwrite.
17
+ export const POST_CHECKOUT_HOOK_SCRIPT = `#!/bin/sh
18
+ ${POST_CHECKOUT_HOOK_MARKER}
19
+ # Materializes AgentTeams convention entry points in a fresh linked worktree.
20
+ # This hook must never fail the checkout: it always exits 0.
21
+
22
+ previous_head="$1"
23
+ branch_checkout="$3"
24
+
25
+ if [ "$branch_checkout" != "1" ]; then
26
+ exit 0
27
+ fi
28
+
29
+ # git worktree add reports the previous HEAD as the all-zero object id; a
30
+ # regular branch checkout reports the real previous commit, which must not
31
+ # trigger a bootstrap.
32
+ case "$previous_head" in
33
+ 0000000000000000000000000000000000000000 | 0000000000000000000000000000000000000000000000000000000000000000) ;;
34
+ *)
35
+ exit 0
36
+ ;;
37
+ esac
38
+
39
+ if ! command -v agentteams >/dev/null 2>&1; then
40
+ echo "agentteams: skipped worktree bootstrap (agentteams CLI not found in PATH)" >&2
41
+ exit 0
42
+ fi
43
+
44
+ if ! agentteams init --format json >/dev/null 2>&1; then
45
+ echo "agentteams: worktree bootstrap failed (agentteams init exited non-zero)" >&2
46
+ fi
47
+
48
+ exit 0
49
+ `;
50
+ /** Anchored pattern for `git-common-dir/info/exclude` (repo-root relative). */
51
+ export function toAnchoredExcludePattern(relativePath) {
52
+ return `/${relativePath.replace(/\\/g, '/').replace(/^\/+/, '')}`;
53
+ }
54
+ function runGit(args, cwd) {
55
+ try {
56
+ const output = execFileSync('git', args, {
57
+ cwd,
58
+ encoding: 'utf8',
59
+ stdio: ['ignore', 'pipe', 'ignore'],
60
+ windowsHide: true,
61
+ });
62
+ const trimmed = output.trim();
63
+ return trimmed.length > 0 ? trimmed : null;
64
+ }
65
+ catch {
66
+ return null;
67
+ }
68
+ }
69
+ function resolveGitCommonDir(repoDir) {
70
+ const commonDir = runGit(['rev-parse', '--git-common-dir'], repoDir);
71
+ if (!commonDir)
72
+ return null;
73
+ return isAbsolute(commonDir) ? resolve(commonDir) : resolve(repoDir, commonDir);
74
+ }
75
+ function toErrorMessage(error) {
76
+ return error instanceof Error ? error.message : String(error);
77
+ }
78
+ function isContainedPath(parentPath, candidatePath) {
79
+ const relativePath = relative(parentPath, candidatePath);
80
+ return (relativePath === '' || (!relativePath.startsWith(`..${sep}`) && relativePath !== '..' && !isAbsolute(relativePath)));
81
+ }
82
+ function unsafeMetadataIssue(code, path, description) {
83
+ return {
84
+ code,
85
+ path,
86
+ message: `Refusing to modify unsafe git metadata path ${path}: ${description}.`,
87
+ };
88
+ }
89
+ function prepareMetadataPath(commonDir, directoryName, fileName, issueCode) {
90
+ let canonicalCommonDir;
91
+ try {
92
+ canonicalCommonDir = realpathSync(commonDir);
93
+ }
94
+ catch (error) {
95
+ const filePath = join(commonDir, directoryName, fileName);
96
+ return {
97
+ filePath,
98
+ exists: false,
99
+ mode: 0o644,
100
+ issue: unsafeMetadataIssue(issueCode, filePath, toErrorMessage(error)),
101
+ };
102
+ }
103
+ const directoryPath = join(commonDir, directoryName);
104
+ const filePath = join(directoryPath, fileName);
105
+ try {
106
+ let directoryStats;
107
+ try {
108
+ directoryStats = lstatSync(directoryPath);
109
+ }
110
+ catch {
111
+ mkdirSync(directoryPath);
112
+ directoryStats = lstatSync(directoryPath);
113
+ }
114
+ if (directoryStats.isSymbolicLink() || !directoryStats.isDirectory()) {
115
+ return {
116
+ filePath,
117
+ exists: false,
118
+ mode: 0o644,
119
+ issue: unsafeMetadataIssue(issueCode, directoryPath, 'the parent is a symlink or is not a directory'),
120
+ };
121
+ }
122
+ const canonicalDirectory = realpathSync(directoryPath);
123
+ if (!isContainedPath(canonicalCommonDir, canonicalDirectory)) {
124
+ return {
125
+ filePath,
126
+ exists: false,
127
+ mode: 0o644,
128
+ issue: unsafeMetadataIssue(issueCode, directoryPath, 'the parent resolves outside git-common-dir'),
129
+ };
130
+ }
131
+ try {
132
+ const fileStats = lstatSync(filePath);
133
+ if (fileStats.isSymbolicLink() || !fileStats.isFile()) {
134
+ return {
135
+ filePath,
136
+ exists: true,
137
+ mode: fileStats.mode & 0o777,
138
+ issue: unsafeMetadataIssue(issueCode, filePath, 'the target is a symlink or is not a regular file'),
139
+ };
140
+ }
141
+ return { filePath, exists: true, mode: fileStats.mode & 0o777 };
142
+ }
143
+ catch {
144
+ return { filePath, exists: false, mode: 0o644 };
145
+ }
146
+ }
147
+ catch (error) {
148
+ return {
149
+ filePath,
150
+ exists: false,
151
+ mode: 0o644,
152
+ issue: unsafeMetadataIssue(issueCode, filePath, toErrorMessage(error)),
153
+ };
154
+ }
155
+ }
156
+ function writeFileAtomically(path, content, mode) {
157
+ const tempPath = join(dirname(path), `.${basename(path)}.agentteams-${process.pid}-${Date.now()}`);
158
+ let fileDescriptor = null;
159
+ try {
160
+ const noFollow = fsConstants.O_NOFOLLOW ?? 0;
161
+ fileDescriptor = openSync(tempPath, fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL | noFollow, mode);
162
+ writeFileSync(fileDescriptor, content, 'utf-8');
163
+ fsyncSync(fileDescriptor);
164
+ closeSync(fileDescriptor);
165
+ fileDescriptor = null;
166
+ renameSync(tempPath, path);
167
+ }
168
+ finally {
169
+ if (fileDescriptor !== null)
170
+ closeSync(fileDescriptor);
171
+ rmSync(tempPath, { force: true });
172
+ }
173
+ }
174
+ export function isReadableRegularFile(path) {
175
+ try {
176
+ lstatSync(path);
177
+ if (!statSync(path).isFile())
178
+ return false;
179
+ readFileSync(path);
180
+ return true;
181
+ }
182
+ catch {
183
+ return false;
184
+ }
185
+ }
186
+ function isTrackedInRepo(repoDir, relativePath) {
187
+ try {
188
+ execFileSync('git', ['ls-files', '--error-unmatch', '--', relativePath], {
189
+ cwd: repoDir,
190
+ stdio: ['ignore', 'ignore', 'ignore'],
191
+ windowsHide: true,
192
+ });
193
+ return true;
194
+ }
195
+ catch {
196
+ return false;
197
+ }
198
+ }
199
+ function ensureEntryPointParent(repoDir, relativePath) {
200
+ const parentRelativePath = dirname(relativePath);
201
+ if (parentRelativePath === '.')
202
+ return;
203
+ let currentPath = repoDir;
204
+ for (const segment of parentRelativePath.split(/[\\/]/).filter(Boolean)) {
205
+ currentPath = join(currentPath, segment);
206
+ try {
207
+ const stats = lstatSync(currentPath);
208
+ if (stats.isSymbolicLink() || !stats.isDirectory()) {
209
+ throw new Error(`${currentPath} is a symlink or is not a directory`);
210
+ }
211
+ }
212
+ catch (error) {
213
+ if (error instanceof Error && error.message.includes('is a symlink or is not a directory'))
214
+ throw error;
215
+ mkdirSync(currentPath);
216
+ }
217
+ }
218
+ }
219
+ export function ensureConventionEntryPoints(repoDir, relativePaths, options) {
220
+ const entries = [];
221
+ const issues = [];
222
+ let changedCount = 0;
223
+ for (const relativePath of relativePaths) {
224
+ const fullPath = join(repoDir, relativePath);
225
+ let pathExists = false;
226
+ try {
227
+ lstatSync(fullPath);
228
+ pathExists = true;
229
+ }
230
+ catch {
231
+ pathExists = false;
232
+ }
233
+ if (pathExists) {
234
+ const state = isTrackedInRepo(repoDir, relativePath) ? 'tracked' : 'existing';
235
+ let compatible = true;
236
+ if (options.validateExistingReference) {
237
+ try {
238
+ compatible = statSync(fullPath).isFile() && readFileSync(fullPath, 'utf-8') === DEFAULT_CONVENTION_REFERENCE;
239
+ }
240
+ catch {
241
+ compatible = false;
242
+ }
243
+ }
244
+ entries.push({ relativePath, state, compatible });
245
+ if (!compatible) {
246
+ issues.push({
247
+ code: 'entry-point-conflict',
248
+ path: fullPath,
249
+ message: `${relativePath} in ${repoDir} is ${state} and does not match the standard convention reference; not modifying it.`,
250
+ });
251
+ }
252
+ continue;
253
+ }
254
+ if (!options.allowCreate) {
255
+ entries.push({ relativePath, state: 'blocked', compatible: false });
256
+ continue;
257
+ }
258
+ try {
259
+ ensureEntryPointParent(repoDir, relativePath);
260
+ const noFollow = fsConstants.O_NOFOLLOW ?? 0;
261
+ const fileDescriptor = openSync(fullPath, fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL | noFollow, 0o644);
262
+ try {
263
+ writeFileSync(fileDescriptor, DEFAULT_CONVENTION_REFERENCE, 'utf-8');
264
+ }
265
+ finally {
266
+ closeSync(fileDescriptor);
267
+ }
268
+ entries.push({ relativePath, state: 'created', compatible: true });
269
+ changedCount += 1;
270
+ }
271
+ catch (error) {
272
+ issues.push({
273
+ code: 'entry-point-write-failed',
274
+ path: fullPath,
275
+ message: `Could not create ${fullPath}: ${toErrorMessage(error)}`,
276
+ });
277
+ entries.push({ relativePath, state: 'blocked', compatible: false });
278
+ }
279
+ }
280
+ return {
281
+ entries,
282
+ issues,
283
+ changedCount,
284
+ ready: entries.every((entry) => entry.state !== 'blocked' && entry.compatible),
285
+ };
286
+ }
287
+ /**
288
+ * Classify the `.agentteams` entry of a member repository. Correctness is
289
+ * judged by the canonical target — not the raw link string — so both POSIX
290
+ * relative symlinks and Windows junctions count as `ready` when they resolve
291
+ * to the convention root's `.agentteams`.
292
+ */
293
+ export function inspectConventionLink(rootDir, repoDir) {
294
+ const linkPath = join(repoDir, CONFIG_DIR);
295
+ let stats;
296
+ try {
297
+ stats = lstatSync(linkPath);
298
+ }
299
+ catch {
300
+ return 'absent';
301
+ }
302
+ if (!stats.isSymbolicLink())
303
+ return 'occupied';
304
+ if (!existsSync(linkPath))
305
+ return 'broken';
306
+ try {
307
+ const canonicalTarget = realpathSync(linkPath);
308
+ const canonicalRoot = realpathSync(join(rootDir, CONFIG_DIR));
309
+ return canonicalTarget === canonicalRoot ? 'ready' : 'wrong-target';
310
+ }
311
+ catch {
312
+ return 'broken';
313
+ }
314
+ }
315
+ /**
316
+ * Create the `.agentteams` link only when nothing exists at the path yet.
317
+ * Existing entries — broken links, links to another target, or real files and
318
+ * directories — are preserved and surfaced as issues. A copy fallback is
319
+ * intentionally not offered because copies break the sync guarantee.
320
+ */
321
+ export function ensureConventionLink(rootDir, repoDir) {
322
+ const linkPath = join(repoDir, CONFIG_DIR);
323
+ const rootConfigDir = join(rootDir, CONFIG_DIR);
324
+ if (!existsSync(rootConfigDir)) {
325
+ return {
326
+ status: 'blocked',
327
+ state: 'absent',
328
+ changed: false,
329
+ linkPath,
330
+ issue: {
331
+ code: 'root-agentteams-missing',
332
+ path: rootConfigDir,
333
+ message: `Convention root directory not found: ${rootConfigDir}`,
334
+ },
335
+ };
336
+ }
337
+ const state = inspectConventionLink(rootDir, repoDir);
338
+ if (state === 'ready') {
339
+ return { status: 'ready', state, changed: false, linkPath };
340
+ }
341
+ if (state !== 'absent') {
342
+ const issueByState = {
343
+ broken: {
344
+ code: 'link-broken',
345
+ path: linkPath,
346
+ message: `A broken .agentteams symlink exists at ${linkPath}; remove it manually and re-run.`,
347
+ },
348
+ 'wrong-target': {
349
+ code: 'link-wrong-target',
350
+ path: linkPath,
351
+ message: `The .agentteams link at ${linkPath} points somewhere other than the convention root; not modifying it.`,
352
+ },
353
+ occupied: {
354
+ code: 'link-occupied',
355
+ path: linkPath,
356
+ message: `A file or directory already exists at ${linkPath}; not overwriting it.`,
357
+ },
358
+ };
359
+ return { status: 'blocked', state, changed: false, linkPath, issue: issueByState[state] };
360
+ }
361
+ try {
362
+ if (process.platform === 'win32') {
363
+ // Junctions work without elevated privileges; they only accept
364
+ // absolute targets, so this is the documented platform exception to
365
+ // the relative-link rule.
366
+ symlinkSync(realpathSync(rootConfigDir), linkPath, 'junction');
367
+ }
368
+ else {
369
+ const linkTarget = relative(realpathSync(repoDir), realpathSync(rootConfigDir));
370
+ symlinkSync(linkTarget, linkPath, 'dir');
371
+ }
372
+ return { status: 'ready', state: 'ready', changed: true, linkPath };
373
+ }
374
+ catch (error) {
375
+ return {
376
+ status: 'blocked',
377
+ state: 'absent',
378
+ changed: false,
379
+ linkPath,
380
+ issue: {
381
+ code: 'link-create-failed',
382
+ path: linkPath,
383
+ message: `Could not create the .agentteams link at ${linkPath}: ${toErrorMessage(error)}`,
384
+ },
385
+ };
386
+ }
387
+ }
388
+ /**
389
+ * Register anchored patterns in `git-common-dir/info/exclude`. The exclude
390
+ * file is shared by every linked worktree, unlike the tracked `.gitignore`,
391
+ * which must never be modified. Existing content and line endings are
392
+ * preserved; each pattern is appended at most once (exact-line match).
393
+ */
394
+ export function ensureLocalExclude(repoDir, patterns) {
395
+ const commonDir = resolveGitCommonDir(repoDir);
396
+ if (!commonDir) {
397
+ return {
398
+ status: 'blocked',
399
+ changed: false,
400
+ excludePath: null,
401
+ addedPatterns: [],
402
+ issue: {
403
+ code: 'not-a-git-repo',
404
+ path: repoDir,
405
+ message: `Not a git repository: ${repoDir}`,
406
+ },
407
+ };
408
+ }
409
+ const metadataPath = prepareMetadataPath(commonDir, 'info', 'exclude', 'exclude-unsafe-path');
410
+ const excludePath = metadataPath.filePath;
411
+ if (metadataPath.issue) {
412
+ return {
413
+ status: 'blocked',
414
+ changed: false,
415
+ excludePath,
416
+ addedPatterns: [],
417
+ issue: metadataPath.issue,
418
+ };
419
+ }
420
+ let existing = '';
421
+ if (metadataPath.exists) {
422
+ try {
423
+ existing = readFileSync(excludePath, 'utf-8');
424
+ }
425
+ catch (error) {
426
+ return {
427
+ status: 'blocked',
428
+ changed: false,
429
+ excludePath,
430
+ addedPatterns: [],
431
+ issue: {
432
+ code: 'exclude-read-failed',
433
+ path: excludePath,
434
+ message: `Could not read ${excludePath}: ${toErrorMessage(error)}`,
435
+ },
436
+ };
437
+ }
438
+ }
439
+ const existingLines = new Set(existing.split('\n').map((line) => line.replace(/\r$/, '')));
440
+ const missing = patterns.filter((pattern) => !existingLines.has(pattern));
441
+ if (missing.length === 0) {
442
+ return { status: 'ready', changed: false, excludePath, addedPatterns: [] };
443
+ }
444
+ try {
445
+ const separator = existing.length === 0 || existing.endsWith('\n') ? '' : '\n';
446
+ writeFileAtomically(excludePath, existing + separator + missing.map((pattern) => `${pattern}\n`).join(''), metadataPath.mode);
447
+ return { status: 'ready', changed: true, excludePath, addedPatterns: missing };
448
+ }
449
+ catch (error) {
450
+ return {
451
+ status: 'blocked',
452
+ changed: false,
453
+ excludePath,
454
+ addedPatterns: [],
455
+ issue: {
456
+ code: 'exclude-write-failed',
457
+ path: excludePath,
458
+ message: `Could not update ${excludePath}: ${toErrorMessage(error)}`,
459
+ },
460
+ };
461
+ }
462
+ }
463
+ /**
464
+ * Install or refresh the managed `post-checkout` hook in
465
+ * `git-common-dir/hooks`. A hook is only written when no hook exists or the
466
+ * existing hook carries the exact managed marker on its second line. A
467
+ * non-empty `core.hooksPath` or an unmanaged hook blocks installation —
468
+ * silently redirecting user-managed hook infrastructure is never safe.
469
+ */
470
+ export function ensurePostCheckoutHook(repoDir) {
471
+ const commonDir = resolveGitCommonDir(repoDir);
472
+ if (!commonDir) {
473
+ return {
474
+ status: 'blocked',
475
+ changed: false,
476
+ hookPath: null,
477
+ issue: {
478
+ code: 'not-a-git-repo',
479
+ path: repoDir,
480
+ message: `Not a git repository: ${repoDir}`,
481
+ },
482
+ };
483
+ }
484
+ const hooksPathConfig = runGit(['config', '--get', 'core.hooksPath'], repoDir);
485
+ if (hooksPathConfig) {
486
+ return {
487
+ status: 'blocked',
488
+ changed: false,
489
+ hookPath: null,
490
+ issue: {
491
+ code: 'hook-hookspath',
492
+ path: hooksPathConfig,
493
+ message: `core.hooksPath is set (${hooksPathConfig}); the managed post-checkout hook cannot take effect.`,
494
+ },
495
+ };
496
+ }
497
+ const metadataPath = prepareMetadataPath(commonDir, 'hooks', 'post-checkout', 'hook-unsafe-path');
498
+ const hookPath = metadataPath.filePath;
499
+ if (metadataPath.issue) {
500
+ return {
501
+ status: 'blocked',
502
+ changed: false,
503
+ hookPath,
504
+ issue: metadataPath.issue,
505
+ };
506
+ }
507
+ let existing = null;
508
+ if (metadataPath.exists) {
509
+ try {
510
+ existing = readFileSync(hookPath, 'utf-8');
511
+ }
512
+ catch (error) {
513
+ return {
514
+ status: 'blocked',
515
+ changed: false,
516
+ hookPath,
517
+ issue: {
518
+ code: 'hook-read-failed',
519
+ path: hookPath,
520
+ message: `Could not read ${hookPath}: ${toErrorMessage(error)}`,
521
+ },
522
+ };
523
+ }
524
+ const secondLine = existing.split(/\r?\n/)[1] ?? '';
525
+ if (secondLine !== POST_CHECKOUT_HOOK_MARKER) {
526
+ return {
527
+ status: 'blocked',
528
+ changed: false,
529
+ hookPath,
530
+ issue: {
531
+ code: 'hook-custom',
532
+ path: hookPath,
533
+ message: `An unmanaged post-checkout hook exists at ${hookPath}; not overwriting it.`,
534
+ },
535
+ };
536
+ }
537
+ }
538
+ try {
539
+ if (existing === POST_CHECKOUT_HOOK_SCRIPT) {
540
+ if (process.platform !== 'win32' && (statSync(hookPath).mode & 0o111) === 0) {
541
+ chmodSync(hookPath, 0o755);
542
+ return { status: 'ready', changed: true, hookPath };
543
+ }
544
+ return { status: 'ready', changed: false, hookPath };
545
+ }
546
+ writeFileAtomically(hookPath, POST_CHECKOUT_HOOK_SCRIPT, 0o755);
547
+ if (process.platform !== 'win32') {
548
+ // writeFileSync only applies mode at creation; refreshing an existing
549
+ // managed hook still needs the execute bit guaranteed.
550
+ chmodSync(hookPath, 0o755);
551
+ }
552
+ return { status: 'ready', changed: true, hookPath };
553
+ }
554
+ catch (error) {
555
+ return {
556
+ status: 'blocked',
557
+ changed: false,
558
+ hookPath,
559
+ issue: {
560
+ code: 'hook-write-failed',
561
+ path: hookPath,
562
+ message: `Could not install ${hookPath}: ${toErrorMessage(error)}`,
563
+ },
564
+ };
565
+ }
566
+ }
567
+ //# sourceMappingURL=conventionLink.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conventionLink.js","sourceRoot":"","sources":["../../src/utils/conventionLink.ts"],"names":[],"mappings":"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"}