@indigoai-us/hq-cli 5.314.0 → 5.316.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 (1193) hide show
  1. package/CHANGELOG.md +4320 -1
  2. package/README.md +113 -0
  3. package/assets/bot-workers/setup/context/USER-GUIDE.md +404 -0
  4. package/assets/bot-workers/setup/context/quick-reference.md +199 -0
  5. package/assets/bot-workers/setup/skills/agents-and-team.md +167 -0
  6. package/assets/bot-workers/setup/skills/explain-hq.md +35 -0
  7. package/assets/bot-workers/setup/skills/first-company.md +74 -0
  8. package/assets/bot-workers/setup/skills/joining-a-team.md +125 -0
  9. package/assets/bot-workers/setup/skills/pricing.md +92 -0
  10. package/assets/bot-workers/setup/skills/standing-help.md +81 -0
  11. package/assets/bot-workers/setup/skills/your-business.md +281 -0
  12. package/assets/bot-workers/setup/worker.yaml +791 -0
  13. package/assets/lanes-hooks/hq-lanes-drain.json +15 -0
  14. package/assets/lanes-hooks/hq-lanes-drain.mjs +275 -0
  15. package/assets/lanes-hooks/hq-lanes-drain.sh +21 -0
  16. package/assets/lanes-reconcile/hq-lanes-reconcile.service +11 -0
  17. package/assets/lanes-reconcile/hq-lanes-reconcile.timer +12 -0
  18. package/assets/scaffold/.claude/hooks/validate-policy-frontmatter.sh +485 -0
  19. package/assets/scaffold/core/scripts/audit-log.sh +384 -0
  20. package/assets/scaffold/core/scripts/checkpoint-stop-gate.sh +281 -43
  21. package/assets/scaffold/core/scripts/clean-worktree-reconcile-handoff.sh +171 -0
  22. package/assets/scaffold/core/scripts/detect-stale-review-base.sh +199 -0
  23. package/assets/scaffold/core/scripts/eval-trigger.sh +193 -0
  24. package/assets/scaffold/core/scripts/git-pack-extension-check.sh +164 -0
  25. package/assets/scaffold/core/scripts/handoff-finalize.sh +688 -0
  26. package/assets/scaffold/core/scripts/handoff-open-steps.sh +81 -0
  27. package/assets/scaffold/core/scripts/handoff-post.sh +252 -0
  28. package/assets/scaffold/core/scripts/hook-lib.sh +345 -50
  29. package/assets/scaffold/core/scripts/hq-delegate-bundle.sh +307 -0
  30. package/assets/scaffold/core/scripts/hq-delegate-grant.sh +252 -0
  31. package/assets/scaffold/core/scripts/hq-delegate-pickup.sh +99 -0
  32. package/assets/scaffold/core/scripts/hq-delegate-publish.sh +91 -0
  33. package/assets/scaffold/core/scripts/hq-delegate-repo.sh +158 -0
  34. package/assets/scaffold/core/scripts/hq-delegate-resolve.sh +145 -0
  35. package/assets/scaffold/core/scripts/hq-delegate-secrets.sh +129 -0
  36. package/assets/scaffold/core/scripts/hq-delegate-send.sh +259 -0
  37. package/assets/scaffold/core/scripts/hq-delegate-transfer.sh +175 -0
  38. package/assets/scaffold/core/scripts/hq-delegate-verify.sh +238 -0
  39. package/assets/scaffold/core/scripts/hq-dm-bind.sh +585 -0
  40. package/assets/scaffold/core/scripts/hq-job-notify.sh +389 -0
  41. package/assets/scaffold/core/scripts/hq-job-probe.sh +835 -0
  42. package/assets/scaffold/core/scripts/hq-job-remediate.sh +359 -0
  43. package/assets/scaffold/core/scripts/hq-job-run.sh +1025 -0
  44. package/assets/scaffold/core/scripts/hq-pin.sh +118 -0
  45. package/assets/scaffold/core/scripts/hq-session.sh +184 -23
  46. package/assets/scaffold/core/scripts/jobs-schedule-parse.sh +310 -0
  47. package/assets/scaffold/core/scripts/jobs-validate.sh +451 -0
  48. package/assets/scaffold/core/scripts/knowledge-prefs.sh +55 -0
  49. package/assets/scaffold/core/scripts/lib/portable.sh +211 -0
  50. package/assets/scaffold/core/scripts/lib/secret-patterns.sh +58 -0
  51. package/assets/scaffold/core/scripts/lib/session-id.sh +3 -2
  52. package/assets/scaffold/core/scripts/lib/session-scope-capability.sh +1 -1
  53. package/assets/scaffold/core/scripts/lib/work-mesh-enqueue.sh +2 -1
  54. package/assets/scaffold/core/scripts/lib/work-mesh-live-hook.sh +378 -0
  55. package/assets/scaffold/core/scripts/lib/work-mesh-live-rebind.sh +141 -0
  56. package/assets/scaffold/core/scripts/migrate-policy-triggers.sh +378 -0
  57. package/assets/scaffold/core/scripts/ontology-audience-grant.sh +81 -0
  58. package/assets/scaffold/core/scripts/ontology-brief.mjs +93 -0
  59. package/assets/scaffold/core/scripts/ontology-candidate.sh +100 -0
  60. package/assets/scaffold/core/scripts/ontology-garden.mjs +238 -0
  61. package/assets/scaffold/core/scripts/ontology-source-worklist.sh +79 -0
  62. package/assets/scaffold/core/scripts/outpost-jobs-reconcile.sh +834 -0
  63. package/assets/scaffold/core/scripts/policy-age-report.sh +156 -0
  64. package/assets/scaffold/core/scripts/policy-retire.sh +199 -0
  65. package/assets/scaffold/core/scripts/qmd-reindex-after-sync.sh +10 -87
  66. package/assets/scaffold/core/scripts/qmd-reindex-bg.sh +40 -0
  67. package/assets/scaffold/core/scripts/read-policy-frontmatter.sh +32 -0
  68. package/assets/scaffold/core/scripts/rebuild-company-knowledge-index.sh +36 -3
  69. package/assets/scaffold/core/scripts/rebuild-projects-index.sh +99 -12
  70. package/assets/scaffold/core/scripts/refresh-vault-access.sh +188 -0
  71. package/assets/scaffold/core/scripts/register-project.sh +262 -0
  72. package/assets/scaffold/core/scripts/repo-run-registry.sh +408 -0
  73. package/assets/scaffold/core/scripts/resolve-company.sh +199 -0
  74. package/assets/scaffold/core/scripts/resume-thread-lock.sh +285 -0
  75. package/assets/scaffold/core/scripts/share-suggestion-state.sh +541 -0
  76. package/assets/scaffold/core/scripts/source-yaml-validate.sh +36 -0
  77. package/assets/scaffold/core/scripts/token-usage-report.sh +81 -20
  78. package/assets/scaffold/core/scripts/verify-story-deliverables.sh +148 -0
  79. package/assets/scaffold/core/scripts/work-mesh-live-bind-trusted.sh +152 -0
  80. package/assets/scaffold/core/scripts/work-mesh-live-rebind.sh +59 -0
  81. package/assets/scaffold/core/scripts/worktree-gc.sh +362 -0
  82. package/contracts/preflight/v1/fixtures.json +87 -0
  83. package/contracts/preflight/v1/schema.json +58 -0
  84. package/dist/bin/hq-auth-refresh.d.ts +2 -0
  85. package/dist/bin/hq-auth-refresh.js +12 -6
  86. package/dist/command-catalog.generated.d.ts +10798 -0
  87. package/dist/command-catalog.generated.js +13915 -0
  88. package/dist/command-registration-plan.d.ts +474 -0
  89. package/dist/command-registration-plan.js +136 -0
  90. package/dist/commands/__fixtures__/access-vault.d.ts +2 -0
  91. package/dist/commands/__fixtures__/access-vault.js +1 -1
  92. package/dist/commands/_patterns.d.ts +16 -0
  93. package/dist/commands/_patterns.js +20 -3
  94. package/dist/commands/access.d.ts +2 -1
  95. package/dist/commands/access.js +58 -49
  96. package/dist/commands/agent-enroll.d.ts +146 -0
  97. package/dist/commands/agent-enroll.js +401 -0
  98. package/dist/commands/agent-inbox.d.ts +9 -0
  99. package/dist/commands/agent-inbox.js +102 -0
  100. package/dist/commands/agent-kit.d.ts +87 -0
  101. package/dist/commands/agent-kit.js +480 -0
  102. package/dist/commands/agent-mcp.d.ts +24 -0
  103. package/dist/commands/agent-mcp.js +127 -0
  104. package/dist/commands/agent-probe.d.ts +77 -0
  105. package/dist/commands/agent-probe.js +335 -0
  106. package/dist/commands/agent.d.ts +13 -0
  107. package/dist/commands/agent.js +40 -0
  108. package/dist/commands/agents.d.ts +106 -4
  109. package/dist/commands/agents.js +924 -45
  110. package/dist/commands/auth.d.ts +1 -0
  111. package/dist/commands/auth.js +189 -19
  112. package/dist/commands/billing-sponsor.d.ts +83 -0
  113. package/dist/commands/billing-sponsor.js +344 -0
  114. package/dist/commands/billing.d.ts +3 -0
  115. package/dist/commands/billing.js +6 -1
  116. package/dist/commands/bot-companies.d.ts +40 -0
  117. package/dist/commands/bot-companies.js +64 -0
  118. package/dist/commands/bot-continuity.d.ts +28 -0
  119. package/dist/commands/bot-continuity.js +68 -0
  120. package/dist/commands/bot-jobs.d.ts +131 -0
  121. package/dist/commands/bot-jobs.js +474 -0
  122. package/dist/commands/bot.d.ts +278 -0
  123. package/dist/commands/bot.js +1982 -0
  124. package/dist/commands/channels.js +56 -1
  125. package/dist/commands/cloud-demote.js +3 -2
  126. package/dist/commands/cloud-provision.d.ts +14 -0
  127. package/dist/commands/cloud-provision.js +232 -58
  128. package/dist/commands/cloud-retire.d.ts +51 -0
  129. package/dist/commands/cloud-retire.js +154 -0
  130. package/dist/commands/cloud.d.ts +49 -15
  131. package/dist/commands/cloud.js +357 -122
  132. package/dist/commands/company-rename-flag.d.ts +4 -0
  133. package/dist/commands/company-rename-flag.js +7 -0
  134. package/dist/commands/company-rename.d.ts +4 -0
  135. package/dist/commands/company-rename.js +90 -0
  136. package/dist/commands/company-transfer.d.ts +4 -28
  137. package/dist/commands/company-transfer.js +5 -49
  138. package/dist/commands/company.js +68 -3
  139. package/dist/commands/core-audit-log-native.d.ts +9 -0
  140. package/dist/commands/core-audit-log-native.js +257 -0
  141. package/dist/commands/core-checkpoint-gate-setting.d.ts +59 -0
  142. package/dist/commands/core-checkpoint-gate-setting.js +163 -0
  143. package/dist/commands/core-checkpoint-stop-gate-native.d.ts +34 -0
  144. package/dist/commands/core-checkpoint-stop-gate-native.js +725 -0
  145. package/dist/commands/core-checkpoint.d.ts +19 -9
  146. package/dist/commands/core-checkpoint.js +301 -37
  147. package/dist/commands/core-command-catalog.d.ts +34 -0
  148. package/dist/commands/core-command-catalog.js +62 -0
  149. package/dist/commands/core-company-index-scope-flag.d.ts +3 -0
  150. package/dist/commands/core-company-index-scope-flag.js +6 -0
  151. package/dist/commands/core-delegate-w1b.d.ts +10 -0
  152. package/dist/commands/core-delegate-w1b.js +1219 -0
  153. package/dist/commands/core-delegate.d.ts +46 -0
  154. package/dist/commands/core-delegate.js +1040 -0
  155. package/dist/commands/core-detect-stale-review-base-native.d.ts +23 -0
  156. package/dist/commands/core-detect-stale-review-base-native.js +178 -0
  157. package/dist/commands/core-dm-bind-native.d.ts +32 -0
  158. package/dist/commands/core-dm-bind-native.js +668 -0
  159. package/dist/commands/core-eval-trigger-native.d.ts +4 -0
  160. package/dist/commands/core-eval-trigger-native.js +12 -0
  161. package/dist/commands/core-git-pack-extension-check-native.d.ts +22 -0
  162. package/dist/commands/core-git-pack-extension-check-native.js +190 -0
  163. package/dist/commands/core-handoff-fast.d.ts +18 -0
  164. package/dist/commands/core-handoff-fast.js +104 -0
  165. package/dist/commands/core-handoff-open-steps.d.ts +21 -0
  166. package/dist/commands/core-handoff-open-steps.js +264 -0
  167. package/dist/commands/core-handoff.d.ts +24 -0
  168. package/dist/commands/core-handoff.js +1144 -0
  169. package/dist/commands/core-hook-state-helpers-native.d.ts +11 -0
  170. package/dist/commands/core-hook-state-helpers-native.js +74 -0
  171. package/dist/commands/core-hq-session-native.d.ts +39 -0
  172. package/dist/commands/core-hq-session-native.js +579 -0
  173. package/dist/commands/core-job-native-utils.d.ts +6 -0
  174. package/dist/commands/core-job-native-utils.js +80 -0
  175. package/dist/commands/core-job-native.d.ts +5 -0
  176. package/dist/commands/core-job-native.js +16 -0
  177. package/dist/commands/core-job-notify-native.d.ts +36 -0
  178. package/dist/commands/core-job-notify-native.js +359 -0
  179. package/dist/commands/core-job-probe-native.d.ts +45 -0
  180. package/dist/commands/core-job-probe-native.js +564 -0
  181. package/dist/commands/core-job-remediate-native.d.ts +26 -0
  182. package/dist/commands/core-job-remediate-native.js +374 -0
  183. package/dist/commands/core-job-remote-launcher.d.ts +7 -0
  184. package/dist/commands/core-job-remote-launcher.js +51 -0
  185. package/dist/commands/core-job-run-native.d.ts +47 -0
  186. package/dist/commands/core-job-run-native.js +1215 -0
  187. package/dist/commands/core-jobs-native.d.ts +25 -0
  188. package/dist/commands/core-jobs-native.js +1339 -0
  189. package/dist/commands/core-knowledge-prefs.d.ts +11 -0
  190. package/dist/commands/core-knowledge-prefs.js +137 -0
  191. package/dist/commands/core-migrate-policy-triggers-native.d.ts +21 -0
  192. package/dist/commands/core-migrate-policy-triggers-native.js +374 -0
  193. package/dist/commands/core-native-handoff-flag.d.ts +4 -0
  194. package/dist/commands/core-native-handoff-flag.js +7 -0
  195. package/dist/commands/core-native-hook-helper-commands.d.ts +4 -0
  196. package/dist/commands/core-native-hook-helper-commands.js +56 -0
  197. package/dist/commands/core-native-hook-helpers-flag.d.ts +4 -0
  198. package/dist/commands/core-native-hook-helpers-flag.js +7 -0
  199. package/dist/commands/core-native-jobs-flag.d.ts +4 -0
  200. package/dist/commands/core-native-jobs-flag.js +7 -0
  201. package/dist/commands/core-native-policy-flag.d.ts +9 -0
  202. package/dist/commands/core-native-policy-flag.js +12 -0
  203. package/dist/commands/core-native-session-flag.d.ts +4 -0
  204. package/dist/commands/core-native-session-flag.js +7 -0
  205. package/dist/commands/core-native-utilities-flag.d.ts +4 -0
  206. package/dist/commands/core-native-utilities-flag.js +7 -0
  207. package/dist/commands/core-native-utilities.d.ts +29 -0
  208. package/dist/commands/core-native-utilities.js +54 -0
  209. package/dist/commands/core-native-worker-skills-flag.d.ts +4 -0
  210. package/dist/commands/core-native-worker-skills-flag.js +7 -0
  211. package/dist/commands/core-ontology-native.d.ts +17 -0
  212. package/dist/commands/core-ontology-native.js +916 -0
  213. package/dist/commands/core-ontology.d.ts +66 -0
  214. package/dist/commands/core-ontology.js +430 -0
  215. package/dist/commands/core-pin-native.d.ts +14 -0
  216. package/dist/commands/core-pin-native.js +236 -0
  217. package/dist/commands/core-policy-frontmatter.d.ts +8 -0
  218. package/dist/commands/core-policy-frontmatter.js +52 -0
  219. package/dist/commands/core-policy.d.ts +14 -0
  220. package/dist/commands/core-policy.js +1018 -0
  221. package/dist/commands/core-refresh-vault-access-native.d.ts +20 -0
  222. package/dist/commands/core-refresh-vault-access-native.js +229 -0
  223. package/dist/commands/core-register-project-native.d.ts +30 -0
  224. package/dist/commands/core-register-project-native.js +347 -0
  225. package/dist/commands/core-repo-run-registry-native.d.ts +19 -0
  226. package/dist/commands/core-repo-run-registry-native.js +357 -0
  227. package/dist/commands/core-resolve-company-command.d.ts +4 -0
  228. package/dist/commands/core-resolve-company-command.js +42 -0
  229. package/dist/commands/core-resolve-company-native.d.ts +28 -0
  230. package/dist/commands/core-resolve-company-native.js +408 -0
  231. package/dist/commands/core-share-suggestion-state-native.d.ts +18 -0
  232. package/dist/commands/core-share-suggestion-state-native.js +445 -0
  233. package/dist/commands/core-work-mesh-bind-trusted-native.d.ts +32 -0
  234. package/dist/commands/core-work-mesh-bind-trusted-native.js +190 -0
  235. package/dist/commands/core-work-mesh-live-rebind-native.d.ts +18 -0
  236. package/dist/commands/core-work-mesh-live-rebind-native.js +262 -0
  237. package/dist/commands/core-worker-lint-native.d.ts +4 -0
  238. package/dist/commands/core-worker-lint-native.js +160 -0
  239. package/dist/commands/core-worker-share-native.d.ts +4 -0
  240. package/dist/commands/core-worker-share-native.js +260 -0
  241. package/dist/commands/core-worker-skills-command.d.ts +8 -0
  242. package/dist/commands/core-worker-skills-command.js +33 -0
  243. package/dist/commands/core-worker-skills-runtime.d.ts +33 -0
  244. package/dist/commands/core-worker-skills-runtime.js +86 -0
  245. package/dist/commands/core.d.ts +4 -0
  246. package/dist/commands/core.js +282 -80
  247. package/dist/commands/crm.js +52 -3
  248. package/dist/commands/daemon.d.ts +63 -0
  249. package/dist/commands/daemon.js +877 -0
  250. package/dist/commands/db-provision.js +4 -4
  251. package/dist/commands/db-sql.js +7 -21
  252. package/dist/commands/deploy-comments.d.ts +3 -0
  253. package/dist/commands/deploy-comments.js +162 -0
  254. package/dist/commands/dm.d.ts +119 -12
  255. package/dist/commands/dm.js +388 -38
  256. package/dist/commands/doctor.d.ts +12 -0
  257. package/dist/commands/doctor.js +158 -12
  258. package/dist/commands/feedback.d.ts +6 -0
  259. package/dist/commands/feedback.js +86 -37
  260. package/dist/commands/files-browse.d.ts +32 -12
  261. package/dist/commands/files-browse.js +176 -60
  262. package/dist/commands/files.d.ts +17 -0
  263. package/dist/commands/files.js +300 -47
  264. package/dist/commands/group-grants.js +3 -2
  265. package/dist/commands/groups.js +6 -5
  266. package/dist/commands/index-cmd.d.ts +19 -1
  267. package/dist/commands/index-cmd.js +74 -7
  268. package/dist/commands/integrations-api.d.ts +15 -10
  269. package/dist/commands/integrations-api.js +27 -22
  270. package/dist/commands/integrations-connect.d.ts +51 -13
  271. package/dist/commands/integrations-connect.js +86 -71
  272. package/dist/commands/integrations-core.d.ts +6 -6
  273. package/dist/commands/integrations-core.js +25 -11
  274. package/dist/commands/integrations-import.d.ts +1 -1
  275. package/dist/commands/integrations-import.js +43 -24
  276. package/dist/commands/integrations-manage.js +20 -13
  277. package/dist/commands/integrations.d.ts +8 -0
  278. package/dist/commands/integrations.js +94 -7
  279. package/dist/commands/lanes-accounts.d.ts +28 -0
  280. package/dist/commands/lanes-accounts.js +595 -0
  281. package/dist/commands/lanes-autopilot.d.ts +11 -0
  282. package/dist/commands/lanes-autopilot.js +336 -0
  283. package/dist/commands/lanes-checks.d.ts +51 -0
  284. package/dist/commands/lanes-checks.js +941 -0
  285. package/dist/commands/lanes-hold.d.ts +43 -0
  286. package/dist/commands/lanes-hold.js +655 -0
  287. package/dist/commands/lanes-keep-alive-audit.d.ts +10 -0
  288. package/dist/commands/lanes-keep-alive-audit.js +19 -0
  289. package/dist/commands/lanes-kpis.d.ts +11 -0
  290. package/dist/commands/lanes-kpis.js +34 -0
  291. package/dist/commands/lanes-message.d.ts +9 -0
  292. package/dist/commands/lanes-message.js +946 -0
  293. package/dist/commands/lanes-move.d.ts +12 -0
  294. package/dist/commands/lanes-move.js +397 -0
  295. package/dist/commands/lanes-questions.d.ts +36 -0
  296. package/dist/commands/lanes-questions.js +1005 -0
  297. package/dist/commands/lanes-report.d.ts +11 -0
  298. package/dist/commands/lanes-report.js +333 -0
  299. package/dist/commands/lanes-resume.d.ts +6 -0
  300. package/dist/commands/lanes-resume.js +564 -0
  301. package/dist/commands/lanes-review.d.ts +10 -0
  302. package/dist/commands/lanes-review.js +56 -0
  303. package/dist/commands/lanes-shared.d.ts +449 -0
  304. package/dist/commands/lanes-shared.js +170 -0
  305. package/dist/commands/lanes-stories.d.ts +15 -0
  306. package/dist/commands/lanes-stories.js +347 -0
  307. package/dist/commands/lanes-watch.d.ts +7 -0
  308. package/dist/commands/lanes-watch.js +216 -0
  309. package/dist/commands/lanes.d.ts +149 -0
  310. package/dist/commands/lanes.js +9013 -0
  311. package/dist/commands/login.js +49 -6
  312. package/dist/commands/mcp-registration.d.ts +32 -25
  313. package/dist/commands/mcp-registration.js +256 -23
  314. package/dist/commands/mcp-status.js +1 -0
  315. package/dist/commands/meetings.js +55 -34
  316. package/dist/commands/members.js +5 -1
  317. package/dist/commands/mesh.d.ts +11 -0
  318. package/dist/commands/mesh.js +1086 -76
  319. package/dist/commands/monitor.d.ts +58 -0
  320. package/dist/commands/monitor.js +980 -0
  321. package/dist/commands/onboard-bot-membership.d.ts +32 -0
  322. package/dist/commands/onboard-bot-membership.js +40 -0
  323. package/dist/commands/onboard-create-identity.d.ts +26 -0
  324. package/dist/commands/onboard-create-identity.js +23 -0
  325. package/dist/commands/onboard-identity-guard.d.ts +1 -1
  326. package/dist/commands/onboard.js +24 -5
  327. package/dist/commands/outpost-pruner.d.ts +3 -0
  328. package/dist/commands/outpost-pruner.js +125 -0
  329. package/dist/commands/pack-install.js +3 -1
  330. package/dist/commands/packs.js +11 -1
  331. package/dist/commands/people.d.ts +4 -0
  332. package/dist/commands/people.js +37 -3
  333. package/dist/commands/personal-connector-settings-flag.d.ts +4 -0
  334. package/dist/commands/personal-connector-settings-flag.js +7 -0
  335. package/dist/commands/personal-targeted-push-flag.d.ts +4 -0
  336. package/dist/commands/personal-targeted-push-flag.js +7 -0
  337. package/dist/commands/personal-targeted-push-paths.d.ts +3 -0
  338. package/dist/commands/personal-targeted-push-paths.js +67 -0
  339. package/dist/commands/publish.d.ts +8 -1
  340. package/dist/commands/publish.js +17 -4
  341. package/dist/commands/reindex.js +56 -6
  342. package/dist/commands/report.d.ts +19 -0
  343. package/dist/commands/report.js +537 -0
  344. package/dist/commands/rescue.d.ts +4 -0
  345. package/dist/commands/rescue.js +27 -17
  346. package/dist/commands/run-feature-telemetry.d.ts +3 -0
  347. package/dist/commands/run-feature-telemetry.js +6 -0
  348. package/dist/commands/run.js +18 -4
  349. package/dist/commands/safe-extract.d.ts +11 -2
  350. package/dist/commands/safe-extract.js +36 -8
  351. package/dist/commands/secrets.d.ts +20 -2
  352. package/dist/commands/secrets.js +175 -71
  353. package/dist/commands/skill.d.ts +35 -4
  354. package/dist/commands/skill.js +357 -18
  355. package/dist/commands/staff/reset-test-account.d.ts +110 -0
  356. package/dist/commands/staff/reset-test-account.js +268 -0
  357. package/dist/commands/staff/test-account.d.ts +51 -0
  358. package/dist/commands/staff/test-account.js +196 -0
  359. package/dist/commands/sync-mode.d.ts +11 -0
  360. package/dist/commands/sync-mode.js +30 -0
  361. package/dist/commands/sync-narrow.js +36 -5
  362. package/dist/commands/team-sync.js +71 -10
  363. package/dist/commands/update.js +6 -0
  364. package/dist/commands/vault-retention-flag.d.ts +3 -0
  365. package/dist/commands/vault-retention-flag.js +9 -0
  366. package/dist/commands/vault-retention.d.ts +11 -0
  367. package/dist/commands/vault-retention.js +69 -0
  368. package/dist/commands/version.d.ts +10 -0
  369. package/dist/commands/version.js +11 -0
  370. package/dist/commands/whoami.d.ts +22 -0
  371. package/dist/commands/whoami.js +137 -4
  372. package/dist/commands/workers.d.ts +2 -14
  373. package/dist/commands/workers.js +7 -10
  374. package/dist/fast-core.d.ts +7 -7
  375. package/dist/fast-core.js +91 -24
  376. package/dist/fast-scaffold.d.ts +86 -0
  377. package/dist/fast-scaffold.js +381 -0
  378. package/dist/index.d.ts +3 -4
  379. package/dist/index.js +59 -9
  380. package/dist/lanes-drain-hook.d.ts +14 -0
  381. package/dist/lanes-drain-hook.js +203 -0
  382. package/dist/lazy-commands.d.ts +20 -44
  383. package/dist/lazy-commands.js +60 -58
  384. package/dist/lib/agent-kit/adopt-identity.d.ts +27 -0
  385. package/dist/lib/agent-kit/adopt-identity.js +60 -0
  386. package/dist/lib/agent-kit/attachment-download.d.ts +24 -0
  387. package/dist/lib/agent-kit/attachment-download.js +47 -0
  388. package/dist/lib/agent-kit/creds.d.ts +106 -0
  389. package/dist/lib/agent-kit/creds.js +163 -0
  390. package/dist/lib/agent-kit/fallback.d.ts +78 -0
  391. package/dist/lib/agent-kit/fallback.js +210 -0
  392. package/dist/lib/agent-kit/inbox-state.d.ts +83 -0
  393. package/dist/lib/agent-kit/inbox-state.js +159 -0
  394. package/dist/lib/agent-kit/kit-config.d.ts +56 -0
  395. package/dist/lib/agent-kit/kit-config.js +65 -0
  396. package/dist/lib/agent-kit/log.d.ts +16 -0
  397. package/dist/lib/agent-kit/log.js +46 -0
  398. package/dist/lib/agent-kit/mcp/attachments.d.ts +126 -0
  399. package/dist/lib/agent-kit/mcp/attachments.js +222 -0
  400. package/dist/lib/agent-kit/mcp/jsonrpc.d.ts +75 -0
  401. package/dist/lib/agent-kit/mcp/jsonrpc.js +164 -0
  402. package/dist/lib/agent-kit/mcp/tools.d.ts +64 -0
  403. package/dist/lib/agent-kit/mcp/tools.js +397 -0
  404. package/dist/lib/agent-kit/paths.d.ts +65 -0
  405. package/dist/lib/agent-kit/paths.js +118 -0
  406. package/dist/lib/agent-kit/private-file.d.ts +29 -0
  407. package/dist/lib/agent-kit/private-file.js +91 -0
  408. package/dist/lib/agent-kit/run/heartbeat.d.ts +72 -0
  409. package/dist/lib/agent-kit/run/heartbeat.js +128 -0
  410. package/dist/lib/agent-kit/run/inbox.d.ts +76 -0
  411. package/dist/lib/agent-kit/run/inbox.js +205 -0
  412. package/dist/lib/agent-kit/run/supervisor.d.ts +35 -0
  413. package/dist/lib/agent-kit/run/supervisor.js +85 -0
  414. package/dist/lib/agent-kit/run/sync.d.ts +33 -0
  415. package/dist/lib/agent-kit/run/sync.js +58 -0
  416. package/dist/lib/agent-kit/services.d.ts +31 -0
  417. package/dist/lib/agent-kit/services.js +55 -0
  418. package/dist/lib/agent-kit/skills.d.ts +18 -0
  419. package/dist/lib/agent-kit/skills.js +151 -0
  420. package/dist/lib/agent-kit/wake.d.ts +83 -0
  421. package/dist/lib/agent-kit/wake.js +243 -0
  422. package/dist/lib/agents/model-catalog.d.ts +62 -0
  423. package/dist/lib/agents/model-catalog.js +275 -0
  424. package/dist/lib/auth-login-provider-state.d.ts +8 -0
  425. package/dist/lib/auth-login-provider-state.js +63 -0
  426. package/dist/lib/aws-sdk-node-warning-output.d.ts +12 -0
  427. package/dist/lib/aws-sdk-node-warning-output.js +22 -0
  428. package/dist/lib/billing/free-month.d.ts +18 -0
  429. package/dist/lib/billing/free-month.js +31 -0
  430. package/dist/lib/billing/plan-limit-refusals.d.ts +69 -0
  431. package/dist/lib/billing/plan-limit-refusals.js +187 -0
  432. package/dist/lib/billing/plan-limit-upgrade-url.d.ts +11 -0
  433. package/dist/lib/billing/plan-limit-upgrade-url.js +66 -0
  434. package/dist/lib/billing/plan-lock.d.ts +143 -0
  435. package/dist/lib/billing/plan-lock.js +439 -0
  436. package/dist/lib/bot/api.d.ts +349 -0
  437. package/dist/lib/bot/api.js +316 -0
  438. package/dist/lib/bot/attachments.d.ts +45 -0
  439. package/dist/lib/bot/attachments.js +89 -0
  440. package/dist/lib/bot/cli-update.d.ts +138 -0
  441. package/dist/lib/bot/cli-update.js +278 -0
  442. package/dist/lib/bot/company-bind.d.ts +27 -0
  443. package/dist/lib/bot/company-bind.js +62 -0
  444. package/dist/lib/bot/config.d.ts +153 -0
  445. package/dist/lib/bot/config.js +233 -0
  446. package/dist/lib/bot/continuity-download.d.ts +28 -0
  447. package/dist/lib/bot/continuity-download.js +75 -0
  448. package/dist/lib/bot/continuity-install.d.ts +14 -0
  449. package/dist/lib/bot/continuity-install.js +101 -0
  450. package/dist/lib/bot/continuity.d.ts +67 -0
  451. package/dist/lib/bot/continuity.js +301 -0
  452. package/dist/lib/bot/creds.d.ts +24 -0
  453. package/dist/lib/bot/creds.js +51 -0
  454. package/dist/lib/bot/daemon.d.ts +173 -0
  455. package/dist/lib/bot/daemon.js +552 -0
  456. package/dist/lib/bot/inbox-poll-backoff-flag.d.ts +24 -0
  457. package/dist/lib/bot/inbox-poll-backoff-flag.js +135 -0
  458. package/dist/lib/bot/inbox-state.d.ts +18 -0
  459. package/dist/lib/bot/inbox-state.js +51 -0
  460. package/dist/lib/bot/index.d.ts +23 -0
  461. package/dist/lib/bot/index.js +23 -0
  462. package/dist/lib/bot/inflight.d.ts +119 -0
  463. package/dist/lib/bot/inflight.js +83 -0
  464. package/dist/lib/bot/job-completions.d.ts +89 -0
  465. package/dist/lib/bot/job-completions.js +132 -0
  466. package/dist/lib/bot/job-quiet-flag.d.ts +4 -0
  467. package/dist/lib/bot/job-quiet-flag.js +14 -0
  468. package/dist/lib/bot/job-run.d.ts +114 -0
  469. package/dist/lib/bot/job-run.js +266 -0
  470. package/dist/lib/bot/local-config.d.ts +61 -0
  471. package/dist/lib/bot/local-config.js +145 -0
  472. package/dist/lib/bot/local-jobs.d.ts +89 -0
  473. package/dist/lib/bot/local-jobs.js +459 -0
  474. package/dist/lib/bot/local-name.d.ts +54 -0
  475. package/dist/lib/bot/local-name.js +114 -0
  476. package/dist/lib/bot/log.d.ts +13 -0
  477. package/dist/lib/bot/log.js +59 -0
  478. package/dist/lib/bot/owner-context.d.ts +79 -0
  479. package/dist/lib/bot/owner-context.js +175 -0
  480. package/dist/lib/bot/paths.d.ts +76 -0
  481. package/dist/lib/bot/paths.js +131 -0
  482. package/dist/lib/bot/progress.d.ts +132 -0
  483. package/dist/lib/bot/progress.js +289 -0
  484. package/dist/lib/bot/promote.d.ts +16 -0
  485. package/dist/lib/bot/promote.js +106 -0
  486. package/dist/lib/bot/promotion-hold.d.ts +24 -0
  487. package/dist/lib/bot/promotion-hold.js +103 -0
  488. package/dist/lib/bot/promotion-receipt.d.ts +9 -0
  489. package/dist/lib/bot/promotion-receipt.js +56 -0
  490. package/dist/lib/bot/promotion-upload.d.ts +16 -0
  491. package/dist/lib/bot/promotion-upload.js +80 -0
  492. package/dist/lib/bot/prompt.d.ts +136 -0
  493. package/dist/lib/bot/prompt.js +433 -0
  494. package/dist/lib/bot/room-policy.d.ts +63 -0
  495. package/dist/lib/bot/room-policy.js +91 -0
  496. package/dist/lib/bot/run.d.ts +219 -0
  497. package/dist/lib/bot/run.js +1881 -0
  498. package/dist/lib/bot/runnable.d.ts +51 -0
  499. package/dist/lib/bot/runnable.js +65 -0
  500. package/dist/lib/bot/runtime/claude.d.ts +50 -0
  501. package/dist/lib/bot/runtime/claude.js +170 -0
  502. package/dist/lib/bot/runtime/codex.d.ts +28 -0
  503. package/dist/lib/bot/runtime/codex.js +153 -0
  504. package/dist/lib/bot/runtime/grok-acp.d.ts +40 -0
  505. package/dist/lib/bot/runtime/grok-acp.js +265 -0
  506. package/dist/lib/bot/runtime/grok.d.ts +41 -0
  507. package/dist/lib/bot/runtime/grok.js +169 -0
  508. package/dist/lib/bot/runtime/index.d.ts +36 -0
  509. package/dist/lib/bot/runtime/index.js +417 -0
  510. package/dist/lib/bot/runtime/messages-stream.d.ts +56 -0
  511. package/dist/lib/bot/runtime/messages-stream.js +194 -0
  512. package/dist/lib/bot/runtime/sanitize.d.ts +18 -0
  513. package/dist/lib/bot/runtime/sanitize.js +28 -0
  514. package/dist/lib/bot/runtime/types.d.ts +159 -0
  515. package/dist/lib/bot/runtime/types.js +51 -0
  516. package/dist/lib/bot/runtime/windows.d.ts +10 -0
  517. package/dist/lib/bot/runtime/windows.js +53 -0
  518. package/dist/lib/bot/runtime-sign-in.d.ts +24 -0
  519. package/dist/lib/bot/runtime-sign-in.js +31 -0
  520. package/dist/lib/bot/scaffold.d.ts +38 -0
  521. package/dist/lib/bot/scaffold.js +94 -0
  522. package/dist/lib/bot/self-heal.d.ts +52 -0
  523. package/dist/lib/bot/self-heal.js +79 -0
  524. package/dist/lib/bot/self-process.d.ts +19 -0
  525. package/dist/lib/bot/self-process.js +35 -0
  526. package/dist/lib/bot/session.d.ts +19 -0
  527. package/dist/lib/bot/session.js +39 -0
  528. package/dist/lib/bot/setup-explain.d.ts +64 -0
  529. package/dist/lib/bot/setup-explain.js +141 -0
  530. package/dist/lib/bot/split.d.ts +32 -0
  531. package/dist/lib/bot/split.js +241 -0
  532. package/dist/lib/bot/status.d.ts +57 -0
  533. package/dist/lib/bot/status.js +66 -0
  534. package/dist/lib/bot/worker-source.d.ts +66 -0
  535. package/dist/lib/bot/worker-source.js +283 -0
  536. package/dist/lib/checkpoint-ontology/aliases.d.ts +17 -0
  537. package/dist/lib/checkpoint-ontology/aliases.js +44 -0
  538. package/dist/lib/checkpoint-ontology/apply.d.ts +110 -0
  539. package/dist/lib/checkpoint-ontology/apply.js +777 -0
  540. package/dist/lib/checkpoint-ontology/company-brief.d.ts +18 -0
  541. package/dist/lib/checkpoint-ontology/company-brief.js +337 -0
  542. package/dist/lib/checkpoint-ontology/company.d.ts +44 -0
  543. package/dist/lib/checkpoint-ontology/company.js +118 -0
  544. package/dist/lib/checkpoint-ontology/drop-aliases.d.ts +41 -0
  545. package/dist/lib/checkpoint-ontology/drop-aliases.js +76 -0
  546. package/dist/lib/checkpoint-ontology/entity-file.d.ts +109 -0
  547. package/dist/lib/checkpoint-ontology/entity-file.js +371 -0
  548. package/dist/lib/checkpoint-ontology/identity.d.ts +38 -0
  549. package/dist/lib/checkpoint-ontology/identity.js +95 -0
  550. package/dist/lib/checkpoint-ontology/merge-copies.d.ts +199 -0
  551. package/dist/lib/checkpoint-ontology/merge-copies.js +1086 -0
  552. package/dist/lib/checkpoint-ontology/multi-writer.d.ts +101 -0
  553. package/dist/lib/checkpoint-ontology/multi-writer.js +394 -0
  554. package/dist/lib/checkpoint-ontology/plan.d.ts +193 -0
  555. package/dist/lib/checkpoint-ontology/plan.js +504 -0
  556. package/dist/lib/checkpoint-ontology/queued-touches.d.ts +29 -0
  557. package/dist/lib/checkpoint-ontology/queued-touches.js +193 -0
  558. package/dist/lib/checkpoint-ontology/sync-client.d.ts +38 -0
  559. package/dist/lib/checkpoint-ontology/sync-client.js +84 -0
  560. package/dist/lib/checkpoint-ontology/tree.d.ts +55 -0
  561. package/dist/lib/checkpoint-ontology/tree.js +198 -0
  562. package/dist/lib/company-errors-sdk-warning-flag.d.ts +5 -0
  563. package/dist/lib/company-errors-sdk-warning-flag.js +8 -0
  564. package/dist/lib/company-skill-wrapper.d.ts +1 -0
  565. package/dist/lib/company-skill-wrapper.js +121 -29
  566. package/dist/lib/core-utils/codex-skill-bridge.d.ts +2 -1
  567. package/dist/lib/core-utils/common.d.ts +0 -1
  568. package/dist/lib/core-utils/common.js +0 -9
  569. package/dist/lib/core-utils/hook-timeout-debug-context-flag.d.ts +20 -0
  570. package/dist/lib/core-utils/hook-timeout-debug-context-flag.js +81 -0
  571. package/dist/lib/core-utils/jq-json-serializer.d.ts +5 -0
  572. package/dist/lib/core-utils/jq-json-serializer.js +10 -0
  573. package/dist/lib/core-utils/qmd-reindex-after-sync.d.ts +14 -1
  574. package/dist/lib/core-utils/qmd-reindex-after-sync.js +101 -17
  575. package/dist/lib/core-utils/secret-patterns.d.ts +43 -0
  576. package/dist/lib/core-utils/secret-patterns.js +34 -0
  577. package/dist/lib/core-utils/sentry-report.d.ts +114 -0
  578. package/dist/lib/core-utils/sentry-report.js +1055 -0
  579. package/dist/lib/core-utils/soft-timeout.js +1 -1
  580. package/dist/lib/core-utils/timeout-guard-native.d.ts +7 -0
  581. package/dist/lib/core-utils/timeout-guard-native.js +40 -0
  582. package/dist/lib/core-utils/timeout-guard.d.ts +3 -3
  583. package/dist/lib/core-utils/timeout-guard.js +28 -13
  584. package/dist/lib/core-utils/token-usage-report.js +17 -3
  585. package/dist/lib/core-utils/worktree-resume.d.ts +20 -0
  586. package/dist/lib/core-utils/worktree-resume.js +1198 -0
  587. package/dist/lib/daemon/catalog.d.ts +134 -0
  588. package/dist/lib/daemon/catalog.js +358 -0
  589. package/dist/lib/daemon/config.d.ts +35 -0
  590. package/dist/lib/daemon/config.js +108 -0
  591. package/dist/lib/daemon/flag.d.ts +25 -0
  592. package/dist/lib/daemon/flag.js +59 -0
  593. package/dist/lib/daemon/handoff.d.ts +56 -0
  594. package/dist/lib/daemon/handoff.js +161 -0
  595. package/dist/lib/daemon/hq-cloud.d.ts +79 -0
  596. package/dist/lib/daemon/hq-cloud.js +183 -0
  597. package/dist/lib/daemon/install.d.ts +85 -0
  598. package/dist/lib/daemon/install.js +320 -0
  599. package/dist/lib/daemon/legacy-sync-env.d.ts +10 -0
  600. package/dist/lib/daemon/legacy-sync-env.js +58 -0
  601. package/dist/lib/daemon/legacy.d.ts +45 -0
  602. package/dist/lib/daemon/legacy.js +133 -0
  603. package/dist/lib/daemon/lock.d.ts +47 -0
  604. package/dist/lib/daemon/lock.js +138 -0
  605. package/dist/lib/daemon/machine-type.d.ts +50 -0
  606. package/dist/lib/daemon/machine-type.js +159 -0
  607. package/dist/lib/daemon/migrate.d.ts +77 -0
  608. package/dist/lib/daemon/migrate.js +265 -0
  609. package/dist/lib/daemon/paths.d.ts +24 -0
  610. package/dist/lib/daemon/paths.js +43 -0
  611. package/dist/lib/daemon/protocol-tail.d.ts +33 -0
  612. package/dist/lib/daemon/protocol-tail.js +131 -0
  613. package/dist/lib/daemon/remote-control.d.ts +74 -0
  614. package/dist/lib/daemon/remote-control.js +153 -0
  615. package/dist/lib/daemon/requests.d.ts +28 -0
  616. package/dist/lib/daemon/requests.js +65 -0
  617. package/dist/lib/daemon/run.d.ts +79 -0
  618. package/dist/lib/daemon/run.js +755 -0
  619. package/dist/lib/daemon/succession.d.ts +118 -0
  620. package/dist/lib/daemon/succession.js +263 -0
  621. package/dist/lib/daemon/supervisor.d.ts +132 -0
  622. package/dist/lib/daemon/supervisor.js +836 -0
  623. package/dist/lib/daemon/sync-runner.d.ts +58 -0
  624. package/dist/lib/daemon/sync-runner.js +277 -0
  625. package/dist/lib/daemon/tools.d.ts +52 -0
  626. package/dist/lib/daemon/tools.js +95 -0
  627. package/dist/lib/daemon/updater.d.ts +57 -0
  628. package/dist/lib/daemon/updater.js +163 -0
  629. package/dist/lib/db/control-plane.js +6 -0
  630. package/dist/lib/db/local.d.ts +0 -5
  631. package/dist/lib/db/local.js +1 -1
  632. package/dist/lib/db/migrate.d.ts +0 -12
  633. package/dist/lib/db/migrate.js +5 -5
  634. package/dist/lib/db/remote-sql.d.ts +2 -2
  635. package/dist/lib/db/remote-sql.js +3 -3
  636. package/dist/lib/db/sql.d.ts +0 -10
  637. package/dist/lib/db/sql.js +4 -8
  638. package/dist/lib/deploy-api.d.ts +5 -0
  639. package/dist/lib/deploy-api.js +21 -0
  640. package/dist/lib/deploy-apps.d.ts +13 -0
  641. package/dist/lib/deploy-apps.js +29 -0
  642. package/dist/lib/doctor/__testing__/fake-hq-tree.d.ts +1 -1
  643. package/dist/lib/doctor/__testing__/fake-hq-tree.js +1 -1
  644. package/dist/lib/doctor/__testing__/run-doctor.d.ts +8 -0
  645. package/dist/lib/doctor/__testing__/run-doctor.js +52 -0
  646. package/dist/lib/doctor/checks/bots.d.ts +13 -0
  647. package/dist/lib/doctor/checks/bots.js +189 -0
  648. package/dist/lib/doctor/checks/claude-wiring.js +70 -1
  649. package/dist/lib/doctor/checks/codex-wiring.d.ts +0 -4
  650. package/dist/lib/doctor/checks/codex-wiring.js +3 -35
  651. package/dist/lib/doctor/checks/grok-wiring.js +1 -34
  652. package/dist/lib/doctor/checks/integrations.js +11 -0
  653. package/dist/lib/doctor/checks/runtime-health.d.ts +4 -17
  654. package/dist/lib/doctor/checks/runtime-health.js +20 -7
  655. package/dist/lib/doctor/checks/scaffold-cli-floor.d.ts +6 -0
  656. package/dist/lib/doctor/checks/scaffold-cli-floor.js +73 -0
  657. package/dist/lib/doctor/checks/sync-health.d.ts +21 -0
  658. package/dist/lib/doctor/checks/sync-health.js +72 -2
  659. package/dist/lib/doctor/checks/sync-runtime.d.ts +11 -0
  660. package/dist/lib/doctor/checks/sync-runtime.js +216 -0
  661. package/dist/lib/doctor/checks/work-context.js +20 -6
  662. package/dist/lib/doctor/client-health-flag-token.d.ts +15 -0
  663. package/dist/lib/doctor/client-health-flag-token.js +66 -0
  664. package/dist/lib/doctor/client-health-reason-codes-flag.d.ts +27 -0
  665. package/dist/lib/doctor/client-health-reason-codes-flag.js +106 -0
  666. package/dist/lib/doctor/compat.d.ts +0 -16
  667. package/dist/lib/doctor/compat.js +4 -3
  668. package/dist/lib/doctor/deep/effects.js +1 -3
  669. package/dist/lib/doctor/deep/executor.d.ts +4 -10
  670. package/dist/lib/doctor/deep/executor.js +1 -1
  671. package/dist/lib/doctor/deep/parity.d.ts +2 -29
  672. package/dist/lib/doctor/deep/parity.js +7 -7
  673. package/dist/lib/doctor/deep/sandbox.d.ts +7 -25
  674. package/dist/lib/doctor/deep/sandbox.js +5 -7
  675. package/dist/lib/doctor/fix/apply.d.ts +79 -8
  676. package/dist/lib/doctor/fix/apply.js +292 -80
  677. package/dist/lib/doctor/fix/json-output.d.ts +28 -0
  678. package/dist/lib/doctor/fix/json-output.js +33 -0
  679. package/dist/lib/doctor/fix/refresh-sync-outcome.d.ts +12 -0
  680. package/dist/lib/doctor/fix/refresh-sync-outcome.js +25 -0
  681. package/dist/lib/doctor/fix/remediation.d.ts +14 -6
  682. package/dist/lib/doctor/fix/remediation.js +49 -9
  683. package/dist/lib/doctor/fixtures/schema.js +1 -3
  684. package/dist/lib/doctor/json-output.d.ts +17 -1
  685. package/dist/lib/doctor/json-output.js +7 -2
  686. package/dist/lib/doctor/platform.d.ts +0 -26
  687. package/dist/lib/doctor/platform.js +5 -5
  688. package/dist/lib/doctor/registry.d.ts +14 -0
  689. package/dist/lib/doctor/registry.js +71 -0
  690. package/dist/lib/doctor/report.js +1 -1
  691. package/dist/lib/doctor/shared.d.ts +8 -0
  692. package/dist/lib/doctor/shared.js +38 -0
  693. package/dist/lib/doctor/stray-gate-entries.d.ts +35 -0
  694. package/dist/lib/doctor/stray-gate-entries.js +83 -0
  695. package/dist/lib/doctor/types.d.ts +5 -0
  696. package/dist/lib/doctor/types.js +20 -0
  697. package/dist/lib/first-sync-next-step.d.ts +34 -0
  698. package/dist/lib/first-sync-next-step.js +179 -0
  699. package/dist/lib/flag-registry-endpoint.d.ts +5 -0
  700. package/dist/lib/flag-registry-endpoint.js +9 -0
  701. package/dist/lib/flag-registry-worker-source.generated.d.ts +2 -0
  702. package/dist/lib/flag-registry-worker-source.generated.js +3 -0
  703. package/dist/lib/flag-registry-worker.js +12 -1
  704. package/dist/lib/flag-registry.d.ts +26 -6
  705. package/dist/lib/flag-registry.js +133 -16
  706. package/dist/lib/flag-snapshot-file.d.ts +20 -0
  707. package/dist/lib/flag-snapshot-file.js +91 -0
  708. package/dist/lib/heartbeat-identity.d.ts +30 -0
  709. package/dist/lib/heartbeat-identity.js +76 -0
  710. package/dist/lib/index-render/companies.d.ts +4 -1
  711. package/dist/lib/index-render/companies.js +66 -3
  712. package/dist/lib/index-render/company-knowledge.js +80 -17
  713. package/dist/lib/index-render/index.d.ts +1 -0
  714. package/dist/lib/index-render/index.js +2 -1
  715. package/dist/lib/index-render/projects.js +82 -5
  716. package/dist/lib/index-render/shared.d.ts +13 -1
  717. package/dist/lib/index-render/shared.js +41 -2
  718. package/dist/lib/lanes/account-home.d.ts +8 -0
  719. package/dist/lib/lanes/account-home.js +10 -0
  720. package/dist/lib/lanes/accounts.d.ts +117 -0
  721. package/dist/lib/lanes/accounts.js +366 -0
  722. package/dist/lib/lanes/admission-host.d.ts +22 -0
  723. package/dist/lib/lanes/admission-host.js +37 -0
  724. package/dist/lib/lanes/admission.d.ts +26 -0
  725. package/dist/lib/lanes/admission.js +210 -0
  726. package/dist/lib/lanes/approval-gate.d.ts +8 -0
  727. package/dist/lib/lanes/approval-gate.js +90 -0
  728. package/dist/lib/lanes/autopilot-metrics.d.ts +99 -0
  729. package/dist/lib/lanes/autopilot-metrics.js +301 -0
  730. package/dist/lib/lanes/autopilot-registry.d.ts +62 -0
  731. package/dist/lib/lanes/autopilot-registry.js +192 -0
  732. package/dist/lib/lanes/autopilot.d.ts +137 -0
  733. package/dist/lib/lanes/autopilot.js +1291 -0
  734. package/dist/lib/lanes/blocker-freshness.d.ts +31 -0
  735. package/dist/lib/lanes/blocker-freshness.js +168 -0
  736. package/dist/lib/lanes/checked-company-path.d.ts +3 -0
  737. package/dist/lib/lanes/checked-company-path.js +39 -0
  738. package/dist/lib/lanes/claude-balance.d.ts +97 -0
  739. package/dist/lib/lanes/claude-balance.js +319 -0
  740. package/dist/lib/lanes/compaction.d.ts +110 -0
  741. package/dist/lib/lanes/compaction.js +293 -0
  742. package/dist/lib/lanes/config.d.ts +94 -0
  743. package/dist/lib/lanes/config.js +606 -0
  744. package/dist/lib/lanes/constants.d.ts +3 -0
  745. package/dist/lib/lanes/constants.js +3 -0
  746. package/dist/lib/lanes/delivery-core.d.ts +15 -0
  747. package/dist/lib/lanes/delivery-core.js +21 -0
  748. package/dist/lib/lanes/delivery.d.ts +180 -0
  749. package/dist/lib/lanes/delivery.js +443 -0
  750. package/dist/lib/lanes/disk-guard.d.ts +65 -0
  751. package/dist/lib/lanes/disk-guard.js +172 -0
  752. package/dist/lib/lanes/dropbox.d.ts +129 -0
  753. package/dist/lib/lanes/dropbox.js +601 -0
  754. package/dist/lib/lanes/effort.d.ts +51 -0
  755. package/dist/lib/lanes/effort.js +113 -0
  756. package/dist/lib/lanes/envelope-repair-dispatch.d.ts +26 -0
  757. package/dist/lib/lanes/envelope-repair-dispatch.js +74 -0
  758. package/dist/lib/lanes/errors.d.ts +39 -0
  759. package/dist/lib/lanes/errors.js +72 -0
  760. package/dist/lib/lanes/flag-keys.d.ts +25 -0
  761. package/dist/lib/lanes/flag-keys.js +25 -0
  762. package/dist/lib/lanes/grants.d.ts +30 -0
  763. package/dist/lib/lanes/grants.js +171 -0
  764. package/dist/lib/lanes/hire-grant-dispatch.d.ts +29 -0
  765. package/dist/lib/lanes/hire-grant-dispatch.js +315 -0
  766. package/dist/lib/lanes/hooks-install.d.ts +82 -0
  767. package/dist/lib/lanes/hooks-install.js +555 -0
  768. package/dist/lib/lanes/host-capacity.d.ts +69 -0
  769. package/dist/lib/lanes/host-capacity.js +254 -0
  770. package/dist/lib/lanes/hq-root.d.ts +19 -0
  771. package/dist/lib/lanes/hq-root.js +28 -0
  772. package/dist/lib/lanes/index.d.ts +76 -0
  773. package/dist/lib/lanes/index.js +42 -0
  774. package/dist/lib/lanes/keep-alive-audit.d.ts +47 -0
  775. package/dist/lib/lanes/keep-alive-audit.js +370 -0
  776. package/dist/lib/lanes/keep-alive.d.ts +68 -0
  777. package/dist/lib/lanes/keep-alive.js +343 -0
  778. package/dist/lib/lanes/kr-freshness.d.ts +76 -0
  779. package/dist/lib/lanes/kr-freshness.js +413 -0
  780. package/dist/lib/lanes/lane-company.d.ts +10 -0
  781. package/dist/lib/lanes/lane-company.js +41 -0
  782. package/dist/lib/lanes/liveness.d.ts +108 -0
  783. package/dist/lib/lanes/liveness.js +396 -0
  784. package/dist/lib/lanes/machine-identity.d.ts +34 -0
  785. package/dist/lib/lanes/machine-identity.js +92 -0
  786. package/dist/lib/lanes/manager-status-gate.d.ts +17 -0
  787. package/dist/lib/lanes/manager-status-gate.js +133 -0
  788. package/dist/lib/lanes/merge-command.d.ts +15 -0
  789. package/dist/lib/lanes/merge-command.js +629 -0
  790. package/dist/lib/lanes/mesh-events.d.ts +127 -0
  791. package/dist/lib/lanes/mesh-events.js +564 -0
  792. package/dist/lib/lanes/message-replay.d.ts +21 -0
  793. package/dist/lib/lanes/message-replay.js +122 -0
  794. package/dist/lib/lanes/models.d.ts +86 -0
  795. package/dist/lib/lanes/models.js +234 -0
  796. package/dist/lib/lanes/monitor.d.ts +48 -0
  797. package/dist/lib/lanes/monitor.js +428 -0
  798. package/dist/lib/lanes/move-account.d.ts +56 -0
  799. package/dist/lib/lanes/move-account.js +193 -0
  800. package/dist/lib/lanes/orphans.d.ts +25 -0
  801. package/dist/lib/lanes/orphans.js +102 -0
  802. package/dist/lib/lanes/outpost-dispatch.d.ts +156 -0
  803. package/dist/lib/lanes/outpost-dispatch.js +293 -0
  804. package/dist/lib/lanes/outpost-hire-cache.d.ts +22 -0
  805. package/dist/lib/lanes/outpost-hire-cache.js +153 -0
  806. package/dist/lib/lanes/outpost-identity.d.ts +33 -0
  807. package/dist/lib/lanes/outpost-identity.js +59 -0
  808. package/dist/lib/lanes/outpost-profile-repin.d.ts +17 -0
  809. package/dist/lib/lanes/outpost-profile-repin.js +84 -0
  810. package/dist/lib/lanes/outpost-pruner-install.d.ts +37 -0
  811. package/dist/lib/lanes/outpost-pruner-install.js +238 -0
  812. package/dist/lib/lanes/outpost-registry-worker-approval.d.ts +18 -0
  813. package/dist/lib/lanes/outpost-registry-worker-approval.js +109 -0
  814. package/dist/lib/lanes/outpost-snapshot-memo.d.ts +6 -0
  815. package/dist/lib/lanes/outpost-snapshot-memo.js +14 -0
  816. package/dist/lib/lanes/outpost-worktree-pruner-flag.d.ts +19 -0
  817. package/dist/lib/lanes/outpost-worktree-pruner-flag.js +86 -0
  818. package/dist/lib/lanes/outpost-worktree-pruner.d.ts +62 -0
  819. package/dist/lib/lanes/outpost-worktree-pruner.js +1201 -0
  820. package/dist/lib/lanes/profile.d.ts +69 -0
  821. package/dist/lib/lanes/profile.js +552 -0
  822. package/dist/lib/lanes/provider-rejection.d.ts +86 -0
  823. package/dist/lib/lanes/provider-rejection.js +286 -0
  824. package/dist/lib/lanes/questions.d.ts +90 -0
  825. package/dist/lib/lanes/questions.js +384 -0
  826. package/dist/lib/lanes/quota.d.ts +134 -0
  827. package/dist/lib/lanes/quota.js +471 -0
  828. package/dist/lib/lanes/reconcile-install.d.ts +90 -0
  829. package/dist/lib/lanes/reconcile-install.js +257 -0
  830. package/dist/lib/lanes/reconcile.d.ts +161 -0
  831. package/dist/lib/lanes/reconcile.js +3343 -0
  832. package/dist/lib/lanes/registry-flag.d.ts +35 -0
  833. package/dist/lib/lanes/registry-flag.js +164 -0
  834. package/dist/lib/lanes/registry-persona.d.ts +20 -0
  835. package/dist/lib/lanes/registry-persona.js +329 -0
  836. package/dist/lib/lanes/registry.d.ts +122 -0
  837. package/dist/lib/lanes/registry.js +570 -0
  838. package/dist/lib/lanes/reviews.d.ts +38 -0
  839. package/dist/lib/lanes/reviews.js +395 -0
  840. package/dist/lib/lanes/runaway-tool-guard.d.ts +38 -0
  841. package/dist/lib/lanes/runaway-tool-guard.js +284 -0
  842. package/dist/lib/lanes/session-relink.d.ts +25 -0
  843. package/dist/lib/lanes/session-relink.js +216 -0
  844. package/dist/lib/lanes/spawn.d.ts +355 -0
  845. package/dist/lib/lanes/spawn.js +2668 -0
  846. package/dist/lib/lanes/ssm-command-context.d.ts +12 -0
  847. package/dist/lib/lanes/ssm-command-context.js +52 -0
  848. package/dist/lib/lanes/store.d.ts +91 -0
  849. package/dist/lib/lanes/store.js +1822 -0
  850. package/dist/lib/lanes/stories.d.ts +23 -0
  851. package/dist/lib/lanes/stories.js +92 -0
  852. package/dist/lib/lanes/story-ledger.d.ts +80 -0
  853. package/dist/lib/lanes/story-ledger.js +815 -0
  854. package/dist/lib/lanes/story-switch.d.ts +21 -0
  855. package/dist/lib/lanes/story-switch.js +75 -0
  856. package/dist/lib/lanes/text-scan.d.ts +11 -0
  857. package/dist/lib/lanes/text-scan.js +103 -0
  858. package/dist/lib/lanes/throttle.d.ts +116 -0
  859. package/dist/lib/lanes/throttle.js +437 -0
  860. package/dist/lib/lanes/timestamp.d.ts +3 -0
  861. package/dist/lib/lanes/timestamp.js +26 -0
  862. package/dist/lib/lanes/tracker-checks.d.ts +77 -0
  863. package/dist/lib/lanes/tracker-checks.js +134 -0
  864. package/dist/lib/lanes/tracker-report-state.d.ts +10 -0
  865. package/dist/lib/lanes/tracker-report-state.js +124 -0
  866. package/dist/lib/lanes/tracker-report.d.ts +203 -0
  867. package/dist/lib/lanes/tracker-report.js +522 -0
  868. package/dist/lib/lanes/tracker-store.d.ts +18 -0
  869. package/dist/lib/lanes/tracker-store.js +106 -0
  870. package/dist/lib/lanes/types.d.ts +1030 -0
  871. package/dist/lib/lanes/types.js +418 -0
  872. package/dist/lib/lanes/wait.d.ts +39 -0
  873. package/dist/lib/lanes/wait.js +159 -0
  874. package/dist/lib/lanes/watch.d.ts +39 -0
  875. package/dist/lib/lanes/watch.js +249 -0
  876. package/dist/lib/lanes/watcher-main.d.ts +11 -0
  877. package/dist/lib/lanes/watcher-main.js +108 -0
  878. package/dist/lib/lanes/watcher.d.ts +287 -0
  879. package/dist/lib/lanes/watcher.js +1972 -0
  880. package/dist/lib/mesh/api.d.ts +103 -10
  881. package/dist/lib/mesh/api.js +334 -64
  882. package/dist/lib/mesh/client.d.ts +3 -2
  883. package/dist/lib/mesh/client.js +26 -7
  884. package/dist/lib/mesh/denial-codes.d.ts +5 -0
  885. package/dist/lib/mesh/denial-codes.js +14 -0
  886. package/dist/lib/mesh/live/backfill-held.d.ts +67 -16
  887. package/dist/lib/mesh/live/backfill-held.js +415 -61
  888. package/dist/lib/mesh/live/backoff.d.ts +2 -2
  889. package/dist/lib/mesh/live/backoff.js +16 -3
  890. package/dist/lib/mesh/live/daemon/board-refresh.d.ts +7 -1
  891. package/dist/lib/mesh/live/daemon/board-refresh.js +78 -30
  892. package/dist/lib/mesh/live/daemon/config.d.ts +36 -0
  893. package/dist/lib/mesh/live/daemon/config.js +120 -0
  894. package/dist/lib/mesh/live/daemon/credentials.d.ts +64 -10
  895. package/dist/lib/mesh/live/daemon/credentials.js +270 -20
  896. package/dist/lib/mesh/live/daemon/doctor.d.ts +53 -0
  897. package/dist/lib/mesh/live/daemon/doctor.js +190 -6
  898. package/dist/lib/mesh/live/daemon/index.d.ts +13 -10
  899. package/dist/lib/mesh/live/daemon/index.js +7 -6
  900. package/dist/lib/mesh/live/daemon/install.d.ts +255 -1
  901. package/dist/lib/mesh/live/daemon/install.js +811 -13
  902. package/dist/lib/mesh/live/daemon/legacy-listen.d.ts +43 -0
  903. package/dist/lib/mesh/live/daemon/legacy-listen.js +89 -0
  904. package/dist/lib/mesh/live/daemon/live-cache.d.ts +26 -0
  905. package/dist/lib/mesh/live/daemon/live-cache.js +116 -0
  906. package/dist/lib/mesh/live/daemon/mqtt-events.d.ts +7 -0
  907. package/dist/lib/mesh/live/daemon/mqtt-events.js +2 -0
  908. package/dist/lib/mesh/live/daemon/mqtt-events.test-d.d.ts +2 -0
  909. package/dist/lib/mesh/live/daemon/mqtt-events.test-d.js +10 -0
  910. package/dist/lib/mesh/live/daemon/paths.d.ts +2 -0
  911. package/dist/lib/mesh/live/daemon/paths.js +2 -0
  912. package/dist/lib/mesh/live/daemon/presence.d.ts +24 -5
  913. package/dist/lib/mesh/live/daemon/presence.js +79 -10
  914. package/dist/lib/mesh/live/daemon/run.d.ts +48 -2
  915. package/dist/lib/mesh/live/daemon/run.js +485 -33
  916. package/dist/lib/mesh/live/daemon/state.d.ts +19 -2
  917. package/dist/lib/mesh/live/daemon/state.js +34 -2
  918. package/dist/lib/mesh/live/daemon/transcript-watch.d.ts +45 -9
  919. package/dist/lib/mesh/live/daemon/transcript-watch.js +227 -31
  920. package/dist/lib/mesh/live/daemon/version-drift.d.ts +5 -0
  921. package/dist/lib/mesh/live/daemon/version-drift.js +47 -0
  922. package/dist/lib/mesh/live/daemon/work-subscribe.d.ts +32 -0
  923. package/dist/lib/mesh/live/daemon/work-subscribe.js +262 -0
  924. package/dist/lib/mesh/live/emit-client.d.ts +8 -0
  925. package/dist/lib/mesh/live/emit-client.js +23 -8
  926. package/dist/lib/mesh/live/emit-evidence.d.ts +19 -0
  927. package/dist/lib/mesh/live/emit-evidence.js +20 -2
  928. package/dist/lib/mesh/live/emit.d.ts +9 -0
  929. package/dist/lib/mesh/live/emit.js +28 -2
  930. package/dist/lib/mesh/live/enqueue.d.ts +5 -0
  931. package/dist/lib/mesh/live/enqueue.js +19 -0
  932. package/dist/lib/mesh/live/flush.d.ts +17 -5
  933. package/dist/lib/mesh/live/flush.js +391 -38
  934. package/dist/lib/mesh/live/format-spool-line.d.ts +5 -2
  935. package/dist/lib/mesh/live/format-spool-line.js +10 -0
  936. package/dist/lib/mesh/live/paths.d.ts +2 -0
  937. package/dist/lib/mesh/live/paths.js +4 -0
  938. package/dist/lib/mesh/live/report-summary.d.ts +45 -0
  939. package/dist/lib/mesh/live/report-summary.js +234 -0
  940. package/dist/lib/mesh/live/session-event.schema.json +24 -1
  941. package/dist/lib/mesh/live/session-events-client.d.ts +2 -0
  942. package/dist/lib/mesh/live/session-events-client.js +26 -0
  943. package/dist/lib/mesh/live/session-seq.d.ts +4 -0
  944. package/dist/lib/mesh/live/session-seq.js +33 -0
  945. package/dist/lib/mesh/live/spool.d.ts +19 -0
  946. package/dist/lib/mesh/live/spool.js +269 -3
  947. package/dist/lib/mesh/live/validate-session-event.d.ts +1 -1
  948. package/dist/lib/mesh/live/validate-session-event.js +1 -1
  949. package/dist/lib/mesh/project-board.d.ts +65 -0
  950. package/dist/lib/mesh/project-board.js +181 -0
  951. package/dist/lib/mesh/story-status.d.ts +22 -0
  952. package/dist/lib/mesh/story-status.js +49 -0
  953. package/dist/lib/monitor.d.ts +149 -0
  954. package/dist/lib/monitor.js +519 -0
  955. package/dist/lib/node-binary.d.ts +50 -0
  956. package/dist/lib/node-binary.js +133 -0
  957. package/dist/lib/notify-recipient.d.ts +7 -0
  958. package/dist/lib/notify-recipient.js +11 -0
  959. package/dist/lib/onboarding/checkpoint.d.ts +13 -0
  960. package/dist/lib/onboarding/checkpoint.js +44 -0
  961. package/dist/lib/onboarding/cli/onboard.d.ts +53 -0
  962. package/dist/lib/onboarding/cli/onboard.js +135 -0
  963. package/dist/lib/onboarding/cli/prompts.d.ts +28 -0
  964. package/dist/lib/onboarding/cli/prompts.js +83 -0
  965. package/dist/lib/onboarding/errors.d.ts +34 -0
  966. package/dist/lib/onboarding/errors.js +59 -0
  967. package/dist/lib/onboarding/index.d.ts +13 -0
  968. package/dist/lib/onboarding/index.js +13 -0
  969. package/dist/lib/onboarding/orchestrator.d.ts +47 -0
  970. package/dist/lib/onboarding/orchestrator.js +569 -0
  971. package/dist/lib/onboarding/types.d.ts +79 -0
  972. package/dist/lib/onboarding/types.js +8 -0
  973. package/dist/lib/plan-limit-nag.d.ts +102 -6
  974. package/dist/lib/plan-limit-nag.js +348 -43
  975. package/dist/lib/policy-validator.d.ts +7 -0
  976. package/dist/lib/policy-validator.js +187 -0
  977. package/dist/lib/process-flag-company-context.d.ts +8 -0
  978. package/dist/lib/process-flag-company-context.js +67 -0
  979. package/dist/lib/report-publish.d.ts +175 -0
  980. package/dist/lib/report-publish.js +421 -0
  981. package/dist/lib/report-run.d.ts +62 -0
  982. package/dist/lib/report-run.js +123 -0
  983. package/dist/lib/report-snapshot.d.ts +12 -0
  984. package/dist/lib/report-snapshot.js +135 -0
  985. package/dist/lib/report-templates.d.ts +9 -0
  986. package/dist/lib/report-templates.js +21 -0
  987. package/dist/lib/scaffold-cli-floor.d.ts +8 -0
  988. package/dist/lib/scaffold-cli-floor.js +50 -0
  989. package/dist/lib/scan-packages/index.d.ts +2 -0
  990. package/dist/lib/scan-packages/index.js +168 -6
  991. package/dist/lib/search-index/background.d.ts +8 -1
  992. package/dist/lib/search-index/background.js +55 -200
  993. package/dist/lib/search-index/collection-path-repair-flag.d.ts +4 -0
  994. package/dist/lib/search-index/collection-path-repair-flag.js +7 -0
  995. package/dist/lib/search-index/embed-lock.d.ts +34 -0
  996. package/dist/lib/search-index/embed-lock.js +295 -0
  997. package/dist/lib/search-index/index.d.ts +12 -0
  998. package/dist/lib/search-index/index.js +153 -7
  999. package/dist/lib/search-index/load-gate.d.ts +57 -0
  1000. package/dist/lib/search-index/load-gate.js +270 -0
  1001. package/dist/lib/search-index/max-doc-bytes.d.ts +219 -0
  1002. package/dist/lib/search-index/max-doc-bytes.js +463 -0
  1003. package/dist/lib/search-index/qmd-exit-diagnostics.d.ts +5 -0
  1004. package/dist/lib/search-index/qmd-exit-diagnostics.js +40 -0
  1005. package/dist/lib/search-index/reindex-single-flight-flag.d.ts +5 -0
  1006. package/dist/lib/search-index/reindex-single-flight-flag.js +8 -0
  1007. package/dist/lib/service-manager/index.d.ts +42 -0
  1008. package/dist/lib/service-manager/index.js +105 -0
  1009. package/dist/lib/service-manager/launchd.d.ts +81 -0
  1010. package/dist/lib/service-manager/launchd.js +212 -0
  1011. package/dist/lib/service-manager/systemd.d.ts +19 -0
  1012. package/dist/lib/service-manager/systemd.js +72 -0
  1013. package/dist/lib/service-manager/types.d.ts +34 -0
  1014. package/dist/lib/service-manager/types.js +26 -0
  1015. package/dist/lib/test-utils/isolated-flag-company-context.d.ts +3 -0
  1016. package/dist/lib/test-utils/isolated-flag-company-context.js +18 -0
  1017. package/dist/lib/work-context/bind-best.d.ts +66 -0
  1018. package/dist/lib/work-context/bind-best.js +344 -0
  1019. package/dist/lib/work-context/bind-calling-session.d.ts +26 -0
  1020. package/dist/lib/work-context/bind-calling-session.js +63 -0
  1021. package/dist/lib/work-context/company-rebind.d.ts +23 -0
  1022. package/dist/lib/work-context/company-rebind.js +59 -0
  1023. package/dist/lib/work-context/company.d.ts +22 -20
  1024. package/dist/lib/work-context/company.js +124 -40
  1025. package/dist/lib/work-context/config.d.ts +58 -11
  1026. package/dist/lib/work-context/config.js +334 -83
  1027. package/dist/lib/work-context/contract.d.ts +13 -0
  1028. package/dist/lib/work-context/contract.schema.json +3 -1
  1029. package/dist/lib/work-context/default-company.d.ts +43 -0
  1030. package/dist/lib/work-context/default-company.js +83 -0
  1031. package/dist/lib/work-context/outbox-quarantine-status-flag.d.ts +4 -0
  1032. package/dist/lib/work-context/outbox-quarantine-status-flag.js +7 -0
  1033. package/dist/lib/work-context/outbox.d.ts +27 -5
  1034. package/dist/lib/work-context/outbox.js +135 -6
  1035. package/dist/lib/work-context/prd-sync.d.ts +56 -0
  1036. package/dist/lib/work-context/prd-sync.js +197 -0
  1037. package/dist/lib/work-context/preflight-contract.d.ts +28 -0
  1038. package/dist/lib/work-context/preflight-contract.js +85 -0
  1039. package/dist/lib/work-context/prompt-rebind.d.ts +25 -0
  1040. package/dist/lib/work-context/prompt-rebind.js +85 -0
  1041. package/dist/lib/work-context/reconcile.d.ts +15 -0
  1042. package/dist/lib/work-context/reconcile.js +405 -29
  1043. package/dist/lib/work-context/state.d.ts +93 -10
  1044. package/dist/lib/work-context/state.js +342 -29
  1045. package/dist/lib/work-context/windows-acl.d.ts +123 -0
  1046. package/dist/lib/work-context/windows-acl.js +425 -0
  1047. package/dist/lib/workers-registry/index.js +62 -8
  1048. package/dist/lib/workers-registry/read.d.ts +15 -0
  1049. package/dist/lib/workers-registry/read.js +17 -0
  1050. package/dist/main.d.ts +32 -0
  1051. package/dist/main.js +273 -73
  1052. package/dist/native-fast-route.d.ts +7 -0
  1053. package/dist/native-fast-route.js +45 -0
  1054. package/dist/node-network-compat-core.d.ts +12 -0
  1055. package/dist/node-network-compat-core.js +41 -0
  1056. package/dist/node-network-compat-fast.d.ts +7 -0
  1057. package/dist/node-network-compat-fast.js +23 -0
  1058. package/dist/node-network-compat.d.ts +2 -30
  1059. package/dist/node-network-compat.js +4 -51
  1060. package/dist/node-preflight.d.ts +7 -1
  1061. package/dist/node-preflight.js +5 -5
  1062. package/dist/register-all.d.ts +4 -29
  1063. package/dist/register-all.js +4 -233
  1064. package/dist/run/discover-schemas.d.ts +2 -1
  1065. package/dist/run/env-graph-guard.d.ts +2 -2
  1066. package/dist/run/env-graph-guard.js +5 -2
  1067. package/dist/run/hq-plugin.d.ts +4 -0
  1068. package/dist/run/hq-plugin.js +36 -8
  1069. package/dist/secrets-env-fast-path.d.ts +5 -0
  1070. package/dist/secrets-env-fast-path.js +16 -0
  1071. package/dist/secrets-env-fast-route.d.ts +18 -0
  1072. package/dist/secrets-env-fast-route.js +54 -0
  1073. package/dist/sentry-before-send.js +80 -0
  1074. package/dist/sentry.d.ts +16 -4
  1075. package/dist/sentry.js +179 -18
  1076. package/dist/startup-registration.d.ts +26 -2
  1077. package/dist/startup-registration.js +116 -15
  1078. package/dist/utils/checkpoint-stamp-write-error.d.ts +28 -0
  1079. package/dist/utils/checkpoint-stamp-write-error.js +99 -0
  1080. package/dist/utils/cli-network-lifecycle.d.ts +4 -0
  1081. package/dist/utils/cli-network-lifecycle.js +11 -0
  1082. package/dist/utils/cli-telemetry.d.ts +75 -1
  1083. package/dist/utils/cli-telemetry.js +433 -7
  1084. package/dist/utils/client-health.d.ts +0 -4
  1085. package/dist/utils/client-health.js +2 -2
  1086. package/dist/utils/cognito-refresh-sentry.d.ts +3 -0
  1087. package/dist/utils/cognito-refresh-sentry.js +49 -0
  1088. package/dist/utils/cognito-session.d.ts +71 -0
  1089. package/dist/utils/cognito-session.js +481 -27
  1090. package/dist/utils/console-origin.d.ts +9 -0
  1091. package/dist/utils/console-origin.js +28 -0
  1092. package/dist/utils/contribution-table.d.ts +1 -1
  1093. package/dist/utils/core-eval-trigger.d.ts +4 -0
  1094. package/dist/utils/core-eval-trigger.js +88 -0
  1095. package/dist/utils/environmental-error.d.ts +18 -0
  1096. package/dist/utils/environmental-error.js +240 -7
  1097. package/dist/utils/exclusive-lock.d.ts +32 -0
  1098. package/dist/utils/exclusive-lock.js +75 -0
  1099. package/dist/utils/expected-cli-error.d.ts +2 -0
  1100. package/dist/utils/expected-cli-error.js +4 -0
  1101. package/dist/utils/fast-stream-errors.d.ts +12 -0
  1102. package/dist/utils/fast-stream-errors.js +18 -0
  1103. package/dist/utils/feedback-diagnostics.d.ts +2 -1
  1104. package/dist/utils/feedback-log-bundle.d.ts +51 -26
  1105. package/dist/utils/feedback-log-bundle.js +211 -31
  1106. package/dist/utils/feedback-logs.d.ts +18 -47
  1107. package/dist/utils/feedback-logs.js +50 -21
  1108. package/dist/utils/feedback-screenshots.d.ts +0 -1
  1109. package/dist/utils/feedback-screenshots.js +1 -1
  1110. package/dist/utils/files-browse-acl.d.ts +5 -0
  1111. package/dist/utils/files-browse-acl.js +11 -0
  1112. package/dist/utils/hq-core-yaml.d.ts +10 -0
  1113. package/dist/utils/hq-core-yaml.js +40 -0
  1114. package/dist/utils/hq-root-resolver.d.ts +13 -0
  1115. package/dist/utils/hq-root-resolver.js +103 -0
  1116. package/dist/utils/hq-roots.d.ts +25 -2
  1117. package/dist/utils/hq-roots.js +67 -7
  1118. package/dist/utils/incomplete-install-error.d.ts +87 -19
  1119. package/dist/utils/incomplete-install-error.js +319 -68
  1120. package/dist/utils/install-tree-torn.d.ts +260 -24
  1121. package/dist/utils/install-tree-torn.js +998 -51
  1122. package/dist/utils/large-file-guard.d.ts +0 -10
  1123. package/dist/utils/large-file-guard.js +1 -1
  1124. package/dist/utils/local-files-overview.d.ts +4 -8
  1125. package/dist/utils/local-files-overview.js +48 -7
  1126. package/dist/utils/login-provider.d.ts +7 -0
  1127. package/dist/utils/login-provider.js +34 -0
  1128. package/dist/utils/pack-contributions.d.ts +2 -14
  1129. package/dist/utils/pack-contributions.js +7 -44
  1130. package/dist/utils/package-root-diagnostics.d.ts +1 -1
  1131. package/dist/utils/people.d.ts +7 -11
  1132. package/dist/utils/people.js +5 -20
  1133. package/dist/utils/plan-gate-error.d.ts +52 -10
  1134. package/dist/utils/plan-gate-error.js +364 -41
  1135. package/dist/utils/qmd-model-download-error.d.ts +0 -8
  1136. package/dist/utils/qmd-model-download-error.js +1 -1
  1137. package/dist/utils/qmd-query-document-error.d.ts +0 -6
  1138. package/dist/utils/qmd-query-document-error.js +1 -1
  1139. package/dist/utils/redact-error-text.d.ts +0 -2
  1140. package/dist/utils/redact-error-text.js +3 -2
  1141. package/dist/utils/redact-url.d.ts +14 -0
  1142. package/dist/utils/redact-url.js +218 -0
  1143. package/dist/utils/run-bundled-script.d.ts +6 -0
  1144. package/dist/utils/run-bundled-script.js +117 -4
  1145. package/dist/utils/sandbox-runner-client.d.ts +2 -1
  1146. package/dist/utils/scaffold-fast-import-guard.d.ts +2 -0
  1147. package/dist/utils/scaffold-fast-import-guard.js +40 -0
  1148. package/dist/utils/scaffold-packlist-guard.d.ts +7 -0
  1149. package/dist/utils/scaffold-packlist-guard.js +23 -0
  1150. package/dist/utils/scaffold-sibling-references.d.ts +22 -0
  1151. package/dist/utils/scaffold-sibling-references.js +156 -0
  1152. package/dist/utils/secret-load-availability.d.ts +8 -0
  1153. package/dist/utils/secret-load-availability.js +54 -0
  1154. package/dist/utils/secrets-cache.d.ts +7 -3
  1155. package/dist/utils/secrets-cache.js +162 -14
  1156. package/dist/utils/self-update.d.ts +34 -1
  1157. package/dist/utils/self-update.js +660 -42
  1158. package/dist/utils/sentry-fingerprint.d.ts +23 -1
  1159. package/dist/utils/sentry-fingerprint.js +223 -31
  1160. package/dist/utils/staged-install.d.ts +34 -0
  1161. package/dist/utils/staged-install.js +346 -0
  1162. package/dist/utils/staged-npm-install.d.ts +16 -0
  1163. package/dist/utils/staged-npm-install.js +264 -0
  1164. package/dist/utils/sync-log-sources.d.ts +15 -0
  1165. package/dist/utils/sync-log-sources.js +36 -0
  1166. package/dist/utils/table-width.d.ts +7 -0
  1167. package/dist/utils/table-width.js +15 -0
  1168. package/dist/utils/team-upgrade.d.ts +1 -1
  1169. package/dist/utils/team-upgrade.js +4 -3
  1170. package/dist/utils/update-command-supervisor.cjs +247 -0
  1171. package/dist/utils/upload-author.d.ts +15 -0
  1172. package/dist/utils/upload-author.js +39 -0
  1173. package/dist/utils/vault-api.d.ts +21 -1
  1174. package/dist/utils/vault-api.js +251 -84
  1175. package/dist/utils/version-check.d.ts +11 -1
  1176. package/dist/utils/version-check.js +32 -3
  1177. package/dist/utils/version-gate.d.ts +101 -17
  1178. package/dist/utils/version-gate.js +645 -70
  1179. package/dist/utils/version-report.d.ts +27 -0
  1180. package/dist/utils/version-report.js +105 -0
  1181. package/dist/utils/windows-spawn.d.ts +6 -0
  1182. package/dist/utils/windows-spawn.js +37 -0
  1183. package/dist/version-request.d.ts +14 -0
  1184. package/dist/version-request.js +36 -0
  1185. package/package.json +20 -8
  1186. package/scripts/mesh-daemon-if-stale.mjs +20 -0
  1187. package/templates/reports/blank.md +3 -0
  1188. package/templates/reports/daily-digest.md +11 -0
  1189. package/templates/runbooks/update-report.md +21 -0
  1190. package/dist/commands/scaffold-fast.d.ts +0 -41
  1191. package/dist/commands/scaffold-fast.js +0 -57
  1192. package/dist/lib/work-context/index.d.ts +0 -25
  1193. package/dist/lib/work-context/index.js +0 -21
