@openrig/cli 0.4.6 → 0.4.8

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 (472) hide show
  1. package/daemon/assets/guidance/CULTURE-default.md +19 -0
  2. package/daemon/assets/guidance/openrig-start.md +20 -5
  3. package/daemon/assets/plugins/openrig-core/README.md +1 -1
  4. package/daemon/assets/plugins/openrig-core/skills/applying-a-permission-policy/SKILL.md +120 -0
  5. package/daemon/assets/plugins/openrig-core/skills/claude-compaction-restore/SKILL.md +9 -6
  6. package/daemon/assets/plugins/openrig-core/skills/claude-compaction-restore/scripts/precompact-hook.mjs +11 -72
  7. package/daemon/assets/plugins/openrig-core/skills/claude-compaction-restore/scripts/restore-from-jsonl.mjs +0 -0
  8. package/daemon/assets/plugins/openrig-core/skills/delegating-work/SKILL.md +43 -0
  9. package/daemon/assets/plugins/openrig-core/skills/forming-an-openrig-mental-model/SKILL.md +36 -22
  10. package/daemon/assets/plugins/openrig-core/skills/messaging-the-human/SKILL.md +108 -0
  11. package/daemon/assets/plugins/openrig-core/skills/mission-slice-sop/SKILL.md +7 -13
  12. package/daemon/assets/plugins/openrig-core/skills/openrig-skills/SKILL.md +88 -0
  13. package/daemon/assets/plugins/openrig-core/skills/openrig-user/SKILL.md +189 -105
  14. package/daemon/assets/plugins/openrig-core/skills/queue-handoff/SKILL.md +26 -9
  15. package/daemon/assets/plugins/openrig-core/skills/seat-continuity-and-handover/SKILL.md +11 -9
  16. package/daemon/assets/plugins/openrig-core/skills/session-compaction-and-restore/SKILL.md +162 -0
  17. package/daemon/assets/plugins/openrig-core/skills/software-for-agents/SKILL.md +165 -0
  18. package/daemon/dist/adapters/claude-code-adapter.d.ts +0 -9
  19. package/daemon/dist/adapters/claude-code-adapter.d.ts.map +1 -1
  20. package/daemon/dist/adapters/claude-code-adapter.js +13 -46
  21. package/daemon/dist/adapters/claude-code-adapter.js.map +1 -1
  22. package/daemon/dist/adapters/claude-resume.d.ts +1 -1
  23. package/daemon/dist/adapters/claude-resume.d.ts.map +1 -1
  24. package/daemon/dist/adapters/claude-resume.js +8 -2
  25. package/daemon/dist/adapters/claude-resume.js.map +1 -1
  26. package/daemon/dist/adapters/cmux-transport.d.ts.map +1 -1
  27. package/daemon/dist/adapters/cmux-transport.js +8 -1
  28. package/daemon/dist/adapters/cmux-transport.js.map +1 -1
  29. package/daemon/dist/adapters/cmux.d.ts +9 -0
  30. package/daemon/dist/adapters/cmux.d.ts.map +1 -1
  31. package/daemon/dist/adapters/cmux.js +21 -0
  32. package/daemon/dist/adapters/cmux.js.map +1 -1
  33. package/daemon/dist/adapters/codex-resume.d.ts +1 -1
  34. package/daemon/dist/adapters/codex-resume.d.ts.map +1 -1
  35. package/daemon/dist/adapters/codex-resume.js +4 -2
  36. package/daemon/dist/adapters/codex-resume.js.map +1 -1
  37. package/daemon/dist/adapters/codex-runtime-adapter.d.ts +3 -0
  38. package/daemon/dist/adapters/codex-runtime-adapter.d.ts.map +1 -1
  39. package/daemon/dist/adapters/codex-runtime-adapter.js +30 -9
  40. package/daemon/dist/adapters/codex-runtime-adapter.js.map +1 -1
  41. package/daemon/dist/adapters/pi-resume.d.ts +1 -1
  42. package/daemon/dist/adapters/pi-resume.d.ts.map +1 -1
  43. package/daemon/dist/adapters/pi-resume.js +7 -2
  44. package/daemon/dist/adapters/pi-resume.js.map +1 -1
  45. package/daemon/dist/adapters/pi-runtime-adapter.d.ts.map +1 -1
  46. package/daemon/dist/adapters/pi-runtime-adapter.js +4 -1
  47. package/daemon/dist/adapters/pi-runtime-adapter.js.map +1 -1
  48. package/daemon/dist/adapters/yolo-mode.d.ts +23 -0
  49. package/daemon/dist/adapters/yolo-mode.d.ts.map +1 -0
  50. package/daemon/dist/adapters/yolo-mode.js +49 -0
  51. package/daemon/dist/adapters/yolo-mode.js.map +1 -0
  52. package/daemon/dist/build-info.js +3 -3
  53. package/daemon/dist/db/migrations/055_node_permission_policy.d.ts +13 -0
  54. package/daemon/dist/db/migrations/055_node_permission_policy.d.ts.map +1 -0
  55. package/daemon/dist/db/migrations/055_node_permission_policy.js +17 -0
  56. package/daemon/dist/db/migrations/055_node_permission_policy.js.map +1 -0
  57. package/daemon/dist/db/migrations/056_rig_permission_policy.d.ts +13 -0
  58. package/daemon/dist/db/migrations/056_rig_permission_policy.d.ts.map +1 -0
  59. package/daemon/dist/db/migrations/056_rig_permission_policy.js +17 -0
  60. package/daemon/dist/db/migrations/056_rig_permission_policy.js.map +1 -0
  61. package/daemon/dist/db/migrations/057_node_policy_provenance.d.ts +19 -0
  62. package/daemon/dist/db/migrations/057_node_policy_provenance.d.ts.map +1 -0
  63. package/daemon/dist/db/migrations/057_node_policy_provenance.js +26 -0
  64. package/daemon/dist/db/migrations/057_node_policy_provenance.js.map +1 -0
  65. package/daemon/dist/db/migrations/058_rig_policy_provenance.d.ts +15 -0
  66. package/daemon/dist/db/migrations/058_rig_policy_provenance.d.ts.map +1 -0
  67. package/daemon/dist/db/migrations/058_rig_policy_provenance.js +22 -0
  68. package/daemon/dist/db/migrations/058_rig_policy_provenance.js.map +1 -0
  69. package/daemon/dist/domain/builtin-policy-reference.d.ts +13 -0
  70. package/daemon/dist/domain/builtin-policy-reference.d.ts.map +1 -0
  71. package/daemon/dist/domain/builtin-policy-reference.js +58 -0
  72. package/daemon/dist/domain/builtin-policy-reference.js.map +1 -0
  73. package/daemon/dist/domain/claude-compaction-enforcer.d.ts +3 -0
  74. package/daemon/dist/domain/claude-compaction-enforcer.d.ts.map +1 -1
  75. package/daemon/dist/domain/claude-compaction-enforcer.js +19 -3
  76. package/daemon/dist/domain/claude-compaction-enforcer.js.map +1 -1
  77. package/daemon/dist/domain/cmux-layout-service.d.ts +36 -0
  78. package/daemon/dist/domain/cmux-layout-service.d.ts.map +1 -1
  79. package/daemon/dist/domain/cmux-layout-service.js +100 -28
  80. package/daemon/dist/domain/cmux-layout-service.js.map +1 -1
  81. package/daemon/dist/domain/context-monitor.d.ts +2 -0
  82. package/daemon/dist/domain/context-monitor.d.ts.map +1 -1
  83. package/daemon/dist/domain/context-monitor.js +14 -0
  84. package/daemon/dist/domain/context-monitor.js.map +1 -1
  85. package/daemon/dist/domain/feed/attention-aggregator.js +1 -1
  86. package/daemon/dist/domain/feed/attention-aggregator.js.map +1 -1
  87. package/daemon/dist/domain/hosts/hosts-registry-reader.d.ts.map +1 -1
  88. package/daemon/dist/domain/hosts/hosts-registry-reader.js +12 -10
  89. package/daemon/dist/domain/hosts/hosts-registry-reader.js.map +1 -1
  90. package/daemon/dist/domain/hosts/hosts-registry-writer.d.ts.map +1 -1
  91. package/daemon/dist/domain/hosts/hosts-registry-writer.js +3 -2
  92. package/daemon/dist/domain/hosts/hosts-registry-writer.js.map +1 -1
  93. package/daemon/dist/domain/hosts/read-through.js +1 -1
  94. package/daemon/dist/domain/hosts/read-through.js.map +1 -1
  95. package/daemon/dist/domain/hosts/remote-daemon-http.d.ts.map +1 -1
  96. package/daemon/dist/domain/hosts/remote-daemon-http.js +8 -5
  97. package/daemon/dist/domain/hosts/remote-daemon-http.js.map +1 -1
  98. package/daemon/dist/domain/native-resume-probe.d.ts +1 -1
  99. package/daemon/dist/domain/native-resume-probe.d.ts.map +1 -1
  100. package/daemon/dist/domain/native-resume-probe.js +11 -4
  101. package/daemon/dist/domain/native-resume-probe.js.map +1 -1
  102. package/daemon/dist/domain/node-inventory.d.ts +3 -12
  103. package/daemon/dist/domain/node-inventory.d.ts.map +1 -1
  104. package/daemon/dist/domain/node-inventory.js +57 -15
  105. package/daemon/dist/domain/node-inventory.js.map +1 -1
  106. package/daemon/dist/domain/permission-policy/policy-ref.d.ts +89 -0
  107. package/daemon/dist/domain/permission-policy/policy-ref.d.ts.map +1 -0
  108. package/daemon/dist/domain/permission-policy/policy-ref.js +171 -0
  109. package/daemon/dist/domain/permission-policy/policy-ref.js.map +1 -0
  110. package/daemon/dist/domain/permission-policy/policy-spec.d.ts +34 -0
  111. package/daemon/dist/domain/permission-policy/policy-spec.d.ts.map +1 -0
  112. package/daemon/dist/domain/permission-policy/policy-spec.js +106 -0
  113. package/daemon/dist/domain/permission-policy/policy-spec.js.map +1 -0
  114. package/daemon/dist/domain/plugin-vendor-service.d.ts +2 -0
  115. package/daemon/dist/domain/plugin-vendor-service.d.ts.map +1 -1
  116. package/daemon/dist/domain/plugin-vendor-service.js +23 -0
  117. package/daemon/dist/domain/plugin-vendor-service.js.map +1 -1
  118. package/daemon/dist/domain/projection-lane.d.ts +7 -0
  119. package/daemon/dist/domain/projection-lane.d.ts.map +1 -0
  120. package/daemon/dist/domain/projection-lane.js +28 -0
  121. package/daemon/dist/domain/projection-lane.js.map +1 -0
  122. package/daemon/dist/domain/ps-projection.d.ts +19 -0
  123. package/daemon/dist/domain/ps-projection.d.ts.map +1 -1
  124. package/daemon/dist/domain/ps-projection.js +46 -6
  125. package/daemon/dist/domain/ps-projection.js.map +1 -1
  126. package/daemon/dist/domain/queue-repository.d.ts +14 -10
  127. package/daemon/dist/domain/queue-repository.d.ts.map +1 -1
  128. package/daemon/dist/domain/queue-repository.js +33 -12
  129. package/daemon/dist/domain/queue-repository.js.map +1 -1
  130. package/daemon/dist/domain/restore-orchestrator.d.ts +14 -0
  131. package/daemon/dist/domain/restore-orchestrator.d.ts.map +1 -1
  132. package/daemon/dist/domain/restore-orchestrator.js +90 -6
  133. package/daemon/dist/domain/restore-orchestrator.js.map +1 -1
  134. package/daemon/dist/domain/review/compose.d.ts +77 -4
  135. package/daemon/dist/domain/review/compose.d.ts.map +1 -1
  136. package/daemon/dist/domain/review/compose.js +152 -16
  137. package/daemon/dist/domain/review/compose.js.map +1 -1
  138. package/daemon/dist/domain/review/fleet-compose.js +1 -1
  139. package/daemon/dist/domain/review/fleet-compose.js.map +1 -1
  140. package/daemon/dist/domain/review/gather.d.ts +1 -1
  141. package/daemon/dist/domain/review/gather.d.ts.map +1 -1
  142. package/daemon/dist/domain/review/gather.js +92 -67
  143. package/daemon/dist/domain/review/gather.js.map +1 -1
  144. package/daemon/dist/domain/review/proof-io.d.ts +2 -0
  145. package/daemon/dist/domain/review/proof-io.d.ts.map +1 -0
  146. package/daemon/dist/domain/review/proof-io.js +38 -0
  147. package/daemon/dist/domain/review/proof-io.js.map +1 -0
  148. package/daemon/dist/domain/rig-expansion-service.d.ts.map +1 -1
  149. package/daemon/dist/domain/rig-expansion-service.js +10 -1
  150. package/daemon/dist/domain/rig-expansion-service.js.map +1 -1
  151. package/daemon/dist/domain/rig-repository.d.ts +45 -0
  152. package/daemon/dist/domain/rig-repository.d.ts.map +1 -1
  153. package/daemon/dist/domain/rig-repository.js +75 -1
  154. package/daemon/dist/domain/rig-repository.js.map +1 -1
  155. package/daemon/dist/domain/rigspec-codec.d.ts.map +1 -1
  156. package/daemon/dist/domain/rigspec-codec.js +6 -0
  157. package/daemon/dist/domain/rigspec-codec.js.map +1 -1
  158. package/daemon/dist/domain/rigspec-exporter.d.ts.map +1 -1
  159. package/daemon/dist/domain/rigspec-exporter.js +8 -0
  160. package/daemon/dist/domain/rigspec-exporter.js.map +1 -1
  161. package/daemon/dist/domain/rigspec-instantiator.d.ts +18 -1
  162. package/daemon/dist/domain/rigspec-instantiator.d.ts.map +1 -1
  163. package/daemon/dist/domain/rigspec-instantiator.js +202 -10
  164. package/daemon/dist/domain/rigspec-instantiator.js.map +1 -1
  165. package/daemon/dist/domain/rigspec-preflight.d.ts +11 -0
  166. package/daemon/dist/domain/rigspec-preflight.d.ts.map +1 -1
  167. package/daemon/dist/domain/rigspec-preflight.js +35 -1
  168. package/daemon/dist/domain/rigspec-preflight.js.map +1 -1
  169. package/daemon/dist/domain/rigspec-schema.d.ts.map +1 -1
  170. package/daemon/dist/domain/rigspec-schema.js +25 -0
  171. package/daemon/dist/domain/rigspec-schema.js.map +1 -1
  172. package/daemon/dist/domain/runtime-adapter.d.ts +5 -0
  173. package/daemon/dist/domain/runtime-adapter.d.ts.map +1 -1
  174. package/daemon/dist/domain/runtime-adapter.js.map +1 -1
  175. package/daemon/dist/domain/scope/plan-lock-artifacts.d.ts +8 -0
  176. package/daemon/dist/domain/scope/plan-lock-artifacts.d.ts.map +1 -0
  177. package/daemon/dist/domain/scope/plan-lock-artifacts.js +57 -0
  178. package/daemon/dist/domain/scope/plan-lock-artifacts.js.map +1 -0
  179. package/daemon/dist/domain/scope/scaffold-placeholder.d.ts +38 -0
  180. package/daemon/dist/domain/scope/scaffold-placeholder.d.ts.map +1 -0
  181. package/daemon/dist/domain/scope/scaffold-placeholder.js +98 -0
  182. package/daemon/dist/domain/scope/scaffold-placeholder.js.map +1 -0
  183. package/daemon/dist/domain/scope/scope-approve.d.ts.map +1 -1
  184. package/daemon/dist/domain/scope/scope-approve.js +22 -1
  185. package/daemon/dist/domain/scope/scope-approve.js.map +1 -1
  186. package/daemon/dist/domain/scope/scope-audit.d.ts.map +1 -1
  187. package/daemon/dist/domain/scope/scope-audit.js +57 -20
  188. package/daemon/dist/domain/scope/scope-audit.js.map +1 -1
  189. package/daemon/dist/domain/seat-handover-service.d.ts.map +1 -1
  190. package/daemon/dist/domain/seat-handover-service.js +7 -1
  191. package/daemon/dist/domain/seat-handover-service.js.map +1 -1
  192. package/daemon/dist/domain/session-transport.d.ts +17 -0
  193. package/daemon/dist/domain/session-transport.d.ts.map +1 -1
  194. package/daemon/dist/domain/session-transport.js +44 -0
  195. package/daemon/dist/domain/session-transport.js.map +1 -1
  196. package/daemon/dist/domain/slices/qitem-membership.d.ts +17 -0
  197. package/daemon/dist/domain/slices/qitem-membership.d.ts.map +1 -0
  198. package/daemon/dist/domain/slices/qitem-membership.js +60 -0
  199. package/daemon/dist/domain/slices/qitem-membership.js.map +1 -0
  200. package/daemon/dist/domain/slices/slice-detail-projector.d.ts +5 -0
  201. package/daemon/dist/domain/slices/slice-detail-projector.d.ts.map +1 -1
  202. package/daemon/dist/domain/slices/slice-detail-projector.js +157 -11
  203. package/daemon/dist/domain/slices/slice-detail-projector.js.map +1 -1
  204. package/daemon/dist/domain/slices/slice-indexer.d.ts +86 -0
  205. package/daemon/dist/domain/slices/slice-indexer.d.ts.map +1 -1
  206. package/daemon/dist/domain/slices/slice-indexer.js +422 -45
  207. package/daemon/dist/domain/slices/slice-indexer.js.map +1 -1
  208. package/daemon/dist/domain/startup-orchestrator.d.ts +9 -0
  209. package/daemon/dist/domain/startup-orchestrator.d.ts.map +1 -1
  210. package/daemon/dist/domain/startup-orchestrator.js +71 -3
  211. package/daemon/dist/domain/startup-orchestrator.js.map +1 -1
  212. package/daemon/dist/domain/successor-session-launcher.d.ts +4 -0
  213. package/daemon/dist/domain/successor-session-launcher.d.ts.map +1 -1
  214. package/daemon/dist/domain/successor-session-launcher.js +2 -0
  215. package/daemon/dist/domain/successor-session-launcher.js.map +1 -1
  216. package/daemon/dist/domain/terminal/cmux-provider-adapter.d.ts +12 -11
  217. package/daemon/dist/domain/terminal/cmux-provider-adapter.d.ts.map +1 -1
  218. package/daemon/dist/domain/terminal/cmux-provider-adapter.js +61 -28
  219. package/daemon/dist/domain/terminal/cmux-provider-adapter.js.map +1 -1
  220. package/daemon/dist/domain/terminal/herdr-adapter.d.ts +27 -10
  221. package/daemon/dist/domain/terminal/herdr-adapter.d.ts.map +1 -1
  222. package/daemon/dist/domain/terminal/herdr-adapter.js +74 -33
  223. package/daemon/dist/domain/terminal/herdr-adapter.js.map +1 -1
  224. package/daemon/dist/domain/transcript-capture.d.ts +3 -0
  225. package/daemon/dist/domain/transcript-capture.d.ts.map +1 -1
  226. package/daemon/dist/domain/transcript-capture.js +28 -0
  227. package/daemon/dist/domain/transcript-capture.js.map +1 -1
  228. package/daemon/dist/domain/transcript-store.d.ts +10 -0
  229. package/daemon/dist/domain/transcript-store.d.ts.map +1 -1
  230. package/daemon/dist/domain/transcript-store.js +26 -0
  231. package/daemon/dist/domain/transcript-store.js.map +1 -1
  232. package/daemon/dist/domain/types.d.ts +21 -0
  233. package/daemon/dist/domain/types.d.ts.map +1 -1
  234. package/daemon/dist/domain/types.js.map +1 -1
  235. package/daemon/dist/domain/workspace/default-workspace-scaffold.d.ts.map +1 -1
  236. package/daemon/dist/domain/workspace/default-workspace-scaffold.js +9 -4
  237. package/daemon/dist/domain/workspace/default-workspace-scaffold.js.map +1 -1
  238. package/daemon/dist/domain/workspace/workspace-doctor.js +1 -1
  239. package/daemon/dist/domain/workspace/workspace-doctor.js.map +1 -1
  240. package/daemon/dist/routes/agent-images.d.ts.map +1 -1
  241. package/daemon/dist/routes/agent-images.js +2 -0
  242. package/daemon/dist/routes/agent-images.js.map +1 -1
  243. package/daemon/dist/routes/mission-control.js +1 -1
  244. package/daemon/dist/routes/mission-control.js.map +1 -1
  245. package/daemon/dist/routes/missions.d.ts +7 -0
  246. package/daemon/dist/routes/missions.d.ts.map +1 -1
  247. package/daemon/dist/routes/missions.js +6 -1
  248. package/daemon/dist/routes/missions.js.map +1 -1
  249. package/daemon/dist/routes/ps.d.ts.map +1 -1
  250. package/daemon/dist/routes/ps.js +5 -1
  251. package/daemon/dist/routes/ps.js.map +1 -1
  252. package/daemon/dist/routes/queue.d.ts.map +1 -1
  253. package/daemon/dist/routes/queue.js +9 -2
  254. package/daemon/dist/routes/queue.js.map +1 -1
  255. package/daemon/dist/routes/rigs.d.ts.map +1 -1
  256. package/daemon/dist/routes/rigs.js +29 -10
  257. package/daemon/dist/routes/rigs.js.map +1 -1
  258. package/daemon/dist/routes/scope-audit.d.ts.map +1 -1
  259. package/daemon/dist/routes/scope-audit.js +141 -135
  260. package/daemon/dist/routes/scope-audit.js.map +1 -1
  261. package/daemon/dist/routes/sessions.js +2 -1
  262. package/daemon/dist/routes/sessions.js.map +1 -1
  263. package/daemon/dist/routes/slices.d.ts.map +1 -1
  264. package/daemon/dist/routes/slices.js +48 -38
  265. package/daemon/dist/routes/slices.js.map +1 -1
  266. package/daemon/dist/routes/transcripts.d.ts.map +1 -1
  267. package/daemon/dist/routes/transcripts.js +62 -33
  268. package/daemon/dist/routes/transcripts.js.map +1 -1
  269. package/daemon/dist/startup.d.ts.map +1 -1
  270. package/daemon/dist/startup.js +42 -12
  271. package/daemon/dist/startup.js.map +1 -1
  272. package/daemon/docs/reference/agent-startup-guide.md +1 -0
  273. package/daemon/docs/reference/rig-spec.md +19 -0
  274. package/daemon/policies/builtin/locked.policy.md +24 -0
  275. package/daemon/policies/builtin/open.policy.md +24 -0
  276. package/daemon/policies/builtin/standard.policy.md +25 -0
  277. package/daemon/policies/builtin/yolo.policy.md +20 -0
  278. package/daemon/policies/examples/my-cautious-dev.policy.md +40 -0
  279. package/daemon/specs/agents/apps/vault-specialist/agent.yaml +2 -1
  280. package/daemon/specs/agents/conveyor/builder/agent.yaml +2 -1
  281. package/daemon/specs/agents/conveyor/lead/agent.yaml +2 -1
  282. package/daemon/specs/agents/conveyor/planner/agent.yaml +2 -1
  283. package/daemon/specs/agents/conveyor/reviewer/agent.yaml +2 -1
  284. package/daemon/specs/agents/design/product-designer/agent.yaml +12 -2
  285. package/daemon/specs/agents/development/implementer/agent.yaml +12 -2
  286. package/daemon/specs/agents/development/qa/agent.yaml +12 -2
  287. package/daemon/specs/agents/development/qa/guidance/role.md +1 -0
  288. package/daemon/specs/agents/factory-rsi/dogfood/agent.yaml +2 -1
  289. package/daemon/specs/agents/factory-rsi/release-manager/agent.yaml +2 -1
  290. package/daemon/specs/agents/orchestration/orchestrator/agent.yaml +12 -2
  291. package/daemon/specs/agents/product-management/pm/agent.yaml +1 -2
  292. package/daemon/specs/agents/research/analyst/agent.yaml +2 -1
  293. package/daemon/specs/agents/research/synthesizer/agent.yaml +2 -1
  294. package/daemon/specs/agents/review/independent-reviewer/agent.yaml +12 -2
  295. package/daemon/specs/agents/shared/agent.yaml +5 -8
  296. package/daemon/specs/agents/shared/runtime/claude-settings.fragment.json +1 -8
  297. package/daemon/specs/agents/shared/skills/core/agent-starters/SKILL.md +132 -0
  298. package/daemon/{assets/plugins/openrig-core/skills → specs/agents/shared/skills/core}/agent-startup-and-context-ingestion/SKILL.md +27 -19
  299. package/daemon/specs/agents/shared/skills/core/attention-queue/SKILL.md +264 -0
  300. package/daemon/specs/agents/shared/skills/core/cross-host-rig-commands/SKILL.md +190 -0
  301. package/daemon/specs/agents/shared/skills/core/human-in-the-loop/SKILL.md +104 -0
  302. package/daemon/specs/agents/shared/skills/core/openrig-architect/SKILL.md +23 -8
  303. package/daemon/specs/agents/shared/skills/core/openrig-cmux/SKILL.md +0 -5
  304. package/daemon/specs/agents/shared/skills/core/openrig-herdr/SKILL.md +1 -6
  305. package/daemon/specs/agents/shared/skills/core/openrig-upgrade/SKILL.md +460 -0
  306. package/daemon/specs/agents/shared/skills/core/rig-bundles-and-shareable-artifacts/SKILL.md +101 -0
  307. package/daemon/specs/agents/shared/skills/core/rig-lifecycle/SKILL.md +22 -11
  308. package/daemon/specs/agents/shared/skills/core/session-source-fork/SKILL.md +160 -0
  309. package/daemon/specs/agents/shared/skills/core/specification-system/SKILL.md +103 -0
  310. package/daemon/specs/agents/shared/skills/core/topology-mutation-and-seat-management/SKILL.md +118 -0
  311. package/daemon/specs/agents/shared/skills/core/watchdog/SKILL.md +125 -0
  312. package/daemon/specs/agents/shared/skills/process/brainstorming/OPENRIG.md +3 -3
  313. package/daemon/specs/agents/shared/skills/process/executing-plans/OPENRIG.md +1 -1
  314. package/daemon/specs/agents/shared/skills/process/frontend-design/SKILL.md +6 -3
  315. package/daemon/specs/agents/shared/skills/process/systematic-debugging/find-polluter.sh +0 -0
  316. package/daemon/specs/agents/shared/skills/process/test-driven-development/SKILL.md +1 -1
  317. package/daemon/specs/agents/shared/skills/process/using-superpowers/OPENRIG.md +1 -1
  318. package/daemon/specs/agents/shared/skills/process/verification-before-completion/SKILL.md +13 -2
  319. package/daemon/specs/agents/shared/skills/process/writing-plans/OPENRIG.md +1 -1
  320. package/daemon/specs/rigs/focused/pm-team/CULTURE.md +1 -1
  321. package/daemon/specs/rigs/launch/kernel/agents/advisor/lead/agent.yaml +2 -2
  322. package/daemon/specs/rigs/launch/kernel/agents/advisor/lead/guidance/role.md +5 -4
  323. package/daemon/specs/rigs/launch/kernel/agents/operator/agent/agent.yaml +2 -2
  324. package/daemon/specs/rigs/launch/kernel/agents/operator/agent/guidance/role.md +3 -5
  325. package/daemon/specs/rigs/launch/kernel/agents/queue/worker/agent.yaml +2 -2
  326. package/daemon/specs/rigs/launch/kernel/culture/CULTURE.md +3 -4
  327. package/daemon/specs/rigs/preview/product-team/CULTURE.md +1 -1
  328. package/dist/bin-wrapper.d.ts.map +1 -1
  329. package/dist/bin-wrapper.js +3 -1
  330. package/dist/bin-wrapper.js.map +1 -1
  331. package/dist/build-info.js +3 -3
  332. package/dist/cli-error.d.ts +33 -0
  333. package/dist/cli-error.d.ts.map +1 -0
  334. package/dist/cli-error.js +94 -0
  335. package/dist/cli-error.js.map +1 -0
  336. package/dist/commands/config-init-workspace.js +1 -1
  337. package/dist/commands/doctor.d.ts +1 -1
  338. package/dist/commands/doctor.d.ts.map +1 -1
  339. package/dist/commands/doctor.js +17 -11
  340. package/dist/commands/doctor.js.map +1 -1
  341. package/dist/commands/host.d.ts.map +1 -1
  342. package/dist/commands/host.js +24 -10
  343. package/dist/commands/host.js.map +1 -1
  344. package/dist/commands/proof.js +1 -1
  345. package/dist/commands/proof.js.map +1 -1
  346. package/dist/commands/ps.d.ts.map +1 -1
  347. package/dist/commands/ps.js +16 -2
  348. package/dist/commands/ps.js.map +1 -1
  349. package/dist/commands/queue.d.ts.map +1 -1
  350. package/dist/commands/queue.js +103 -24
  351. package/dist/commands/queue.js.map +1 -1
  352. package/dist/commands/rig.d.ts.map +1 -1
  353. package/dist/commands/rig.js +122 -0
  354. package/dist/commands/rig.js.map +1 -1
  355. package/dist/commands/scope.js +2 -2
  356. package/dist/commands/scope.js.map +1 -1
  357. package/dist/commands/send.d.ts.map +1 -1
  358. package/dist/commands/send.js +118 -24
  359. package/dist/commands/send.js.map +1 -1
  360. package/dist/commands/setup.d.ts +14 -0
  361. package/dist/commands/setup.d.ts.map +1 -1
  362. package/dist/commands/setup.js +131 -8
  363. package/dist/commands/setup.js.map +1 -1
  364. package/dist/commands/slack.d.ts +37 -0
  365. package/dist/commands/slack.d.ts.map +1 -0
  366. package/dist/commands/slack.js +274 -0
  367. package/dist/commands/slack.js.map +1 -0
  368. package/dist/commands/ui.d.ts +1 -0
  369. package/dist/commands/ui.d.ts.map +1 -1
  370. package/dist/commands/ui.js +2 -0
  371. package/dist/commands/ui.js.map +1 -1
  372. package/dist/commands/up.js +1 -1
  373. package/dist/commands/up.js.map +1 -1
  374. package/dist/commands/whoami.d.ts.map +1 -1
  375. package/dist/commands/whoami.js +3 -3
  376. package/dist/commands/whoami.js.map +1 -1
  377. package/dist/daemon-lifecycle.d.ts.map +1 -1
  378. package/dist/daemon-lifecycle.js +45 -14
  379. package/dist/daemon-lifecycle.js.map +1 -1
  380. package/dist/host-registry.d.ts +6 -1
  381. package/dist/host-registry.d.ts.map +1 -1
  382. package/dist/host-registry.js +15 -6
  383. package/dist/host-registry.js.map +1 -1
  384. package/dist/index.d.ts +3 -0
  385. package/dist/index.d.ts.map +1 -1
  386. package/dist/index.js +6 -1
  387. package/dist/index.js.map +1 -1
  388. package/dist/lib/scope/scaffold-placeholder.d.ts +38 -0
  389. package/dist/lib/scope/scaffold-placeholder.d.ts.map +1 -0
  390. package/dist/lib/scope/scaffold-placeholder.js +98 -0
  391. package/dist/lib/scope/scaffold-placeholder.js.map +1 -0
  392. package/dist/lib/scope/scope-audit.d.ts.map +1 -1
  393. package/dist/lib/scope/scope-audit.js +57 -20
  394. package/dist/lib/scope/scope-audit.js.map +1 -1
  395. package/dist/lib/scope-templates/backlog-deprecation.md +1 -1
  396. package/dist/lib/scope-templates/backlog-tech-debt.md +1 -1
  397. package/dist/lib/scope-templates/bug-fix.md +1 -1
  398. package/dist/lib/scope-templates/implementation-prd.md +1 -1
  399. package/dist/lib/scope-templates/mission-notes.md +7 -2
  400. package/dist/lib/scope-templates/mission-placeholder.md +1 -1
  401. package/dist/lib/scope-templates/mission-progress.md +1 -1
  402. package/dist/lib/scope-templates/mission-release.md +1 -1
  403. package/dist/lib/scope-templates/placeholder.md +1 -1
  404. package/dist/lib/scope-templates/proof.md +1 -1
  405. package/dist/lib/scope-templates/release-feature.md +1 -1
  406. package/dist/lib/scope-templates/research.md +1 -1
  407. package/dist/lib/scope-templates/slice-progress.md +1 -1
  408. package/dist/remote-host-ops.d.ts.map +1 -1
  409. package/dist/remote-host-ops.js +2 -2
  410. package/dist/remote-host-ops.js.map +1 -1
  411. package/dist/slack/config.d.ts +41 -0
  412. package/dist/slack/config.d.ts.map +1 -0
  413. package/dist/slack/config.js +60 -0
  414. package/dist/slack/config.js.map +1 -0
  415. package/dist/slack/inbound.d.ts +75 -0
  416. package/dist/slack/inbound.d.ts.map +1 -0
  417. package/dist/slack/inbound.js +133 -0
  418. package/dist/slack/inbound.js.map +1 -0
  419. package/dist/slack/message.d.ts +26 -0
  420. package/dist/slack/message.d.ts.map +1 -0
  421. package/dist/slack/message.js +60 -0
  422. package/dist/slack/message.js.map +1 -0
  423. package/dist/slack/outbound.d.ts +39 -0
  424. package/dist/slack/outbound.d.ts.map +1 -0
  425. package/dist/slack/outbound.js +52 -0
  426. package/dist/slack/outbound.js.map +1 -0
  427. package/dist/slack/queue-bridge.d.ts +56 -0
  428. package/dist/slack/queue-bridge.d.ts.map +1 -0
  429. package/dist/slack/queue-bridge.js +114 -0
  430. package/dist/slack/queue-bridge.js.map +1 -0
  431. package/dist/slack/secrets.d.ts +21 -0
  432. package/dist/slack/secrets.d.ts.map +1 -0
  433. package/dist/slack/secrets.js +73 -0
  434. package/dist/slack/secrets.js.map +1 -0
  435. package/dist/slack/slack-api.d.ts +49 -0
  436. package/dist/slack/slack-api.d.ts.map +1 -0
  437. package/dist/slack/slack-api.js +110 -0
  438. package/dist/slack/slack-api.js.map +1 -0
  439. package/dist/slack/state-store.d.ts +62 -0
  440. package/dist/slack/state-store.d.ts.map +1 -0
  441. package/dist/slack/state-store.js +132 -0
  442. package/dist/slack/state-store.js.map +1 -0
  443. package/package.json +1 -1
  444. package/ui/dist/assets/{index-zrFqS7gL.js → index-DkNi0RT8.js} +184 -184
  445. package/ui/dist/assets/index-N-SdPj-I.css +32 -0
  446. package/ui/dist/index.html +2 -2
  447. package/daemon/assets/plugins/openrig-core/skills/openrig-architect/SKILL.md +0 -361
  448. package/daemon/assets/plugins/openrig-core/skills/openrig-cmux/SKILL.md +0 -86
  449. package/daemon/assets/plugins/openrig-core/skills/openrig-herdr/SKILL.md +0 -158
  450. package/daemon/assets/plugins/openrig-core/skills/openrig-operator/SKILL.md +0 -222
  451. package/daemon/docs/reference/product-factory-vps-runbook.md +0 -132
  452. package/daemon/specs/agents/shared/skills/core/mission-slice-sop/SKILL.md +0 -113
  453. package/daemon/specs/agents/shared/skills/core/openrig-installer/SKILL.md +0 -142
  454. package/daemon/specs/agents/shared/skills/core/openrig-operator/SKILL.md +0 -110
  455. package/daemon/specs/agents/shared/skills/core/openrig-user/SKILL.md +0 -1245
  456. package/daemon/specs/agents/shared/skills/core/openrig-user-settings/SKILL.md +0 -153
  457. package/daemon/specs/agents/shared/skills/pm/backlog-capture/SKILL.md +0 -43
  458. package/daemon/specs/agents/shared/skills/pm/context-builder/SKILL.md +0 -87
  459. package/daemon/specs/agents/shared/skills/pm/exec-summary/SKILL.md +0 -84
  460. package/daemon/specs/agents/shared/skills/pm/office-hours/SKILL.md +0 -129
  461. package/daemon/specs/agents/shared/skills/pm/plan-review/SKILL.md +0 -98
  462. package/daemon/specs/agents/shared/skills/pm/requirements-writer/SKILL.md +0 -113
  463. package/daemon/specs/agents/shared/skills/pm/ui-mockup/SKILL.md +0 -76
  464. package/daemon/specs/agents/shared/skills/pods/development-team/SKILL.md +0 -148
  465. package/daemon/specs/agents/shared/skills/pods/orchestration-team/SKILL.md +0 -266
  466. package/daemon/specs/agents/shared/skills/pods/review-team/SKILL.md +0 -210
  467. package/daemon/specs/agents/shared/skills/process/systematic-debugging/CREATION-LOG.md +0 -119
  468. package/daemon/specs/agents/shared/skills/process/systematic-debugging/test-academic.md +0 -14
  469. package/daemon/specs/agents/shared/skills/process/systematic-debugging/test-pressure-1.md +0 -58
  470. package/daemon/specs/agents/shared/skills/process/systematic-debugging/test-pressure-2.md +0 -68
  471. package/daemon/specs/agents/shared/skills/process/systematic-debugging/test-pressure-3.md +0 -69
  472. package/ui/dist/assets/index-CFqxa0zW.css +0 -32
