@indigoai-us/hq-cli 5.313.0 → 5.314.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 (1174) hide show
  1. package/CHANGELOG.md +1 -4300
  2. package/assets/scaffold/core/scripts/checkpoint-stop-gate.sh +43 -281
  3. package/assets/scaffold/core/scripts/hook-lib.sh +50 -345
  4. package/assets/scaffold/core/scripts/hq-session.sh +23 -184
  5. package/assets/scaffold/core/scripts/lib/session-id.sh +2 -3
  6. package/assets/scaffold/core/scripts/lib/session-scope-capability.sh +1 -1
  7. package/assets/scaffold/core/scripts/lib/work-mesh-enqueue.sh +1 -2
  8. package/assets/scaffold/core/scripts/qmd-reindex-after-sync.sh +87 -10
  9. package/assets/scaffold/core/scripts/rebuild-company-knowledge-index.sh +3 -36
  10. package/assets/scaffold/core/scripts/rebuild-projects-index.sh +12 -99
  11. package/assets/scaffold/core/scripts/token-usage-report.sh +20 -81
  12. package/dist/bin/hq-auth-refresh.d.ts +0 -2
  13. package/dist/bin/hq-auth-refresh.js +6 -12
  14. package/dist/commands/__fixtures__/access-vault.d.ts +0 -2
  15. package/dist/commands/__fixtures__/access-vault.js +1 -1
  16. package/dist/commands/_patterns.d.ts +0 -16
  17. package/dist/commands/_patterns.js +3 -20
  18. package/dist/commands/access.d.ts +1 -2
  19. package/dist/commands/access.js +49 -58
  20. package/dist/commands/agents.d.ts +4 -106
  21. package/dist/commands/agents.js +45 -924
  22. package/dist/commands/auth.d.ts +0 -1
  23. package/dist/commands/auth.js +19 -189
  24. package/dist/commands/billing.d.ts +0 -3
  25. package/dist/commands/billing.js +1 -6
  26. package/dist/commands/channels.js +1 -56
  27. package/dist/commands/cloud-demote.js +2 -3
  28. package/dist/commands/cloud-provision.d.ts +0 -14
  29. package/dist/commands/cloud-provision.js +58 -232
  30. package/dist/commands/cloud.d.ts +15 -49
  31. package/dist/commands/cloud.js +122 -357
  32. package/dist/commands/company-transfer.d.ts +28 -4
  33. package/dist/commands/company-transfer.js +49 -5
  34. package/dist/commands/company.js +3 -68
  35. package/dist/commands/core-checkpoint.d.ts +9 -19
  36. package/dist/commands/core-checkpoint.js +37 -301
  37. package/dist/commands/core.d.ts +0 -4
  38. package/dist/commands/core.js +80 -277
  39. package/dist/commands/crm.js +3 -52
  40. package/dist/commands/db-provision.js +4 -4
  41. package/dist/commands/db-sql.js +21 -7
  42. package/dist/commands/dm.d.ts +12 -119
  43. package/dist/commands/dm.js +38 -388
  44. package/dist/commands/doctor.d.ts +0 -12
  45. package/dist/commands/doctor.js +12 -158
  46. package/dist/commands/feedback.d.ts +0 -6
  47. package/dist/commands/feedback.js +37 -86
  48. package/dist/commands/files-browse.d.ts +12 -32
  49. package/dist/commands/files-browse.js +60 -176
  50. package/dist/commands/files.d.ts +0 -17
  51. package/dist/commands/files.js +47 -300
  52. package/dist/commands/group-grants.js +2 -3
  53. package/dist/commands/groups.js +5 -6
  54. package/dist/commands/index-cmd.d.ts +1 -19
  55. package/dist/commands/index-cmd.js +7 -74
  56. package/dist/commands/integrations-api.d.ts +10 -15
  57. package/dist/commands/integrations-api.js +22 -27
  58. package/dist/commands/integrations-connect.d.ts +13 -51
  59. package/dist/commands/integrations-connect.js +71 -86
  60. package/dist/commands/integrations-core.d.ts +6 -6
  61. package/dist/commands/integrations-core.js +11 -25
  62. package/dist/commands/integrations-import.d.ts +1 -1
  63. package/dist/commands/integrations-import.js +24 -43
  64. package/dist/commands/integrations-manage.js +13 -20
  65. package/dist/commands/integrations.d.ts +0 -8
  66. package/dist/commands/integrations.js +7 -94
  67. package/dist/commands/login.js +6 -49
  68. package/dist/commands/mcp-registration.d.ts +25 -32
  69. package/dist/commands/mcp-registration.js +23 -256
  70. package/dist/commands/mcp-status.js +0 -1
  71. package/dist/commands/meetings.js +34 -55
  72. package/dist/commands/members.js +1 -5
  73. package/dist/commands/mesh.d.ts +0 -11
  74. package/dist/commands/mesh.js +76 -1086
  75. package/dist/commands/onboard-identity-guard.d.ts +1 -1
  76. package/dist/commands/onboard.js +5 -24
  77. package/dist/commands/pack-install.js +1 -3
  78. package/dist/commands/packs.js +1 -11
  79. package/dist/commands/people.d.ts +0 -4
  80. package/dist/commands/people.js +3 -37
  81. package/dist/commands/publish.d.ts +1 -8
  82. package/dist/commands/publish.js +4 -17
  83. package/dist/commands/reindex.js +6 -56
  84. package/dist/commands/rescue.d.ts +0 -4
  85. package/dist/commands/rescue.js +17 -27
  86. package/dist/commands/run.js +4 -18
  87. package/dist/commands/safe-extract.d.ts +2 -11
  88. package/dist/commands/safe-extract.js +8 -36
  89. package/dist/commands/scaffold-fast.d.ts +41 -0
  90. package/dist/commands/scaffold-fast.js +57 -0
  91. package/dist/commands/secrets.d.ts +2 -20
  92. package/dist/commands/secrets.js +71 -175
  93. package/dist/commands/skill.d.ts +4 -35
  94. package/dist/commands/skill.js +18 -357
  95. package/dist/commands/sync-mode.d.ts +0 -11
  96. package/dist/commands/sync-mode.js +0 -30
  97. package/dist/commands/sync-narrow.js +5 -36
  98. package/dist/commands/team-sync.js +10 -71
  99. package/dist/commands/update.js +0 -6
  100. package/dist/commands/whoami.d.ts +0 -22
  101. package/dist/commands/whoami.js +4 -137
  102. package/dist/commands/workers.d.ts +14 -2
  103. package/dist/commands/workers.js +10 -7
  104. package/dist/fast-core.d.ts +7 -6
  105. package/dist/fast-core.js +24 -87
  106. package/dist/index.d.ts +4 -3
  107. package/dist/index.js +9 -59
  108. package/dist/lazy-commands.d.ts +44 -20
  109. package/dist/lazy-commands.js +58 -60
  110. package/dist/lib/company-skill-wrapper.d.ts +0 -1
  111. package/dist/lib/company-skill-wrapper.js +29 -121
  112. package/dist/lib/core-utils/codex-skill-bridge.d.ts +1 -2
  113. package/dist/lib/core-utils/qmd-reindex-after-sync.d.ts +1 -14
  114. package/dist/lib/core-utils/qmd-reindex-after-sync.js +17 -101
  115. package/dist/lib/core-utils/soft-timeout.js +1 -1
  116. package/dist/lib/core-utils/timeout-guard.d.ts +3 -3
  117. package/dist/lib/core-utils/timeout-guard.js +13 -28
  118. package/dist/lib/core-utils/token-usage-report.js +3 -17
  119. package/dist/lib/db/control-plane.js +0 -6
  120. package/dist/lib/db/local.d.ts +5 -0
  121. package/dist/lib/db/local.js +1 -1
  122. package/dist/lib/db/migrate.d.ts +12 -0
  123. package/dist/lib/db/migrate.js +5 -5
  124. package/dist/lib/db/remote-sql.d.ts +2 -2
  125. package/dist/lib/db/remote-sql.js +3 -3
  126. package/dist/lib/db/sql.d.ts +10 -0
  127. package/dist/lib/db/sql.js +8 -4
  128. package/dist/lib/doctor/__testing__/fake-hq-tree.d.ts +1 -1
  129. package/dist/lib/doctor/__testing__/fake-hq-tree.js +1 -1
  130. package/dist/lib/doctor/checks/claude-wiring.js +1 -70
  131. package/dist/lib/doctor/checks/codex-wiring.d.ts +4 -0
  132. package/dist/lib/doctor/checks/codex-wiring.js +35 -3
  133. package/dist/lib/doctor/checks/grok-wiring.js +34 -1
  134. package/dist/lib/doctor/checks/integrations.js +0 -11
  135. package/dist/lib/doctor/checks/runtime-health.d.ts +17 -4
  136. package/dist/lib/doctor/checks/runtime-health.js +7 -20
  137. package/dist/lib/doctor/checks/sync-health.d.ts +0 -21
  138. package/dist/lib/doctor/checks/sync-health.js +2 -72
  139. package/dist/lib/doctor/checks/work-context.js +6 -20
  140. package/dist/lib/doctor/compat.d.ts +16 -0
  141. package/dist/lib/doctor/compat.js +3 -4
  142. package/dist/lib/doctor/deep/effects.js +3 -1
  143. package/dist/lib/doctor/deep/executor.d.ts +10 -4
  144. package/dist/lib/doctor/deep/executor.js +1 -1
  145. package/dist/lib/doctor/deep/parity.d.ts +29 -2
  146. package/dist/lib/doctor/deep/parity.js +7 -7
  147. package/dist/lib/doctor/deep/sandbox.d.ts +25 -7
  148. package/dist/lib/doctor/deep/sandbox.js +7 -5
  149. package/dist/lib/doctor/fix/apply.d.ts +8 -79
  150. package/dist/lib/doctor/fix/apply.js +80 -292
  151. package/dist/lib/doctor/fix/remediation.d.ts +6 -14
  152. package/dist/lib/doctor/fix/remediation.js +9 -49
  153. package/dist/lib/doctor/fixtures/schema.js +3 -1
  154. package/dist/lib/doctor/json-output.d.ts +1 -17
  155. package/dist/lib/doctor/json-output.js +2 -7
  156. package/dist/lib/doctor/platform.d.ts +26 -0
  157. package/dist/lib/doctor/platform.js +5 -5
  158. package/dist/lib/doctor/registry.d.ts +0 -14
  159. package/dist/lib/doctor/registry.js +0 -71
  160. package/dist/lib/doctor/report.js +1 -1
  161. package/dist/lib/doctor/types.d.ts +0 -5
  162. package/dist/lib/doctor/types.js +0 -20
  163. package/dist/lib/flag-registry-worker.js +1 -12
  164. package/dist/lib/flag-registry.d.ts +6 -26
  165. package/dist/lib/flag-registry.js +16 -133
  166. package/dist/lib/index-render/companies.d.ts +1 -4
  167. package/dist/lib/index-render/companies.js +3 -66
  168. package/dist/lib/index-render/company-knowledge.js +17 -80
  169. package/dist/lib/index-render/index.d.ts +0 -1
  170. package/dist/lib/index-render/index.js +1 -2
  171. package/dist/lib/index-render/projects.js +5 -82
  172. package/dist/lib/index-render/shared.d.ts +1 -13
  173. package/dist/lib/index-render/shared.js +2 -41
  174. package/dist/lib/mesh/api.d.ts +10 -103
  175. package/dist/lib/mesh/api.js +64 -334
  176. package/dist/lib/mesh/client.d.ts +2 -3
  177. package/dist/lib/mesh/client.js +7 -26
  178. package/dist/lib/mesh/live/backfill-held.d.ts +16 -67
  179. package/dist/lib/mesh/live/backfill-held.js +61 -415
  180. package/dist/lib/mesh/live/backoff.d.ts +2 -2
  181. package/dist/lib/mesh/live/backoff.js +3 -16
  182. package/dist/lib/mesh/live/daemon/board-refresh.d.ts +1 -7
  183. package/dist/lib/mesh/live/daemon/board-refresh.js +30 -78
  184. package/dist/lib/mesh/live/daemon/credentials.d.ts +10 -64
  185. package/dist/lib/mesh/live/daemon/credentials.js +20 -270
  186. package/dist/lib/mesh/live/daemon/doctor.d.ts +0 -53
  187. package/dist/lib/mesh/live/daemon/doctor.js +6 -190
  188. package/dist/lib/mesh/live/daemon/index.d.ts +10 -13
  189. package/dist/lib/mesh/live/daemon/index.js +6 -7
  190. package/dist/lib/mesh/live/daemon/install.d.ts +1 -255
  191. package/dist/lib/mesh/live/daemon/install.js +13 -811
  192. package/dist/lib/mesh/live/daemon/paths.d.ts +0 -2
  193. package/dist/lib/mesh/live/daemon/paths.js +0 -2
  194. package/dist/lib/mesh/live/daemon/presence.d.ts +5 -24
  195. package/dist/lib/mesh/live/daemon/presence.js +10 -79
  196. package/dist/lib/mesh/live/daemon/run.d.ts +2 -48
  197. package/dist/lib/mesh/live/daemon/run.js +33 -485
  198. package/dist/lib/mesh/live/daemon/state.d.ts +2 -19
  199. package/dist/lib/mesh/live/daemon/state.js +2 -34
  200. package/dist/lib/mesh/live/daemon/transcript-watch.d.ts +9 -45
  201. package/dist/lib/mesh/live/daemon/transcript-watch.js +31 -227
  202. package/dist/lib/mesh/live/emit-client.d.ts +0 -8
  203. package/dist/lib/mesh/live/emit-client.js +8 -23
  204. package/dist/lib/mesh/live/emit-evidence.d.ts +0 -19
  205. package/dist/lib/mesh/live/emit-evidence.js +2 -20
  206. package/dist/lib/mesh/live/emit.d.ts +0 -9
  207. package/dist/lib/mesh/live/emit.js +2 -28
  208. package/dist/lib/mesh/live/enqueue.d.ts +0 -5
  209. package/dist/lib/mesh/live/enqueue.js +0 -19
  210. package/dist/lib/mesh/live/flush.d.ts +5 -17
  211. package/dist/lib/mesh/live/flush.js +38 -391
  212. package/dist/lib/mesh/live/format-spool-line.d.ts +2 -5
  213. package/dist/lib/mesh/live/format-spool-line.js +0 -10
  214. package/dist/lib/mesh/live/paths.d.ts +0 -2
  215. package/dist/lib/mesh/live/paths.js +0 -4
  216. package/dist/lib/mesh/live/session-event.schema.json +1 -24
  217. package/dist/lib/mesh/live/session-events-client.d.ts +0 -2
  218. package/dist/lib/mesh/live/session-events-client.js +0 -26
  219. package/dist/lib/mesh/live/spool.d.ts +0 -19
  220. package/dist/lib/mesh/live/spool.js +3 -269
  221. package/dist/lib/mesh/live/validate-session-event.d.ts +1 -1
  222. package/dist/lib/mesh/live/validate-session-event.js +1 -1
  223. package/dist/lib/plan-limit-nag.d.ts +6 -102
  224. package/dist/lib/plan-limit-nag.js +43 -348
  225. package/dist/lib/scan-packages/index.d.ts +0 -2
  226. package/dist/lib/scan-packages/index.js +6 -168
  227. package/dist/lib/search-index/background.d.ts +1 -8
  228. package/dist/lib/search-index/background.js +200 -55
  229. package/dist/lib/search-index/index.d.ts +0 -12
  230. package/dist/lib/search-index/index.js +7 -153
  231. package/dist/lib/work-context/company.d.ts +20 -22
  232. package/dist/lib/work-context/company.js +40 -124
  233. package/dist/lib/work-context/config.d.ts +11 -58
  234. package/dist/lib/work-context/config.js +83 -334
  235. package/dist/lib/work-context/contract.d.ts +0 -13
  236. package/dist/lib/work-context/contract.schema.json +1 -3
  237. package/dist/lib/work-context/index.d.ts +25 -0
  238. package/dist/lib/work-context/index.js +21 -0
  239. package/dist/lib/work-context/outbox.d.ts +5 -27
  240. package/dist/lib/work-context/outbox.js +6 -135
  241. package/dist/lib/work-context/reconcile.d.ts +0 -15
  242. package/dist/lib/work-context/reconcile.js +29 -405
  243. package/dist/lib/work-context/state.d.ts +10 -93
  244. package/dist/lib/work-context/state.js +29 -342
  245. package/dist/lib/workers-registry/index.js +8 -62
  246. package/dist/main.d.ts +0 -32
  247. package/dist/main.js +73 -273
  248. package/dist/node-network-compat.d.ts +30 -2
  249. package/dist/node-network-compat.js +51 -4
  250. package/dist/node-preflight.d.ts +1 -7
  251. package/dist/node-preflight.js +5 -5
  252. package/dist/register-all.d.ts +29 -4
  253. package/dist/register-all.js +233 -4
  254. package/dist/run/discover-schemas.d.ts +1 -2
  255. package/dist/run/env-graph-guard.d.ts +2 -2
  256. package/dist/run/env-graph-guard.js +2 -5
  257. package/dist/run/hq-plugin.d.ts +0 -4
  258. package/dist/run/hq-plugin.js +8 -36
  259. package/dist/sentry-before-send.js +0 -80
  260. package/dist/sentry.d.ts +2 -8
  261. package/dist/sentry.js +13 -117
  262. package/dist/startup-registration.d.ts +2 -26
  263. package/dist/startup-registration.js +15 -116
  264. package/dist/utils/cli-telemetry.d.ts +1 -74
  265. package/dist/utils/cli-telemetry.js +7 -434
  266. package/dist/utils/client-health.d.ts +4 -0
  267. package/dist/utils/client-health.js +2 -2
  268. package/dist/utils/cognito-session.d.ts +0 -71
  269. package/dist/utils/cognito-session.js +27 -481
  270. package/dist/utils/contribution-table.d.ts +1 -1
  271. package/dist/utils/environmental-error.d.ts +0 -18
  272. package/dist/utils/environmental-error.js +7 -240
  273. package/dist/utils/expected-cli-error.d.ts +0 -2
  274. package/dist/utils/expected-cli-error.js +0 -4
  275. package/dist/utils/feedback-diagnostics.d.ts +1 -2
  276. package/dist/utils/feedback-log-bundle.d.ts +26 -51
  277. package/dist/utils/feedback-log-bundle.js +31 -211
  278. package/dist/utils/feedback-logs.d.ts +47 -18
  279. package/dist/utils/feedback-logs.js +21 -50
  280. package/dist/utils/feedback-screenshots.d.ts +1 -0
  281. package/dist/utils/feedback-screenshots.js +1 -1
  282. package/dist/utils/hq-roots.d.ts +2 -25
  283. package/dist/utils/hq-roots.js +7 -67
  284. package/dist/utils/incomplete-install-error.d.ts +19 -87
  285. package/dist/utils/incomplete-install-error.js +68 -319
  286. package/dist/utils/install-tree-torn.d.ts +24 -260
  287. package/dist/utils/install-tree-torn.js +51 -998
  288. package/dist/utils/large-file-guard.d.ts +10 -0
  289. package/dist/utils/large-file-guard.js +1 -1
  290. package/dist/utils/local-files-overview.d.ts +8 -4
  291. package/dist/utils/local-files-overview.js +7 -48
  292. package/dist/utils/login-provider.d.ts +0 -7
  293. package/dist/utils/login-provider.js +0 -34
  294. package/dist/utils/pack-contributions.d.ts +14 -2
  295. package/dist/utils/pack-contributions.js +44 -7
  296. package/dist/utils/package-root-diagnostics.d.ts +1 -1
  297. package/dist/utils/people.d.ts +11 -7
  298. package/dist/utils/people.js +20 -5
  299. package/dist/utils/plan-gate-error.d.ts +10 -52
  300. package/dist/utils/plan-gate-error.js +41 -364
  301. package/dist/utils/qmd-model-download-error.d.ts +8 -0
  302. package/dist/utils/qmd-model-download-error.js +1 -1
  303. package/dist/utils/qmd-query-document-error.d.ts +6 -0
  304. package/dist/utils/qmd-query-document-error.js +1 -1
  305. package/dist/utils/redact-error-text.d.ts +2 -0
  306. package/dist/utils/redact-error-text.js +2 -3
  307. package/dist/utils/run-bundled-script.d.ts +0 -6
  308. package/dist/utils/run-bundled-script.js +4 -117
  309. package/dist/utils/sandbox-runner-client.d.ts +1 -2
  310. package/dist/utils/secrets-cache.d.ts +3 -7
  311. package/dist/utils/secrets-cache.js +14 -162
  312. package/dist/utils/self-update.d.ts +1 -34
  313. package/dist/utils/self-update.js +42 -660
  314. package/dist/utils/sentry-fingerprint.d.ts +1 -23
  315. package/dist/utils/sentry-fingerprint.js +31 -223
  316. package/dist/utils/team-upgrade.d.ts +1 -1
  317. package/dist/utils/team-upgrade.js +3 -4
  318. package/dist/utils/vault-api.d.ts +1 -21
  319. package/dist/utils/vault-api.js +84 -251
  320. package/dist/utils/version-check.d.ts +1 -11
  321. package/dist/utils/version-check.js +3 -32
  322. package/dist/utils/version-gate.d.ts +17 -101
  323. package/dist/utils/version-gate.js +70 -645
  324. package/dist/utils/windows-spawn.d.ts +0 -6
  325. package/dist/utils/windows-spawn.js +0 -37
  326. package/package.json +8 -20
  327. package/README.md +0 -113
  328. package/assets/bot-workers/setup/context/USER-GUIDE.md +0 -404
  329. package/assets/bot-workers/setup/context/quick-reference.md +0 -199
  330. package/assets/bot-workers/setup/skills/agents-and-team.md +0 -167
  331. package/assets/bot-workers/setup/skills/explain-hq.md +0 -35
  332. package/assets/bot-workers/setup/skills/first-company.md +0 -74
  333. package/assets/bot-workers/setup/skills/joining-a-team.md +0 -125
  334. package/assets/bot-workers/setup/skills/pricing.md +0 -92
  335. package/assets/bot-workers/setup/skills/standing-help.md +0 -81
  336. package/assets/bot-workers/setup/skills/your-business.md +0 -281
  337. package/assets/bot-workers/setup/worker.yaml +0 -791
  338. package/assets/lanes-hooks/hq-lanes-drain.json +0 -15
  339. package/assets/lanes-hooks/hq-lanes-drain.mjs +0 -275
  340. package/assets/lanes-hooks/hq-lanes-drain.sh +0 -21
  341. package/assets/lanes-reconcile/hq-lanes-reconcile.service +0 -11
  342. package/assets/lanes-reconcile/hq-lanes-reconcile.timer +0 -12
  343. package/assets/scaffold/.claude/hooks/validate-policy-frontmatter.sh +0 -485
  344. package/assets/scaffold/core/scripts/audit-log.sh +0 -384
  345. package/assets/scaffold/core/scripts/clean-worktree-reconcile-handoff.sh +0 -171
  346. package/assets/scaffold/core/scripts/eval-trigger.sh +0 -193
  347. package/assets/scaffold/core/scripts/git-pack-extension-check.sh +0 -164
  348. package/assets/scaffold/core/scripts/handoff-finalize.sh +0 -688
  349. package/assets/scaffold/core/scripts/handoff-open-steps.sh +0 -81
  350. package/assets/scaffold/core/scripts/handoff-post.sh +0 -252
  351. package/assets/scaffold/core/scripts/hq-delegate-bundle.sh +0 -307
  352. package/assets/scaffold/core/scripts/hq-delegate-grant.sh +0 -252
  353. package/assets/scaffold/core/scripts/hq-delegate-pickup.sh +0 -99
  354. package/assets/scaffold/core/scripts/hq-delegate-publish.sh +0 -91
  355. package/assets/scaffold/core/scripts/hq-delegate-repo.sh +0 -158
  356. package/assets/scaffold/core/scripts/hq-delegate-resolve.sh +0 -145
  357. package/assets/scaffold/core/scripts/hq-delegate-secrets.sh +0 -129
  358. package/assets/scaffold/core/scripts/hq-delegate-send.sh +0 -259
  359. package/assets/scaffold/core/scripts/hq-delegate-transfer.sh +0 -175
  360. package/assets/scaffold/core/scripts/hq-delegate-verify.sh +0 -238
  361. package/assets/scaffold/core/scripts/hq-dm-bind.sh +0 -585
  362. package/assets/scaffold/core/scripts/hq-job-notify.sh +0 -389
  363. package/assets/scaffold/core/scripts/hq-job-probe.sh +0 -835
  364. package/assets/scaffold/core/scripts/hq-job-remediate.sh +0 -359
  365. package/assets/scaffold/core/scripts/hq-job-run.sh +0 -1025
  366. package/assets/scaffold/core/scripts/hq-pin.sh +0 -118
  367. package/assets/scaffold/core/scripts/jobs-schedule-parse.sh +0 -310
  368. package/assets/scaffold/core/scripts/jobs-validate.sh +0 -451
  369. package/assets/scaffold/core/scripts/knowledge-prefs.sh +0 -55
  370. package/assets/scaffold/core/scripts/lib/portable.sh +0 -211
  371. package/assets/scaffold/core/scripts/lib/secret-patterns.sh +0 -58
  372. package/assets/scaffold/core/scripts/lib/work-mesh-live-hook.sh +0 -378
  373. package/assets/scaffold/core/scripts/lib/work-mesh-live-rebind.sh +0 -141
  374. package/assets/scaffold/core/scripts/migrate-policy-triggers.sh +0 -373
  375. package/assets/scaffold/core/scripts/ontology-audience-grant.sh +0 -81
  376. package/assets/scaffold/core/scripts/ontology-brief.mjs +0 -93
  377. package/assets/scaffold/core/scripts/ontology-candidate.sh +0 -100
  378. package/assets/scaffold/core/scripts/ontology-garden.mjs +0 -238
  379. package/assets/scaffold/core/scripts/ontology-source-worklist.sh +0 -79
  380. package/assets/scaffold/core/scripts/outpost-jobs-reconcile.sh +0 -834
  381. package/assets/scaffold/core/scripts/policy-age-report.sh +0 -156
  382. package/assets/scaffold/core/scripts/policy-retire.sh +0 -199
  383. package/assets/scaffold/core/scripts/qmd-reindex-bg.sh +0 -40
  384. package/assets/scaffold/core/scripts/read-policy-frontmatter.sh +0 -32
  385. package/assets/scaffold/core/scripts/refresh-vault-access.sh +0 -188
  386. package/assets/scaffold/core/scripts/register-project.sh +0 -262
  387. package/assets/scaffold/core/scripts/resolve-company.sh +0 -199
  388. package/assets/scaffold/core/scripts/resume-thread-lock.sh +0 -285
  389. package/assets/scaffold/core/scripts/source-yaml-validate.sh +0 -36
  390. package/assets/scaffold/core/scripts/verify-story-deliverables.sh +0 -148
  391. package/assets/scaffold/core/scripts/work-mesh-live-bind-trusted.sh +0 -152
  392. package/assets/scaffold/core/scripts/work-mesh-live-rebind.sh +0 -59
  393. package/assets/scaffold/core/scripts/worktree-gc.sh +0 -362
  394. package/contracts/preflight/v1/fixtures.json +0 -87
  395. package/contracts/preflight/v1/schema.json +0 -58
  396. package/dist/command-catalog.generated.d.ts +0 -10735
  397. package/dist/command-catalog.generated.js +0 -13836
  398. package/dist/command-registration-plan.d.ts +0 -474
  399. package/dist/command-registration-plan.js +0 -136
  400. package/dist/commands/agent-enroll.d.ts +0 -146
  401. package/dist/commands/agent-enroll.js +0 -401
  402. package/dist/commands/agent-inbox.d.ts +0 -9
  403. package/dist/commands/agent-inbox.js +0 -102
  404. package/dist/commands/agent-kit.d.ts +0 -87
  405. package/dist/commands/agent-kit.js +0 -480
  406. package/dist/commands/agent-mcp.d.ts +0 -24
  407. package/dist/commands/agent-mcp.js +0 -127
  408. package/dist/commands/agent-probe.d.ts +0 -77
  409. package/dist/commands/agent-probe.js +0 -335
  410. package/dist/commands/agent.d.ts +0 -13
  411. package/dist/commands/agent.js +0 -40
  412. package/dist/commands/billing-sponsor.d.ts +0 -83
  413. package/dist/commands/billing-sponsor.js +0 -344
  414. package/dist/commands/bot-companies.d.ts +0 -40
  415. package/dist/commands/bot-companies.js +0 -64
  416. package/dist/commands/bot-continuity.d.ts +0 -28
  417. package/dist/commands/bot-continuity.js +0 -68
  418. package/dist/commands/bot-jobs.d.ts +0 -127
  419. package/dist/commands/bot-jobs.js +0 -454
  420. package/dist/commands/bot.d.ts +0 -278
  421. package/dist/commands/bot.js +0 -1982
  422. package/dist/commands/cloud-retire.d.ts +0 -51
  423. package/dist/commands/cloud-retire.js +0 -154
  424. package/dist/commands/company-rename-flag.d.ts +0 -4
  425. package/dist/commands/company-rename-flag.js +0 -7
  426. package/dist/commands/company-rename.d.ts +0 -4
  427. package/dist/commands/company-rename.js +0 -90
  428. package/dist/commands/core-audit-log-native.d.ts +0 -9
  429. package/dist/commands/core-audit-log-native.js +0 -257
  430. package/dist/commands/core-checkpoint-gate-setting.d.ts +0 -59
  431. package/dist/commands/core-checkpoint-gate-setting.js +0 -163
  432. package/dist/commands/core-checkpoint-stop-gate-native.d.ts +0 -34
  433. package/dist/commands/core-checkpoint-stop-gate-native.js +0 -725
  434. package/dist/commands/core-command-catalog.d.ts +0 -34
  435. package/dist/commands/core-command-catalog.js +0 -62
  436. package/dist/commands/core-company-index-scope-flag.d.ts +0 -3
  437. package/dist/commands/core-company-index-scope-flag.js +0 -6
  438. package/dist/commands/core-delegate-w1b.d.ts +0 -10
  439. package/dist/commands/core-delegate-w1b.js +0 -1219
  440. package/dist/commands/core-delegate.d.ts +0 -46
  441. package/dist/commands/core-delegate.js +0 -1040
  442. package/dist/commands/core-dm-bind-native.d.ts +0 -32
  443. package/dist/commands/core-dm-bind-native.js +0 -668
  444. package/dist/commands/core-eval-trigger-native.d.ts +0 -4
  445. package/dist/commands/core-eval-trigger-native.js +0 -12
  446. package/dist/commands/core-git-pack-extension-check-native.d.ts +0 -22
  447. package/dist/commands/core-git-pack-extension-check-native.js +0 -190
  448. package/dist/commands/core-handoff-fast.d.ts +0 -18
  449. package/dist/commands/core-handoff-fast.js +0 -104
  450. package/dist/commands/core-handoff-open-steps.d.ts +0 -21
  451. package/dist/commands/core-handoff-open-steps.js +0 -264
  452. package/dist/commands/core-handoff.d.ts +0 -24
  453. package/dist/commands/core-handoff.js +0 -1144
  454. package/dist/commands/core-hq-session-native.d.ts +0 -39
  455. package/dist/commands/core-hq-session-native.js +0 -579
  456. package/dist/commands/core-job-native-utils.d.ts +0 -6
  457. package/dist/commands/core-job-native-utils.js +0 -80
  458. package/dist/commands/core-job-native.d.ts +0 -5
  459. package/dist/commands/core-job-native.js +0 -16
  460. package/dist/commands/core-job-notify-native.d.ts +0 -36
  461. package/dist/commands/core-job-notify-native.js +0 -359
  462. package/dist/commands/core-job-probe-native.d.ts +0 -45
  463. package/dist/commands/core-job-probe-native.js +0 -564
  464. package/dist/commands/core-job-remediate-native.d.ts +0 -26
  465. package/dist/commands/core-job-remediate-native.js +0 -374
  466. package/dist/commands/core-job-remote-launcher.d.ts +0 -7
  467. package/dist/commands/core-job-remote-launcher.js +0 -51
  468. package/dist/commands/core-job-run-native.d.ts +0 -47
  469. package/dist/commands/core-job-run-native.js +0 -1215
  470. package/dist/commands/core-jobs-native.d.ts +0 -25
  471. package/dist/commands/core-jobs-native.js +0 -1339
  472. package/dist/commands/core-knowledge-prefs.d.ts +0 -11
  473. package/dist/commands/core-knowledge-prefs.js +0 -137
  474. package/dist/commands/core-migrate-policy-triggers-native.d.ts +0 -21
  475. package/dist/commands/core-migrate-policy-triggers-native.js +0 -378
  476. package/dist/commands/core-native-handoff-flag.d.ts +0 -4
  477. package/dist/commands/core-native-handoff-flag.js +0 -7
  478. package/dist/commands/core-native-hook-helper-commands.d.ts +0 -4
  479. package/dist/commands/core-native-hook-helper-commands.js +0 -56
  480. package/dist/commands/core-native-hook-helpers-flag.d.ts +0 -4
  481. package/dist/commands/core-native-hook-helpers-flag.js +0 -7
  482. package/dist/commands/core-native-jobs-flag.d.ts +0 -4
  483. package/dist/commands/core-native-jobs-flag.js +0 -7
  484. package/dist/commands/core-native-policy-flag.d.ts +0 -9
  485. package/dist/commands/core-native-policy-flag.js +0 -12
  486. package/dist/commands/core-native-session-flag.d.ts +0 -4
  487. package/dist/commands/core-native-session-flag.js +0 -7
  488. package/dist/commands/core-native-utilities-flag.d.ts +0 -4
  489. package/dist/commands/core-native-utilities-flag.js +0 -7
  490. package/dist/commands/core-native-utilities.d.ts +0 -29
  491. package/dist/commands/core-native-utilities.js +0 -54
  492. package/dist/commands/core-native-worker-skills-flag.d.ts +0 -4
  493. package/dist/commands/core-native-worker-skills-flag.js +0 -7
  494. package/dist/commands/core-ontology-native.d.ts +0 -17
  495. package/dist/commands/core-ontology-native.js +0 -916
  496. package/dist/commands/core-ontology.d.ts +0 -66
  497. package/dist/commands/core-ontology.js +0 -430
  498. package/dist/commands/core-pin-native.d.ts +0 -14
  499. package/dist/commands/core-pin-native.js +0 -236
  500. package/dist/commands/core-policy-frontmatter.d.ts +0 -8
  501. package/dist/commands/core-policy-frontmatter.js +0 -52
  502. package/dist/commands/core-policy.d.ts +0 -14
  503. package/dist/commands/core-policy.js +0 -1018
  504. package/dist/commands/core-refresh-vault-access-native.d.ts +0 -20
  505. package/dist/commands/core-refresh-vault-access-native.js +0 -229
  506. package/dist/commands/core-register-project-native.d.ts +0 -30
  507. package/dist/commands/core-register-project-native.js +0 -347
  508. package/dist/commands/core-resolve-company-command.d.ts +0 -4
  509. package/dist/commands/core-resolve-company-command.js +0 -42
  510. package/dist/commands/core-resolve-company-native.d.ts +0 -28
  511. package/dist/commands/core-resolve-company-native.js +0 -408
  512. package/dist/commands/core-work-mesh-bind-trusted-native.d.ts +0 -32
  513. package/dist/commands/core-work-mesh-bind-trusted-native.js +0 -190
  514. package/dist/commands/core-work-mesh-live-rebind-native.d.ts +0 -18
  515. package/dist/commands/core-work-mesh-live-rebind-native.js +0 -262
  516. package/dist/commands/core-worker-lint-native.d.ts +0 -4
  517. package/dist/commands/core-worker-lint-native.js +0 -160
  518. package/dist/commands/core-worker-share-native.d.ts +0 -4
  519. package/dist/commands/core-worker-share-native.js +0 -260
  520. package/dist/commands/core-worker-skills-command.d.ts +0 -8
  521. package/dist/commands/core-worker-skills-command.js +0 -33
  522. package/dist/commands/core-worker-skills-runtime.d.ts +0 -33
  523. package/dist/commands/core-worker-skills-runtime.js +0 -86
  524. package/dist/commands/daemon.d.ts +0 -63
  525. package/dist/commands/daemon.js +0 -877
  526. package/dist/commands/deploy-comments.d.ts +0 -3
  527. package/dist/commands/deploy-comments.js +0 -162
  528. package/dist/commands/lanes-accounts.d.ts +0 -28
  529. package/dist/commands/lanes-accounts.js +0 -595
  530. package/dist/commands/lanes-autopilot.d.ts +0 -11
  531. package/dist/commands/lanes-autopilot.js +0 -336
  532. package/dist/commands/lanes-checks.d.ts +0 -51
  533. package/dist/commands/lanes-checks.js +0 -941
  534. package/dist/commands/lanes-hold.d.ts +0 -43
  535. package/dist/commands/lanes-hold.js +0 -655
  536. package/dist/commands/lanes-kpis.d.ts +0 -11
  537. package/dist/commands/lanes-kpis.js +0 -34
  538. package/dist/commands/lanes-message.d.ts +0 -9
  539. package/dist/commands/lanes-message.js +0 -937
  540. package/dist/commands/lanes-move.d.ts +0 -12
  541. package/dist/commands/lanes-move.js +0 -397
  542. package/dist/commands/lanes-questions.d.ts +0 -36
  543. package/dist/commands/lanes-questions.js +0 -1005
  544. package/dist/commands/lanes-report.d.ts +0 -11
  545. package/dist/commands/lanes-report.js +0 -333
  546. package/dist/commands/lanes-resume.d.ts +0 -6
  547. package/dist/commands/lanes-resume.js +0 -564
  548. package/dist/commands/lanes-review.d.ts +0 -10
  549. package/dist/commands/lanes-review.js +0 -56
  550. package/dist/commands/lanes-shared.d.ts +0 -448
  551. package/dist/commands/lanes-shared.js +0 -170
  552. package/dist/commands/lanes-stories.d.ts +0 -15
  553. package/dist/commands/lanes-stories.js +0 -347
  554. package/dist/commands/lanes-watch.d.ts +0 -7
  555. package/dist/commands/lanes-watch.js +0 -216
  556. package/dist/commands/lanes.d.ts +0 -149
  557. package/dist/commands/lanes.js +0 -8973
  558. package/dist/commands/monitor.d.ts +0 -58
  559. package/dist/commands/monitor.js +0 -980
  560. package/dist/commands/onboard-bot-membership.d.ts +0 -32
  561. package/dist/commands/onboard-bot-membership.js +0 -40
  562. package/dist/commands/onboard-create-identity.d.ts +0 -26
  563. package/dist/commands/onboard-create-identity.js +0 -23
  564. package/dist/commands/outpost-pruner.d.ts +0 -3
  565. package/dist/commands/outpost-pruner.js +0 -125
  566. package/dist/commands/personal-connector-settings-flag.d.ts +0 -4
  567. package/dist/commands/personal-connector-settings-flag.js +0 -7
  568. package/dist/commands/personal-targeted-push-flag.d.ts +0 -4
  569. package/dist/commands/personal-targeted-push-flag.js +0 -7
  570. package/dist/commands/personal-targeted-push-paths.d.ts +0 -3
  571. package/dist/commands/personal-targeted-push-paths.js +0 -67
  572. package/dist/commands/report.d.ts +0 -19
  573. package/dist/commands/report.js +0 -537
  574. package/dist/commands/run-feature-telemetry.d.ts +0 -3
  575. package/dist/commands/run-feature-telemetry.js +0 -6
  576. package/dist/commands/staff/reset-test-account.d.ts +0 -110
  577. package/dist/commands/staff/reset-test-account.js +0 -268
  578. package/dist/commands/staff/test-account.d.ts +0 -51
  579. package/dist/commands/staff/test-account.js +0 -196
  580. package/dist/commands/vault-retention-flag.d.ts +0 -3
  581. package/dist/commands/vault-retention-flag.js +0 -9
  582. package/dist/commands/vault-retention.d.ts +0 -11
  583. package/dist/commands/vault-retention.js +0 -69
  584. package/dist/commands/version.d.ts +0 -10
  585. package/dist/commands/version.js +0 -11
  586. package/dist/fast-scaffold.d.ts +0 -86
  587. package/dist/fast-scaffold.js +0 -364
  588. package/dist/lanes-drain-hook.d.ts +0 -14
  589. package/dist/lanes-drain-hook.js +0 -203
  590. package/dist/lib/agent-kit/adopt-identity.d.ts +0 -27
  591. package/dist/lib/agent-kit/adopt-identity.js +0 -60
  592. package/dist/lib/agent-kit/attachment-download.d.ts +0 -24
  593. package/dist/lib/agent-kit/attachment-download.js +0 -47
  594. package/dist/lib/agent-kit/creds.d.ts +0 -106
  595. package/dist/lib/agent-kit/creds.js +0 -163
  596. package/dist/lib/agent-kit/fallback.d.ts +0 -78
  597. package/dist/lib/agent-kit/fallback.js +0 -210
  598. package/dist/lib/agent-kit/inbox-state.d.ts +0 -83
  599. package/dist/lib/agent-kit/inbox-state.js +0 -159
  600. package/dist/lib/agent-kit/kit-config.d.ts +0 -56
  601. package/dist/lib/agent-kit/kit-config.js +0 -65
  602. package/dist/lib/agent-kit/log.d.ts +0 -16
  603. package/dist/lib/agent-kit/log.js +0 -46
  604. package/dist/lib/agent-kit/mcp/attachments.d.ts +0 -126
  605. package/dist/lib/agent-kit/mcp/attachments.js +0 -222
  606. package/dist/lib/agent-kit/mcp/jsonrpc.d.ts +0 -75
  607. package/dist/lib/agent-kit/mcp/jsonrpc.js +0 -164
  608. package/dist/lib/agent-kit/mcp/tools.d.ts +0 -64
  609. package/dist/lib/agent-kit/mcp/tools.js +0 -397
  610. package/dist/lib/agent-kit/paths.d.ts +0 -65
  611. package/dist/lib/agent-kit/paths.js +0 -118
  612. package/dist/lib/agent-kit/private-file.d.ts +0 -29
  613. package/dist/lib/agent-kit/private-file.js +0 -91
  614. package/dist/lib/agent-kit/run/heartbeat.d.ts +0 -72
  615. package/dist/lib/agent-kit/run/heartbeat.js +0 -128
  616. package/dist/lib/agent-kit/run/inbox.d.ts +0 -76
  617. package/dist/lib/agent-kit/run/inbox.js +0 -205
  618. package/dist/lib/agent-kit/run/supervisor.d.ts +0 -35
  619. package/dist/lib/agent-kit/run/supervisor.js +0 -85
  620. package/dist/lib/agent-kit/run/sync.d.ts +0 -33
  621. package/dist/lib/agent-kit/run/sync.js +0 -58
  622. package/dist/lib/agent-kit/services.d.ts +0 -31
  623. package/dist/lib/agent-kit/services.js +0 -55
  624. package/dist/lib/agent-kit/skills.d.ts +0 -18
  625. package/dist/lib/agent-kit/skills.js +0 -151
  626. package/dist/lib/agent-kit/wake.d.ts +0 -83
  627. package/dist/lib/agent-kit/wake.js +0 -243
  628. package/dist/lib/agents/model-catalog.d.ts +0 -62
  629. package/dist/lib/agents/model-catalog.js +0 -275
  630. package/dist/lib/auth-login-provider-state.d.ts +0 -8
  631. package/dist/lib/auth-login-provider-state.js +0 -63
  632. package/dist/lib/aws-sdk-node-warning-output.d.ts +0 -12
  633. package/dist/lib/aws-sdk-node-warning-output.js +0 -22
  634. package/dist/lib/billing/free-month.d.ts +0 -18
  635. package/dist/lib/billing/free-month.js +0 -31
  636. package/dist/lib/billing/plan-limit-refusals.d.ts +0 -69
  637. package/dist/lib/billing/plan-limit-refusals.js +0 -187
  638. package/dist/lib/billing/plan-limit-upgrade-url.d.ts +0 -11
  639. package/dist/lib/billing/plan-limit-upgrade-url.js +0 -66
  640. package/dist/lib/billing/plan-lock.d.ts +0 -143
  641. package/dist/lib/billing/plan-lock.js +0 -439
  642. package/dist/lib/bot/api.d.ts +0 -349
  643. package/dist/lib/bot/api.js +0 -316
  644. package/dist/lib/bot/attachments.d.ts +0 -45
  645. package/dist/lib/bot/attachments.js +0 -89
  646. package/dist/lib/bot/cli-update.d.ts +0 -138
  647. package/dist/lib/bot/cli-update.js +0 -278
  648. package/dist/lib/bot/company-bind.d.ts +0 -27
  649. package/dist/lib/bot/company-bind.js +0 -62
  650. package/dist/lib/bot/config.d.ts +0 -153
  651. package/dist/lib/bot/config.js +0 -233
  652. package/dist/lib/bot/continuity-download.d.ts +0 -28
  653. package/dist/lib/bot/continuity-download.js +0 -75
  654. package/dist/lib/bot/continuity-install.d.ts +0 -14
  655. package/dist/lib/bot/continuity-install.js +0 -101
  656. package/dist/lib/bot/continuity.d.ts +0 -67
  657. package/dist/lib/bot/continuity.js +0 -301
  658. package/dist/lib/bot/creds.d.ts +0 -24
  659. package/dist/lib/bot/creds.js +0 -51
  660. package/dist/lib/bot/daemon.d.ts +0 -173
  661. package/dist/lib/bot/daemon.js +0 -552
  662. package/dist/lib/bot/inbox-poll-backoff-flag.d.ts +0 -24
  663. package/dist/lib/bot/inbox-poll-backoff-flag.js +0 -135
  664. package/dist/lib/bot/inbox-state.d.ts +0 -18
  665. package/dist/lib/bot/inbox-state.js +0 -51
  666. package/dist/lib/bot/index.d.ts +0 -23
  667. package/dist/lib/bot/index.js +0 -23
  668. package/dist/lib/bot/inflight.d.ts +0 -119
  669. package/dist/lib/bot/inflight.js +0 -83
  670. package/dist/lib/bot/job-completions.d.ts +0 -89
  671. package/dist/lib/bot/job-completions.js +0 -132
  672. package/dist/lib/bot/job-run.d.ts +0 -109
  673. package/dist/lib/bot/job-run.js +0 -246
  674. package/dist/lib/bot/local-config.d.ts +0 -61
  675. package/dist/lib/bot/local-config.js +0 -145
  676. package/dist/lib/bot/local-jobs.d.ts +0 -89
  677. package/dist/lib/bot/local-jobs.js +0 -459
  678. package/dist/lib/bot/local-name.d.ts +0 -54
  679. package/dist/lib/bot/local-name.js +0 -114
  680. package/dist/lib/bot/log.d.ts +0 -13
  681. package/dist/lib/bot/log.js +0 -59
  682. package/dist/lib/bot/owner-context.d.ts +0 -79
  683. package/dist/lib/bot/owner-context.js +0 -175
  684. package/dist/lib/bot/paths.d.ts +0 -76
  685. package/dist/lib/bot/paths.js +0 -131
  686. package/dist/lib/bot/progress.d.ts +0 -132
  687. package/dist/lib/bot/progress.js +0 -289
  688. package/dist/lib/bot/promote.d.ts +0 -16
  689. package/dist/lib/bot/promote.js +0 -106
  690. package/dist/lib/bot/promotion-hold.d.ts +0 -24
  691. package/dist/lib/bot/promotion-hold.js +0 -103
  692. package/dist/lib/bot/promotion-receipt.d.ts +0 -9
  693. package/dist/lib/bot/promotion-receipt.js +0 -56
  694. package/dist/lib/bot/promotion-upload.d.ts +0 -16
  695. package/dist/lib/bot/promotion-upload.js +0 -80
  696. package/dist/lib/bot/prompt.d.ts +0 -136
  697. package/dist/lib/bot/prompt.js +0 -433
  698. package/dist/lib/bot/room-policy.d.ts +0 -63
  699. package/dist/lib/bot/room-policy.js +0 -91
  700. package/dist/lib/bot/run.d.ts +0 -217
  701. package/dist/lib/bot/run.js +0 -1869
  702. package/dist/lib/bot/runnable.d.ts +0 -51
  703. package/dist/lib/bot/runnable.js +0 -65
  704. package/dist/lib/bot/runtime/claude.d.ts +0 -50
  705. package/dist/lib/bot/runtime/claude.js +0 -170
  706. package/dist/lib/bot/runtime/codex.d.ts +0 -28
  707. package/dist/lib/bot/runtime/codex.js +0 -153
  708. package/dist/lib/bot/runtime/grok-acp.d.ts +0 -40
  709. package/dist/lib/bot/runtime/grok-acp.js +0 -265
  710. package/dist/lib/bot/runtime/grok.d.ts +0 -41
  711. package/dist/lib/bot/runtime/grok.js +0 -169
  712. package/dist/lib/bot/runtime/index.d.ts +0 -36
  713. package/dist/lib/bot/runtime/index.js +0 -417
  714. package/dist/lib/bot/runtime/messages-stream.d.ts +0 -56
  715. package/dist/lib/bot/runtime/messages-stream.js +0 -194
  716. package/dist/lib/bot/runtime/sanitize.d.ts +0 -18
  717. package/dist/lib/bot/runtime/sanitize.js +0 -28
  718. package/dist/lib/bot/runtime/types.d.ts +0 -159
  719. package/dist/lib/bot/runtime/types.js +0 -51
  720. package/dist/lib/bot/runtime/windows.d.ts +0 -10
  721. package/dist/lib/bot/runtime/windows.js +0 -53
  722. package/dist/lib/bot/runtime-sign-in.d.ts +0 -24
  723. package/dist/lib/bot/runtime-sign-in.js +0 -31
  724. package/dist/lib/bot/scaffold.d.ts +0 -38
  725. package/dist/lib/bot/scaffold.js +0 -94
  726. package/dist/lib/bot/self-heal.d.ts +0 -52
  727. package/dist/lib/bot/self-heal.js +0 -79
  728. package/dist/lib/bot/self-process.d.ts +0 -19
  729. package/dist/lib/bot/self-process.js +0 -35
  730. package/dist/lib/bot/session.d.ts +0 -19
  731. package/dist/lib/bot/session.js +0 -39
  732. package/dist/lib/bot/setup-explain.d.ts +0 -64
  733. package/dist/lib/bot/setup-explain.js +0 -141
  734. package/dist/lib/bot/split.d.ts +0 -32
  735. package/dist/lib/bot/split.js +0 -241
  736. package/dist/lib/bot/status.d.ts +0 -57
  737. package/dist/lib/bot/status.js +0 -66
  738. package/dist/lib/bot/worker-source.d.ts +0 -66
  739. package/dist/lib/bot/worker-source.js +0 -283
  740. package/dist/lib/checkpoint-ontology/aliases.d.ts +0 -17
  741. package/dist/lib/checkpoint-ontology/aliases.js +0 -44
  742. package/dist/lib/checkpoint-ontology/apply.d.ts +0 -110
  743. package/dist/lib/checkpoint-ontology/apply.js +0 -777
  744. package/dist/lib/checkpoint-ontology/company-brief.d.ts +0 -18
  745. package/dist/lib/checkpoint-ontology/company-brief.js +0 -337
  746. package/dist/lib/checkpoint-ontology/company.d.ts +0 -44
  747. package/dist/lib/checkpoint-ontology/company.js +0 -118
  748. package/dist/lib/checkpoint-ontology/drop-aliases.d.ts +0 -41
  749. package/dist/lib/checkpoint-ontology/drop-aliases.js +0 -76
  750. package/dist/lib/checkpoint-ontology/entity-file.d.ts +0 -109
  751. package/dist/lib/checkpoint-ontology/entity-file.js +0 -371
  752. package/dist/lib/checkpoint-ontology/identity.d.ts +0 -38
  753. package/dist/lib/checkpoint-ontology/identity.js +0 -95
  754. package/dist/lib/checkpoint-ontology/merge-copies.d.ts +0 -199
  755. package/dist/lib/checkpoint-ontology/merge-copies.js +0 -1086
  756. package/dist/lib/checkpoint-ontology/multi-writer.d.ts +0 -101
  757. package/dist/lib/checkpoint-ontology/multi-writer.js +0 -394
  758. package/dist/lib/checkpoint-ontology/plan.d.ts +0 -193
  759. package/dist/lib/checkpoint-ontology/plan.js +0 -504
  760. package/dist/lib/checkpoint-ontology/queued-touches.d.ts +0 -29
  761. package/dist/lib/checkpoint-ontology/queued-touches.js +0 -193
  762. package/dist/lib/checkpoint-ontology/sync-client.d.ts +0 -38
  763. package/dist/lib/checkpoint-ontology/sync-client.js +0 -84
  764. package/dist/lib/checkpoint-ontology/tree.d.ts +0 -55
  765. package/dist/lib/checkpoint-ontology/tree.js +0 -198
  766. package/dist/lib/company-errors-sdk-warning-flag.d.ts +0 -5
  767. package/dist/lib/company-errors-sdk-warning-flag.js +0 -8
  768. package/dist/lib/core-utils/hook-timeout-debug-context-flag.d.ts +0 -20
  769. package/dist/lib/core-utils/hook-timeout-debug-context-flag.js +0 -81
  770. package/dist/lib/core-utils/jq-json-serializer.d.ts +0 -5
  771. package/dist/lib/core-utils/jq-json-serializer.js +0 -10
  772. package/dist/lib/core-utils/secret-patterns.d.ts +0 -43
  773. package/dist/lib/core-utils/secret-patterns.js +0 -34
  774. package/dist/lib/core-utils/sentry-report.d.ts +0 -114
  775. package/dist/lib/core-utils/sentry-report.js +0 -1034
  776. package/dist/lib/core-utils/timeout-guard-native.d.ts +0 -7
  777. package/dist/lib/core-utils/timeout-guard-native.js +0 -40
  778. package/dist/lib/core-utils/worktree-resume.d.ts +0 -20
  779. package/dist/lib/core-utils/worktree-resume.js +0 -1198
  780. package/dist/lib/daemon/catalog.d.ts +0 -134
  781. package/dist/lib/daemon/catalog.js +0 -358
  782. package/dist/lib/daemon/config.d.ts +0 -35
  783. package/dist/lib/daemon/config.js +0 -108
  784. package/dist/lib/daemon/flag.d.ts +0 -25
  785. package/dist/lib/daemon/flag.js +0 -59
  786. package/dist/lib/daemon/handoff.d.ts +0 -56
  787. package/dist/lib/daemon/handoff.js +0 -161
  788. package/dist/lib/daemon/hq-cloud.d.ts +0 -79
  789. package/dist/lib/daemon/hq-cloud.js +0 -183
  790. package/dist/lib/daemon/install.d.ts +0 -85
  791. package/dist/lib/daemon/install.js +0 -320
  792. package/dist/lib/daemon/legacy-sync-env.d.ts +0 -10
  793. package/dist/lib/daemon/legacy-sync-env.js +0 -58
  794. package/dist/lib/daemon/legacy.d.ts +0 -45
  795. package/dist/lib/daemon/legacy.js +0 -133
  796. package/dist/lib/daemon/lock.d.ts +0 -47
  797. package/dist/lib/daemon/lock.js +0 -138
  798. package/dist/lib/daemon/machine-type.d.ts +0 -50
  799. package/dist/lib/daemon/machine-type.js +0 -159
  800. package/dist/lib/daemon/migrate.d.ts +0 -77
  801. package/dist/lib/daemon/migrate.js +0 -265
  802. package/dist/lib/daemon/paths.d.ts +0 -24
  803. package/dist/lib/daemon/paths.js +0 -43
  804. package/dist/lib/daemon/protocol-tail.d.ts +0 -33
  805. package/dist/lib/daemon/protocol-tail.js +0 -131
  806. package/dist/lib/daemon/remote-control.d.ts +0 -74
  807. package/dist/lib/daemon/remote-control.js +0 -153
  808. package/dist/lib/daemon/requests.d.ts +0 -28
  809. package/dist/lib/daemon/requests.js +0 -65
  810. package/dist/lib/daemon/run.d.ts +0 -79
  811. package/dist/lib/daemon/run.js +0 -755
  812. package/dist/lib/daemon/succession.d.ts +0 -118
  813. package/dist/lib/daemon/succession.js +0 -263
  814. package/dist/lib/daemon/supervisor.d.ts +0 -132
  815. package/dist/lib/daemon/supervisor.js +0 -836
  816. package/dist/lib/daemon/sync-runner.d.ts +0 -58
  817. package/dist/lib/daemon/sync-runner.js +0 -277
  818. package/dist/lib/daemon/tools.d.ts +0 -52
  819. package/dist/lib/daemon/tools.js +0 -95
  820. package/dist/lib/daemon/updater.d.ts +0 -57
  821. package/dist/lib/daemon/updater.js +0 -163
  822. package/dist/lib/deploy-api.d.ts +0 -5
  823. package/dist/lib/deploy-api.js +0 -21
  824. package/dist/lib/deploy-apps.d.ts +0 -13
  825. package/dist/lib/deploy-apps.js +0 -29
  826. package/dist/lib/doctor/__testing__/run-doctor.d.ts +0 -8
  827. package/dist/lib/doctor/__testing__/run-doctor.js +0 -52
  828. package/dist/lib/doctor/checks/bots.d.ts +0 -13
  829. package/dist/lib/doctor/checks/bots.js +0 -189
  830. package/dist/lib/doctor/checks/scaffold-cli-floor.d.ts +0 -6
  831. package/dist/lib/doctor/checks/scaffold-cli-floor.js +0 -73
  832. package/dist/lib/doctor/checks/sync-runtime.d.ts +0 -11
  833. package/dist/lib/doctor/checks/sync-runtime.js +0 -216
  834. package/dist/lib/doctor/client-health-flag-token.d.ts +0 -15
  835. package/dist/lib/doctor/client-health-flag-token.js +0 -66
  836. package/dist/lib/doctor/client-health-reason-codes-flag.d.ts +0 -27
  837. package/dist/lib/doctor/client-health-reason-codes-flag.js +0 -106
  838. package/dist/lib/doctor/fix/json-output.d.ts +0 -28
  839. package/dist/lib/doctor/fix/json-output.js +0 -33
  840. package/dist/lib/doctor/fix/refresh-sync-outcome.d.ts +0 -12
  841. package/dist/lib/doctor/fix/refresh-sync-outcome.js +0 -25
  842. package/dist/lib/doctor/shared.d.ts +0 -8
  843. package/dist/lib/doctor/shared.js +0 -38
  844. package/dist/lib/doctor/stray-gate-entries.d.ts +0 -35
  845. package/dist/lib/doctor/stray-gate-entries.js +0 -83
  846. package/dist/lib/first-sync-next-step.d.ts +0 -37
  847. package/dist/lib/first-sync-next-step.js +0 -189
  848. package/dist/lib/flag-registry-endpoint.d.ts +0 -5
  849. package/dist/lib/flag-registry-endpoint.js +0 -9
  850. package/dist/lib/flag-registry-worker-source.generated.d.ts +0 -2
  851. package/dist/lib/flag-registry-worker-source.generated.js +0 -3
  852. package/dist/lib/flag-snapshot-file.d.ts +0 -20
  853. package/dist/lib/flag-snapshot-file.js +0 -91
  854. package/dist/lib/heartbeat-identity.d.ts +0 -30
  855. package/dist/lib/heartbeat-identity.js +0 -76
  856. package/dist/lib/lanes/account-home.d.ts +0 -8
  857. package/dist/lib/lanes/account-home.js +0 -10
  858. package/dist/lib/lanes/accounts.d.ts +0 -117
  859. package/dist/lib/lanes/accounts.js +0 -366
  860. package/dist/lib/lanes/admission-host.d.ts +0 -22
  861. package/dist/lib/lanes/admission-host.js +0 -37
  862. package/dist/lib/lanes/admission.d.ts +0 -26
  863. package/dist/lib/lanes/admission.js +0 -210
  864. package/dist/lib/lanes/approval-gate.d.ts +0 -8
  865. package/dist/lib/lanes/approval-gate.js +0 -90
  866. package/dist/lib/lanes/autopilot-metrics.d.ts +0 -99
  867. package/dist/lib/lanes/autopilot-metrics.js +0 -301
  868. package/dist/lib/lanes/autopilot-registry.d.ts +0 -62
  869. package/dist/lib/lanes/autopilot-registry.js +0 -192
  870. package/dist/lib/lanes/autopilot.d.ts +0 -120
  871. package/dist/lib/lanes/autopilot.js +0 -1061
  872. package/dist/lib/lanes/blocker-freshness.d.ts +0 -31
  873. package/dist/lib/lanes/blocker-freshness.js +0 -168
  874. package/dist/lib/lanes/checked-company-path.d.ts +0 -3
  875. package/dist/lib/lanes/checked-company-path.js +0 -39
  876. package/dist/lib/lanes/claude-balance.d.ts +0 -97
  877. package/dist/lib/lanes/claude-balance.js +0 -319
  878. package/dist/lib/lanes/compaction.d.ts +0 -110
  879. package/dist/lib/lanes/compaction.js +0 -293
  880. package/dist/lib/lanes/config.d.ts +0 -94
  881. package/dist/lib/lanes/config.js +0 -606
  882. package/dist/lib/lanes/constants.d.ts +0 -3
  883. package/dist/lib/lanes/constants.js +0 -3
  884. package/dist/lib/lanes/delivery-core.d.ts +0 -15
  885. package/dist/lib/lanes/delivery-core.js +0 -21
  886. package/dist/lib/lanes/delivery.d.ts +0 -180
  887. package/dist/lib/lanes/delivery.js +0 -443
  888. package/dist/lib/lanes/disk-guard.d.ts +0 -66
  889. package/dist/lib/lanes/disk-guard.js +0 -172
  890. package/dist/lib/lanes/dropbox.d.ts +0 -129
  891. package/dist/lib/lanes/dropbox.js +0 -601
  892. package/dist/lib/lanes/effort.d.ts +0 -51
  893. package/dist/lib/lanes/effort.js +0 -113
  894. package/dist/lib/lanes/envelope-repair-dispatch.d.ts +0 -26
  895. package/dist/lib/lanes/envelope-repair-dispatch.js +0 -74
  896. package/dist/lib/lanes/errors.d.ts +0 -39
  897. package/dist/lib/lanes/errors.js +0 -72
  898. package/dist/lib/lanes/flag-keys.d.ts +0 -15
  899. package/dist/lib/lanes/flag-keys.js +0 -15
  900. package/dist/lib/lanes/grants.d.ts +0 -30
  901. package/dist/lib/lanes/grants.js +0 -171
  902. package/dist/lib/lanes/hire-grant-dispatch.d.ts +0 -29
  903. package/dist/lib/lanes/hire-grant-dispatch.js +0 -315
  904. package/dist/lib/lanes/hooks-install.d.ts +0 -82
  905. package/dist/lib/lanes/hooks-install.js +0 -479
  906. package/dist/lib/lanes/host-capacity.d.ts +0 -69
  907. package/dist/lib/lanes/host-capacity.js +0 -254
  908. package/dist/lib/lanes/hq-root.d.ts +0 -19
  909. package/dist/lib/lanes/hq-root.js +0 -28
  910. package/dist/lib/lanes/index.d.ts +0 -76
  911. package/dist/lib/lanes/index.js +0 -42
  912. package/dist/lib/lanes/keep-alive.d.ts +0 -68
  913. package/dist/lib/lanes/keep-alive.js +0 -343
  914. package/dist/lib/lanes/kr-freshness.d.ts +0 -76
  915. package/dist/lib/lanes/kr-freshness.js +0 -413
  916. package/dist/lib/lanes/lane-company.d.ts +0 -10
  917. package/dist/lib/lanes/lane-company.js +0 -41
  918. package/dist/lib/lanes/liveness.d.ts +0 -108
  919. package/dist/lib/lanes/liveness.js +0 -396
  920. package/dist/lib/lanes/machine-identity.d.ts +0 -34
  921. package/dist/lib/lanes/machine-identity.js +0 -92
  922. package/dist/lib/lanes/manager-status-gate.d.ts +0 -17
  923. package/dist/lib/lanes/manager-status-gate.js +0 -133
  924. package/dist/lib/lanes/merge-command.d.ts +0 -15
  925. package/dist/lib/lanes/merge-command.js +0 -629
  926. package/dist/lib/lanes/mesh-events.d.ts +0 -127
  927. package/dist/lib/lanes/mesh-events.js +0 -564
  928. package/dist/lib/lanes/message-replay.d.ts +0 -21
  929. package/dist/lib/lanes/message-replay.js +0 -122
  930. package/dist/lib/lanes/models.d.ts +0 -86
  931. package/dist/lib/lanes/models.js +0 -234
  932. package/dist/lib/lanes/monitor.d.ts +0 -48
  933. package/dist/lib/lanes/monitor.js +0 -428
  934. package/dist/lib/lanes/move-account.d.ts +0 -56
  935. package/dist/lib/lanes/move-account.js +0 -193
  936. package/dist/lib/lanes/orphans.d.ts +0 -25
  937. package/dist/lib/lanes/orphans.js +0 -102
  938. package/dist/lib/lanes/outpost-dispatch.d.ts +0 -147
  939. package/dist/lib/lanes/outpost-dispatch.js +0 -271
  940. package/dist/lib/lanes/outpost-hire-cache.d.ts +0 -22
  941. package/dist/lib/lanes/outpost-hire-cache.js +0 -153
  942. package/dist/lib/lanes/outpost-identity.d.ts +0 -33
  943. package/dist/lib/lanes/outpost-identity.js +0 -59
  944. package/dist/lib/lanes/outpost-profile-repin.d.ts +0 -17
  945. package/dist/lib/lanes/outpost-profile-repin.js +0 -84
  946. package/dist/lib/lanes/outpost-pruner-install.d.ts +0 -37
  947. package/dist/lib/lanes/outpost-pruner-install.js +0 -238
  948. package/dist/lib/lanes/outpost-registry-worker-approval.d.ts +0 -18
  949. package/dist/lib/lanes/outpost-registry-worker-approval.js +0 -109
  950. package/dist/lib/lanes/outpost-snapshot-memo.d.ts +0 -6
  951. package/dist/lib/lanes/outpost-snapshot-memo.js +0 -14
  952. package/dist/lib/lanes/outpost-worktree-pruner-flag.d.ts +0 -19
  953. package/dist/lib/lanes/outpost-worktree-pruner-flag.js +0 -86
  954. package/dist/lib/lanes/outpost-worktree-pruner.d.ts +0 -62
  955. package/dist/lib/lanes/outpost-worktree-pruner.js +0 -1201
  956. package/dist/lib/lanes/profile.d.ts +0 -69
  957. package/dist/lib/lanes/profile.js +0 -552
  958. package/dist/lib/lanes/provider-rejection.d.ts +0 -86
  959. package/dist/lib/lanes/provider-rejection.js +0 -286
  960. package/dist/lib/lanes/questions.d.ts +0 -90
  961. package/dist/lib/lanes/questions.js +0 -384
  962. package/dist/lib/lanes/quota.d.ts +0 -134
  963. package/dist/lib/lanes/quota.js +0 -471
  964. package/dist/lib/lanes/reconcile-install.d.ts +0 -90
  965. package/dist/lib/lanes/reconcile-install.js +0 -257
  966. package/dist/lib/lanes/reconcile.d.ts +0 -161
  967. package/dist/lib/lanes/reconcile.js +0 -3324
  968. package/dist/lib/lanes/registry-flag.d.ts +0 -35
  969. package/dist/lib/lanes/registry-flag.js +0 -164
  970. package/dist/lib/lanes/registry-persona.d.ts +0 -20
  971. package/dist/lib/lanes/registry-persona.js +0 -329
  972. package/dist/lib/lanes/registry.d.ts +0 -122
  973. package/dist/lib/lanes/registry.js +0 -570
  974. package/dist/lib/lanes/reviews.d.ts +0 -38
  975. package/dist/lib/lanes/reviews.js +0 -395
  976. package/dist/lib/lanes/runaway-tool-guard.d.ts +0 -38
  977. package/dist/lib/lanes/runaway-tool-guard.js +0 -284
  978. package/dist/lib/lanes/session-relink.d.ts +0 -25
  979. package/dist/lib/lanes/session-relink.js +0 -216
  980. package/dist/lib/lanes/spawn.d.ts +0 -355
  981. package/dist/lib/lanes/spawn.js +0 -2668
  982. package/dist/lib/lanes/ssm-command-context.d.ts +0 -12
  983. package/dist/lib/lanes/ssm-command-context.js +0 -52
  984. package/dist/lib/lanes/store.d.ts +0 -91
  985. package/dist/lib/lanes/store.js +0 -1822
  986. package/dist/lib/lanes/stories.d.ts +0 -23
  987. package/dist/lib/lanes/stories.js +0 -92
  988. package/dist/lib/lanes/story-ledger.d.ts +0 -80
  989. package/dist/lib/lanes/story-ledger.js +0 -815
  990. package/dist/lib/lanes/story-switch.d.ts +0 -21
  991. package/dist/lib/lanes/story-switch.js +0 -75
  992. package/dist/lib/lanes/text-scan.d.ts +0 -11
  993. package/dist/lib/lanes/text-scan.js +0 -103
  994. package/dist/lib/lanes/throttle.d.ts +0 -116
  995. package/dist/lib/lanes/throttle.js +0 -437
  996. package/dist/lib/lanes/timestamp.d.ts +0 -3
  997. package/dist/lib/lanes/timestamp.js +0 -26
  998. package/dist/lib/lanes/tracker-checks.d.ts +0 -77
  999. package/dist/lib/lanes/tracker-checks.js +0 -134
  1000. package/dist/lib/lanes/tracker-report-state.d.ts +0 -10
  1001. package/dist/lib/lanes/tracker-report-state.js +0 -124
  1002. package/dist/lib/lanes/tracker-report.d.ts +0 -203
  1003. package/dist/lib/lanes/tracker-report.js +0 -522
  1004. package/dist/lib/lanes/tracker-store.d.ts +0 -18
  1005. package/dist/lib/lanes/tracker-store.js +0 -106
  1006. package/dist/lib/lanes/types.d.ts +0 -1030
  1007. package/dist/lib/lanes/types.js +0 -418
  1008. package/dist/lib/lanes/wait.d.ts +0 -39
  1009. package/dist/lib/lanes/wait.js +0 -159
  1010. package/dist/lib/lanes/watch.d.ts +0 -39
  1011. package/dist/lib/lanes/watch.js +0 -249
  1012. package/dist/lib/lanes/watcher-main.d.ts +0 -11
  1013. package/dist/lib/lanes/watcher-main.js +0 -108
  1014. package/dist/lib/lanes/watcher.d.ts +0 -287
  1015. package/dist/lib/lanes/watcher.js +0 -1972
  1016. package/dist/lib/mesh/denial-codes.d.ts +0 -5
  1017. package/dist/lib/mesh/denial-codes.js +0 -14
  1018. package/dist/lib/mesh/live/daemon/config.d.ts +0 -36
  1019. package/dist/lib/mesh/live/daemon/config.js +0 -120
  1020. package/dist/lib/mesh/live/daemon/legacy-listen.d.ts +0 -43
  1021. package/dist/lib/mesh/live/daemon/legacy-listen.js +0 -89
  1022. package/dist/lib/mesh/live/daemon/live-cache.d.ts +0 -26
  1023. package/dist/lib/mesh/live/daemon/live-cache.js +0 -116
  1024. package/dist/lib/mesh/live/daemon/mqtt-events.d.ts +0 -7
  1025. package/dist/lib/mesh/live/daemon/mqtt-events.js +0 -2
  1026. package/dist/lib/mesh/live/daemon/mqtt-events.test-d.d.ts +0 -2
  1027. package/dist/lib/mesh/live/daemon/mqtt-events.test-d.js +0 -10
  1028. package/dist/lib/mesh/live/daemon/version-drift.d.ts +0 -5
  1029. package/dist/lib/mesh/live/daemon/version-drift.js +0 -47
  1030. package/dist/lib/mesh/live/daemon/work-subscribe.d.ts +0 -32
  1031. package/dist/lib/mesh/live/daemon/work-subscribe.js +0 -262
  1032. package/dist/lib/mesh/live/report-summary.d.ts +0 -45
  1033. package/dist/lib/mesh/live/report-summary.js +0 -234
  1034. package/dist/lib/mesh/live/session-seq.d.ts +0 -4
  1035. package/dist/lib/mesh/live/session-seq.js +0 -33
  1036. package/dist/lib/mesh/project-board.d.ts +0 -65
  1037. package/dist/lib/mesh/project-board.js +0 -181
  1038. package/dist/lib/mesh/story-status.d.ts +0 -22
  1039. package/dist/lib/mesh/story-status.js +0 -49
  1040. package/dist/lib/monitor.d.ts +0 -149
  1041. package/dist/lib/monitor.js +0 -519
  1042. package/dist/lib/node-binary.d.ts +0 -50
  1043. package/dist/lib/node-binary.js +0 -133
  1044. package/dist/lib/notify-recipient.d.ts +0 -7
  1045. package/dist/lib/notify-recipient.js +0 -11
  1046. package/dist/lib/onboarding/checkpoint.d.ts +0 -13
  1047. package/dist/lib/onboarding/checkpoint.js +0 -44
  1048. package/dist/lib/onboarding/cli/onboard.d.ts +0 -53
  1049. package/dist/lib/onboarding/cli/onboard.js +0 -135
  1050. package/dist/lib/onboarding/cli/prompts.d.ts +0 -28
  1051. package/dist/lib/onboarding/cli/prompts.js +0 -83
  1052. package/dist/lib/onboarding/errors.d.ts +0 -34
  1053. package/dist/lib/onboarding/errors.js +0 -59
  1054. package/dist/lib/onboarding/index.d.ts +0 -13
  1055. package/dist/lib/onboarding/index.js +0 -13
  1056. package/dist/lib/onboarding/orchestrator.d.ts +0 -47
  1057. package/dist/lib/onboarding/orchestrator.js +0 -569
  1058. package/dist/lib/onboarding/types.d.ts +0 -79
  1059. package/dist/lib/onboarding/types.js +0 -8
  1060. package/dist/lib/policy-validator.d.ts +0 -7
  1061. package/dist/lib/policy-validator.js +0 -187
  1062. package/dist/lib/process-flag-company-context.d.ts +0 -8
  1063. package/dist/lib/process-flag-company-context.js +0 -67
  1064. package/dist/lib/report-publish.d.ts +0 -175
  1065. package/dist/lib/report-publish.js +0 -421
  1066. package/dist/lib/report-run.d.ts +0 -62
  1067. package/dist/lib/report-run.js +0 -123
  1068. package/dist/lib/report-snapshot.d.ts +0 -12
  1069. package/dist/lib/report-snapshot.js +0 -135
  1070. package/dist/lib/report-templates.d.ts +0 -9
  1071. package/dist/lib/report-templates.js +0 -21
  1072. package/dist/lib/scaffold-cli-floor.d.ts +0 -8
  1073. package/dist/lib/scaffold-cli-floor.js +0 -50
  1074. package/dist/lib/search-index/collection-path-repair-flag.d.ts +0 -4
  1075. package/dist/lib/search-index/collection-path-repair-flag.js +0 -7
  1076. package/dist/lib/search-index/embed-lock.d.ts +0 -34
  1077. package/dist/lib/search-index/embed-lock.js +0 -295
  1078. package/dist/lib/search-index/load-gate.d.ts +0 -57
  1079. package/dist/lib/search-index/load-gate.js +0 -270
  1080. package/dist/lib/search-index/max-doc-bytes.d.ts +0 -219
  1081. package/dist/lib/search-index/max-doc-bytes.js +0 -463
  1082. package/dist/lib/search-index/qmd-exit-diagnostics.d.ts +0 -5
  1083. package/dist/lib/search-index/qmd-exit-diagnostics.js +0 -40
  1084. package/dist/lib/search-index/reindex-single-flight-flag.d.ts +0 -5
  1085. package/dist/lib/search-index/reindex-single-flight-flag.js +0 -8
  1086. package/dist/lib/service-manager/index.d.ts +0 -42
  1087. package/dist/lib/service-manager/index.js +0 -105
  1088. package/dist/lib/service-manager/launchd.d.ts +0 -81
  1089. package/dist/lib/service-manager/launchd.js +0 -212
  1090. package/dist/lib/service-manager/systemd.d.ts +0 -19
  1091. package/dist/lib/service-manager/systemd.js +0 -72
  1092. package/dist/lib/service-manager/types.d.ts +0 -34
  1093. package/dist/lib/service-manager/types.js +0 -26
  1094. package/dist/lib/test-utils/isolated-flag-company-context.d.ts +0 -3
  1095. package/dist/lib/test-utils/isolated-flag-company-context.js +0 -18
  1096. package/dist/lib/work-context/bind-best.d.ts +0 -66
  1097. package/dist/lib/work-context/bind-best.js +0 -344
  1098. package/dist/lib/work-context/bind-calling-session.d.ts +0 -26
  1099. package/dist/lib/work-context/bind-calling-session.js +0 -63
  1100. package/dist/lib/work-context/company-rebind.d.ts +0 -23
  1101. package/dist/lib/work-context/company-rebind.js +0 -59
  1102. package/dist/lib/work-context/default-company.d.ts +0 -43
  1103. package/dist/lib/work-context/default-company.js +0 -83
  1104. package/dist/lib/work-context/outbox-quarantine-status-flag.d.ts +0 -4
  1105. package/dist/lib/work-context/outbox-quarantine-status-flag.js +0 -7
  1106. package/dist/lib/work-context/prd-sync.d.ts +0 -56
  1107. package/dist/lib/work-context/prd-sync.js +0 -197
  1108. package/dist/lib/work-context/preflight-contract.d.ts +0 -28
  1109. package/dist/lib/work-context/preflight-contract.js +0 -85
  1110. package/dist/lib/work-context/prompt-rebind.d.ts +0 -25
  1111. package/dist/lib/work-context/prompt-rebind.js +0 -85
  1112. package/dist/lib/work-context/windows-acl.d.ts +0 -123
  1113. package/dist/lib/work-context/windows-acl.js +0 -425
  1114. package/dist/lib/workers-registry/read.d.ts +0 -15
  1115. package/dist/lib/workers-registry/read.js +0 -17
  1116. package/dist/native-fast-route.d.ts +0 -7
  1117. package/dist/native-fast-route.js +0 -45
  1118. package/dist/node-network-compat-core.d.ts +0 -12
  1119. package/dist/node-network-compat-core.js +0 -41
  1120. package/dist/node-network-compat-fast.d.ts +0 -7
  1121. package/dist/node-network-compat-fast.js +0 -23
  1122. package/dist/secrets-env-fast-path.d.ts +0 -5
  1123. package/dist/secrets-env-fast-path.js +0 -16
  1124. package/dist/secrets-env-fast-route.d.ts +0 -18
  1125. package/dist/secrets-env-fast-route.js +0 -54
  1126. package/dist/utils/checkpoint-stamp-write-error.d.ts +0 -28
  1127. package/dist/utils/checkpoint-stamp-write-error.js +0 -99
  1128. package/dist/utils/cli-network-lifecycle.d.ts +0 -4
  1129. package/dist/utils/cli-network-lifecycle.js +0 -11
  1130. package/dist/utils/cognito-refresh-sentry.d.ts +0 -3
  1131. package/dist/utils/cognito-refresh-sentry.js +0 -49
  1132. package/dist/utils/console-origin.d.ts +0 -9
  1133. package/dist/utils/console-origin.js +0 -28
  1134. package/dist/utils/core-eval-trigger.d.ts +0 -4
  1135. package/dist/utils/core-eval-trigger.js +0 -88
  1136. package/dist/utils/exclusive-lock.d.ts +0 -32
  1137. package/dist/utils/exclusive-lock.js +0 -75
  1138. package/dist/utils/fast-stream-errors.d.ts +0 -12
  1139. package/dist/utils/fast-stream-errors.js +0 -18
  1140. package/dist/utils/files-browse-acl.d.ts +0 -5
  1141. package/dist/utils/files-browse-acl.js +0 -11
  1142. package/dist/utils/hq-core-yaml.d.ts +0 -10
  1143. package/dist/utils/hq-core-yaml.js +0 -40
  1144. package/dist/utils/hq-root-resolver.d.ts +0 -13
  1145. package/dist/utils/hq-root-resolver.js +0 -103
  1146. package/dist/utils/redact-url.d.ts +0 -14
  1147. package/dist/utils/redact-url.js +0 -218
  1148. package/dist/utils/scaffold-fast-import-guard.d.ts +0 -2
  1149. package/dist/utils/scaffold-fast-import-guard.js +0 -40
  1150. package/dist/utils/scaffold-packlist-guard.d.ts +0 -7
  1151. package/dist/utils/scaffold-packlist-guard.js +0 -23
  1152. package/dist/utils/scaffold-sibling-references.d.ts +0 -22
  1153. package/dist/utils/scaffold-sibling-references.js +0 -156
  1154. package/dist/utils/secret-load-availability.d.ts +0 -8
  1155. package/dist/utils/secret-load-availability.js +0 -54
  1156. package/dist/utils/staged-install.d.ts +0 -34
  1157. package/dist/utils/staged-install.js +0 -346
  1158. package/dist/utils/staged-npm-install.d.ts +0 -16
  1159. package/dist/utils/staged-npm-install.js +0 -264
  1160. package/dist/utils/sync-log-sources.d.ts +0 -15
  1161. package/dist/utils/sync-log-sources.js +0 -36
  1162. package/dist/utils/table-width.d.ts +0 -7
  1163. package/dist/utils/table-width.js +0 -15
  1164. package/dist/utils/update-command-supervisor.cjs +0 -247
  1165. package/dist/utils/upload-author.d.ts +0 -15
  1166. package/dist/utils/upload-author.js +0 -39
  1167. package/dist/utils/version-report.d.ts +0 -27
  1168. package/dist/utils/version-report.js +0 -105
  1169. package/dist/version-request.d.ts +0 -14
  1170. package/dist/version-request.js +0 -36
  1171. package/scripts/mesh-daemon-if-stale.mjs +0 -20
  1172. package/templates/reports/blank.md +0 -3
  1173. package/templates/reports/daily-digest.md +0 -11
  1174. package/templates/runbooks/update-report.md +0 -21
