@sentry/dotagents 0.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 (202) hide show
  1. package/README.md +96 -0
  2. package/dist/cli/commands/add.d.ts +12 -0
  3. package/dist/cli/commands/add.d.ts.map +1 -0
  4. package/dist/cli/commands/add.js +127 -0
  5. package/dist/cli/commands/add.js.map +1 -0
  6. package/dist/cli/commands/init.d.ts +10 -0
  7. package/dist/cli/commands/init.d.ts.map +1 -0
  8. package/dist/cli/commands/init.js +81 -0
  9. package/dist/cli/commands/init.js.map +1 -0
  10. package/dist/cli/commands/init.test.d.ts +2 -0
  11. package/dist/cli/commands/init.test.d.ts.map +1 -0
  12. package/dist/cli/commands/init.test.js +71 -0
  13. package/dist/cli/commands/init.test.js.map +1 -0
  14. package/dist/cli/commands/install.d.ts +15 -0
  15. package/dist/cli/commands/install.d.ts.map +1 -0
  16. package/dist/cli/commands/install.js +139 -0
  17. package/dist/cli/commands/install.js.map +1 -0
  18. package/dist/cli/commands/install.test.d.ts +2 -0
  19. package/dist/cli/commands/install.test.d.ts.map +1 -0
  20. package/dist/cli/commands/install.test.js +94 -0
  21. package/dist/cli/commands/install.test.js.map +1 -0
  22. package/dist/cli/commands/list.d.ts +13 -0
  23. package/dist/cli/commands/list.d.ts.map +1 -0
  24. package/dist/cli/commands/list.js +82 -0
  25. package/dist/cli/commands/list.js.map +1 -0
  26. package/dist/cli/commands/list.test.d.ts +2 -0
  27. package/dist/cli/commands/list.test.d.ts.map +1 -0
  28. package/dist/cli/commands/list.test.js +96 -0
  29. package/dist/cli/commands/list.test.js.map +1 -0
  30. package/dist/cli/commands/remove.d.ts +10 -0
  31. package/dist/cli/commands/remove.d.ts.map +1 -0
  32. package/dist/cli/commands/remove.js +68 -0
  33. package/dist/cli/commands/remove.js.map +1 -0
  34. package/dist/cli/commands/sync.d.ts +16 -0
  35. package/dist/cli/commands/sync.d.ts.map +1 -0
  36. package/dist/cli/commands/sync.js +108 -0
  37. package/dist/cli/commands/sync.js.map +1 -0
  38. package/dist/cli/commands/sync.test.d.ts +2 -0
  39. package/dist/cli/commands/sync.test.d.ts.map +1 -0
  40. package/dist/cli/commands/sync.test.js +100 -0
  41. package/dist/cli/commands/sync.test.js.map +1 -0
  42. package/dist/cli/commands/update.d.ts +15 -0
  43. package/dist/cli/commands/update.d.ts.map +1 -0
  44. package/dist/cli/commands/update.js +113 -0
  45. package/dist/cli/commands/update.js.map +1 -0
  46. package/dist/cli/commands/update.test.d.ts +2 -0
  47. package/dist/cli/commands/update.test.d.ts.map +1 -0
  48. package/dist/cli/commands/update.test.js +90 -0
  49. package/dist/cli/commands/update.test.js.map +1 -0
  50. package/dist/cli/index.d.ts +2 -0
  51. package/dist/cli/index.d.ts.map +1 -0
  52. package/dist/cli/index.js +49 -0
  53. package/dist/cli/index.js.map +1 -0
  54. package/dist/config/index.d.ts +5 -0
  55. package/dist/config/index.d.ts.map +1 -0
  56. package/dist/config/index.js +4 -0
  57. package/dist/config/index.js.map +1 -0
  58. package/dist/config/loader.d.ts +6 -0
  59. package/dist/config/loader.d.ts.map +1 -0
  60. package/dist/config/loader.js +35 -0
  61. package/dist/config/loader.js.map +1 -0
  62. package/dist/config/loader.test.d.ts +2 -0
  63. package/dist/config/loader.test.d.ts.map +1 -0
  64. package/dist/config/loader.test.js +60 -0
  65. package/dist/config/loader.test.js.map +1 -0
  66. package/dist/config/schema.d.ts +37 -0
  67. package/dist/config/schema.d.ts.map +1 -0
  68. package/dist/config/schema.js +43 -0
  69. package/dist/config/schema.js.map +1 -0
  70. package/dist/config/schema.test.d.ts +2 -0
  71. package/dist/config/schema.test.d.ts.map +1 -0
  72. package/dist/config/schema.test.js +138 -0
  73. package/dist/config/schema.test.js.map +1 -0
  74. package/dist/config/writer.d.ts +17 -0
  75. package/dist/config/writer.d.ts.map +1 -0
  76. package/dist/config/writer.js +71 -0
  77. package/dist/config/writer.js.map +1 -0
  78. package/dist/config/writer.test.d.ts +2 -0
  79. package/dist/config/writer.test.d.ts.map +1 -0
  80. package/dist/config/writer.test.js +103 -0
  81. package/dist/config/writer.test.js.map +1 -0
  82. package/dist/gitignore/index.d.ts +2 -0
  83. package/dist/gitignore/index.d.ts.map +1 -0
  84. package/dist/gitignore/index.js +2 -0
  85. package/dist/gitignore/index.js.map +1 -0
  86. package/dist/gitignore/writer.d.ts +16 -0
  87. package/dist/gitignore/writer.d.ts.map +1 -0
  88. package/dist/gitignore/writer.js +40 -0
  89. package/dist/gitignore/writer.js.map +1 -0
  90. package/dist/gitignore/writer.test.d.ts +2 -0
  91. package/dist/gitignore/writer.test.d.ts.map +1 -0
  92. package/dist/gitignore/writer.test.js +99 -0
  93. package/dist/gitignore/writer.test.js.map +1 -0
  94. package/dist/index.d.ts +12 -0
  95. package/dist/index.d.ts.map +1 -0
  96. package/dist/index.js +8 -0
  97. package/dist/index.js.map +1 -0
  98. package/dist/lockfile/index.d.ts +5 -0
  99. package/dist/lockfile/index.d.ts.map +1 -0
  100. package/dist/lockfile/index.js +4 -0
  101. package/dist/lockfile/index.js.map +1 -0
  102. package/dist/lockfile/loader.d.ts +10 -0
  103. package/dist/lockfile/loader.d.ts.map +1 -0
  104. package/dist/lockfile/loader.js +36 -0
  105. package/dist/lockfile/loader.js.map +1 -0
  106. package/dist/lockfile/schema.d.ts +42 -0
  107. package/dist/lockfile/schema.d.ts.map +1 -0
  108. package/dist/lockfile/schema.js +25 -0
  109. package/dist/lockfile/schema.js.map +1 -0
  110. package/dist/lockfile/schema.test.d.ts +2 -0
  111. package/dist/lockfile/schema.test.d.ts.map +1 -0
  112. package/dist/lockfile/schema.test.js +60 -0
  113. package/dist/lockfile/schema.test.js.map +1 -0
  114. package/dist/lockfile/writer.d.ts +7 -0
  115. package/dist/lockfile/writer.d.ts.map +1 -0
  116. package/dist/lockfile/writer.js +17 -0
  117. package/dist/lockfile/writer.js.map +1 -0
  118. package/dist/lockfile/writer.test.d.ts +2 -0
  119. package/dist/lockfile/writer.test.d.ts.map +1 -0
  120. package/dist/lockfile/writer.test.js +73 -0
  121. package/dist/lockfile/writer.test.js.map +1 -0
  122. package/dist/skills/discovery.d.ts +17 -0
  123. package/dist/skills/discovery.d.ts.map +1 -0
  124. package/dist/skills/discovery.js +156 -0
  125. package/dist/skills/discovery.js.map +1 -0
  126. package/dist/skills/discovery.test.d.ts +2 -0
  127. package/dist/skills/discovery.test.d.ts.map +1 -0
  128. package/dist/skills/discovery.test.js +110 -0
  129. package/dist/skills/discovery.test.js.map +1 -0
  130. package/dist/skills/index.d.ts +7 -0
  131. package/dist/skills/index.d.ts.map +1 -0
  132. package/dist/skills/index.js +4 -0
  133. package/dist/skills/index.js.map +1 -0
  134. package/dist/skills/loader.d.ts +14 -0
  135. package/dist/skills/loader.d.ts.map +1 -0
  136. package/dist/skills/loader.js +57 -0
  137. package/dist/skills/loader.js.map +1 -0
  138. package/dist/skills/loader.test.d.ts +2 -0
  139. package/dist/skills/loader.test.d.ts.map +1 -0
  140. package/dist/skills/loader.test.js +69 -0
  141. package/dist/skills/loader.test.js.map +1 -0
  142. package/dist/skills/resolver.d.ts +46 -0
  143. package/dist/skills/resolver.d.ts.map +1 -0
  144. package/dist/skills/resolver.integration.test.d.ts +2 -0
  145. package/dist/skills/resolver.integration.test.d.ts.map +1 -0
  146. package/dist/skills/resolver.integration.test.js +106 -0
  147. package/dist/skills/resolver.integration.test.js.map +1 -0
  148. package/dist/skills/resolver.js +82 -0
  149. package/dist/skills/resolver.js.map +1 -0
  150. package/dist/skills/resolver.test.d.ts +2 -0
  151. package/dist/skills/resolver.test.d.ts.map +1 -0
  152. package/dist/skills/resolver.test.js +36 -0
  153. package/dist/skills/resolver.test.js.map +1 -0
  154. package/dist/sources/cache.d.ts +23 -0
  155. package/dist/sources/cache.d.ts.map +1 -0
  156. package/dist/sources/cache.js +61 -0
  157. package/dist/sources/cache.js.map +1 -0
  158. package/dist/sources/git.d.ts +25 -0
  159. package/dist/sources/git.d.ts.map +1 -0
  160. package/dist/sources/git.js +72 -0
  161. package/dist/sources/git.js.map +1 -0
  162. package/dist/sources/index.d.ts +5 -0
  163. package/dist/sources/index.d.ts.map +1 -0
  164. package/dist/sources/index.js +4 -0
  165. package/dist/sources/index.js.map +1 -0
  166. package/dist/sources/local.d.ts +9 -0
  167. package/dist/sources/local.d.ts.map +1 -0
  168. package/dist/sources/local.js +32 -0
  169. package/dist/sources/local.js.map +1 -0
  170. package/dist/symlinks/index.d.ts +2 -0
  171. package/dist/symlinks/index.d.ts.map +1 -0
  172. package/dist/symlinks/index.js +2 -0
  173. package/dist/symlinks/index.js.map +1 -0
  174. package/dist/symlinks/manager.d.ts +20 -0
  175. package/dist/symlinks/manager.d.ts.map +1 -0
  176. package/dist/symlinks/manager.js +103 -0
  177. package/dist/symlinks/manager.js.map +1 -0
  178. package/dist/symlinks/manager.test.d.ts +2 -0
  179. package/dist/symlinks/manager.test.d.ts.map +1 -0
  180. package/dist/symlinks/manager.test.js +94 -0
  181. package/dist/symlinks/manager.test.js.map +1 -0
  182. package/dist/utils/exec.d.ts +16 -0
  183. package/dist/utils/exec.d.ts.map +1 -0
  184. package/dist/utils/exec.js +37 -0
  185. package/dist/utils/exec.js.map +1 -0
  186. package/dist/utils/fs.d.ts +6 -0
  187. package/dist/utils/fs.d.ts.map +1 -0
  188. package/dist/utils/fs.js +10 -0
  189. package/dist/utils/fs.js.map +1 -0
  190. package/dist/utils/hash.d.ts +16 -0
  191. package/dist/utils/hash.d.ts.map +1 -0
  192. package/dist/utils/hash.js +50 -0
  193. package/dist/utils/hash.js.map +1 -0
  194. package/dist/utils/hash.test.d.ts +2 -0
  195. package/dist/utils/hash.test.d.ts.map +1 -0
  196. package/dist/utils/hash.test.js +61 -0
  197. package/dist/utils/hash.test.js.map +1 -0
  198. package/dist/utils/index.d.ts +4 -0
  199. package/dist/utils/index.d.ts.map +1 -0
  200. package/dist/utils/index.js +4 -0
  201. package/dist/utils/index.js.map +1 -0
  202. package/package.json +56 -0
