@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 @@
1
+ {"version":3,"file":"workspace_state.d.ts","sourceRoot":"","sources":["../../src/types/workspace_state.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,kBAAkB,EAAE,MAAM,CAAC;IAC3B,yDAAyD;IACzD,aAAa,EAAE,MAAM,CAAC;IACtB,uDAAuD;IACvD,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;AAEjD;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;AAE/D;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,SAAS,GAAG,WAAW,GAAG,UAAU,GAAG,MAAM,CAAC;AAE/E;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,oDAAoD;IACpD,EAAE,EAAE,MAAM,CAAC;IACX,yBAAyB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,YAAY,EAAE,MAAM,CAAC;IACrB,uCAAuC;IACvC,MAAM,EAAE,aAAa,GAAG,KAAK,GAAG,KAAK,CAAC;IACtC,8BAA8B;IAC9B,MAAM,EAAE,UAAU,CAAC;IACnB,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,mCAAmC;IACnC,gBAAgB,CAAC,EAAE,mBAAmB,CAAC;IACvC,oDAAoD;IACpD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iCAAiC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,4BAA4B;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,yBAAyB;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,uBAAuB;IACvB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,wBAAwB;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,wBAAwB;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oCAAoC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc;IAC7B,gEAAgE;IAChE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5B,2DAA2D;IAC3D,OAAO,EAAE,YAAY,CAAC;IAEtB;;;;OAIG;IACH,cAAc,EAAE,OAAO,CAAC;IAExB,+DAA+D;IAC/D,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAE3B,yDAAyD;IACzD,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5B,6CAA6C;IAC7C,UAAU,CAAC,EAAE,cAAc,EAAE,CAAC;IAE9B,oDAAoD;IACpD,eAAe,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAExC,gEAAgE;IAChE,sBAAsB,CAAC,EAAE,eAAe,EAAE,CAAC;CAC5C"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * TypeScript interfaces for workspace state persistence.
3
+ *
4
+ * WorkspaceState tracks milestone progress and budget consumption
5
+ * across restarts, enabling budget enforcement and crash recovery.
6
+ *
7
+ * @see docs/NEW-PLAN.md lines 32-45
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=workspace_state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace_state.js","sourceRoot":"","sources":["../../src/types/workspace_state.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -0,0 +1,191 @@
1
+ {
2
+ "version": "1.0",
3
+ "product_name": "envoi",
4
+ "workspace_dir": "envoi",
5
+ "runner": {
6
+ "require_git": true,
7
+ "max_tick_seconds": 900,
8
+ "default_loop_mode": "task",
9
+ "lockfile": "envoi/lock.json",
10
+ "runner_owned_globs": [
11
+ "envoi/STATE.json",
12
+ "envoi/TASK.json",
13
+ "envoi/REPORT.json",
14
+ "envoi/REPORT.md",
15
+ "envoi/BLOCKED.json",
16
+ "envoi/FACTS.md",
17
+ "envoi/PRD.md",
18
+ "envoi/history/**",
19
+ "envoi/lock.json",
20
+ "envoi/schemas/**",
21
+ "envoi/prompts/**"
22
+ ],
23
+ "crash_cleanup": {
24
+ "delete_tmp_glob": "envoi/*.tmp",
25
+ "validate_runner_json_files": true
26
+ },
27
+ "render_report_md": {
28
+ "enabled": true,
29
+ "max_chars": 6000
30
+ },
31
+ "autonomy": {
32
+ "profile": "balanced",
33
+ "command_trust": [],
34
+ "fs_policy": "workspace_write",
35
+ "network_policy": "deny"
36
+ }
37
+ },
38
+ "claude_code_cli": {
39
+ "command": "claude",
40
+ "output_format": "json",
41
+ "no_session_persistence": true
42
+ },
43
+ "models": {
44
+ "orchestrator_model": "opus",
45
+ "orchestrator_fallback_model": "sonnet",
46
+ "builder_model": "sonnet",
47
+ "builder_fallback_model": "haiku"
48
+ },
49
+ "orchestrator": {
50
+ "max_turns": 3,
51
+ "permission_mode": "plan",
52
+ "allowed_tools": "",
53
+ "system_prompt_file": "envoi/prompts/orchestrator.system.txt",
54
+ "user_prompt_file": "envoi/prompts/orchestrator.user.txt",
55
+ "task_schema_file": "envoi/schemas/task.schema.json",
56
+ "max_parse_retries_per_tick": 1,
57
+ "max_budget_usd": 0.4
58
+ },
59
+ "builder": {
60
+ "default_mode": "cursor",
61
+ "allow_patch_mode": true,
62
+ "claude_code": {
63
+ "max_turns": 8,
64
+ "permission_mode": "bypassPermissions",
65
+ "allowed_tools": "Read,Edit,Glob,Grep,Bash",
66
+ "system_prompt_file": "envoi/prompts/builder.system.txt",
67
+ "user_prompt_file": "envoi/prompts/builder.user.txt",
68
+ "builder_result_schema_file": "envoi/schemas/builder_result.schema.json",
69
+ "max_budget_usd": 1.5,
70
+ "strict_builder_json": false
71
+ },
72
+ "patch": {
73
+ "max_patch_attempts_per_milestone": 10
74
+ },
75
+ "cursor": {
76
+ "driver_kind": "cursor_agent",
77
+ "command": "cursor",
78
+ "args": [
79
+ "agent",
80
+ "--print",
81
+ "--output-format",
82
+ "text",
83
+ "--workspace",
84
+ ".",
85
+ "--force"
86
+ ],
87
+ "timeout_seconds": 300,
88
+ "output_file": "BUILDER_RESULT.json"
89
+ }
90
+ },
91
+ "scope": {
92
+ "default_allowed_globs": [
93
+ "src/**",
94
+ "app/**",
95
+ "packages/**",
96
+ "tests/**",
97
+ "README.md"
98
+ ],
99
+ "default_forbidden_globs": [
100
+ ".git/**",
101
+ "envoi/**",
102
+ "**/.env*",
103
+ "**/*secret*",
104
+ "**/*token*",
105
+ "**/node_modules/**"
106
+ ],
107
+ "default_allow_new_files": false,
108
+ "default_allow_lockfile_changes": false,
109
+ "lockfiles": [
110
+ "pnpm-lock.yaml",
111
+ "package-lock.json",
112
+ "yarn.lock",
113
+ "bun.lockb"
114
+ ]
115
+ },
116
+ "diff_limits": {
117
+ "default_max_files_touched": 12,
118
+ "default_max_lines_changed": 400
119
+ },
120
+ "verification": {
121
+ "execution_mode": "argv_no_shell",
122
+ "max_param_len": 128,
123
+ "reject_whitespace_in_params": true,
124
+ "reject_dotdot": true,
125
+ "reject_metachars_regex": "[;&|$\\\\><(){}\\[\\]`\\n\\r\\t\\0]",
126
+ "timeout_fast_seconds": 90,
127
+ "timeout_slow_seconds": 600,
128
+ "templates": [
129
+ {
130
+ "id": "lint",
131
+ "cmd": "pnpm",
132
+ "args": [
133
+ "lint"
134
+ ]
135
+ },
136
+ {
137
+ "id": "typecheck",
138
+ "cmd": "pnpm",
139
+ "args": [
140
+ "typecheck"
141
+ ]
142
+ },
143
+ {
144
+ "id": "test",
145
+ "cmd": "pnpm",
146
+ "args": [
147
+ "test"
148
+ ]
149
+ },
150
+ {
151
+ "id": "test_filter",
152
+ "cmd": "pnpm",
153
+ "args": [
154
+ "test",
155
+ "--filter",
156
+ "{{pkg}}"
157
+ ],
158
+ "params": {
159
+ "pkg": {
160
+ "kind": "string_token"
161
+ }
162
+ }
163
+ }
164
+ ]
165
+ },
166
+ "budgets": {
167
+ "per_milestone": {
168
+ "max_ticks": 200,
169
+ "max_orchestrator_calls": 260,
170
+ "max_builder_calls": 200,
171
+ "max_verify_runs": 600,
172
+ "max_estimated_cost_usd": 80
173
+ },
174
+ "warn_at_fraction": 0.8
175
+ },
176
+ "history": {
177
+ "enabled": true,
178
+ "dir": "history",
179
+ "max_mb": 500,
180
+ "include_diff_patch": true,
181
+ "include_verify_log": true
182
+ },
183
+ "git": {
184
+ "branching": {
185
+ "mode": "off",
186
+ "name_template": "envoi/{{task_id}}",
187
+ "base_ref": "HEAD",
188
+ "n_tasks": 5
189
+ }
190
+ }
191
+ }
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@ttfw/envoi",
3
+ "version": "1.0.0",
4
+ "description": "Deterministic orchestration runner for AI workflows: planner -> builder -> checker",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "envoi": "dist/index.js",
9
+ "relais": "dist/index.js"
10
+ },
11
+ "files": [
12
+ "dist/**",
13
+ "relais/prompts/**",
14
+ "relais/schemas/**",
15
+ "envoi.config.json",
16
+ "README.md"
17
+ ],
18
+ "publishConfig": {
19
+ "access": "public"
20
+ },
21
+ "scripts": {
22
+ "build": "tsc",
23
+ "pack:check": "node scripts/pack-check.mjs",
24
+ "prepack": "npm run -s build && node scripts/pack-check.mjs",
25
+ "dev": "tsx src/index.ts",
26
+ "start": "node dist/index.js",
27
+ "test": "pnpm -s build && vitest",
28
+ "typecheck": "tsc --noEmit"
29
+ },
30
+ "keywords": [
31
+ "claude",
32
+ "orchestration",
33
+ "ai",
34
+ "automation"
35
+ ],
36
+ "author": "",
37
+ "license": "ISC",
38
+ "packageManager": "pnpm@10.24.0",
39
+ "dependencies": {
40
+ "ajv": "^8.17.1",
41
+ "commander": "^14.0.2",
42
+ "micromatch": "^4.0.8"
43
+ },
44
+ "devDependencies": {
45
+ "@types/micromatch": "^4.0.9",
46
+ "@types/node": "^25.0.10",
47
+ "@vitest/coverage-v8": "^4.0.18",
48
+ "tsx": "^4.21.0",
49
+ "typescript": "^5.9.3",
50
+ "vitest": "^4.0.18"
51
+ }
52
+ }
File without changes
@@ -0,0 +1,13 @@
1
+ You are Envoi's builder.
2
+
3
+ Execute TASK safely and minimally.
4
+
5
+ Rules:
6
+ - Output exactly one JSON object matching `builder_result.schema.json`.
7
+ - No markdown, no code fences, no extra text.
8
+ - Obey TASK scope: only allowed_globs, never forbidden_globs.
9
+ - Do not touch runner-owned files, `.git/**`, secrets, or `node_modules`.
10
+ - Keep diff focused; no drive-by refactors or formatting.
11
+ - Do not change lockfiles unless `allow_lockfile_changes=true`.
12
+ - Do not create files unless `allow_new_files=true`.
13
+ - If blocked, return builder_result with clear notes and stop.
@@ -0,0 +1,15 @@
1
+ Execute this task.
2
+
3
+ Return ONLY one `builder_result` JSON object matching `builder_result.schema.json`.
4
+
5
+ TASK_JSON:
6
+ {{TASK_JSON}}
7
+
8
+ Constraints:
9
+ - allowed_globs={{ALLOWED_GLOBS}}
10
+ - forbidden_globs={{FORBIDDEN_GLOBS}}
11
+ - allow_new_files={{ALLOW_NEW_FILES}}
12
+ - allow_lockfile_changes={{ALLOW_LOCKFILE_CHANGES}}
13
+ - diff_limits=files<= {{MAX_FILES_TOUCHED}}, lines<= {{MAX_LINES_CHANGED}}
14
+ - If `task_kind` is `verify_only` or `question`, do not modify files.
15
+ - Do not invent verification results; runner executes verification separately.
@@ -0,0 +1,37 @@
1
+ You are Envoi's orchestrator.
2
+
3
+ Return exactly ONE task JSON object. Nothing else.
4
+
5
+ Core rules:
6
+ - Output must be valid JSON matching `task.schema.json`.
7
+ - No markdown, no code fences, no commentary.
8
+ - Propose the smallest safe next step.
9
+ - Respect budgets, scope constraints, and builder capabilities in the user prompt.
10
+ - Never touch runner-owned files or forbidden paths.
11
+ - If a safe task is not possible, emit `task_kind="question"` with a clear product-level prompt.
12
+
13
+ Task policy:
14
+ - `execute`: code edits expected.
15
+ - `verify_only` / `question`: zero-diff tasks.
16
+ - Use minimal `allowed_globs`; keep `forbidden_globs` strict.
17
+ - Keep `allow_new_files=false` and `allow_lockfile_changes=false` unless required.
18
+ - Use conservative `diff_limits`.
19
+ - Use only provided verification template IDs.
20
+
21
+ Builder policy:
22
+ - Prefer `mode="cursor"` only when cursor is configured.
23
+ - Otherwise use `mode="claude_code"`.
24
+ - Keep `max_turns` tight (typically 4-8).
25
+ - `instructions` must be concrete and implementation-ready.
26
+
27
+ PM policy for idea intake:
28
+ - Integrate pending ideas into roadmap decisions.
29
+ - Do not push technical choices to the user.
30
+ - Ask only high-impact product clarifications (timeline, urgency, testability).
31
+ - Include `planning_decision` when ideas are considered:
32
+ - `decision`: `schedule_now` | `schedule_next` | `defer`
33
+ - concise rationale and milestone hint when useful.
34
+
35
+ Anti-loop policy:
36
+ - Avoid re-dispatching the same failed task fingerprint.
37
+ - If you need to retry, change intent/scope/verification so fingerprint differs.
@@ -0,0 +1,34 @@
1
+ You are orchestrating the next tick for Envoi.
2
+
3
+ Return EXACTLY one JSON object matching `task.schema.json`. Nothing else.
4
+
5
+ CONTEXT
6
+ - project_goal: {{PROJECT_GOAL}}
7
+ - milestone_id: {{MILESTONE_ID}}
8
+ - budget_status: {{BUDGETS_SUMMARY}}
9
+ - verify_template_ids: {{VERIFY_TEMPLATE_IDS}}
10
+ - repo_summary: {{REPO_SUMMARY}}
11
+ - facts_md: {{FACTS_MD}}
12
+ - prd_md: {{PRD_MD}}
13
+ - last_report_md: {{LAST_REPORT_MD}}
14
+ - pending_ideas_json: {{PENDING_IDEAS_JSON}}
15
+ - planning_digest_json: {{PLANNING_DIGEST_JSON}}
16
+ - open_product_questions_json: {{OPEN_PRODUCT_QUESTIONS_JSON}}
17
+ - blocked_json_or_empty: {{BLOCKED_JSON_OR_EMPTY}}
18
+ - builder_default_mode: {{BUILDER_DEFAULT_MODE}}
19
+ - builder_cursor_configured: {{BUILDER_CURSOR_CONFIGURED}}
20
+
21
+ NON-NEGOTIABLE
22
+ - One tick only.
23
+ - Scope is enforced from git reality.
24
+ - `verify_only` and `question` must produce zero diff.
25
+ - Treat pending ideas like a PM: schedule now/next/defer, avoid technical burdens on user.
26
+
27
+ OUTPUT POLICY
28
+ - If workspace is fresh (`milestone_id="none"` or PRD changed), first return `task_kind="question"` with:
29
+ - 3-7 proposed milestones
30
+ - up to 5 product clarifying questions
31
+ - `control: { "action": "stop" }`
32
+ - For `question` tasks, still fill required fields (`scope`, `diff_limits`, `verification`).
33
+ - Otherwise return the smallest safe `execute` task.
34
+ - If ideas are considered, include `planning_decision` with idea IDs, decision, rationale, optional milestone.
@@ -0,0 +1,33 @@
1
+ You are the Reviewer (Eyes) for Envoi.
2
+
3
+ Your job: review builder output and decide whether to proceed, request a patch, or ask a clarifying question.
4
+
5
+ Hard rules:
6
+
7
+ - Output MUST be a single JSON object matching reviewer_result.schema.json and NOTHING ELSE.
8
+
9
+ - No markdown. No code fences. No commentary.
10
+
11
+ - You are READ-ONLY. You cannot modify files or execute commands.
12
+
13
+ - Safety first: block anything that violates scope, introduces security risks, or breaks critical functionality.
14
+
15
+ Decision meanings:
16
+
17
+ - proceed: The changes are safe and acceptable. The orchestrator will merge.
18
+
19
+ - force_patch: The changes need correction before proceeding. Provide patch_hint with specific guidance. The orchestrator will re-dispatch with your patch_hint.
20
+
21
+ - ask_question: You need clarification from the human. Provide question object with prompt and optional choices. The orchestrator will pause and wait for human response.
22
+
23
+ Review criteria:
24
+
25
+ - Scope compliance: Are all touched files within allowed_globs? Any forbidden paths touched?
26
+
27
+ - Risk assessment: Are there security, performance, or correctness concerns?
28
+
29
+ - Verification results: Did verifications pass? Are there suspicious failures?
30
+
31
+ - Diff quality: Is the diff minimal and focused? Any unnecessary changes?
32
+
33
+ - Task completion: Does the output match the task intent?
@@ -0,0 +1,35 @@
1
+ Review this builder output and decide: proceed, force_patch, or ask_question.
2
+
3
+ Return ONLY reviewer_result JSON matching reviewer_result.schema.json. Nothing else.
4
+
5
+ === RISK FLAGS ===
6
+
7
+ {{RISK_FLAGS}}
8
+
9
+ === TASK ===
10
+
11
+ {{TASK_JSON}}
12
+
13
+ === LAST REPORT ===
14
+
15
+ {{LAST_REPORT_MD}}
16
+
17
+ === DIFF PATCH ===
18
+
19
+ {{DIFF_PATCH_OR_EMPTY}}
20
+
21
+ === VERIFY LOG EXCERPT ===
22
+
23
+ {{VERIFY_LOG_EXCERPT_OR_EMPTY}}
24
+
25
+ === TOUCHED PATHS ===
26
+
27
+ {{TOUCHED_PATHS}}
28
+
29
+ === YOUR DECISION ===
30
+
31
+ Review the above and output your decision:
32
+
33
+ - proceed: Changes are safe and acceptable
34
+ - force_patch: Changes need correction (provide patch_hint)
35
+ - ask_question: Need human clarification (provide question object)
File without changes
@@ -0,0 +1,29 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://envoi.local/schemas/builder_result.schema.json",
4
+ "title": "Envoi Builder Result",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["summary", "files_intended", "commands_ran", "notes"],
8
+ "properties": {
9
+ "summary": { "type": "string", "minLength": 1, "maxLength": 800 },
10
+ "files_intended": {
11
+ "type": "array",
12
+ "items": { "type": "string", "minLength": 1, "maxLength": 300 },
13
+ "minItems": 0,
14
+ "maxItems": 200
15
+ },
16
+ "commands_ran": {
17
+ "type": "array",
18
+ "items": { "type": "string", "minLength": 1, "maxLength": 300 },
19
+ "minItems": 0,
20
+ "maxItems": 50
21
+ },
22
+ "notes": {
23
+ "type": "array",
24
+ "items": { "type": "string", "minLength": 1, "maxLength": 300 },
25
+ "minItems": 0,
26
+ "maxItems": 20
27
+ }
28
+ }
29
+ }
@@ -0,0 +1,195 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://envoi.local/schemas/report.schema.json",
4
+ "title": "Envoi Report",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": [
8
+ "run_id",
9
+ "started_at",
10
+ "ended_at",
11
+ "duration_ms",
12
+ "base_commit",
13
+ "head_commit",
14
+ "task",
15
+ "verdict",
16
+ "code",
17
+ "blast_radius",
18
+ "scope",
19
+ "diff",
20
+ "verification",
21
+ "budgets"
22
+ ],
23
+ "properties": {
24
+ "run_id": { "type": "string", "minLength": 8, "maxLength": 80 },
25
+ "started_at": { "type": "string", "format": "date-time" },
26
+ "ended_at": { "type": "string", "format": "date-time" },
27
+ "duration_ms": { "type": "integer", "minimum": 0 },
28
+ "base_commit": { "type": "string", "minLength": 7, "maxLength": 64 },
29
+ "head_commit": { "type": "string", "minLength": 7, "maxLength": 64 },
30
+ "task": {
31
+ "type": "object",
32
+ "additionalProperties": false,
33
+ "required": ["task_id", "milestone_id", "task_kind", "intent"],
34
+ "properties": {
35
+ "task_id": { "type": "string" },
36
+ "milestone_id": { "type": "string" },
37
+ "task_kind": { "type": "string", "enum": ["execute", "verify_only", "question"] },
38
+ "intent": { "type": "string" }
39
+ }
40
+ },
41
+ "verdict": { "type": "string", "enum": ["success", "stop", "blocked"] },
42
+ "code": {
43
+ "type": "string",
44
+ "enum": [
45
+ "SUCCESS",
46
+ "STOP_SCOPE_VIOLATION_FORBIDDEN",
47
+ "STOP_SCOPE_VIOLATION_OUTSIDE_ALLOWED",
48
+ "STOP_SCOPE_VIOLATION_NEW_FILE",
49
+ "STOP_LOCKFILE_CHANGE_FORBIDDEN",
50
+ "STOP_DIFF_TOO_LARGE",
51
+ "STOP_VERIFY_FAILED_FAST",
52
+ "STOP_VERIFY_FAILED_SLOW",
53
+ "STOP_VERIFY_TAINTED",
54
+ "STOP_VERIFY_ONLY_SIDE_EFFECTS",
55
+ "STOP_QUESTION_SIDE_EFFECTS",
56
+ "STOP_RUNNER_OWNED_MUTATION",
57
+ "STOP_BUILDER_JSON_PARSE",
58
+ "STOP_BUILDER_SCHEMA_INVALID",
59
+ "STOP_BUILDER_SHAPE_INVALID",
60
+ "STOP_BUILDER_CLI_ERROR",
61
+ "STOP_BUILDER_TIMEOUT",
62
+ "STOP_HEAD_MOVED",
63
+ "STOP_INTERRUPTED",
64
+ "STOP_REVIEWER_FORCED_PATCH",
65
+ "STOP_REVIEWER_ASK_QUESTION",
66
+ "STOP_ORCHESTRATOR_ASK_QUESTION",
67
+ "STOP_REDISPATCH_IDENTICAL_TASK",
68
+ "STOP_VERIFY_FLAKY_OR_TIMEOUT",
69
+ "STOP_ORCHESTRATOR_TIMEOUT",
70
+ "STOP_MERGE_DIRTY_WORKTREE",
71
+ "STOP_BRANCH_MISMATCH",
72
+ "STOP_EVIDENCE_INCOMPLETE",
73
+ "BLOCKED_BUDGET_EXHAUSTED",
74
+ "BLOCKED_DIRTY_WORKTREE",
75
+ "BLOCKED_LOCK_HELD",
76
+ "BLOCKED_CRASH_RECOVERY_REQUIRED",
77
+ "BLOCKED_ORCHESTRATOR_OUTPUT_INVALID",
78
+ "BLOCKED_HISTORY_CAP_CLEANUP_REQUIRED",
79
+ "BLOCKED_MISSING_CONFIG",
80
+ "BLOCKED_BUDGET_CAP",
81
+ "BLOCKED_TRANSPORT_STALLED",
82
+ "BLOCKED_ROLLBACK_FAILED",
83
+ "BLOCKED_ROLLBACK_DIRTY",
84
+ "BLOCKED_BUILDER_COMMAND_NOT_FOUND",
85
+ "BLOCKED_BRANCH_FAILED"
86
+ ]
87
+ },
88
+ "blast_radius": {
89
+ "type": "object",
90
+ "additionalProperties": false,
91
+ "required": ["files_touched", "lines_added", "lines_deleted", "new_files"],
92
+ "properties": {
93
+ "files_touched": { "type": "integer", "minimum": 0 },
94
+ "lines_added": { "type": "integer", "minimum": 0 },
95
+ "lines_deleted": { "type": "integer", "minimum": 0 },
96
+ "new_files": { "type": "integer", "minimum": 0 }
97
+ }
98
+ },
99
+ "scope": {
100
+ "type": "object",
101
+ "additionalProperties": false,
102
+ "required": ["ok", "violations", "touched_paths"],
103
+ "properties": {
104
+ "ok": { "type": "boolean" },
105
+ "violations": {
106
+ "type": "array",
107
+ "items": { "type": "string", "minLength": 1, "maxLength": 200 },
108
+ "minItems": 0,
109
+ "maxItems": 200
110
+ },
111
+ "touched_paths": {
112
+ "type": "array",
113
+ "items": { "type": "string", "minLength": 1, "maxLength": 400 },
114
+ "minItems": 0,
115
+ "maxItems": 500
116
+ }
117
+ }
118
+ },
119
+ "diff": {
120
+ "type": "object",
121
+ "additionalProperties": false,
122
+ "required": ["files_changed", "lines_changed", "diff_patch_path"],
123
+ "properties": {
124
+ "files_changed": { "type": "integer", "minimum": 0 },
125
+ "lines_changed": { "type": "integer", "minimum": 0 },
126
+ "diff_patch_path": { "type": "string", "minLength": 1, "maxLength": 300 }
127
+ }
128
+ },
129
+ "verification": {
130
+ "type": "object",
131
+ "additionalProperties": false,
132
+ "required": ["exec_mode", "runs", "verify_log_path"],
133
+ "properties": {
134
+ "exec_mode": { "type": "string", "enum": ["argv_no_shell"] },
135
+ "runs": {
136
+ "type": "array",
137
+ "items": {
138
+ "type": "object",
139
+ "additionalProperties": false,
140
+ "required": ["template_id", "phase", "cmd", "args", "exit_code", "duration_ms", "timed_out"],
141
+ "properties": {
142
+ "template_id": { "type": "string", "minLength": 1, "maxLength": 64 },
143
+ "phase": { "type": "string", "enum": ["fast", "slow"] },
144
+ "cmd": { "type": "string", "minLength": 1, "maxLength": 120 },
145
+ "args": {
146
+ "type": "array",
147
+ "items": { "type": "string", "maxLength": 200 },
148
+ "minItems": 0,
149
+ "maxItems": 40
150
+ },
151
+ "exit_code": { "type": "integer", "minimum": -1, "maximum": 255 },
152
+ "duration_ms": { "type": "integer", "minimum": 0 },
153
+ "timed_out": { "type": "boolean" }
154
+ }
155
+ },
156
+ "minItems": 0,
157
+ "maxItems": 40
158
+ },
159
+ "verify_log_path": { "type": "string", "minLength": 1, "maxLength": 300 }
160
+ }
161
+ },
162
+ "budgets": {
163
+ "type": "object",
164
+ "additionalProperties": false,
165
+ "required": ["milestone_id", "ticks", "orchestrator_calls", "builder_calls", "verify_runs", "estimated_cost_usd", "warnings"],
166
+ "properties": {
167
+ "milestone_id": { "type": "string" },
168
+ "ticks": { "type": "integer", "minimum": 0 },
169
+ "orchestrator_calls": { "type": "integer", "minimum": 0 },
170
+ "builder_calls": { "type": "integer", "minimum": 0 },
171
+ "verify_runs": { "type": "integer", "minimum": 0 },
172
+ "estimated_cost_usd": { "type": "number", "minimum": 0 },
173
+ "warnings": {
174
+ "type": "array",
175
+ "items": { "type": "string", "minLength": 1, "maxLength": 200 },
176
+ "minItems": 0,
177
+ "maxItems": 20
178
+ }
179
+ }
180
+ },
181
+ "pointers": {
182
+ "type": "object",
183
+ "additionalProperties": false,
184
+ "properties": {
185
+ "report_md_path": { "type": "string" },
186
+ "history_dir": { "type": "string" }
187
+ }
188
+ },
189
+ "reviewer_error": {
190
+ "type": "string",
191
+ "minLength": 1,
192
+ "maxLength": 1000
193
+ }
194
+ }
195
+ }