@openrig/cli 0.4.6 → 0.4.7

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 (352) 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/claude-compaction-restore/SKILL.md +9 -6
  5. package/daemon/assets/plugins/openrig-core/skills/claude-compaction-restore/scripts/precompact-hook.mjs +11 -72
  6. package/daemon/assets/plugins/openrig-core/skills/forming-an-openrig-mental-model/SKILL.md +34 -22
  7. package/daemon/assets/plugins/openrig-core/skills/messaging-the-human/SKILL.md +108 -0
  8. package/daemon/assets/plugins/openrig-core/skills/mission-slice-sop/SKILL.md +11 -14
  9. package/daemon/assets/plugins/openrig-core/skills/openrig-skills/SKILL.md +95 -0
  10. package/daemon/assets/plugins/openrig-core/skills/openrig-user/SKILL.md +175 -105
  11. package/daemon/assets/plugins/openrig-core/skills/queue-handoff/SKILL.md +26 -9
  12. package/daemon/assets/plugins/openrig-core/skills/seat-continuity-and-handover/SKILL.md +11 -9
  13. package/daemon/assets/plugins/openrig-core/skills/session-compaction-and-restore/SKILL.md +162 -0
  14. package/daemon/assets/plugins/openrig-core/skills/software-for-agents/SKILL.md +165 -0
  15. package/daemon/dist/adapters/cmux-transport.d.ts.map +1 -1
  16. package/daemon/dist/adapters/cmux-transport.js +8 -1
  17. package/daemon/dist/adapters/cmux-transport.js.map +1 -1
  18. package/daemon/dist/adapters/cmux.d.ts +9 -0
  19. package/daemon/dist/adapters/cmux.d.ts.map +1 -1
  20. package/daemon/dist/adapters/cmux.js +21 -0
  21. package/daemon/dist/adapters/cmux.js.map +1 -1
  22. package/daemon/dist/adapters/codex-runtime-adapter.d.ts +3 -0
  23. package/daemon/dist/adapters/codex-runtime-adapter.d.ts.map +1 -1
  24. package/daemon/dist/adapters/codex-runtime-adapter.js +20 -4
  25. package/daemon/dist/adapters/codex-runtime-adapter.js.map +1 -1
  26. package/daemon/dist/build-info.js +3 -3
  27. package/daemon/dist/domain/claude-compaction-enforcer.d.ts +3 -0
  28. package/daemon/dist/domain/claude-compaction-enforcer.d.ts.map +1 -1
  29. package/daemon/dist/domain/claude-compaction-enforcer.js +19 -3
  30. package/daemon/dist/domain/claude-compaction-enforcer.js.map +1 -1
  31. package/daemon/dist/domain/cmux-layout-service.d.ts +36 -0
  32. package/daemon/dist/domain/cmux-layout-service.d.ts.map +1 -1
  33. package/daemon/dist/domain/cmux-layout-service.js +100 -28
  34. package/daemon/dist/domain/cmux-layout-service.js.map +1 -1
  35. package/daemon/dist/domain/context-monitor.d.ts +2 -0
  36. package/daemon/dist/domain/context-monitor.d.ts.map +1 -1
  37. package/daemon/dist/domain/context-monitor.js +14 -0
  38. package/daemon/dist/domain/context-monitor.js.map +1 -1
  39. package/daemon/dist/domain/feed/attention-aggregator.js +1 -1
  40. package/daemon/dist/domain/feed/attention-aggregator.js.map +1 -1
  41. package/daemon/dist/domain/hosts/hosts-registry-reader.d.ts.map +1 -1
  42. package/daemon/dist/domain/hosts/hosts-registry-reader.js +12 -10
  43. package/daemon/dist/domain/hosts/hosts-registry-reader.js.map +1 -1
  44. package/daemon/dist/domain/hosts/hosts-registry-writer.d.ts.map +1 -1
  45. package/daemon/dist/domain/hosts/hosts-registry-writer.js +3 -2
  46. package/daemon/dist/domain/hosts/hosts-registry-writer.js.map +1 -1
  47. package/daemon/dist/domain/hosts/read-through.js +1 -1
  48. package/daemon/dist/domain/hosts/read-through.js.map +1 -1
  49. package/daemon/dist/domain/hosts/remote-daemon-http.d.ts.map +1 -1
  50. package/daemon/dist/domain/hosts/remote-daemon-http.js +8 -5
  51. package/daemon/dist/domain/hosts/remote-daemon-http.js.map +1 -1
  52. package/daemon/dist/domain/node-inventory.d.ts +3 -12
  53. package/daemon/dist/domain/node-inventory.d.ts.map +1 -1
  54. package/daemon/dist/domain/node-inventory.js +55 -13
  55. package/daemon/dist/domain/node-inventory.js.map +1 -1
  56. package/daemon/dist/domain/plugin-vendor-service.d.ts +2 -0
  57. package/daemon/dist/domain/plugin-vendor-service.d.ts.map +1 -1
  58. package/daemon/dist/domain/plugin-vendor-service.js +23 -0
  59. package/daemon/dist/domain/plugin-vendor-service.js.map +1 -1
  60. package/daemon/dist/domain/projection-lane.d.ts +7 -0
  61. package/daemon/dist/domain/projection-lane.d.ts.map +1 -0
  62. package/daemon/dist/domain/projection-lane.js +28 -0
  63. package/daemon/dist/domain/projection-lane.js.map +1 -0
  64. package/daemon/dist/domain/ps-projection.d.ts +19 -0
  65. package/daemon/dist/domain/ps-projection.d.ts.map +1 -1
  66. package/daemon/dist/domain/ps-projection.js +46 -6
  67. package/daemon/dist/domain/ps-projection.js.map +1 -1
  68. package/daemon/dist/domain/queue-repository.d.ts +14 -10
  69. package/daemon/dist/domain/queue-repository.d.ts.map +1 -1
  70. package/daemon/dist/domain/queue-repository.js +33 -12
  71. package/daemon/dist/domain/queue-repository.js.map +1 -1
  72. package/daemon/dist/domain/review/compose.d.ts +77 -4
  73. package/daemon/dist/domain/review/compose.d.ts.map +1 -1
  74. package/daemon/dist/domain/review/compose.js +152 -16
  75. package/daemon/dist/domain/review/compose.js.map +1 -1
  76. package/daemon/dist/domain/review/fleet-compose.js +1 -1
  77. package/daemon/dist/domain/review/fleet-compose.js.map +1 -1
  78. package/daemon/dist/domain/review/gather.d.ts +1 -1
  79. package/daemon/dist/domain/review/gather.d.ts.map +1 -1
  80. package/daemon/dist/domain/review/gather.js +92 -67
  81. package/daemon/dist/domain/review/gather.js.map +1 -1
  82. package/daemon/dist/domain/review/proof-io.d.ts +2 -0
  83. package/daemon/dist/domain/review/proof-io.d.ts.map +1 -0
  84. package/daemon/dist/domain/review/proof-io.js +38 -0
  85. package/daemon/dist/domain/review/proof-io.js.map +1 -0
  86. package/daemon/dist/domain/rigspec-instantiator.d.ts.map +1 -1
  87. package/daemon/dist/domain/rigspec-instantiator.js +15 -2
  88. package/daemon/dist/domain/rigspec-instantiator.js.map +1 -1
  89. package/daemon/dist/domain/scope/plan-lock-artifacts.d.ts +8 -0
  90. package/daemon/dist/domain/scope/plan-lock-artifacts.d.ts.map +1 -0
  91. package/daemon/dist/domain/scope/plan-lock-artifacts.js +57 -0
  92. package/daemon/dist/domain/scope/plan-lock-artifacts.js.map +1 -0
  93. package/daemon/dist/domain/scope/scaffold-placeholder.d.ts +38 -0
  94. package/daemon/dist/domain/scope/scaffold-placeholder.d.ts.map +1 -0
  95. package/daemon/dist/domain/scope/scaffold-placeholder.js +98 -0
  96. package/daemon/dist/domain/scope/scaffold-placeholder.js.map +1 -0
  97. package/daemon/dist/domain/scope/scope-approve.d.ts.map +1 -1
  98. package/daemon/dist/domain/scope/scope-approve.js +22 -1
  99. package/daemon/dist/domain/scope/scope-approve.js.map +1 -1
  100. package/daemon/dist/domain/scope/scope-audit.d.ts.map +1 -1
  101. package/daemon/dist/domain/scope/scope-audit.js +57 -20
  102. package/daemon/dist/domain/scope/scope-audit.js.map +1 -1
  103. package/daemon/dist/domain/session-transport.d.ts +17 -0
  104. package/daemon/dist/domain/session-transport.d.ts.map +1 -1
  105. package/daemon/dist/domain/session-transport.js +44 -0
  106. package/daemon/dist/domain/session-transport.js.map +1 -1
  107. package/daemon/dist/domain/slices/qitem-membership.d.ts +17 -0
  108. package/daemon/dist/domain/slices/qitem-membership.d.ts.map +1 -0
  109. package/daemon/dist/domain/slices/qitem-membership.js +60 -0
  110. package/daemon/dist/domain/slices/qitem-membership.js.map +1 -0
  111. package/daemon/dist/domain/slices/slice-detail-projector.d.ts +5 -0
  112. package/daemon/dist/domain/slices/slice-detail-projector.d.ts.map +1 -1
  113. package/daemon/dist/domain/slices/slice-detail-projector.js +157 -11
  114. package/daemon/dist/domain/slices/slice-detail-projector.js.map +1 -1
  115. package/daemon/dist/domain/slices/slice-indexer.d.ts +86 -0
  116. package/daemon/dist/domain/slices/slice-indexer.d.ts.map +1 -1
  117. package/daemon/dist/domain/slices/slice-indexer.js +422 -45
  118. package/daemon/dist/domain/slices/slice-indexer.js.map +1 -1
  119. package/daemon/dist/domain/startup-orchestrator.d.ts +9 -0
  120. package/daemon/dist/domain/startup-orchestrator.d.ts.map +1 -1
  121. package/daemon/dist/domain/startup-orchestrator.js +71 -3
  122. package/daemon/dist/domain/startup-orchestrator.js.map +1 -1
  123. package/daemon/dist/domain/terminal/cmux-provider-adapter.d.ts +12 -11
  124. package/daemon/dist/domain/terminal/cmux-provider-adapter.d.ts.map +1 -1
  125. package/daemon/dist/domain/terminal/cmux-provider-adapter.js +61 -28
  126. package/daemon/dist/domain/terminal/cmux-provider-adapter.js.map +1 -1
  127. package/daemon/dist/domain/terminal/herdr-adapter.d.ts +27 -10
  128. package/daemon/dist/domain/terminal/herdr-adapter.d.ts.map +1 -1
  129. package/daemon/dist/domain/terminal/herdr-adapter.js +74 -33
  130. package/daemon/dist/domain/terminal/herdr-adapter.js.map +1 -1
  131. package/daemon/dist/domain/transcript-capture.d.ts +3 -0
  132. package/daemon/dist/domain/transcript-capture.d.ts.map +1 -1
  133. package/daemon/dist/domain/transcript-capture.js +28 -0
  134. package/daemon/dist/domain/transcript-capture.js.map +1 -1
  135. package/daemon/dist/domain/transcript-store.d.ts +10 -0
  136. package/daemon/dist/domain/transcript-store.d.ts.map +1 -1
  137. package/daemon/dist/domain/transcript-store.js +26 -0
  138. package/daemon/dist/domain/transcript-store.js.map +1 -1
  139. package/daemon/dist/domain/types.d.ts +4 -0
  140. package/daemon/dist/domain/types.d.ts.map +1 -1
  141. package/daemon/dist/domain/types.js.map +1 -1
  142. package/daemon/dist/domain/workspace/default-workspace-scaffold.d.ts.map +1 -1
  143. package/daemon/dist/domain/workspace/default-workspace-scaffold.js +9 -4
  144. package/daemon/dist/domain/workspace/default-workspace-scaffold.js.map +1 -1
  145. package/daemon/dist/domain/workspace/workspace-doctor.js +1 -1
  146. package/daemon/dist/domain/workspace/workspace-doctor.js.map +1 -1
  147. package/daemon/dist/routes/mission-control.js +1 -1
  148. package/daemon/dist/routes/mission-control.js.map +1 -1
  149. package/daemon/dist/routes/missions.d.ts +7 -0
  150. package/daemon/dist/routes/missions.d.ts.map +1 -1
  151. package/daemon/dist/routes/missions.js +6 -1
  152. package/daemon/dist/routes/missions.js.map +1 -1
  153. package/daemon/dist/routes/ps.d.ts.map +1 -1
  154. package/daemon/dist/routes/ps.js +5 -1
  155. package/daemon/dist/routes/ps.js.map +1 -1
  156. package/daemon/dist/routes/queue.d.ts.map +1 -1
  157. package/daemon/dist/routes/queue.js +9 -2
  158. package/daemon/dist/routes/queue.js.map +1 -1
  159. package/daemon/dist/routes/rigs.d.ts.map +1 -1
  160. package/daemon/dist/routes/rigs.js +21 -10
  161. package/daemon/dist/routes/rigs.js.map +1 -1
  162. package/daemon/dist/routes/scope-audit.d.ts.map +1 -1
  163. package/daemon/dist/routes/scope-audit.js +141 -135
  164. package/daemon/dist/routes/scope-audit.js.map +1 -1
  165. package/daemon/dist/routes/sessions.js +2 -1
  166. package/daemon/dist/routes/sessions.js.map +1 -1
  167. package/daemon/dist/routes/slices.d.ts.map +1 -1
  168. package/daemon/dist/routes/slices.js +48 -38
  169. package/daemon/dist/routes/slices.js.map +1 -1
  170. package/daemon/dist/routes/transcripts.d.ts.map +1 -1
  171. package/daemon/dist/routes/transcripts.js +62 -33
  172. package/daemon/dist/routes/transcripts.js.map +1 -1
  173. package/daemon/dist/startup.d.ts.map +1 -1
  174. package/daemon/dist/startup.js +25 -11
  175. package/daemon/dist/startup.js.map +1 -1
  176. package/daemon/docs/reference/agent-startup-guide.md +1 -0
  177. package/daemon/specs/agents/apps/vault-specialist/agent.yaml +2 -1
  178. package/daemon/specs/agents/conveyor/builder/agent.yaml +2 -1
  179. package/daemon/specs/agents/conveyor/lead/agent.yaml +2 -1
  180. package/daemon/specs/agents/conveyor/planner/agent.yaml +2 -1
  181. package/daemon/specs/agents/conveyor/reviewer/agent.yaml +2 -1
  182. package/daemon/specs/agents/design/product-designer/agent.yaml +12 -2
  183. package/daemon/specs/agents/development/implementer/agent.yaml +12 -2
  184. package/daemon/specs/agents/development/qa/agent.yaml +12 -2
  185. package/daemon/specs/agents/development/qa/guidance/role.md +1 -0
  186. package/daemon/specs/agents/factory-rsi/dogfood/agent.yaml +2 -1
  187. package/daemon/specs/agents/factory-rsi/release-manager/agent.yaml +2 -1
  188. package/daemon/specs/agents/orchestration/orchestrator/agent.yaml +12 -2
  189. package/daemon/specs/agents/product-management/pm/agent.yaml +1 -2
  190. package/daemon/specs/agents/research/analyst/agent.yaml +2 -1
  191. package/daemon/specs/agents/research/synthesizer/agent.yaml +2 -1
  192. package/daemon/specs/agents/review/independent-reviewer/agent.yaml +12 -2
  193. package/daemon/specs/agents/shared/agent.yaml +5 -8
  194. package/daemon/specs/agents/shared/runtime/claude-settings.fragment.json +13 -1
  195. package/daemon/specs/agents/shared/skills/core/agent-starters/SKILL.md +132 -0
  196. package/daemon/{assets/plugins/openrig-core/skills → specs/agents/shared/skills/core}/agent-startup-and-context-ingestion/SKILL.md +27 -19
  197. package/daemon/specs/agents/shared/skills/core/attention-queue/SKILL.md +264 -0
  198. package/daemon/specs/agents/shared/skills/core/cross-host-rig-commands/SKILL.md +190 -0
  199. package/daemon/specs/agents/shared/skills/core/human-in-the-loop/SKILL.md +104 -0
  200. package/daemon/specs/agents/shared/skills/core/openrig-architect/SKILL.md +25 -8
  201. package/daemon/specs/agents/shared/skills/core/openrig-cmux/SKILL.md +0 -5
  202. package/daemon/specs/agents/shared/skills/core/openrig-herdr/SKILL.md +1 -6
  203. package/daemon/specs/agents/shared/skills/core/openrig-upgrade/SKILL.md +460 -0
  204. package/daemon/specs/agents/shared/skills/core/rig-bundles-and-shareable-artifacts/SKILL.md +101 -0
  205. package/daemon/specs/agents/shared/skills/core/rig-lifecycle/SKILL.md +22 -11
  206. package/daemon/specs/agents/shared/skills/core/session-source-fork/SKILL.md +160 -0
  207. package/daemon/specs/agents/shared/skills/core/specification-system/SKILL.md +103 -0
  208. package/daemon/specs/agents/shared/skills/core/topology-mutation-and-seat-management/SKILL.md +118 -0
  209. package/daemon/specs/agents/shared/skills/core/watchdog/SKILL.md +125 -0
  210. package/daemon/specs/agents/shared/skills/pods/orchestration-team/SKILL.md +4 -4
  211. package/daemon/specs/agents/shared/skills/pods/review-team/SKILL.md +3 -0
  212. package/daemon/specs/agents/shared/skills/process/brainstorming/OPENRIG.md +3 -3
  213. package/daemon/specs/agents/shared/skills/process/executing-plans/OPENRIG.md +1 -1
  214. package/daemon/specs/agents/shared/skills/process/frontend-design/SKILL.md +6 -3
  215. package/daemon/specs/agents/shared/skills/process/test-driven-development/SKILL.md +1 -1
  216. package/daemon/specs/agents/shared/skills/process/using-superpowers/OPENRIG.md +1 -1
  217. package/daemon/specs/agents/shared/skills/process/verification-before-completion/SKILL.md +12 -2
  218. package/daemon/specs/agents/shared/skills/process/writing-plans/OPENRIG.md +1 -1
  219. package/daemon/specs/rigs/focused/pm-team/CULTURE.md +1 -1
  220. package/daemon/specs/rigs/launch/kernel/agents/advisor/lead/agent.yaml +2 -2
  221. package/daemon/specs/rigs/launch/kernel/agents/advisor/lead/guidance/role.md +5 -4
  222. package/daemon/specs/rigs/launch/kernel/agents/operator/agent/agent.yaml +2 -2
  223. package/daemon/specs/rigs/launch/kernel/agents/operator/agent/guidance/role.md +3 -5
  224. package/daemon/specs/rigs/launch/kernel/agents/queue/worker/agent.yaml +2 -2
  225. package/daemon/specs/rigs/launch/kernel/culture/CULTURE.md +3 -4
  226. package/daemon/specs/rigs/preview/product-team/CULTURE.md +1 -1
  227. package/dist/bin-wrapper.d.ts.map +1 -1
  228. package/dist/bin-wrapper.js +3 -1
  229. package/dist/bin-wrapper.js.map +1 -1
  230. package/dist/build-info.js +3 -3
  231. package/dist/cli-error.d.ts +33 -0
  232. package/dist/cli-error.d.ts.map +1 -0
  233. package/dist/cli-error.js +94 -0
  234. package/dist/cli-error.js.map +1 -0
  235. package/dist/commands/config-init-workspace.js +1 -1
  236. package/dist/commands/doctor.d.ts +1 -1
  237. package/dist/commands/doctor.d.ts.map +1 -1
  238. package/dist/commands/doctor.js +17 -11
  239. package/dist/commands/doctor.js.map +1 -1
  240. package/dist/commands/host.d.ts.map +1 -1
  241. package/dist/commands/host.js +24 -10
  242. package/dist/commands/host.js.map +1 -1
  243. package/dist/commands/proof.js +1 -1
  244. package/dist/commands/proof.js.map +1 -1
  245. package/dist/commands/ps.d.ts.map +1 -1
  246. package/dist/commands/ps.js +16 -2
  247. package/dist/commands/ps.js.map +1 -1
  248. package/dist/commands/queue.d.ts.map +1 -1
  249. package/dist/commands/queue.js +103 -24
  250. package/dist/commands/queue.js.map +1 -1
  251. package/dist/commands/rig.d.ts.map +1 -1
  252. package/dist/commands/rig.js +122 -0
  253. package/dist/commands/rig.js.map +1 -1
  254. package/dist/commands/scope.js +2 -2
  255. package/dist/commands/scope.js.map +1 -1
  256. package/dist/commands/send.d.ts.map +1 -1
  257. package/dist/commands/send.js +118 -24
  258. package/dist/commands/send.js.map +1 -1
  259. package/dist/commands/slack.d.ts +37 -0
  260. package/dist/commands/slack.d.ts.map +1 -0
  261. package/dist/commands/slack.js +274 -0
  262. package/dist/commands/slack.js.map +1 -0
  263. package/dist/commands/ui.d.ts +1 -0
  264. package/dist/commands/ui.d.ts.map +1 -1
  265. package/dist/commands/ui.js +2 -0
  266. package/dist/commands/ui.js.map +1 -1
  267. package/dist/commands/up.js +1 -1
  268. package/dist/commands/up.js.map +1 -1
  269. package/dist/commands/whoami.d.ts.map +1 -1
  270. package/dist/commands/whoami.js +3 -3
  271. package/dist/commands/whoami.js.map +1 -1
  272. package/dist/daemon-lifecycle.d.ts.map +1 -1
  273. package/dist/daemon-lifecycle.js +45 -14
  274. package/dist/daemon-lifecycle.js.map +1 -1
  275. package/dist/host-registry.d.ts +6 -1
  276. package/dist/host-registry.d.ts.map +1 -1
  277. package/dist/host-registry.js +15 -6
  278. package/dist/host-registry.js.map +1 -1
  279. package/dist/index.d.ts +3 -0
  280. package/dist/index.d.ts.map +1 -1
  281. package/dist/index.js +6 -1
  282. package/dist/index.js.map +1 -1
  283. package/dist/lib/scope/scaffold-placeholder.d.ts +38 -0
  284. package/dist/lib/scope/scaffold-placeholder.d.ts.map +1 -0
  285. package/dist/lib/scope/scaffold-placeholder.js +98 -0
  286. package/dist/lib/scope/scaffold-placeholder.js.map +1 -0
  287. package/dist/lib/scope/scope-audit.d.ts.map +1 -1
  288. package/dist/lib/scope/scope-audit.js +57 -20
  289. package/dist/lib/scope/scope-audit.js.map +1 -1
  290. package/dist/lib/scope-templates/backlog-deprecation.md +1 -1
  291. package/dist/lib/scope-templates/backlog-tech-debt.md +1 -1
  292. package/dist/lib/scope-templates/bug-fix.md +1 -1
  293. package/dist/lib/scope-templates/implementation-prd.md +1 -1
  294. package/dist/lib/scope-templates/mission-notes.md +7 -2
  295. package/dist/lib/scope-templates/mission-placeholder.md +1 -1
  296. package/dist/lib/scope-templates/mission-progress.md +1 -1
  297. package/dist/lib/scope-templates/mission-release.md +1 -1
  298. package/dist/lib/scope-templates/placeholder.md +1 -1
  299. package/dist/lib/scope-templates/proof.md +1 -1
  300. package/dist/lib/scope-templates/release-feature.md +1 -1
  301. package/dist/lib/scope-templates/research.md +1 -1
  302. package/dist/lib/scope-templates/slice-progress.md +1 -1
  303. package/dist/remote-host-ops.d.ts.map +1 -1
  304. package/dist/remote-host-ops.js +2 -2
  305. package/dist/remote-host-ops.js.map +1 -1
  306. package/dist/slack/config.d.ts +41 -0
  307. package/dist/slack/config.d.ts.map +1 -0
  308. package/dist/slack/config.js +60 -0
  309. package/dist/slack/config.js.map +1 -0
  310. package/dist/slack/inbound.d.ts +75 -0
  311. package/dist/slack/inbound.d.ts.map +1 -0
  312. package/dist/slack/inbound.js +133 -0
  313. package/dist/slack/inbound.js.map +1 -0
  314. package/dist/slack/message.d.ts +26 -0
  315. package/dist/slack/message.d.ts.map +1 -0
  316. package/dist/slack/message.js +60 -0
  317. package/dist/slack/message.js.map +1 -0
  318. package/dist/slack/outbound.d.ts +39 -0
  319. package/dist/slack/outbound.d.ts.map +1 -0
  320. package/dist/slack/outbound.js +52 -0
  321. package/dist/slack/outbound.js.map +1 -0
  322. package/dist/slack/queue-bridge.d.ts +56 -0
  323. package/dist/slack/queue-bridge.d.ts.map +1 -0
  324. package/dist/slack/queue-bridge.js +114 -0
  325. package/dist/slack/queue-bridge.js.map +1 -0
  326. package/dist/slack/secrets.d.ts +21 -0
  327. package/dist/slack/secrets.d.ts.map +1 -0
  328. package/dist/slack/secrets.js +73 -0
  329. package/dist/slack/secrets.js.map +1 -0
  330. package/dist/slack/slack-api.d.ts +49 -0
  331. package/dist/slack/slack-api.d.ts.map +1 -0
  332. package/dist/slack/slack-api.js +110 -0
  333. package/dist/slack/slack-api.js.map +1 -0
  334. package/dist/slack/state-store.d.ts +62 -0
  335. package/dist/slack/state-store.d.ts.map +1 -0
  336. package/dist/slack/state-store.js +132 -0
  337. package/dist/slack/state-store.js.map +1 -0
  338. package/package.json +1 -1
  339. package/ui/dist/assets/{index-zrFqS7gL.js → index-DkNi0RT8.js} +184 -184
  340. package/ui/dist/assets/index-N-SdPj-I.css +32 -0
  341. package/ui/dist/index.html +2 -2
  342. package/daemon/assets/plugins/openrig-core/skills/openrig-architect/SKILL.md +0 -361
  343. package/daemon/assets/plugins/openrig-core/skills/openrig-cmux/SKILL.md +0 -86
  344. package/daemon/assets/plugins/openrig-core/skills/openrig-herdr/SKILL.md +0 -158
  345. package/daemon/assets/plugins/openrig-core/skills/openrig-operator/SKILL.md +0 -222
  346. package/daemon/docs/reference/product-factory-vps-runbook.md +0 -132
  347. package/daemon/specs/agents/shared/skills/core/mission-slice-sop/SKILL.md +0 -113
  348. package/daemon/specs/agents/shared/skills/core/openrig-installer/SKILL.md +0 -142
  349. package/daemon/specs/agents/shared/skills/core/openrig-operator/SKILL.md +0 -110
  350. package/daemon/specs/agents/shared/skills/core/openrig-user/SKILL.md +0 -1245
  351. package/daemon/specs/agents/shared/skills/core/openrig-user-settings/SKILL.md +0 -153
  352. package/ui/dist/assets/index-CFqxa0zW.css +0 -32