@@ -0,0 +1,23 @@
1
+ export interface CacheResult {
2
+ /** Path to the cached repo checkout */
3
+ repoDir: string;
4
+ /** Resolved commit SHA */
5
+ commit: string;
6
+ }
7
+ /**
8
+ * Get or populate the global cache for a git source.
9
+ *
10
+ * Cache layout:
11
+ * ~/.local/dotagents/<owner>/<repo>/ -- unpinned (TTL-refreshed)
12
+ * ~/.local/dotagents/<owner>/<repo>@<sha>/ -- pinned (immutable)
13
+ */
14
+ export declare function ensureCached(opts: {
15
+ url: string;
16
+ /** Cache key, e.g. "anthropics/skills" or "git.corp.example.com/team/skills" */
17
+ cacheKey: string;
18
+ ref?: string;
19
+ /** If set, we pin to this exact commit and don't refresh */
20
+ pinnedCommit?: string;
21
+ ttlMs?: number;
22
+ }): Promise<CacheResult>;
23
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/sources/cache.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,WAAW;IAC1B,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,gFAAgF;IAChF,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,WAAW,CAAC,CAsCvB"}
@@ -0,0 +1,61 @@
1
+ import { join } from "node:path";
2
+ import { mkdir, stat } from "node:fs/promises";
3
+ import { homedir } from "node:os";
4
+ import { clone, fetchAndReset, fetchRef, headCommit, isGitRepo } from "./git.js";
5
+ const DEFAULT_STATE_DIR = join(homedir(), ".local", "dotagents");
6
+ const DEFAULT_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours
7
+ /**
8
+ * Get or populate the global cache for a git source.
9
+ *
10
+ * Cache layout:
11
+ * ~/.local/dotagents/<owner>/<repo>/ -- unpinned (TTL-refreshed)
12
+ * ~/.local/dotagents/<owner>/<repo>@<sha>/ -- pinned (immutable)
13
+ */
14
+ export async function ensureCached(opts) {
15
+ const stateDir = process.env["DOTAGENTS_STATE_DIR"] || DEFAULT_STATE_DIR;
16
+ const ttl = opts.ttlMs ?? DEFAULT_TTL_MS;
17
+ // Pinned to an exact commit
18
+ if (opts.pinnedCommit) {
19
+ const repoDir = join(stateDir, `${opts.cacheKey}@${opts.pinnedCommit}`);
20
+ if (isGitRepo(repoDir)) {
21
+ return { repoDir, commit: opts.pinnedCommit };
22
+ }
23
+ await mkdir(repoDir, { recursive: true });
24
+ await clone(opts.url, repoDir, opts.ref);
25
+ await fetchRef(repoDir, opts.pinnedCommit);
26
+ const commit = await headCommit(repoDir);
27
+ return { repoDir, commit };
28
+ }
29
+ // Unpinned — use TTL-based refresh
30
+ const repoDir = join(stateDir, opts.cacheKey);
31
+ if (isGitRepo(repoDir)) {
32
+ const needsRefresh = await isStale(repoDir, ttl);
33
+ if (needsRefresh) {
34
+ if (opts.ref) {
35
+ await fetchRef(repoDir, opts.ref);
36
+ }
37
+ else {
38
+ await fetchAndReset(repoDir);
39
+ }
40
+ }
41
+ const commit = await headCommit(repoDir);
42
+ return { repoDir, commit };
43
+ }
44
+ // Not cached yet — clone
45
+ await mkdir(join(stateDir, opts.cacheKey, ".."), { recursive: true });
46
+ await clone(opts.url, repoDir, opts.ref);
47
+ const commit = await headCommit(repoDir);
48
+ return { repoDir, commit };
49
+ }
50
+ async function isStale(repoDir, ttlMs) {
51
+ try {
52
+ const gitDir = join(repoDir, ".git", "FETCH_HEAD");
53
+ const s = await stat(gitDir);
54
+ return Date.now() - s.mtimeMs > ttlMs;
55
+ }
56
+ catch {
57
+ // No FETCH_HEAD yet — consider stale
58
+ return true;
59
+ }
60
+ }
61
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/sources/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAEjF,MAAM,iBAAiB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;AACjE,MAAM,cAAc,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,WAAW;AASvD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAQlC;IACC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,IAAI,iBAAiB,CAAC;IACzE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,IAAI,cAAc,CAAC;IAEzC,4BAA4B;IAC5B,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;QACxE,IAAI,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;YACvB,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC;QAChD,CAAC;QACD,MAAM,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1C,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QACzC,MAAM,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC;QACzC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAC7B,CAAC;IAED,mCAAmC;IACnC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IAE9C,IAAI,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;QACvB,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACjD,IAAI,YAAY,EAAE,CAAC;YACjB,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;gBACb,MAAM,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;YACpC,CAAC;iBAAM,CAAC;gBACN,MAAM,aAAa,CAAC,OAAO,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC;QACzC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAC7B,CAAC;IAED,yBAAyB;IACzB,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtE,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC;IACzC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AAC7B,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,OAAe,EAAE,KAAa;IACnD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;QACnD,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC;QAC7B,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,OAAO,GAAG,KAAK,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,qCAAqC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,25 @@
1
+ export declare class GitError extends Error {
2
+ constructor(message: string);
3
+ }
4
+ /**
5
+ * Clone a repo with --depth=1 into the given directory.
6
+ * If ref is provided, clones that specific ref.
7
+ */
8
+ export declare function clone(url: string, dest: string, ref?: string): Promise<void>;
9
+ /**
10
+ * Fetch latest and reset to origin's HEAD. For updating unpinned repos.
11
+ */
12
+ export declare function fetchAndReset(repoDir: string): Promise<void>;
13
+ /**
14
+ * Fetch a specific ref and checkout.
15
+ */
16
+ export declare function fetchRef(repoDir: string, ref: string): Promise<void>;
17
+ /**
18
+ * Get the current HEAD commit SHA (full 40 chars).
19
+ */
20
+ export declare function headCommit(repoDir: string): Promise<string>;
21
+ /**
22
+ * Check if a directory is a git repository.
23
+ */
24
+ export declare function isGitRepo(dir: string): boolean;
25
+ //# sourceMappingURL=git.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/sources/git.ts"],"names":[],"mappings":"AAGA,qBAAa,QAAS,SAAQ,KAAK;gBACrB,OAAO,EAAE,MAAM;CAI5B;AAED;;;GAGG;AACH,wBAAsB,KAAK,CACzB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAef;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUlE;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAU1E;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGjE;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAE9C"}
@@ -0,0 +1,72 @@
1
+ import { exec, ExecError } from "../utils/exec.js";
2
+ import { existsSync } from "node:fs";
3
+ export class GitError extends Error {
4
+ constructor(message) {
5
+ super(message);
6
+ this.name = "GitError";
7
+ }
8
+ }
9
+ /**
10
+ * Clone a repo with --depth=1 into the given directory.
11
+ * If ref is provided, clones that specific ref.
12
+ */
13
+ export async function clone(url, dest, ref) {
14
+ const args = ["clone", "--depth=1"];
15
+ if (ref) {
16
+ args.push("--branch", ref);
17
+ }
18
+ args.push("--", url, dest);
19
+ try {
20
+ await exec("git", args);
21
+ }
22
+ catch (err) {
23
+ if (err instanceof ExecError) {
24
+ throw new GitError(`Failed to clone ${url}: ${err.stderr}`);
25
+ }
26
+ throw err;
27
+ }
28
+ }
29
+ /**
30
+ * Fetch latest and reset to origin's HEAD. For updating unpinned repos.
31
+ */
32
+ export async function fetchAndReset(repoDir) {
33
+ try {
34
+ await exec("git", ["fetch", "--depth=1", "--", "origin"], { cwd: repoDir });
35
+ await exec("git", ["reset", "--hard", "FETCH_HEAD"], { cwd: repoDir });
36
+ }
37
+ catch (err) {
38
+ if (err instanceof ExecError) {
39
+ throw new GitError(`Failed to update ${repoDir}: ${err.stderr}`);
40
+ }
41
+ throw err;
42
+ }
43
+ }
44
+ /**
45
+ * Fetch a specific ref and checkout.
46
+ */
47
+ export async function fetchRef(repoDir, ref) {
48
+ try {
49
+ await exec("git", ["fetch", "--depth=1", "--", "origin", ref], { cwd: repoDir });
50
+ await exec("git", ["checkout", "FETCH_HEAD"], { cwd: repoDir });
51
+ }
52
+ catch (err) {
53
+ if (err instanceof ExecError) {
54
+ throw new GitError(`Failed to fetch ref ${ref} in ${repoDir}: ${err.stderr}`);
55
+ }
56
+ throw err;
57
+ }
58
+ }
59
+ /**
60
+ * Get the current HEAD commit SHA (full 40 chars).
61
+ */
62
+ export async function headCommit(repoDir) {
63
+ const { stdout } = await exec("git", ["rev-parse", "HEAD"], { cwd: repoDir });
64
+ return stdout.trim();
65
+ }
66
+ /**
67
+ * Check if a directory is a git repository.
68
+ */
69
+ export function isGitRepo(dir) {
70
+ return existsSync(`${dir}/.git`);
71
+ }
72
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/sources/git.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { clone, fetchAndReset, fetchRef, headCommit, isGitRepo, GitError } from "./git.js";
2
+ export { ensureCached } from "./cache.js";
3
+ export type { CacheResult } from "./cache.js";
4
+ export { resolveLocalSource, LocalSourceError } from "./local.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sources/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAC3F,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { clone, fetchAndReset, fetchRef, headCommit, isGitRepo, GitError } from "./git.js";
2
+ export { ensureCached } from "./cache.js";
3
+ export { resolveLocalSource, LocalSourceError } from "./local.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sources/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAC3F,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,9 @@
1
+ export declare class LocalSourceError extends Error {
2
+ constructor(message: string);
3
+ }
4
+ /**
5
+ * Resolve a path: source to an absolute directory.
6
+ * The path is relative to the project root.
7
+ */
8
+ export declare function resolveLocalSource(projectRoot: string, relativePath: string): Promise<string>;
9
+ //# sourceMappingURL=local.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../src/sources/local.ts"],"names":[],"mappings":"AAGA,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM;CAI5B;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,CAuBjB"}
@@ -0,0 +1,32 @@
1
+ import { resolve } from "node:path";
2
+ import { stat } from "node:fs/promises";
3
+ export class LocalSourceError extends Error {
4
+ constructor(message) {
5
+ super(message);
6
+ this.name = "LocalSourceError";
7
+ }
8
+ }
9
+ /**
10
+ * Resolve a path: source to an absolute directory.
11
+ * The path is relative to the project root.
12
+ */
13
+ export async function resolveLocalSource(projectRoot, relativePath) {
14
+ const absRoot = resolve(projectRoot);
15
+ const absPath = resolve(projectRoot, relativePath);
16
+ // Prevent path traversal outside the project root
17
+ if (!absPath.startsWith(absRoot + "/") && absPath !== absRoot) {
18
+ throw new LocalSourceError(`Local source "${relativePath}" resolves outside project root`);
19
+ }
20
+ let s;
21
+ try {
22
+ s = await stat(absPath);
23
+ }
24
+ catch {
25
+ throw new LocalSourceError(`Local source not found: ${absPath}`);
26
+ }
27
+ if (!s.isDirectory()) {
28
+ throw new LocalSourceError(`Local source is not a directory: ${absPath}`);
29
+ }
30
+ return absPath;
31
+ }
32
+ //# sourceMappingURL=local.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local.js","sourceRoot":"","sources":["../../src/sources/local.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACzC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,WAAmB,EACnB,YAAoB;IAEpB,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACrC,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAEnD,kDAAkD;IAClD,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,GAAG,GAAG,CAAC,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;QAC9D,MAAM,IAAI,gBAAgB,CACxB,iBAAiB,YAAY,iCAAiC,CAC/D,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,CAAC;IACN,IAAI,CAAC;QACH,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,gBAAgB,CAAC,2BAA2B,OAAO,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QACrB,MAAM,IAAI,gBAAgB,CAAC,oCAAoC,OAAO,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { ensureSkillsSymlink, verifySymlinks, SymlinkError } from "./manager.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/symlinks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { ensureSkillsSymlink, verifySymlinks, SymlinkError } from "./manager.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/symlinks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,20 @@
1
+ export declare class SymlinkError extends Error {
2
+ constructor(message: string);
3
+ }
4
+ /**
5
+ * Ensure <targetDir>/skills/ is a symlink pointing to <agentsDir>/skills/.
6
+ * Creates the parent directory if it doesn't exist.
7
+ */
8
+ export declare function ensureSkillsSymlink(agentsDir: string, targetDir: string): Promise<{
9
+ created: boolean;
10
+ migrated: string[];
11
+ }>;
12
+ /**
13
+ * Verify all configured symlinks are correct.
14
+ * Returns a list of issues found.
15
+ */
16
+ export declare function verifySymlinks(agentsDir: string, targets: string[]): Promise<{
17
+ target: string;
18
+ issue: string;
19
+ }[]>;
20
+ //# sourceMappingURL=manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/symlinks/manager.ts"],"names":[],"mappings":"AAGA,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,EAAE,MAAM;CAI5B;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAyCnD;AAkCD;;;GAGG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EAAE,GAChB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,CA2B9C"}
@@ -0,0 +1,103 @@
1
+ import { symlink, readlink, unlink, mkdir, lstat, readdir } from "node:fs/promises";
2
+ import { join, relative } from "node:path";
3
+ export class SymlinkError extends Error {
4
+ constructor(message) {
5
+ super(message);
6
+ this.name = "SymlinkError";
7
+ }
8
+ }
9
+ /**
10
+ * Ensure <targetDir>/skills/ is a symlink pointing to <agentsDir>/skills/.
11
+ * Creates the parent directory if it doesn't exist.
12
+ */
13
+ export async function ensureSkillsSymlink(agentsDir, targetDir) {
14
+ const skillsSource = join(agentsDir, "skills");
15
+ const skillsLink = join(targetDir, "skills");
16
+ const relativeTarget = relative(targetDir, skillsSource);
17
+ // Ensure parent directory exists
18
+ await mkdir(targetDir, { recursive: true });
19
+ // Check if skills path already exists
20
+ let stat;
21
+ try {
22
+ stat = await lstat(skillsLink);
23
+ }
24
+ catch {
25
+ // Doesn't exist, create symlink
26
+ await symlink(relativeTarget, skillsLink);
27
+ return { created: true, migrated: [] };
28
+ }
29
+ // Already a symlink - check if it points to the right place
30
+ if (stat.isSymbolicLink()) {
31
+ const currentTarget = await readlink(skillsLink);
32
+ if (currentTarget === relativeTarget) {
33
+ return { created: false, migrated: [] };
34
+ }
35
+ // Wrong target, replace
36
+ await unlink(skillsLink);
37
+ await symlink(relativeTarget, skillsLink);
38
+ return { created: true, migrated: [] };
39
+ }
40
+ // Real directory - migrate contents then replace with symlink
41
+ if (stat.isDirectory()) {
42
+ const migrated = await migrateDirectory(skillsLink, skillsSource);
43
+ await rmdir(skillsLink);
44
+ await symlink(relativeTarget, skillsLink);
45
+ return { created: true, migrated };
46
+ }
47
+ throw new SymlinkError(`${skillsLink} exists but is not a directory or symlink`);
48
+ }
49
+ async function migrateDirectory(from, to) {
50
+ const entries = await readdir(from, { withFileTypes: true });
51
+ const migrated = [];
52
+ for (const entry of entries) {
53
+ const srcPath = join(from, entry.name);
54
+ const destPath = join(to, entry.name);
55
+ // Skip if destination already exists
56
+ try {
57
+ await lstat(destPath);
58
+ continue;
59
+ }
60
+ catch {
61
+ // Doesn't exist, proceed with migration
62
+ }
63
+ const { rename } = await import("node:fs/promises");
64
+ await rename(srcPath, destPath);
65
+ migrated.push(entry.name);
66
+ }
67
+ return migrated;
68
+ }
69
+ async function rmdir(dir) {
70
+ const { rm } = await import("node:fs/promises");
71
+ await rm(dir, { recursive: true });
72
+ }
73
+ /**
74
+ * Verify all configured symlinks are correct.
75
+ * Returns a list of issues found.
76
+ */
77
+ export async function verifySymlinks(agentsDir, targets) {
78
+ const issues = [];
79
+ const skillsSource = join(agentsDir, "skills");
80
+ for (const target of targets) {
81
+ const skillsLink = join(target, "skills");
82
+ const relativeTarget = relative(target, skillsSource);
83
+ try {
84
+ const stat = await lstat(skillsLink);
85
+ if (!stat.isSymbolicLink()) {
86
+ issues.push({ target, issue: `${skillsLink} is not a symlink` });
87
+ continue;
88
+ }
89
+ const currentTarget = await readlink(skillsLink);
90
+ if (currentTarget !== relativeTarget) {
91
+ issues.push({
92
+ target,
93
+ issue: `${skillsLink} points to ${currentTarget}, expected ${relativeTarget}`,
94
+ });
95
+ }
96
+ }
97
+ catch {
98
+ issues.push({ target, issue: `${skillsLink} does not exist` });
99
+ }
100
+ }
101
+ return issues;
102
+ }
103
+ //# sourceMappingURL=manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/symlinks/manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=manager.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.test.d.ts","sourceRoot":"","sources":["../../src/symlinks/manager.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,94 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
+ import { mkdtemp, rm, mkdir, writeFile, lstat, readlink, readdir, } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ import { tmpdir } from "node:os";
5
+ import { ensureSkillsSymlink, verifySymlinks } from "./manager.js";
6
+ describe("symlinks", () => {
7
+ let dir;
8
+ let agentsDir;
9
+ beforeEach(async () => {
10
+ dir = await mkdtemp(join(tmpdir(), "dotagents-test-"));
11
+ agentsDir = join(dir, ".agents");
12
+ await mkdir(join(agentsDir, "skills"), { recursive: true });
13
+ });
14
+ afterEach(async () => {
15
+ await rm(dir, { recursive: true });
16
+ });
17
+ describe("ensureSkillsSymlink", () => {
18
+ it("creates symlink when target dir does not exist", async () => {
19
+ const targetDir = join(dir, ".claude");
20
+ const result = await ensureSkillsSymlink(agentsDir, targetDir);
21
+ expect(result.created).toBe(true);
22
+ expect(result.migrated).toEqual([]);
23
+ const stat = await lstat(join(targetDir, "skills"));
24
+ expect(stat.isSymbolicLink()).toBe(true);
25
+ const linkTarget = await readlink(join(targetDir, "skills"));
26
+ expect(linkTarget).toBe("../.agents/skills");
27
+ });
28
+ it("creates symlink when target dir exists but skills/ does not", async () => {
29
+ const targetDir = join(dir, ".claude");
30
+ await mkdir(targetDir, { recursive: true });
31
+ await writeFile(join(targetDir, "settings.json"), "{}");
32
+ const result = await ensureSkillsSymlink(agentsDir, targetDir);
33
+ expect(result.created).toBe(true);
34
+ // settings.json should still be there
35
+ const entries = await readdir(targetDir);
36
+ expect(entries).toContain("settings.json");
37
+ expect(entries).toContain("skills");
38
+ });
39
+ it("is idempotent when symlink already correct", async () => {
40
+ const targetDir = join(dir, ".claude");
41
+ await ensureSkillsSymlink(agentsDir, targetDir);
42
+ const result = await ensureSkillsSymlink(agentsDir, targetDir);
43
+ expect(result.created).toBe(false);
44
+ });
45
+ it("replaces wrong symlink", async () => {
46
+ const targetDir = join(dir, ".claude");
47
+ await mkdir(targetDir, { recursive: true });
48
+ // Create a wrong symlink
49
+ const { symlink } = await import("node:fs/promises");
50
+ await symlink("/wrong/target", join(targetDir, "skills"));
51
+ const result = await ensureSkillsSymlink(agentsDir, targetDir);
52
+ expect(result.created).toBe(true);
53
+ const linkTarget = await readlink(join(targetDir, "skills"));
54
+ expect(linkTarget).toBe("../.agents/skills");
55
+ });
56
+ it("migrates existing real directory", async () => {
57
+ const targetDir = join(dir, ".claude");
58
+ const realSkillsDir = join(targetDir, "skills");
59
+ await mkdir(join(realSkillsDir, "my-local-skill"), { recursive: true });
60
+ await writeFile(join(realSkillsDir, "my-local-skill", "SKILL.md"), "---\nname: test\n---\n");
61
+ const result = await ensureSkillsSymlink(agentsDir, targetDir);
62
+ expect(result.created).toBe(true);
63
+ expect(result.migrated).toContain("my-local-skill");
64
+ // Verify the skill was moved to .agents/skills/
65
+ const agentsEntries = await readdir(join(agentsDir, "skills"));
66
+ expect(agentsEntries).toContain("my-local-skill");
67
+ // Verify symlink is now in place
68
+ const stat = await lstat(join(targetDir, "skills"));
69
+ expect(stat.isSymbolicLink()).toBe(true);
70
+ });
71
+ });
72
+ describe("verifySymlinks", () => {
73
+ it("returns no issues when all symlinks correct", async () => {
74
+ const targetDir = join(dir, ".claude");
75
+ await ensureSkillsSymlink(agentsDir, targetDir);
76
+ const issues = await verifySymlinks(agentsDir, [targetDir]);
77
+ expect(issues).toEqual([]);
78
+ });
79
+ it("reports missing symlink", async () => {
80
+ const targetDir = join(dir, ".claude");
81
+ const issues = await verifySymlinks(agentsDir, [targetDir]);
82
+ expect(issues).toHaveLength(1);
83
+ expect(issues[0]?.issue).toContain("does not exist");
84
+ });
85
+ it("reports non-symlink directory", async () => {
86
+ const targetDir = join(dir, ".claude");
87
+ await mkdir(join(targetDir, "skills"), { recursive: true });
88
+ const issues = await verifySymlinks(agentsDir, [targetDir]);
89
+ expect(issues).toHaveLength(1);
90
+ expect(issues[0]?.issue).toContain("not a symlink");
91
+ });
92
+ });
93
+ });
94
+ //# sourceMappingURL=manager.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.test.js","sourceRoot":"","sources":["../../src/symlinks/manager.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export declare class ExecError extends Error {
2
+ readonly exitCode: number | null;
3
+ readonly stderr: string;
4
+ constructor(message: string, exitCode: number | null, stderr: string);
5
+ }
6
+ interface ExecResult {
7
+ stdout: string;
8
+ stderr: string;
9
+ }
10
+ export declare function exec(cmd: string, args: string[], opts?: {
11
+ cwd?: string;
12
+ env?: Record<string, string>;
13
+ timeoutMs?: number;
14
+ }): Promise<ExecResult>;
15
+ export {};
16
+ //# sourceMappingURL=exec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../src/utils/exec.ts"],"names":[],"mappings":"AAEA,qBAAa,SAAU,SAAQ,KAAK;aAGhB,QAAQ,EAAE,MAAM,GAAG,IAAI;aACvB,MAAM,EAAE,MAAM;gBAF9B,OAAO,EAAE,MAAM,EACC,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,MAAM,EAAE,MAAM;CAKjC;AAED,UAAU,UAAU;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAQD,wBAAgB,IAAI,CAClB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACxE,OAAO,CAAC,UAAU,CAAC,CA0BrB"}
@@ -0,0 +1,37 @@
1
+ import { execFile } from "node:child_process";
2
+ export class ExecError extends Error {
3
+ exitCode;
4
+ stderr;
5
+ constructor(message, exitCode, stderr) {
6
+ super(message);
7
+ this.exitCode = exitCode;
8
+ this.stderr = stderr;
9
+ this.name = "ExecError";
10
+ }
11
+ }
12
+ /**
13
+ * Run a command and return stdout/stderr.
14
+ * Non-interactive: sets GIT_TERMINAL_PROMPT=0 for git commands.
15
+ */
16
+ const DEFAULT_TIMEOUT_MS = 60_000; // 60 seconds
17
+ export function exec(cmd, args, opts) {
18
+ return new Promise((resolve, reject) => {
19
+ const env = {
20
+ ...process.env,
21
+ // Prevent git from prompting for credentials
22
+ GIT_TERMINAL_PROMPT: "0",
23
+ // Prevent git from asking for SSH key passphrases
24
+ GIT_SSH_COMMAND: "ssh -o BatchMode=yes",
25
+ ...opts?.env,
26
+ };
27
+ execFile(cmd, args, { cwd: opts?.cwd, env, maxBuffer: 50 * 1024 * 1024, timeout: opts?.timeoutMs ?? DEFAULT_TIMEOUT_MS }, (err, stdout, stderr) => {
28
+ if (err) {
29
+ const code = "code" in err ? err.code : null;
30
+ reject(new ExecError(`${cmd} ${args.join(" ")} failed: ${stderr.trim() || err.message}`, code, stderr));
31
+ return;
32
+ }
33
+ resolve({ stdout, stderr });
34
+ });
35
+ });
36
+ }
37
+ //# sourceMappingURL=exec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec.js","sourceRoot":"","sources":["../../src/utils/exec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,MAAM,OAAO,SAAU,SAAQ,KAAK;IAGhB;IACA;IAHlB,YACE,OAAe,EACC,QAAuB,EACvB,MAAc;QAE9B,KAAK,CAAC,OAAO,CAAC,CAAC;QAHC,aAAQ,GAAR,QAAQ,CAAe;QACvB,WAAM,GAAN,MAAM,CAAQ;QAG9B,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;IAC1B,CAAC;CACF;AAOD;;;GAGG;AACH,MAAM,kBAAkB,GAAG,MAAM,CAAC,CAAC,aAAa;AAEhD,MAAM,UAAU,IAAI,CAClB,GAAW,EACX,IAAc,EACd,IAAyE;IAEzE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,GAAG,GAAG;YACV,GAAG,OAAO,CAAC,GAAG;YACd,6CAA6C;YAC7C,mBAAmB,EAAE,GAAG;YACxB,kDAAkD;YAClD,eAAe,EAAE,sBAAsB;YACvC,GAAG,IAAI,EAAE,GAAG;SACb,CAAC;QAEF,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,IAAI,kBAAkB,EAAE,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YAChJ,IAAI,GAAG,EAAE,CAAC;gBACR,MAAM,IAAI,GAAG,MAAM,IAAI,GAAG,CAAC,CAAC,CAAE,GAAG,CAAC,IAAsB,CAAC,CAAC,CAAC,IAAI,CAAC;gBAChE,MAAM,CACJ,IAAI,SAAS,CACX,GAAG,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,OAAO,EAAE,EAClE,IAAI,EACJ,MAAM,CACP,CACF,CAAC;gBACF,OAAO;YACT,CAAC;YACD,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Copy a directory recursively.
3
+ * Removes destination first if it exists.
4
+ */
5
+ export declare function copyDir(src: string, dest: string): Promise<void>;
6
+ //# sourceMappingURL=fs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/utils/fs.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAsB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGtE"}
@@ -0,0 +1,10 @@
1
+ import { cp, rm } from "node:fs/promises";
2
+ /**
3
+ * Copy a directory recursively.
4
+ * Removes destination first if it exists.
5
+ */
6
+ export async function copyDir(src, dest) {
7
+ await rm(dest, { recursive: true, force: true });
8
+ await cp(src, dest, { recursive: true });
9
+ }
10
+ //# sourceMappingURL=fs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs.js","sourceRoot":"","sources":["../../src/utils/fs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAE1C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,GAAW,EAAE,IAAY;IACrD,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACjD,MAAM,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC3C,CAAC"}