@cluesmith/codev 3.3.2 → 3.3.4

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 (257) hide show
  1. package/dashboard-dist/assets/{index-D3XaKpZW.js → index-DZf6pNPE.js} +41 -41
  2. package/dashboard-dist/assets/index-DZf6pNPE.js.map +1 -0
  3. package/dashboard-dist/assets/index-DnYLy5C_.css +32 -0
  4. package/dashboard-dist/index.html +2 -2
  5. package/dist/agent-farm/cli.d.ts.map +1 -1
  6. package/dist/agent-farm/cli.js +48 -0
  7. package/dist/agent-farm/cli.js.map +1 -1
  8. package/dist/agent-farm/commands/ide.d.ts +20 -0
  9. package/dist/agent-farm/commands/ide.d.ts.map +1 -0
  10. package/dist/agent-farm/commands/ide.js +138 -0
  11. package/dist/agent-farm/commands/ide.js.map +1 -0
  12. package/dist/agent-farm/commands/inbox.d.ts.map +1 -1
  13. package/dist/agent-farm/commands/inbox.js +79 -10
  14. package/dist/agent-farm/commands/inbox.js.map +1 -1
  15. package/dist/agent-farm/commands/interrupt.d.ts +4 -1
  16. package/dist/agent-farm/commands/interrupt.d.ts.map +1 -1
  17. package/dist/agent-farm/commands/interrupt.js +6 -3
  18. package/dist/agent-farm/commands/interrupt.js.map +1 -1
  19. package/dist/agent-farm/commands/reset.d.ts +4 -1
  20. package/dist/agent-farm/commands/reset.d.ts.map +1 -1
  21. package/dist/agent-farm/commands/reset.js +6 -3
  22. package/dist/agent-farm/commands/reset.js.map +1 -1
  23. package/dist/agent-farm/commands/send.d.ts +28 -0
  24. package/dist/agent-farm/commands/send.d.ts.map +1 -1
  25. package/dist/agent-farm/commands/send.js +79 -6
  26. package/dist/agent-farm/commands/send.js.map +1 -1
  27. package/dist/agent-farm/commands/spawn-worktree.d.ts.map +1 -1
  28. package/dist/agent-farm/commands/spawn-worktree.js +16 -7
  29. package/dist/agent-farm/commands/spawn-worktree.js.map +1 -1
  30. package/dist/agent-farm/commands/tower.d.ts +21 -9
  31. package/dist/agent-farm/commands/tower.d.ts.map +1 -1
  32. package/dist/agent-farm/commands/tower.js +90 -30
  33. package/dist/agent-farm/commands/tower.js.map +1 -1
  34. package/dist/agent-farm/db/index.d.ts +3 -1
  35. package/dist/agent-farm/db/index.d.ts.map +1 -1
  36. package/dist/agent-farm/db/index.js +8 -443
  37. package/dist/agent-farm/db/index.js.map +1 -1
  38. package/dist/agent-farm/db/mailbox.d.ts +47 -7
  39. package/dist/agent-farm/db/mailbox.d.ts.map +1 -1
  40. package/dist/agent-farm/db/mailbox.js +56 -12
  41. package/dist/agent-farm/db/mailbox.js.map +1 -1
  42. package/dist/agent-farm/db/migrations.d.ts +57 -0
  43. package/dist/agent-farm/db/migrations.d.ts.map +1 -0
  44. package/dist/agent-farm/db/migrations.js +530 -0
  45. package/dist/agent-farm/db/migrations.js.map +1 -0
  46. package/dist/agent-farm/db/schema.d.ts +1 -1
  47. package/dist/agent-farm/db/schema.d.ts.map +1 -1
  48. package/dist/agent-farm/db/schema.js +1 -0
  49. package/dist/agent-farm/db/schema.js.map +1 -1
  50. package/dist/agent-farm/db/tower-owner.d.ts +168 -0
  51. package/dist/agent-farm/db/tower-owner.d.ts.map +1 -0
  52. package/dist/agent-farm/db/tower-owner.js +369 -0
  53. package/dist/agent-farm/db/tower-owner.js.map +1 -0
  54. package/dist/agent-farm/db/types.d.ts +47 -0
  55. package/dist/agent-farm/db/types.d.ts.map +1 -1
  56. package/dist/agent-farm/db/types.js.map +1 -1
  57. package/dist/agent-farm/lib/ide-record.d.ts +65 -0
  58. package/dist/agent-farm/lib/ide-record.d.ts.map +1 -0
  59. package/dist/agent-farm/lib/ide-record.js +118 -0
  60. package/dist/agent-farm/lib/ide-record.js.map +1 -0
  61. package/dist/agent-farm/lib/tunnel-client.d.ts +22 -0
  62. package/dist/agent-farm/lib/tunnel-client.d.ts.map +1 -1
  63. package/dist/agent-farm/lib/tunnel-client.js +96 -19
  64. package/dist/agent-farm/lib/tunnel-client.js.map +1 -1
  65. package/dist/agent-farm/servers/cron-delivery.d.ts +7 -1
  66. package/dist/agent-farm/servers/cron-delivery.d.ts.map +1 -1
  67. package/dist/agent-farm/servers/cron-delivery.js +2 -1
  68. package/dist/agent-farm/servers/cron-delivery.js.map +1 -1
  69. package/dist/agent-farm/servers/gate-profiles.d.ts +44 -2
  70. package/dist/agent-farm/servers/gate-profiles.d.ts.map +1 -1
  71. package/dist/agent-farm/servers/gate-profiles.js +79 -6
  72. package/dist/agent-farm/servers/gate-profiles.js.map +1 -1
  73. package/dist/agent-farm/servers/ide-forward.d.ts +62 -0
  74. package/dist/agent-farm/servers/ide-forward.d.ts.map +1 -0
  75. package/dist/agent-farm/servers/ide-forward.js +274 -0
  76. package/dist/agent-farm/servers/ide-forward.js.map +1 -0
  77. package/dist/agent-farm/servers/ide-server.d.ts +68 -0
  78. package/dist/agent-farm/servers/ide-server.d.ts.map +1 -0
  79. package/dist/agent-farm/servers/ide-server.js +281 -0
  80. package/dist/agent-farm/servers/ide-server.js.map +1 -0
  81. package/dist/agent-farm/servers/mailbox-delivery.d.ts +296 -12
  82. package/dist/agent-farm/servers/mailbox-delivery.d.ts.map +1 -1
  83. package/dist/agent-farm/servers/mailbox-delivery.js +566 -69
  84. package/dist/agent-farm/servers/mailbox-delivery.js.map +1 -1
  85. package/dist/agent-farm/servers/mailbox-wiring.d.ts +66 -19
  86. package/dist/agent-farm/servers/mailbox-wiring.d.ts.map +1 -1
  87. package/dist/agent-farm/servers/mailbox-wiring.js +204 -37
  88. package/dist/agent-farm/servers/mailbox-wiring.js.map +1 -1
  89. package/dist/agent-farm/servers/message-write.d.ts +138 -11
  90. package/dist/agent-farm/servers/message-write.d.ts.map +1 -1
  91. package/dist/agent-farm/servers/message-write.js +144 -35
  92. package/dist/agent-farm/servers/message-write.js.map +1 -1
  93. package/dist/agent-farm/servers/overview.d.ts +28 -12
  94. package/dist/agent-farm/servers/overview.d.ts.map +1 -1
  95. package/dist/agent-farm/servers/overview.js +130 -79
  96. package/dist/agent-farm/servers/overview.js.map +1 -1
  97. package/dist/agent-farm/servers/render-gate.d.ts +77 -1
  98. package/dist/agent-farm/servers/render-gate.d.ts.map +1 -1
  99. package/dist/agent-farm/servers/render-gate.js +174 -25
  100. package/dist/agent-farm/servers/render-gate.js.map +1 -1
  101. package/dist/agent-farm/servers/session-submit.d.ts +7 -4
  102. package/dist/agent-farm/servers/session-submit.d.ts.map +1 -1
  103. package/dist/agent-farm/servers/session-submit.js +7 -4
  104. package/dist/agent-farm/servers/session-submit.js.map +1 -1
  105. package/dist/agent-farm/servers/tower-cron.d.ts.map +1 -1
  106. package/dist/agent-farm/servers/tower-cron.js +7 -3
  107. package/dist/agent-farm/servers/tower-cron.js.map +1 -1
  108. package/dist/agent-farm/servers/tower-instances.d.ts.map +1 -1
  109. package/dist/agent-farm/servers/tower-instances.js +17 -10
  110. package/dist/agent-farm/servers/tower-instances.js.map +1 -1
  111. package/dist/agent-farm/servers/tower-routes.d.ts +32 -0
  112. package/dist/agent-farm/servers/tower-routes.d.ts.map +1 -1
  113. package/dist/agent-farm/servers/tower-routes.js +186 -26
  114. package/dist/agent-farm/servers/tower-routes.js.map +1 -1
  115. package/dist/agent-farm/servers/tower-server.js +79 -9
  116. package/dist/agent-farm/servers/tower-server.js.map +1 -1
  117. package/dist/agent-farm/servers/tower-terminals.d.ts +21 -0
  118. package/dist/agent-farm/servers/tower-terminals.d.ts.map +1 -1
  119. package/dist/agent-farm/servers/tower-terminals.js +106 -13
  120. package/dist/agent-farm/servers/tower-terminals.js.map +1 -1
  121. package/dist/agent-farm/servers/tower-utils.d.ts +35 -0
  122. package/dist/agent-farm/servers/tower-utils.d.ts.map +1 -1
  123. package/dist/agent-farm/servers/tower-utils.js +39 -0
  124. package/dist/agent-farm/servers/tower-utils.js.map +1 -1
  125. package/dist/agent-farm/servers/tower-websocket.d.ts.map +1 -1
  126. package/dist/agent-farm/servers/tower-websocket.js +26 -2
  127. package/dist/agent-farm/servers/tower-websocket.js.map +1 -1
  128. package/dist/agent-farm/utils/message-format.d.ts +78 -2
  129. package/dist/agent-farm/utils/message-format.d.ts.map +1 -1
  130. package/dist/agent-farm/utils/message-format.js +107 -11
  131. package/dist/agent-farm/utils/message-format.js.map +1 -1
  132. package/dist/agent-farm/utils/port.d.ts +22 -0
  133. package/dist/agent-farm/utils/port.d.ts.map +1 -0
  134. package/dist/agent-farm/utils/port.js +35 -0
  135. package/dist/agent-farm/utils/port.js.map +1 -0
  136. package/dist/agent-farm/utils/server-utils.d.ts +26 -0
  137. package/dist/agent-farm/utils/server-utils.d.ts.map +1 -1
  138. package/dist/agent-farm/utils/server-utils.js +36 -0
  139. package/dist/agent-farm/utils/server-utils.js.map +1 -1
  140. package/dist/cli.d.ts.map +1 -1
  141. package/dist/cli.js +3 -1
  142. package/dist/cli.js.map +1 -1
  143. package/dist/commands/consult/index.d.ts.map +1 -1
  144. package/dist/commands/consult/index.js +61 -1
  145. package/dist/commands/consult/index.js.map +1 -1
  146. package/dist/commands/consult/tree-tripwire.d.ts +177 -0
  147. package/dist/commands/consult/tree-tripwire.d.ts.map +1 -0
  148. package/dist/commands/consult/tree-tripwire.js +356 -0
  149. package/dist/commands/consult/tree-tripwire.js.map +1 -0
  150. package/dist/commands/doctor.d.ts +69 -0
  151. package/dist/commands/doctor.d.ts.map +1 -1
  152. package/dist/commands/doctor.js +165 -2
  153. package/dist/commands/doctor.js.map +1 -1
  154. package/dist/commands/generate-image.d.ts +25 -1
  155. package/dist/commands/generate-image.d.ts.map +1 -1
  156. package/dist/commands/generate-image.js +410 -2
  157. package/dist/commands/generate-image.js.map +1 -1
  158. package/dist/commands/porch/prompts.d.ts.map +1 -1
  159. package/dist/commands/porch/prompts.js +18 -2
  160. package/dist/commands/porch/prompts.js.map +1 -1
  161. package/dist/lib/agent-env.d.ts +86 -0
  162. package/dist/lib/agent-env.d.ts.map +1 -0
  163. package/dist/lib/agent-env.js +126 -0
  164. package/dist/lib/agent-env.js.map +1 -0
  165. package/dist/lib/forge-contracts.d.ts +76 -5
  166. package/dist/lib/forge-contracts.d.ts.map +1 -1
  167. package/dist/lib/forge-contracts.js.map +1 -1
  168. package/dist/lib/forge-rate-limit.d.ts +45 -0
  169. package/dist/lib/forge-rate-limit.d.ts.map +1 -0
  170. package/dist/lib/forge-rate-limit.js +89 -0
  171. package/dist/lib/forge-rate-limit.js.map +1 -0
  172. package/dist/lib/forge.d.ts +29 -1
  173. package/dist/lib/forge.d.ts.map +1 -1
  174. package/dist/lib/forge.js +96 -21
  175. package/dist/lib/forge.js.map +1 -1
  176. package/dist/lib/github.d.ts +13 -1
  177. package/dist/lib/github.d.ts.map +1 -1
  178. package/dist/lib/github.js +58 -15
  179. package/dist/lib/github.js.map +1 -1
  180. package/dist/lib/test-env.d.ts +17 -0
  181. package/dist/lib/test-env.d.ts.map +1 -1
  182. package/dist/lib/test-env.js +20 -0
  183. package/dist/lib/test-env.js.map +1 -1
  184. package/dist/terminal/pty-manager.d.ts +10 -1
  185. package/dist/terminal/pty-manager.d.ts.map +1 -1
  186. package/dist/terminal/pty-manager.js +38 -9
  187. package/dist/terminal/pty-manager.js.map +1 -1
  188. package/dist/terminal/pty-session.d.ts +174 -8
  189. package/dist/terminal/pty-session.d.ts.map +1 -1
  190. package/dist/terminal/pty-session.js +299 -25
  191. package/dist/terminal/pty-session.js.map +1 -1
  192. package/dist/terminal/session-manager.d.ts +23 -2
  193. package/dist/terminal/session-manager.d.ts.map +1 -1
  194. package/dist/terminal/session-manager.js +115 -36
  195. package/dist/terminal/session-manager.js.map +1 -1
  196. package/dist/terminal/session-screen.d.ts +34 -5
  197. package/dist/terminal/session-screen.d.ts.map +1 -1
  198. package/dist/terminal/session-screen.js +52 -6
  199. package/dist/terminal/session-screen.js.map +1 -1
  200. package/dist/terminal/shellper-client.d.ts +73 -0
  201. package/dist/terminal/shellper-client.d.ts.map +1 -1
  202. package/dist/terminal/shellper-client.js +151 -0
  203. package/dist/terminal/shellper-client.js.map +1 -1
  204. package/dist/terminal/shellper-main.js +20 -3
  205. package/dist/terminal/shellper-main.js.map +1 -1
  206. package/dist/terminal/shellper-process.d.ts +2 -0
  207. package/dist/terminal/shellper-process.d.ts.map +1 -1
  208. package/dist/terminal/shellper-process.js +17 -1
  209. package/dist/terminal/shellper-process.js.map +1 -1
  210. package/dist/terminal/shellper-protocol.d.ts +28 -0
  211. package/dist/terminal/shellper-protocol.d.ts.map +1 -1
  212. package/dist/terminal/shellper-protocol.js.map +1 -1
  213. package/dist/terminal/terminal-replies.d.ts +102 -0
  214. package/dist/terminal/terminal-replies.d.ts.map +1 -0
  215. package/dist/terminal/terminal-replies.js +181 -0
  216. package/dist/terminal/terminal-replies.js.map +1 -0
  217. package/package.json +4 -4
  218. package/scripts/forge/gitea/_lib.sh +214 -0
  219. package/scripts/forge/gitea/issue-comment.sh +8 -1
  220. package/scripts/forge/gitea/issue-view.sh +95 -4
  221. package/scripts/forge/gitea/pr-create.sh +155 -0
  222. package/scripts/forge/gitea/pr-exists.sh +32 -4
  223. package/scripts/forge/gitea/pr-list.sh +40 -31
  224. package/scripts/forge/gitea/pr-view.sh +65 -4
  225. package/scripts/forge/gitea/recently-merged.sh +91 -21
  226. package/scripts/forge/gitea/user-identity.sh +30 -1
  227. package/scripts/forge/github/issue-view.sh +5 -2
  228. package/scripts/forge/github/pr-create.sh +47 -0
  229. package/scripts/forge/github/pr-list.sh +6 -2
  230. package/scripts/forge/github/pr-search.sh +6 -2
  231. package/scripts/forge/gitlab/issue-search.sh +1 -0
  232. package/scripts/forge/gitlab/issue-view.sh +24 -4
  233. package/scripts/forge/gitlab/pr-create.sh +53 -0
  234. package/scripts/forge/gitlab/pr-search.sh +37 -2
  235. package/scripts/forge/linear/auth-status.sh +1 -0
  236. package/scripts/forge/linear/issue-comment.sh +1 -0
  237. package/scripts/forge/linear/issue-list.sh +1 -0
  238. package/scripts/forge/linear/issue-search.sh +1 -0
  239. package/scripts/forge/linear/issue-view.sh +14 -2
  240. package/scripts/forge/linear/recently-closed.sh +1 -0
  241. package/scripts/forge/linear/user-identity.sh +1 -0
  242. package/skeleton/.claude/skills/generate-image/SKILL.md +39 -1
  243. package/skeleton/.codex/skills/generate-image/SKILL.md +39 -1
  244. package/skeleton/protocols/air/prompts/pr.md +6 -1
  245. package/skeleton/protocols/aspir/prompts/review.md +6 -1
  246. package/skeleton/protocols/bugfix/prompts/pr.md +6 -1
  247. package/skeleton/protocols/bugfix/protocol.md +2 -1
  248. package/skeleton/protocols/maintain/prompts/review.md +6 -1
  249. package/skeleton/protocols/pir/prompts/review.md +10 -7
  250. package/skeleton/protocols/spir/prompts/review.md +6 -1
  251. package/skeleton/resources/commands/agent-farm.md +28 -3
  252. package/skeleton/roles/consultant.md +32 -0
  253. package/skeleton/templates/AGENTS.md +1 -1
  254. package/skeleton/templates/CLAUDE.md +1 -1
  255. package/templates/tower.html +16 -1
  256. package/dashboard-dist/assets/index-BZRTEMtH.css +0 -32
  257. package/dashboard-dist/assets/index-D3XaKpZW.js.map +0 -1
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Environment sanitation for agent processes Tower spawns (Issue #1219).
3
+ *
4
+ * Claude Code plants session markers — `CLAUDECODE`, `CLAUDE_CODE_CHILD_SESSION`,
5
+ * `CLAUDE_CODE_SESSION_ID`, … — into every subprocess it creates, so a nested
6
+ * `claude` can tell it was launched from inside another session and turn
7
+ * transcript saving off. Tower is a daemon, but it inherits the environment of
8
+ * whoever started it, and starting Tower from inside a Claude session is routine
9
+ * (`afx tower start`, `pnpm -w run local-install`, an architect recovering from a
10
+ * crash). The markers then cascade:
11
+ *
12
+ * claude session → Bash → afx tower start → Tower → shellper → agent claude
13
+ *
14
+ * Every agent Tower spawns believes it is a nested child session, and a session
15
+ * with transcript saving off **cannot be resumed** — which quietly guts the
16
+ * crash-recovery story (#1145, #1149) and only shows up at recovery time, when
17
+ * it is too late.
18
+ *
19
+ * ## Why this strips named families rather than the whole namespace
20
+ *
21
+ * The first version of this module denied `CLAUDE_CODE_*` wholesale and kept a
22
+ * short allowlist, on the theory that a *missed marker* is worse than a missed
23
+ * config var. The CMAP review (codex) rejected that, and checking the shipped
24
+ * `claude` binary settled it: it reads **594** distinct `CLAUDE_CODE_*`
25
+ * variables, and they are overwhelmingly configuration — provider selection
26
+ * (`USE_BEDROCK`, `USE_VERTEX`, `USE_FOUNDRY`, `USE_MANTLE`,
27
+ * `USE_ANTHROPIC_AWS`, `USE_GATEWAY`), the matching `SKIP_*_AUTH` switches,
28
+ * credentials (`OAUTH_TOKEN`, `OAUTH_REFRESH_TOKEN`, `OAUTH_SCOPES`,
29
+ * `CLIENT_CERT`), routing (`API_BASE_URL`, `PROXY_URL`, `HTTPS_PROXY`), and
30
+ * policy (`MANAGED_SETTINGS_PATH`). No hand-maintained allowlist survives that,
31
+ * and dropping any of them is not the harmless failure the original reasoning
32
+ * assumed — it silently routes an agent at the wrong provider, or strips the
33
+ * subscription credential and reroutes CMAP to the metered API (the #985 scar).
34
+ *
35
+ * So the rule is: **strip what is per-session identity, keep everything else.**
36
+ * Identity is a small, stable, nameable set; configuration is not.
37
+ *
38
+ * The cost of that direction is real and worth stating plainly: a marker added
39
+ * upstream that this list has not caught up with will pass through, and nothing
40
+ * here will notice. `codev doctor`'s Tower Environment check is not a backstop
41
+ * for that case — it classifies with this same list, so it is blind to exactly
42
+ * what it would need to catch. Claude Code's own "transcript saving is off"
43
+ * banner is the only real signal, and it is how #1219 was found in the first
44
+ * place. Adding the new name here is the fix when that happens.
45
+ */
46
+ /**
47
+ * Whole families of per-session identity. Every variable Claude Code ships
48
+ * under these prefixes describes *this* session — its id, its socket, its
49
+ * bridge — and inheriting one into a different agent is always wrong.
50
+ */
51
+ export declare const CLAUDE_SESSION_MARKER_PREFIXES: readonly string[];
52
+ /**
53
+ * Individually named session markers that do not fall under a prefix family.
54
+ *
55
+ * `CLAUDECODE` was already being deleted ad hoc at each Tower spawn site; it
56
+ * lives here now so there is one list rather than six copies of one `delete`.
57
+ * `CHILD_SESSION`, `ENTRYPOINT` and `EXECPATH` are the nesting-detection triple
58
+ * that #1219 is actually about.
59
+ *
60
+ * `CLAUDE_PID` sits outside the `CLAUDE_CODE_` namespace but belongs here on the
61
+ * merits: the shipped binary builds its child environment as
62
+ * `{CLAUDECODE:"1", CLAUDE_CODE_SESSION_ID:…, CLAUDE_CODE_CHILD_SESSION:"1",
63
+ * CLAUDE_PID:String(process.pid)}` — one object literal, so it is identity by
64
+ * construction, not by namespace. Nothing reads it for nesting detection; its
65
+ * only reader is the `pkill` guard in the Bash tool's shell prelude, which
66
+ * refuses a pattern matching the Claude CLI's own pid. An inherited stale value
67
+ * points that guard at a dead or unrelated pid, which is its own small bug.
68
+ *
69
+ * `CLAUDE_EFFORT` is planted by that same function and is deliberately NOT here:
70
+ * being planted by Claude Code is not the test — it carries a *setting* (the
71
+ * effort level), not an identity, so it is configuration and passes through.
72
+ */
73
+ export declare const CLAUDE_SESSION_MARKER_NAMES: readonly string[];
74
+ /** Whether `name` is a Claude Code session marker that must not reach an agent. */
75
+ export declare function isClaudeSessionMarker(name: string): boolean;
76
+ /**
77
+ * Copy `env` with Claude Code session markers removed.
78
+ *
79
+ * Returns a plain `Record<string, string>` — `undefined`-valued entries (which
80
+ * `NodeJS.ProcessEnv` permits and node-pty rejects) are dropped — so callers can
81
+ * hand the result straight to a spawn call.
82
+ */
83
+ export declare function sanitizeAgentEnv(env?: NodeJS.ProcessEnv | Record<string, string>): Record<string, string>;
84
+ /** The session markers present in `env`, for diagnostics (`codev doctor`). */
85
+ export declare function findClaudeSessionMarkers(env?: NodeJS.ProcessEnv | Record<string, string>): string[];
86
+ //# sourceMappingURL=agent-env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-env.d.ts","sourceRoot":"","sources":["../../src/lib/agent-env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAEH;;;;GAIG;AACH,eAAO,MAAM,8BAA8B,EAAE,SAAS,MAAM,EAS3D,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,2BAA2B,EAAE,SAAS,MAAM,EAcxD,CAAC;AAIF,mFAAmF;AACnF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAG3D;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,GAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAe,GAC5D,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQxB;AAED,8EAA8E;AAC9E,wBAAgB,wBAAwB,CACtC,GAAG,GAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAe,GAC5D,MAAM,EAAE,CAEV"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Environment sanitation for agent processes Tower spawns (Issue #1219).
3
+ *
4
+ * Claude Code plants session markers — `CLAUDECODE`, `CLAUDE_CODE_CHILD_SESSION`,
5
+ * `CLAUDE_CODE_SESSION_ID`, … — into every subprocess it creates, so a nested
6
+ * `claude` can tell it was launched from inside another session and turn
7
+ * transcript saving off. Tower is a daemon, but it inherits the environment of
8
+ * whoever started it, and starting Tower from inside a Claude session is routine
9
+ * (`afx tower start`, `pnpm -w run local-install`, an architect recovering from a
10
+ * crash). The markers then cascade:
11
+ *
12
+ * claude session → Bash → afx tower start → Tower → shellper → agent claude
13
+ *
14
+ * Every agent Tower spawns believes it is a nested child session, and a session
15
+ * with transcript saving off **cannot be resumed** — which quietly guts the
16
+ * crash-recovery story (#1145, #1149) and only shows up at recovery time, when
17
+ * it is too late.
18
+ *
19
+ * ## Why this strips named families rather than the whole namespace
20
+ *
21
+ * The first version of this module denied `CLAUDE_CODE_*` wholesale and kept a
22
+ * short allowlist, on the theory that a *missed marker* is worse than a missed
23
+ * config var. The CMAP review (codex) rejected that, and checking the shipped
24
+ * `claude` binary settled it: it reads **594** distinct `CLAUDE_CODE_*`
25
+ * variables, and they are overwhelmingly configuration — provider selection
26
+ * (`USE_BEDROCK`, `USE_VERTEX`, `USE_FOUNDRY`, `USE_MANTLE`,
27
+ * `USE_ANTHROPIC_AWS`, `USE_GATEWAY`), the matching `SKIP_*_AUTH` switches,
28
+ * credentials (`OAUTH_TOKEN`, `OAUTH_REFRESH_TOKEN`, `OAUTH_SCOPES`,
29
+ * `CLIENT_CERT`), routing (`API_BASE_URL`, `PROXY_URL`, `HTTPS_PROXY`), and
30
+ * policy (`MANAGED_SETTINGS_PATH`). No hand-maintained allowlist survives that,
31
+ * and dropping any of them is not the harmless failure the original reasoning
32
+ * assumed — it silently routes an agent at the wrong provider, or strips the
33
+ * subscription credential and reroutes CMAP to the metered API (the #985 scar).
34
+ *
35
+ * So the rule is: **strip what is per-session identity, keep everything else.**
36
+ * Identity is a small, stable, nameable set; configuration is not.
37
+ *
38
+ * The cost of that direction is real and worth stating plainly: a marker added
39
+ * upstream that this list has not caught up with will pass through, and nothing
40
+ * here will notice. `codev doctor`'s Tower Environment check is not a backstop
41
+ * for that case — it classifies with this same list, so it is blind to exactly
42
+ * what it would need to catch. Claude Code's own "transcript saving is off"
43
+ * banner is the only real signal, and it is how #1219 was found in the first
44
+ * place. Adding the new name here is the fix when that happens.
45
+ */
46
+ /**
47
+ * Whole families of per-session identity. Every variable Claude Code ships
48
+ * under these prefixes describes *this* session — its id, its socket, its
49
+ * bridge — and inheriting one into a different agent is always wrong.
50
+ */
51
+ export const CLAUDE_SESSION_MARKER_PREFIXES = [
52
+ // SESSION_ID / _KIND / _LOG / _NAME / _ORIGIN / _ACCESS_TOKEN
53
+ 'CLAUDE_CODE_SESSION_',
54
+ // REMOTE_SESSION_ID / _ORIGIN / _UUID
55
+ 'CLAUDE_CODE_REMOTE_SESSION_',
56
+ // BRIDGE_SESSION_ID / _PROMPT_SHA256 / _OWNER_* / _MCP_CARRIER
57
+ 'CLAUDE_CODE_BRIDGE_',
58
+ // MESSAGING_SOCKET / _TOKEN — a live socket path and its bearer token
59
+ 'CLAUDE_CODE_MESSAGING_',
60
+ ];
61
+ /**
62
+ * Individually named session markers that do not fall under a prefix family.
63
+ *
64
+ * `CLAUDECODE` was already being deleted ad hoc at each Tower spawn site; it
65
+ * lives here now so there is one list rather than six copies of one `delete`.
66
+ * `CHILD_SESSION`, `ENTRYPOINT` and `EXECPATH` are the nesting-detection triple
67
+ * that #1219 is actually about.
68
+ *
69
+ * `CLAUDE_PID` sits outside the `CLAUDE_CODE_` namespace but belongs here on the
70
+ * merits: the shipped binary builds its child environment as
71
+ * `{CLAUDECODE:"1", CLAUDE_CODE_SESSION_ID:…, CLAUDE_CODE_CHILD_SESSION:"1",
72
+ * CLAUDE_PID:String(process.pid)}` — one object literal, so it is identity by
73
+ * construction, not by namespace. Nothing reads it for nesting detection; its
74
+ * only reader is the `pkill` guard in the Bash tool's shell prelude, which
75
+ * refuses a pattern matching the Claude CLI's own pid. An inherited stale value
76
+ * points that guard at a dead or unrelated pid, which is its own small bug.
77
+ *
78
+ * `CLAUDE_EFFORT` is planted by that same function and is deliberately NOT here:
79
+ * being planted by Claude Code is not the test — it carries a *setting* (the
80
+ * effort level), not an identity, so it is configuration and passes through.
81
+ */
82
+ export const CLAUDE_SESSION_MARKER_NAMES = [
83
+ 'CLAUDECODE',
84
+ 'CLAUDE_CODE_CHILD_SESSION',
85
+ // Not in the CLAUDE_CODE_ namespace, but planted by the same object literal
86
+ // as CHILD_SESSION and set to `String(process.pid)` — see the note below.
87
+ 'CLAUDE_PID',
88
+ 'CLAUDE_CODE_ENTRYPOINT',
89
+ 'CLAUDE_CODE_EXECPATH',
90
+ 'CLAUDE_CODE_SSE_PORT',
91
+ 'CLAUDE_CODE_CLOUD_SESSION_ID',
92
+ 'CLAUDE_CODE_RESUME_FROM_SESSION',
93
+ 'CLAUDE_CODE_SPAWN_TIMESTAMP_MS',
94
+ 'CLAUDE_CODE_TRIGGER_ID',
95
+ 'CLAUDE_CODE_WORKER_EPOCH',
96
+ ];
97
+ const MARKER_NAMES = new Set(CLAUDE_SESSION_MARKER_NAMES);
98
+ /** Whether `name` is a Claude Code session marker that must not reach an agent. */
99
+ export function isClaudeSessionMarker(name) {
100
+ if (MARKER_NAMES.has(name))
101
+ return true;
102
+ return CLAUDE_SESSION_MARKER_PREFIXES.some((prefix) => name.startsWith(prefix));
103
+ }
104
+ /**
105
+ * Copy `env` with Claude Code session markers removed.
106
+ *
107
+ * Returns a plain `Record<string, string>` — `undefined`-valued entries (which
108
+ * `NodeJS.ProcessEnv` permits and node-pty rejects) are dropped — so callers can
109
+ * hand the result straight to a spawn call.
110
+ */
111
+ export function sanitizeAgentEnv(env = process.env) {
112
+ const out = {};
113
+ for (const [key, value] of Object.entries(env)) {
114
+ if (value === undefined)
115
+ continue;
116
+ if (isClaudeSessionMarker(key))
117
+ continue;
118
+ out[key] = value;
119
+ }
120
+ return out;
121
+ }
122
+ /** The session markers present in `env`, for diagnostics (`codev doctor`). */
123
+ export function findClaudeSessionMarkers(env = process.env) {
124
+ return Object.keys(env).filter(isClaudeSessionMarker).sort();
125
+ }
126
+ //# sourceMappingURL=agent-env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-env.js","sourceRoot":"","sources":["../../src/lib/agent-env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAEH;;;;GAIG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAsB;IAC/D,8DAA8D;IAC9D,sBAAsB;IACtB,sCAAsC;IACtC,6BAA6B;IAC7B,+DAA+D;IAC/D,qBAAqB;IACrB,sEAAsE;IACtE,wBAAwB;CACzB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAsB;IAC5D,YAAY;IACZ,2BAA2B;IAC3B,4EAA4E;IAC5E,0EAA0E;IAC1E,YAAY;IACZ,wBAAwB;IACxB,sBAAsB;IACtB,sBAAsB;IACtB,8BAA8B;IAC9B,iCAAiC;IACjC,gCAAgC;IAChC,wBAAwB;IACxB,0BAA0B;CAC3B,CAAC;AAEF,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,2BAA2B,CAAC,CAAC;AAE1D,mFAAmF;AACnF,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,IAAI,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACxC,OAAO,8BAA8B,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;AAClF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAC9B,MAAkD,OAAO,CAAC,GAAG;IAE7D,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QAClC,IAAI,qBAAqB,CAAC,GAAG,CAAC;YAAE,SAAS;QACzC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACnB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,wBAAwB,CACtC,MAAkD,OAAO,CAAC,GAAG;IAE7D,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,IAAI,EAAE,CAAC;AAC/D,CAAC"}
@@ -24,6 +24,46 @@ export interface IssueViewResult {
24
24
  * forge-neutral (a forge script that doesn't emit it degrades gracefully).
25
25
  */
26
26
  url?: string;
27
+ /**
28
+ * Login/handle of the user who opened the issue, when the forge concept
29
+ * supplies it: GitHub `author.login`, GitLab `author.username`, Gitea
30
+ * `user.login`, Linear `creator.displayName`. Optional so the contract
31
+ * stays forge-neutral — a forge/script that omits it degrades gracefully
32
+ * (the consumer drops the "opened by" attribution).
33
+ */
34
+ author?: {
35
+ login: string;
36
+ };
37
+ /**
38
+ * ISO 8601 creation timestamp, when the forge concept supplies it. Optional
39
+ * for forge-neutral degradation, same as `url`.
40
+ */
41
+ createdAt?: string;
42
+ /**
43
+ * Assignee logins/handles, when the forge concept supplies them: absent when
44
+ * the forge doesn't expose them, empty when the issue is unassigned. Optional
45
+ * per the forge-neutral degradation contract.
46
+ */
47
+ assignees?: Array<{
48
+ login: string;
49
+ }>;
50
+ /**
51
+ * Issue labels, when the forge concept supplies them: absent when the forge
52
+ * doesn't expose labels, empty when the issue has none. Optional per the
53
+ * forge-neutral degradation contract.
54
+ */
55
+ labels?: Array<{
56
+ name: string;
57
+ }>;
58
+ /**
59
+ * The issue's milestone, when set. GitHub emits a literal `null` when the
60
+ * issue has no milestone (hence `| null`, not merely optional); consumers
61
+ * guard on `milestone?.title`, so both absent and null render nothing.
62
+ * Optional/nullable per the forge-neutral degradation contract.
63
+ */
64
+ milestone?: {
65
+ title: string;
66
+ } | null;
27
67
  comments: Array<{
28
68
  body: string;
29
69
  createdAt: string;
@@ -74,13 +114,17 @@ export interface PrListItem {
74
114
  login: string;
75
115
  };
76
116
  /**
77
- * Logins of users requested as reviewers. Emitted by every forge's `pr-list`
78
- * script (GitHub flattens gh's reviewer objects to logins; GitLab/Gitea emit
79
- * `[]` as they expose no GitHub-equivalent per-user review-request list).
80
- * Consumed by the VSCode PR sidebar to bucket "review-requested" PRs.
117
+ * Logins of users requested as reviewers. Every preset populates it for real:
118
+ * GitHub flattens gh's reviewer objects to logins, GitLab maps glab's
119
+ * `.reviewers[].username`, and Gitea maps the REST `requested_reviewers[]`
120
+ * (team reviewers carry no login and are dropped). Consumed by the VSCode PR
121
+ * sidebar to bucket "review-requested" PRs.
81
122
  */
82
123
  reviewRequests: string[];
83
- /** Whether the PR is a draft. GitLab/Gitea emit `false` (not exposed). */
124
+ /**
125
+ * Whether the PR is a draft. Every preset reports it for real — GitLab from
126
+ * the merge request's `draft`/WIP flag, Gitea from the REST `draft` flag.
127
+ */
84
128
  isDraft: boolean;
85
129
  }
86
130
  /** Output of the `pr-list` concept command. */
@@ -102,6 +146,16 @@ export type RecentlyMergedResult = MergedPrItem[];
102
146
  export interface PrSearchItem {
103
147
  number: number;
104
148
  headRefName: string;
149
+ /**
150
+ * PR/MR state, normalized to the GitHub convention: `OPEN` | `MERGED` |
151
+ * `CLOSED`. Because `pr-search` runs `--state all` (#759), consumers that
152
+ * only want open PRs must filter on this — the spawn collision guard ignores
153
+ * non-open results (#1637). Optional: a stale project-local override of
154
+ * `pr-search.sh` may predate this field (and the gitlab script leaves it
155
+ * blank when glab omits it), so consumers treat an absent or empty value as
156
+ * "unknown" rather than assuming a state.
157
+ */
158
+ state?: string;
105
159
  }
106
160
  /** Output of the `pr-search` concept command. */
107
161
  export type PrSearchResult = PrSearchItem[];
@@ -127,6 +181,23 @@ export interface PrViewResult {
127
181
  additions: number;
128
182
  deletions: number;
129
183
  }
184
+ /**
185
+ * Output of the `pr-create` concept command.
186
+ *
187
+ * Inputs are environment variables, like every other concept:
188
+ * `CODEV_PR_TITLE` (required), `CODEV_PR_BODY` (required — set it to `''` for
189
+ * an empty body; an *absent* one is rejected rather than silently posting a
190
+ * bodyless PR), and the optional `CODEV_PR_BASE`, `CODEV_PR_HEAD`,
191
+ * `CODEV_PR_REPO`, `CODEV_PR_DRAFT`. The gitea script also reads the optional
192
+ * `CODEV_PR_LOGIN` (tea's `--login`, for multi-login hosts). A failed creation
193
+ * exits non-zero rather than emitting JSON.
194
+ */
195
+ export interface PrCreateResult {
196
+ /** The created PR's number (`iid` on GitLab, `index` on Gitea). */
197
+ number: number;
198
+ /** The created PR's **browser/web** URL — never an API endpoint. */
199
+ url: string;
200
+ }
130
201
  /** Output of the `pr-diff` concept command: raw diff text, not JSON. */
131
202
  /** Output of the `pr-merge` concept command: exit code only, no JSON. */
132
203
  /** Output of the `user-identity` concept command: plain string (username). */
@@ -1 +1 @@
1
- {"version":3,"file":"forge-contracts.d.ts","sourceRoot":"","sources":["../../src/lib/forge-contracts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"forge-contracts.d.ts","sourceRoot":"","sources":["../../src/lib/forge-contracts.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"forge-contracts.js","sourceRoot":"","sources":["../../src/lib/forge-contracts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;;AAiIH,wEAAwE;AACxE,uDAAuD;AAEvD,yEAAyE;AACzE,8DAA8D;AAE9D,gFAAgF;AAChF,2BAA2B;AAC3B,gFAAgF;AAEhF,8EAA8E;AAC9E,+CAA+C;AAE/C,2EAA2E;AAC3E,mEAAmE;AACnE,8CAA8C;AAE9C,8EAA8E;AAC9E,0EAA0E;AAC1E,yCAAyC;AAEzC,gFAAgF;AAChF,gBAAgB;AAChB,gFAAgF;AAEhF,mEAAmE;AACnE,6DAA6D"}
1
+ {"version":3,"file":"forge-contracts.js","sourceRoot":"","sources":["../../src/lib/forge-contracts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;;AAiMH,wEAAwE;AACxE,uDAAuD;AAEvD,yEAAyE;AACzE,8DAA8D;AAE9D,gFAAgF;AAChF,2BAA2B;AAC3B,gFAAgF;AAEhF,8EAA8E;AAC9E,+CAA+C;AAE/C,2EAA2E;AAC3E,mEAAmE;AACnE,8CAA8C;AAE9C,8EAA8E;AAC9E,0EAA0E;AAC1E,yCAAyC;AAEzC,gFAAgF;AAChF,gBAAgB;AAChB,gFAAgF;AAEhF,mEAAmE;AACnE,6DAA6D"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Per-backend rate-limit suspension for forge fetches (#1645).
3
+ *
4
+ * When a backend (`gh`, `glab`, …) reports that its budget is exhausted, every
5
+ * fetch that would spend the same budget is suspended until the reset instant.
6
+ * Importing this module never shells out: the optional reset probe is injected
7
+ * by the caller that wants it (Tower's overview cache).
8
+ */
9
+ export declare function isRateLimitError(text: string): boolean;
10
+ /** The budget a concept spends on its backend, e.g. `gh` or `gh:rest`. */
11
+ export declare function budgetKeyFor(backend: string, concept: string): string;
12
+ /** Result of a reset probe. `remaining === 0` makes the reported reset credible. */
13
+ export interface RateLimitProbeResult {
14
+ remaining: number;
15
+ /** Reset instant, epoch milliseconds. */
16
+ resetAt: number;
17
+ }
18
+ export type RateLimitProbe = (backend: string, cwd: string) => Promise<RateLimitProbeResult | null>;
19
+ export declare const SUSPENSION_FALLBACK_MS: number;
20
+ export declare class ForgeRateLimiter {
21
+ private readonly probe?;
22
+ private readonly suspensions;
23
+ constructor(probe?: RateLimitProbe | undefined);
24
+ /** Read-only: never allocates, so polling it every 2.5 s costs nothing. */
25
+ isSuspended(budget: string, now: number): boolean;
26
+ /** Reset instant (epoch ms) of an active suspension, else null. */
27
+ resetAt(budget: string, now: number): number | null;
28
+ /**
29
+ * Record a failure. Only a rate-limit error suspends, and only the failing
30
+ * budget: a REST failure never suspends the GraphQL bucket. A fresh
31
+ * suspension runs the reset probe at most once; a credible probe result
32
+ * (budget confirmed gone) sets the true reset instant, even if that is
33
+ * earlier than the fallback window.
34
+ */
35
+ noteFailure(budget: string, backend: string, cwd: string, errorText: string, now: number): boolean;
36
+ /**
37
+ * A success clears a suspension only if it was dispatched strictly after the
38
+ * suspension began: a batch dispatched in one tick shares a millisecond with
39
+ * the failure that suspended it, and its successes are not evidence of recovery.
40
+ */
41
+ noteSuccess(budget: string, dispatchedAt: number): void;
42
+ /** Honour a credible probe: the true reset instant wins over the fallback in both directions. */
43
+ private applyProbe;
44
+ }
45
+ //# sourceMappingURL=forge-rate-limit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forge-rate-limit.d.ts","sourceRoot":"","sources":["../../src/lib/forge-rate-limit.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD;AAYD,0EAA0E;AAC1E,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAGrE;AAED,oFAAoF;AACpF,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC;AAOpG,eAAO,MAAM,sBAAsB,QAAc,CAAC;AAElD,qBAAa,gBAAgB;IAGf,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;IAFnC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAiC;gBAEhC,KAAK,CAAC,EAAE,cAAc,YAAA;IAEnD,2EAA2E;IAC3E,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO;IAKjD,mEAAmE;IACnE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKnD;;;;;;OAMG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO;IAgBlG;;;;OAIG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI;IAKvD,iGAAiG;IACjG,OAAO,CAAC,UAAU;CAKnB"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Per-backend rate-limit suspension for forge fetches (#1645).
3
+ *
4
+ * When a backend (`gh`, `glab`, …) reports that its budget is exhausted, every
5
+ * fetch that would spend the same budget is suspended until the reset instant.
6
+ * Importing this module never shells out: the optional reset probe is injected
7
+ * by the caller that wants it (Tower's overview cache).
8
+ */
9
+ /** GitHub's GraphQL and REST primary-limit messages, and gh's error type. */
10
+ const RATE_LIMIT_PATTERN = /rate limit (?:already )?exceeded|RATE_LIMITED|graphql_rate_limit|secondary rate limit/i;
11
+ export function isRateLimitError(text) {
12
+ return RATE_LIMIT_PATTERN.test(text);
13
+ }
14
+ /**
15
+ * Concepts that spend a budget other than the one the backend's list concepts
16
+ * spend. This is a fact about the backend: on `gh`, `user-identity` is a REST
17
+ * call outside the GraphQL bucket; on Linear every concept is GraphQL on
18
+ * Linear's own budget, so nothing is split out there.
19
+ */
20
+ const OFF_BUDGET_CONCEPTS = {
21
+ gh: new Set(['user-identity', 'auth-status']),
22
+ };
23
+ /** The budget a concept spends on its backend, e.g. `gh` or `gh:rest`. */
24
+ export function budgetKeyFor(backend, concept) {
25
+ const key = backend.toLowerCase();
26
+ return OFF_BUDGET_CONCEPTS[key]?.has(concept) ? `${key}:rest` : key;
27
+ }
28
+ export const SUSPENSION_FALLBACK_MS = 15 * 60_000;
29
+ export class ForgeRateLimiter {
30
+ probe;
31
+ suspensions = new Map();
32
+ constructor(probe) {
33
+ this.probe = probe;
34
+ }
35
+ /** Read-only: never allocates, so polling it every 2.5 s costs nothing. */
36
+ isSuspended(budget, now) {
37
+ const s = this.suspensions.get(budget);
38
+ return s !== undefined && now < s.until;
39
+ }
40
+ /** Reset instant (epoch ms) of an active suspension, else null. */
41
+ resetAt(budget, now) {
42
+ const s = this.suspensions.get(budget);
43
+ return s !== undefined && now < s.until ? s.until : null;
44
+ }
45
+ /**
46
+ * Record a failure. Only a rate-limit error suspends, and only the failing
47
+ * budget: a REST failure never suspends the GraphQL bucket. A fresh
48
+ * suspension runs the reset probe at most once; a credible probe result
49
+ * (budget confirmed gone) sets the true reset instant, even if that is
50
+ * earlier than the fallback window.
51
+ */
52
+ noteFailure(budget, backend, cwd, errorText, now) {
53
+ if (!isRateLimitError(errorText))
54
+ return false;
55
+ const existing = this.suspensions.get(budget);
56
+ if (existing && now < existing.until)
57
+ return true;
58
+ const suspension = { startedAt: now, until: now + SUSPENSION_FALLBACK_MS };
59
+ this.suspensions.set(budget, suspension);
60
+ const probe = this.probe;
61
+ if (probe && backend === 'gh') {
62
+ Promise.resolve()
63
+ .then(() => probe(backend, cwd))
64
+ .then(result => this.applyProbe(budget, suspension, result))
65
+ .catch(() => { });
66
+ }
67
+ return true;
68
+ }
69
+ /**
70
+ * A success clears a suspension only if it was dispatched strictly after the
71
+ * suspension began: a batch dispatched in one tick shares a millisecond with
72
+ * the failure that suspended it, and its successes are not evidence of recovery.
73
+ */
74
+ noteSuccess(budget, dispatchedAt) {
75
+ const s = this.suspensions.get(budget);
76
+ if (s && dispatchedAt > s.startedAt)
77
+ this.suspensions.delete(budget);
78
+ }
79
+ /** Honour a credible probe: the true reset instant wins over the fallback in both directions. */
80
+ applyProbe(budget, suspension, result) {
81
+ if (!result || result.remaining > 0)
82
+ return;
83
+ if (this.suspensions.get(budget) !== suspension)
84
+ return;
85
+ if (result.resetAt > suspension.startedAt)
86
+ suspension.until = result.resetAt;
87
+ }
88
+ }
89
+ //# sourceMappingURL=forge-rate-limit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forge-rate-limit.js","sourceRoot":"","sources":["../../src/lib/forge-rate-limit.ts"],"names":[],"mappings":"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"}
@@ -39,7 +39,7 @@ export interface ConceptResolution {
39
39
  executable: string | null;
40
40
  }
41
41
  /**
42
- * Resolve all 15 concepts with their source and executable.
42
+ * Resolve every known concept with its source and executable.
43
43
  * Used by `codev doctor` for full concept reporting.
44
44
  */
45
45
  export declare function resolveAllConcepts(forgeConfig?: ForgeConfig | null): ConceptResolution[];
@@ -73,6 +73,34 @@ export declare function isConceptDisabled(concept: string, forgeConfig?: ForgeCo
73
73
  * @returns Parsed JSON from stdout, raw string for non-JSON concepts, or null on failure
74
74
  */
75
75
  export declare function executeForgeCommand(concept: string, env?: Record<string, string>, options?: ForgeCommandOptions): Promise<unknown | null>;
76
+ /** Why a forge command produced no data (#1645). `null` on the result means it exited 0. */
77
+ export interface ForgeCommandError {
78
+ message: string;
79
+ stderr: string;
80
+ /** Process exit code; null when the command was disabled, timed out, or config failed to load. */
81
+ exitCode: number | null;
82
+ }
83
+ export interface ForgeCommandResult {
84
+ data: unknown | null;
85
+ error: ForgeCommandError | null;
86
+ }
87
+ /**
88
+ * Like `executeForgeCommand`, but keeps the failure (#1645). Callers that must
89
+ * tell "rate limited" from "CLI missing" need stderr and the exit code; the
90
+ * plain variant collapses every failure to `null`. Never throws — a malformed
91
+ * `.codev/config.json` is reported as an error, not raised into Tower's
92
+ * `unhandledRejection` handler.
93
+ */
94
+ export declare function executeForgeCommandDetailed(concept: string, env?: Record<string, string>, options?: ForgeCommandOptions): Promise<ForgeCommandResult>;
95
+ /**
96
+ * The backend a concept actually spends budget on (#1645): the resolved
97
+ * executable's lowercased basename (`gh`, whether configured as `gh` or
98
+ * `/usr/local/bin/gh`), never the configured provider — a Linear workspace's
99
+ * `pr-list` falls through to the GitHub script and spends GitHub's budget.
100
+ * Generic transports and custom script paths key by provider instead.
101
+ * Returns null when the concept is disabled or unknown.
102
+ */
103
+ export declare function resolveForgeBackend(concept: string, options?: ForgeCommandOptions): string | null;
76
104
  /**
77
105
  * Execute a forge concept command synchronously.
78
106
  *
@@ -1 +1 @@
1
- {"version":3,"file":"forge.d.ts","sourceRoot":"","sources":["../../src/lib/forge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AA8BH,oGAAoG;AACpG,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhF,2CAA2C;AAC3C,MAAM,WAAW,mBAAmB;IAClC,+CAA+C;IAC/C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,6FAA6F;IAC7F,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,yEAAyE;IACzE,WAAW,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC,uEAAuE;IACvE,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA6ED,gCAAgC;AAChC,wBAAgB,iBAAiB,IAAI,MAAM,EAAE,CAE5C;AAED,+CAA+C;AAC/C,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC;AAE3E,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,CAAC,EAAE,WAAW,GAAG,IAAI,GAAG,iBAAiB,EAAE,CA4BxF;AAmDD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,aAAa,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAGzE;AAUD;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,WAAW,GAAG,IAAI,GAC/B,MAAM,GAAG,IAAI,CAgBf;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,WAAW,GAAG,IAAI,GAC/B,OAAO,CAGT;AAMD;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,MAAM,EACf,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAuBzB;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EACf,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,GAAG,IAAI,CAyBhB;AAoDD;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAE3C;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEhE;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,WAAW,GACvB;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,IAAI,GAAG,UAAU,GAAG,iBAAiB,GAAG,eAAe,GAAG,UAAU,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAAE,CA2BtH"}
1
+ {"version":3,"file":"forge.d.ts","sourceRoot":"","sources":["../../src/lib/forge.ts"],"names":[],"mappings":"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"}