@paysdoc/devplatform 1.0.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 (243) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +122 -0
  3. package/dist/git/bootstrapIdentity.d.ts +50 -0
  4. package/dist/git/bootstrapIdentity.d.ts.map +1 -0
  5. package/dist/git/bootstrapIdentity.js +72 -0
  6. package/dist/git/bootstrapIdentity.js.map +1 -0
  7. package/dist/git/branchOps.d.ts +27 -0
  8. package/dist/git/branchOps.d.ts.map +1 -0
  9. package/dist/git/branchOps.js +91 -0
  10. package/dist/git/branchOps.js.map +1 -0
  11. package/dist/git/claimOps.d.ts +40 -0
  12. package/dist/git/claimOps.d.ts.map +1 -0
  13. package/dist/git/claimOps.js +44 -0
  14. package/dist/git/claimOps.js.map +1 -0
  15. package/dist/git/commitOps.d.ts +35 -0
  16. package/dist/git/commitOps.d.ts.map +1 -0
  17. package/dist/git/commitOps.js +131 -0
  18. package/dist/git/commitOps.js.map +1 -0
  19. package/dist/git/consoleLogger.d.ts +8 -0
  20. package/dist/git/consoleLogger.d.ts.map +1 -0
  21. package/dist/git/consoleLogger.js +9 -0
  22. package/dist/git/consoleLogger.js.map +1 -0
  23. package/dist/git/gitContext.d.ts +150 -0
  24. package/dist/git/gitContext.d.ts.map +1 -0
  25. package/dist/git/gitContext.js +405 -0
  26. package/dist/git/gitContext.js.map +1 -0
  27. package/dist/git/gitReadOps.d.ts +33 -0
  28. package/dist/git/gitReadOps.d.ts.map +1 -0
  29. package/dist/git/gitReadOps.js +38 -0
  30. package/dist/git/gitReadOps.js.map +1 -0
  31. package/dist/git/index.d.ts +49 -0
  32. package/dist/git/index.d.ts.map +1 -0
  33. package/dist/git/index.js +44 -0
  34. package/dist/git/index.js.map +1 -0
  35. package/dist/git/processCleanup.d.ts +7 -0
  36. package/dist/git/processCleanup.d.ts.map +1 -0
  37. package/dist/git/processCleanup.js +45 -0
  38. package/dist/git/processCleanup.js.map +1 -0
  39. package/dist/git/remoteOps.d.ts +25 -0
  40. package/dist/git/remoteOps.d.ts.map +1 -0
  41. package/dist/git/remoteOps.js +30 -0
  42. package/dist/git/remoteOps.js.map +1 -0
  43. package/dist/git/repoWorkspace.d.ts +72 -0
  44. package/dist/git/repoWorkspace.d.ts.map +1 -0
  45. package/dist/git/repoWorkspace.js +85 -0
  46. package/dist/git/repoWorkspace.js.map +1 -0
  47. package/dist/git/types.d.ts +182 -0
  48. package/dist/git/types.d.ts.map +1 -0
  49. package/dist/git/types.js +10 -0
  50. package/dist/git/types.js.map +1 -0
  51. package/dist/git/workingDirectoryGuard.d.ts +39 -0
  52. package/dist/git/workingDirectoryGuard.d.ts.map +1 -0
  53. package/dist/git/workingDirectoryGuard.js +53 -0
  54. package/dist/git/workingDirectoryGuard.js.map +1 -0
  55. package/dist/git/worktreeCreateOps.d.ts +45 -0
  56. package/dist/git/worktreeCreateOps.d.ts.map +1 -0
  57. package/dist/git/worktreeCreateOps.js +208 -0
  58. package/dist/git/worktreeCreateOps.js.map +1 -0
  59. package/dist/git/worktreeProbeOps.d.ts +17 -0
  60. package/dist/git/worktreeProbeOps.d.ts.map +1 -0
  61. package/dist/git/worktreeProbeOps.js +66 -0
  62. package/dist/git/worktreeProbeOps.js.map +1 -0
  63. package/dist/git/worktreeQueryOps.d.ts +45 -0
  64. package/dist/git/worktreeQueryOps.d.ts.map +1 -0
  65. package/dist/git/worktreeQueryOps.js +129 -0
  66. package/dist/git/worktreeQueryOps.js.map +1 -0
  67. package/dist/git/worktreeRemoveOps.d.ts +27 -0
  68. package/dist/git/worktreeRemoveOps.d.ts.map +1 -0
  69. package/dist/git/worktreeRemoveOps.js +132 -0
  70. package/dist/git/worktreeRemoveOps.js.map +1 -0
  71. package/dist/git/worktreeResetOps.d.ts +18 -0
  72. package/dist/git/worktreeResetOps.d.ts.map +1 -0
  73. package/dist/git/worktreeResetOps.js +68 -0
  74. package/dist/git/worktreeResetOps.js.map +1 -0
  75. package/dist/index.d.ts +13 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +13 -0
  78. package/dist/index.js.map +1 -0
  79. package/dist/providers/forgeProviders.d.ts +72 -0
  80. package/dist/providers/forgeProviders.d.ts.map +1 -0
  81. package/dist/providers/forgeProviders.js +112 -0
  82. package/dist/providers/forgeProviders.js.map +1 -0
  83. package/dist/providers/github/appAuth.d.ts +70 -0
  84. package/dist/providers/github/appAuth.d.ts.map +1 -0
  85. package/dist/providers/github/appAuth.js +243 -0
  86. package/dist/providers/github/appAuth.js.map +1 -0
  87. package/dist/providers/github/cloneUrl.d.ts +12 -0
  88. package/dist/providers/github/cloneUrl.d.ts.map +1 -0
  89. package/dist/providers/github/cloneUrl.js +20 -0
  90. package/dist/providers/github/cloneUrl.js.map +1 -0
  91. package/dist/providers/github/commands/boardCommands.d.ts +22 -0
  92. package/dist/providers/github/commands/boardCommands.d.ts.map +1 -0
  93. package/dist/providers/github/commands/boardCommands.js +66 -0
  94. package/dist/providers/github/commands/boardCommands.js.map +1 -0
  95. package/dist/providers/github/commands/issueCommands.d.ts +21 -0
  96. package/dist/providers/github/commands/issueCommands.d.ts.map +1 -0
  97. package/dist/providers/github/commands/issueCommands.js +50 -0
  98. package/dist/providers/github/commands/issueCommands.js.map +1 -0
  99. package/dist/providers/github/commands/labelCommands.d.ts +3 -0
  100. package/dist/providers/github/commands/labelCommands.d.ts.map +1 -0
  101. package/dist/providers/github/commands/labelCommands.js +8 -0
  102. package/dist/providers/github/commands/labelCommands.js.map +1 -0
  103. package/dist/providers/github/commands/prCommands.d.ts +14 -0
  104. package/dist/providers/github/commands/prCommands.d.ts.map +1 -0
  105. package/dist/providers/github/commands/prCommands.js +46 -0
  106. package/dist/providers/github/commands/prCommands.js.map +1 -0
  107. package/dist/providers/github/commands/secretCommands.d.ts +2 -0
  108. package/dist/providers/github/commands/secretCommands.d.ts.map +1 -0
  109. package/dist/providers/github/commands/secretCommands.js +5 -0
  110. package/dist/providers/github/commands/secretCommands.js.map +1 -0
  111. package/dist/providers/github/contextBinding.d.ts +11 -0
  112. package/dist/providers/github/contextBinding.d.ts.map +1 -0
  113. package/dist/providers/github/contextBinding.js +15 -0
  114. package/dist/providers/github/contextBinding.js.map +1 -0
  115. package/dist/providers/github/domain/issue.d.ts +94 -0
  116. package/dist/providers/github/domain/issue.d.ts.map +1 -0
  117. package/dist/providers/github/domain/issue.js +7 -0
  118. package/dist/providers/github/domain/issue.js.map +1 -0
  119. package/dist/providers/github/domain/pullRequest.d.ts +55 -0
  120. package/dist/providers/github/domain/pullRequest.d.ts.map +1 -0
  121. package/dist/providers/github/domain/pullRequest.js +9 -0
  122. package/dist/providers/github/domain/pullRequest.js.map +1 -0
  123. package/dist/providers/github/ghAuthToken.d.ts +28 -0
  124. package/dist/providers/github/ghAuthToken.d.ts.map +1 -0
  125. package/dist/providers/github/ghAuthToken.js +39 -0
  126. package/dist/providers/github/ghAuthToken.js.map +1 -0
  127. package/dist/providers/github/ghCommandRunner.d.ts +20 -0
  128. package/dist/providers/github/ghCommandRunner.d.ts.map +1 -0
  129. package/dist/providers/github/ghCommandRunner.js +21 -0
  130. package/dist/providers/github/ghCommandRunner.js.map +1 -0
  131. package/dist/providers/github/ghIssueApi.d.ts +29 -0
  132. package/dist/providers/github/ghIssueApi.d.ts.map +1 -0
  133. package/dist/providers/github/ghIssueApi.js +37 -0
  134. package/dist/providers/github/ghIssueApi.js.map +1 -0
  135. package/dist/providers/github/ghIssueParsers.d.ts +28 -0
  136. package/dist/providers/github/ghIssueParsers.d.ts.map +1 -0
  137. package/dist/providers/github/ghIssueParsers.js +105 -0
  138. package/dist/providers/github/ghIssueParsers.js.map +1 -0
  139. package/dist/providers/github/ghPrApi.d.ts +27 -0
  140. package/dist/providers/github/ghPrApi.d.ts.map +1 -0
  141. package/dist/providers/github/ghPrApi.js +32 -0
  142. package/dist/providers/github/ghPrApi.js.map +1 -0
  143. package/dist/providers/github/ghPrParsers.d.ts +57 -0
  144. package/dist/providers/github/ghPrParsers.d.ts.map +1 -0
  145. package/dist/providers/github/ghPrParsers.js +135 -0
  146. package/dist/providers/github/ghPrParsers.js.map +1 -0
  147. package/dist/providers/github/ghRepoApi.d.ts +33 -0
  148. package/dist/providers/github/ghRepoApi.d.ts.map +1 -0
  149. package/dist/providers/github/ghRepoApi.js +89 -0
  150. package/dist/providers/github/ghRepoApi.js.map +1 -0
  151. package/dist/providers/github/githubBoardManager.d.ts +39 -0
  152. package/dist/providers/github/githubBoardManager.d.ts.map +1 -0
  153. package/dist/providers/github/githubBoardManager.js +166 -0
  154. package/dist/providers/github/githubBoardManager.js.map +1 -0
  155. package/dist/providers/github/githubCodeHost.d.ts +73 -0
  156. package/dist/providers/github/githubCodeHost.d.ts.map +1 -0
  157. package/dist/providers/github/githubCodeHost.js +217 -0
  158. package/dist/providers/github/githubCodeHost.js.map +1 -0
  159. package/dist/providers/github/githubIdentity.d.ts +51 -0
  160. package/dist/providers/github/githubIdentity.d.ts.map +1 -0
  161. package/dist/providers/github/githubIdentity.js +110 -0
  162. package/dist/providers/github/githubIdentity.js.map +1 -0
  163. package/dist/providers/github/githubIssueTracker.d.ts +69 -0
  164. package/dist/providers/github/githubIssueTracker.d.ts.map +1 -0
  165. package/dist/providers/github/githubIssueTracker.js +209 -0
  166. package/dist/providers/github/githubIssueTracker.js.map +1 -0
  167. package/dist/providers/github/githubTokenProvider.d.ts +41 -0
  168. package/dist/providers/github/githubTokenProvider.d.ts.map +1 -0
  169. package/dist/providers/github/githubTokenProvider.js +51 -0
  170. package/dist/providers/github/githubTokenProvider.js.map +1 -0
  171. package/dist/providers/github/index.d.ts +10 -0
  172. package/dist/providers/github/index.d.ts.map +1 -0
  173. package/dist/providers/github/index.js +5 -0
  174. package/dist/providers/github/index.js.map +1 -0
  175. package/dist/providers/github/mappers.d.ts +40 -0
  176. package/dist/providers/github/mappers.d.ts.map +1 -0
  177. package/dist/providers/github/mappers.js +103 -0
  178. package/dist/providers/github/mappers.js.map +1 -0
  179. package/dist/providers/github/tokenResolver.d.ts +37 -0
  180. package/dist/providers/github/tokenResolver.d.ts.map +1 -0
  181. package/dist/providers/github/tokenResolver.js +43 -0
  182. package/dist/providers/github/tokenResolver.js.map +1 -0
  183. package/dist/providers/gitlab/gitlabApiClient.d.ts +45 -0
  184. package/dist/providers/gitlab/gitlabApiClient.d.ts.map +1 -0
  185. package/dist/providers/gitlab/gitlabApiClient.js +95 -0
  186. package/dist/providers/gitlab/gitlabApiClient.js.map +1 -0
  187. package/dist/providers/gitlab/gitlabBoardManager.d.ts +11 -0
  188. package/dist/providers/gitlab/gitlabBoardManager.d.ts.map +1 -0
  189. package/dist/providers/gitlab/gitlabBoardManager.js +27 -0
  190. package/dist/providers/gitlab/gitlabBoardManager.js.map +1 -0
  191. package/dist/providers/gitlab/gitlabCodeHost.d.ts +49 -0
  192. package/dist/providers/gitlab/gitlabCodeHost.d.ts.map +1 -0
  193. package/dist/providers/gitlab/gitlabCodeHost.js +109 -0
  194. package/dist/providers/gitlab/gitlabCodeHost.js.map +1 -0
  195. package/dist/providers/gitlab/gitlabTypes.d.ts +46 -0
  196. package/dist/providers/gitlab/gitlabTypes.d.ts.map +1 -0
  197. package/dist/providers/gitlab/gitlabTypes.js +6 -0
  198. package/dist/providers/gitlab/gitlabTypes.js.map +1 -0
  199. package/dist/providers/gitlab/index.d.ts +5 -0
  200. package/dist/providers/gitlab/index.d.ts.map +1 -0
  201. package/dist/providers/gitlab/index.js +4 -0
  202. package/dist/providers/gitlab/index.js.map +1 -0
  203. package/dist/providers/gitlab/mappers.d.ts +26 -0
  204. package/dist/providers/gitlab/mappers.d.ts.map +1 -0
  205. package/dist/providers/gitlab/mappers.js +63 -0
  206. package/dist/providers/gitlab/mappers.js.map +1 -0
  207. package/dist/providers/index.d.ts +7 -0
  208. package/dist/providers/index.d.ts.map +1 -0
  209. package/dist/providers/index.js +7 -0
  210. package/dist/providers/index.js.map +1 -0
  211. package/dist/providers/jira/adfConverter.d.ts +32 -0
  212. package/dist/providers/jira/adfConverter.d.ts.map +1 -0
  213. package/dist/providers/jira/adfConverter.js +144 -0
  214. package/dist/providers/jira/adfConverter.js.map +1 -0
  215. package/dist/providers/jira/index.d.ts +8 -0
  216. package/dist/providers/jira/index.d.ts.map +1 -0
  217. package/dist/providers/jira/index.js +5 -0
  218. package/dist/providers/jira/index.js.map +1 -0
  219. package/dist/providers/jira/jiraApiClient.d.ts +42 -0
  220. package/dist/providers/jira/jiraApiClient.d.ts.map +1 -0
  221. package/dist/providers/jira/jiraApiClient.js +84 -0
  222. package/dist/providers/jira/jiraApiClient.js.map +1 -0
  223. package/dist/providers/jira/jiraBoardManager.d.ts +11 -0
  224. package/dist/providers/jira/jiraBoardManager.d.ts.map +1 -0
  225. package/dist/providers/jira/jiraBoardManager.js +27 -0
  226. package/dist/providers/jira/jiraBoardManager.js.map +1 -0
  227. package/dist/providers/jira/jiraIssueTracker.d.ts +53 -0
  228. package/dist/providers/jira/jiraIssueTracker.d.ts.map +1 -0
  229. package/dist/providers/jira/jiraIssueTracker.js +231 -0
  230. package/dist/providers/jira/jiraIssueTracker.js.map +1 -0
  231. package/dist/providers/jira/jiraTypes.d.ts +61 -0
  232. package/dist/providers/jira/jiraTypes.d.ts.map +1 -0
  233. package/dist/providers/jira/jiraTypes.js +6 -0
  234. package/dist/providers/jira/jiraTypes.js.map +1 -0
  235. package/dist/providers/types.d.ts +271 -0
  236. package/dist/providers/types.d.ts.map +1 -0
  237. package/dist/providers/types.js +52 -0
  238. package/dist/providers/types.js.map +1 -0
  239. package/dist/providers/workspaceValidation.d.ts +18 -0
  240. package/dist/providers/workspaceValidation.d.ts.map +1 -0
  241. package/dist/providers/workspaceValidation.js +37 -0
  242. package/dist/providers/workspaceValidation.js.map +1 -0
  243. package/package.json +66 -0
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Process cleanup utility for the GitContext package.
3
+ * Kills processes that have open files in a given directory.
4
+ * Self-contained — no git/gh, no ADW core imports.
5
+ */
6
+ import { execSync } from 'child_process';
7
+ export function killProcessesInDirectory(directoryPath) {
8
+ try {
9
+ const output = execSync(`lsof +D "${directoryPath}" -t`, { encoding: 'utf-8' });
10
+ const pids = output
11
+ .split('\n')
12
+ .map((line) => parseInt(line.trim(), 10))
13
+ .filter((pid) => !isNaN(pid) && pid !== process.pid);
14
+ if (pids.length === 0)
15
+ return;
16
+ pids.forEach((pid) => {
17
+ try {
18
+ process.kill(pid, 'SIGTERM');
19
+ }
20
+ catch { /* already exited */ }
21
+ });
22
+ execSync('sleep 0.5', { stdio: 'pipe' });
23
+ const survivors = pids.filter((pid) => {
24
+ try {
25
+ process.kill(pid, 0);
26
+ return true;
27
+ }
28
+ catch {
29
+ return false;
30
+ }
31
+ });
32
+ if (survivors.length > 0) {
33
+ survivors.forEach((pid) => {
34
+ try {
35
+ process.kill(pid, 'SIGKILL');
36
+ }
37
+ catch { /* already exited */ }
38
+ });
39
+ }
40
+ }
41
+ catch {
42
+ // lsof not available or no processes found — proceed silently
43
+ }
44
+ }
45
+ //# sourceMappingURL=processCleanup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processCleanup.js","sourceRoot":"","sources":["../../src/git/processCleanup.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,MAAM,UAAU,wBAAwB,CAAC,aAAqB;IAC5D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,YAAY,aAAa,MAAM,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QAChF,MAAM,IAAI,GAAG,MAAM;aAChB,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;aACxC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;QAEvD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAE9B,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YACnB,IAAI,CAAC;gBAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,CAAC;QACtE,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAEzC,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE;YACpC,IAAI,CAAC;gBAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;gBAAC,OAAO,IAAI,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC;gBAAC,OAAO,KAAK,CAAC;YAAC,CAAC;QACpE,CAAC,CAAC,CAAC;QAEH,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,SAAS,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;gBACxB,IAAI,CAAC;oBAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,CAAC;YACtE,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,8DAA8D;IAChE,CAAC;AACH,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Package-private remote-interaction and merge op module for GitContext.
3
+ * Handles fetch from origin, ls-remote queries, merge a ref, and abort
4
+ * an in-progress merge.
5
+ *
6
+ * All functions propagate errors except abortMerge (which swallows them
7
+ * because aborting with no merge in progress is a benign no-op).
8
+ */
9
+ type Runner = (command: string, cwd: string) => string;
10
+ declare function fetchRemote(run: Runner, branch: string, cwd: string): string;
11
+ declare function mergeBranch(run: Runner, ref: string, cwd: string, opts?: {
12
+ noCommit?: boolean;
13
+ noFf?: boolean;
14
+ noEdit?: boolean;
15
+ }): void;
16
+ declare function abortMerge(run: Runner, cwd: string): void;
17
+ declare function lsRemote(run: Runner, branch: string, cwd: string): string;
18
+ export declare const remoteOps: {
19
+ fetchRemote: typeof fetchRemote;
20
+ mergeBranch: typeof mergeBranch;
21
+ abortMerge: typeof abortMerge;
22
+ lsRemote: typeof lsRemote;
23
+ };
24
+ export {};
25
+ //# sourceMappingURL=remoteOps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remoteOps.d.ts","sourceRoot":"","sources":["../../src/git/remoteOps.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,KAAK,MAAM,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;AAEvD,iBAAS,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAErE;AAED,iBAAS,WAAW,CAClB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,IAAI,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAClE,IAAI,CAON;AAED,iBAAS,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAIlD;AAED,iBAAS,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAElE;AAED,eAAO,MAAM,SAAS;;;;;CAAqD,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Package-private remote-interaction and merge op module for GitContext.
3
+ * Handles fetch from origin, ls-remote queries, merge a ref, and abort
4
+ * an in-progress merge.
5
+ *
6
+ * All functions propagate errors except abortMerge (which swallows them
7
+ * because aborting with no merge in progress is a benign no-op).
8
+ */
9
+ function fetchRemote(run, branch, cwd) {
10
+ return run(`git fetch origin "${branch}"`, cwd);
11
+ }
12
+ function mergeBranch(run, ref, cwd, opts = {}) {
13
+ const flags = [
14
+ opts.noCommit && '--no-commit',
15
+ opts.noFf && '--no-ff',
16
+ opts.noEdit && '--no-edit',
17
+ ].filter(Boolean).join(' ');
18
+ run(flags ? `git merge ${flags} "${ref}"` : `git merge "${ref}"`, cwd);
19
+ }
20
+ function abortMerge(run, cwd) {
21
+ try {
22
+ run('git merge --abort', cwd);
23
+ }
24
+ catch { /* no merge in progress — ignore */ }
25
+ }
26
+ function lsRemote(run, branch, cwd) {
27
+ return run(`git ls-remote origin "${branch}"`, cwd);
28
+ }
29
+ export const remoteOps = { fetchRemote, mergeBranch, abortMerge, lsRemote };
30
+ //# sourceMappingURL=remoteOps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remoteOps.js","sourceRoot":"","sources":["../../src/git/remoteOps.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,SAAS,WAAW,CAAC,GAAW,EAAE,MAAc,EAAE,GAAW;IAC3D,OAAO,GAAG,CAAC,qBAAqB,MAAM,GAAG,EAAE,GAAG,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,WAAW,CAClB,GAAW,EACX,GAAW,EACX,GAAW,EACX,OAAiE,EAAE;IAEnE,MAAM,KAAK,GAAG;QACZ,IAAI,CAAC,QAAQ,IAAI,aAAa;QAC9B,IAAI,CAAC,IAAI,IAAI,SAAS;QACtB,IAAI,CAAC,MAAM,IAAI,WAAW;KAC3B,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5B,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,KAAK,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,cAAc,GAAG,GAAG,EAAE,GAAG,CAAC,CAAC;AACzE,CAAC;AAED,SAAS,UAAU,CAAC,GAAW,EAAE,GAAW;IAC1C,IAAI,CAAC;QACH,GAAG,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC,CAAC,mCAAmC,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,QAAQ,CAAC,GAAW,EAAE,MAAc,EAAE,GAAW;IACxD,OAAO,GAAG,CAAC,yBAAyB,MAAM,GAAG,EAAE,GAAG,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,CAAC,MAAM,SAAS,GAAG,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Target repository workspace management — absorbed into the gitContext package (issue #700).
3
+ *
4
+ * Handles workspace path resolution, cloning, and fetching for external target
5
+ * repositories. Structurally exempt from the guard (adws/gitContext/ directory).
6
+ *
7
+ * All ADW-global config (TARGET_REPOS_DIR) is injected at the shim boundary in
8
+ * targetRepoManager.ts; this module stays ADW-global-free for standalone reuse.
9
+ * The `defaultBranch` thunk is injected so the caller can bind a veracious
10
+ * forge credential rather than relying on ambient auth.
11
+ *
12
+ * The caller supplies a ready-made clone URL (issue #793, PRD story 14): this
13
+ * module clones exactly the URL it is handed, with no rewriting and no forge
14
+ * vocabulary. The GitHub HTTPS→SSH rewrite lives in the adapter
15
+ * (`adws/providers/github/cloneUrl.ts`) and is applied by the ADW wiring
16
+ * shim (`adws/core/targetRepoManager.ts`) before this module is called.
17
+ */
18
+ import type { ExecSyncOptions } from 'child_process';
19
+ import * as fs from 'fs';
20
+ import type { Logger } from './types.js';
21
+ /** Minimal exec seam shared by clone and fetch operations. */
22
+ export type WorkspaceExecFn = (cmd: string, opts: {
23
+ cwd?: string;
24
+ stdio?: ExecSyncOptions['stdio'];
25
+ encoding?: string;
26
+ }) => void;
27
+ export interface EnsureRepoWorkspaceDeps {
28
+ /** Absolute path to the directory housing cloned target repos (injected from ADW env). */
29
+ targetReposDir: string;
30
+ /** Returns the default branch name, run under per-command veracious auth. */
31
+ getDefaultBranch: () => string;
32
+ /** Override for hermetic tests; defaults to execSync. */
33
+ exec?: WorkspaceExecFn;
34
+ /** Override for hermetic tests; defaults to real fs. */
35
+ fsDeps?: Pick<typeof fs, 'existsSync' | 'mkdirSync'>;
36
+ /** Log function; defaults to no-op (tests control verbosity). */
37
+ log?: Logger;
38
+ }
39
+ /**
40
+ * Returns the workspace path for a target repository.
41
+ * Format: `targetReposDir/{owner}/{repo}`
42
+ * `targetReposDir` is injected — never reads TARGET_REPOS_DIR directly.
43
+ */
44
+ export declare function getTargetRepoWorkspacePath(owner: string, repo: string, targetReposDir: string): string;
45
+ /** Returns true if a `.git` directory exists at workspacePath. */
46
+ export declare function isRepoCloned(workspacePath: string, fsDeps?: Pick<typeof fs, 'existsSync'>): boolean;
47
+ /**
48
+ * Clones a repository into workspacePath. Clones exactly the URL it is
49
+ * given (issue #793) — no rewriting, no scheme translation. The caller
50
+ * (`adws/core/targetRepoManager.ts`) is responsible for handing this
51
+ * function a ready-made clone URL.
52
+ */
53
+ export declare function cloneRepo(cloneUrl: string, workspacePath: string, opts?: {
54
+ fsDeps?: Pick<typeof fs, 'mkdirSync'>;
55
+ log?: Logger;
56
+ exec?: WorkspaceExecFn;
57
+ }): void;
58
+ /**
59
+ * Ensures a target repository workspace exists and is up-to-date.
60
+ *
61
+ * - Not cloned: clones `cloneUrl` exactly as given — no rewriting. The
62
+ * caller supplies a ready-made clone URL (issue #793); this function never
63
+ * consults forge conventions to decide what to clone.
64
+ * - Already cloned: runs `git fetch origin` and reads the default branch through
65
+ * the injected `getDefaultBranch` thunk — the forge's default-branch read,
66
+ * under per-command veracious auth. The clone URL is never consulted on
67
+ * this path.
68
+ *
69
+ * Returns the absolute workspace path.
70
+ */
71
+ export declare function ensureRepoWorkspace(owner: string, repo: string, cloneUrl: string, deps: EnsureRepoWorkspaceDeps): string;
72
+ //# sourceMappingURL=repoWorkspace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repoWorkspace.d.ts","sourceRoot":"","sources":["../../src/git/repoWorkspace.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAEzB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAMzC,8DAA8D;AAC9D,MAAM,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI,CAAC;AAEjI,MAAM,WAAW,uBAAuB;IACtC,0FAA0F;IAC1F,cAAc,EAAE,MAAM,CAAC;IACvB,6EAA6E;IAC7E,gBAAgB,EAAE,MAAM,MAAM,CAAC;IAC/B,yDAAyD;IACzD,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,wDAAwD;IACxD,MAAM,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,YAAY,GAAG,WAAW,CAAC,CAAC;IACrD,iEAAiE;IACjE,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAMD;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAEtG;AAED,kEAAkE;AAClE,wBAAgB,YAAY,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,YAAY,CAAC,GAAG,OAAO,CAGnG;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CACvB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE;IACL,MAAM,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;IACtC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,eAAe,CAAC;CACxB,GACA,IAAI,CAUN;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,uBAAuB,GAC5B,MAAM,CAiBR"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Target repository workspace management — absorbed into the gitContext package (issue #700).
3
+ *
4
+ * Handles workspace path resolution, cloning, and fetching for external target
5
+ * repositories. Structurally exempt from the guard (adws/gitContext/ directory).
6
+ *
7
+ * All ADW-global config (TARGET_REPOS_DIR) is injected at the shim boundary in
8
+ * targetRepoManager.ts; this module stays ADW-global-free for standalone reuse.
9
+ * The `defaultBranch` thunk is injected so the caller can bind a veracious
10
+ * forge credential rather than relying on ambient auth.
11
+ *
12
+ * The caller supplies a ready-made clone URL (issue #793, PRD story 14): this
13
+ * module clones exactly the URL it is handed, with no rewriting and no forge
14
+ * vocabulary. The GitHub HTTPS→SSH rewrite lives in the adapter
15
+ * (`adws/providers/github/cloneUrl.ts`) and is applied by the ADW wiring
16
+ * shim (`adws/core/targetRepoManager.ts`) before this module is called.
17
+ */
18
+ import { execSync } from 'child_process';
19
+ import * as fs from 'fs';
20
+ import * as path from 'path';
21
+ // ---------------------------------------------------------------------------
22
+ // Path helpers
23
+ // ---------------------------------------------------------------------------
24
+ /**
25
+ * Returns the workspace path for a target repository.
26
+ * Format: `targetReposDir/{owner}/{repo}`
27
+ * `targetReposDir` is injected — never reads TARGET_REPOS_DIR directly.
28
+ */
29
+ export function getTargetRepoWorkspacePath(owner, repo, targetReposDir) {
30
+ return path.join(targetReposDir, owner, repo);
31
+ }
32
+ /** Returns true if a `.git` directory exists at workspacePath. */
33
+ export function isRepoCloned(workspacePath, fsDeps) {
34
+ const fsOps = fsDeps ?? fs;
35
+ return fsOps.existsSync(path.join(workspacePath, '.git'));
36
+ }
37
+ /**
38
+ * Clones a repository into workspacePath. Clones exactly the URL it is
39
+ * given (issue #793) — no rewriting, no scheme translation. The caller
40
+ * (`adws/core/targetRepoManager.ts`) is responsible for handing this
41
+ * function a ready-made clone URL.
42
+ */
43
+ export function cloneRepo(cloneUrl, workspacePath, opts) {
44
+ const fsDeps = opts?.fsDeps ?? fs;
45
+ const logFn = opts?.log ?? (() => { });
46
+ const execFn = opts?.exec ?? ((cmd, o) => { execSync(cmd, { ...o, encoding: 'utf-8' }); });
47
+ const parentDir = path.dirname(workspacePath);
48
+ fsDeps.mkdirSync(parentDir, { recursive: true });
49
+ logFn(`Cloning ${cloneUrl} into ${workspacePath}...`, 'info');
50
+ execFn(`git clone "${cloneUrl}" "${workspacePath}"`, { stdio: 'pipe', encoding: 'utf-8' });
51
+ logFn(`Cloned ${cloneUrl} into ${workspacePath}`, 'success');
52
+ }
53
+ // ---------------------------------------------------------------------------
54
+ // ensureRepoWorkspace
55
+ // ---------------------------------------------------------------------------
56
+ /**
57
+ * Ensures a target repository workspace exists and is up-to-date.
58
+ *
59
+ * - Not cloned: clones `cloneUrl` exactly as given — no rewriting. The
60
+ * caller supplies a ready-made clone URL (issue #793); this function never
61
+ * consults forge conventions to decide what to clone.
62
+ * - Already cloned: runs `git fetch origin` and reads the default branch through
63
+ * the injected `getDefaultBranch` thunk — the forge's default-branch read,
64
+ * under per-command veracious auth. The clone URL is never consulted on
65
+ * this path.
66
+ *
67
+ * Returns the absolute workspace path.
68
+ */
69
+ export function ensureRepoWorkspace(owner, repo, cloneUrl, deps) {
70
+ const { targetReposDir, getDefaultBranch, log: logFn = () => { } } = deps;
71
+ const fsDeps = deps.fsDeps ?? fs;
72
+ const execFn = deps.exec ?? ((cmd, opts) => { execSync(cmd, { ...opts, encoding: 'utf-8', stdio: 'pipe' }); });
73
+ const workspacePath = getTargetRepoWorkspacePath(owner, repo, targetReposDir);
74
+ if (isRepoCloned(workspacePath, fsDeps)) {
75
+ logFn(`Target repo ${owner}/${repo} already cloned at ${workspacePath}`, 'info');
76
+ execFn('git fetch origin', { cwd: workspacePath });
77
+ const defaultBranch = getDefaultBranch();
78
+ logFn(`Fetched latest refs for ${defaultBranch} in ${workspacePath}`, 'success');
79
+ }
80
+ else {
81
+ cloneRepo(cloneUrl, workspacePath, { fsDeps, log: logFn, exec: execFn });
82
+ }
83
+ return workspacePath;
84
+ }
85
+ //# sourceMappingURL=repoWorkspace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repoWorkspace.js","sourceRoot":"","sources":["../../src/git/repoWorkspace.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,182 @@
1
+ /**
2
+ * Public types for the GitContext deep module.
3
+ *
4
+ * Contract: identity in, repo-scoped operations out. Base-path resolution
5
+ * lives only in the GitContext constructor — no optional base path, no cwd
6
+ * fallback. All identity and config are injected at construction so the
7
+ * package carries no dependency on ADW-specific globals.
8
+ */
9
+ /**
10
+ * Injectable command runner seam — exists for hermetic testing and
11
+ * standalone-package reuse. The default is a thin execSync wrapper;
12
+ * tests inject a spy that records invocations without spawning real processes.
13
+ *
14
+ * The optional `input` field passes data to the child process's stdin.
15
+ */
16
+ export type ExecFn = (command: string, options: {
17
+ cwd: string;
18
+ env: NodeJS.ProcessEnv;
19
+ input?: string;
20
+ }) => string;
21
+ /**
22
+ * The working-directory CLASS a command belongs to — the caller's declaration,
23
+ * never the executor's inference. There is no `process.cwd()` fallback and no
24
+ * fourth option.
25
+ *
26
+ * - `workspace` — the target workspace this context is bound to. Omitting
27
+ * `path` means the context base path; supplying `path`
28
+ * narrows to an explicit worktree beneath it.
29
+ * - `frameworkRoot` — the injected framework repository root, for commands
30
+ * that carry their own repository identity and need no
31
+ * checkout (#775's contract). Deliberately carries no `path`
32
+ * — "framework root with an explicit worktree path" is
33
+ * unrepresentable rather than merely undocumented.
34
+ */
35
+ export type ExecWorkingDirectory = {
36
+ readonly kind: 'workspace';
37
+ readonly path?: string;
38
+ } | {
39
+ readonly kind: 'frameworkRoot';
40
+ };
41
+ /**
42
+ * Options for {@link GitContext.exec}, the package's public forge-neutral
43
+ * executor. Deliberately carries no forge semantics — no credential
44
+ * selection, no PAT-versus-installation-token discrimination, no `--repo`
45
+ * awareness. `command` stays a separate, first positional parameter on
46
+ * `exec` (not folded into this object) so the `git-gh-shellout` CI guard
47
+ * keeps inspecting it.
48
+ */
49
+ export interface ExecOptions {
50
+ /** The working-directory class this command runs in — never a bare path. */
51
+ readonly cwd: ExecWorkingDirectory;
52
+ /**
53
+ * Per-command credential/identity overlay, merged over the inherited
54
+ * process environment inside the executor. Never a whole replacement
55
+ * environment, and never a `process.env` mutation.
56
+ */
57
+ readonly env: NodeJS.ProcessEnv;
58
+ /** Optional data piped to the child process's stdin. */
59
+ readonly input?: string;
60
+ }
61
+ /**
62
+ * The core's forge-neutral declaration of *why* a command needs a credential —
63
+ * never a declaration of *which kind* of credential it needs. `'alternateIdentity'`
64
+ * means "the primary automation identity cannot perform this operation" — true of
65
+ * PR approval (GitHub forbids bot self-approval) and Projects V2 writes (app tokens
66
+ * lack access on user-owned repos), and expressible on any forge. `'default'` is
67
+ * everything else. The core never learns that the answer to `'alternateIdentity'`
68
+ * is a PAT — only the provider knows that.
69
+ */
70
+ export type CredentialPurpose = 'default' | 'alternateIdentity';
71
+ /** A single command's credential request, bound to the repository it targets. */
72
+ export interface CredentialRequest {
73
+ readonly owner: string;
74
+ readonly repo: string;
75
+ readonly purpose: CredentialPurpose;
76
+ }
77
+ /**
78
+ * The TokenProvider port — the seam a forge adapter implements to hand the core
79
+ * credentials without the core ever holding one.
80
+ *
81
+ * `credentialEnv` is called on **every** command; the core never memoises its
82
+ * result. A GitHub App installation token expires roughly an hour after minting,
83
+ * and this is what lets the credential source's own expiry-aware refresh actually
84
+ * fire for a long-running orchestrator instead of replaying a stale snapshot.
85
+ *
86
+ * The return value is a per-command environment **overlay** — the same shape
87
+ * `ExecOptions.env` accepts — never a whole environment and never a
88
+ * `process.env` mutation. Returning an overlay rather than a bare token string
89
+ * keeps the credential variable's *name* (e.g. `GH_TOKEN`) on the provider's
90
+ * side of the port, so the core carries no forge vocabulary.
91
+ */
92
+ export interface TokenProvider {
93
+ credentialEnv(request: CredentialRequest): NodeJS.ProcessEnv;
94
+ }
95
+ /**
96
+ * Injectable filesystem seam for worktree management ops.
97
+ * All fields optional; defaults are the real fs functions.
98
+ */
99
+ export interface FsDeps {
100
+ existsSync: (p: string) => boolean;
101
+ mkdirSync: (p: string, opts?: {
102
+ recursive?: boolean;
103
+ }) => void;
104
+ copyFileSync: (src: string, dest: string) => void;
105
+ rmSync: (p: string, opts?: {
106
+ force?: boolean;
107
+ recursive?: boolean;
108
+ }) => void;
109
+ }
110
+ /**
111
+ * The four levels the worktree operations report at.
112
+ */
113
+ export type LogLevel = 'info' | 'error' | 'success' | 'warn';
114
+ /**
115
+ * The logger port (PRD story 17) — exists so the package carries no
116
+ * dependency on the host application's utilities. Structurally compatible
117
+ * with the host application's `log(message, level?)` (`adws/core/logger.ts`),
118
+ * so the ADW logger is injectable with no adapter.
119
+ */
120
+ export type Logger = (message: string, level?: LogLevel) => void;
121
+ /**
122
+ * Optional dependency bag for GitContext. Follows the ADW Deps idiom
123
+ * (JanitorDeps, MergeDeps, ReconcileDeps). All fields optional so existing
124
+ * call sites `new GitContext(options)` continue to work unchanged.
125
+ */
126
+ export interface GitContextDeps {
127
+ exec?: ExecFn;
128
+ /** Injectable fs for worktree management ops — defaults to real 'fs' functions. */
129
+ fsDeps?: FsDeps;
130
+ /** Injectable logger port — defaults to `consoleLogger`. */
131
+ logger?: Logger;
132
+ }
133
+ /** Git author and committer identity for child-process env overlays. */
134
+ export interface GitIdentity {
135
+ authorName: string;
136
+ authorEmail: string;
137
+ committerName: string;
138
+ committerEmail: string;
139
+ }
140
+ /**
141
+ * Construction options for GitContext.
142
+ *
143
+ * All fields, including `tokenProvider`, are mandatory — any missing or empty
144
+ * field is a hard construction error. There is no optional base-path
145
+ * parameter and no cwd fallback.
146
+ *
147
+ * frameworkRepoRoot and targetReposDir are injected by the caller (e.g. from
148
+ * environment.ts's REPO_ROOT and TARGET_REPOS_DIR) so this package depends on
149
+ * no ADW globals and can be imported by other projects.
150
+ */
151
+ export interface GitContextOptions {
152
+ /** Repository owner (organisation or user). */
153
+ owner: string;
154
+ /** Repository name (without the owner prefix). */
155
+ repo: string;
156
+ /**
157
+ * True when ADW is operating on its own (self-hosted) repository.
158
+ * False for any external target repository. Must be a boolean — omitting
159
+ * this field is a hard construction error (story 23).
160
+ */
161
+ selfHost: boolean;
162
+ /** Author and committer identity for git operations. */
163
+ gitIdentity: GitIdentity;
164
+ /**
165
+ * Absolute path to the ADW framework repository root.
166
+ * Injected by the caller (environment.ts REPO_ROOT). Used as basePath for
167
+ * self-host contexts.
168
+ */
169
+ frameworkRepoRoot: string;
170
+ /**
171
+ * Absolute path to the directory that houses cloned target repositories.
172
+ * Injected by the caller (environment.ts TARGET_REPOS_DIR). Used as the
173
+ * base of basePath for target contexts: join(targetReposDir, owner, repo).
174
+ */
175
+ targetReposDir: string;
176
+ /**
177
+ * A port the core asks, once per command, for a credential environment
178
+ * overlay. The core holds no token of its own — see {@link TokenProvider}.
179
+ */
180
+ tokenProvider: TokenProvider;
181
+ }
182
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/git/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Public types for the GitContext deep module.
3
+ *
4
+ * Contract: identity in, repo-scoped operations out. Base-path resolution
5
+ * lives only in the GitContext constructor — no optional base path, no cwd
6
+ * fallback. All identity and config are injected at construction so the
7
+ * package carries no dependency on ADW-specific globals.
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/git/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Diagnoses a spawn failure caused by a missing working directory and turns
3
+ * it into an error naming the path and repository identity.
4
+ *
5
+ * Node resolves a spawn's cwd before exec'ing the shell, so a nonexistent
6
+ * cwd surfaces as an ENOENT on the shell binary itself rather than on the
7
+ * directory. The message differs by runtime (node: "spawnSync /bin/sh
8
+ * ENOENT"; bun: "ENOENT: no such file or directory, posix_spawn '/bin/sh'")
9
+ * but `code` does not (verified 2026-07-30) — detection keys off `code`,
10
+ * never the message.
11
+ *
12
+ * Pure — no fs, no spawn. The existence probe is injected by the caller.
13
+ */
14
+ /** The five facts the diagnostic message needs — deliberately no basePath/frameworkRepoRoot, so the message never classifies which kind of directory went missing. */
15
+ export interface WorkingDirectoryContext {
16
+ cwd: string;
17
+ command: string;
18
+ owner: string;
19
+ repo: string;
20
+ selfHost: boolean;
21
+ }
22
+ /**
23
+ * Structural check for an ENOENT-coded failure — not `instanceof Error`, so
24
+ * an injected ExecFn seam that throws a plain shaped object is still
25
+ * diagnosed. Keys off `code` because the message text differs between node
26
+ * and bun for the same failure.
27
+ */
28
+ export declare function isSpawnEnoent(error: unknown): boolean;
29
+ /** One message shape for every missing-working-directory case — basePath or an explicit worktree path alike. */
30
+ export declare function describeMissingWorkingDirectory(ctx: WorkingDirectoryContext): string;
31
+ /**
32
+ * Returns the original error untouched in every case except a confirmed
33
+ * missing cwd — never a blanket wrap. When it does fire, the returned error
34
+ * preserves `code: 'ENOENT'` (plus `syscall`/`path`) and carries the
35
+ * original as `cause`, so existing ENOENT handling keeps working while the
36
+ * message gains the path, the repo, and the cause.
37
+ */
38
+ export declare function rewrapMissingWorkingDirectory(error: unknown, ctx: WorkingDirectoryContext, exists: (path: string) => boolean): unknown;
39
+ //# sourceMappingURL=workingDirectoryGuard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workingDirectoryGuard.d.ts","sourceRoot":"","sources":["../../src/git/workingDirectoryGuard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,sKAAsK;AACtK,MAAM,WAAW,uBAAuB;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;CACnB;AASD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAErD;AAED,gHAAgH;AAChH,wBAAgB,+BAA+B,CAAC,GAAG,EAAE,uBAAuB,GAAG,MAAM,CAEpF;AAED;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,OAAO,EACd,GAAG,EAAE,uBAAuB,EAC5B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GAChC,OAAO,CAUT"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Diagnoses a spawn failure caused by a missing working directory and turns
3
+ * it into an error naming the path and repository identity.
4
+ *
5
+ * Node resolves a spawn's cwd before exec'ing the shell, so a nonexistent
6
+ * cwd surfaces as an ENOENT on the shell binary itself rather than on the
7
+ * directory. The message differs by runtime (node: "spawnSync /bin/sh
8
+ * ENOENT"; bun: "ENOENT: no such file or directory, posix_spawn '/bin/sh'")
9
+ * but `code` does not (verified 2026-07-30) — detection keys off `code`,
10
+ * never the message.
11
+ *
12
+ * Pure — no fs, no spawn. The existence probe is injected by the caller.
13
+ */
14
+ const MAX_COMMAND_CHARS = 120;
15
+ function truncateCommand(command) {
16
+ if (command.length <= MAX_COMMAND_CHARS)
17
+ return command;
18
+ return `${command.slice(0, MAX_COMMAND_CHARS)}…`;
19
+ }
20
+ /**
21
+ * Structural check for an ENOENT-coded failure — not `instanceof Error`, so
22
+ * an injected ExecFn seam that throws a plain shaped object is still
23
+ * diagnosed. Keys off `code` because the message text differs between node
24
+ * and bun for the same failure.
25
+ */
26
+ export function isSpawnEnoent(error) {
27
+ return typeof error === 'object' && error !== null && error.code === 'ENOENT';
28
+ }
29
+ /** One message shape for every missing-working-directory case — basePath or an explicit worktree path alike. */
30
+ export function describeMissingWorkingDirectory(ctx) {
31
+ return `GitContext: working directory does not exist: ${ctx.cwd} (${ctx.owner}/${ctx.repo}, selfHost=${ctx.selfHost}) — has a workflow ever cloned this workspace on this host? [while running: ${truncateCommand(ctx.command)}]`;
32
+ }
33
+ /**
34
+ * Returns the original error untouched in every case except a confirmed
35
+ * missing cwd — never a blanket wrap. When it does fire, the returned error
36
+ * preserves `code: 'ENOENT'` (plus `syscall`/`path`) and carries the
37
+ * original as `cause`, so existing ENOENT handling keeps working while the
38
+ * message gains the path, the repo, and the cause.
39
+ */
40
+ export function rewrapMissingWorkingDirectory(error, ctx, exists) {
41
+ if (!isSpawnEnoent(error))
42
+ return error;
43
+ if (exists(ctx.cwd))
44
+ return error;
45
+ const original = error;
46
+ return Object.assign(new Error(describeMissingWorkingDirectory(ctx)), {
47
+ code: 'ENOENT',
48
+ syscall: original.syscall,
49
+ path: original.path,
50
+ cause: original,
51
+ });
52
+ }
53
+ //# sourceMappingURL=workingDirectoryGuard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workingDirectoryGuard.js","sourceRoot":"","sources":["../../src/git/workingDirectoryGuard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAWH,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAE9B,SAAS,eAAe,CAAC,OAAe;IACtC,IAAI,OAAO,CAAC,MAAM,IAAI,iBAAiB;QAAE,OAAO,OAAO,CAAC;IACxD,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,iBAAiB,CAAC,GAAG,CAAC;AACnD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,CAAC;AAC3G,CAAC;AAED,gHAAgH;AAChH,MAAM,UAAU,+BAA+B,CAAC,GAA4B;IAC1E,OAAO,iDAAiD,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,IAAI,cAAc,GAAG,CAAC,QAAQ,+EAA+E,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC;AACpO,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,6BAA6B,CAC3C,KAAc,EACd,GAA4B,EAC5B,MAAiC;IAEjC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACxC,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAClC,MAAM,QAAQ,GAAG,KAA8B,CAAC;IAChD,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,+BAA+B,CAAC,GAAG,CAAC,CAAC,EAAE;QACpE,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,QAAQ,CAAC,OAAO;QACzB,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,KAAK,EAAE,QAAQ;KAChB,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Package-private worktree create/ensure ops for GitContext.
3
+ * Injects runner, fs and a logger port for testability — no base-path
4
+ * computation here.
5
+ */
6
+ import type { Logger } from './types.js';
7
+ type Runner = (command: string, cwd: string) => string;
8
+ interface FsDeps {
9
+ existsSync: (p: string) => boolean;
10
+ mkdirSync: (p: string, opts?: {
11
+ recursive?: boolean;
12
+ }) => void;
13
+ copyFileSync: (src: string, dest: string) => void;
14
+ }
15
+ interface WorktreePaths {
16
+ worktreesDir: string;
17
+ worktreePath: string;
18
+ baseCwd: string;
19
+ }
20
+ export type { FsDeps as WorktreeCreateFsDeps };
21
+ /**
22
+ * Copies .env and .env.local from baseCwd (the repo root) to the worktree.
23
+ */
24
+ declare function copyEnvToWorktree(fs: FsDeps, log: Logger, baseCwd: string, worktreePath: string): void;
25
+ /**
26
+ * Creates a worktree for an existing branch (or creates a new one from baseBranch).
27
+ * Returns the worktree path.
28
+ */
29
+ declare function createWorktree(run: Runner, fs: FsDeps, log: Logger, paths: WorktreePaths, branchName: string, baseBranch?: string): string;
30
+ /**
31
+ * Creates a worktree with a new branch from an optional base (defaults to HEAD).
32
+ */
33
+ declare function createWorktreeForNewBranch(run: Runner, fs: FsDeps, log: Logger, paths: WorktreePaths, branchName: string, baseBranch?: string): string;
34
+ /**
35
+ * Ensures a worktree exists for the branch, creating if needed.
36
+ * Copies env files into the worktree.
37
+ */
38
+ declare function ensureWorktree(run: Runner, fs: FsDeps, log: Logger, paths: WorktreePaths, branchName: string, baseBranch?: string): string;
39
+ export declare const worktreeCreateOps: {
40
+ createWorktree: typeof createWorktree;
41
+ createWorktreeForNewBranch: typeof createWorktreeForNewBranch;
42
+ ensureWorktree: typeof ensureWorktree;
43
+ copyEnvToWorktree: typeof copyEnvToWorktree;
44
+ };
45
+ //# sourceMappingURL=worktreeCreateOps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktreeCreateOps.d.ts","sourceRoot":"","sources":["../../src/git/worktreeCreateOps.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAGzC,KAAK,MAAM,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;AAEvD,UAAU,MAAM;IACd,UAAU,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;IACnC,SAAS,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC/D,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACnD;AAED,UAAU,aAAa;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,YAAY,EAAE,MAAM,IAAI,oBAAoB,EAAE,CAAC;AAqE/C;;GAEG;AACH,iBAAS,iBAAiB,CACxB,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,GACnB,IAAI,CAWN;AAqBD;;;GAGG;AACH,iBAAS,cAAc,CACrB,GAAG,EAAE,MAAM,EACX,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,aAAa,EACpB,UAAU,EAAE,MAAM,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CA4CR;AAED;;GAEG;AACH,iBAAS,0BAA0B,CACjC,GAAG,EAAE,MAAM,EACX,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,aAAa,EACpB,UAAU,EAAE,MAAM,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CAqBR;AAED;;;GAGG;AACH,iBAAS,cAAc,CACrB,GAAG,EAAE,MAAM,EACX,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,aAAa,EACpB,UAAU,EAAE,MAAM,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CAYR;AAED,eAAO,MAAM,iBAAiB;;;;;CAK7B,CAAC"}