@@ -5,37 +5,57 @@
5
5
  * require hq-pack-work-mesh on disk and does not start MQTT listen.
6
6
  * Distinct from `hq doctor` (hook guardrails).
7
7
  */
8
+ import { resolve as resolvePath } from "node:path";
8
9
  import * as os from "node:os";
10
+ import { readFileSync } from "node:fs";
11
+ import { findHqRoot } from "../utils/manifest.js";
12
+ import { CLI_VERSION } from "../cli-version.js";
9
13
  import chalk from "chalk";
10
- import { loadCachedTokens, isMachineIdentity } from "../utils/cognito-session.js";
14
+ import { ensureCognitoToken, isExpiring, isMachineIdentity, loadCachedTokens, } from "../utils/cognito-session.js";
11
15
  import * as readline from "node:readline/promises";
12
- import { STORY_STATUSES, appendThreadEvent, callerLabelFromToken, ensureProjectThread, eventPayload, listActiveMembershipCompanies, listActiveThreads, patchStoryStatus, resolveActiveMembershipCompany, resolveMeshPrincipalUid, warmMeshConversationCache, } from "../lib/mesh/api.js";
16
+ import { STORY_STATUSES, appendThreadEvent, ensureProjectThread, eventPayload, getProjectView, listActiveMembershipCompanies, listActiveThreads, patchStory, putProjectView, registerMeshProject, resolveActiveMembershipCompany, resolveMeshPrincipalUid, warmMeshConversationCache, } from "../lib/mesh/api.js";
17
+ import { closeSupersededProjectThread, ensureMissingBoardStories, ensureProjectBoard, boardStoryStatus, formatStoryStatusChanges, mergeProjectStories, prdSyncEventsThatChangeBoard, } from "../lib/mesh/project-board.js";
18
+ import { mapSourceStoryStatus } from "../lib/mesh/story-status.js";
19
+ import { buildPreflightFixtures } from "../lib/work-context/preflight-contract.js";
13
20
  import { createCandidatesFetcher, createMigratePoster, createOrganizePoster, createWorkSessionDeliverer, fetchCompanyLive, formatCompanyLiveTable, openMeshTransport, probeMigrationCapabilityForMemberships, requireToken, } from "../lib/mesh/client.js";