@@ -1,2668 +0,0 @@
1
- /**
2
- * Detached lane-worker spawn (spec §5, §5.1, §5.4, §5.5).
3
- *
4
- * The worker must leave the caller's process tree (`detached: true` / setsid)
5
- * with stdio pointed at files in the run directory. Account selection is the
6
- * provider home environment variable only. Provider credential files are
7
- * probed for existence and never read. Identity in the child is `HQ_LANE_ID`;
8
- * mutable fields are re-read from the lane record (spec §5.4).
9
- */
10
- import { spawn, spawnSync } from "node:child_process";
11
- import { randomUUID } from "node:crypto";
12
- import * as fs from "node:fs";
13
- import * as path from "node:path";
14
- import { fileURLToPath } from "node:url";
15
- import { PROVIDER_HOME_ENV, accountStatus, isLoggedOut, resolveAccount, selectBalancedAccount, } from "./accounts.js";
16
- import { effectiveAccountHome } from "./account-home.js";
17
- import { buildHostCapacitySnapshot } from "./host-capacity.js";
18
- import { selectClaudeAccount } from "./claude-balance.js";
19
- import { loadQuotaState } from "./quota.js";
20
- import { COMPACTION_PROMPT, compactionAfterUsage, compactionDue, compactLaneSession, } from "./compaction.js";
21
- import { installDrainHook } from "./hooks-install.js";
22
- import { loadLanesConfig, providerAutoCompactTokens, providerCompactAfterMs, } from "./config.js";
23
- import { appendEffortFlag, resolveLaneEffort, } from "./effort.js";
24
- import { defaultProbe, validateLaneModel, validateProfileLaneModel, } from "./models.js";
25
- import { claimableStatesFor, planLaneLaunch, providerSupportsSessionResume, } from "./delivery.js";
26
- import { AccountResolutionError, LanesError } from "./errors.js";
27
- import { ignoredWorkerProfileFields, loadWorkerProfile, loadWorkerProfileWithRegistry, materializeWorkerProfile, workerProfilePrompt, } from "./profile.js";
28
- import { registryWorkerRecord } from "./registry-persona.js";
29
- import { resolveMachineIdentity, } from "./machine-identity.js";
30
- import { appendCappedHistory, listLaneIds, readLane, retryUpdateLane } from "./store.js";
31
- import { managerStatusGateHeartbeat } from "./manager-status-gate.js";
32
- import { LEAD_LANE_KEEP_ALIVE_BLOCKED_RESUME_TEXT } from "./keep-alive.js";
33
- import { copySessionFiles, planSessionCopy } from "./move-account.js";
34
- import { ensureSessionHome } from "./session-relink.js";
35
- import { MESSAGE_REPLAY_STATE_NAME } from "./message-replay.js";
36
- import { markAnsweredQuestionsDelivered } from "./questions.js";
37
- import { hasEarlierEligibleQueuedLane, laneAdmissionCapReason, withLaneAdmissionLock, } from "./admission.js";
38
- import { resolveAdmissionHost } from "./admission-host.js";
39
- import { checkLaneDiskSpace, lowDiskGuardEnabledForLane } from "./disk-guard.js";
40
- import { LANE_ENVELOPE_JSON_SCHEMA, ENVELOPE_INVALID_REASON, parseLaneProvider, } from "./types.js";
41
- export const LANES_RUNS_REL = path.join("workspace", "lanes-runs");
42
- /** Written by reconcile before a resume spawn; the worker prompt names this path. */
43
- export const ANSWERED_QUESTIONS_FILE = "answered-questions.json";
44
- export const SPAWN_TERMINAL_REASONS = [
45
- "account_not_logged_in",
46
- "unknown_account",
47
- "account_disabled",
48
- "no_enabled_account",
49
- "spawn_failed",
50
- "not_detached",
51
- "watcher_not_armed",
52
- "model_unsupported",
53
- ];
54
- const PROVIDER_COMMAND = {
55
- claude: "claude",
56
- codex: "codex",
57
- grok: "grok",
58
- };
59
- export function providerCommandOnPath(command, pathEnv) {
60
- // Test and embedded callers can intentionally omit PATH and delegate lookup
61
- // to their spawn implementation. A present PATH is authoritative.
62
- if (pathEnv === undefined)
63
- return true;
64
- if (!pathEnv)
65
- return false;
66
- return pathEnv.split(path.delimiter).some((dir) => {
67
- if (!dir)
68
- return false;
69
- const candidate = path.join(dir, command);
70
- try {
71
- fs.accessSync(candidate, fs.constants.X_OK);
72
- return true;
73
- }
74
- catch {
75
- return false;
76
- }
77
- });
78
- }
79
- /** Per-provider model flag. A missing entry means --model is refused. */
80
- export const PROVIDER_MODEL_FLAG = {
81
- claude: "--model",
82
- codex: "-m",
83
- grok: "-m",
84
- };
85
- export const CLAUDE_AUTO_COMPACT_ENV = "CLAUDE_CODE_AUTO_COMPACT_WINDOW";
86
- /** Codex CLI overrides required for its ChatGPT fast service tier. */
87
- export const CODEX_FAST_MODE_FLAGS = [
88
- "-c",
89
- 'service_tier="fast"',
90
- "--enable",
91
- "fast_mode",
92
- ];
93
- export function parseCliModel(raw) {
94
- if (raw === undefined)
95
- return undefined;
96
- const trimmed = raw.trim();
97
- if (trimmed.length === 0) {
98
- throw new LanesError("empty_model", "--model is empty or whitespace-only", {
99
- value: raw,
100
- });
101
- }
102
- return trimmed;
103
- }
104
- export function resolveLaneModel(input) {
105
- if (input.cliModel !== undefined)
106
- return input.cliModel;
107
- if (input.profileModel !== undefined && input.profileModel.trim().length > 0) {
108
- return input.profileModel.trim();
109
- }
110
- if (input.accountModel !== undefined && input.accountModel.trim().length > 0) {
111
- return input.accountModel.trim();
112
- }
113
- if (input.providerModel !== undefined && input.providerModel.trim().length > 0) {
114
- return input.providerModel.trim();
115
- }
116
- return undefined;
117
- }
118
- function accountModelForSpawn(provider, accountId, config, pinnedModel, profileModel) {
119
- return resolveLaneModel({
120
- cliModel: pinnedModel,
121
- profileModel,
122
- accountModel: config.providers[provider].accounts[accountId]?.model,
123
- providerModel: config.providers[provider].model,
124
- });
125
- }
126
- function supportsSpawnModel(provider, accountId, config, pinnedModel, profileModel, modelDeps, hostname) {
127
- const account = config.providers[provider].accounts[accountId];
128
- if (account === undefined)
129
- return false;
130
- const model = accountModelForSpawn(provider, accountId, config, pinnedModel, profileModel);
131
- if (model === undefined)
132
- return true;
133
- try {
134
- validateLaneModel(provider, model, effectiveAccountHome(account, hostname).home, modelDeps);
135
- return true;
136
- }
137
- catch (err) {
138
- if (err instanceof LanesError && err.error === "model_unsupported")
139
- return false;
140
- throw err;
141
- }
142
- }
143
- function spawnModelFailure(provider, accountId, config, pinnedModel, profileModel, profileId, modelDeps, hostname) {
144
- const account = config.providers[provider].accounts[accountId];
145
- if (account === undefined)
146
- return new LanesError("unknown_account", `Unknown account ${accountId} for ${provider}`, { provider, account: accountId });
147
- const model = accountModelForSpawn(provider, accountId, config, pinnedModel, profileModel);
148
- if (model === undefined)
149
- return null;
150
- try {
151
- validateLaneModel(provider, model, effectiveAccountHome(account, hostname).home, modelDeps);
152
- return null;
153
- }
154
- catch (err) {
155
- if (!(err instanceof LanesError) || err.error !== "model_unsupported")
156
- throw err;
157
- if (profileModel !== undefined && pinnedModel === undefined && profileId !== undefined) {
158
- return new LanesError(err.error, err.message, {
159
- ...err.details,
160
- profile_id: profileId,
161
- worker_profile: profileId,
162
- model_source: "profile",
163
- });
164
- }
165
- return err;
166
- }
167
- }
168
- function selectSpawnAccount(input) {
169
- const { hqRoot, lane, config, existsSync, accountDeps, modelDeps, pinnedModel, profileModel, currentModelValidated, hostname, repairRecordedAccount, recordedModel, now } = input;
170
- const context = {
171
- hqRoot,
172
- existsSync,
173
- accountDeps,
174
- hostname,
175
- ...(pinnedModel ?? profileModel ? { model: pinnedModel ?? profileModel } : {}),
176
- };
177
- if (lane.account === undefined) {
178
- const modelSpecified = pinnedModel !== undefined || profileModel !== undefined;
179
- const allowedAccounts = modelSpecified
180
- ? Object.keys(config.providers[lane.provider].accounts).filter((id) => supportsSpawnModel(lane.provider, id, config, pinnedModel, profileModel, modelDeps, hostname))
181
- : undefined;
182
- return {
183
- account: selectBalancedAccount(lane.provider, config, {
184
- ...context,
185
- ...(allowedAccounts !== undefined ? { allowedAccounts } : {}),
186
- preferredAccounts: config.providers[lane.provider].preferred_accounts ?? [],
187
- }),
188
- changeReason: "first_assignment",
189
- };
190
- }
191
- const current = config.providers[lane.provider].accounts[lane.account];
192
- let reason;
193
- let refusal;
194
- const operatorMovePending = lane.pending_resume !== undefined &&
195
- lane.account_history?.at(-1)?.reason === "operator_move";
196
- if (current === undefined || !current.enabled) {
197
- reason = "account_unavailable";
198
- refusal = new AccountResolutionError(current === undefined ? "unknown_account" : "account_disabled", `Account ${JSON.stringify(lane.account)} is unavailable for ${lane.provider}`, { provider: lane.provider, account: lane.account });
199
- }
200
- else {
201
- const status = accountStatus(lane.provider, lane.account, config, {
202
- existsSync,
203
- hostname,
204
- ...(accountDeps?.probe ? { probe: accountDeps.probe } : {}),
205
- ...(accountDeps?.env ? { env: accountDeps.env } : {}),
206
- });
207
- if (isLoggedOut(status)) {
208
- reason = repairRecordedAccount ? "recorded_account_logged_out" : "account_unavailable";
209
- refusal = new LanesError("account_not_logged_in", `Account ${lane.account} for ${lane.provider} is not logged in`, { provider: lane.provider, account: lane.account });
210
- }
211
- else {
212
- try {
213
- resolveAccount(lane.provider, lane.account, config, context);
214
- const modelFailure = currentModelValidated
215
- ? null
216
- : spawnModelFailure(lane.provider, lane.account, config, pinnedModel, profileModel, lane.worker_profile, modelDeps, hostname);
217
- if (modelFailure !== null) {
218
- reason = "model_change";
219
- refusal = modelFailure;
220
- }
221
- else {
222
- return { account: resolveAccount(lane.provider, lane.account, config, context) };
223
- }
224
- }
225
- catch (err) {
226
- if (err instanceof AccountResolutionError && err.error === "account_quota_exhausted") {
227
- reason = "usage_limit";
228
- refusal = err;
229
- }
230
- else if (err instanceof AccountResolutionError && err.error === "account_model_unavailable") {
231
- reason = "usage_limit";
232
- refusal = err;
233
- }
234
- else if (err instanceof LanesError && err.error === "model_unsupported") {
235
- reason = "model_change";
236
- refusal = err;
237
- }
238
- else {
239
- throw err;
240
- }
241
- }
242
- }
243
- }
244
- if (operatorMovePending) {
245
- if (refusal instanceof Error)
246
- throw refusal;
247
- throw new LanesError("account_unavailable", `Explicit account move target ${lane.account} is unavailable`, {
248
- provider: lane.provider,
249
- account: lane.account,
250
- });
251
- }
252
- const recoverRecordedClaudeModel = lane.provider === "claude" &&
253
- reason !== undefined &&
254
- (reason === "recorded_account_logged_out" ||
255
- (reason === "account_unavailable" && repairRecordedAccount && recordedModel !== undefined));
256
- if (recoverRecordedClaudeModel) {
257
- const lanes = listLaneIds(hqRoot)
258
- .map((laneId) => readLane(hqRoot, laneId))
259
- .filter((record) => record.host.kind === lane.host.kind && record.host.id === lane.host.id);
260
- const capacity = buildHostCapacitySnapshot({
261
- host: lane.host,
262
- lanes,
263
- config,
264
- existsSync,
265
- probe: accountDeps?.probe,
266
- env: accountDeps?.env,
267
- hostname,
268
- now,
269
- });
270
- const selection = selectClaudeAccount({
271
- hosts: [{ capacity, lanes, laneListAvailable: true }],
272
- targetHost: lane.host,
273
- config,
274
- quotaState: loadQuotaState(hqRoot),
275
- ...((recordedModel ?? pinnedModel ?? profileModel) !== undefined
276
- ? { model: recordedModel ?? pinnedModel ?? profileModel }
277
- : {}),
278
- });
279
- return {
280
- account: resolveAccount(lane.provider, selection.account, config, context),
281
- changeReason: reason,
282
- ...(recordedModel !== undefined ? { preservedModel: recordedModel } : {}),
283
- };
284
- }
285
- const allowedAccounts = Object.entries(config.providers[lane.provider].accounts)
286
- .filter(([id, account]) => id !== lane.account && account.enabled)
287
- .filter(([id]) => accountStatus(lane.provider, id, config, {
288
- existsSync,
289
- hostname,
290
- ...(accountDeps?.probe ? { probe: accountDeps.probe } : {}),
291
- ...(accountDeps?.env ? { env: accountDeps.env } : {}),
292
- }).logged_in === true)
293
- .filter(([id]) => supportsSpawnModel(lane.provider, id, config, pinnedModel, profileModel, modelDeps, hostname))
294
- .map(([id]) => id);
295
- try {
296
- return {
297
- account: selectBalancedAccount(lane.provider, config, {
298
- ...context,
299
- allowedAccounts,
300
- }),
301
- changeReason: reason,
302
- };
303
- }
304
- catch (err) {
305
- if (reason === "account_unavailable" || reason === "recorded_account_logged_out") {
306
- if (refusal instanceof Error)
307
- throw refusal;
308
- throw new LanesError("account_not_logged_in", `Account ${lane.account} for ${lane.provider} is not logged in or available, and no other logged-in account can serve this lane`, { provider: lane.provider, account: lane.account });
309
- }
310
- if (refusal instanceof Error)
311
- throw refusal;
312
- throw err;
313
- }
314
- }
315
- function previouslyUnavailableAccounts(lane) {
316
- const excluded = new Set();
317
- for (const entry of [...(lane.account_history ?? [])].reverse()) {
318
- if (entry.reason === "first_assignment" || entry.reason === "operator_move")
319
- break;
320
- if ((entry.reason === "account_unavailable" || entry.reason === "recorded_account_logged_out") &&
321
- entry.from !== null)
322
- excluded.add(entry.from);
323
- }
324
- return excluded;
325
- }
326
- function archivedResumeMessageText(hqRoot, laneId, messageId) {
327
- if (!messageId || /[\\/\0]/.test(messageId))
328
- return undefined;
329
- const file = path.join(laneRunDir(hqRoot, laneId), "dropbox", "delivered", `${messageId}.resume.jsonl`);
330
- let raw;
331
- try {
332
- raw = fs.readFileSync(file, "utf8");
333
- }
334
- catch (err) {
335
- if (err.code === "ENOENT")
336
- return undefined;
337
- throw new LanesError("account_retry_context_unreadable", `Could not read the archived message needed to resume lane ${laneId}`, { lane_id: laneId, message_id: messageId });
338
- }
339
- const records = [];
340
- for (const line of raw.split(/\r?\n/)) {
341
- if (line.trim().length === 0)
342
- continue;
343
- let parsed;
344
- try {
345
- parsed = JSON.parse(line);
346
- }
347
- catch {
348
- continue;
349
- }
350
- if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed))
351
- continue;
352
- records.push(parsed);
353
- }
354
- if (records.length !== 1) {
355
- throw new LanesError("account_retry_context_invalid", `The archived message needed to resume lane ${laneId} is malformed`, { lane_id: laneId, message_id: messageId });
356
- }
357
- const value = records[0];
358
- if (value === null ||
359
- typeof value !== "object" ||
360
- value.message_id !== messageId ||
361
- typeof value.text !== "string") {
362
- throw new LanesError("account_retry_context_invalid", `The archived message needed to resume lane ${laneId} is malformed`, { lane_id: laneId, message_id: messageId });
363
- }
364
- return value.text;
365
- }
366
- function pendingResumeForRetry(hqRoot, lane, sessionId, at) {
367
- const last = lane.last_resume;
368
- const keepAlive = last?.keep_alive === true ? { keep_alive: true } : {};
369
- if (last === undefined || last.session_id !== sessionId) {
370
- return { session_id: sessionId, trigger: "resume", resumed_from: "interrupted", at, ...keepAlive };
371
- }
372
- const compact = last.compact === undefined ? {} : { compact: last.compact };
373
- if (last.trigger === "answered_questions") {
374
- return { session_id: sessionId, trigger: "answered_questions", at, ...compact, ...keepAlive };
375
- }
376
- if (last.trigger === "watcher") {
377
- return {
378
- session_id: sessionId,
379
- trigger: "watcher",
380
- resumed_from: last.resumed_from ?? "interrupted",
381
- ...(last.text !== undefined ? { text: last.text } : {}),
382
- at,
383
- ...compact,
384
- ...keepAlive,
385
- };
386
- }
387
- if (last.trigger === "message" || last.trigger === "monitor_event" || last.trigger === "system_notice") {
388
- if (last.message_id === undefined) {
389
- throw new LanesError("account_retry_context_missing", `The message id needed to resume lane ${lane.lane_id} is missing`, { lane_id: lane.lane_id, trigger: last.trigger });
390
- }
391
- const text = last.text ?? archivedResumeMessageText(hqRoot, lane.lane_id, last.message_id);
392
- if (text === undefined) {
393
- throw new LanesError("account_retry_context_missing", `The operator message needed to resume lane ${lane.lane_id} is unavailable`, { lane_id: lane.lane_id, message_id: last.message_id });
394
- }
395
- return {
396
- session_id: sessionId,
397
- trigger: last.trigger === "message" && last.monitor_event === true ? "monitor_event" : last.trigger,
398
- text,
399
- message_id: last.message_id,
400
- ...(last.monitor_event === true || last.trigger === "monitor_event" ? { monitor_event: true } : {}),
401
- at,
402
- ...compact,
403
- ...keepAlive,
404
- };
405
- }
406
- return {
407
- session_id: sessionId,
408
- trigger: "resume",
409
- resumed_from: last.resumed_from ?? "interrupted",
410
- ...(last.text !== undefined ? { text: last.text } : {}),
411
- ...(last.message_id !== undefined ? { message_id: last.message_id } : {}),
412
- at,
413
- ...compact,
414
- ...keepAlive,
415
- };
416
- }
417
- /** Change account only after a provider/runtime account failure, then re-admit. */
418
- export async function retryLaneOnAlternateAccount(hqRoot, lane, reason, writer = "watcher", deps = {}) {
419
- const config = loadLanesConfig(hqRoot);
420
- const existsSync = deps.existsSync ?? ((p) => fs.existsSync(p));
421
- const env = deps.env ?? process.env;
422
- const admissionHost = deps.admissionHost ?? resolveAdmissionHost();
423
- const hostname = deps.hostname?.trim() || admissionHost.hostname.trim() || resolveAdmissionHost().hostname;
424
- const modelDeps = {
425
- ...deps.modelDeps,
426
- env: deps.modelDeps?.env ?? env,
427
- };
428
- const accountDeps = {
429
- probe: modelDeps.probe ?? defaultProbe,
430
- env,
431
- };
432
- const profile = lane.worker_profile ? loadWorkerProfile(hqRoot, lane.worker_profile) : undefined;
433
- const profileModel = profile?.meta.provider === lane.provider ? profile.meta.model : undefined;
434
- const pinnedModel = lane.model_source === undefined || lane.model_source === "cli" || lane.model_source === "preserved"
435
- ? lane.model
436
- : undefined;
437
- const unavailableAccounts = previouslyUnavailableAccounts(lane);
438
- const allowedAccounts = Object.entries(config.providers[lane.provider].accounts)
439
- .filter(([id, account]) => id !== lane.account && !unavailableAccounts.has(id) && account.enabled)
440
- .filter(([id]) => accountStatus(lane.provider, id, config, {
441
- existsSync,
442
- hostname,
443
- ...(accountDeps?.probe ? { probe: accountDeps.probe } : {}),
444
- ...(accountDeps?.env ? { env: accountDeps.env } : {}),
445
- }).logged_in === true)
446
- .filter(([id]) => supportsSpawnModel(lane.provider, id, config, pinnedModel, profileModel, modelDeps, hostname))
447
- .map(([id]) => id);
448
- const modelContext = {
449
- hqRoot,
450
- existsSync,
451
- accountDeps,
452
- hostname,
453
- ...(pinnedModel ?? profileModel ? { model: pinnedModel ?? profileModel } : {}),
454
- allowedAccounts,
455
- };
456
- let target;
457
- try {
458
- target = selectBalancedAccount(lane.provider, config, modelContext);
459
- }
460
- catch (err) {
461
- if (reason === "account_unavailable" || unavailableAccounts.size > 0) {
462
- throw new LanesError("account_not_logged_in", `Account ${lane.account ?? "(none)"} for ${lane.provider} is unavailable and no other logged-in account can serve this lane`, { provider: lane.provider, account: lane.account ?? null });
463
- }
464
- throw err;
465
- }
466
- const source = lane.account ? config.providers[lane.provider].accounts[lane.account] : undefined;
467
- const sessionId = providerSupportsSessionResume(lane.provider) &&
468
- typeof lane.provider_session_id === "string" &&
469
- lane.provider_session_id.trim().length > 0
470
- ? lane.provider_session_id
471
- : undefined;
472
- if (source && sessionId) {
473
- copySessionFiles(planSessionCopy(lane.provider, {
474
- sourceHome: lane.provider_home_at_spawn ?? effectiveAccountHome(source, hostname).home,
475
- targetHome: target.home,
476
- cwd: hqRoot,
477
- sessionId,
478
- }));
479
- }
480
- const now = (deps.now ?? (() => new Date()))();
481
- const at = now.toISOString();
482
- const nowMs = now.getTime();
483
- return withLaneAdmissionLock(hqRoot, lane.provider, async () => {
484
- const current = readLane(hqRoot, lane.lane_id);
485
- if (current.state !== "running" ||
486
- current.account !== lane.account ||
487
- current.provider_session_id !== lane.provider_session_id) {
488
- throw new LanesError("account_retry_conflict", `Lane ${lane.lane_id} changed while account recovery was prepared`, {
489
- lane_id: lane.lane_id,
490
- state: current.state,
491
- account: current.account ?? null,
492
- provider_session_id_changed: current.provider_session_id !== lane.provider_session_id,
493
- });
494
- }
495
- const moveToRetryQueue = (row) => {
496
- const entry = {
497
- from: row.account ?? null,
498
- to: target.id,
499
- at,
500
- reason,
501
- };
502
- return {
503
- ...row,
504
- state: "queued",
505
- queued_reason: "account_retry",
506
- queued_details: undefined,
507
- queued_at: at,
508
- admission_reserved_at: undefined,
509
- terminal_reason: undefined,
510
- terminal_details: undefined,
511
- account: target.id,
512
- account_history: appendCappedHistory(row.account_history ?? [], entry),
513
- pending_resume: sessionId
514
- ? pendingResumeForRetry(hqRoot, row, sessionId, at)
515
- : undefined,
516
- };
517
- };
518
- const candidate = moveToRetryQueue(current);
519
- const admissionLanes = listLaneIds(hqRoot)
520
- .filter((id) => id !== current.lane_id)
521
- .map((id) => readLane(hqRoot, id));
522
- admissionLanes.push(candidate);
523
- const profileMaxFor = (row) => row.worker_profile === undefined
524
- ? undefined
525
- : loadWorkerProfile(hqRoot, row.worker_profile).meta.max_concurrent;
526
- const capacityReason = laneAdmissionCapReason(admissionLanes, candidate, config, admissionHost, profile?.meta.max_concurrent, nowMs);
527
- const earlierEligibleLane = hasEarlierEligibleQueuedLane(admissionLanes, candidate, config, admissionHost, profileMaxFor, nowMs);
528
- const moved = retryUpdateLane(hqRoot, lane.lane_id, writer, (row) => {
529
- if (row.state !== "running" ||
530
- row.account !== lane.account ||
531
- row.provider_session_id !== lane.provider_session_id) {
532
- throw new LanesError("account_retry_conflict", `Lane ${lane.lane_id} changed while account recovery was prepared`, {
533
- lane_id: lane.lane_id,
534
- state: row.state,
535
- account: row.account ?? null,
536
- provider_session_id_changed: row.provider_session_id !== lane.provider_session_id,
537
- });
538
- }
539
- return moveToRetryQueue(row);
540
- });
541
- if (capacityReason !== undefined || earlierEligibleLane)
542
- return moved;
543
- return spawnLaneWorker(hqRoot, moved, {
544
- ...deps,
545
- lowDiskGuardEnabled: deps.lowDiskGuardEnabled ?? await lowDiskGuardEnabledForLane(hqRoot, moved),
546
- });
547
- });
548
- }
549
- export function appendModelFlag(provider, args, model) {
550
- if (model === undefined)
551
- return args;
552
- const flag = PROVIDER_MODEL_FLAG[provider];
553
- if (flag === undefined) {
554
- throw new LanesError("model_unsupported", `Provider ${provider} does not accept --model`, { provider, model });
555
- }
556
- if (provider === "codex") {
557
- // `codex exec -- <prompt>`: an option after `--` is read as a positional.
558
- const end = args.indexOf("--");
559
- if (end !== -1)
560
- return [...args.slice(0, end), flag, model, ...args.slice(end)];
561
- }
562
- return [...args, flag, model];
563
- }
564
- /** Add Codex fast-mode flags before the prompt/positional separator. */
565
- export function appendFastModeFlags(provider, args, enabled) {
566
- if (provider !== "codex" || enabled !== true)
567
- return args;
568
- const flags = [...CODEX_FAST_MODE_FLAGS];
569
- const end = args.indexOf("--");
570
- if (end === -1)
571
- return [...args, ...flags];
572
- return [...args.slice(0, end), ...flags, ...args.slice(end)];
573
- }
574
- function appendProviderProfileFlags(provider, args, profile) {
575
- if (profile === undefined)
576
- return args;
577
- const ignored = new Set(profile.ignoredFields ?? []);
578
- switch (provider) {
579
- case "claude": {
580
- const flags = [
581
- "--append-system-prompt",
582
- profile.systemPrompt,
583
- // A profile is a per-spawn input. Do not let Claude's session resume
584
- // snapshot hide a changed profile from the next launch.
585
- "--system-prompt-snapshot",
586
- "off",
587
- ...(profile.settingsPath !== undefined && !ignored.has("settings")
588
- ? ["--settings", profile.settingsPath]
589
- : []),
590
- ];
591
- return [...args, ...flags];
592
- }
593
- case "codex": {
594
- const flags = ["-c", `developer_instructions=${JSON.stringify(profile.systemPrompt)}`];
595
- const end = args.indexOf("--");
596
- if (end === -1)
597
- return [...args, ...flags];
598
- return [...args.slice(0, end), ...flags, ...args.slice(end)];
599
- }
600
- case "grok":
601
- return [...args, "--rules", profile.systemPrompt];
602
- default: {
603
- const _exhaustive = provider;
604
- return _exhaustive;
605
- }
606
- }
607
- }
608
- /** Make the worker policy directory available to Codex hook subprocesses. */
609
- function appendCodexWorkerPolicyDirFlag(provider, args, workerPolicyDir) {
610
- if (provider !== "codex" || workerPolicyDir === undefined)
611
- return args;
612
- if (!workerPolicyDir.trim()) {
613
- throw new LanesError("invalid_worker_policy_dir", "Worker policy directory must not be empty");
614
- }
615
- const setting = `shell_environment_policy.set.HQ_POLICY_WORKER_DIR=${JSON.stringify(workerPolicyDir)}`;
616
- const separator = args.indexOf("--");
617
- if (separator === -1)
618
- return [...args, "-c", setting];
619
- return [...args.slice(0, separator), "-c", setting, ...args.slice(separator)];
620
- }
621
- function accountHomeHostname(deps) {
622
- return (deps.hostname?.trim() ||
623
- deps.admissionHost?.hostname.trim() ||
624
- resolveAdmissionHost().hostname);
625
- }
626
- export const PID_LIVENESS_DECISIONS = [
627
- "esrch",
628
- "starttime_mismatch",
629
- "eperm",
630
- "starttime_match",
631
- "no_recorded_starttime",
632
- "starttime_unreadable",
633
- "missing_pid_file",
634
- ];
635
- export function missingPidProbe() {
636
- return {
637
- pid: null,
638
- recorded_starttime: null,
639
- live_starttime: null,
640
- starttime_error: "ENOENT",
641
- alive: false,
642
- decided_by: "missing_pid_file",
643
- };
644
- }
645
- export function defaultPidIsAlive(pid) {
646
- try {
647
- process.kill(pid, 0);
648
- return true;
649
- }
650
- catch (err) {
651
- const code = err.code;
652
- if (code === "ESRCH")
653
- return false;
654
- if (code === "EPERM")
655
- return true;
656
- throw err;
657
- }
658
- }
659
- export const STOP_TERM_WAIT_MS = 500;
660
- export const STOP_KILL_WAIT_MS = 200;
661
- const defaultSpawnProcess = (command, args, options) => spawn(command, args, options);
662
- function defaultKillProcess(pid, signal = "SIGTERM") {
663
- process.kill(pid, signal);
664
- }
665
- export function parseSpawnTerminalReason(value) {
666
- if (SPAWN_TERMINAL_REASONS.includes(value)) {
667
- return value;
668
- }
669
- throw new LanesError("unknown_spawn_reason", `Unknown spawn terminal reason ${JSON.stringify(value)}. Accepted: ${SPAWN_TERMINAL_REASONS.join(", ")}`, { accepted: [...SPAWN_TERMINAL_REASONS], value });
670
- }
671
- export function laneRunDir(hqRoot, laneId) {
672
- return path.join(hqRoot, LANES_RUNS_REL, laneId);
673
- }
674
- export function watcherMainPath() {
675
- return fileURLToPath(new URL("./watcher-main.js", import.meta.url));
676
- }
677
- export function parseProcStat(text) {
678
- const open = text.indexOf("(");
679
- const close = text.lastIndexOf(")");
680
- if (open <= 0 || close <= open) {
681
- throw new LanesError("proc_stat_unreadable", "Could not parse /proc/<pid>/stat", { text: text.slice(0, 120) });
682
- }
683
- const pid = Number(text.slice(0, open).trim());
684
- const rest = text.slice(close + 1).trim().split(/\s+/);
685
- const ppid = Number(rest[1]);
686
- const pgrp = Number(rest[2]);
687
- const session = Number(rest[3]);
688
- if (![pid, ppid, pgrp, session].every((n) => Number.isInteger(n))) {
689
- throw new LanesError("proc_stat_unreadable", "Could not parse pid/ppid/pgrp/session from /proc/<pid>/stat", { text: text.slice(0, 120) });
690
- }
691
- // /proc/<pid>/stat fields are 1-indexed and `rest` begins at field 3 (state),
692
- // so field N lives at rest[N - 3]. starttime is field 22 -> rest[19].
693
- // rest[21] is field 24 (rss), which at spawn is a page count like 1 and grows
694
- // as the process runs — recording it made every fresh lane look dead within
695
- // seconds of starting.
696
- const startRaw = rest[19];
697
- const starttime = startRaw !== undefined ? Number(startRaw) : undefined;
698
- return {
699
- pid,
700
- ppid,
701
- pgrp,
702
- session,
703
- starttime: Number.isInteger(starttime) ? starttime : undefined,
704
- };
705
- }
706
- export function readProcStarttimeDetailed(pid) {
707
- const proc = path.join("/proc", String(pid), "stat");
708
- try {
709
- const starttime = parseProcStat(fs.readFileSync(proc, "utf8")).starttime;
710
- if (starttime === undefined)
711
- return { starttime: null, error: "missing_field" };
712
- return { starttime, error: null };
713
- }
714
- catch (err) {
715
- const code = err.code;
716
- if (code === "ENOENT")
717
- return { starttime: null, error: "ENOENT" };
718
- process.stderr.write(`hq lanes: failed to read starttime for pid ${pid}: ${err instanceof Error ? err.message : String(err)}\n`);
719
- return {
720
- starttime: null,
721
- error: typeof code === "string" ? code : "unreadable",
722
- };
723
- }
724
- }
725
- export function readProcStarttime(pid) {
726
- return readProcStarttimeDetailed(pid).starttime;
727
- }
728
- export function formatPidRecord(rec) {
729
- return rec.starttime !== undefined ? `${rec.pid} ${rec.starttime}\n` : `${rec.pid}\n`;
730
- }
731
- export function parsePidRecord(text) {
732
- const tokens = text.trim().split(/\s+/);
733
- const pid = Number(tokens[0]);
734
- if (!Number.isInteger(pid) || pid <= 0)
735
- return null;
736
- const starttime = tokens[1] !== undefined ? Number(tokens[1]) : undefined;
737
- return {
738
- pid,
739
- starttime: Number.isInteger(starttime) ? starttime : undefined,
740
- };
741
- }
742
- export function readPidRecord(filePath) {
743
- try {
744
- return parsePidRecord(fs.readFileSync(filePath, "utf8"));
745
- }
746
- catch (err) {
747
- const code = err.code;
748
- if (code === "ENOENT")
749
- return null;
750
- process.stderr.write(`hq lanes: failed to read pid file ${filePath}: ${err instanceof Error ? err.message : String(err)}\n`);
751
- throw err;
752
- }
753
- }
754
- export function writePidRecord(filePath, rec) {
755
- writeText(filePath, formatPidRecord(rec));
756
- }
757
- export function probePidRecord(rec, isAlive = defaultPidIsAlive, readStarttime = readProcStarttime) {
758
- const recorded = rec.starttime ?? null;
759
- const base = { pid: rec.pid, recorded_starttime: recorded };
760
- let killAlive;
761
- let killDecision = "starttime_match";
762
- try {
763
- killAlive = isAlive(rec.pid);
764
- }
765
- catch (err) {
766
- const code = err.code;
767
- if (code === "ESRCH") {
768
- return {
769
- ...base,
770
- live_starttime: null,
771
- starttime_error: null,
772
- alive: false,
773
- decided_by: "esrch",
774
- };
775
- }
776
- if (code === "EPERM") {
777
- killAlive = true;
778
- killDecision = "eperm";
779
- }
780
- else {
781
- throw err;
782
- }
783
- }
784
- if (!killAlive) {
785
- return {
786
- ...base,
787
- live_starttime: null,
788
- starttime_error: null,
789
- alive: false,
790
- decided_by: "esrch",
791
- };
792
- }
793
- if (recorded === null) {
794
- return {
795
- ...base,
796
- live_starttime: null,
797
- starttime_error: null,
798
- alive: true,
799
- decided_by: killDecision === "eperm" ? "eperm" : "no_recorded_starttime",
800
- };
801
- }
802
- let live;
803
- let starttime_error = null;
804
- try {
805
- live = readStarttime(rec.pid);
806
- if (live === null)
807
- starttime_error = "unreadable";
808
- }
809
- catch (err) {
810
- const code = err.code;
811
- live = null;
812
- starttime_error = typeof code === "string" ? code : "unreadable";
813
- }
814
- if (live === null) {
815
- return {
816
- ...base,
817
- live_starttime: null,
818
- starttime_error,
819
- alive: true,
820
- decided_by: "starttime_unreadable",
821
- };
822
- }
823
- if (live !== recorded) {
824
- return {
825
- ...base,
826
- live_starttime: live,
827
- starttime_error: null,
828
- alive: false,
829
- decided_by: "starttime_mismatch",
830
- };
831
- }
832
- return {
833
- ...base,
834
- live_starttime: live,
835
- starttime_error: null,
836
- alive: true,
837
- decided_by: killDecision === "eperm" ? "eperm" : "starttime_match",
838
- };
839
- }
840
- export function isPidRecordAlive(rec, isAlive = defaultPidIsAlive, readStarttime = readProcStarttime) {
841
- return probePidRecord(rec, isAlive, readStarttime).alive;
842
- }
843
- function blockingSleep(ms) {
844
- Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
845
- }
846
- export function signalProcessGroup(pid, signal, killProcess) {
847
- try {
848
- killProcess(-pid, signal);
849
- return;
850
- }
851
- catch (err) {
852
- const code = err.code;
853
- if (code === "ESRCH")
854
- return;
855
- if (code !== "EINVAL" && code !== "EPERM") {
856
- process.stderr.write(`hq lanes: process-group ${signal} for pid ${pid} failed: ${err instanceof Error ? err.message : String(err)}\n`);
857
- }
858
- }
859
- try {
860
- killProcess(pid, signal);
861
- }
862
- catch (err) {
863
- const code = err.code;
864
- if (code === "ESRCH")
865
- return;
866
- process.stderr.write(`hq lanes: ${signal} for pid ${pid} failed: ${err instanceof Error ? err.message : String(err)}\n`);
867
- throw err;
868
- }
869
- }
870
- export function stopLaneProcesses(hqRoot, laneId, deps = {}) {
871
- const killProcess = deps.killProcess ?? defaultKillProcess;
872
- const isAlive = deps.isAlive ??
873
- ((pid) => {
874
- try {
875
- process.kill(pid, 0);
876
- return true;
877
- }
878
- catch (err) {
879
- const code = err.code;
880
- if (code === "ESRCH")
881
- return false;
882
- if (code === "EPERM")
883
- return true;
884
- throw err;
885
- }
886
- });
887
- const sleepMs = deps.sleepMs ?? blockingSleep;
888
- const readStarttime = deps.readStarttime ?? readProcStarttime;
889
- const runDir = laneRunDir(hqRoot, laneId);
890
- const worker = readPidRecord(path.join(runDir, "worker.pid"));
891
- const watcher = readPidRecord(path.join(runDir, "watcher.pid"));
892
- const signals = [];
893
- const targets = [worker, watcher].filter((rec) => rec !== null);
894
- const fire = (rec, signal) => {
895
- if (!isPidRecordAlive(rec, isAlive, readStarttime))
896
- return;
897
- signals.push({ pid: rec.pid, signal, group: true });
898
- signalProcessGroup(rec.pid, signal, killProcess);
899
- };
900
- for (const rec of targets)
901
- fire(rec, "SIGTERM");
902
- if (targets.some((rec) => isPidRecordAlive(rec, isAlive, readStarttime))) {
903
- sleepMs(STOP_TERM_WAIT_MS);
904
- }
905
- for (const rec of targets) {
906
- if (isPidRecordAlive(rec, isAlive, readStarttime))
907
- fire(rec, "SIGKILL");
908
- }
909
- return { worker, watcher, signals };
910
- }
911
- export function defaultProveDetached(pid, deps = {}) {
912
- const proc = path.join("/proc", String(pid), "stat");
913
- try {
914
- const text = deps.readProcStatText
915
- ? deps.readProcStatText(pid)
916
- : fs.readFileSync(proc, "utf8");
917
- const parsed = parseProcStat(text);
918
- const leader = parsed.pid === pid && parsed.pgrp === parsed.pid && parsed.session === parsed.pgrp;
919
- return {
920
- detached: leader,
921
- pid,
922
- pgid: parsed.pgrp,
923
- sid: parsed.session,
924
- method: "proc_stat_session_leader",
925
- reason: leader ? undefined : "not_session_leader",
926
- };
927
- }
928
- catch (err) {
929
- const code = err.code;
930
- if (code !== "ENOENT") {
931
- process.stderr.write(`hq lanes: failed to read ${proc}: ${err instanceof Error ? err.message : String(err)}\n`);
932
- throw err;
933
- }
934
- }
935
- try {
936
- process.kill(pid, 0);
937
- }
938
- catch (err) {
939
- const code = err.code;
940
- if (code === "ESRCH") {
941
- return { detached: false, pid, method: "pid_alive", reason: "pid_not_alive" };
942
- }
943
- if (code !== "EPERM") {
944
- process.stderr.write(`hq lanes: liveness probe for pid ${pid} failed: ${err instanceof Error ? err.message : String(err)}\n`);
945
- throw err;
946
- }
947
- }
948
- const psProof = proveDetachedViaPs(pid);
949
- if (psProof)
950
- return psProof;
951
- return {
952
- detached: false,
953
- pid,
954
- method: "pid_alive_without_proc",
955
- reason: "not_session_leader",
956
- };
957
- }
958
- function proveDetachedViaPs(pid) {
959
- try {
960
- const result = spawnSync("ps", ["-p", String(pid), "-o", "pid=,pgid="], {
961
- encoding: "utf8",
962
- timeout: 500,
963
- });
964
- if (result.error || result.status !== 0)
965
- return null;
966
- const parts = (result.stdout ?? "").trim().split(/\s+/).map(Number);
967
- if (parts.length < 2 || parts.some((n) => !Number.isInteger(n)))
968
- return null;
969
- const psPid = parts[0];
970
- const pgid = parts[1];
971
- const leader = psPid === pid && pgid === pid;
972
- return {
973
- detached: leader,
974
- pid,
975
- pgid,
976
- method: "ps_session_leader",
977
- reason: leader ? undefined : "not_session_leader",
978
- };
979
- }
980
- catch (err) {
981
- process.stderr.write(`hq lanes: ps detach proof failed for pid ${pid}: ${err instanceof Error ? err.message : String(err)}\n`);
982
- return null;
983
- }
984
- }
985
- export function nextEnvelopePath(runDir) {
986
- const dir = path.join(runDir, "envelopes");
987
- let n = 1;
988
- while (true) {
989
- const name = `${String(n).padStart(3, "0")}.json`;
990
- const filePath = path.join(dir, name);
991
- if (!fs.existsSync(filePath))
992
- return filePath;
993
- n += 1;
994
- if (n > 999) {
995
- throw new LanesError("envelope_sequence_exhausted", `No free envelope slot under ${dir}`, { dir });
996
- }
997
- }
998
- }
999
- export function envelopeInstruction(envelopePath) {
1000
- return (`When finished, write a JSON object to ${envelopePath} using these key names exactly: ` +
1001
- `schema_version, decision, summary, story_status, artifacts, story_complete, story_complete_reason, questions, blocked_reason, next_check_at. ` +
1002
- `schema_version must be the exact string "hq-lane-envelope.v1". ` +
1003
- `decision must be one of "done", "ask", "blocked". ` +
1004
- `summary is a string. ` +
1005
- `story_status must be one of "queued", "in_progress", "review", "done". ` +
1006
- `artifacts is an array. ` +
1007
- `story_complete is a boolean and story_complete_reason is a non-empty string. ` +
1008
- `story_complete true requires story_status done and a reason stating what was delivered and how it was verified. ` +
1009
- `story_complete false requires story_status other than done and a reason stating what is still missing. ` +
1010
- `questions is present and non-empty exactly when decision is "ask". ` +
1011
- `blocked_reason is present exactly when decision is "blocked". ` +
1012
- `next_check_at is optional; when present, use an ISO date-time for the next time-based keep-alive check.`);
1013
- }
1014
- /**
1015
- * Standing authorization carried by every brief and every resume turn. A
1016
- * lane that ends each turn asking "continue or stop" has asked the operator
1017
- * to re-grant what the brief already granted; the paragraph names that as
1018
- * out of bounds and says what a `decision: ask` envelope is for.
1019
- */
1020
- export const STANDING_AUTHORIZATION = "STANDING AUTHORIZATION. This brief authorises completing every item it lists; " +
1021
- "you do not need to ask before finishing any of them. " +
1022
- 'A "decision": "ask" envelope is only for a decision this brief does not settle, ' +
1023
- "and it must name that decision and its options. " +
1024
- 'Do not raise a question whose options amount to "continue" or "stop" the work this brief describes; ' +
1025
- "continue that work until it is complete or you are blocked on something only the operator can supply.";
1026
- /**
1027
- * Foreground-only rule carried next to the standing authorization. Two lanes
1028
- * ended `interrupted` after backgrounding a slow test suite and ending the
1029
- * turn while it was still running; nothing in the brief said not to.
1030
- */
1031
- export const FOREGROUND_ONLY_RULE = "FOREGROUND ONLY. Run every command, test suite and check in the foreground and wait for it to finish. " +
1032
- "Never background a process and end the turn while it is still running. " +
1033
- "A turn that ends before the envelope is written is classified interrupted, " +
1034
- "and whatever the background process produces afterwards is not read.";
1035
- /**
1036
- * The answers as written by the reconcile pass (`answered-questions.json`),
1037
- * reduced to id + choice. A malformed file reads as no inline answers; the
1038
- * path is still named so the worker can read it.
1039
- */
1040
- export function readAnsweredQuestionLines(answersPath) {
1041
- let text;
1042
- try {
1043
- text = fs.readFileSync(answersPath, "utf8");
1044
- }
1045
- catch (err) {
1046
- const code = err.code;
1047
- if (code === "ENOENT")
1048
- return [];
1049
- process.stderr.write(`hq lanes: failed to read ${answersPath}: ${err instanceof Error ? err.message : String(err)}\n`);
1050
- throw err;
1051
- }
1052
- let parsed;
1053
- try {
1054
- parsed = JSON.parse(text);
1055
- }
1056
- catch (err) {
1057
- throw new LanesError("answered_questions_invalid", `Answered questions at ${answersPath} are not valid JSON`, { path: answersPath });
1058
- }
1059
- if (!Array.isArray(parsed)) {
1060
- throw new LanesError("answered_questions_invalid", `Answered questions at ${answersPath} must be a JSON array`, { path: answersPath });
1061
- }
1062
- const out = [];
1063
- for (const [index, item] of parsed.entries()) {
1064
- if (!item || typeof item !== "object" || Array.isArray(item)) {
1065
- throw new LanesError("answered_questions_invalid", `Answered question ${index} at ${answersPath} must be an object`, { path: answersPath, index });
1066
- }
1067
- const rec = item;
1068
- if (typeof rec.question_id !== "string" || !rec.question_id.trim()) {
1069
- throw new LanesError("answered_questions_invalid", `Answered question ${index} at ${answersPath} must have a question_id`, { path: answersPath, index });
1070
- }
1071
- if (typeof rec.choice !== "string") {
1072
- throw new LanesError("answered_questions_invalid", `Answered question ${rec.question_id} at ${answersPath} must have a choice`, { path: answersPath, question_id: rec.question_id });
1073
- }
1074
- const line = {
1075
- question_id: rec.question_id,
1076
- choice: rec.choice,
1077
- };
1078
- if (rec.notes !== undefined && typeof rec.notes !== "string") {
1079
- throw new LanesError("answered_questions_invalid", `Answered question ${rec.question_id} at ${answersPath} has invalid notes`, { path: answersPath, question_id: rec.question_id });
1080
- }
1081
- if (typeof rec.notes === "string" && rec.notes.length > 0)
1082
- line.notes = rec.notes;
1083
- out.push(line);
1084
- }
1085
- return out;
1086
- }
1087
- export function resumePrompt(input) {
1088
- const parts = [];
1089
- if (input.resumedFrom !== undefined) {
1090
- parts.push(`${input.resumeSource === "watcher" ? "The lane watcher" : "The operator"} resumed this lane from state ${input.resumedFrom}. ` +
1091
- (input.resumedFrom === "interrupted"
1092
- ? "The previous run ended without writing its envelope; continue the work from where it stopped."
1093
- : "Continue the work from where the previous run stopped."));
1094
- }
1095
- if (input.monitorEvent !== undefined) {
1096
- parts.push(input.monitorEvent);
1097
- }
1098
- else if (input.operatorMessage !== undefined) {
1099
- parts.push("OPERATOR INSTRUCTION (outranks the lane brief). " +
1100
- "The following message was sent to this lane by the operator. Treat it as an operator instruction that outranks the brief.\n\n" +
1101
- input.operatorMessage);
1102
- }
1103
- if (input.answersPath !== undefined) {
1104
- const lines = (input.answers ?? []).map((item) => item.notes !== undefined
1105
- ? `- ${item.question_id}: ${item.choice}\n Operator notes: ${item.notes}`
1106
- : `- ${item.question_id}: ${item.choice}`);
1107
- parts.push([
1108
- `Previously answered questions are at ${input.answersPath}; treat those choices and the operator notes under them as operator decisions that outrank the brief. Continue the work.`,
1109
- ...(lines.length > 0 ? ["Answers:", ...lines] : []),
1110
- ].join("\n"));
1111
- }
1112
- if (input.envelopeRepairErrors !== undefined) {
1113
- const errors = [input.envelopeRepairErrors.first_error, input.envelopeRepairErrors.second_error]
1114
- .filter((error) => typeof error === "string" && error.length > 0);
1115
- parts.push([
1116
- `The previous envelope repair failed validation. The next envelope slot is ${input.envelopePath}; write a new valid envelope there.`,
1117
- "Exact validation errors recorded in envelope_repair:",
1118
- ...errors.map((error, index) => `- envelope_repair.${index === 0 ? "first_error" : "second_error"}: ${JSON.stringify(error)}`),
1119
- "For an ask question, include non-empty id, question, and context fields.",
1120
- ].join("\n"));
1121
- }
1122
- // Every resume turn carries the authorization, including a textless
1123
- // `hq lanes resume`: a pre-upgrade session's brief never had the paragraph.
1124
- if (input.operatorMessage !== undefined ||
1125
- input.monitorEvent !== undefined ||
1126
- input.answersPath !== undefined ||
1127
- input.resumedFrom !== undefined) {
1128
- parts.push(STANDING_AUTHORIZATION);
1129
- parts.push(FOREGROUND_ONLY_RULE);
1130
- }
1131
- parts.push(envelopeInstruction(input.envelopePath));
1132
- return parts.join("\n\n");
1133
- }
1134
- /** Spec §4: the one repair turn. Schema, parser error, raw text, JSON only. */
1135
- export function envelopeRepairPrompt(input) {
1136
- const maxRawTextChars = 24_000;
1137
- const rawText = input.rawText.length <= maxRawTextChars
1138
- ? input.rawText
1139
- : `${input.rawText.slice(0, 12_000)}\n\n[... raw envelope truncated; inspect ${input.envelopePath} for the complete file ...]\n\n${input.rawText.slice(-12_000)}`;
1140
- if (input.missing) {
1141
- return [
1142
- `Missing expected envelope file: ${input.envelopePath}`,
1143
- "The previous envelope is stale and must not be reused or copied into this run's result.",
1144
- "Printing an envelope in the conversation or writing it to last-message.txt is not enough; write the JSON object directly to the expected file.",
1145
- "If the task is unfinished, write decision: done, story_complete: false, and set story_status and story_complete_reason to describe the work that remains. The repair turn itself is never a reason for blocked.",
1146
- "This repair turn only writes the missing envelope; do not resume the task.",
1147
- "Schema:",
1148
- JSON.stringify(LANE_ENVELOPE_JSON_SCHEMA, null, 2),
1149
- `Write the corrected JSON object to ${input.envelopePath}, overwriting it. ` +
1150
- `Output only that JSON. Do not add keys the schema does not name, and do not resume the task.`,
1151
- ].join("\n\n");
1152
- }
1153
- return [
1154
- `The file you wrote at ${input.envelopePath} is not a valid hq-lane-envelope.v1. ` +
1155
- `This is the single repair turn: rewrite that file so it validates, and do nothing else.`,
1156
- `Parser error: ${input.error}`,
1157
- "For an ask question, include non-empty id, question, and context fields.",
1158
- "Schema:",
1159
- JSON.stringify(LANE_ENVELOPE_JSON_SCHEMA, null, 2),
1160
- "Your previous output was:",
1161
- rawText,
1162
- `Write the corrected JSON object to ${input.envelopePath}, overwriting it. ` +
1163
- `Output only that JSON. Do not add keys the schema does not name, and do not resume the task.`,
1164
- ].join("\n\n");
1165
- }
1166
- export function buildProviderCommand(provider, input) {
1167
- const parsed = parseLaneProvider(provider);
1168
- const command = PROVIDER_COMMAND[parsed];
1169
- if (input.resume && !providerSupportsSessionResume(parsed)) {
1170
- throw new LanesError("resume_unsupported", `Provider ${parsed} cannot resume an exited worker from a session id`, { provider: parsed });
1171
- }
1172
- if (input.resume && input.freshTurnPrompt !== undefined) {
1173
- throw new LanesError("invalid_launch", "resume and freshTurnPrompt cannot both be set on one launch", { provider: parsed });
1174
- }
1175
- let prompt;
1176
- if (input.freshTurnPrompt !== undefined) {
1177
- prompt = input.freshTurnPrompt;
1178
- }
1179
- else {
1180
- prompt = `Execute the lane brief at ${input.briefPath}. ${envelopeInstruction(input.envelopePath)}`;
1181
- if (input.extraPrompt)
1182
- prompt += ` ${input.extraPrompt}`;
1183
- }
1184
- let args;
1185
- if (input.resume && parsed === "codex") {
1186
- // `codex exec resume` (0.155.1) takes `[SESSION_ID] [PROMPT]` and has
1187
- // neither `-C` nor `--color`; the session keeps its recorded cwd. `--json`
1188
- // makes the resumed run re-emit `thread.started` with the same id.
1189
- args = [
1190
- "exec",
1191
- "resume",
1192
- "--dangerously-bypass-hook-trust",
1193
- "--skip-git-repo-check",
1194
- "--dangerously-bypass-approvals-and-sandbox",
1195
- "--json",
1196
- "--output-last-message",
1197
- input.lastMessagePath,
1198
- "--",
1199
- input.resume.session_id,
1200
- input.resume.prompt,
1201
- ];
1202
- }
1203
- else if (input.resume && parsed === "grok") {
1204
- // `grok --single <prompt> --resume <id>` (1.0.34) continues the recorded
1205
- // session and prints the same `sessionId` in its JSON result.
1206
- args = [
1207
- "--single",
1208
- input.resume.prompt,
1209
- "--resume",
1210
- input.resume.session_id,
1211
- "--permission-mode",
1212
- "bypassPermissions",
1213
- "--always-approve",
1214
- "--output-format",
1215
- "json",
1216
- ];
1217
- }
1218
- else if (input.resume) {
1219
- args = [
1220
- "-p",
1221
- "--resume",
1222
- input.resume.session_id,
1223
- input.resume.prompt,
1224
- "--permission-mode",
1225
- "bypassPermissions",
1226
- "--output-format",
1227
- "json",
1228
- ];
1229
- }
1230
- else if (parsed === "codex") {
1231
- // `--json` puts the thread id on stdout (`thread.started`); that is the
1232
- // only place `codex exec` exposes the id a later resume needs.
1233
- args = [
1234
- "exec",
1235
- "--dangerously-bypass-hook-trust",
1236
- "--skip-git-repo-check",
1237
- "--dangerously-bypass-approvals-and-sandbox",
1238
- "--color",
1239
- "never",
1240
- "--json",
1241
- "-C",
1242
- input.hqRoot,
1243
- "--output-last-message",
1244
- input.lastMessagePath,
1245
- "--",
1246
- prompt,
1247
- ];
1248
- }
1249
- else if (parsed === "grok") {
1250
- args = [
1251
- "--single",
1252
- prompt,
1253
- "--permission-mode",
1254
- "bypassPermissions",
1255
- "--always-approve",
1256
- "--output-format",
1257
- "json",
1258
- ];
1259
- }
1260
- else {
1261
- args = [
1262
- "-p",
1263
- prompt,
1264
- "--permission-mode",
1265
- "bypassPermissions",
1266
- "--output-format",
1267
- "json",
1268
- ];
1269
- }
1270
- return {
1271
- command,
1272
- args: appendFastModeFlags(parsed, appendEffortFlag(parsed, appendModelFlag(parsed, appendCodexWorkerPolicyDirFlag(parsed, appendProviderProfileFlags(parsed, args, input.profile), input.workerPolicyDir), input.model), input.effort), input.fastMode),
1273
- };
1274
- }
1275
- export function workerEnv(base, resolved, laneId, hqRoot, autoCompactTokens, meshCompany, workerPolicyDir, registryWorker) {
1276
- const accepted = Object.values(PROVIDER_HOME_ENV);
1277
- if (!accepted.includes(resolved.envVar)) {
1278
- throw new LanesError("unknown_provider_home_env", `Unknown provider home variable ${JSON.stringify(resolved.envVar)}. Accepted: ${accepted.join(", ")}`, { accepted, value: resolved.envVar });
1279
- }
1280
- const env = { ...base };
1281
- delete env.HQ_PROJECT_ID;
1282
- delete env.HQ_STORY_ID;
1283
- delete env.HQ_POLICY_WORKER_DIR;
1284
- delete env.HQ_LANE_APPROVAL_REQUIRED;
1285
- delete env.HQ_LANE_HUMAN_CHECKPOINTS;
1286
- env[resolved.envVar] = resolved.home;
1287
- delete env[CLAUDE_AUTO_COMPACT_ENV];
1288
- if (resolved.envVar === PROVIDER_HOME_ENV.claude && autoCompactTokens !== undefined) {
1289
- env[CLAUDE_AUTO_COMPACT_ENV] = String(autoCompactTokens);
1290
- }
1291
- env.HQ_LANE_ID = laneId;
1292
- env.HQ_ROOT = hqRoot;
1293
- if (registryWorker && (registryWorker.approval_required || registryWorker.human_checkpoints.length > 0)) {
1294
- env.HQ_LANE_APPROVAL_REQUIRED = "1";
1295
- env.HQ_LANE_HUMAN_CHECKPOINTS = registryWorker.human_checkpoints.length > 0
1296
- ? registryWorker.human_checkpoints.join(",")
1297
- : "external_publish";
1298
- }
1299
- if (workerPolicyDir !== undefined &&
1300
- (resolved.envVar === PROVIDER_HOME_ENV.claude || resolved.envVar === PROVIDER_HOME_ENV.codex)) {
1301
- env.HQ_POLICY_WORKER_DIR = workerPolicyDir;
1302
- }
1303
- if (meshCompany) {
1304
- env.HQ_SPAWN_COMPANY = meshCompany.slug || meshCompany.uid;
1305
- }
1306
- else {
1307
- delete env.HQ_SPAWN_COMPANY;
1308
- }
1309
- return env;
1310
- }
1311
- export const WORKER_POLICY_HOOK_CAPABILITY = "# hq-capability: worker-policy-dir v1";
1312
- function installedWorkerPolicyHookSupportsDirectory(hqRoot) {
1313
- const hookPath = path.join(hqRoot, ".claude", "hooks", "inject-policy-on-trigger.sh");
1314
- try {
1315
- return fs.readFileSync(hookPath, "utf8")
1316
- .split(/\r?\n/)
1317
- .some((line) => line === WORKER_POLICY_HOOK_CAPABILITY);
1318
- }
1319
- catch (err) {
1320
- const code = err.code;
1321
- if (code === "ENOENT")
1322
- return false;
1323
- process.stderr.write(`hq lanes: cannot inspect worker-policy hook capability at ${hookPath}: ${err instanceof Error ? err.message : String(err)}; keeping policy prompt delivery\n`);
1324
- return false;
1325
- }
1326
- }
1327
- /** Grok does not run HQ hooks; Claude and Codex use the installed capability marker. */
1328
- export function workerPolicyDeliveryMode(hqRoot, provider) {
1329
- return provider !== "grok" && installedWorkerPolicyHookSupportsDirectory(hqRoot)
1330
- ? "hook"
1331
- : "prompt";
1332
- }
1333
- function ensureDir(dir) {
1334
- fs.mkdirSync(dir, { recursive: true });
1335
- }
1336
- function fileSizeOrZero(filePath) {
1337
- try {
1338
- return fs.statSync(filePath).size;
1339
- }
1340
- catch (err) {
1341
- const code = err.code;
1342
- if (code === "ENOENT")
1343
- return 0;
1344
- process.stderr.write(`hq lanes: failed to stat ${filePath}: ${err instanceof Error ? err.message : String(err)}\n`);
1345
- throw err;
1346
- }
1347
- }
1348
- function writeText(filePath, text) {
1349
- ensureDir(path.dirname(filePath));
1350
- fs.writeFileSync(filePath, text, "utf8");
1351
- }
1352
- function appendWorkerProfileEvent(runDir, event) {
1353
- const eventsPath = path.join(runDir, "watcher", "profile-events.jsonl");
1354
- ensureDir(path.dirname(eventsPath));
1355
- fs.appendFileSync(eventsPath, `${JSON.stringify({
1356
- event: "profile_applied",
1357
- ...event,
1358
- at: new Date().toISOString(),
1359
- })}\n`);
1360
- }
1361
- function openLog(filePath) {
1362
- ensureDir(path.dirname(filePath));
1363
- return fs.openSync(filePath, "a");
1364
- }
1365
- function closeFd(fd, label) {
1366
- try {
1367
- fs.closeSync(fd);
1368
- }
1369
- catch (err) {
1370
- process.stderr.write(`hq lanes: failed to close ${label} fd ${fd}: ${err instanceof Error ? err.message : String(err)}\n`);
1371
- throw err;
1372
- }
1373
- }
1374
- function killQuietly(kill, pid, label) {
1375
- try {
1376
- signalProcessGroup(pid, "SIGTERM", kill);
1377
- }
1378
- catch (err) {
1379
- const code = err.code;
1380
- if (code === "ESRCH")
1381
- return;
1382
- process.stderr.write(`hq lanes: failed to stop ${label} pid ${pid}: ${err instanceof Error ? err.message : String(err)}\n`);
1383
- throw err;
1384
- }
1385
- }
1386
- export function markSpawnFailure(hqRoot, laneId, reasonRaw, details) {
1387
- const reason = parseSpawnTerminalReason(reasonRaw);
1388
- return retryUpdateLane(hqRoot, laneId, "spawn", (current) => {
1389
- const existing = current
1390
- .terminal_reason;
1391
- if (current.state === "failed" && existing === reason)
1392
- return current;
1393
- return {
1394
- ...current,
1395
- state: "failed",
1396
- queued_reason: undefined,
1397
- queued_details: undefined,
1398
- queued_at: undefined,
1399
- admission_reserved_at: undefined,
1400
- terminal_reason: reason,
1401
- terminal_details: details,
1402
- };
1403
- });
1404
- }
1405
- function spawnDetached(spawnProcess, command, args, env, cwd, stdoutPath, stderrPath) {
1406
- const outFd = openLog(stdoutPath);
1407
- let errFd;
1408
- try {
1409
- errFd = openLog(stderrPath);
1410
- const child = spawnProcess(command, args, {
1411
- detached: true,
1412
- windowsHide: true,
1413
- stdio: ["ignore", outFd, errFd],
1414
- env,
1415
- cwd,
1416
- });
1417
- child.unref();
1418
- if (typeof child.pid !== "number" || child.pid <= 0) {
1419
- throw new LanesError("spawn_failed", `Failed to start ${command} (no pid)`, { command, args });
1420
- }
1421
- return child.pid;
1422
- }
1423
- catch (err) {
1424
- if (err instanceof LanesError)
1425
- throw err;
1426
- throw new LanesError("spawn_failed", `Failed to start ${command}: ${err instanceof Error ? err.message : String(err)}`, {
1427
- command,
1428
- args,
1429
- message: err instanceof Error ? err.message : String(err),
1430
- });
1431
- }
1432
- finally {
1433
- closeFd(outFd, stdoutPath);
1434
- if (errFd !== undefined)
1435
- closeFd(errFd, stderrPath);
1436
- }
1437
- }
1438
- function requireDetached(proveDetached, pid, kind) {
1439
- const proof = proveDetached(pid);
1440
- if (proof.detached)
1441
- return proof;
1442
- const error = kind === "watcher" ? "watcher_not_armed" : "not_detached";
1443
- throw new LanesError(error, `${kind} pid ${pid} was not proven detached`, { pid, kind, reason: proof.reason ?? error, method: proof.method });
1444
- }
1445
- function originHostOf(lane) {
1446
- const value = lane.origin_host;
1447
- return typeof value === "string" ? value : "";
1448
- }
1449
- function originHostSourceOf(lane) {
1450
- const value = lane.origin_host_source;
1451
- return value === "imds" || value === "hostname" ? value : "";
1452
- }
1453
- function markOutpostSelfTarget(hqRoot, laneId, details) {
1454
- return retryUpdateLane(hqRoot, laneId, "spawn", (current) => {
1455
- const existing = current
1456
- .terminal_reason;
1457
- if (current.state === "cancelled" && existing === "outpost_self_target") {
1458
- return current;
1459
- }
1460
- return {
1461
- ...current,
1462
- state: "cancelled",
1463
- queued_reason: undefined,
1464
- queued_details: undefined,
1465
- terminal_reason: "outpost_self_target",
1466
- terminal_details: details,
1467
- };
1468
- });
1469
- }
1470
- /**
1471
- * Spec §5.2 executing-side check. Compares this machine's identity to
1472
- * `origin_host` (never to `host.id`). Unresolvable identity is a cancel.
1473
- * Must run before the worker is spawned.
1474
- */
1475
- export function refuseOutpostSelfTarget(hqRoot, lane, deps) {
1476
- const identity = (deps.resolveMachineIdentity ?? resolveMachineIdentity)();
1477
- const origin = originHostOf(lane);
1478
- const originSource = originHostSourceOf(lane);
1479
- let selfTargeted = origin === "" || identity.status !== "ok";
1480
- if (!selfTargeted && identity.status === "ok") {
1481
- if (originSource === "imds") {
1482
- const execImds = identity.imds ?? (identity.source === "imds" ? identity.id : null);
1483
- selfTargeted = execImds === null || execImds === origin;
1484
- }
1485
- else if (originSource === "hostname") {
1486
- const execHost = identity.hostname ??
1487
- (identity.source === "hostname" ? identity.id : null);
1488
- selfTargeted = execHost === null ? identity.id === origin : execHost === origin;
1489
- }
1490
- else {
1491
- selfTargeted = identity.id === origin;
1492
- }
1493
- }
1494
- if (!selfTargeted)
1495
- return;
1496
- const cancelled = markOutpostSelfTarget(hqRoot, lane.lane_id, {
1497
- origin_host: origin,
1498
- identity,
1499
- });
1500
- throw new LanesError("outpost_self_target", "Outpost exec came back to the caller; lane cancelled before work", {
1501
- origin_host: origin,
1502
- identity,
1503
- lane_id: lane.lane_id,
1504
- lane: cancelled,
1505
- });
1506
- }
1507
- function writeSpawnManifest(runDir, input) {
1508
- writeText(path.join(runDir, "spawn.json"), `${JSON.stringify({
1509
- command: input.command,
1510
- args: input.args,
1511
- env_var: input.envVar,
1512
- account: input.account,
1513
- worker_pid: input.workerPid,
1514
- watcher_pid: input.watcherPid,
1515
- detached: true,
1516
- envelope_path: input.envelopePath,
1517
- ...(input.turnId !== undefined ? { turn_id: input.turnId } : {}),
1518
- resume: input.resume,
1519
- worker_out_offset: input.workerOutOffset,
1520
- ...(input.fastMode ? { fast_mode: true } : {}),
1521
- ...(input.profile
1522
- ? {
1523
- worker_profile: input.profile.id,
1524
- worker_profile_hash: input.profile.hash,
1525
- worker_profile_ignored: [...input.profile.ignoredFields],
1526
- worker_policy_delivery: input.profile.policyDelivery,
1527
- ...(input.profile.policyDir !== undefined
1528
- ? {
1529
- worker_policy_dir: input.profile.policyDir,
1530
- worker_policy_env: { HQ_POLICY_WORKER_DIR: input.profile.policyDir },
1531
- }
1532
- : {}),
1533
- ...(input.profile.settingsPath
1534
- ? { worker_profile_settings: input.profile.settingsPath }
1535
- : {}),
1536
- }
1537
- : {}),
1538
- }, null, 2)}\n`);
1539
- }
1540
- /** Arm (or re-arm) the detached per-lane watcher. */
1541
- export function armLaneWatcher(hqRoot, laneId, deps = {}) {
1542
- const env = deps.env ?? process.env;
1543
- const spawnProcess = deps.spawnProcess ?? defaultSpawnProcess;
1544
- const proveDetached = deps.proveDetached ?? defaultProveDetached;
1545
- const runDir = laneRunDir(hqRoot, laneId);
1546
- const logsDir = path.join(runDir, "logs");
1547
- ensureDir(logsDir);
1548
- const cliEntry = deps.hqCliEntry?.trim() || process.argv[1]?.trim();
1549
- if (!cliEntry) {
1550
- throw new LanesError("watcher_cli_entry_unavailable", "Cannot arm the lane watcher without the current hq CLI entrypoint", { lane_id: laneId });
1551
- }
1552
- const watcherPid = spawnDetached(spawnProcess, process.execPath, [watcherMainPath(), laneId], {
1553
- ...env,
1554
- HQ_ROOT: hqRoot,
1555
- HQ_LANE_ID: laneId,
1556
- HQ_LANE_CLI_ENTRY: path.resolve(cliEntry),
1557
- }, hqRoot, path.join(logsDir, "watcher.out"), path.join(logsDir, "watcher.err"));
1558
- writePidRecord(path.join(runDir, "watcher.pid"), {
1559
- pid: watcherPid,
1560
- starttime: readProcStarttime(watcherPid) ?? undefined,
1561
- });
1562
- try {
1563
- requireDetached(proveDetached, watcherPid, "watcher");
1564
- }
1565
- catch (err) {
1566
- killQuietly(deps.killProcess ?? defaultKillProcess, watcherPid, "watcher");
1567
- throw err;
1568
- }
1569
- return watcherPid;
1570
- }
1571
- /** Read the per-run manifest. Missing file or field reads as absent. */
1572
- export function readSpawnManifest(runDir) {
1573
- const filePath = path.join(runDir, "spawn.json");
1574
- let text;
1575
- try {
1576
- text = fs.readFileSync(filePath, "utf8");
1577
- }
1578
- catch (err) {
1579
- const code = err.code;
1580
- if (code === "ENOENT")
1581
- return {};
1582
- process.stderr.write(`hq lanes: failed to read ${filePath}: ${err instanceof Error ? err.message : String(err)}\n`);
1583
- throw err;
1584
- }
1585
- let parsed;
1586
- try {
1587
- parsed = JSON.parse(text);
1588
- }
1589
- catch (err) {
1590
- process.stderr.write(`hq lanes: ${filePath} is not valid JSON: ${err instanceof Error ? err.message : String(err)}\n`);
1591
- return {};
1592
- }
1593
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
1594
- return {};
1595
- const rec = parsed;
1596
- const out = {};
1597
- if (typeof rec.envelope_path === "string")
1598
- out.envelope_path = rec.envelope_path;
1599
- if (typeof rec.turn_id === "string")
1600
- out.turn_id = rec.turn_id;
1601
- if (typeof rec.provider_home_at_spawn === "string") {
1602
- out.provider_home_at_spawn = rec.provider_home_at_spawn;
1603
- }
1604
- if (typeof rec.worker_out_offset === "number" &&
1605
- Number.isInteger(rec.worker_out_offset) &&
1606
- rec.worker_out_offset >= 0) {
1607
- out.worker_out_offset = rec.worker_out_offset;
1608
- }
1609
- if (typeof rec.fast_mode === "boolean")
1610
- out.fast_mode = rec.fast_mode;
1611
- if (typeof rec.worker_profile === "string")
1612
- out.worker_profile = rec.worker_profile;
1613
- if (typeof rec.worker_profile_hash === "string")
1614
- out.worker_profile_hash = rec.worker_profile_hash;
1615
- if (Array.isArray(rec.worker_profile_ignored) && rec.worker_profile_ignored.every((item) => typeof item === "string")) {
1616
- out.worker_profile_ignored = rec.worker_profile_ignored;
1617
- }
1618
- if (typeof rec.worker_profile_settings === "string")
1619
- out.worker_profile_settings = rec.worker_profile_settings;
1620
- if (rec.resume &&
1621
- typeof rec.resume === "object" &&
1622
- typeof rec.resume.session_id === "string") {
1623
- out.resume = { session_id: rec.resume.session_id };
1624
- }
1625
- else if (rec.resume === null) {
1626
- out.resume = null;
1627
- }
1628
- return out;
1629
- }
1630
- function laneLaunchResult(lane) {
1631
- const { provider_home_at_spawn: _providerHomeAtSpawn, ...safe } = lane;
1632
- return safe;
1633
- }
1634
- function sameSeniorRef(a, b) {
1635
- return a.kind === b.kind && a.id === b.id;
1636
- }
1637
- function inferTrigger(lane) {
1638
- if (lane.state === "awaiting_input")
1639
- return { kind: "answered_questions" };
1640
- return { kind: "admit" };
1641
- }
1642
- /**
1643
- * Bind the account, spawn the worker and its watcher outside the caller's
1644
- * tree, then CAS the record to `running`. A spawn that cannot be proven
1645
- * started and detached is a named terminal reason, never a bare `failed`.
1646
- *
1647
- * Fresh-vs-resume is decided by `planLaneLaunch` (delivery.ts), never here.
1648
- */
1649
- export function spawnLaneWorker(hqRoot, lane, deps = {}, launch = {}) {
1650
- const env = deps.env ?? process.env;
1651
- const hostname = accountHomeHostname(deps);
1652
- const modelDeps = {
1653
- ...deps.modelDeps,
1654
- env: deps.modelDeps?.env ?? env,
1655
- };
1656
- const existsSync = deps.existsSync ?? ((p) => fs.existsSync(p));
1657
- const spawnProcess = deps.spawnProcess ?? defaultSpawnProcess;
1658
- const proveDetached = deps.proveDetached ?? defaultProveDetached;
1659
- const killProcess = deps.killProcess ?? defaultKillProcess;
1660
- const runDir = laneRunDir(hqRoot, lane.lane_id);
1661
- const previousSpawn = readSpawnManifest(runDir);
1662
- const stored = readLane(hqRoot, lane.lane_id);
1663
- const recoveredSessionId = (typeof stored.provider_session_id === "string" && stored.provider_session_id.trim()
1664
- ? stored.provider_session_id
1665
- : undefined) ??
1666
- (typeof stored.last_resume?.session_id === "string" && stored.last_resume.session_id.trim()
1667
- ? stored.last_resume.session_id
1668
- : undefined) ??
1669
- (typeof previousSpawn.resume?.session_id === "string" && previousSpawn.resume.session_id.trim()
1670
- ? previousSpawn.resume.session_id
1671
- : undefined);
1672
- const existing = {
1673
- ...stored,
1674
- ...(stored.provider_session_id === undefined && recoveredSessionId !== undefined
1675
- ? { provider_session_id: recoveredSessionId }
1676
- : {}),
1677
- ...(stored.provider_home_at_spawn === undefined && previousSpawn.provider_home_at_spawn !== undefined
1678
- ? { provider_home_at_spawn: previousSpawn.provider_home_at_spawn }
1679
- : {}),
1680
- };
1681
- if (existing.state === "running") {
1682
- if (launch.trigger?.kind === "resume") {
1683
- throw new LanesError("lane_not_resumable", `Lane ${lane.lane_id} is already running`, { lane_id: lane.lane_id, state: existing.state });
1684
- }
1685
- return laneLaunchResult(existing);
1686
- }
1687
- // A queued lane that a move parked at the target's cap carries the turn
1688
- // it was resumed with: the admit spawn continues that session instead of
1689
- // starting fresh from the brief.
1690
- const pendingResume = launch.trigger === undefined && existing.state === "queued" ? existing.pending_resume : undefined;
1691
- const trigger = launch.trigger ?? inferTrigger(existing);
1692
- const failedResumeClaim = (trigger.kind === "resume" && trigger.fromFailed === true) || pendingResume?.from_failed === true;
1693
- const failedResumeExpectedSenior = trigger.kind === "resume" && trigger.fromFailed === true
1694
- ? trigger.expectedSenior
1695
- : pendingResume?.from_failed === true
1696
- ? pendingResume.expected_senior
1697
- : undefined;
1698
- // A message into a finished lane must not turn that lane `failed` when the
1699
- // account cannot be bound: nothing has started yet, so the record keeps its
1700
- // state and the caller sees the error. Admission and question resume keep
1701
- // today's behaviour of naming the terminal reason on the record.
1702
- const markPreSpawnFailure = trigger.kind !== "message" && trigger.kind !== "resume";
1703
- const plan = pendingResume?.trigger === "answered_questions"
1704
- ? pendingResume.session_id !== undefined && providerSupportsSessionResume(existing.provider)
1705
- ? { mode: "resume", session_id: pendingResume.session_id }
1706
- : planLaneLaunch(existing, { kind: "answered_questions" })
1707
- : pendingResume?.session_id !== undefined && providerSupportsSessionResume(existing.provider)
1708
- ? { mode: "resume", session_id: pendingResume.session_id }
1709
- : planLaneLaunch(existing, trigger);
1710
- if (existing.host.kind === "outpost") {
1711
- refuseOutpostSelfTarget(hqRoot, existing, deps);
1712
- }
1713
- const logsDir = path.join(runDir, "logs");
1714
- ensureDir(logsDir);
1715
- ensureDir(path.join(runDir, "envelopes"));
1716
- const profile = existing.worker_profile
1717
- ? loadWorkerProfileWithRegistry(hqRoot, existing.worker_profile, {
1718
- laneCompany: existing.company?.slug ?? existing.mesh_company?.slug,
1719
- ...(existing.registry_worker !== undefined
1720
- ? { registryWorkerRecord: existing.registry_worker }
1721
- : {}),
1722
- })
1723
- : undefined;
1724
- if (existing.host.kind === "outpost" &&
1725
- profile !== undefined &&
1726
- existing.worker_profile_hash !== profile.contentHash) {
1727
- throw new LanesError("worker_profile_hash_mismatch", `Worker profile ${JSON.stringify(existing.worker_profile)} on Outpost ${existing.host.id} changed after pickup validation`, {
1728
- lane_id: existing.lane_id,
1729
- worker: existing.worker_profile,
1730
- outpost: existing.host.id,
1731
- expected_hash: existing.worker_profile_hash ?? null,
1732
- actual_hash: profile.contentHash,
1733
- });
1734
- }
1735
- const profileDefaultsApply = profile !== undefined && profile.meta.provider === existing.provider;
1736
- const profileModel = profileDefaultsApply ? profile.meta.model : undefined;
1737
- const profileEffort = profileDefaultsApply ? profile.meta.effort : undefined;
1738
- const ignoredProfileFields = profile
1739
- ? ignoredWorkerProfileFields(existing.provider)
1740
- : [];
1741
- const policyDelivery = profile
1742
- ? workerPolicyDeliveryMode(hqRoot, existing.provider)
1743
- : undefined;
1744
- const workerPolicyDir = profile !== undefined && existing.provider !== "grok"
1745
- ? path.relative(hqRoot, profile.dir).split(path.sep).join("/")
1746
- : undefined;
1747
- const profileRuntime = profile
1748
- ? materializeWorkerProfile(profile, runDir)
1749
- : undefined;
1750
- const profileLaunch = profile
1751
- ? {
1752
- systemPrompt: workerProfilePrompt(profile, policyDelivery ?? "prompt"),
1753
- ...(profileRuntime?.settingsPath !== undefined
1754
- ? { settingsPath: profileRuntime.settingsPath }
1755
- : {}),
1756
- ignoredFields: ignoredProfileFields,
1757
- }
1758
- : undefined;
1759
- const profileChanged = profile !== undefined && existing.worker_profile_hash !== profile.contentHash;
1760
- const config = loadLanesConfig(hqRoot);
1761
- const repairRecordedAccount = plan.mode === "resume" &&
1762
- (trigger.kind === "resume" || pendingResume?.trigger === "resume" || pendingResume?.trigger === "watcher");
1763
- const recordedModel = repairRecordedAccount && existing.model_source === "account"
1764
- ? existing.model
1765
- : undefined;
1766
- // `hq lanes set` on a running lane leaves the change pending until this spawn.
1767
- const pendingSettings = existing.pending_settings;
1768
- let pinnedModel = pendingSettings?.model ?? (existing.model_source === undefined || existing.model_source === "cli" || existing.model_source === "preserved"
1769
- ? existing.model
1770
- : undefined);
1771
- const accountDeps = {
1772
- probe: modelDeps.probe ?? defaultProbe,
1773
- env,
1774
- };
1775
- let selection;
1776
- try {
1777
- selection = selectSpawnAccount({
1778
- hqRoot,
1779
- lane: existing,
1780
- config,
1781
- existsSync,
1782
- accountDeps,
1783
- modelDeps,
1784
- pinnedModel,
1785
- profileModel,
1786
- currentModelValidated: deps.currentModelValidated === true,
1787
- hostname,
1788
- repairRecordedAccount,
1789
- ...(recordedModel !== undefined ? { recordedModel } : {}),
1790
- now: (deps.now ?? (() => new Date()))(),
1791
- });
1792
- }
1793
- catch (err) {
1794
- if (err instanceof AccountResolutionError ||
1795
- (err instanceof LanesError &&
1796
- (err.error === "account_not_logged_in" || err.error === "model_unsupported"))) {
1797
- if (markPreSpawnFailure) {
1798
- markSpawnFailure(hqRoot, lane.lane_id, err.error, err.details);
1799
- }
1800
- throw err;
1801
- }
1802
- process.stderr.write(`hq lanes: account bind failed for ${lane.lane_id}: ${err instanceof Error ? err.message : String(err)}\n`);
1803
- throw err;
1804
- }
1805
- const preservedAccountModel = selection.preservedModel;
1806
- if (preservedAccountModel !== undefined)
1807
- pinnedModel = preservedAccountModel;
1808
- const resolved = selection.account;
1809
- if (deps.lowDiskGuardEnabled === true) {
1810
- const free = checkLaneDiskSpace(hqRoot, resolved.home, deps.statfs, config.low_disk_min_free_bytes);
1811
- if (free.low) {
1812
- const measuredAt = (deps.now ?? (() => new Date()))().toISOString();
1813
- return retryUpdateLane(hqRoot, lane.lane_id, "spawn", (current) => ({
1814
- ...current,
1815
- state: "queued",
1816
- queued_reason: "low_disk",
1817
- queued_details: {
1818
- reason: "low_disk",
1819
- hq_free_bytes: free.hq.free_bytes,
1820
- provider_free_bytes: free.provider.free_bytes,
1821
- measured_at: measuredAt,
1822
- },
1823
- queued_at: current.queued_at ?? measuredAt,
1824
- admission_reserved_at: undefined,
1825
- terminal_reason: undefined,
1826
- terminal_details: undefined,
1827
- }));
1828
- }
1829
- }
1830
- const status = accountStatus(lane.provider, resolved.id, config, { existsSync, hostname });
1831
- if (isLoggedOut(status)) {
1832
- const failed = markPreSpawnFailure
1833
- ? markSpawnFailure(hqRoot, lane.lane_id, "account_not_logged_in", {
1834
- provider: lane.provider,
1835
- account: resolved.id,
1836
- })
1837
- : existing;
1838
- throw new LanesError("account_not_logged_in", `Account ${resolved.id} for ${lane.provider} is not logged in (no credential file)`, { provider: lane.provider, account: resolved.id, lane_id: lane.lane_id, lane: failed });
1839
- }
1840
- if (existing.account !== resolved.id) {
1841
- const source = existing.account
1842
- ? config.providers[existing.provider].accounts[existing.account]
1843
- : undefined;
1844
- if (source &&
1845
- existing.provider_session_id &&
1846
- providerSupportsSessionResume(existing.provider)) {
1847
- copySessionFiles(planSessionCopy(existing.provider, {
1848
- sourceHome: existing.provider_home_at_spawn ?? effectiveAccountHome(source, hostname).home,
1849
- targetHome: resolved.home,
1850
- cwd: hqRoot,
1851
- sessionId: existing.provider_session_id,
1852
- }));
1853
- }
1854
- }
1855
- if (plan.mode === "resume" && existing.provider !== "grok") {
1856
- ensureSessionHome({
1857
- provider: existing.provider,
1858
- sessionId: plan.session_id,
1859
- cwd: hqRoot,
1860
- targetHome: resolved.home,
1861
- registeredHomes: Object.values(config.providers[existing.provider].accounts)
1862
- .map((account) => effectiveAccountHome(account, hostname).home),
1863
- providerHomeAtSpawn: existing.provider_home_at_spawn,
1864
- });
1865
- }
1866
- if (existing.account !== resolved.id) {
1867
- const at = (deps.now ?? (() => new Date()))().toISOString();
1868
- const reason = selection.changeReason ?? "first_assignment";
1869
- retryUpdateLane(hqRoot, lane.lane_id, "spawn", (current) => {
1870
- if (current.account === resolved.id)
1871
- return current;
1872
- if (current.account !== existing.account) {
1873
- throw new LanesError("account_bind_conflict", `Lane ${lane.lane_id} changed accounts while its worker spawn was prepared`, { lane_id: lane.lane_id, expected_account: existing.account ?? null, account: current.account ?? null });
1874
- }
1875
- const entry = {
1876
- from: current.account ?? null,
1877
- to: resolved.id,
1878
- at,
1879
- reason,
1880
- };
1881
- return {
1882
- ...current,
1883
- account: resolved.id,
1884
- ...(preservedAccountModel !== undefined
1885
- ? { model: preservedAccountModel, model_source: "preserved" }
1886
- : {}),
1887
- account_history: appendCappedHistory(current.account_history ?? [], entry),
1888
- };
1889
- });
1890
- }
1891
- try {
1892
- installDrainHook(lane.provider, resolved.home);
1893
- }
1894
- catch (err) {
1895
- process.stderr.write(`hq lanes: drain hook install failed for ${resolved.home}: ${err instanceof Error ? err.message : String(err)}\n`);
1896
- throw err;
1897
- }
1898
- const briefPath = path.join(runDir, "brief.md");
1899
- const envelopePath = nextEnvelopePath(runDir);
1900
- const lastMessagePath = path.join(logsDir, "last-message.txt");
1901
- const answersPath = path.join(runDir, ANSWERED_QUESTIONS_FILE);
1902
- const carriesAnsweredQuestions = trigger.kind === "answered_questions" || pendingResume?.trigger === "answered_questions";
1903
- const answeredLines = carriesAnsweredQuestions && existsSync(answersPath)
1904
- ? readAnsweredQuestionLines(answersPath)
1905
- : undefined;
1906
- const extraPrompt = existsSync(answersPath)
1907
- ? `Previously answered questions are at ${answersPath}; treat those choices as operator decisions that outrank the brief.`
1908
- : undefined;
1909
- const accountCfg = config.providers[lane.provider].accounts[resolved.id];
1910
- const autoCompactTokens = lane.provider === "claude"
1911
- ? providerAutoCompactTokens(config.providers.claude)
1912
- : undefined;
1913
- const childEnv = workerEnv(env, { envVar: resolved.envVar, home: resolved.home }, lane.lane_id, hqRoot, autoCompactTokens, lane.mesh_company ?? lane.company ?? undefined, workerPolicyDir, lane.registry_worker);
1914
- const laneTurnId = randomUUID();
1915
- childEnv.HQ_LANE_TURN_ID = laneTurnId;
1916
- const model = resolveLaneModel({
1917
- cliModel: pinnedModel,
1918
- profileModel,
1919
- accountModel: accountCfg?.model,
1920
- providerModel: config.providers[lane.provider].model,
1921
- });
1922
- const pendingResumeEffort = pendingResume !== undefined
1923
- ? pendingSettings?.effort !== undefined
1924
- ? { effort: pendingSettings.effort, source: "cli" }
1925
- : {
1926
- ...(existing.effort !== undefined ? { effort: existing.effort } : {}),
1927
- source: existing.effort_source ?? "none",
1928
- }
1929
- : undefined;
1930
- const effort = launch.effort ?? pendingResumeEffort ?? resolveLaneEffort({
1931
- cliEffort: pendingSettings?.effort ?? (existing.effort_source === "cli" ? existing.effort : undefined),
1932
- profileEffort,
1933
- accountEffort: accountCfg?.effort,
1934
- providerEffort: config.providers[lane.provider].effort,
1935
- model,
1936
- });
1937
- const fastMode = lane.provider === "codex"
1938
- ? (profileDefaultsApply ? profile?.meta.fast_mode : undefined) ??
1939
- (model !== undefined && (config.providers.codex.fast_mode_models ?? []).includes(model))
1940
- : false;
1941
- const resume = plan.mode === "resume"
1942
- ? {
1943
- session_id: plan.session_id,
1944
- prompt: resumePrompt({
1945
- envelopePath,
1946
- operatorMessage: trigger.kind === "message" && trigger.monitor_event !== true
1947
- ? trigger.text
1948
- : trigger.kind === "resume"
1949
- ? trigger.text
1950
- : pendingResume?.monitor_event === true
1951
- ? undefined
1952
- : pendingResume?.text,
1953
- monitorEvent: trigger.kind === "message" && trigger.monitor_event === true
1954
- ? trigger.text
1955
- : pendingResume?.monitor_event === true
1956
- ? pendingResume.text
1957
- : undefined,
1958
- resumedFrom: trigger.kind === "resume" ? trigger.from : pendingResume?.resumed_from,
1959
- resumeSource: pendingResume?.trigger === "watcher" ? "watcher" : undefined,
1960
- answersPath: answeredLines !== undefined ? answersPath : undefined,
1961
- answers: answeredLines,
1962
- envelopeRepairErrors: lane.terminal_reason === ENVELOPE_INVALID_REASON &&
1963
- lane.envelope_repair?.attempted === true &&
1964
- lane.envelope_repair.succeeded === false
1965
- ? {
1966
- first_error: lane.envelope_repair.first_error,
1967
- ...(lane.envelope_repair.second_error !== undefined
1968
- ? { second_error: lane.envelope_repair.second_error }
1969
- : {}),
1970
- }
1971
- : undefined,
1972
- }),
1973
- }
1974
- : undefined;
1975
- const command = buildProviderCommand(lane.provider, {
1976
- hqRoot,
1977
- briefPath,
1978
- envelopePath,
1979
- lastMessagePath,
1980
- extraPrompt,
1981
- model,
1982
- effort: effort.effort,
1983
- fastMode,
1984
- profile: profileLaunch,
1985
- workerPolicyDir,
1986
- resume,
1987
- });
1988
- // A systemd PATH mismatch is an environment defect, not a lane failure.
1989
- // Keep the lane eligible for a later reconcile after the installer repairs it.
1990
- if (!providerCommandOnPath(command.command, childEnv.PATH)) {
1991
- const searchedPath = childEnv.PATH ?? "";
1992
- // Only admission may re-queue. A resume (answered questions, operator
1993
- // message) must keep the recorded state so the next reconcile does not
1994
- // infer `admit` and start a fresh run in place of the recorded session;
1995
- // the caller keeps the message text and sees the named error.
1996
- if (trigger.kind !== "admit") {
1997
- throw new LanesError("provider_binary_missing", `Provider binary ${command.command} for ${lane.provider} is not executable on PATH ${JSON.stringify(searchedPath)}; lane ${lane.lane_id} keeps state ${existing.state}`, {
1998
- provider: lane.provider,
1999
- command: command.command,
2000
- searched_path: searchedPath,
2001
- lane_id: lane.lane_id,
2002
- state: existing.state,
2003
- trigger: trigger.kind,
2004
- });
2005
- }
2006
- return retryUpdateLane(hqRoot, lane.lane_id, "spawn", (current) => ({
2007
- ...current,
2008
- state: "queued",
2009
- queued_reason: "provider_binary_missing",
2010
- queued_details: undefined,
2011
- terminal_reason: undefined,
2012
- terminal_details: {
2013
- provider: lane.provider,
2014
- command: command.command,
2015
- searched_path: searchedPath,
2016
- },
2017
- }));
2018
- }
2019
- // Resume-time compaction (compaction.ts). Runs before the claim so the
2020
- // lane is never `running` without a worker while `/compact` works.
2021
- let compaction;
2022
- const compactWanted = pendingResume?.compact ?? launch.compact;
2023
- if (resume && compactWanted !== false) {
2024
- const nowFn = deps.now ?? (() => new Date());
2025
- const decision = compactionDue(existing, nowFn().getTime(), providerCompactAfterMs(config.providers[lane.provider]));
2026
- if (decision.due) {
2027
- const compactCommand = buildProviderCommand(lane.provider, {
2028
- hqRoot,
2029
- briefPath,
2030
- envelopePath,
2031
- lastMessagePath,
2032
- model,
2033
- effort: effort.effort,
2034
- fastMode,
2035
- profile: profileLaunch,
2036
- workerPolicyDir,
2037
- resume: { session_id: resume.session_id, prompt: COMPACTION_PROMPT },
2038
- });
2039
- compaction = compactLaneSession({
2040
- command: compactCommand.command,
2041
- args: compactCommand.args,
2042
- sessionId: resume.session_id,
2043
- accountHome: resolved.home,
2044
- env: childEnv,
2045
- cwd: hqRoot,
2046
- logsDir,
2047
- decision,
2048
- before: existing.last_run_usage ?? null,
2049
- now: nowFn,
2050
- run: deps.runCompaction,
2051
- locateTranscript: deps.locateTranscript,
2052
- });
2053
- }
2054
- }
2055
- // Claim running before spawning. Two callers that both observe queued must
2056
- // not both start processes; the CAS loser returns without spawn.
2057
- const nowIso = (deps.now ?? (() => new Date()))().toISOString();
2058
- const resumeHistoryTrigger = pendingResume?.keep_alive === true
2059
- ? "keep_alive"
2060
- : pendingResume?.trigger === "monitor_event" || pendingResume?.monitor_event === true ||
2061
- (trigger.kind === "message" && trigger.monitor_event === true)
2062
- ? "monitor_event"
2063
- : pendingResume?.trigger === "system_notice" ||
2064
- (trigger.kind === "message" && trigger.system_notice === true)
2065
- ? "system_notice"
2066
- : pendingResume?.trigger === "watcher"
2067
- ? "watcher"
2068
- : pendingResume?.trigger === "message" || trigger.kind === "message"
2069
- ? "message"
2070
- : pendingResume?.trigger === "resume" || trigger.kind === "resume"
2071
- ? "resume_cli"
2072
- : "reconcile";
2073
- const resumeHistoryCaller = pendingResume?.caller ||
2074
- (pendingResume?.trigger !== "watcher" && typeof env.HQ_LANE_ID === "string" ? env.HQ_LANE_ID.trim() : "") ||
2075
- (pendingResume?.trigger === "message" || pendingResume?.trigger === "monitor_event" ||
2076
- pendingResume?.trigger === "system_notice" || trigger.kind === "answered_questions" ||
2077
- trigger.kind === "resume" || trigger.kind === "message"
2078
- ? "user"
2079
- : undefined);
2080
- let statusGateHeartbeat;
2081
- try {
2082
- statusGateHeartbeat = managerStatusGateHeartbeat(hqRoot, existing, laneTurnId, nowIso);
2083
- }
2084
- catch (err) {
2085
- const code = err instanceof LanesError ? err.error : "manager_status_gate_unavailable";
2086
- const message = err instanceof Error ? err.message : String(err);
2087
- process.stderr.write(`hq lanes: manager status gate disabled for ${lane.lane_id}: ${code}: ${message}\n`);
2088
- statusGateHeartbeat = undefined;
2089
- }
2090
- let claimed = false;
2091
- let priorStartRecorded = false;
2092
- const claimedRecord = retryUpdateLane(hqRoot, lane.lane_id, "spawn", (current) => {
2093
- claimed = false;
2094
- if (current.state === "running" && current.account === resolved.id) {
2095
- if (trigger.kind === "resume") {
2096
- throw new LanesError("lane_not_resumable", `Lane ${current.lane_id} is already running`, { lane_id: current.lane_id, state: current.state });
2097
- }
2098
- return current;
2099
- }
2100
- if (!claimableStatesFor(trigger, current).includes(current.state)) {
2101
- throw new LanesError("spawn_state_mismatch", `Cannot mark ${current.lane_id} running from ${current.state}`, { lane_id: current.lane_id, state: current.state, trigger: trigger.kind });
2102
- }
2103
- // The host report is written in the claim CAS before exec proves that a
2104
- // worker started. Use the prior spawn manifest's turn id (written only
2105
- // after detachment is proven), with last_resume for legacy manifests.
2106
- priorStartRecorded = previousSpawn.turn_id !== undefined ||
2107
- current.last_resume !== undefined ||
2108
- (current.resume_history?.length ?? 0) > 0;
2109
- if (failedResumeClaim &&
2110
- (failedResumeExpectedSenior === undefined ||
2111
- !sameSeniorRef(current.senior, failedResumeExpectedSenior))) {
2112
- throw new LanesError("failed_resume_senior_changed", `Lane ${current.lane_id}'s senior changed after its failed-resume request was authorized`, {
2113
- lane_id: current.lane_id,
2114
- expected_senior: failedResumeExpectedSenior ?? null,
2115
- current_senior: current.senior,
2116
- });
2117
- }
2118
- claimed = true;
2119
- const next = {
2120
- ...current,
2121
- state: "running",
2122
- queued_reason: undefined,
2123
- queued_details: undefined,
2124
- queued_at: undefined,
2125
- admission_reserved_at: undefined,
2126
- terminal_reason: undefined,
2127
- terminal_details: undefined,
2128
- // An account move's reservation ends with the claim.
2129
- pending_resume: undefined,
2130
- pending_settings: undefined,
2131
- account: resolved.id,
2132
- provider_home_at_spawn: resolved.home,
2133
- ...(model !== undefined ? { model } : {}),
2134
- ...(model !== undefined
2135
- ? {
2136
- model_source: pinnedModel !== undefined
2137
- ? preservedAccountModel === undefined && pendingSettings?.model !== undefined
2138
- ? "cli"
2139
- : preservedAccountModel !== undefined || existing.model_source === "preserved"
2140
- ? "preserved"
2141
- : "cli"
2142
- : profileModel !== undefined
2143
- ? "profile"
2144
- : accountCfg?.model !== undefined
2145
- ? "account"
2146
- : config.providers[lane.provider].model !== undefined
2147
- ? "provider"
2148
- : "none",
2149
- }
2150
- : { model_source: "none" }),
2151
- effort_source: effort.source,
2152
- status_gate: statusGateHeartbeat,
2153
- last_host_report_at: nowIso,
2154
- ...(profile
2155
- ? {
2156
- worker_profile_hash: profile.contentHash,
2157
- registry_worker: profile.registryWorker !== undefined
2158
- ? registryWorkerRecord(profile.registryWorker)
2159
- : undefined,
2160
- worker_profile_ignored: [...ignoredProfileFields],
2161
- worker_policy_delivery: policyDelivery,
2162
- }
2163
- : { registry_worker: undefined, worker_policy_delivery: undefined }),
2164
- };
2165
- if (resume !== undefined) {
2166
- next.provider_session_id = resume.session_id;
2167
- next.provider_session_id_absent = undefined;
2168
- }
2169
- if (effort.effort !== undefined)
2170
- next.effort = effort.effort;
2171
- else
2172
- delete next.effort;
2173
- // `undefined` deliberately overlays the CAS merge's current record so a
2174
- // dynamic default disappearing removes the stale persisted model.
2175
- if (model === undefined)
2176
- next.model = undefined;
2177
- if (fastMode)
2178
- next.fast_mode = true;
2179
- else
2180
- delete next.fast_mode;
2181
- // Freeze the counters of the run that followed the previous compaction
2182
- // before this launch replaces last_resume.
2183
- if (current.last_compaction && current.last_compaction.after === null) {
2184
- const after = compactionAfterUsage(current);
2185
- if (after !== null)
2186
- next.last_compaction = { ...current.last_compaction, after };
2187
- }
2188
- if (compaction)
2189
- next.last_compaction = { ...compaction, resume_at: nowIso };
2190
- if (resume && pendingResume !== undefined) {
2191
- next.last_resume = {
2192
- session_id: resume.session_id,
2193
- at: nowIso,
2194
- account: resolved.id,
2195
- trigger: pendingResume.trigger,
2196
- ...(pendingResume.keep_alive === true ? { keep_alive: true } : {}),
2197
- ...(pendingResume.message_id !== undefined ? { message_id: pendingResume.message_id } : {}),
2198
- ...(pendingResume.monitor_event === true ? { monitor_event: true } : {}),
2199
- ...(pendingResume.resumed_from !== undefined ? { resumed_from: pendingResume.resumed_from } : {}),
2200
- ...(pendingResume.from_failed === true ? { from_failed: true } : {}),
2201
- ...(pendingResume.text !== undefined ? { text: pendingResume.text } : {}),
2202
- ...(pendingResume.compact !== undefined ? { compact: pendingResume.compact } : {}),
2203
- };
2204
- }
2205
- else if (resume && trigger.kind !== "admit") {
2206
- next.last_resume = {
2207
- session_id: resume.session_id,
2208
- at: nowIso,
2209
- account: resolved.id,
2210
- trigger: trigger.kind === "message" && trigger.system_notice === true ? "system_notice" : trigger.kind,
2211
- ...(trigger.kind === "message"
2212
- ? {
2213
- message_id: trigger.message_id,
2214
- text: trigger.text,
2215
- ...(trigger.monitor_event === true ? { monitor_event: true } : {}),
2216
- }
2217
- : {}),
2218
- ...(launch.compact !== undefined ? { compact: launch.compact } : {}),
2219
- ...(trigger.kind === "resume"
2220
- ? {
2221
- resumed_from: trigger.from,
2222
- ...(trigger.fromFailed === true ? { from_failed: true } : {}),
2223
- ...(trigger.text !== undefined ? { text: trigger.text } : {}),
2224
- ...(trigger.message_id !== undefined ? { message_id: trigger.message_id } : {}),
2225
- }
2226
- : {}),
2227
- };
2228
- }
2229
- if (resume && pendingResume?.text !== LEAD_LANE_KEEP_ALIVE_BLOCKED_RESUME_TEXT) {
2230
- next.keep_alive_blocked_resume_streak = 0;
2231
- }
2232
- return next;
2233
- });
2234
- if (!claimed) {
2235
- if (compaction) {
2236
- const record = compaction;
2237
- return retryUpdateLane(hqRoot, lane.lane_id, "spawn", (current) => ({
2238
- ...current,
2239
- last_compaction: record,
2240
- }));
2241
- }
2242
- return laneLaunchResult(claimedRecord);
2243
- }
2244
- // Each normal spawn/resume starts a fresh provider turn. The resume prompt
2245
- // carries the prior message text, so only messages delivered after this
2246
- // reset may be replayed if the new turn compacts.
2247
- const replayStatePath = path.join(runDir, "dropbox", MESSAGE_REPLAY_STATE_NAME);
2248
- const replayStateTempPath = `${replayStatePath}.${process.pid}.${laneTurnId}.tmp`;
2249
- try {
2250
- fs.mkdirSync(path.dirname(replayStatePath), { recursive: true });
2251
- fs.writeFileSync(replayStateTempPath, `${JSON.stringify({
2252
- schema_version: 1,
2253
- turn_id: laneTurnId,
2254
- last_compaction_marker: null,
2255
- })}\n`, { mode: 0o600 });
2256
- fs.renameSync(replayStateTempPath, replayStatePath);
2257
- }
2258
- catch (err) {
2259
- try {
2260
- fs.rmSync(replayStateTempPath, { force: true });
2261
- }
2262
- catch (cleanupErr) {
2263
- process.stderr.write(`hq lanes: compaction replay state temp cleanup failed for ${lane.lane_id}: ${cleanupErr instanceof Error ? cleanupErr.message : String(cleanupErr)}\n`);
2264
- }
2265
- delete childEnv.HQ_LANE_TURN_ID;
2266
- process.stderr.write(`hq lanes: compaction replay disabled for ${lane.lane_id}; failed to reset turn state: ${err instanceof Error ? err.message : String(err)}\n`);
2267
- }
2268
- const workerOutPath = path.join(logsDir, "worker.out");
2269
- const workerOutOffset = fileSizeOrZero(workerOutPath);
2270
- let workerPid;
2271
- let watcherPid;
2272
- try {
2273
- workerPid = spawnDetached(spawnProcess, command.command, command.args, childEnv, hqRoot, path.join(logsDir, "worker.out"), path.join(logsDir, "worker.err"));
2274
- writePidRecord(path.join(runDir, "worker.pid"), {
2275
- pid: workerPid,
2276
- starttime: readProcStarttime(workerPid) ?? undefined,
2277
- });
2278
- requireDetached(proveDetached, workerPid, "worker");
2279
- if (answeredLines && answeredLines.length > 0) {
2280
- markAnsweredQuestionsDelivered(hqRoot, lane.lane_id, answeredLines.map(({ question_id }) => question_id), (deps.now ?? (() => new Date()))().toISOString());
2281
- }
2282
- watcherPid = armLaneWatcher(hqRoot, lane.lane_id, deps);
2283
- writeSpawnManifest(runDir, {
2284
- command: command.command,
2285
- args: command.args,
2286
- envVar: resolved.envVar,
2287
- account: resolved.id,
2288
- workerPid,
2289
- watcherPid,
2290
- envelopePath,
2291
- turnId: laneTurnId,
2292
- resume: resume ? { session_id: resume.session_id } : null,
2293
- workerOutOffset,
2294
- fastMode,
2295
- ...(profile
2296
- ? {
2297
- profile: {
2298
- id: profile.id,
2299
- hash: profile.contentHash,
2300
- ignoredFields: ignoredProfileFields,
2301
- policyDelivery: policyDelivery ?? "prompt",
2302
- ...(workerPolicyDir !== undefined ? { policyDir: workerPolicyDir } : {}),
2303
- ...(profileRuntime?.settingsPath !== undefined
2304
- ? { settingsPath: profileRuntime.settingsPath }
2305
- : {}),
2306
- },
2307
- }
2308
- : {}),
2309
- });
2310
- if (profile !== undefined) {
2311
- appendWorkerProfileEvent(runDir, {
2312
- profile_id: profile.id,
2313
- profile_hash: profile.contentHash,
2314
- changed: profileChanged,
2315
- provider: lane.provider,
2316
- ignored_fields: ignoredProfileFields,
2317
- });
2318
- }
2319
- }
2320
- catch (err) {
2321
- if (workerPid !== undefined)
2322
- killQuietly(killProcess, workerPid, "worker");
2323
- if (watcherPid !== undefined)
2324
- killQuietly(killProcess, watcherPid, "watcher");
2325
- const reason = err instanceof LanesError &&
2326
- SPAWN_TERMINAL_REASONS.includes(err.error)
2327
- ? err.error
2328
- : "spawn_failed";
2329
- const failed = markSpawnFailure(hqRoot, lane.lane_id, reason, {
2330
- message: err instanceof Error ? err.message : String(err),
2331
- ...(err instanceof LanesError ? err.details : {}),
2332
- });
2333
- if (err instanceof LanesError) {
2334
- throw new LanesError(err.error, err.message, {
2335
- ...err.details,
2336
- lane_id: lane.lane_id,
2337
- lane: failed,
2338
- });
2339
- }
2340
- throw err;
2341
- }
2342
- if (priorStartRecorded) {
2343
- retryUpdateLane(hqRoot, lane.lane_id, "spawn", (current) => ({
2344
- ...current,
2345
- resume_history: appendCappedHistory(current.resume_history ?? [], {
2346
- at: nowIso,
2347
- trigger: resumeHistoryTrigger,
2348
- ...(resumeHistoryCaller ? { caller: resumeHistoryCaller } : {}),
2349
- }),
2350
- }));
2351
- }
2352
- return laneLaunchResult(readLane(hqRoot, lane.lane_id));
2353
- }
2354
- /**
2355
- * Handle the private request sent by an older, long-running watcher to the
2356
- * currently installed `hq` executable. The persisted repair attempt is the
2357
- * authorization for this one-shot spawn; the request cannot select an
2358
- * arbitrary lane or write outside that lane's envelope directory.
2359
- */
2360
- export function spawnEnvelopeRepairRequest(hqRoot, rawRequest, deps = {}) {
2361
- const invalid = (message) => {
2362
- throw new LanesError("repair_request_invalid", message, {});
2363
- };
2364
- if (!rawRequest || typeof rawRequest !== "object" || Array.isArray(rawRequest)) {
2365
- return invalid("Envelope repair request must be an object");
2366
- }
2367
- const request = rawRequest;
2368
- if (Object.keys(request).some((key) => key !== "lane_id" && key !== "input")) {
2369
- return invalid("Envelope repair request has unknown fields");
2370
- }
2371
- if (typeof request.lane_id !== "string" ||
2372
- !/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(request.lane_id)) {
2373
- return invalid("Envelope repair request must include a lane_id");
2374
- }
2375
- if (!request.input || typeof request.input !== "object" || Array.isArray(request.input)) {
2376
- return invalid("Envelope repair request input must be an object");
2377
- }
2378
- const rawInput = request.input;
2379
- const allowedInputFields = new Set([
2380
- "session_id",
2381
- "envelopePath",
2382
- "error",
2383
- "rawText",
2384
- "missing",
2385
- ]);
2386
- if (Object.keys(rawInput).some((key) => !allowedInputFields.has(key))) {
2387
- return invalid("Envelope repair request input has unknown fields");
2388
- }
2389
- if (typeof rawInput.envelopePath !== "string" ||
2390
- !path.isAbsolute(rawInput.envelopePath) ||
2391
- path.resolve(rawInput.envelopePath) !== rawInput.envelopePath ||
2392
- typeof rawInput.error !== "string" ||
2393
- !rawInput.error.trim() ||
2394
- typeof rawInput.rawText !== "string" ||
2395
- (rawInput.session_id !== undefined &&
2396
- rawInput.session_id !== null &&
2397
- (typeof rawInput.session_id !== "string" || !rawInput.session_id.trim())) ||
2398
- (rawInput.missing !== undefined && typeof rawInput.missing !== "boolean")) {
2399
- return invalid("Envelope repair request input has invalid fields");
2400
- }
2401
- const lane = readLane(hqRoot, request.lane_id);
2402
- const repair = lane.envelope_repair;
2403
- if (lane.state !== "running" || !repair?.attempted || repair.succeeded) {
2404
- throw new LanesError("repair_request_not_authorized", `Lane ${lane.lane_id} has no pending envelope repair attempt`, { lane_id: lane.lane_id });
2405
- }
2406
- if (repair.first_error !== rawInput.error) {
2407
- throw new LanesError("repair_request_stale", `Lane ${lane.lane_id} envelope repair request no longer matches its recorded error`, { lane_id: lane.lane_id });
2408
- }
2409
- const envelopeDir = path.resolve(laneRunDir(hqRoot, lane.lane_id), "envelopes");
2410
- const envelopePath = path.resolve(rawInput.envelopePath);
2411
- if (path.dirname(envelopePath) !== envelopeDir ||
2412
- !path.basename(envelopePath).endsWith(".json") ||
2413
- typeof repair.envelope_ref !== "string" ||
2414
- path.posix.dirname(repair.envelope_ref) !== "envelopes" ||
2415
- !path.posix.basename(repair.envelope_ref).endsWith(".json")) {
2416
- throw new LanesError("repair_request_path_invalid", `Lane ${lane.lane_id} envelope repair request does not name a lane envelope`, { lane_id: lane.lane_id });
2417
- }
2418
- const recordedEnvelopePath = path.resolve(laneRunDir(hqRoot, lane.lane_id), repair.envelope_ref);
2419
- if (envelopePath !== recordedEnvelopePath) {
2420
- throw new LanesError("repair_request_envelope_mismatch", `Lane ${lane.lane_id} envelope repair request does not match the recorded repair slot`, { lane_id: lane.lane_id, envelope_ref: repair.envelope_ref });
2421
- }
2422
- const warnings = [];
2423
- const input = {
2424
- envelopePath,
2425
- error: rawInput.error,
2426
- rawText: rawInput.rawText,
2427
- ...(typeof rawInput.session_id === "string" || rawInput.session_id === null
2428
- ? { session_id: rawInput.session_id }
2429
- : {}),
2430
- ...(typeof rawInput.missing === "boolean" ? { missing: rawInput.missing } : {}),
2431
- onProfileWarning: (fields) => warnings.push([...fields]),
2432
- };
2433
- const pid = spawnEnvelopeRepair(hqRoot, lane, input, deps);
2434
- return { pid, profile_warnings: warnings };
2435
- }
2436
- /**
2437
- * `resume`: claude and codex continue the recorded session with the repair
2438
- * prompt. `fresh_turn`: grok gets a new single-turn invocation on the same
2439
- * account, whose prompt carries the schema, the parser error and the raw
2440
- * failed output. Grok can resume a session (operator messages and
2441
- * `hq lanes resume` use it), but its repair turn stays a fresh turn: that
2442
- * path was built and proven that way, and a repair by resume has not been.
2443
- */
2444
- export function envelopeRepairMode(provider) {
2445
- return providerSupportsSessionResume(provider) && provider !== "grok" ? "resume" : "fresh_turn";
2446
- }
2447
- /**
2448
- * Spec §4 repair turn. The lane is still `running` (the watcher has not
2449
- * written a terminal state), so this does not claim or transition the
2450
- * record. It resumes the recorded provider session with the repair prompt
2451
- * (`resume` mode), or for a provider with no session resume runs the repair
2452
- * prompt as a fresh single turn on the same account (`fresh_turn` mode). It
2453
- * replaces `worker.pid` and rewrites `spawn.json` so the watcher's next tick
2454
- * follows the new process. The account is the one already bound on the record.
2455
- * Fast-mode evidence is updated after the replacement is proven detached.
2456
- */
2457
- export function spawnEnvelopeRepair(hqRoot, lane, input, deps = {}) {
2458
- const env = deps.env ?? process.env;
2459
- const hostname = accountHomeHostname(deps);
2460
- const existsSync = deps.existsSync ?? ((p) => fs.existsSync(p));
2461
- const spawnProcess = deps.spawnProcess ?? defaultSpawnProcess;
2462
- const proveDetached = deps.proveDetached ?? defaultProveDetached;
2463
- const killProcess = deps.killProcess ?? defaultKillProcess;
2464
- const mode = envelopeRepairMode(lane.provider);
2465
- const sessionId = input.session_id ?? null;
2466
- if (mode === "resume" && sessionId === null) {
2467
- throw new LanesError("repair_session_missing", `Provider ${lane.provider} repairs by resuming its session, but no session id was given`, { provider: lane.provider });
2468
- }
2469
- const runDir = laneRunDir(hqRoot, lane.lane_id);
2470
- const logsDir = path.join(runDir, "logs");
2471
- ensureDir(logsDir);
2472
- const config = loadLanesConfig(hqRoot);
2473
- const profile = lane.worker_profile
2474
- ? loadWorkerProfileWithRegistry(hqRoot, lane.worker_profile, {
2475
- laneCompany: lane.company?.slug ?? lane.mesh_company?.slug,
2476
- ...(lane.registry_worker !== undefined
2477
- ? { registryWorkerRecord: lane.registry_worker }
2478
- : {}),
2479
- onUnknownMetaFields: (fields) => {
2480
- process.stderr.write(`hq lanes watcher: envelope repair ignored unknown worker profile meta field(s) for ${lane.worker_profile}: ${fields.join(", ")}\n`);
2481
- input.onProfileWarning?.(fields);
2482
- },
2483
- })
2484
- : undefined;
2485
- const profileDefaultsApply = profile !== undefined && profile.meta.provider === lane.provider;
2486
- const profileModel = profileDefaultsApply ? profile.meta.model : undefined;
2487
- const profileEffort = profileDefaultsApply ? profile.meta.effort : undefined;
2488
- const ignoredProfileFields = profile
2489
- ? ignoredWorkerProfileFields(lane.provider)
2490
- : [];
2491
- const policyDelivery = profile
2492
- ? workerPolicyDeliveryMode(hqRoot, lane.provider)
2493
- : undefined;
2494
- const workerPolicyDir = profile !== undefined && lane.provider !== "grok"
2495
- ? path.relative(hqRoot, profile.dir).split(path.sep).join("/")
2496
- : undefined;
2497
- const profileRuntime = profile
2498
- ? materializeWorkerProfile(profile, runDir)
2499
- : undefined;
2500
- const profileLaunch = profile
2501
- ? {
2502
- systemPrompt: workerProfilePrompt(profile, policyDelivery ?? "prompt"),
2503
- ...(profileRuntime?.settingsPath !== undefined
2504
- ? { settingsPath: profileRuntime.settingsPath }
2505
- : {}),
2506
- ignoredFields: ignoredProfileFields,
2507
- }
2508
- : undefined;
2509
- const pinnedModel = lane.model_source === undefined || lane.model_source === "cli" || lane.model_source === "preserved"
2510
- ? lane.model
2511
- : undefined;
2512
- const resolved = resolveAccount(lane.provider, lane.account, config, {
2513
- hqRoot,
2514
- existsSync,
2515
- hostname,
2516
- model: pinnedModel ?? profileModel,
2517
- });
2518
- if (profileDefaultsApply && profileModel !== undefined && pinnedModel === undefined) {
2519
- validateProfileLaneModel(lane.provider, profileModel, resolved.home, profile.id, {
2520
- ...deps.modelDeps,
2521
- env: deps.modelDeps?.env ?? env,
2522
- });
2523
- }
2524
- const autoCompactTokens = lane.provider === "claude"
2525
- ? providerAutoCompactTokens(config.providers.claude)
2526
- : undefined;
2527
- const childEnv = workerEnv(env, { envVar: resolved.envVar, home: resolved.home }, lane.lane_id, hqRoot, autoCompactTokens, lane.mesh_company ?? lane.company ?? undefined, workerPolicyDir, lane.registry_worker);
2528
- const accountCfg = config.providers[lane.provider].accounts[resolved.id];
2529
- const model = resolveLaneModel({
2530
- cliModel: pinnedModel,
2531
- profileModel,
2532
- accountModel: accountCfg?.model,
2533
- providerModel: config.providers[lane.provider].model,
2534
- });
2535
- const effort = resolveLaneEffort({
2536
- cliEffort: lane.effort_source === "cli" ? lane.effort : undefined,
2537
- profileEffort,
2538
- accountEffort: accountCfg?.effort,
2539
- providerEffort: config.providers[lane.provider].effort,
2540
- model,
2541
- });
2542
- const fastMode = lane.provider === "codex"
2543
- ? (profileDefaultsApply ? profile?.meta.fast_mode : undefined) ??
2544
- (model !== undefined && (config.providers.codex.fast_mode_models ?? []).includes(model))
2545
- : false;
2546
- const repairPrompt = envelopeRepairPrompt({
2547
- envelopePath: input.envelopePath,
2548
- error: input.error,
2549
- rawText: input.rawText,
2550
- missing: input.missing,
2551
- });
2552
- const command = buildProviderCommand(lane.provider, {
2553
- hqRoot,
2554
- briefPath: path.join(runDir, "brief.md"),
2555
- envelopePath: input.envelopePath,
2556
- lastMessagePath: path.join(logsDir, "last-message.txt"),
2557
- model,
2558
- effort: effort.effort,
2559
- fastMode,
2560
- profile: profileLaunch,
2561
- workerPolicyDir,
2562
- ...(mode === "resume" && sessionId !== null
2563
- ? { resume: { session_id: sessionId, prompt: repairPrompt } }
2564
- : { freshTurnPrompt: repairPrompt }),
2565
- });
2566
- const workerOutOffset = fileSizeOrZero(path.join(logsDir, "worker.out"));
2567
- const previous = readSpawnManifest(runDir);
2568
- let workerPid;
2569
- try {
2570
- workerPid = spawnDetached(spawnProcess, command.command, command.args, childEnv, hqRoot, path.join(logsDir, "worker.out"), path.join(logsDir, "worker.err"));
2571
- writePidRecord(path.join(runDir, "worker.pid"), {
2572
- pid: workerPid,
2573
- starttime: readProcStarttime(workerPid) ?? undefined,
2574
- });
2575
- requireDetached(proveDetached, workerPid, "worker");
2576
- const watcherPid = readPidRecord(path.join(runDir, "watcher.pid"))?.pid ?? 0;
2577
- writeSpawnManifest(runDir, {
2578
- command: command.command,
2579
- args: command.args,
2580
- envVar: resolved.envVar,
2581
- account: resolved.id,
2582
- workerPid,
2583
- watcherPid,
2584
- envelopePath: previous.envelope_path ?? input.envelopePath,
2585
- resume: mode === "resume" && sessionId !== null ? { session_id: sessionId } : null,
2586
- workerOutOffset,
2587
- fastMode,
2588
- ...(profile
2589
- ? {
2590
- profile: {
2591
- id: profile.id,
2592
- hash: profile.contentHash,
2593
- ignoredFields: ignoredProfileFields,
2594
- policyDelivery: policyDelivery ?? "prompt",
2595
- ...(workerPolicyDir !== undefined ? { policyDir: workerPolicyDir } : {}),
2596
- ...(profileRuntime?.settingsPath !== undefined
2597
- ? { settingsPath: profileRuntime.settingsPath }
2598
- : {}),
2599
- },
2600
- }
2601
- : {}),
2602
- });
2603
- if (profile !== undefined) {
2604
- appendWorkerProfileEvent(runDir, {
2605
- profile_id: profile.id,
2606
- profile_hash: profile.contentHash,
2607
- changed: lane.worker_profile_hash !== profile.contentHash,
2608
- provider: lane.provider,
2609
- ignored_fields: ignoredProfileFields,
2610
- });
2611
- }
2612
- retryUpdateLane(hqRoot, lane.lane_id, "spawn", (current) => {
2613
- const next = { ...current };
2614
- if (profile !== undefined) {
2615
- next.worker_profile_hash = profile.contentHash;
2616
- next.worker_profile_ignored = [...ignoredProfileFields];
2617
- next.worker_policy_delivery = policyDelivery;
2618
- if (model !== undefined) {
2619
- next.model = model;
2620
- next.model_source = pinnedModel !== undefined
2621
- ? lane.model_source === "preserved" ? "preserved" : "cli"
2622
- : profileModel !== undefined
2623
- ? "profile"
2624
- : accountCfg?.model !== undefined
2625
- ? "account"
2626
- : config.providers[lane.provider].model !== undefined
2627
- ? "provider"
2628
- : "none";
2629
- }
2630
- else {
2631
- next.model = undefined;
2632
- next.model_source = "none";
2633
- }
2634
- next.effort_source = effort.source;
2635
- if (effort.effort !== undefined)
2636
- next.effort = effort.effort;
2637
- else
2638
- delete next.effort;
2639
- }
2640
- else {
2641
- next.worker_policy_delivery = undefined;
2642
- }
2643
- if (fastMode)
2644
- next.fast_mode = true;
2645
- else
2646
- delete next.fast_mode;
2647
- return next;
2648
- });
2649
- }
2650
- catch (err) {
2651
- if (workerPid !== undefined)
2652
- killQuietly(killProcess, workerPid, "worker");
2653
- throw err;
2654
- }
2655
- const startedAt = (deps.now ?? (() => new Date()))().toISOString();
2656
- const callerLaneId = typeof env.HQ_LANE_ID === "string" ? env.HQ_LANE_ID.trim() : "";
2657
- retryUpdateLane(hqRoot, lane.lane_id, "spawn", (current) => ({
2658
- ...current,
2659
- resume_history: appendCappedHistory(current.resume_history ?? [], {
2660
- at: startedAt,
2661
- trigger: "envelope_repair",
2662
- ...(callerLaneId ? { caller: callerLaneId } : {}),
2663
- }),
2664
- }));
2665
- return workerPid;
2666
- }
2667
- export { PROVIDER_HOME_ENV, PROVIDER_COMMAND };
2668
- //# sourceMappingURL=spawn.js.map