@ttfw/envoi 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 (283) hide show
  1. package/README.md +238 -0
  2. package/dist/commands/app.d.ts +2 -0
  3. package/dist/commands/app.d.ts.map +1 -0
  4. package/dist/commands/app.js +31 -0
  5. package/dist/commands/app.js.map +1 -0
  6. package/dist/commands/autonomy.d.ts +6 -0
  7. package/dist/commands/autonomy.d.ts.map +1 -0
  8. package/dist/commands/autonomy.js +89 -0
  9. package/dist/commands/autonomy.js.map +1 -0
  10. package/dist/commands/builder.d.ts +13 -0
  11. package/dist/commands/builder.d.ts.map +1 -0
  12. package/dist/commands/builder.js +142 -0
  13. package/dist/commands/builder.js.map +1 -0
  14. package/dist/commands/idea.d.ts +12 -0
  15. package/dist/commands/idea.d.ts.map +1 -0
  16. package/dist/commands/idea.js +79 -0
  17. package/dist/commands/idea.js.map +1 -0
  18. package/dist/commands/init.d.ts +18 -0
  19. package/dist/commands/init.d.ts.map +1 -0
  20. package/dist/commands/init.js +423 -0
  21. package/dist/commands/init.js.map +1 -0
  22. package/dist/commands/mode.d.ts +13 -0
  23. package/dist/commands/mode.d.ts.map +1 -0
  24. package/dist/commands/mode.js +96 -0
  25. package/dist/commands/mode.js.map +1 -0
  26. package/dist/commands/onboard.d.ts +37 -0
  27. package/dist/commands/onboard.d.ts.map +1 -0
  28. package/dist/commands/onboard.js +743 -0
  29. package/dist/commands/onboard.js.map +1 -0
  30. package/dist/commands/pr-note.d.ts +8 -0
  31. package/dist/commands/pr-note.d.ts.map +1 -0
  32. package/dist/commands/pr-note.js +27 -0
  33. package/dist/commands/pr-note.js.map +1 -0
  34. package/dist/commands/undo.d.ts +7 -0
  35. package/dist/commands/undo.d.ts.map +1 -0
  36. package/dist/commands/undo.js +59 -0
  37. package/dist/commands/undo.js.map +1 -0
  38. package/dist/commands/update.d.ts +24 -0
  39. package/dist/commands/update.d.ts.map +1 -0
  40. package/dist/commands/update.js +248 -0
  41. package/dist/commands/update.js.map +1 -0
  42. package/dist/constants/report_codes.d.ts +29 -0
  43. package/dist/constants/report_codes.d.ts.map +1 -0
  44. package/dist/constants/report_codes.js +69 -0
  45. package/dist/constants/report_codes.js.map +1 -0
  46. package/dist/index.d.ts +3 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/dist/index.js +675 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/lib/autonomy.d.ts +16 -0
  51. package/dist/lib/autonomy.d.ts.map +1 -0
  52. package/dist/lib/autonomy.js +38 -0
  53. package/dist/lib/autonomy.js.map +1 -0
  54. package/dist/lib/blocked.d.ts +87 -0
  55. package/dist/lib/blocked.d.ts.map +1 -0
  56. package/dist/lib/blocked.js +134 -0
  57. package/dist/lib/blocked.js.map +1 -0
  58. package/dist/lib/branding.d.ts +13 -0
  59. package/dist/lib/branding.d.ts.map +1 -0
  60. package/dist/lib/branding.js +19 -0
  61. package/dist/lib/branding.js.map +1 -0
  62. package/dist/lib/claude.d.ts +42 -0
  63. package/dist/lib/claude.d.ts.map +1 -0
  64. package/dist/lib/claude.js +291 -0
  65. package/dist/lib/claude.js.map +1 -0
  66. package/dist/lib/config.d.ts +71 -0
  67. package/dist/lib/config.d.ts.map +1 -0
  68. package/dist/lib/config.js +410 -0
  69. package/dist/lib/config.js.map +1 -0
  70. package/dist/lib/diff.d.ts +150 -0
  71. package/dist/lib/diff.d.ts.map +1 -0
  72. package/dist/lib/diff.js +257 -0
  73. package/dist/lib/diff.js.map +1 -0
  74. package/dist/lib/doctor.d.ts +67 -0
  75. package/dist/lib/doctor.d.ts.map +1 -0
  76. package/dist/lib/doctor.js +211 -0
  77. package/dist/lib/doctor.js.map +1 -0
  78. package/dist/lib/fingerprint.d.ts +27 -0
  79. package/dist/lib/fingerprint.d.ts.map +1 -0
  80. package/dist/lib/fingerprint.js +116 -0
  81. package/dist/lib/fingerprint.js.map +1 -0
  82. package/dist/lib/fs.d.ts +93 -0
  83. package/dist/lib/fs.d.ts.map +1 -0
  84. package/dist/lib/fs.js +179 -0
  85. package/dist/lib/fs.js.map +1 -0
  86. package/dist/lib/git.d.ts +177 -0
  87. package/dist/lib/git.d.ts.map +1 -0
  88. package/dist/lib/git.js +355 -0
  89. package/dist/lib/git.js.map +1 -0
  90. package/dist/lib/git_branching.d.ts +84 -0
  91. package/dist/lib/git_branching.d.ts.map +1 -0
  92. package/dist/lib/git_branching.js +327 -0
  93. package/dist/lib/git_branching.js.map +1 -0
  94. package/dist/lib/gitignore.d.ts +26 -0
  95. package/dist/lib/gitignore.d.ts.map +1 -0
  96. package/dist/lib/gitignore.js +119 -0
  97. package/dist/lib/gitignore.js.map +1 -0
  98. package/dist/lib/guardrails.d.ts +232 -0
  99. package/dist/lib/guardrails.d.ts.map +1 -0
  100. package/dist/lib/guardrails.js +323 -0
  101. package/dist/lib/guardrails.js.map +1 -0
  102. package/dist/lib/history.d.ts +110 -0
  103. package/dist/lib/history.d.ts.map +1 -0
  104. package/dist/lib/history.js +236 -0
  105. package/dist/lib/history.js.map +1 -0
  106. package/dist/lib/index.d.ts +29 -0
  107. package/dist/lib/index.d.ts.map +1 -0
  108. package/dist/lib/index.js +29 -0
  109. package/dist/lib/index.js.map +1 -0
  110. package/dist/lib/json-extract.d.ts +42 -0
  111. package/dist/lib/json-extract.d.ts.map +1 -0
  112. package/dist/lib/json-extract.js +201 -0
  113. package/dist/lib/json-extract.js.map +1 -0
  114. package/dist/lib/judge.d.ts +237 -0
  115. package/dist/lib/judge.d.ts.map +1 -0
  116. package/dist/lib/judge.js +501 -0
  117. package/dist/lib/judge.js.map +1 -0
  118. package/dist/lib/lock.d.ts +79 -0
  119. package/dist/lib/lock.d.ts.map +1 -0
  120. package/dist/lib/lock.js +254 -0
  121. package/dist/lib/lock.js.map +1 -0
  122. package/dist/lib/migration.d.ts +9 -0
  123. package/dist/lib/migration.d.ts.map +1 -0
  124. package/dist/lib/migration.js +74 -0
  125. package/dist/lib/migration.js.map +1 -0
  126. package/dist/lib/paths.d.ts +18 -0
  127. package/dist/lib/paths.d.ts.map +1 -0
  128. package/dist/lib/paths.js +27 -0
  129. package/dist/lib/paths.js.map +1 -0
  130. package/dist/lib/preflight.d.ts +33 -0
  131. package/dist/lib/preflight.d.ts.map +1 -0
  132. package/dist/lib/preflight.js +177 -0
  133. package/dist/lib/preflight.js.map +1 -0
  134. package/dist/lib/prompt_budget.d.ts +18 -0
  135. package/dist/lib/prompt_budget.d.ts.map +1 -0
  136. package/dist/lib/prompt_budget.js +36 -0
  137. package/dist/lib/prompt_budget.js.map +1 -0
  138. package/dist/lib/report.d.ts +102 -0
  139. package/dist/lib/report.d.ts.map +1 -0
  140. package/dist/lib/report.js +347 -0
  141. package/dist/lib/report.js.map +1 -0
  142. package/dist/lib/reviewer-flow.d.ts +80 -0
  143. package/dist/lib/reviewer-flow.d.ts.map +1 -0
  144. package/dist/lib/reviewer-flow.js +138 -0
  145. package/dist/lib/reviewer-flow.js.map +1 -0
  146. package/dist/lib/reviewer.d.ts +53 -0
  147. package/dist/lib/reviewer.d.ts.map +1 -0
  148. package/dist/lib/reviewer.js +199 -0
  149. package/dist/lib/reviewer.js.map +1 -0
  150. package/dist/lib/risk.d.ts +127 -0
  151. package/dist/lib/risk.d.ts.map +1 -0
  152. package/dist/lib/risk.js +192 -0
  153. package/dist/lib/risk.js.map +1 -0
  154. package/dist/lib/rollback.d.ts +143 -0
  155. package/dist/lib/rollback.d.ts.map +1 -0
  156. package/dist/lib/rollback.js +244 -0
  157. package/dist/lib/rollback.js.map +1 -0
  158. package/dist/lib/schema.d.ts +47 -0
  159. package/dist/lib/schema.d.ts.map +1 -0
  160. package/dist/lib/schema.js +91 -0
  161. package/dist/lib/schema.js.map +1 -0
  162. package/dist/lib/scope.d.ts +89 -0
  163. package/dist/lib/scope.d.ts.map +1 -0
  164. package/dist/lib/scope.js +135 -0
  165. package/dist/lib/scope.js.map +1 -0
  166. package/dist/lib/self_update.d.ts +13 -0
  167. package/dist/lib/self_update.d.ts.map +1 -0
  168. package/dist/lib/self_update.js +172 -0
  169. package/dist/lib/self_update.js.map +1 -0
  170. package/dist/lib/state.d.ts +143 -0
  171. package/dist/lib/state.d.ts.map +1 -0
  172. package/dist/lib/state.js +258 -0
  173. package/dist/lib/state.js.map +1 -0
  174. package/dist/lib/tick.d.ts +310 -0
  175. package/dist/lib/tick.d.ts.map +1 -0
  176. package/dist/lib/tick.js +424 -0
  177. package/dist/lib/tick.js.map +1 -0
  178. package/dist/lib/transport.d.ts +145 -0
  179. package/dist/lib/transport.d.ts.map +1 -0
  180. package/dist/lib/transport.js +237 -0
  181. package/dist/lib/transport.js.map +1 -0
  182. package/dist/lib/verdict_labels.d.ts +5 -0
  183. package/dist/lib/verdict_labels.d.ts.map +1 -0
  184. package/dist/lib/verdict_labels.js +25 -0
  185. package/dist/lib/verdict_labels.js.map +1 -0
  186. package/dist/lib/verify-safety.d.ts +63 -0
  187. package/dist/lib/verify-safety.d.ts.map +1 -0
  188. package/dist/lib/verify-safety.js +123 -0
  189. package/dist/lib/verify-safety.js.map +1 -0
  190. package/dist/lib/verify.d.ts +139 -0
  191. package/dist/lib/verify.d.ts.map +1 -0
  192. package/dist/lib/verify.js +311 -0
  193. package/dist/lib/verify.js.map +1 -0
  194. package/dist/lib/workspace_state.d.ts +79 -0
  195. package/dist/lib/workspace_state.d.ts.map +1 -0
  196. package/dist/lib/workspace_state.js +283 -0
  197. package/dist/lib/workspace_state.js.map +1 -0
  198. package/dist/runner/builder.d.ts +58 -0
  199. package/dist/runner/builder.d.ts.map +1 -0
  200. package/dist/runner/builder.js +775 -0
  201. package/dist/runner/builder.js.map +1 -0
  202. package/dist/runner/builder_parse.d.ts +37 -0
  203. package/dist/runner/builder_parse.d.ts.map +1 -0
  204. package/dist/runner/builder_parse.js +76 -0
  205. package/dist/runner/builder_parse.js.map +1 -0
  206. package/dist/runner/index.d.ts +9 -0
  207. package/dist/runner/index.d.ts.map +1 -0
  208. package/dist/runner/index.js +7 -0
  209. package/dist/runner/index.js.map +1 -0
  210. package/dist/runner/loop.d.ts +51 -0
  211. package/dist/runner/loop.d.ts.map +1 -0
  212. package/dist/runner/loop.js +221 -0
  213. package/dist/runner/loop.js.map +1 -0
  214. package/dist/runner/orchestrator.d.ts +67 -0
  215. package/dist/runner/orchestrator.d.ts.map +1 -0
  216. package/dist/runner/orchestrator.js +376 -0
  217. package/dist/runner/orchestrator.js.map +1 -0
  218. package/dist/runner/tick.d.ts +10 -0
  219. package/dist/runner/tick.d.ts.map +1 -0
  220. package/dist/runner/tick.js +1639 -0
  221. package/dist/runner/tick.js.map +1 -0
  222. package/dist/types/blocked.d.ts +52 -0
  223. package/dist/types/blocked.d.ts.map +1 -0
  224. package/dist/types/blocked.js +8 -0
  225. package/dist/types/blocked.js.map +1 -0
  226. package/dist/types/builder.d.ts +25 -0
  227. package/dist/types/builder.d.ts.map +1 -0
  228. package/dist/types/builder.js +7 -0
  229. package/dist/types/builder.js.map +1 -0
  230. package/dist/types/claude.d.ts +86 -0
  231. package/dist/types/claude.d.ts.map +1 -0
  232. package/dist/types/claude.js +48 -0
  233. package/dist/types/claude.js.map +1 -0
  234. package/dist/types/config.d.ts +384 -0
  235. package/dist/types/config.d.ts.map +1 -0
  236. package/dist/types/config.js +7 -0
  237. package/dist/types/config.js.map +1 -0
  238. package/dist/types/index.d.ts +18 -0
  239. package/dist/types/index.d.ts.map +1 -0
  240. package/dist/types/index.js +8 -0
  241. package/dist/types/index.js.map +1 -0
  242. package/dist/types/lock.d.ts +21 -0
  243. package/dist/types/lock.d.ts.map +1 -0
  244. package/dist/types/lock.js +8 -0
  245. package/dist/types/lock.js.map +1 -0
  246. package/dist/types/preflight.d.ts +49 -0
  247. package/dist/types/preflight.d.ts.map +1 -0
  248. package/dist/types/preflight.js +8 -0
  249. package/dist/types/preflight.js.map +1 -0
  250. package/dist/types/report.d.ts +161 -0
  251. package/dist/types/report.d.ts.map +1 -0
  252. package/dist/types/report.js +8 -0
  253. package/dist/types/report.js.map +1 -0
  254. package/dist/types/reviewer.d.ts +66 -0
  255. package/dist/types/reviewer.d.ts.map +1 -0
  256. package/dist/types/reviewer.js +5 -0
  257. package/dist/types/reviewer.js.map +1 -0
  258. package/dist/types/state.d.ts +124 -0
  259. package/dist/types/state.d.ts.map +1 -0
  260. package/dist/types/state.js +20 -0
  261. package/dist/types/state.js.map +1 -0
  262. package/dist/types/task.d.ts +117 -0
  263. package/dist/types/task.d.ts.map +1 -0
  264. package/dist/types/task.js +7 -0
  265. package/dist/types/task.js.map +1 -0
  266. package/dist/types/workspace_state.d.ts +125 -0
  267. package/dist/types/workspace_state.d.ts.map +1 -0
  268. package/dist/types/workspace_state.js +10 -0
  269. package/dist/types/workspace_state.js.map +1 -0
  270. package/envoi.config.json +191 -0
  271. package/package.json +52 -0
  272. package/relais/prompts/.gitkeep +0 -0
  273. package/relais/prompts/builder.system.txt +13 -0
  274. package/relais/prompts/builder.user.txt +15 -0
  275. package/relais/prompts/orchestrator.system.txt +37 -0
  276. package/relais/prompts/orchestrator.user.txt +34 -0
  277. package/relais/prompts/reviewer.system.txt +33 -0
  278. package/relais/prompts/reviewer.user.txt +35 -0
  279. package/relais/schemas/.gitkeep +0 -0
  280. package/relais/schemas/builder_result.schema.json +29 -0
  281. package/relais/schemas/report.schema.json +195 -0
  282. package/relais/schemas/reviewer_result.schema.json +70 -0
  283. package/relais/schemas/task.schema.json +155 -0