@@ -0,0 +1,133 @@
1
+ import { createQitem } from "./queue-bridge.js";
2
+ /**
3
+ * Loop-safety + non-text ignore. Ingest ONLY genuine human text messages:
4
+ * reject bot posts (our own loop), message subtypes (edits/joins/file_share),
5
+ * and — T1076 — anything carrying files/images. v1 ignores non-text CLEANLY:
6
+ * a false return is a clean skip, never a crash or partial ingestion.
7
+ */
8
+ export function shouldIngest(ev) {
9
+ if (ev.type !== "message" && ev.type !== "app_mention")
10
+ return false;
11
+ if (ev.bot_id)
12
+ return false; // never ingest our own / any bot post
13
+ if (ev.subtype)
14
+ return false; // edits, joins, file_share, etc.
15
+ if (ev.files && ev.files.length > 0)
16
+ return false; // T1076: image/file events ignored cleanly (Slice-12)
17
+ if (!ev.user || !ev.text || !ev.text.trim())
18
+ return false;
19
+ return true;
20
+ }
21
+ export class InboundRouter {
22
+ deps;
23
+ inflight = new Set(); // same-ts double-dispatch guard (item 8)
24
+ constructor(deps) {
25
+ this.deps = deps;
26
+ }
27
+ summaryOf(ev) {
28
+ const text = String(ev.text ?? "").slice(0, 1800);
29
+ const meta = `slack channel=${ev.channel} user=${ev.user} ts=${ev.ts}`;
30
+ return {
31
+ summary: `Founder via Slack: ${text.slice(0, 90)}`,
32
+ body: `${text}\n\n---\nSource: ${meta}\nRouted by openrig slack-inbound. Default destination per config; re-route via queue as needed.`,
33
+ };
34
+ }
35
+ /**
36
+ * Core landing attempt — NO dead-letter side effect. Dedup by ts (in-flight +
37
+ * durable seen). `reason` distinguishes a dedup skip from a genuine create
38
+ * failure so callers dead-letter ONLY real failures. On success, marks seen
39
+ * (durable qitem exists → safe).
40
+ */
41
+ async attemptLand(ev) {
42
+ const ts = ev.ts ?? "";
43
+ if (!ts || this.inflight.has(ts) || this.deps.seen.load().has(ts))
44
+ return { landed: false, reason: "dup" };
45
+ this.inflight.add(ts);
46
+ try {
47
+ const { summary, body } = this.summaryOf(ev);
48
+ let qitemId;
49
+ try {
50
+ qitemId = await createQitem(this.deps.runner, {
51
+ source: `human-${ev.user}@kernel`, // provenance classifies as human (name convention)
52
+ destination: this.deps.destination,
53
+ priority: "routine",
54
+ tags: ["founder-slack", "inbound"],
55
+ summary,
56
+ body,
57
+ });
58
+ }
59
+ catch (e) {
60
+ this.deps.log?.(`qitem create failed ts=${ts}: ${e.message}`);
61
+ return { landed: false, reason: "create_failed" };
62
+ }
63
+ this.deps.seen.mark(ts, "landed"); // durable qitem exists → safe to mark
64
+ this.deps.log?.(`qitem ${qitemId} -> ${this.deps.destination} (ts=${ts})`);
65
+ return { landed: true, qitemId };
66
+ }
67
+ finally {
68
+ this.inflight.delete(ts);
69
+ }
70
+ }
71
+ /**
72
+ * LIVE path: attempt to land; on a genuine create failure, dead-letter the
73
+ * event (attempt-counted) BEFORE returning — NOT marked seen (item 8).
74
+ */
75
+ async route(ev, attempts = 0) {
76
+ const r = await this.attemptLand(ev);
77
+ if (!r.landed && r.reason === "create_failed") {
78
+ this.deps.deadLetter.append(ev, attempts + 1);
79
+ this.deps.log?.(`dead-lettered ts=${ev.ts} (attempt ${attempts + 1})`);
80
+ }
81
+ return { landed: r.landed, qitemId: r.qitemId };
82
+ }
83
+ /**
84
+ * INTERRUPTION-SAFE retry (item 8): read the durable set NON-destructively,
85
+ * attempt each, then ATOMICALLY replace the file with only the still-failing
86
+ * entries. The original file stays intact until the atomic replace, so a crash
87
+ * at any point loses nothing (a since-landed event is skipped via the seen-set).
88
+ * Does NOT go through route() (which would double-append) — uses attemptLand.
89
+ */
90
+ async retryDeadLetters() {
91
+ const entries = this.deps.deadLetter.readAll();
92
+ if (entries.length === 0)
93
+ return { retried: 0, landed: 0 };
94
+ this.deps.log?.(`retrying ${entries.length} dead-letter(s)`);
95
+ const stillFailing = [];
96
+ let landed = 0;
97
+ const seen = this.deps.seen.load();
98
+ for (const e of entries) {
99
+ if (e.ev.ts && seen.has(e.ev.ts))
100
+ continue; // already landed → recovered, drop from set
101
+ const r = await this.attemptLand(e.ev);
102
+ if (r.landed)
103
+ landed++;
104
+ else if (r.reason === "create_failed")
105
+ stillFailing.push({ ev: e.ev, at: e.at, attempts: e.attempts + 1 });
106
+ // reason === "dup" (in-flight) → drop; a concurrent path owns it
107
+ }
108
+ this.deps.deadLetter.replaceAll(stillFailing); // atomic; original intact until here
109
+ return { retried: entries.length, landed };
110
+ }
111
+ }
112
+ /**
113
+ * Handle one Socket Mode envelope. FAST-ACK first, ALWAYS (item 8: Socket Mode
114
+ * punishes slow acks; transport redelivery is not the safety net). Then filter
115
+ * and route. Ack happens even if routing later fails — the dead-letter, not
116
+ * transport redelivery, is the zero-drop net.
117
+ */
118
+ export async function handleEnvelope(env, ack, router, log) {
119
+ if (env.envelope_id)
120
+ ack(); // fast-ack, unconditional, first
121
+ if (env.type === "disconnect")
122
+ return;
123
+ if (env.type !== "events_api")
124
+ return;
125
+ const ev = env.payload?.event ?? {};
126
+ if (!shouldIngest(ev)) {
127
+ if (ev.type)
128
+ log?.(`ignored non-ingestible event type=${ev.type} subtype=${ev.subtype ?? "-"} files=${ev.files?.length ?? 0}`);
129
+ return;
130
+ }
131
+ await router.route(ev);
132
+ }
133
+ //# sourceMappingURL=inbound.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inbound.js","sourceRoot":"","sources":["../../src/slack/inbound.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ export declare const SLACK_TEXT_CAP = 3900;
2
+ export declare const DEFAULT_BODY_EXCERPT = 800;
3
+ export interface QitemLike {
4
+ qitemId: string;
5
+ summary?: string | null;
6
+ body?: string | null;
7
+ destinationSession?: string | null;
8
+ }
9
+ export interface OutboundMessageOpts {
10
+ sourceLabel: string;
11
+ bodyExcerpt?: number;
12
+ /** T1076 extension point: extra Block Kit blocks (e.g. future media). v1 unused. */
13
+ extraBlocks?: unknown[];
14
+ }
15
+ export declare function containsSecret(text: string): boolean;
16
+ export declare function redactSecrets(text: string): string;
17
+ export interface SlackMessagePayload {
18
+ text: string;
19
+ blocks: unknown[];
20
+ }
21
+ /**
22
+ * Build the Slack payload for a human-destined qitem. Pure + deterministic
23
+ * (no clock, no io) so it is trivially testable and safe to snapshot.
24
+ */
25
+ export declare function buildOutboundMessage(q: QitemLike, opts: OutboundMessageOpts): SlackMessagePayload;
26
+ //# sourceMappingURL=message.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../src/slack/message.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,cAAc,OAAO,CAAC;AACnC,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oFAAoF;IACpF,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC;CACzB;AAWD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAKpD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMlD;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,EAAE,CAAC;CACnB;AAMD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,mBAAmB,GAAG,mBAAmB,CAiBjG"}
@@ -0,0 +1,60 @@
1
+ // Slice-11 slack-connector — outbound message construction.
2
+ //
3
+ // Locked item 7 (content hygiene): a posted message carries summary + qitem id
4
+ // + source + a BOUNDED body excerpt, and NEVER a token/secret/secret-bearing
5
+ // path. We never add our own credentials (we only render qitem fields), and as
6
+ // defense-in-depth we redact anything that looks like a Slack/bearer secret
7
+ // leaking through a qitem body before it goes out.
8
+ //
9
+ // T1076 (don't preclude Slice-12): construction is BLOCKS/ATTACHMENTS-capable —
10
+ // we always emit Block Kit `blocks` PLUS a plain-text fallback, and accept
11
+ // optional extra blocks / media refs so image relay can extend this later
12
+ // WITHOUT redefining the shape here. v1 ships text only.
13
+ export const SLACK_TEXT_CAP = 3900; // Slack hard-limits ~4000; stay under.
14
+ export const DEFAULT_BODY_EXCERPT = 800;
15
+ // Secret-looking patterns we refuse to forward (item 7 defense-in-depth).
16
+ const SECRET_PATTERNS = [
17
+ /xox[baprs]-[A-Za-z0-9-]+/g, // Slack bot/user/app/refresh tokens
18
+ /xapp-[A-Za-z0-9-]+/g, // Slack app-level (Socket Mode) token
19
+ /https:\/\/hooks\.slack\.com\/services\/[A-Za-z0-9/_-]+/g, // incoming webhook URL
20
+ /\bBearer\s+[A-Za-z0-9._-]{12,}/gi, // bearer tokens
21
+ /xoxe\.xox[bp]-[A-Za-z0-9-]+/g, // rotation tokens
22
+ ];
23
+ export function containsSecret(text) {
24
+ return SECRET_PATTERNS.some((p) => {
25
+ p.lastIndex = 0;
26
+ return p.test(text);
27
+ });
28
+ }
29
+ export function redactSecrets(text) {
30
+ let out = text;
31
+ for (const p of SECRET_PATTERNS) {
32
+ out = out.replace(p, "[redacted-secret]");
33
+ }
34
+ return out;
35
+ }
36
+ function clamp(s, max) {
37
+ return s.length > max ? s.slice(0, max) : s;
38
+ }
39
+ /**
40
+ * Build the Slack payload for a human-destined qitem. Pure + deterministic
41
+ * (no clock, no io) so it is trivially testable and safe to snapshot.
42
+ */
43
+ export function buildOutboundMessage(q, opts) {
44
+ const summary = redactSecrets(String(q.summary || "(no summary)"));
45
+ const bodyRaw = redactSecrets(String(q.body || ""));
46
+ const body = clamp(bodyRaw, opts.bodyExcerpt ?? DEFAULT_BODY_EXCERPT);
47
+ const dest = q.destinationSession || "(unknown destination)";
48
+ const footer = `qitem ${q.qitemId} → ${dest} on ${opts.sourceLabel}`;
49
+ const text = clamp(`:rotating_light: *${summary}*\n${body}\n_${footer}_`, SLACK_TEXT_CAP);
50
+ const blocks = [
51
+ { type: "section", text: { type: "mrkdwn", text: clamp(`:rotating_light: *${summary}*`, 3000) } },
52
+ ];
53
+ if (body.trim())
54
+ blocks.push({ type: "section", text: { type: "mrkdwn", text: clamp(body, 3000) } });
55
+ blocks.push({ type: "context", elements: [{ type: "mrkdwn", text: footer }] });
56
+ if (opts.extraBlocks?.length)
57
+ blocks.push(...opts.extraBlocks);
58
+ return { text, blocks };
59
+ }
60
+ //# sourceMappingURL=message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message.js","sourceRoot":"","sources":["../../src/slack/message.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import type { SeenStore } from "./state-store.js";
2
+ import type { QueueRunner, AlertFilterOpts } from "./queue-bridge.js";
3
+ import { type FetchImpl } from "./slack-api.js";
4
+ export interface OutboundDeps {
5
+ runner: QueueRunner;
6
+ seen: SeenStore;
7
+ webhookUrl: string;
8
+ fetchImpl?: FetchImpl;
9
+ sourceLabel: string;
10
+ filter: AlertFilterOpts;
11
+ bodyExcerpt?: number;
12
+ log?: (msg: string) => void;
13
+ }
14
+ export interface OutboundResult {
15
+ freshCount: number;
16
+ posted: string[];
17
+ failed: {
18
+ id: string;
19
+ error: string;
20
+ }[];
21
+ }
22
+ /**
23
+ * One outbound sweep. Posts every FRESH human alert, marking it seen ONLY after
24
+ * a 200. A failed post is logged loudly and left UNSEEN so the next sweep
25
+ * retries it — never a silent drop. Returns failures so the caller exits
26
+ * non-zero (fail-visible).
27
+ */
28
+ export declare function runOutboundOnce(deps: OutboundDeps): Promise<OutboundResult>;
29
+ export interface SeedResult {
30
+ seeded: number;
31
+ onlineStatus: string;
32
+ }
33
+ /**
34
+ * Item 9: on ENABLE, seed all currently-active human alerts as history/seen
35
+ * WITHOUT posting, so turning the connector on never replays the backlog.
36
+ * Returns an honest online-status line marking the transition.
37
+ */
38
+ export declare function seedBacklogOnEnable(deps: Pick<OutboundDeps, "runner" | "seen" | "filter" | "log">): Promise<SeedResult>;
39
+ //# sourceMappingURL=outbound.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbound.d.ts","sourceRoot":"","sources":["../../src/slack/outbound.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEtE,OAAO,EAAe,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG7D,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,eAAe,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACzC;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC,CA6BjF;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAQ7H"}
@@ -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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"}