14
- import { clearDefaultCompany, getDefaultCompany, readDeviceConfig, recordMigrationCapabilitySnapshot, setDefaultCompany, } from "../lib/work-context/config.js";
15
- import { DefaultCompanyLockedError, DefaultCompanyUnavailableError, } from "../lib/work-context/errors.js";
21
+ import { clearDefaultCompany, isDefaultCompanyDisabled, readDeviceConfig, recordMigrationCapabilitySnapshot, setRepairHeldWithDefault, setDefaultCompany, } from "../lib/work-context/config.js";
22
+ import { ensureDefaultCompany } from "../lib/work-context/default-company.js";
23
+ import { DefaultCompanyUnavailableError, } from "../lib/work-context/errors.js";
16
24
  import { isValidSessionId } from "../lib/mesh/live/session-identity.js";
17
25
  import { CLI_KIND_TO_SCHEMA, resolveEnqueueSessionId, } from "../lib/mesh/live/index.js";
18
26
  import { flushSessionEvents } from "../lib/mesh/live/flush.js";
19
27
  import { backfillHeldSessions } from "../lib/mesh/live/backfill-held.js";
20
28
  import { createSessionEventsPoster, resolveVaultApiBase, } from "../lib/mesh/live/session-events-client.js";
21
- import { buildEmitEvidence } from "../lib/mesh/live/emit-evidence.js";
29
+ const ONLINE_MEMBERSHIP_VALIDATION_TIMEOUT_MS = 5_000;
30
+ // Leave 500 ms of headroom inside SessionStart's 2 s process-group limit.
31
+ const OFFLINE_MEMBERSHIP_VALIDATION_TIMEOUT_MS = 1_500;
32
+ import { buildEmitEvidence, machineEmitDisposition } from "../lib/mesh/live/emit-evidence.js";
33
+ import { appendHeldLine } from "../lib/mesh/live/spool.js";
22
34
  import { createEmitPoster, buildMeshEmitEvent } from "../lib/mesh/live/emit-client.js";