@@ -0,0 +1,327 @@
1
+ /**
2
+ * Git branching helper functions for runner-owned branch management.
3
+ *
4
+ * Uses execSync for git operations to ensure synchronous, blocking behavior.
5
+ * All git commands use argv-only (no shell strings) for security.
6
+ */
7
+ import { spawnSync } from 'node:child_process';
8
+ /**
9
+ * Expands a branch name template with placeholders.
10
+ *
11
+ * Supported placeholders (both {{...}} and {...} styles):
12
+ * - {{task_id}} or {task_id} - Task ID
13
+ * - {{milestone_id}} or {milestone_id} - Milestone ID
14
+ * - {{run_id}} or {run_id} - Run ID
15
+ * - {{tick_count}} or {tick_count} - Tick count (1-based)
16
+ * - {{seq}} or {seq} or {{batch_index}} or {batch_index} - Sequence/batch index (0-based)
17
+ * - {{YYYYMMDD}} or {YYYYMMDD} - Date in YYYYMMDD format
18
+ *
19
+ * @param template - Template string with placeholders
20
+ * @param params - Parameters to substitute
21
+ * @returns Expanded branch name
22
+ */
23
+ export function expandBranchTemplate(template, params) {
24
+ let result = template;
25
+ // Generate YYYYMMDD if not provided
26
+ if (!params.YYYYMMDD) {
27
+ const now = new Date();
28
+ const year = now.getFullYear();
29
+ const month = String(now.getMonth() + 1).padStart(2, '0');
30
+ const day = String(now.getDate()).padStart(2, '0');
31
+ params.YYYYMMDD = `${year}${month}${day}`;
32
+ }
33
+ // Use seq if batch_index is provided but seq is not
34
+ if (params.batch_index !== undefined && params.seq === undefined) {
35
+ params.seq = params.batch_index;
36
+ }
37
+ // Replace both {{...}} and {...} styles
38
+ const replacements = [
39
+ [/\{\{task_id\}\}|\{task_id\}/g, params.task_id || ''],
40
+ [/\{\{milestone_id\}\}|\{milestone_id\}/g, params.milestone_id || ''],
41
+ [/\{\{run_id\}\}|\{run_id\}/g, params.run_id || ''],
42
+ [/\{\{tick_count\}\}|\{tick_count\}/g, params.tick_count !== undefined ? String(params.tick_count) : ''],
43
+ [/\{\{seq\}\}|\{seq\}/g, params.seq !== undefined ? String(params.seq) : ''],
44
+ [/\{\{batch_index\}\}|\{batch_index\}/g, params.seq !== undefined ? String(params.seq) : ''],
45
+ [/\{\{YYYYMMDD\}\}|\{YYYYMMDD\}/g, params.YYYYMMDD || ''],
46
+ ];
47
+ for (const [pattern, replacement] of replacements) {
48
+ result = result.replace(pattern, replacement);
49
+ }
50
+ // Remove any remaining placeholders (replace with empty string)
51
+ result = result.replace(/\{\{?\w+\}?\}/g, '');
52
+ return result;
53
+ }
54
+ /**
55
+ * Checks if a branch exists locally.
56
+ *
57
+ * @param branchName - Branch name to check
58
+ * @returns true if branch exists, false otherwise
59
+ */
60
+ function branchExists(branchName) {
61
+ try {
62
+ const result = spawnSync('git', ['show-ref', '--verify', '--quiet', `refs/heads/${branchName}`], {
63
+ encoding: 'utf-8',
64
+ stdio: ['pipe', 'pipe', 'pipe'],
65
+ });
66
+ return result.status === 0;
67
+ }
68
+ catch {
69
+ return false;
70
+ }
71
+ }
72
+ /**
73
+ * Gets the current branch name.
74
+ *
75
+ * @returns Current branch name, or null if detached HEAD
76
+ */
77
+ function getCurrentBranch() {
78
+ try {
79
+ const result = spawnSync('git', ['branch', '--show-current'], {
80
+ encoding: 'utf-8',
81
+ stdio: ['pipe', 'pipe', 'pipe'],
82
+ });
83
+ if (result.status !== 0 || !result.stdout) {
84
+ return null;
85
+ }
86
+ return result.stdout.toString().trim() || null;
87
+ }
88
+ catch {
89
+ return null;
90
+ }
91
+ }
92
+ /**
93
+ * Creates a new branch or switches to existing branch.
94
+ *
95
+ * If the branch already exists, switches to it.
96
+ * If the branch doesn't exist, creates it from the specified base ref (default: HEAD).
97
+ *
98
+ * @param branchName - Branch name to create/switch to
99
+ * @param baseRef - Base ref (commit/branch) to create branch from. Default: 'HEAD'
100
+ * @returns BranchResult indicating success or failure
101
+ */
102
+ function createOrSwitchBranch(branchName, baseRef = 'HEAD') {
103
+ const exists = branchExists(branchName);
104
+ const currentBranch = getCurrentBranch();
105
+ // If already on the target branch, no-op
106
+ if (currentBranch === branchName) {
107
+ return {
108
+ ok: true,
109
+ branchName,
110
+ existed: exists,
111
+ };
112
+ }
113
+ try {
114
+ let result;
115
+ if (exists) {
116
+ // Branch exists, switch to it
117
+ result = spawnSync('git', ['checkout', branchName], {
118
+ encoding: 'utf-8',
119
+ stdio: ['pipe', 'pipe', 'pipe'],
120
+ });
121
+ }
122
+ else {
123
+ // Branch doesn't exist, create it from baseRef
124
+ result = spawnSync('git', ['checkout', '-b', branchName, baseRef], {
125
+ encoding: 'utf-8',
126
+ stdio: ['pipe', 'pipe', 'pipe'],
127
+ });
128
+ }
129
+ if (result.status !== 0) {
130
+ const errorMsg = result.stderr?.toString() || `Git command failed with status ${result.status}`;
131
+ return {
132
+ ok: false,
133
+ branchName,
134
+ existed: exists,
135
+ error: errorMsg,
136
+ };
137
+ }
138
+ return {
139
+ ok: true,
140
+ branchName,
141
+ existed: exists,
142
+ };
143
+ }
144
+ catch (error) {
145
+ return {
146
+ ok: false,
147
+ branchName,
148
+ existed: exists,
149
+ error: error instanceof Error ? error.message : String(error),
150
+ };
151
+ }
152
+ }
153
+ /**
154
+ * Finds an available branch name by appending a numeric suffix.
155
+ *
156
+ * If the base name exists, tries base-1, base-2, etc. until finding an available name.
157
+ *
158
+ * @param baseName - Base branch name
159
+ * @param maxAttempts - Maximum number of attempts (default: 100)
160
+ * @returns Available branch name
161
+ */
162
+ function findAvailableBranchName(baseName, maxAttempts = 100) {
163
+ if (!branchExists(baseName)) {
164
+ return baseName;
165
+ }
166
+ for (let i = 1; i <= maxAttempts; i++) {
167
+ const candidate = `${baseName}-${i}`;
168
+ if (!branchExists(candidate)) {
169
+ return candidate;
170
+ }
171
+ }
172
+ // Fallback: use timestamp if all attempts exhausted
173
+ return `${baseName}-${Date.now()}`;
174
+ }
175
+ /**
176
+ * Sanitizes a branch name to comply with git branch naming rules.
177
+ *
178
+ * @param name - Branch name to sanitize
179
+ * @returns Sanitized branch name
180
+ */
181
+ function sanitizeBranchName(name) {
182
+ // Replace invalid characters with hyphens
183
+ let sanitized = name
184
+ .replace(/[^a-zA-Z0-9\/_\-\.]/g, '-')
185
+ .replace(/\/+/g, '/')
186
+ .replace(/^-+|-+$/g, '');
187
+ // Ensure it's not empty
188
+ if (!sanitized) {
189
+ sanitized = 'envoi/branch';
190
+ }
191
+ return sanitized;
192
+ }
193
+ /**
194
+ * Ensures a branch exists and HEAD is on it (per_tick mode).
195
+ *
196
+ * For per_tick mode, creates/switches to a branch based on the template.
197
+ * If the branch already exists, switches to it (idempotent).
198
+ * If there's a collision, appends a numeric suffix.
199
+ *
200
+ * @param config - Git branching configuration
201
+ * @param params - Parameters for template expansion
202
+ * @returns BranchResult indicating success or failure
203
+ */
204
+ export function ensureBranchPerTick(config, params) {
205
+ if (config.mode !== 'per_tick') {
206
+ return {
207
+ ok: false,
208
+ branchName: '',
209
+ error: `Branching mode is not 'per_tick' (got '${config.mode}')`,
210
+ existed: false,
211
+ };
212
+ }
213
+ const template = config.name_template || 'envoi/{{task_id}}';
214
+ const baseName = expandBranchTemplate(template, params);
215
+ const sanitizedName = sanitizeBranchName(baseName);
216
+ if (!sanitizedName) {
217
+ return {
218
+ ok: false,
219
+ branchName: '',
220
+ error: 'Branch name template expanded to empty string',
221
+ existed: false,
222
+ };
223
+ }
224
+ // Find available branch name (handles collisions)
225
+ const branchName = findAvailableBranchName(sanitizedName);
226
+ const baseRef = config.base_ref || 'HEAD';
227
+ return createOrSwitchBranch(branchName, baseRef);
228
+ }
229
+ /**
230
+ * Ensures a branch exists and HEAD is on it (per_n_tasks mode).
231
+ *
232
+ * For per_n_tasks mode, creates/switches to a branch based on the template,
233
+ * grouping tasks into batches of n_tasks. The seq parameter represents
234
+ * the batch index (0-based).
235
+ *
236
+ * @param config - Git branching configuration
237
+ * @param params - Parameters for template expansion (must include seq for batch index)
238
+ * @returns BranchResult indicating success or failure
239
+ */
240
+ export function ensureBranchPerNTasks(config, params) {
241
+ if (config.mode !== 'per_n_tasks') {
242
+ return {
243
+ ok: false,
244
+ branchName: '',
245
+ error: `Branching mode is not 'per_n_tasks' (got '${config.mode}')`,
246
+ existed: false,
247
+ };
248
+ }
249
+ if (!config.n_tasks || config.n_tasks < 1) {
250
+ return {
251
+ ok: false,
252
+ branchName: '',
253
+ error: `per_n_tasks mode requires n_tasks >= 1 (got ${config.n_tasks})`,
254
+ existed: false,
255
+ };
256
+ }
257
+ if (params.seq === undefined && params.batch_index === undefined) {
258
+ return {
259
+ ok: false,
260
+ branchName: '',
261
+ error: 'per_n_tasks mode requires seq or batch_index parameter',
262
+ existed: false,
263
+ };
264
+ }
265
+ // Use seq if available, otherwise batch_index
266
+ const batchIndex = params.seq !== undefined ? params.seq : (params.batch_index || 0);
267
+ const templateParams = { ...params, seq: batchIndex, batch_index: batchIndex };
268
+ const template = config.name_template || 'envoi/batch-{{seq}}';
269
+ const baseName = expandBranchTemplate(template, templateParams);
270
+ const sanitizedName = sanitizeBranchName(baseName);
271
+ if (!sanitizedName) {
272
+ return {
273
+ ok: false,
274
+ branchName: '',
275
+ error: 'Branch name template expanded to empty string',
276
+ existed: false,
277
+ };
278
+ }
279
+ // Find available branch name (handles collisions)
280
+ const branchName = findAvailableBranchName(sanitizedName);
281
+ const baseRef = config.base_ref || 'HEAD';
282
+ return createOrSwitchBranch(branchName, baseRef);
283
+ }
284
+ /**
285
+ * Ensures a branch exists and HEAD is on it (per_milestone mode).
286
+ *
287
+ * For per_milestone mode, creates/switches to a branch based on the template
288
+ * for the current milestone. All tasks in the same milestone use the same branch.
289
+ *
290
+ * @param config - Git branching configuration
291
+ * @param params - Parameters for template expansion (must include milestone_id)
292
+ * @returns BranchResult indicating success or failure
293
+ */
294
+ export function ensureBranchPerMilestone(config, params) {
295
+ if (config.mode !== 'per_milestone') {
296
+ return {
297
+ ok: false,
298
+ branchName: '',
299
+ error: `Branching mode is not 'per_milestone' (got '${config.mode}')`,
300
+ existed: false,
301
+ };
302
+ }
303
+ if (!params.milestone_id) {
304
+ return {
305
+ ok: false,
306
+ branchName: '',
307
+ error: 'per_milestone mode requires milestone_id parameter',
308
+ existed: false,
309
+ };
310
+ }
311
+ const template = config.name_template || 'envoi/{{milestone_id}}';
312
+ const baseName = expandBranchTemplate(template, params);
313
+ const sanitizedName = sanitizeBranchName(baseName);
314
+ if (!sanitizedName) {
315
+ return {
316
+ ok: false,
317
+ branchName: '',
318
+ error: 'Branch name template expanded to empty string',
319
+ existed: false,
320
+ };
321
+ }
322
+ // Find available branch name (handles collisions)
323
+ const branchName = findAvailableBranchName(sanitizedName);
324
+ const baseRef = config.base_ref || 'HEAD';
325
+ return createOrSwitchBranch(branchName, baseRef);
326
+ }
327
+ //# sourceMappingURL=git_branching.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git_branching.js","sourceRoot":"","sources":["../../src/lib/git_branching.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Utilities for managing .gitignore entries for Envoi runner-owned files.
3
+ *
4
+ * Runner-owned files (STATE.json, REPORT.json, etc.) change every tick and
5
+ * should be gitignored to prevent BLOCKED_DIRTY_WORKTREE on subsequent runs.
6
+ */
7
+ /**
8
+ * Marker comment to identify Envoi-managed section in .gitignore.
9
+ */
10
+ export declare const ENVOI_GITIGNORE_MARKER = "# Envoi runner-owned (auto-generated)";
11
+ /**
12
+ * Default entries to add to .gitignore for Envoi runner-owned files.
13
+ */
14
+ export declare function getEnvoiGitignoreEntries(workspaceDir: string): string[];
15
+ export declare const ENVOI_GITIGNORE_ENTRIES: string[];
16
+ export declare function addEnvoiIgnores(repoRoot: string, entries?: string[]): Promise<{
17
+ added: string[];
18
+ alreadyPresent: string[];
19
+ created: boolean;
20
+ }>;
21
+ export declare function checkEnvoiIgnores(repoRoot: string): Promise<{
22
+ complete: boolean;
23
+ missing: string[];
24
+ present: string[];
25
+ }>;
26
+ //# sourceMappingURL=gitignore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gitignore.d.ts","sourceRoot":"","sources":["../../src/lib/gitignore.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH;;GAEG;AACH,eAAO,MAAM,sBAAsB,0CAA0C,CAAC;AAG9E;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CAevE;AAED,eAAO,MAAM,uBAAuB,UAA+C,CAAC;AAWpF,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,MAAM,EAA4B,GAC1C,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,cAAc,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CA2D1E;AAED,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAmCtE"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Utilities for managing .gitignore entries for Envoi runner-owned files.
3
+ *
4
+ * Runner-owned files (STATE.json, REPORT.json, etc.) change every tick and
5
+ * should be gitignored to prevent BLOCKED_DIRTY_WORKTREE on subsequent runs.
6
+ */
7
+ import { readFile, writeFile, access } from 'node:fs/promises';
8
+ import { join } from 'node:path';
9
+ import { WORKSPACE_DIR_NAME } from './branding.js';
10
+ /**
11
+ * Marker comment to identify Envoi-managed section in .gitignore.
12
+ */
13
+ export const ENVOI_GITIGNORE_MARKER = '# Envoi runner-owned (auto-generated)';
14
+ const MIGRATION_GITIGNORE_MARKER = '# Relais runner-owned (auto-generated)';
15
+ /**
16
+ * Default entries to add to .gitignore for Envoi runner-owned files.
17
+ */
18
+ export function getEnvoiGitignoreEntries(workspaceDir) {
19
+ const ws = workspaceDir.replace(/\/+$/, '');
20
+ return [
21
+ `${ws}/REPORT.json`,
22
+ `${ws}/REPORT.md`,
23
+ `${ws}/STATE.json`,
24
+ `${ws}/TASK.json`,
25
+ `${ws}/BLOCKED.json`,
26
+ `${ws}/lock.json`,
27
+ `${ws}/history/`,
28
+ `${ws}/*.tmp`,
29
+ `${ws}/PRD.md`,
30
+ `${ws}/FACTS.md`,
31
+ `${ws}/BUILDER_RESULT.json`,
32
+ ];
33
+ }
34
+ export const ENVOI_GITIGNORE_ENTRIES = getEnvoiGitignoreEntries(WORKSPACE_DIR_NAME);
35
+ async function fileExists(filePath) {
36
+ try {
37
+ await access(filePath);
38
+ return true;
39
+ }
40
+ catch {
41
+ return false;
42
+ }
43
+ }
44
+ export async function addEnvoiIgnores(repoRoot, entries = ENVOI_GITIGNORE_ENTRIES) {
45
+ const gitignorePath = join(repoRoot, '.gitignore');
46
+ let existingContent = '';
47
+ let created = false;
48
+ if (await fileExists(gitignorePath)) {
49
+ existingContent = await readFile(gitignorePath, 'utf-8');
50
+ }
51
+ else {
52
+ created = true;
53
+ }
54
+ const existingLines = new Set(existingContent
55
+ .split('\n')
56
+ .map((line) => line.trim())
57
+ .filter((line) => line.length > 0));
58
+ const hasMarker = existingContent.includes(ENVOI_GITIGNORE_MARKER) ||
59
+ existingContent.includes(MIGRATION_GITIGNORE_MARKER);
60
+ const added = [];
61
+ const alreadyPresent = [];
62
+ for (const entry of entries) {
63
+ if (existingLines.has(entry)) {
64
+ alreadyPresent.push(entry);
65
+ }
66
+ else {
67
+ added.push(entry);
68
+ }
69
+ }
70
+ if (added.length === 0 && hasMarker) {
71
+ return { added: [], alreadyPresent, created: false };
72
+ }
73
+ let newContent = existingContent;
74
+ if (newContent.length > 0 && !newContent.endsWith('\n')) {
75
+ newContent += '\n';
76
+ }
77
+ if (newContent.length > 0 && !hasMarker) {
78
+ newContent += '\n';
79
+ }
80
+ if (!hasMarker) {
81
+ newContent += ENVOI_GITIGNORE_MARKER + '\n';
82
+ }
83
+ for (const entry of added) {
84
+ newContent += entry + '\n';
85
+ }
86
+ await writeFile(gitignorePath, newContent, 'utf-8');
87
+ return { added, alreadyPresent, created };
88
+ }
89
+ export async function checkEnvoiIgnores(repoRoot) {
90
+ const gitignorePath = join(repoRoot, '.gitignore');
91
+ if (!(await fileExists(gitignorePath))) {
92
+ return {
93
+ complete: false,
94
+ missing: [...ENVOI_GITIGNORE_ENTRIES],
95
+ present: [],
96
+ };
97
+ }
98
+ const content = await readFile(gitignorePath, 'utf-8');
99
+ const existingLines = new Set(content
100
+ .split('\n')
101
+ .map((line) => line.trim())
102
+ .filter((line) => line.length > 0));
103
+ const missing = [];
104
+ const present = [];
105
+ for (const entry of ENVOI_GITIGNORE_ENTRIES) {
106
+ if (existingLines.has(entry)) {
107
+ present.push(entry);
108
+ }
109
+ else {
110
+ missing.push(entry);
111
+ }
112
+ }
113
+ return {
114
+ complete: missing.length === 0,
115
+ missing,
116
+ present,
117
+ };
118
+ }
119
+ //# sourceMappingURL=gitignore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gitignore.js","sourceRoot":"","sources":["../../src/lib/gitignore.ts"],"names":[],"mappings":"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"}