@@ -0,0 +1,52 @@
1
+ import { listHumanAlerts, showFull } from "./queue-bridge.js";
2
+ import { postWebhook } from "./slack-api.js";
3
+ import { buildOutboundMessage } from "./message.js";
4
+ /**
5
+ * One outbound sweep. Posts every FRESH human alert, marking it seen ONLY after
6
+ * a 200. A failed post is logged loudly and left UNSEEN so the next sweep
7
+ * retries it — never a silent drop. Returns failures so the caller exits
8
+ * non-zero (fail-visible).
9
+ */
10
+ export async function runOutboundOnce(deps) {
11
+ const log = deps.log ?? (() => { });
12
+ const alerts = await listHumanAlerts(deps.runner, deps.filter);
13
+ const seen = deps.seen.load();
14
+ const fresh = alerts.filter((q) => !seen.has(q.qitemId));
15
+ log(`alerts=${alerts.length} fresh=${fresh.length}`);
16
+ const posted = [];
17
+ const failed = [];
18
+ for (const a of fresh) {
19
+ // list bounds bodies (item 9 N+1) — pull the full item for summary+body.
20
+ const full = (await showFull(deps.runner, a.qitemId)) ?? a;
21
+ const payload = buildOutboundMessage({ qitemId: a.qitemId, summary: full.summary ?? a.summary, body: full.body, destinationSession: a.destinationSession }, { sourceLabel: deps.sourceLabel, bodyExcerpt: deps.bodyExcerpt });
22
+ const res = await postWebhook(deps.webhookUrl, payload, deps.fetchImpl);
23
+ if (res.ok) {
24
+ deps.seen.mark(a.qitemId, "posted"); // …seen ONLY after success (item 2)
25
+ posted.push(a.qitemId);
26
+ log(`posted ${a.qitemId}`);
27
+ }
28
+ else {
29
+ // fail-VISIBLE (item 3): loud, NOT marked seen → retried next sweep (no drop).
30
+ log(`ERROR posting ${a.qitemId}: ${res.error}`);
31
+ failed.push({ id: a.qitemId, error: res.error ?? "unknown" });
32
+ }
33
+ }
34
+ if (fresh.length === 0)
35
+ log("nothing new");
36
+ return { freshCount: fresh.length, posted, failed };
37
+ }
38
+ /**
39
+ * Item 9: on ENABLE, seed all currently-active human alerts as history/seen
40
+ * WITHOUT posting, so turning the connector on never replays the backlog.
41
+ * Returns an honest online-status line marking the transition.
42
+ */
43
+ export async function seedBacklogOnEnable(deps) {
44
+ const alerts = await listHumanAlerts(deps.runner, deps.filter);
45
+ const already = deps.seen.load();
46
+ const toSeed = alerts.map((a) => a.qitemId).filter((id) => !already.has(id));
47
+ const seeded = deps.seen.seed(toSeed, "seeded-at-enable");
48
+ const onlineStatus = `slack outbound ENABLED at enable-time: ${seeded} pre-existing alert(s) seeded as history (not reposted); only alerts created after this point will deliver.`;
49
+ deps.log?.(onlineStatus);
50
+ return { seeded, onlineStatus };
51
+ }
52
+ //# sourceMappingURL=outbound.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbound.js","sourceRoot":"","sources":["../../src/slack/outbound.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ export interface RunResult {
2
+ ok: boolean;
3
+ stdout: string;
4
+ stderr: string;
5
+ code: number;
6
+ }
7
+ /** Injectable: run `rig queue <args>` and return the result. */
8
+ export type QueueRunner = (args: string[]) => Promise<RunResult>;
9
+ /**
10
+ * Default runner: spawn the configured `rig` binary. `env` carries OPENRIG_URL
11
+ * (or nothing, letting rig resolve the local daemon); `baseArgs` can inject
12
+ * `--host <id>` for a registered remote queue. No shell — argv only.
13
+ */
14
+ export declare function makeExecRunner(opts: {
15
+ rigBin: string;
16
+ baseArgs?: string[];
17
+ env?: NodeJS.ProcessEnv;
18
+ timeoutMs?: number;
19
+ }): QueueRunner;
20
+ export interface QueueItem {
21
+ qitemId: string;
22
+ destinationSession?: string | null;
23
+ sourceSession?: string | null;
24
+ tags?: string[] | null;
25
+ state?: string | null;
26
+ tier?: string | null;
27
+ summary?: string | null;
28
+ body?: string | null;
29
+ }
30
+ export interface AlertFilterOpts {
31
+ alertTag: string;
32
+ /** Optional explicit human-seat allow-list; when empty, any human-seat destination or human-gate tier matches. */
33
+ destinations?: string[];
34
+ }
35
+ /**
36
+ * PURE: select the qitems that should alert a human. A qitem alerts iff it is
37
+ * active, carries the alert tag, AND targets a human — either an explicit
38
+ * configured destination, a human-seat session name, or tier `human-gate`.
39
+ */
40
+ export declare function filterHumanAlerts(items: QueueItem[], opts: AlertFilterOpts): QueueItem[];
41
+ export declare const QUEUE_LIST_LIMIT = 100000;
42
+ /** Read active human alerts across ALL rigs (the -A scope fix) with a full-backlog limit. */
43
+ export declare function listHumanAlerts(runner: QueueRunner, opts: AlertFilterOpts): Promise<QueueItem[]>;
44
+ /** Full single-item read (list omits/bounds body — item 9 N+1). */
45
+ export declare function showFull(runner: QueueRunner, qitemId: string): Promise<QueueItem | null>;
46
+ export interface CreateQitemInput {
47
+ source: string;
48
+ destination: string;
49
+ summary: string;
50
+ body: string;
51
+ priority?: string;
52
+ tags?: string[];
53
+ }
54
+ /** Create a qitem (inbound landing). Returns the created qitem id, or throws. */
55
+ export declare function createQitem(runner: QueueRunner, input: CreateQitemInput): Promise<string>;
56
+ //# sourceMappingURL=queue-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue-bridge.d.ts","sourceRoot":"","sources":["../../src/slack/queue-bridge.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,gEAAgE;AAChE,MAAM,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;AAEjE;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,WAAW,CAiBd;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAcD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,kHAAkH;IAClH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,eAAe,GAAG,SAAS,EAAE,CAUxF;AASD,eAAO,MAAM,gBAAgB,SAAS,CAAC;AAEvC,6FAA6F;AAC7F,wBAAsB,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAItG;AAED,mEAAmE;AACnE,wBAAsB,QAAQ,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAQ9F;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,iFAAiF;AACjF,wBAAsB,WAAW,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAsB/F"}
@@ -0,0 +1,114 @@
1
+ // Slice-11 slack-connector — fleet access via the `rig` CLI ONLY.
2
+ //
3
+ // The connector NEVER imports daemon internals; it shells out to `rig queue`
4
+ // exactly like the reference relay (which ssh'd `rig queue` to the box). That
5
+ // keeps it transport-agnostic (local daemon via OPENRIG_URL, a registered
6
+ // remote via `--host`, or an ssh wrapper) and honors the secret-host axis
7
+ // (item 10): connector-host may differ from the queue/alert host.
8
+ //
9
+ // Productization fix over the reference (proven firsthand): reads use `-A`
10
+ // (all-rigs), because bare `rig queue list --json` is CURRENT-RIG only and
11
+ // silently misses cross-rig human-destined alerts.
12
+ import { execFile } from "node:child_process";
13
+ import { isHumanSeatSessionRef } from "../session-name.js";
14
+ /**
15
+ * Default runner: spawn the configured `rig` binary. `env` carries OPENRIG_URL
16
+ * (or nothing, letting rig resolve the local daemon); `baseArgs` can inject
17
+ * `--host <id>` for a registered remote queue. No shell — argv only.
18
+ */
19
+ export function makeExecRunner(opts) {
20
+ return (args) => new Promise((resolve) => {
21
+ execFile(opts.rigBin, [...(opts.baseArgs ?? []), ...args], { timeout: opts.timeoutMs ?? 30000, env: opts.env ?? process.env, maxBuffer: 16 * 1024 * 1024 }, (err, stdout, stderr) => {
22
+ resolve({
23
+ ok: !err,
24
+ stdout: String(stdout ?? ""),
25
+ stderr: String(stderr ?? ""),
26
+ code: err && typeof err.code === "number" ? err.code : err ? 1 : 0,
27
+ });
28
+ });
29
+ });
30
+ }
31
+ function parseArray(stdout) {
32
+ let j;
33
+ try {
34
+ j = JSON.parse(stdout);
35
+ }
36
+ catch {
37
+ throw new Error("queue list: non-JSON output");
38
+ }
39
+ if (Array.isArray(j))
40
+ return j;
41
+ const o = j;
42
+ return o.qitems ?? o.items ?? [];
43
+ }
44
+ /**
45
+ * PURE: select the qitems that should alert a human. A qitem alerts iff it is
46
+ * active, carries the alert tag, AND targets a human — either an explicit
47
+ * configured destination, a human-seat session name, or tier `human-gate`.
48
+ */
49
+ export function filterHumanAlerts(items, opts) {
50
+ const active = new Set(["pending", "in-progress", "blocked"]);
51
+ const allow = new Set(opts.destinations ?? []);
52
+ return items.filter((q) => {
53
+ if (q.state && !active.has(q.state))
54
+ return false;
55
+ if (!(q.tags ?? []).includes(opts.alertTag))
56
+ return false;
57
+ const dest = q.destinationSession ?? "";
58
+ const isHuman = allow.size > 0 ? allow.has(dest) : isHumanSeatSessionRef(dest) || q.tier === "human-gate";
59
+ return isHuman;
60
+ });
61
+ }
62
+ // Cross-host queue targeting is via OPENRIG_URL on the runner's env (supported
63
+ // by ALL queue verbs), NOT `--host` — `queue list`/`queue show` reject `--host`
64
+ // (only write/handoff verbs accept it). See makeExecRunner env / config.queueUrl.
65
+ // `queue list` defaults to --limit 100 and ALWAYS sends it, so an unbounded read
66
+ // silently truncates a large backlog (the B5 defect). Pass an explicit high
67
+ // limit so enable-time seeding + outbound see the COMPLETE matching set.
68
+ export const QUEUE_LIST_LIMIT = 100000;
69
+ /** Read active human alerts across ALL rigs (the -A scope fix) with a full-backlog limit. */
70
+ export async function listHumanAlerts(runner, opts) {
71
+ const r = await runner(["queue", "list", "-A", "--limit", String(QUEUE_LIST_LIMIT), "--json"]);
72
+ if (!r.ok)
73
+ throw new Error(`rig queue list failed (code ${r.code}): ${r.stderr.slice(0, 200)}`);
74
+ return filterHumanAlerts(parseArray(r.stdout), opts);
75
+ }
76
+ /** Full single-item read (list omits/bounds body — item 9 N+1). */
77
+ export async function showFull(runner, qitemId) {
78
+ const r = await runner(["queue", "show", qitemId, "--full", "--json"]);
79
+ if (!r.ok)
80
+ return null;
81
+ try {
82
+ return JSON.parse(r.stdout);
83
+ }
84
+ catch {
85
+ return null;
86
+ }
87
+ }
88
+ /** Create a qitem (inbound landing). Returns the created qitem id, or throws. */
89
+ export async function createQitem(runner, input) {
90
+ const args = [
91
+ "queue",
92
+ "create",
93
+ "--source",
94
+ input.source,
95
+ "--destination",
96
+ input.destination,
97
+ "--priority",
98
+ input.priority ?? "routine",
99
+ "--tags",
100
+ (input.tags ?? ["founder-slack", "inbound"]).join(","),
101
+ "--summary",
102
+ input.summary,
103
+ "--body",
104
+ input.body,
105
+ ];
106
+ const r = await runner(args);
107
+ if (!r.ok)
108
+ throw new Error(`rig queue create failed (code ${r.code}): ${r.stderr.slice(0, 200) || r.stdout.slice(0, 200)}`);
109
+ const id = (r.stdout.match(/qitem-[a-z0-9-]+/) ?? [])[0];
110
+ if (!id)
111
+ throw new Error("rig queue create: no qitem id in output");
112
+ return id;
113
+ }
114
+ //# sourceMappingURL=queue-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue-bridge.js","sourceRoot":"","sources":["../../src/slack/queue-bridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ export interface SecretFsOps {
2
+ readFileSync(p: string): string;
3
+ statMode(p: string): number | null;
4
+ }
5
+ export declare const nodeSecretFs: SecretFsOps;
6
+ /** Parse KEY=VALUE lines (quotes trimmed). Blank lines / #comments ignored. */
7
+ export declare function parseEnvFile(text: string): Record<string, string>;
8
+ export interface SecretLookupOpts {
9
+ envFile?: string;
10
+ env?: NodeJS.ProcessEnv;
11
+ fsops?: SecretFsOps;
12
+ }
13
+ /** Warn if the env file is group/world readable (item 10 hygiene). Returns a warning string or null. */
14
+ export declare function checkEnvFilePermissions(envFile: string, fsops?: SecretFsOps): string | null;
15
+ /**
16
+ * Resolve a secret by logical name. Precedence: explicit env var (OPENRIG_SLACK_<NAME>
17
+ * or the raw name) → env-file key. Returns null when unresolved (honest: callers
18
+ * report "unconfigured", they do NOT fabricate). Never logs the value.
19
+ */
20
+ export declare function resolveSecret(name: string, opts?: SecretLookupOpts): string | null;
21
+ //# sourceMappingURL=secrets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../src/slack/secrets.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,WAAW;IAC1B,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAChC,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CACpC;AAED,eAAO,MAAM,YAAY,EAAE,WAS1B,CAAC;AAEF,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAYjE;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,wGAAwG;AACxG,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,GAAE,WAA0B,GAAG,MAAM,GAAG,IAAI,CAKzG;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,gBAAqB,GAAG,MAAM,GAAG,IAAI,CAmBtF"}
@@ -0,0 +1,73 @@
1
+ // Slice-11 slack-connector — secret resolution (item 7 + 10).
2
+ //
3
+ // Secrets (Slack bot token / app-level token / incoming-webhook URL) resolve
4
+ // from EITHER an OPENRIG_SLACK_* environment variable OR a 0600 env file, at
5
+ // call time — NEVER stored in the connector config file, NEVER in the repo,
6
+ // NEVER logged. Mirrors the daemon's bearer_file/activity-hook-token posture.
7
+ // The env file lives on the TRUSTED host (item 10 secret-host axis); it may be
8
+ // a different host from the queue/alert host.
9
+ import fs from "node:fs";
10
+ export const nodeSecretFs = {
11
+ readFileSync: (p) => fs.readFileSync(p, "utf8"),
12
+ statMode: (p) => {
13
+ try {
14
+ return fs.statSync(p).mode & 0o777;
15
+ }
16
+ catch {
17
+ return null;
18
+ }
19
+ },
20
+ };
21
+ /** Parse KEY=VALUE lines (quotes trimmed). Blank lines / #comments ignored. */
22
+ export function parseEnvFile(text) {
23
+ const out = {};
24
+ for (const line of text.split("\n")) {
25
+ const t = line.trim();
26
+ if (!t || t.startsWith("#") || !t.includes("="))
27
+ continue;
28
+ const i = t.indexOf("=");
29
+ out[t.slice(0, i).trim()] = t
30
+ .slice(i + 1)
31
+ .trim()
32
+ .replace(/^"|"$/g, "");
33
+ }
34
+ return out;
35
+ }
36
+ /** Warn if the env file is group/world readable (item 10 hygiene). Returns a warning string or null. */
37
+ export function checkEnvFilePermissions(envFile, fsops = nodeSecretFs) {
38
+ const mode = fsops.statMode(envFile);
39
+ if (mode === null)
40
+ return null; // absent — a separate "unconfigured" concern
41
+ if (mode & 0o077)
42
+ return `secret env file ${envFile} is mode ${mode.toString(8)} — should be 0600 (group/other must not read secrets)`;
43
+ return null;
44
+ }
45
+ /**
46
+ * Resolve a secret by logical name. Precedence: explicit env var (OPENRIG_SLACK_<NAME>
47
+ * or the raw name) → env-file key. Returns null when unresolved (honest: callers
48
+ * report "unconfigured", they do NOT fabricate). Never logs the value.
49
+ */
50
+ export function resolveSecret(name, opts = {}) {
51
+ const env = opts.env ?? process.env;
52
+ const fsops = opts.fsops ?? nodeSecretFs;
53
+ // Aliases: the raw name (e.g. SLACK_WEBHOOK_URL) and the OPENRIG_-prefixed
54
+ // form (OPENRIG_SLACK_WEBHOOK_URL). NOT OPENRIG_SLACK_<name> — that would
55
+ // double the SLACK_ segment (the B4 defect).
56
+ const envKeys = [name, `OPENRIG_${name.replace(/[^A-Za-z0-9]/g, "_").toUpperCase()}`];
57
+ for (const k of envKeys) {
58
+ if (env[k])
59
+ return env[k];
60
+ }
61
+ if (opts.envFile) {
62
+ try {
63
+ const map = parseEnvFile(fsops.readFileSync(opts.envFile));
64
+ if (map[name])
65
+ return map[name];
66
+ }
67
+ catch {
68
+ /* absent/unreadable → null */
69
+ }
70
+ }
71
+ return null;
72
+ }
73
+ //# sourceMappingURL=secrets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/slack/secrets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ export type FetchImpl = (url: string, init?: RequestInit) => Promise<Response>;
2
+ export interface HttpResult {
3
+ ok: boolean;
4
+ status: number;
5
+ error?: string;
6
+ }
7
+ /**
8
+ * Post to a Slack incoming webhook. Fail-VISIBLE (item 3): any non-2xx or
9
+ * transport error returns ok:false with a bounded error string — the caller
10
+ * logs loudly and does NOT mark the alert seen (so it retries, never a silent drop).
11
+ */
12
+ export declare function postWebhook(url: string, payload: unknown, fetchImpl?: FetchImpl, timeoutMs?: number): Promise<HttpResult>;
13
+ export interface WebApiResult {
14
+ ok: boolean;
15
+ status: number;
16
+ grantedScopes: string[];
17
+ json: Record<string, unknown>;
18
+ error?: string;
19
+ }
20
+ /** Call a Slack Web API method (Bearer token) and surface the granted-scope header. */
21
+ export declare function callWebApi(method: string, token: string, body: Record<string, unknown>, fetchImpl?: FetchImpl, timeoutMs?: number): Promise<WebApiResult>;
22
+ /** Item 5: read the ACTUAL granted scopes from the response header (configured != granted). */
23
+ export declare function getGrantedScopes(token: string, fetchImpl?: FetchImpl, timeoutMs?: number): Promise<{
24
+ ok: boolean;
25
+ granted: string[];
26
+ error?: string;
27
+ }>;
28
+ export interface ScopeVerdict {
29
+ ok: boolean;
30
+ granted: string[];
31
+ missing: string[];
32
+ error?: string;
33
+ }
34
+ /** Item 5: verify the token actually HAS the required scopes (from the header, not config). */
35
+ export declare function verifyScopes(token: string, required: string[], fetchImpl?: FetchImpl, timeoutMs?: number): Promise<ScopeVerdict>;
36
+ /** Item 5: verify the bot is actually a MEMBER of the channel before inbound-ready. */
37
+ export declare function verifyChannelMembership(token: string, channel: string, fetchImpl?: FetchImpl, timeoutMs?: number): Promise<{
38
+ ok: boolean;
39
+ isMember: boolean;
40
+ name?: string;
41
+ error?: string;
42
+ }>;
43
+ /** Inbound Socket Mode: open a WebSocket URL via apps.connections.open (app-level xapp token). */
44
+ export declare function openSocketConnection(appToken: string, fetchImpl?: FetchImpl, timeoutMs?: number): Promise<{
45
+ ok: boolean;
46
+ url?: string;
47
+ error?: string;
48
+ }>;
49
+ //# sourceMappingURL=slack-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack-api.d.ts","sourceRoot":"","sources":["../../src/slack/slack-api.ts"],"names":[],"mappings":"AAcA,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAK/E,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAYD;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,OAAO,EAChB,SAAS,GAAE,SAAwB,EACnC,SAAS,SAAqB,GAC7B,OAAO,CAAC,UAAU,CAAC,CAkBrB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,uFAAuF;AACvF,wBAAsB,UAAU,CAC9B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,SAAS,GAAE,SAAwB,EACnC,SAAS,SAAqB,GAC7B,OAAO,CAAC,YAAY,CAAC,CA0BvB;AAED,+FAA+F;AAC/F,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,SAAwB,EACnC,SAAS,SAAqB,GAC7B,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAG7D;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,+FAA+F;AAC/F,wBAAsB,YAAY,CAChC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAAE,EAClB,SAAS,GAAE,SAAwB,EACnC,SAAS,SAAqB,GAC7B,OAAO,CAAC,YAAY,CAAC,CAMvB;AAED,uFAAuF;AACvF,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,SAAwB,EACnC,SAAS,SAAqB,GAC7B,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAK5E;AAED,kGAAkG;AAClG,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,MAAM,EAChB,SAAS,GAAE,SAAwB,EACnC,SAAS,SAAqB,GAC7B,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAIxD"}
@@ -0,0 +1,110 @@
1
+ // Slice-11 slack-connector — Slack HTTP client.
2
+ //
3
+ // `fetch`-based (http/https agnostic + injectable) matching the daemon's
4
+ // WebhookNotificationAdapter + its fake-fetch test pattern; every call is
5
+ // bounded by an explicit timeout with a structured failure result (never
6
+ // throws past the boundary, never hangs) — the remote-daemon-http discipline.
7
+ //
8
+ // Item 5 (the setup-scope trap): Slack's "Add New Webhook" grants ONLY the
9
+ // webhook scope; configured bot scopes are NOT granted until a full reinstall,
10
+ // with no warning. The ONLY proof of granted scopes is the `x-oauth-scopes`
11
+ // RESPONSE HEADER on a real API call — configured != granted. getGrantedScopes()
12
+ // reads exactly that header. Channel membership is likewise verified live
13
+ // (conversations.info.is_member) before declaring inbound ready.
14
+ const defaultFetch = (url, init) => fetch(url, init);
15
+ const DEFAULT_TIMEOUT_MS = 15000;
16
+ async function withTimeout(timeoutMs, run) {
17
+ const ctrl = new AbortController();
18
+ const timer = setTimeout(() => ctrl.abort(new Error(`timeout after ${timeoutMs}ms`)), timeoutMs);
19
+ try {
20
+ return await run(ctrl.signal);
21
+ }
22
+ finally {
23
+ clearTimeout(timer);
24
+ }
25
+ }
26
+ /**
27
+ * Post to a Slack incoming webhook. Fail-VISIBLE (item 3): any non-2xx or
28
+ * transport error returns ok:false with a bounded error string — the caller
29
+ * logs loudly and does NOT mark the alert seen (so it retries, never a silent drop).
30
+ */
31
+ export async function postWebhook(url, payload, fetchImpl = defaultFetch, timeoutMs = DEFAULT_TIMEOUT_MS) {
32
+ try {
33
+ return await withTimeout(timeoutMs, async (signal) => {
34
+ const res = await fetchImpl(url, {
35
+ method: "POST",
36
+ headers: { "content-type": "application/json" },
37
+ body: JSON.stringify(payload),
38
+ signal,
39
+ });
40
+ if (!res.ok) {
41
+ const text = await res.text().catch(() => "");
42
+ return { ok: false, status: res.status, error: `slack ${res.status}: ${text.slice(0, 160)}` };
43
+ }
44
+ return { ok: true, status: res.status };
45
+ });
46
+ }
47
+ catch (e) {
48
+ return { ok: false, status: 0, error: `webhook transport: ${e.message}` };
49
+ }
50
+ }
51
+ /** Call a Slack Web API method (Bearer token) and surface the granted-scope header. */
52
+ export async function callWebApi(method, token, body, fetchImpl = defaultFetch, timeoutMs = DEFAULT_TIMEOUT_MS) {
53
+ try {
54
+ return await withTimeout(timeoutMs, async (signal) => {
55
+ const res = await fetchImpl(`https://slack.com/api/${method}`, {
56
+ method: "POST",
57
+ headers: { authorization: `Bearer ${token}`, "content-type": "application/json; charset=utf-8" },
58
+ body: JSON.stringify(body),
59
+ signal,
60
+ });
61
+ const scopeHeader = res.headers.get("x-oauth-scopes") ?? "";
62
+ const grantedScopes = scopeHeader
63
+ .split(",")
64
+ .map((s) => s.trim())
65
+ .filter(Boolean);
66
+ let json = {};
67
+ try {
68
+ json = (await res.json());
69
+ }
70
+ catch {
71
+ /* non-JSON */
72
+ }
73
+ const ok = res.ok && json.ok === true;
74
+ return { ok, status: res.status, grantedScopes, json, error: ok ? undefined : String(json.error ?? `http ${res.status}`) };
75
+ });
76
+ }
77
+ catch (e) {
78
+ return { ok: false, status: 0, grantedScopes: [], json: {}, error: `web-api transport: ${e.message}` };
79
+ }
80
+ }
81
+ /** Item 5: read the ACTUAL granted scopes from the response header (configured != granted). */
82
+ export async function getGrantedScopes(token, fetchImpl = defaultFetch, timeoutMs = DEFAULT_TIMEOUT_MS) {
83
+ const r = await callWebApi("auth.test", token, {}, fetchImpl, timeoutMs);
84
+ return { ok: r.ok, granted: r.grantedScopes, error: r.error };
85
+ }
86
+ /** Item 5: verify the token actually HAS the required scopes (from the header, not config). */
87
+ export async function verifyScopes(token, required, fetchImpl = defaultFetch, timeoutMs = DEFAULT_TIMEOUT_MS) {
88
+ const g = await getGrantedScopes(token, fetchImpl, timeoutMs);
89
+ if (!g.ok)
90
+ return { ok: false, granted: g.granted, missing: required, error: g.error };
91
+ const grantedSet = new Set(g.granted);
92
+ const missing = required.filter((s) => !grantedSet.has(s));
93
+ return { ok: missing.length === 0, granted: g.granted, missing };
94
+ }
95
+ /** Item 5: verify the bot is actually a MEMBER of the channel before inbound-ready. */
96
+ export async function verifyChannelMembership(token, channel, fetchImpl = defaultFetch, timeoutMs = DEFAULT_TIMEOUT_MS) {
97
+ const r = await callWebApi("conversations.info", token, { channel }, fetchImpl, timeoutMs);
98
+ if (!r.ok)
99
+ return { ok: false, isMember: false, error: r.error };
100
+ const ch = (r.json.channel ?? {});
101
+ return { ok: true, isMember: ch.is_member === true, name: ch.name };
102
+ }
103
+ /** Inbound Socket Mode: open a WebSocket URL via apps.connections.open (app-level xapp token). */
104
+ export async function openSocketConnection(appToken, fetchImpl = defaultFetch, timeoutMs = DEFAULT_TIMEOUT_MS) {
105
+ const r = await callWebApi("apps.connections.open", appToken, {}, fetchImpl, timeoutMs);
106
+ if (!r.ok)
107
+ return { ok: false, error: r.error };
108
+ return { ok: true, url: r.json.url };
109
+ }
110
+ //# sourceMappingURL=slack-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack-api.js","sourceRoot":"","sources":["../../src/slack/slack-api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ export interface StateFsOps {
2
+ readFileSync(p: string): string;
3
+ appendFileSync(p: string, data: string): void;
4
+ writeFileSync(p: string, data: string): void;
5
+ rename(from: string, to: string): void;
6
+ mkdirp(dir: string): void;
7
+ }
8
+ export declare const nodeStateFs: StateFsOps;
9
+ export interface SeenRecord {
10
+ id: string;
11
+ ts: string;
12
+ status: string;
13
+ }
14
+ /**
15
+ * Delivery-dedup log. `load()` reads the durable set from disk; `mark()` appends
16
+ * AFTER the guarded side effect. Idempotent on id: a repeated id collapses in
17
+ * `load()`'s Set, and callers gate the side effect on `!seen.has(id)` so a
18
+ * duplicate is never re-delivered within a run.
19
+ */
20
+ export declare class SeenStore {
21
+ private readonly file;
22
+ private readonly fsops;
23
+ private readonly now;
24
+ constructor(file: string, fsops?: StateFsOps, now?: () => Date);
25
+ load(): Set<string>;
26
+ /** Append a seen record. MUST be called only after the guarded side effect succeeds. */
27
+ mark(id: string, status: string): void;
28
+ /**
29
+ * Seed existing ids as already-seen WITHOUT triggering the side effect
30
+ * (locked item 9: enable-time backlog seeds as history, zero replay storm).
31
+ */
32
+ seed(ids: string[], status?: string): number;
33
+ }
34
+ export interface DeadLetterEntry<T = unknown> {
35
+ ev: T;
36
+ at: string;
37
+ attempts: number;
38
+ }
39
+ /**
40
+ * Inbound never-drop net. Every event that fails to land is appended
41
+ * (attempt-counted) BEFORE the error path returns.
42
+ *
43
+ * INTERRUPTION-SAFE retry (the B2 fix): retry does NOT truncate first. The
44
+ * caller `readAll()`s (non-destructive), attempts each, then `replaceAll()`s the
45
+ * file with ONLY the still-failing entries via an atomic temp-write + rename. So
46
+ * the durable file always reflects the unrecovered set: a crash at ANY point
47
+ * before the rename leaves the ORIGINAL file fully intact (at-least-once — a
48
+ * since-landed event is skipped on re-read via the seen-set, so not even a dup).
49
+ * There is no truncate-before-success window.
50
+ */
51
+ export declare class DeadLetterStore<T = unknown> {
52
+ private readonly file;
53
+ private readonly fsops;
54
+ private readonly now;
55
+ constructor(file: string, fsops?: StateFsOps, now?: () => Date);
56
+ append(ev: T, attempts: number): void;
57
+ /** Non-destructive read of all durable entries. */
58
+ readAll(): DeadLetterEntry<T>[];
59
+ /** Atomically replace the durable set (temp-write + rename). Used after a retry pass. */
60
+ replaceAll(entries: DeadLetterEntry<T>[]): void;
61
+ }
62
+ //# sourceMappingURL=state-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-store.d.ts","sourceRoot":"","sources":["../../src/slack/state-store.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,UAAU;IACzB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAChC,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9C,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7C,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,eAAO,MAAM,WAAW,EAAE,UAQzB,CAAC;AAiBF,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,qBAAa,SAAS;IAElB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAFH,IAAI,EAAE,MAAM,EACZ,KAAK,GAAE,UAAwB,EAC/B,GAAG,GAAE,MAAM,IAAuB;IAGrD,IAAI,IAAI,GAAG,CAAC,MAAM,CAAC;IAUnB,wFAAwF;IACxF,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAKtC;;;OAGG;IACH,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,MAAM,SAAW,GAAG,MAAM;CAQ/C;AAED,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,OAAO;IAC1C,EAAE,EAAE,CAAC,CAAC;IACN,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,eAAe,CAAC,CAAC,GAAG,OAAO;IAEpC,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAFH,IAAI,EAAE,MAAM,EACZ,KAAK,GAAE,UAAwB,EAC/B,GAAG,GAAE,MAAM,IAAuB;IAGrD,MAAM,CAAC,EAAE,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAQrC,mDAAmD;IACnD,OAAO,IAAI,eAAe,CAAC,CAAC,CAAC,EAAE;IAU/B,yFAAyF;IACzF,UAAU,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI;CAOhD"}