23
- import { emitEvents } from "../lib/mesh/live/emit.js";
35
+ import { enrichSessionEndEvent } from "../lib/mesh/live/report-summary.js";
36
+ import { emitEvents, formatEmitRejectionLines } from "../lib/mesh/live/emit.js";
24
37
  import { readEmitRetry, writeEmitRetry } from "../lib/mesh/live/emit-retry.js";
25
38
  import { generateUlid } from "../lib/mesh/live/ulid.js";
26
39
  import { readLegacyBacklog } from "../lib/mesh/live/emit-replay.js";
27
40
  import { resolveMeshEmitMode, writeMeshConfigMode, } from "../lib/mesh/live/daemon/mode.js";
28
41
  import { workMeshRoot } from "../lib/mesh/live/paths.js";
29
- import { buildInstallPaths, collectDaemonDoctor, daemonServiceStatus, detectPlatform, formatDaemonDoctor, installDaemonService, readDaemonState, runMeshDaemon, uninstallDaemonService, daemonDir, } from "../lib/mesh/live/daemon/index.js";
42
+ import { buildInstallPaths, collectDaemonDoctor, daemonServiceIsLoaded, daemonServiceStatus, findAncestorHqRoot, resolveInstallHqRoot, detectPlatform, formatCliIdentityLines, formatDaemonDoctor, installDaemonIfStale, installDaemonService, readDaemonState, resolveAbsoluteNodeBinary, resolveRunningCliEntry, runMeshDaemon, uninstallDaemonService, } from "../lib/mesh/live/daemon/index.js";
43
+ import { defaultRunCommand } from "../lib/service-manager/launchd.js";
30
44
  import { workContextRoot } from "../lib/work-context/paths.js";
31
45
  import { formatMigrateConfirmation, submitSessionMigration, } from "../lib/work-context/migrate.js";
32
46
  import { formatOrganizeList, prepareOrganizeDecision, settleOrganizeAskWithoutBind, submitOrganizeDecision, } from "../lib/work-context/organize.js";
33
- import { readSessionState } from "../lib/work-context/state.js";
47
+ import { applyOperatorProjectBinding, readSessionState, updateSessionState, } from "../lib/work-context/state.js";
48
+ import { findLocalPrd, listNeedsProjectSessions } from "../lib/work-context/bind-best.js";
49
+ import { bindCallingSession, formatSessionBoundLine } from "../lib/work-context/bind-calling-session.js";
50
+ import { rebindNeedsProjectOnPrompt } from "../lib/work-context/prompt-rebind.js";
51
+ import { planPrdSync, rebindSessionToProject } from "../lib/work-context/prd-sync.js";
52
+ import { reserveSessionSeq } from "../lib/mesh/live/session-seq.js";
34
53
  import { loadObservationFromFile, markUntracked, parseObservationJson, reconcileObservation, } from "../lib/work-context/reconcile.js";
35
54
  import { resolveCompany } from "../lib/work-context/company.js";
36
55
  import { deriveRemoteOwnerSlug, deriveRepoIdentityKey, } from "../lib/work-context/repo-remote.js";
37
56
  import { promptRepoCompany, } from "../lib/work-context/repo-prompt.js";
38
57
  import { requeueQuarantinedOutbox } from "../lib/work-context/outbox.js";
58
+ import { handOffInstallHere } from "../lib/daemon/handoff.js";
39
59
  export function formatCheckLines(threads, company, projectId) {
40
60
  if (threads.length === 0) {
41
61
  return ["Work mesh: no active project threads found."];
@@ -43,14 +63,22 @@ export function formatCheckLines(threads, company, projectId) {
43
63
  const scope = projectId
44
64
  ? `${company.companySlug || company.companyUid}/${projectId}`
45
65
  : company.companySlug || company.companyUid;
46
- const lines = [`Work mesh: ${threads.length} active thread(s) for ${scope}`];
66
+ const lines = [`Work mesh: ${threads.length} thread(s) for ${scope}`];
47
67
  for (const thread of threads.slice(0, 8)) {
48
68
  const owner = thread.ownerUid ? ` owner=${thread.ownerUid}` : "";
49
69
  const summary = thread.progressSummary ||
50
70
  thread.sourceSignalSummary ||
51
71
  thread.blockedReason ||
52
72
  "";
53
- lines.push(`- ${thread.threadStatus ?? "unknown"} ${thread.threadId ?? "?"}${owner}${summary ? `: ${summary}` : ""}`);
73
+ const lane = thread.kind === "lane" ? thread.lane : undefined;
74
+ const laneDetails = lane
75
+ ? ` lane=${lane.laneId} laneStatus=${thread.laneStatus ?? "unknown"}` +
76
+ ` story=${lane.storyId ?? "unknown"} profile=${lane.workerProfile ?? "unknown"}` +
77
+ ` model=${lane.model ?? "unknown"} account=${lane.account ?? "unknown"}` +
78
+ `${lane.parentLaneId ? ` parent=${lane.parentLaneId}` : ""}`
79
+ : "";
80
+ const machine = thread.senderMachineUid ? ` machine=${thread.senderMachineUid}` : "";
81
+ lines.push(`- ${thread.threadStatus ?? "unknown"} ${thread.threadId ?? "?"}${owner}${machine}${laneDetails}${summary ? `: ${summary}` : ""}`);
54
82
  }
55
83
  return lines;
56
84
  }
@@ -85,12 +113,20 @@ async function runCheck(opts) {
85
113
  async function runEvent(verb, opts) {
86
114
  const { token, company } = await withCompany(opts);
87
115
  const projectId = requireProject(opts);
116
+ const eventKind = verb === "start" ? "claim" : verb;
117
+ let claimant = "";
118
+ if (eventKind === "claim") {
119
+ const resolvedClaimant = await resolveMeshPrincipalUid(token, loadCachedTokens());
120
+ if (!resolvedClaimant) {
121
+ fail("Could not resolve the authenticated claimant. Sign in again and retry `hq mesh start`.");
122
+ }
123
+ claimant = resolvedClaimant;
124
+ }
88
125
  const ensured = await ensureProjectThread(token, company, projectId, {
89
126
  threadId: opts.threadId,
90
127
  summary: opts.summary,
91
128
  });
92
- const eventKind = verb === "start" ? "claim" : verb;
93
- const event = await appendThreadEvent(token, company.companyUid, ensured.threadId, eventKind, eventPayload(eventKind, opts, callerLabelFromToken(token)));
129
+ const event = await appendThreadEvent(token, company.companyUid, ensured.threadId, eventKind, eventPayload(eventKind, opts, claimant));
94
130
  if (opts.json) {
95
131
  console.log(JSON.stringify({
96
132
  ok: true,
@@ -109,33 +145,705 @@ async function runEvent(verb, opts) {
109
145
  async function runStory(opts) {
110
146
  const storyId = opts.story?.trim();
111
147
  const status = opts.status?.trim();
112
- if (!storyId || !status || !STORY_STATUSES.has(status)) {
113
- fail("story requires --story <id> and --status queued|in_progress|review|done");
148
+ const assignee = opts.assignee?.trim();
149
+ if (!storyId) {
150
+ fail("story requires --story <id>");
151
+ }
152
+ if (!status && !assignee) {
153
+ fail("story requires --status queued|in_progress|review|done or --assignee <uid|me|none>");
154
+ }
155
+ if (status && !STORY_STATUSES.has(status)) {
156
+ fail("story --status must be queued|in_progress|review|done");
114
157
  }
115
158
  const { token, company } = await withCompany(opts);
116
159
  const projectId = requireProject(opts);
117
- const patched = await patchStoryStatus(token, company.companyUid, projectId, storyId, status);
160
+ let assigneeUid;
161
+ let clearAssignee = false;
162
+ if (assignee === "none") {
163
+ clearAssignee = true;
164
+ }
165
+ else if (assignee === "me") {
166
+ const resolved = await resolveMeshPrincipalUid(token, loadCachedTokens());
167
+ if (!resolved || resolved === "session") {
168
+ fail("`--assignee me` needs the signed-in person or agent. The synthetic session identity cannot be assigned. Sign in again and retry `hq mesh story`.");
169
+ }
170
+ assigneeUid = resolved;
171
+ }
172
+ else if (assignee) {
173
+ if (!/^(prs|agt)_/.test(assignee)) {
174
+ fail("`--assignee` must be a person or agent uid, `me`, or `none`.");
175
+ }
176
+ assigneeUid = assignee;
177
+ }
178
+ const patched = await patchStory(token, company.companyUid, projectId, storyId, {
179
+ ...(status ? { status } : {}),
180
+ ...(assigneeUid ? { assigneeUid } : {}),
181
+ ...(clearAssignee ? { clearAssignee: true } : {}),
182
+ });
118
183
  if (opts.json) {
119
184
  console.log(JSON.stringify({ ok: true, action: "story", company, ...patched, storyId }, null, 2));
120
185
  return;
121
186
  }
122
- console.log(`Work mesh: story ${storyId} → ${patched.status} (v${patched.version ?? "?"})`);
187
+ const assignment = assignee === "none"
188
+ ? "assignee cleared"
189
+ : assignee
190
+ ? `assignee ${patched.assigneeUid ?? assigneeUid}`
191
+ : "";
192
+ const statusPart = status ? `${storyId} → ${patched.status}` : storyId;
193
+ console.log(`Work mesh: story ${statusPart}${assignment ? ` ${assignment}` : ""} (v${patched.version ?? "?"})`);
194
+ }
195
+ function record(value) {
196
+ return value && typeof value === "object" && !Array.isArray(value)
197
+ ? value
198
+ : null;
199
+ }
200
+ function parseProjectRepoSpec(value, source) {
201
+ const raw = value.trim();
202
+ const separator = raw.lastIndexOf("@");
203
+ const path = (separator > 0 ? raw.slice(0, separator) : raw).trim();
204
+ const branch = (separator > 0 ? raw.slice(separator + 1) : "").trim();
205
+ if (!path)
206
+ fail(`${source} requires a non-empty repository path.`);
207
+ if (separator > 0 && !branch)
208
+ fail(`${source} has an empty branch after @.`);
209
+ return { path, branch };
210
+ }
211
+ function parseProjectRepos(value, source) {
212
+ if (!Array.isArray(value))
213
+ fail(`${source} must be a JSON repository array.`);
214
+ return value.map((raw, index) => {
215
+ if (typeof raw === "string")
216
+ return parseProjectRepoSpec(raw, `${source}[${index}]`);
217
+ const repo = record(raw);
218
+ const path = typeof repo?.path === "string"
219
+ ? repo.path.trim()
220
+ : typeof repo?.repoPath === "string"
221
+ ? repo.repoPath.trim()
222
+ : typeof repo?.repo === "string"
223
+ ? repo.repo.trim()
224
+ : "";
225
+ const branchValue = repo?.branch ?? repo?.branchName;
226
+ const branch = branchValue === undefined ? "" : typeof branchValue === "string" ? branchValue.trim() : null;
227
+ if (!repo || !path)
228
+ fail(`${source}[${index}].path requires a string.`);
229
+ if (branch === null)
230
+ fail(`${source}[${index}].branch requires a string.`);
231
+ return { path, branch };
232
+ });
233
+ }
234
+ function parseProjectReposJson(raw, source) {
235
+ try {
236
+ return parseProjectRepos(JSON.parse(raw), source);
237
+ }
238
+ catch (err) {
239
+ if (err instanceof SyntaxError)
240
+ fail(`${source} must contain valid JSON.`);
241
+ throw err;
242
+ }
243
+ }
244
+ function projectStoriesFromJson(value, source) {
245
+ const plan = Array.isArray(value) ? null : record(value);
246
+ const rawStories = Array.isArray(value)
247
+ ? value
248
+ : Array.isArray(plan?.userStories)
249
+ ? plan.userStories
250
+ : Array.isArray(plan?.stories)
251
+ ? plan.stories
252
+ : null;
253
+ if (!rawStories) {
254
+ fail(`${source} must be a JSON story array or an object with userStories.`);
255
+ }
256
+ const stories = rawStories.map((raw, index) => {
257
+ const story = record(raw);
258
+ const id = typeof story?.id === "string" ? story.id.trim() : "";
259
+ const title = typeof story?.title === "string" ? story.title.trim() : "";
260
+ if (!story || !id || !title) {
261
+ fail(`${source} userStories[${index}] requires string id and title.`);
262
+ }
263
+ const status = mapSourceStoryStatus(story, `${source} userStories[${index}]`);
264
+ const resolvedStatus = status || (story.passes === true ? "done" : undefined);
265
+ return {
266
+ id,
267
+ title,
268
+ ...(typeof story.description === "string" ? { description: story.description } : {}),
269
+ ...(Array.isArray(story.acceptanceCriteria)
270
+ ? {
271
+ acceptanceCriteria: story.acceptanceCriteria.filter((item) => typeof item === "string"),
272
+ }
273
+ : {}),
274
+ ...(resolvedStatus ? { status: resolvedStatus } : {}),
275
+ // hq-pro makes passes mirror the Board status. A completed PRD story
276
+ // without an explicit status must therefore become done.
277
+ passes: resolvedStatus === "done",
278
+ ...(typeof story.priority === "number" && Number.isFinite(story.priority)
279
+ ? { priority: story.priority }
280
+ : {}),
281
+ };
282
+ });
283
+ const metadata = record(plan?.metadata);
284
+ const repos = metadata && Object.hasOwn(metadata, "repos")
285
+ ? parseProjectRepos(metadata.repos, `${source} metadata.repos`)
286
+ : undefined;
287
+ return {
288
+ ...(typeof plan?.name === "string" ? { name: plan.name } : {}),
289
+ ...(typeof plan?.description === "string" ? { description: plan.description } : {}),
290
+ stories,
291
+ ...(repos ? { repos } : {}),
292
+ };
293
+ }
294
+ function parseProjectPlan(raw, source) {
295
+ try {
296
+ return projectStoriesFromJson(JSON.parse(raw), source);
297
+ }
298
+ catch (err) {
299
+ if (err instanceof SyntaxError)
300
+ fail(`${source} must contain valid JSON.`);
301
+ throw err;
302
+ }
303
+ }
304
+ function httpStatus(err) {
305
+ if (err && typeof err === "object" && "status" in err && typeof err.status === "number") {
306
+ return err.status;
307
+ }
308
+ return undefined;
309
+ }
310
+ function mergeProjectRepos(current, planned) {
311
+ const plannedPaths = new Set(planned.map((repo) => repo.path));
312
+ return [...planned, ...current.filter((repo) => !plannedPaths.has(repo.path))];
313
+ }
314
+ async function runProjectSet(projectId, opts) {
315
+ if (opts.channel !== undefined && !opts.channel.trim()) {
316
+ fail("PROJECT_CHANNEL_INVALID: --channel must be a non-empty channel id.");
317
+ }
318
+ if (opts.storiesFile && opts.storiesJson) {
319
+ fail("Pass only one of --stories-file or --stories-json.");
320
+ }
321
+ if (opts.reposJson && opts.repo?.length) {
322
+ fail("Pass only one of --repos-json or --repo.");
323
+ }
324
+ const source = opts.storiesFile
325
+ ? parseProjectPlan(readFileSync(opts.storiesFile, "utf8"), opts.storiesFile)
326
+ : opts.storiesJson
327
+ ? parseProjectPlan(opts.storiesJson, "--stories-json")
328
+ : undefined;
329
+ const explicitRepos = opts.reposJson
330
+ ? parseProjectReposJson(opts.reposJson, "--repos-json")
331
+ : opts.repo?.length
332
+ ? opts.repo.map((repo, index) => parseProjectRepoSpec(repo, `--repo[${index}]`))
333
+ : undefined;
334
+ const { token, company } = await withCompany(opts);
335
+ let current;
336
+ try {
337
+ current = await getProjectView(token, company.companyUid, projectId);
338
+ }
339
+ catch (err) {
340
+ if (httpStatus(err) === 404 && opts.create) {
341
+ if (!source && !opts.name?.trim()) {
342
+ fail("`--create` needs --name or a stories file when the Board view does not exist.");
343
+ }
344
+ current = undefined;
345
+ }
346
+ else {
347
+ throw err;
348
+ }
349
+ }
350
+ if (!current && !opts.create) {
351
+ fail(`Work mesh project ${projectId} has no Board view. Re-run with --create to add one.`);
352
+ }
353
+ const principalUid = await resolveMeshPrincipalUid(token, loadCachedTokens());
354
+ const PROJECT_CHANGED = "The Board changed while you were editing. Re-run to pick up the latest.";
355
+ let view;
356
+ let registration;
357
+ if (!current) {
358
+ const ensured = await ensureProjectBoard({
359
+ token,
360
+ company,
361
+ projectId,
362
+ name: opts.name?.trim() || source?.name || projectId,
363
+ description: opts.description !== undefined ? opts.description : source?.description ?? "",
364
+ stories: source?.stories ?? [],
365
+ repos: explicitRepos ?? source?.repos ?? [],
366
+ channelId: opts.channel,
367
+ });
368
+ view = ensured.view;
369
+ registration = ensured.registration;
370
+ }
371
+ else if (opts.name !== undefined || opts.description !== undefined || source !== undefined || explicitRepos !== undefined) {
372
+ const stories = source
373
+ ? mergeProjectStories(current.stories, source.stories, { resetStatus: Boolean(opts.resetStatus) })
374
+ : current.stories;
375
+ const statusChangeLine = source ? formatStoryStatusChanges(current.stories, stories) : undefined;
376
+ try {
377
+ view = await putProjectView(token, company.companyUid, projectId, {
378
+ name: opts.name?.trim() || source?.name || current.name,
379
+ ...(opts.description !== undefined
380
+ ? { description: opts.description }
381
+ : source?.description !== undefined
382
+ ? { description: source.description }
383
+ : { description: current.description }),
384
+ stories,
385
+ repos: explicitRepos ?? source?.repos ?? current.repos,
386
+ ...(current.version !== undefined ? { expectedVersion: current.version } : {}),
387
+ });
388
+ }
389
+ catch (err) {
390
+ const conflict = err;
391
+ if (conflict.status === 409 && conflict.code === "VERSION_CONFLICT") {
392
+ if (opts.json) {
393
+ console.log(JSON.stringify({ ok: false, code: "VERSION_CONFLICT", error: PROJECT_CHANGED }));
394
+ }
395
+ fail(PROJECT_CHANGED);
396
+ }
397
+ throw err;
398
+ }
399
+ if (statusChangeLine) {
400
+ if (opts.json)
401
+ console.error(statusChangeLine);
402
+ else
403
+ console.log(statusChangeLine);
404
+ }
405
+ }
406
+ else {
407
+ view = current;
408
+ }
409
+ if (current && opts.channel !== undefined) {
410
+ registration = await registerMeshProject(token, company.companyUid, projectId, opts.channel);
411
+ }
412
+ if (!current && opts.create) {
413
+ noteCallingSessionBound(view.projectId, company);
414
+ }
415
+ if (opts.json) {
416
+ console.log(JSON.stringify({
417
+ ok: true,
418
+ action: "project.set",
419
+ principalUid,
420
+ ...view,
421
+ ...(registration ? { registration } : {}),
422
+ }, null, 2));
423
+ return;
424
+ }
425
+ console.log(`Work mesh: project ${view.projectId} set (${view.name}; ${view.stories.length} stories)`);
426
+ }
427
+ async function runProjectRegister(projectId, opts) {
428
+ if (opts.channel !== undefined && !opts.channel.trim()) {
429
+ fail("PROJECT_CHANNEL_INVALID: --channel must be a non-empty channel id.");
430
+ }
431
+ const { token, company } = await withCompany(opts);
432
+ const principalUid = await resolveMeshPrincipalUid(token, loadCachedTokens());
433
+ const companyRef = company.companySlug || company.companyUid;
434
+ try {
435
+ const board = await getProjectView(token, company.companyUid, projectId);
436
+ if (board.companyUid !== company.companyUid || board.projectId !== projectId) {
437
+ fail(`Work mesh project ${projectId} has no Board view in company ${companyRef}. Create the Board before registering it.`);
438
+ }
439
+ }
440
+ catch (err) {
441
+ if (httpStatus(err) === 404) {
442
+ fail(`Work mesh project ${projectId} has no Board view in company ${companyRef}. Create the Board before registering it.`);
443
+ }
444
+ throw err;
445
+ }
446
+ let registration;
447
+ try {
448
+ registration = await registerMeshProject(token, company.companyUid, projectId, opts.channel);
449
+ }
450
+ catch (err) {
451
+ const failure = err;
452
+ if (failure.status === 403 && failure.code === "PROJECT_NOT_IN_COMPANY") {
453
+ fail(`Work mesh project ${projectId} could not be registered in company ${companyRef}: the Board or its genesis thread is missing. Run "hq mesh project ensure ${projectId} --company ${companyRef} --stories-file <prd.json>" to create or restore them.`);
454
+ }
455
+ throw err;
456
+ }
457
+ const boardState = "registered";
458
+ if (opts.json) {
459
+ console.log(JSON.stringify({ ok: true, action: "project.register", principalUid, boardState, ...registration }, null, 2));
460
+ return;
461
+ }
462
+ console.log(`Work mesh: project ${registration.projectId} registered (${boardState}; channel ${registration.channelId} ${registration.channelCreated ? "created" : "bound"})`);
463
+ }
464
+ async function runProjectEnsure(projectId, opts) {
465
+ if (!opts.storiesFile?.trim())
466
+ fail("`--stories-file <prd.json>` is required.");
467
+ const source = parseProjectPlan(readFileSync(opts.storiesFile, "utf8"), opts.storiesFile);
468
+ const { token, company } = await withCompany(opts);
469
+ let current;
470
+ try {
471
+ current = await getProjectView(token, company.companyUid, projectId);
472
+ }
473
+ catch (err) {
474
+ if (httpStatus(err) !== 404)
475
+ throw err;
476
+ }
477
+ if (opts.dryRun) {
478
+ if (current && (current.companyUid !== company.companyUid || current.projectId !== projectId)) {
479
+ fail("Work mesh project ensure dry-run: Board company or project id did not match the request.");
480
+ }
481
+ const stories = current ? mergeProjectStories(current.stories, source.stories) : source.stories;
482
+ const sourceStatuses = source.stories.map((story) => ({
483
+ id: story.id,
484
+ title: story.title,
485
+ status: boardStoryStatus(story),
486
+ }));
487
+ const boardStatuses = stories.map((story) => ({
488
+ id: story.id,
489
+ title: story.title,
490
+ status: boardStoryStatus(story),
491
+ }));
492
+ if (opts.json) {
493
+ console.log(JSON.stringify({
494
+ ok: true,
495
+ action: "project.ensure.dry-run",
496
+ projectId,
497
+ companyUid: company.companyUid,
498
+ sourceStatuses,
499
+ stories: boardStatuses,
500
+ }, null, 2));
501
+ }
502
+ else {
503
+ console.log(`Work mesh: project ${projectId} dry run (${sourceStatuses.length} source stories)`);
504
+ console.log("Source statuses:");
505
+ for (const story of sourceStatuses)
506
+ console.log(`${story.id}\t${story.status}`);
507
+ console.log("Merged Board statuses:");
508
+ for (const story of boardStatuses)
509
+ console.log(`${story.id}\t${story.status}`);
510
+ }
511
+ return;
512
+ }
513
+ // Genesis thread, then the view, then register. Register returns 403
514
+ // PROJECT_NOT_IN_COMPANY until both exist. A missing view uses that chain
515
+ // from ensureProjectBoard; an existing view is merged, then registered.
516
+ let registration;
517
+ let verified;
518
+ if (!current) {
519
+ const ensured = await ensureProjectBoard({
520
+ token,
521
+ company,
522
+ projectId,
523
+ name: source.name || projectId,
524
+ description: source.description ?? "",
525
+ stories: source.stories,
526
+ repos: source.repos ?? [],
527
+ });
528
+ registration = ensured.registration;
529
+ verified = ensured.view;
530
+ }
531
+ else {
532
+ const genesis = await ensureProjectThread(token, company, projectId, {
533
+ summary: source.name || projectId,
534
+ });
535
+ if (!genesis.threadId)
536
+ fail("Work mesh did not return a threadId.");
537
+ {
538
+ const stories = mergeProjectStories(current.stories, source.stories);
539
+ const repos = mergeProjectRepos(current.repos, source.repos ?? []);
540
+ const name = source.name || current.name;
541
+ const description = source.description !== undefined ? source.description : current.description;
542
+ const changed = name !== current.name ||
543
+ description !== current.description ||
544
+ JSON.stringify(stories) !== JSON.stringify(current.stories) ||
545
+ JSON.stringify(repos) !== JSON.stringify(current.repos);
546
+ if (changed) {
547
+ await putProjectView(token, company.companyUid, projectId, {
548
+ name,
549
+ description,
550
+ stories,
551
+ repos,
552
+ ...(current.version !== undefined ? { expectedVersion: current.version } : {}),
553
+ });
554
+ }
555
+ }
556
+ registration = await registerMeshProject(token, company.companyUid, projectId);
557
+ await closeSupersededProjectThread({
558
+ token,
559
+ companyUid: company.companyUid,
560
+ openedThreadId: genesis.threadId,
561
+ canonicalThreadId: registration.threadId,
562
+ created: genesis.created,
563
+ });
564
+ if (!registration.threadId || !registration.channelId) {
565
+ fail("Work mesh registration did not return a threadId and channelId.");
566
+ }
567
+ verified = await getProjectView(token, company.companyUid, projectId);
568
+ }
569
+ if (verified.companyUid !== company.companyUid) {
570
+ fail(`Work mesh project ensure: company mismatch (expected ${company.companyUid}, got ${verified.companyUid}).`);
571
+ }
572
+ if (verified.projectId !== projectId) {
573
+ fail(`Work mesh project ensure: project id mismatch (expected ${projectId}, got ${verified.projectId}).`);
574
+ }
575
+ for (const story of source.stories) {
576
+ if (!verified.stories.some((row) => row.id === story.id)) {
577
+ fail(`Work mesh project ensure: missing story ${story.id}.`);
578
+ }
579
+ }
580
+ for (const repo of source.repos ?? []) {
581
+ if (!verified.repos.some((row) => row.path === repo.path)) {
582
+ fail(`Work mesh project ensure: missing repo ${repo.path}.`);
583
+ }
584
+ }
585
+ if (verified.version === undefined) {
586
+ fail("Work mesh project ensure: verified view has no version.");
587
+ }
588
+ const payload = {
589
+ projectId: verified.projectId,
590
+ threadId: registration.threadId,
591
+ channelId: registration.channelId,
592
+ version: verified.version,
593
+ stories: verified.stories,
594
+ };
595
+ noteCallingSessionBound(payload.projectId, company);
596
+ if (opts.json) {
597
+ console.log(JSON.stringify(payload));
598
+ return;
599
+ }
600
+ console.log(`Work mesh: project ${payload.projectId} ensured (thread ${payload.threadId}, channel ${payload.channelId}, ${payload.stories.length} stories)`);
601
+ }
602
+ async function runPrdSync(opts) {
603
+ const sessionId = opts.session.trim();
604
+ const file = opts.file.trim();
605
+ if (!sessionId || !file)
606
+ fail("Usage: hq mesh context prd-sync --session <sid> --file <prd.json>");
607
+ const root = workContextHomeRoot();
608
+ const plan = planPrdSync({ sessionId, file, root });
609
+ if (plan.rebindTo) {
610
+ rebindSessionToProject({ sessionId, root, projectId: plan.rebindTo });
611
+ }
612
+ if (!plan.changed) {
613
+ const payload = { ok: true, action: "context.prd-sync", changed: 0, ...(plan.skip ? { skip: plan.skip } : {}) };
614
+ if (opts.json)
615
+ console.log(JSON.stringify(payload));
616
+ else
617
+ console.log(plan.skip ? `Work mesh: prd-sync skipped (${plan.skip})` : "Work mesh: prd-sync unchanged");
618
+ return;
619
+ }
620
+ let token;
621
+ try {
622
+ token = await requireToken();
623
+ }
624
+ catch {
625
+ token = null;
626
+ }
627
+ if (!token) {
628
+ console.error("work-mesh: prd-sync has changes but no token; snapshot not advanced");
629
+ return;
630
+ }
631
+ // Attribution evidence: without company and project the server files these
632
+ // as unassigned and the Board never moves. After a same-company switch,
633
+ // this is the new project's id so ingest writes SESSION_STATE.projectId
634
+ // and bound-forward posts the channel line there.
635
+ const bound = readSessionState(sessionId, root);
636
+ const evidenceBase = {
637
+ ...(bound?.companySlug ? { companySlug: bound.companySlug } : {}),
638
+ ...(bound?.projectId ? { project: bound.projectId } : {}),
639
+ touchedPaths: [resolvePath(file)],
640
+ };
641
+ let toEmit = plan.events;
642
+ if (bound?.companyUid && bound.projectId) {
643
+ try {
644
+ const live = await getProjectView(token, bound.companyUid, bound.projectId);
645
+ toEmit = prdSyncEventsThatChangeBoard(plan.events, live.stories);
646
+ }
647
+ catch {
648
+ // Board unread — emit the snapshot diff; the server drops same-status.
649
+ }
650
+ if (toEmit.length === 0) {
651
+ plan.commit();
652
+ if (opts.json) {
653
+ console.log(JSON.stringify({ ok: true, action: "context.prd-sync", changed: 0 }));
654
+ }
655
+ else {
656
+ console.log("Work mesh: prd-sync unchanged");
657
+ }
658
+ return;
659
+ }
660
+ try {
661
+ const source = parseProjectPlan(readFileSync(file, "utf8"), file);
662
+ await ensureMissingBoardStories({
663
+ token,
664
+ company: {
665
+ companyUid: bound.companyUid,
666
+ companySlug: bound.companySlug || bound.companyUid,
667
+ },
668
+ projectId: bound.projectId,
669
+ name: source.name || bound.projectId,
670
+ description: source.description ?? "",
671
+ stories: source.stories,
672
+ repos: source.repos ?? [],
673
+ requiredIds: toEmit.map((event) => event.taskId),
674
+ });
675
+ }
676
+ catch (err) {
677
+ const reason = err instanceof Error ? err.message : String(err);
678
+ console.error(`work-mesh: prd-sync ensure failed; emitting anyway (${reason.slice(0, 160)})`);
679
+ }
680
+ }
681
+ const alreadyOnBoard = plan.events
682
+ .filter((event) => !toEmit.some((row) => row.taskId === event.taskId))
683
+ .map((event) => event.taskId);
684
+ const meshRoot = workMeshHomeRoot();
685
+ const seqFirst = reserveSessionSeq(sessionId, toEmit.length);
686
+ const events = toEmit.map((event, index) => buildMeshEmitEvent({
687
+ eventId: generateUlid(Date.now() + index),
688
+ kind: "task_status",
689
+ sessionId,
690
+ harness: "hq-sessions",
691
+ adapterVersion: "1.0.0",
692
+ at: new Date().toISOString(),
693
+ seq: seqFirst + index,
694
+ source: "hooks",
695
+ taskId: event.taskId,
696
+ status: event.status,
697
+ summary: event.status === "done"
698
+ ? `${event.taskId} passes`
699
+ : event.status === "in_progress"
700
+ ? `${event.taskId} in progress`
701
+ : `${event.taskId} in review`,
702
+ evidence: { ...evidenceBase, task: event.taskId },
703
+ }));
704
+ const poster = createEmitPoster({ token, baseUrl: resolveVaultApiBase(process.env) });
705
+ const emitted = await emitEvents({
706
+ workMeshRoot: meshRoot,
707
+ poster,
708
+ newEvents: events,
709
+ });
710
+ if (emitted.unassigned > 0 || emitted.rejected > 0) {
711
+ console.error(`work-mesh: prd-sync sent ${events.length}; unassigned=${emitted.unassigned} rejected=${emitted.rejected}`);
712
+ for (const line of formatEmitRejectionLines(emitted.rejections))
713
+ console.error(line);
714
+ }
715
+ const blocked = new Set(emitted.rejections.map((row) => row.eventId));
716
+ for (const pending of readEmitRetry(meshRoot)) {
717
+ const id = typeof pending.eventId === "string" ? pending.eventId : "";
718
+ if (id)
719
+ blocked.add(id);
720
+ }
721
+ const advanced = events.flatMap((event) => (event.eventId && event.taskId && !blocked.has(event.eventId) ? [event.taskId] : []));
722
+ plan.commit([...alreadyOnBoard, ...advanced]);
723
+ if (plan.taskId && advanced.includes(plan.taskId)) {
724
+ updateSessionState(sessionId, root, (current) => {
725
+ if (!current)
726
+ return null;
727
+ return {
728
+ ...current,
729
+ taskId: plan.taskId,
730
+ contextStatus: current.projectId ? "bound" : current.contextStatus,
731
+ updatedAt: new Date().toISOString(),
732
+ };
733
+ });
734
+ }
735
+ if (opts.json) {
736
+ console.log(JSON.stringify({ ok: true, action: "context.prd-sync", changed: toEmit.length, taskId: plan.taskId }));
737
+ return;
738
+ }
739
+ console.log(`Work mesh: prd-sync emitted ${toEmit.length} task_status`);
740
+ }
741
+ function noteCallingSessionBound(projectId, company) {
742
+ try {
743
+ const bound = bindCallingSession({
744
+ root: workContextHomeRoot(),
745
+ projectId,
746
+ company,
747
+ });
748
+ if (bound.bound)
749
+ console.error(formatSessionBoundLine(bound.sessionId, bound.projectId));
750
+ }
751
+ catch {
752
+ /* session bind is local and must not fail project ensure */
753
+ }
123
754
  }
124
755
  async function runDoctor(opts) {
125
756
  if (opts.apply) {
126
757
  fail("`hq mesh doctor --apply` (paced Board PUTs from local prd.json) is not in the CLI yet.\n" +
127
758
  "Omit --apply to warm the conversation cache (directory, inbox, pair DMs).");
128
759
  }
760
+ const identity = collectDaemonDoctor();
761
+ const identityLines = formatCliIdentityLines(identity);
762
+ if (!opts.json) {
763
+ for (const line of identityLines)
764
+ console.log(line);
765
+ }
129
766
  const token = await requireToken();
130
767
  const principalUid = await resolveMeshPrincipalUid(token, loadCachedTokens());
768
+ if (!principalUid) {
769
+ fail("Could not resolve the authenticated principal. Sign in again and retry `hq mesh doctor`.");
770
+ }
131
771
  const warmed = await warmMeshConversationCache(token, principalUid);
772
+ const needsProject = listNeedsProjectSessions(workContextHomeRoot());
132
773
  if (opts.json) {
133
- console.log(JSON.stringify({ ok: true, action: "doctor", ...warmed }, null, 2));
774
+ console.log(JSON.stringify({
775
+ ok: true,
776
+ action: "doctor",
777
+ ...warmed,
778
+ needsProject,
779
+ cliMismatchLine: identity.cliMismatchLine ?? null,
780
+ hqOnPath: identity.hqOnPath,
781
+ multipleHqOnPath: identity.multipleHqOnPath,
782
+ }, null, 2));
134
783
  return;
135
784
  }
136
785
  console.log(`Work mesh cache warmed at ${warmed.cacheRoot}` +
137
786
  ` (directory=${warmed.directory} inbox=${warmed.inbox}` +
138
787
  ` contacts=${warmed.contacts} pair-threads=${warmed.threads})`);
788
+ if (needsProject.length === 0) {
789
+ console.log("needs_project sessions: none");
790
+ return;
791
+ }
792
+ console.log(`needs_project sessions: ${needsProject.length}`);
793
+ for (const row of needsProject) {
794
+ const choices = row.candidates.map((candidate) => candidate.projectId).join(", ") || "(none)";
795
+ console.log(`- ${row.sessionId}: ${row.reason ?? "no reason recorded"}; candidates: ${choices}`);
796
+ }
797
+ }
798
+ async function runBindProject(target, opts) {
799
+ const sessionId = opts.session.trim();
800
+ const root = workContextHomeRoot();
801
+ const current = readSessionState(sessionId, root);
802
+ if (!current)
803
+ fail(`No work-context state for session ${sessionId}.`);
804
+ let projectId = target.trim();
805
+ if (projectId === "new") {
806
+ const slug = opts.slug?.trim();
807
+ if (!slug)
808
+ fail("Usage: hq mesh context bind-project new <slug> --session <sid>");
809
+ const hqRoot = process.env.HQ_ROOT?.trim() || findHqRoot();
810
+ const prdPath = findLocalPrd(hqRoot, current.companySlug, slug);
811
+ if (!prdPath) {
812
+ fail(`No PRD for ${slug}. Run /prd before binding a new project.`);
813
+ }
814
+ if (!current.companyUid)
815
+ fail(`Session ${sessionId} has no company. Bind a company first.`);
816
+ const { token, company } = await withCompany({ company: opts.company ?? current.companySlug });
817
+ const plan = parseProjectPlan(readFileSync(prdPath, "utf8"), prdPath);
818
+ await ensureProjectBoard({
819
+ token,
820
+ company: {
821
+ companyUid: current.companyUid,
822
+ companySlug: current.companySlug || company.companySlug,
823
+ },
824
+ projectId: slug,
825
+ name: plan.name || slug,
826
+ description: plan.description ?? "",
827
+ stories: plan.stories,
828
+ repos: plan.repos ?? [],
829
+ });
830
+ projectId = slug;
831
+ }
832
+ else if (/^[1-9][0-9]*$/.test(projectId)) {
833
+ const index = Number(projectId) - 1;
834
+ const chosen = current.projectCandidates?.[index];
835
+ if (!chosen)
836
+ fail(`No candidate ${projectId} on session ${sessionId}.`);
837
+ projectId = chosen.projectId;
838
+ }
839
+ const updated = updateSessionState(sessionId, root, (state) => state ? applyOperatorProjectBinding(state, projectId) : null);
840
+ if (!updated)
841
+ fail(`No work-context state for session ${sessionId}.`);
842
+ if (opts.json) {
843
+ console.log(JSON.stringify({ ok: true, action: "context.bind-project", sessionId, projectId, contextStatus: updated.contextStatus }));
844
+ return;
845
+ }
846
+ console.log(`Work mesh: session ${sessionId} bound to project ${projectId}`);
139
847
  }
140
848
  async function runContextReconcile(opts) {
141
849
  if (!opts.observationFile && !opts.observationJson) {
@@ -152,25 +860,92 @@ async function runContextReconcile(opts) {
152
860
  let fetchCandidates;
153
861
  let validateMembership;
154
862
  let offline = Boolean(opts.offline);
155
- if (!offline) {
156
- try {
157
- const token = await requireToken();
158
- deliver = createWorkSessionDeliverer({ token });
159
- fetchCandidates = createCandidatesFetcher({ token });
863
+ let token;
864
+ try {
865
+ if (offline) {
866
+ if (isMachineIdentity()) {
867
+ token = await ensureCognitoToken({ tokenSource: "machine", interactive: false });
868
+ }
869
+ else {
870
+ const cached = loadCachedTokens();
871
+ if (cached && !isExpiring(cached, 120)) {
872
+ token = cached.accessToken;
873
+ }
874
+ }
875
+ }
876
+ else {
877
+ token = await requireToken();
878
+ }
879
+ if (token) {
880
+ const sessionToken = token;
881
+ const membershipValidationTimeoutMs = offline
882
+ ? OFFLINE_MEMBERSHIP_VALIDATION_TIMEOUT_MS
883
+ : ONLINE_MEMBERSHIP_VALIDATION_TIMEOUT_MS;
160
884
  validateMembership = async (candidate) => {
161
- const membership = await resolveActiveMembershipCompany(token, candidate);
162
- if (!membership)
885
+ const membership = await new Promise((resolve, reject) => {
886
+ const timer = setTimeout(() => reject(new Error("membership validation timed out")), membershipValidationTimeoutMs);
887
+ void resolveActiveMembershipCompany(sessionToken, candidate).then((value) => {
888
+ clearTimeout(timer);
889
+ resolve(value);
890
+ }, (error) => {
891
+ clearTimeout(timer);
892
+ reject(error);
893
+ });
894
+ });
895
+ if (!membership || typeof membership.companyUid !== "string" || !membership.companyUid) {
163
896
  return false;
897
+ }
164
898
  return { uid: membership.companyUid };
165
899
  };
900
+ if (!offline) {
901
+ deliver = createWorkSessionDeliverer({ token: sessionToken });
902
+ fetchCandidates = createCandidatesFetcher({ token: sessionToken });
903
+ }
166
904
  }
167
- catch {
905
+ }
906
+ catch {
907
+ if (!offline) {
168
908
  offline = true;
169
909
  if (!opts.machine) {
170
910
  console.error(chalk.yellow("No Cognito session; reconciling offline (outbox only)."));
171
911
  }
172
912
  }
173
913
  }
914
+ if (token) {
915
+ const activation = await ensureDefaultCompany({
916
+ root,
917
+ listMemberships: () => listActiveMembershipCompanies(token),
918
+ log: (message) => console.error(chalk.dim(message)),
919
+ });
920
+ if (activation.status === "needs_choice") {
921
+ const interactive = !offline &&
922
+ !opts.machine &&
923
+ Boolean(process.stdin.isTTY && process.stdout.isTTY) &&
924
+ !isMachineIdentity();
925
+ if (interactive) {
926
+ const choices = activation.memberships
927
+ .map((membership, index) => `${index + 1}. ${membership.slug}`)
928
+ .join("\n");
929
+ const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
930
+ try {
931
+ const answer = await rl.question(`Choose this device's default company:\n${choices}\nSelection: `);
932
+ const selected = activation.memberships[Number.parseInt(answer, 10) - 1];
933
+ if (selected) {
934
+ await setDefaultCompany(selected.slug, {
935
+ root,
936
+ validateMembership: (candidate) => candidate === selected.slug ? { uid: selected.uid } : false,
937
+ });
938
+ }
939
+ }
940
+ finally {
941
+ rl.close();
942
+ }
943
+ }
944
+ else if (!offline && !opts.machine) {
945
+ console.error(chalk.yellow("Multiple active memberships. Run `hq mesh context default set <slug>` to choose this device's default company."));
946
+ }
947
+ }
948
+ }
174
949
  const outcome = await reconcileObservation(obs, {
175
950
  root,
176
951
  env: process.env,
@@ -178,6 +953,20 @@ async function runContextReconcile(opts) {
178
953
  fetchCandidates,
179
954
  offline,
180
955
  validateMembership,
956
+ ensureProjectBoard: token
957
+ ? async ({ companyUid, projectId, prdPath }) => {
958
+ const plan = parseProjectPlan(readFileSync(prdPath, "utf8"), prdPath);
959
+ await ensureProjectBoard({
960
+ token,
961
+ company: { companyUid, companySlug: companyUid },
962
+ projectId,
963
+ name: plan.name || projectId,
964
+ description: plan.description ?? "",
965
+ stories: plan.stories,
966
+ repos: plan.repos ?? [],
967
+ });
968
+ }
969
+ : undefined,
181
970
  });
182
971
  for (const line of outcome.diagnostics) {
183
972
  console.error(line);
@@ -294,19 +1083,21 @@ async function runContextBackfillHeld(opts) {
294
1083
  const parsedLimit = opts.limit ? Number.parseInt(opts.limit, 10) : 0;
295
1084
  const limit = Number.isFinite(parsedLimit) && parsedLimit > 0 ? parsedLimit : 0;
296
1085
  const companyHint = opts.company?.trim() || undefined;
297
- // Build the reconcile network seam exactly like `hq mesh context reconcile`.
298
- // Not needed in --dry-run (reconcile is never invoked then). Explicit types
299
- // because these are captured in the reconcile closure below (no control-flow
300
- // narrowing, unlike the inline reconcile handler).
1086
+ const useDeviceDefault = opts.useDeviceDefault === true || readDeviceConfig({ root }).repairHeldWithDefault === true;
1087
+ // Build the membership seam for both modes; dry-run is read-only but must
1088
+ // validate a locally resolved slug just as live reconciliation does.
1089
+ // The remaining seams are captured in the reconcile closure below.
301
1090
  let deliver;
302
1091
  let fetchCandidates;
303
1092
  let validateMembership;
304
1093
  let offline = Boolean(opts.offline);
305
- if (!dryRun && !offline) {
1094
+ if (!offline) {
306
1095
  try {
307
1096
  const token = await requireToken();
308
- deliver = createWorkSessionDeliverer({ token });
309
- fetchCandidates = createCandidatesFetcher({ token });
1097
+ if (!dryRun) {
1098
+ deliver = createWorkSessionDeliverer({ token });
1099
+ fetchCandidates = createCandidatesFetcher({ token });
1100
+ }
310
1101
  validateMembership = async (candidate) => {
311
1102
  const membership = await resolveActiveMembershipCompany(token, candidate);
312
1103
  if (!membership)
@@ -324,11 +1115,14 @@ async function runContextBackfillHeld(opts) {
324
1115
  const result = await backfillHeldSessions({
325
1116
  workMeshRoot: meshRoot,
326
1117
  workContextRoot: root,
1118
+ hqRoot: process.env.HQ_ROOT?.trim() || findHqRoot(),
327
1119
  dryRun,
328
1120
  limit,
329
1121
  // Mirror the reconcile closure's non-forcing hint in the dry-run predictor
330
1122
  // so `--dry-run` and the real run report the same counts.
331
1123
  remoteOwnerHint: companyHint || undefined,
1124
+ useDeviceDefault,
1125
+ validateMembership,
332
1126
  reconcile: (obs) => reconcileObservation(
333
1127
  // Pass --company as a non-forcing hint (remoteOwnerSlug feeds
334
1128
  // deterministic resolution BELOW the identity-file / device default,
@@ -340,6 +1134,8 @@ async function runContextBackfillHeld(opts) {
340
1134
  fetchCandidates,
341
1135
  offline,
342
1136
  validateMembership,
1137
+ allowDeviceDefault: useDeviceDefault,
1138
+ deviceDefaultConfidence: useDeviceDefault,
343
1139
  }),
344
1140
  });
345
1141
  if (opts.json) {
@@ -354,6 +1150,9 @@ async function runContextBackfillHeld(opts) {
354
1150
  `${result.unresolved} unresolved, ` +
355
1151
  `${result.errors} error(s).` +
356
1152
  (dryRun ? " (dry-run: nothing written)" : ""));
1153
+ for (const { sessionId, reason } of result.unresolvedReasons) {
1154
+ console.log(`Unresolved ${sessionId}: ${reason}`);
1155
+ }
357
1156
  if (!dryRun && result.reconciled > 0) {
358
1157
  console.log("Reconciled session state files were rewritten with a resolved company; " +
359
1158
  "the mesh daemon's held retry will re-attribute and post those events.");
@@ -362,20 +1161,38 @@ async function runContextBackfillHeld(opts) {
362
1161
  async function runContextDefaultGet(opts) {
363
1162
  const root = workContextHomeRoot();
364
1163
  const cfg = readDeviceConfig({ root });
365
- const current = getDefaultCompany({ root });
1164
+ const current = cfg.defaultCompany?.enabled && cfg.defaultCompany.slug
1165
+ ? cfg.defaultCompany
1166
+ : null;
1167
+ const memberships = cfg.defaultCompanyMemberships?.memberships ?? [];
1168
+ const disabled = isDefaultCompanyDisabled({ root });
1169
+ const source = disabled ? "disabled" : current?.source ?? (current ? "chosen" : "unset");
366
1170
  if (opts.json) {
367
- console.log(JSON.stringify({ ok: true, config: cfg, defaultCompany: current }, null, 2));
1171
+ console.log(JSON.stringify({
1172
+ ok: true,
1173
+ slug: current?.slug ?? null,
1174
+ uid: current?.uid ?? null,
1175
+ enabled: current?.enabled ?? false,
1176
+ source,
1177
+ needsChoice: !current && !disabled && memberships.length > 1,
1178
+ memberships,
1179
+ repairHeldWithDefault: cfg.repairHeldWithDefault === true,
1180
+ }, null, 2));
1181
+ return;
1182
+ }
1183
+ if (disabled) {
1184
+ console.log("Default company disabled on this device.");
368
1185
  return;
369
1186
  }
370
1187
  if (!current) {
371
1188
  console.log("No device default company (default-company mode may be dark).");
372
1189
  return;
373
1190
  }
374
- console.log(`Default company: ${current.slug}${current.uid ? ` (${current.uid})` : ""} enabled=${current.enabled}`);
1191
+ console.log(`Default company: ${current.slug}${current.uid ? ` (${current.uid})` : ""} enabled=${current.enabled} source=${source}`);
375
1192
  }
376
1193
  async function runContextDefaultSet(slug, opts) {
377
1194
  const root = workContextHomeRoot();
378
- void opts.company; // retained for CLI compatibility; unlock is memberships-wide
1195
+ void opts.company; // retained for CLI compatibility
379
1196
  let token;
380
1197
  try {
381
1198
  token = await requireToken();
@@ -383,42 +1200,38 @@ async function runContextDefaultSet(slug, opts) {
383
1200
  catch {
384
1201
  token = undefined;
385
1202
  }
386
- // US-017B: unlock only when EVERY active membership advertises migration.
1203
+ // Migration remains useful diagnostic context, but it must never prevent a
1204
+ // verified member from choosing their own device-local preference.
387
1205
  let migrationCapability = false;
1206
+ let migrationWarning;
388
1207
  if (token) {
389
1208
  const probe = await probeMigrationCapabilityForMemberships(token);
390
1209
  recordMigrationCapabilitySnapshot(probe, { root });
391
1210
  migrationCapability = probe.unlocked;
392
- if (probe.offline && !opts.allowWithoutMigration) {
393
- console.error(chalk.red("DEFAULT_COMPANY_LOCKED: cannot probe migration capability (offline or not logged in)"));
394
- process.exitCode = 1;
395
- return;
1211
+ if (probe.offline) {
1212
+ migrationWarning =
1213
+ "Warning: migration capability could not be checked; membership for the selected company will still be verified.";
396
1214
  }
397
- if (!probe.unlocked && !opts.allowWithoutMigration) {
1215
+ else if (!probe.unlocked) {
398
1216
  const detail = probe.companies.length === 0
399
1217
  ? "no active memberships"
400
1218
  : probe.companies
401
1219
  .filter((c) => !c.migration)
402
1220
  .map((c) => c.companySlug || c.companyUid)
403
1221
  .join(", ");
404
- console.error(chalk.red(`DEFAULT_COMPANY_LOCKED: migration capability is not true for every company you belong to (${detail || "locked"})`));
405
- process.exitCode = 1;
406
- return;
1222
+ migrationWarning =
1223
+ `Warning: migration capability is mixed or unavailable for ${detail || "some memberships"}; ` +
1224
+ "the selected company can still be set because membership is verified directly.";
407
1225
  }
408
1226
  }
409
- else if (!opts.allowWithoutMigration) {
410
- console.error(chalk.red("DEFAULT_COMPANY_LOCKED: cannot probe migration capability (no Cognito session)"));
411
- process.exitCode = 1;
412
- return;
413
- }
414
- if (!migrationCapability && opts.allowWithoutMigration) {
415
- console.error(chalk.yellow("Warning: --allow-without-migration bypasses DEFAULT_COMPANY_LOCKED; a wrong default is hard to correct until migration is available for every company you belong to."));
1227
+ else {
1228
+ migrationWarning =
1229
+ "Warning: migration capability could not be checked without a Cognito session; membership for the selected company must still be verified.";
416
1230
  }
417
1231
  try {
418
1232
  const cfg = await setDefaultCompany(slug, {
419
1233
  root,
420
1234
  migrationCapability,
421
- allowWithoutMigration: opts.allowWithoutMigration,
422
1235
  validateMembership: async (candidate) => {
423
1236
  if (!token) {
424
1237
  throw new DefaultCompanyUnavailableError(`Cannot verify membership for company "${candidate}" (no Cognito session; offline or not logged in)`);
@@ -436,16 +1249,20 @@ async function runContextDefaultSet(slug, opts) {
436
1249
  return { uid: membership.companyUid };
437
1250
  },
438
1251
  });
1252
+ const configured = opts.repairHeldWithDefault
1253
+ ? setRepairHeldWithDefault(true, { root })
1254
+ : cfg;
439
1255
  if (opts.json) {
440
- console.log(JSON.stringify({ ok: true, config: cfg }, null, 2));
1256
+ console.log(JSON.stringify({ ok: true, config: configured, migrationWarning }, null, 2));
441
1257
  return;
442
1258
  }
443
- const stored = cfg.defaultCompany;
1259
+ const stored = configured.defaultCompany;
444
1260
  console.log(`Default company set to ${stored?.slug ?? slug}${stored?.uid ? ` (${stored.uid})` : ""}`);
1261
+ if (migrationWarning)
1262
+ console.error(chalk.yellow(migrationWarning));
445
1263
  }
446
1264
  catch (err) {
447
- if (err instanceof DefaultCompanyLockedError ||
448
- err instanceof DefaultCompanyUnavailableError) {
1265
+ if (err instanceof DefaultCompanyUnavailableError) {
449
1266
  console.error(chalk.red(`${err.code}: ${err.message}`));
450
1267
  process.exitCode = 1;
451
1268
  return;
@@ -715,13 +1532,16 @@ async function runSessionStatus(opts) {
715
1532
  }
716
1533
  const { token, company } = await withCompany({ company: opts.company });
717
1534
  const live = await fetchCompanyLive(token, company.companyUid);
1535
+ const unattributedEvents = collectDaemonDoctor().unattributedEvents;
718
1536
  if (opts.json) {
719
- console.log(JSON.stringify({ ok: true, action: "session-status", company, live }, null, 2));
1537
+ console.log(JSON.stringify({ ok: true, action: "session-status", company, live, unattributedEvents }, null, 2));
720
1538
  return;
721
1539
  }
722
1540
  for (const line of formatCompanyLiveTable(live, company.companySlug || company.companyUid)) {
723
1541
  console.log(line);
724
1542
  }
1543
+ console.log(`unattributed events: ${unattributedEvents.total} ` +
1544
+ `(spool=${unattributedEvents.spool} held=${unattributedEvents.held} dead-letter=${unattributedEvents.deadLetter})`);
725
1545
  }
726
1546
  const HARNESSES = new Set([
727
1547
  "claude-code",
@@ -754,6 +1574,21 @@ async function runSessionEnqueue(cliKind, opts) {
754
1574
  const sessionId = resolveEnqueueSessionId(opts.sessionId, process.env);
755
1575
  if (!sessionId)
756
1576
  fail("sessionId required (--session-id or HQ_SESSION_ID)");
1577
+ if (kind === "turn_start") {
1578
+ try {
1579
+ rebindNeedsProjectOnPrompt({
1580
+ sessionId,
1581
+ root: workContextHomeRoot(),
1582
+ hqRoot: opts.hqRoot?.trim() || process.env.HQ_ROOT,
1583
+ cwd: opts.cwd,
1584
+ companySlug: opts.companySlug,
1585
+ env: process.env,
1586
+ });
1587
+ }
1588
+ catch {
1589
+ /* prompt rebind is fail-soft */
1590
+ }
1591
+ }
757
1592
  const evidence = buildEmitEvidence({
758
1593
  sessionId: sessionId,
759
1594
  hqRoot: opts.hqRoot,
@@ -763,7 +1598,16 @@ async function runSessionEnqueue(cliKind, opts) {
763
1598
  companySlug: opts.companySlug,
764
1599
  project: opts.project,
765
1600
  task: opts.task,
1601
+ env: process.env,
766
1602
  });
1603
+ const reportFields = kind === "session_end"
1604
+ ? enrichSessionEndEvent({
1605
+ kind,
1606
+ sessionId: sessionId,
1607
+ cwd: opts.cwd,
1608
+ summary: opts.summary,
1609
+ })
1610
+ : {};
767
1611
  const event = buildMeshEmitEvent({
768
1612
  eventId: opts.eventId?.trim() || generateUlid(Date.now()),
769
1613
  kind: kind,
@@ -777,10 +1621,35 @@ async function runSessionEnqueue(cliKind, opts) {
777
1621
  taskId: opts.taskId,
778
1622
  status: opts.status,
779
1623
  reason: opts.reason,
780
- summary: opts.summary,
1624
+ summary: opts.summary ||
1625
+ (typeof reportFields.summary === "string" ? reportFields.summary : undefined),
1626
+ repo: typeof reportFields.repo === "string" ? reportFields.repo : undefined,
1627
+ gitBranch: typeof reportFields.gitBranch === "string"
1628
+ ? reportFields.gitBranch
1629
+ : undefined,
1630
+ prUrls: Array.isArray(reportFields.prUrls)
1631
+ ? reportFields.prUrls
1632
+ : undefined,
781
1633
  evidence,
782
1634
  });
783
1635
  const meshRoot = workMeshHomeRoot();
1636
+ // A machine credential with no company must not be posted. The server files
1637
+ // that as company NONE. Hold it and say why.
1638
+ if (machineEmitDisposition({ machine: isMachineIdentity(), companySlug: evidence.companySlug }) === "hold") {
1639
+ appendHeldLine(JSON.stringify({
1640
+ event,
1641
+ heldReason: "NEEDS_COMPANY",
1642
+ heldAt: new Date().toISOString(),
1643
+ reason: "machine session has no company; event was not sent",
1644
+ }), meshRoot);
1645
+ const heldMessage = `work-mesh: held ${kind}; needs_company (machine session has no company; not sent)`;
1646
+ if (opts.json) {
1647
+ console.log(JSON.stringify({ ok: true, action: "emit", kind, held: true, reason: "needs_company" }, null, 2));
1648
+ return;
1649
+ }
1650
+ console.error(heldMessage);
1651
+ return;
1652
+ }
784
1653
  // Resolve a token non-interactively (same path as every CLI call). If the box
785
1654
  // is not logged in, retain the event locally for the next invocation to drain.
786
1655
  let token;
@@ -816,6 +1685,9 @@ async function runSessionEnqueue(cliKind, opts) {
816
1685
  console.error(`work-mesh: emit ${kind} accepted=${summary.accepted}` +
817
1686
  ` unassigned=${summary.unassigned} rejected=${summary.rejected}` +
818
1687
  ` retryDepth=${summary.retryDepth}`);
1688
+ for (const line of formatEmitRejectionLines(summary.rejections)) {
1689
+ console.error(line);
1690
+ }
819
1691
  }
820
1692
  async function runMeshMode(action, opts) {
821
1693
  const meshRoot = workMeshHomeRoot();
@@ -900,6 +1772,9 @@ async function runMeshEmit(opts) {
900
1772
  ` unassigned=${summary.unassigned} rejected=${summary.rejected}` +
901
1773
  ` retryDepth=${summary.retryDepth}` +
902
1774
  (opts.replayLegacy ? ` (legacy scanned=${scanned} skipped=${skipped})` : ""));
1775
+ for (const line of formatEmitRejectionLines(summary.rejections)) {
1776
+ console.log(line);
1777
+ }
903
1778
  }
904
1779
  async function runSessionFlush(opts) {
905
1780
  const token = await requireToken();
@@ -998,9 +1873,43 @@ export function registerMeshCommand(program) {
998
1873
  .option("--summary <text>", "Note text")).action((opts) => wrap(() => runEvent("note", opts))());
999
1874
  addSharedFlags(mesh
1000
1875
  .command("story")
1001
- .description("PATCH one Board story status")
1876
+ .description("PATCH one Board story status and/or assignee")
1002
1877
  .requiredOption("--story <id>", "Story id, e.g. US-001")
1003
- .requiredOption("--status <status>", "queued|in_progress|review|done")).action((opts) => wrap(() => runStory(opts))());
1878
+ .option("--status <status>", "queued|in_progress|review|done")
1879
+ .option("--assignee <uid|me|none>", "Assign a person or agent uid, yourself, or clear")).action((opts) => wrap(() => runStory(opts))());
1880
+ const project = mesh
1881
+ .command("project")
1882
+ .description("Set a project Board view or register its project channel");
1883
+ project
1884
+ .command("set <projectId>")
1885
+ .description("PUT the project Board view from flags or a PRD JSON file")
1886
+ .requiredOption("--company <slug|uid>", "Company slug or cloud uid")
1887
+ .option("--name <name>", "Project name")
1888
+ .option("--description <text>", "Project description")
1889
+ .option("--stories-file <path>", "PRD JSON file with userStories")
1890
+ .option("--stories-json <json>", "Story array or JSON object with userStories")
1891
+ .option("--repos-json <json>", "Repository array, such as [{path,branch}]")
1892
+ .option("--repo <path[@branch]>", "Repository binding (repeatable)", collectRepeatable)
1893
+ .option("--channel <channelId>", "Bind the project to an existing company or project channel")
1894
+ .option("--create", "Create the Board view when the GET is a 404")
1895
+ .option("--reset-status", "Overwrite live story status from the PRD (prints a one-line summary of changes)")
1896
+ .option("--json", "Print machine-readable JSON")
1897
+ .action((projectId, opts) => wrap(() => runProjectSet(projectId, opts))());
1898
+ project
1899
+ .command("ensure <projectId>")
1900
+ .description("Idempotently register a PRD on the Board and verify the view")
1901
+ .requiredOption("--company <slug|uid>", "Company slug or cloud uid")
1902
+ .requiredOption("--stories-file <path>", "PRD JSON file with userStories and metadata.repos")
1903
+ .option("--dry-run", "Read the current Board and print computed story statuses without writing")
1904
+ .option("--json", "Print {projectId, threadId, channelId, version, stories}")
1905
+ .action((projectId, opts) => wrap(() => runProjectEnsure(projectId, opts))());
1906
+ project
1907
+ .command("register <projectId>")
1908
+ .description("Register an existing Board and bind its project channel; use project ensure to create or repair a Board")
1909
+ .requiredOption("--company <slug|uid>", "Company slug or cloud uid")
1910
+ .option("--channel <channelId>", "Bind the project to an existing company or project channel")
1911
+ .option("--json", "Print machine-readable JSON")
1912
+ .action((projectId, opts) => wrap(() => runProjectRegister(projectId, opts))());
1004
1913
  mesh
1005
1914
  .command("doctor")
1006
1915
  .description("Warm ~/.hq/work-mesh/cache from hq-pro (directory, inbox, pair DMs). Not `hq doctor`.")
@@ -1030,12 +1939,29 @@ export function registerMeshCommand(program) {
1030
1939
  context
1031
1940
  .command("backfill-held")
1032
1941
  .description("Reconcile ENDED sessions whose held events lack a company so the daemon re-attributes the backlog (explicit, opt-in; no fleet fan-out)")
1033
- .option("--dry-run", "Report what would be reconciled; write nothing, no network")
1942
+ .option("--dry-run", "Report what would be reconciled; write nothing or deliver events")
1034
1943
  .option("--offline", "Reconcile outbox-only (no candidates/register network)")
1035
1944
  .option("--limit <n>", "Cap sessions processed (default 0 = no cap)")
1036
- .option("--company <slug>", "Optional non-forcing company hint (resolver default still wins)")
1945
+ .option("--company <slug>", "Optional non-forcing company hint")
1946
+ .option("--use-device-default", "Opt in to historical repair using the device default (lower-confidence attribution)")
1037
1947
  .option("--json", "Print machine-readable JSON")
1038
1948
  .action((opts) => wrap(() => runContextBackfillHeld(opts))());
1949
+ context
1950
+ .command("bind-project")
1951
+ .description("Bind this session to a project id, a numbered candidate, or new <slug>")
1952
+ .argument("<target>", "Project id, candidate number, or new")
1953
+ .argument("[slug]", "Project slug when target is new")
1954
+ .requiredOption("--session <sid>", "Canonical session id")
1955
+ .option("--company <slug|uid>", "Company override when creating a Board")
1956
+ .option("--json", "Print machine-readable JSON")
1957
+ .action((target, slug, opts) => wrap(() => runBindProject(target, { ...opts, slug }))());
1958
+ context
1959
+ .command("prd-sync")
1960
+ .description("Emit task_status for PRD story passes/status changes on a bound session")
1961
+ .requiredOption("--session <sid>", "Canonical session id")
1962
+ .requiredOption("--file <path>", "prd.json written by the bound session")
1963
+ .option("--json", "Print machine-readable JSON")
1964
+ .action((opts) => wrap(() => runPrdSync(opts))());
1039
1965
  context
1040
1966
  .command("organize")
1041
1967
  .description("List or submit one-time project/task decisions (US-007B / US-005B)")
@@ -1085,10 +2011,11 @@ export function registerMeshCommand(program) {
1085
2011
  .action((opts) => wrap(() => runContextDefaultGet(opts))());
1086
2012
  def
1087
2013
  .command("set")
1088
- .description("Set the device default company slug (unlocked when migration is true for every membership)")
2014
+ .description("Set the device default company slug after verifying membership")
1089
2015
  .argument("<slug>", "Company slug")
1090
- .option("--allow-without-migration", "Bypass DEFAULT_COMPANY_LOCKED with a warning")
1091
- .option("--company <slug|uid>", "Deprecated no-op; unlock probes every active membership")
2016
+ .option("--allow-without-migration", "Deprecated compatibility no-op; selected-company membership is always verified")
2017
+ .option("--repair-held-with-default", "Persist opt-in for lower-confidence historical held-session repair")
2018
+ .option("--company <slug|uid>", "Deprecated no-op; the selected company is verified directly")
1092
2019
  .option("--json", "Print machine-readable JSON")
1093
2020
  .action((slug, opts) => wrap(() => runContextDefaultSet(slug, opts))());
1094
2021
  def
@@ -1102,6 +2029,19 @@ export function registerMeshCommand(program) {
1102
2029
  .argument("<sessionId>", "Canonical session id")
1103
2030
  .option("--machine", "Write exactly one ContextResult JSON line to stdout")
1104
2031
  .action((sessionId, opts) => wrap(() => runContextUntracked(sessionId, opts))());
2032
+ const contract = mesh
2033
+ .command("contract")
2034
+ .description("Print versioned work-mesh contracts for other repositories");
2035
+ contract
2036
+ .command("preflight")
2037
+ .description("Offline preflight ContextResult contract (contracts/preflight/v1)")
2038
+ .option("--print-fixtures", "Write the fixture file JSON to stdout")
2039
+ .action((opts) => wrap(async () => {
2040
+ if (!opts.printFixtures) {
2041
+ throw new Error("Pass --print-fixtures. The stable package path is contracts/preflight/v1/fixtures.json.");
2042
+ }
2043
+ process.stdout.write(`${JSON.stringify(buildPreflightFixtures(), null, 2)}\n`);
2044
+ })());
1105
2045
  const session = mesh
1106
2046
  .command("session")
1107
2047
  .description("Local session-event spool: enqueue (printf-compatible), flush, and live status");
@@ -1148,11 +2088,14 @@ export function registerMeshCommand(program) {
1148
2088
  daemon
1149
2089
  .command("run")
1150
2090
  .description("Start the single-instance daemon (pid lock, spool watch, presence)")
1151
- .action(() => wrap(() => runDaemonRun())());
2091
+ .option("--hq-root <path>", "HQ tree root (else HQ_ROOT / persisted trusted roots); the Windows task passes this explicitly")
2092
+ .action((opts) => wrap(() => runDaemonRun(opts))());
1152
2093
  daemon
1153
2094
  .command("install")
1154
- .description("Install LaunchAgent (macOS) or systemd user unit (Linux)")
2095
+ .description("Install LaunchAgent (macOS), systemd user unit (Linux), or Scheduled Task (Windows)")
1155
2096
  .option("--system-user <user>", "Write a root-owned unit template for agent boxes (e.g. ec2-user)")
2097
+ .option("--hq-root <path>", "HQ root to record for the service (else HQ_ROOT, else the nearest HQ root above cwd)")
2098
+ .option("--if-stale", "Reinstall and restart only when this CLI is newer than the daemon's recorded version")
1156
2099
  .option("--json", "Print machine-readable JSON")
1157
2100
  .action((opts) => wrap(() => runDaemonInstall(opts))());
1158
2101
  daemon
@@ -1171,18 +2114,65 @@ export function registerMeshCommand(program) {
1171
2114
  .option("--json", "Print machine-readable JSON")
1172
2115
  .action((opts) => wrap(() => runDaemonDoctorCmd(opts))());
1173
2116
  }
1174
- async function runDaemonRun() {
1175
- const handle = await runMeshDaemon();
2117
+ async function runDaemonRun(opts = {}) {
2118
+ const hqRoot = opts.hqRoot?.trim() || undefined;
2119
+ const handle = await runMeshDaemon({
2120
+ ...(hqRoot ? { hqRoot } : {}),
2121
+ enableWorkCache: true,
2122
+ });
1176
2123
  // Stay alive until signal handlers call stop + exit.
1177
2124
  await new Promise(() => {
1178
2125
  void handle;
1179
2126
  });
1180
2127
  }
1181
2128
  async function runDaemonInstall(opts) {
2129
+ // `hq daemon` runs mesh on this machine: installing a second unit would run it twice.
2130
+ // An explicit --hq-root is verified the same way as below and saved for the daemon.
2131
+ const explicitRoot = opts.hqRoot ? resolveInstallHqRoot({ explicit: opts.hqRoot }).root : undefined;
2132
+ const handedOff = opts.systemUser
2133
+ ? null
2134
+ : handOffInstallHere(["mesh"], process.env, { hqRoot: explicitRoot, ifStale: opts.ifStale });
2135
+ if (handedOff) {
2136
+ console.log(opts.json ? JSON.stringify({ ok: true, action: "hq-daemon", reinstalled: false, message: handedOff }) : handedOff);
2137
+ return;
2138
+ }
2139
+ // Verified root only: a repo's own .claude/ must never become the daemon's
2140
+ // HQ root (that path is persisted as trusted and used for attribution).
2141
+ const hqRoot = resolveInstallHqRoot({ explicit: opts.hqRoot });
2142
+ const paths = buildInstallPaths({
2143
+ systemUser: opts.systemUser,
2144
+ hqRoot: hqRoot.root,
2145
+ hqRootSource: hqRoot.source,
2146
+ hqBinary: resolveRunningCliEntry(),
2147
+ nodeBinary: resolveAbsoluteNodeBinary(),
2148
+ });
2149
+ if (opts.ifStale) {
2150
+ const stale = installDaemonIfStale({
2151
+ currentVersion: CLI_VERSION,
2152
+ platform: detectPlatform(),
2153
+ paths,
2154
+ systemUser: opts.systemUser,
2155
+ });
2156
+ if (opts.json) {
2157
+ console.log(JSON.stringify({
2158
+ ok: true,
2159
+ action: stale.reinstalled ? "install" : "unchanged",
2160
+ reinstalled: stale.reinstalled,
2161
+ message: stale.message,
2162
+ hqBinary: paths.hqBinary,
2163
+ nodeBinary: paths.nodeBinary,
2164
+ hqRoot: hqRoot.root,
2165
+ }, null, 2));
2166
+ return;
2167
+ }
2168
+ console.log(stale.message);
2169
+ return;
2170
+ }
1182
2171
  const result = installDaemonService({
1183
2172
  platform: detectPlatform(),
1184
- paths: buildInstallPaths({ systemUser: opts.systemUser }),
2173
+ paths,
1185
2174
  systemUser: opts.systemUser,
2175
+ run: defaultRunCommand,
1186
2176
  });
1187
2177
  if (opts.json) {
1188
2178
  console.log(JSON.stringify({
@@ -1191,10 +2181,15 @@ async function runDaemonInstall(opts) {
1191
2181
  platform: result.platform,
1192
2182
  dest: result.dest,
1193
2183
  message: result.message,
2184
+ hqRoot: hqRoot.root,
2185
+ hqRootSource: hqRoot.source,
2186
+ ...(result.notice ? { notice: result.notice } : {}),
1194
2187
  }, null, 2));
1195
2188
  return;
1196
2189
  }
1197
2190
  console.log(result.message);
2191
+ if (result.notice)
2192
+ console.log(result.notice);
1198
2193
  }
1199
2194
  async function runDaemonUninstall(opts) {
1200
2195
  const result = uninstallDaemonService({
@@ -1213,12 +2208,14 @@ async function runDaemonUninstall(opts) {
1213
2208
  }
1214
2209
  console.log(result.message);
1215
2210
  }
1216
- async function runDaemonStatus(opts) {
2211
+ export async function runDaemonStatus(opts, deps = {}) {
2212
+ const paths = deps.paths ?? buildInstallPaths({});
1217
2213
  const result = daemonServiceStatus({
1218
- platform: detectPlatform(),
1219
- paths: buildInstallPaths({}),
2214
+ platform: deps.platform ?? detectPlatform(),
2215
+ paths,
2216
+ isLoaded: daemonServiceIsLoaded(deps.run ?? defaultRunCommand, deps.uid),
1220
2217
  });
1221
- const state = readDaemonState(daemonDir());
2218
+ const state = readDaemonState(paths.daemonDir);
1222
2219
  const presenceRefusal = state?.presenceRefusal ?? null;
1223
2220
  if (opts.json) {
1224
2221
  console.log(JSON.stringify({
@@ -1228,12 +2225,21 @@ async function runDaemonStatus(opts) {
1228
2225
  running: result.running ?? false,
1229
2226
  dest: result.dest,
1230
2227
  message: result.message,
2228
+ ...(result.lastResult !== undefined ? { lastResult: result.lastResult } : {}),
2229
+ ...(result.lastRunFailed !== undefined ? { lastRunFailed: result.lastRunFailed } : {}),
2230
+ ...(result.recordedHqRoot !== undefined ? { hqRoot: result.recordedHqRoot } : {}),
2231
+ ...(result.rootValid !== undefined ? { rootValid: result.rootValid } : {}),
2232
+ ...(result.notice ? { notice: result.notice } : {}),
1231
2233
  mqttState: state?.mqttState,
1232
2234
  presenceRefusal,
1233
2235
  }, null, 2));
1234
2236
  return;
1235
2237
  }
1236
2238
  console.log(result.message);
2239
+ if (result.recordedHqRoot)
2240
+ console.log(`hq root: ${result.recordedHqRoot}`);
2241
+ if (result.notice)
2242
+ console.log(result.notice);
1237
2243
  if (presenceRefusal) {
1238
2244
  console.log(`presence refusal: ${presenceRefusal.code} (HTTP ${presenceRefusal.status}); next retry at ${presenceRefusal.nextRetryAt}`);
1239
2245
  }
@@ -1242,7 +2248,11 @@ async function runDaemonStatus(opts) {
1242
2248
  }
1243
2249
  }
1244
2250
  async function runDaemonDoctorCmd(opts) {
1245
- const report = collectDaemonDoctor();
2251
+ // Same predicate as install: a repo's .claude/ is not an HQ root. Doctor
2252
+ // only reads, so an unresolvable root is reported as absent, not fatal.
2253
+ const report = collectDaemonDoctor({
2254
+ hqRoot: process.env.HQ_ROOT?.trim() || findAncestorHqRoot(process.cwd()) || undefined,
2255
+ });
1246
2256
  if (opts.json) {
1247
2257
  console.log(JSON.stringify({ ok: !report.unhealthy, ...report }, null, 2));
1248
2258
  return;