@openrig/cli 0.4.7 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (463) hide show
  1. package/daemon/assets/claude-statusline-context.cjs +40 -8
  2. package/daemon/assets/plugins/openrig-core/hooks/scripts/activity-relay.cjs +0 -0
  3. package/daemon/assets/plugins/openrig-core/skills/applying-a-permission-policy/SKILL.md +120 -0
  4. package/daemon/assets/plugins/openrig-core/skills/claude-compaction-restore/scripts/precompact-hook.mjs +0 -0
  5. package/daemon/assets/plugins/openrig-core/skills/claude-compaction-restore/scripts/restore-from-jsonl.mjs +0 -0
  6. package/daemon/assets/plugins/openrig-core/skills/delegating-work/SKILL.md +43 -0
  7. package/daemon/assets/plugins/openrig-core/skills/forming-an-openrig-mental-model/SKILL.md +2 -0
  8. package/daemon/assets/plugins/openrig-core/skills/openrig-skills/SKILL.md +50 -57
  9. package/daemon/assets/plugins/openrig-core/skills/openrig-user/SKILL.md +84 -19
  10. package/daemon/assets/plugins/openrig-core/skills/queue-handoff/SKILL.md +2 -0
  11. package/daemon/assets/plugins/openrig-core/skills/seat-continuity-and-handover/SKILL.md +2 -1
  12. package/daemon/assets/plugins/openrig-core/skills/session-compaction-and-restore/SKILL.md +1 -0
  13. package/daemon/dist/adapters/claude-code-adapter.d.ts +36 -9
  14. package/daemon/dist/adapters/claude-code-adapter.d.ts.map +1 -1
  15. package/daemon/dist/adapters/claude-code-adapter.js +216 -49
  16. package/daemon/dist/adapters/claude-code-adapter.js.map +1 -1
  17. package/daemon/dist/adapters/claude-resume.d.ts +1 -1
  18. package/daemon/dist/adapters/claude-resume.d.ts.map +1 -1
  19. package/daemon/dist/adapters/claude-resume.js +8 -2
  20. package/daemon/dist/adapters/claude-resume.js.map +1 -1
  21. package/daemon/dist/adapters/codex-resume.d.ts +1 -1
  22. package/daemon/dist/adapters/codex-resume.d.ts.map +1 -1
  23. package/daemon/dist/adapters/codex-resume.js +4 -2
  24. package/daemon/dist/adapters/codex-resume.js.map +1 -1
  25. package/daemon/dist/adapters/codex-runtime-adapter.d.ts +12 -0
  26. package/daemon/dist/adapters/codex-runtime-adapter.d.ts.map +1 -1
  27. package/daemon/dist/adapters/codex-runtime-adapter.js +34 -7
  28. package/daemon/dist/adapters/codex-runtime-adapter.js.map +1 -1
  29. package/daemon/dist/adapters/pi-resume.d.ts +1 -1
  30. package/daemon/dist/adapters/pi-resume.d.ts.map +1 -1
  31. package/daemon/dist/adapters/pi-resume.js +7 -2
  32. package/daemon/dist/adapters/pi-resume.js.map +1 -1
  33. package/daemon/dist/adapters/pi-runtime-adapter.d.ts.map +1 -1
  34. package/daemon/dist/adapters/pi-runtime-adapter.js +4 -1
  35. package/daemon/dist/adapters/pi-runtime-adapter.js.map +1 -1
  36. package/daemon/dist/adapters/yolo-mode.d.ts +23 -0
  37. package/daemon/dist/adapters/yolo-mode.d.ts.map +1 -0
  38. package/daemon/dist/adapters/yolo-mode.js +49 -0
  39. package/daemon/dist/adapters/yolo-mode.js.map +1 -0
  40. package/daemon/dist/build-info.js +3 -3
  41. package/daemon/dist/db/migrations/055_node_permission_policy.d.ts +13 -0
  42. package/daemon/dist/db/migrations/055_node_permission_policy.d.ts.map +1 -0
  43. package/daemon/dist/db/migrations/055_node_permission_policy.js +17 -0
  44. package/daemon/dist/db/migrations/055_node_permission_policy.js.map +1 -0
  45. package/daemon/dist/db/migrations/056_rig_permission_policy.d.ts +13 -0
  46. package/daemon/dist/db/migrations/056_rig_permission_policy.d.ts.map +1 -0
  47. package/daemon/dist/db/migrations/056_rig_permission_policy.js +17 -0
  48. package/daemon/dist/db/migrations/056_rig_permission_policy.js.map +1 -0
  49. package/daemon/dist/db/migrations/057_node_policy_provenance.d.ts +19 -0
  50. package/daemon/dist/db/migrations/057_node_policy_provenance.d.ts.map +1 -0
  51. package/daemon/dist/db/migrations/057_node_policy_provenance.js +26 -0
  52. package/daemon/dist/db/migrations/057_node_policy_provenance.js.map +1 -0
  53. package/daemon/dist/db/migrations/058_rig_policy_provenance.d.ts +15 -0
  54. package/daemon/dist/db/migrations/058_rig_policy_provenance.d.ts.map +1 -0
  55. package/daemon/dist/db/migrations/058_rig_policy_provenance.js +22 -0
  56. package/daemon/dist/db/migrations/058_rig_policy_provenance.js.map +1 -0
  57. package/daemon/dist/domain/agent-activity-store.d.ts +1 -0
  58. package/daemon/dist/domain/agent-activity-store.d.ts.map +1 -1
  59. package/daemon/dist/domain/agent-activity-store.js +2 -2
  60. package/daemon/dist/domain/agent-activity-store.js.map +1 -1
  61. package/daemon/dist/domain/builtin-policy-reference.d.ts +13 -0
  62. package/daemon/dist/domain/builtin-policy-reference.d.ts.map +1 -0
  63. package/daemon/dist/domain/builtin-policy-reference.js +58 -0
  64. package/daemon/dist/domain/builtin-policy-reference.js.map +1 -0
  65. package/daemon/dist/domain/claude-activity-hooks.d.ts +33 -0
  66. package/daemon/dist/domain/claude-activity-hooks.d.ts.map +1 -0
  67. package/daemon/dist/domain/claude-activity-hooks.js +60 -0
  68. package/daemon/dist/domain/claude-activity-hooks.js.map +1 -0
  69. package/daemon/dist/domain/context-packs/bundle-assembler.d.ts +30 -0
  70. package/daemon/dist/domain/context-packs/bundle-assembler.d.ts.map +1 -1
  71. package/daemon/dist/domain/context-packs/bundle-assembler.js +31 -1
  72. package/daemon/dist/domain/context-packs/bundle-assembler.js.map +1 -1
  73. package/daemon/dist/domain/context-packs/context-pack-library-service.d.ts +69 -14
  74. package/daemon/dist/domain/context-packs/context-pack-library-service.d.ts.map +1 -1
  75. package/daemon/dist/domain/context-packs/context-pack-library-service.js +263 -48
  76. package/daemon/dist/domain/context-packs/context-pack-library-service.js.map +1 -1
  77. package/daemon/dist/domain/context-packs/context-pack-types.d.ts +2 -2
  78. package/daemon/dist/domain/context-packs/context-pack-types.d.ts.map +1 -1
  79. package/daemon/dist/domain/context-packs/context-pack-types.js.map +1 -1
  80. package/daemon/dist/domain/context-packs/manifest-parser.d.ts.map +1 -1
  81. package/daemon/dist/domain/context-packs/manifest-parser.js +11 -0
  82. package/daemon/dist/domain/context-packs/manifest-parser.js.map +1 -1
  83. package/daemon/dist/domain/context-packs/ref-safety.d.ts +11 -0
  84. package/daemon/dist/domain/context-packs/ref-safety.d.ts.map +1 -0
  85. package/daemon/dist/domain/context-packs/ref-safety.js +46 -0
  86. package/daemon/dist/domain/context-packs/ref-safety.js.map +1 -0
  87. package/daemon/dist/domain/context-packs/token-estimate.d.ts +3 -0
  88. package/daemon/dist/domain/context-packs/token-estimate.d.ts.map +1 -0
  89. package/daemon/dist/domain/context-packs/token-estimate.js +5 -0
  90. package/daemon/dist/domain/context-packs/token-estimate.js.map +1 -0
  91. package/daemon/dist/domain/native-resume-probe.d.ts +1 -1
  92. package/daemon/dist/domain/native-resume-probe.d.ts.map +1 -1
  93. package/daemon/dist/domain/native-resume-probe.js +11 -4
  94. package/daemon/dist/domain/native-resume-probe.js.map +1 -1
  95. package/daemon/dist/domain/node-inventory.js +2 -2
  96. package/daemon/dist/domain/node-inventory.js.map +1 -1
  97. package/daemon/dist/domain/permission-policy/policy-ref.d.ts +89 -0
  98. package/daemon/dist/domain/permission-policy/policy-ref.d.ts.map +1 -0
  99. package/daemon/dist/domain/permission-policy/policy-ref.js +171 -0
  100. package/daemon/dist/domain/permission-policy/policy-ref.js.map +1 -0
  101. package/daemon/dist/domain/permission-policy/policy-spec.d.ts +34 -0
  102. package/daemon/dist/domain/permission-policy/policy-spec.d.ts.map +1 -0
  103. package/daemon/dist/domain/permission-policy/policy-spec.js +106 -0
  104. package/daemon/dist/domain/permission-policy/policy-spec.js.map +1 -0
  105. package/daemon/dist/domain/plugin-vendor-service.d.ts +14 -0
  106. package/daemon/dist/domain/plugin-vendor-service.d.ts.map +1 -1
  107. package/daemon/dist/domain/plugin-vendor-service.js +26 -2
  108. package/daemon/dist/domain/plugin-vendor-service.js.map +1 -1
  109. package/daemon/dist/domain/provider/claude-usage-reader.d.ts +44 -0
  110. package/daemon/dist/domain/provider/claude-usage-reader.d.ts.map +1 -0
  111. package/daemon/dist/domain/provider/claude-usage-reader.js +112 -0
  112. package/daemon/dist/domain/provider/claude-usage-reader.js.map +1 -0
  113. package/daemon/dist/domain/provider/codex-auth-reader.d.ts +18 -0
  114. package/daemon/dist/domain/provider/codex-auth-reader.d.ts.map +1 -0
  115. package/daemon/dist/domain/provider/codex-auth-reader.js +64 -0
  116. package/daemon/dist/domain/provider/codex-auth-reader.js.map +1 -0
  117. package/daemon/dist/domain/provider/host-usage-rollup.d.ts +51 -0
  118. package/daemon/dist/domain/provider/host-usage-rollup.d.ts.map +1 -0
  119. package/daemon/dist/domain/provider/host-usage-rollup.js +162 -0
  120. package/daemon/dist/domain/provider/host-usage-rollup.js.map +1 -0
  121. package/daemon/dist/domain/provider/provider-collect.d.ts +22 -0
  122. package/daemon/dist/domain/provider/provider-collect.d.ts.map +1 -0
  123. package/daemon/dist/domain/provider/provider-collect.js +74 -0
  124. package/daemon/dist/domain/provider/provider-collect.js.map +1 -0
  125. package/daemon/dist/domain/provider/provider-policy.d.ts +38 -0
  126. package/daemon/dist/domain/provider/provider-policy.d.ts.map +1 -0
  127. package/daemon/dist/domain/provider/provider-policy.js +76 -0
  128. package/daemon/dist/domain/provider/provider-policy.js.map +1 -0
  129. package/daemon/dist/domain/provider/provider-read-model.d.ts +28 -0
  130. package/daemon/dist/domain/provider/provider-read-model.d.ts.map +1 -0
  131. package/daemon/dist/domain/provider/provider-read-model.js +68 -0
  132. package/daemon/dist/domain/provider/provider-read-model.js.map +1 -0
  133. package/daemon/dist/domain/provider/provider-service-impl.d.ts +26 -0
  134. package/daemon/dist/domain/provider/provider-service-impl.d.ts.map +1 -0
  135. package/daemon/dist/domain/provider/provider-service-impl.js +83 -0
  136. package/daemon/dist/domain/provider/provider-service-impl.js.map +1 -0
  137. package/daemon/dist/domain/provider/provider-service.d.ts +33 -0
  138. package/daemon/dist/domain/provider/provider-service.d.ts.map +1 -0
  139. package/daemon/dist/domain/provider/provider-service.js +6 -0
  140. package/daemon/dist/domain/provider/provider-service.js.map +1 -0
  141. package/daemon/dist/domain/provider/provider-signals.d.ts +76 -0
  142. package/daemon/dist/domain/provider/provider-signals.d.ts.map +1 -0
  143. package/daemon/dist/domain/provider/provider-signals.js +144 -0
  144. package/daemon/dist/domain/provider/provider-signals.js.map +1 -0
  145. package/daemon/dist/domain/provider/provider-types.d.ts +101 -0
  146. package/daemon/dist/domain/provider/provider-types.d.ts.map +1 -0
  147. package/daemon/dist/domain/provider/provider-types.js +7 -0
  148. package/daemon/dist/domain/provider/provider-types.js.map +1 -0
  149. package/daemon/dist/domain/provider/reactive-tap.d.ts +29 -0
  150. package/daemon/dist/domain/provider/reactive-tap.d.ts.map +1 -0
  151. package/daemon/dist/domain/provider/reactive-tap.js +80 -0
  152. package/daemon/dist/domain/provider/reactive-tap.js.map +1 -0
  153. package/daemon/dist/domain/restore-orchestrator.d.ts +14 -0
  154. package/daemon/dist/domain/restore-orchestrator.d.ts.map +1 -1
  155. package/daemon/dist/domain/restore-orchestrator.js +90 -6
  156. package/daemon/dist/domain/restore-orchestrator.js.map +1 -1
  157. package/daemon/dist/domain/rig-expansion-service.d.ts.map +1 -1
  158. package/daemon/dist/domain/rig-expansion-service.js +10 -1
  159. package/daemon/dist/domain/rig-expansion-service.js.map +1 -1
  160. package/daemon/dist/domain/rig-repository.d.ts +45 -0
  161. package/daemon/dist/domain/rig-repository.d.ts.map +1 -1
  162. package/daemon/dist/domain/rig-repository.js +75 -1
  163. package/daemon/dist/domain/rig-repository.js.map +1 -1
  164. package/daemon/dist/domain/rigspec-codec.d.ts.map +1 -1
  165. package/daemon/dist/domain/rigspec-codec.js +6 -0
  166. package/daemon/dist/domain/rigspec-codec.js.map +1 -1
  167. package/daemon/dist/domain/rigspec-exporter.d.ts.map +1 -1
  168. package/daemon/dist/domain/rigspec-exporter.js +8 -0
  169. package/daemon/dist/domain/rigspec-exporter.js.map +1 -1
  170. package/daemon/dist/domain/rigspec-instantiator.d.ts +25 -24
  171. package/daemon/dist/domain/rigspec-instantiator.d.ts.map +1 -1
  172. package/daemon/dist/domain/rigspec-instantiator.js +190 -69
  173. package/daemon/dist/domain/rigspec-instantiator.js.map +1 -1
  174. package/daemon/dist/domain/rigspec-preflight.d.ts +22 -0
  175. package/daemon/dist/domain/rigspec-preflight.d.ts.map +1 -1
  176. package/daemon/dist/domain/rigspec-preflight.js +76 -0
  177. package/daemon/dist/domain/rigspec-preflight.js.map +1 -1
  178. package/daemon/dist/domain/rigspec-schema.d.ts.map +1 -1
  179. package/daemon/dist/domain/rigspec-schema.js +25 -0
  180. package/daemon/dist/domain/rigspec-schema.js.map +1 -1
  181. package/daemon/dist/domain/runtime-adapter.d.ts +7 -11
  182. package/daemon/dist/domain/runtime-adapter.d.ts.map +1 -1
  183. package/daemon/dist/domain/runtime-adapter.js.map +1 -1
  184. package/daemon/dist/domain/scope/attestation-lineage.generated.d.ts +14 -0
  185. package/daemon/dist/domain/scope/attestation-lineage.generated.d.ts.map +1 -0
  186. package/daemon/dist/domain/scope/attestation-lineage.generated.js +26 -0
  187. package/daemon/dist/domain/scope/attestation-lineage.generated.js.map +1 -0
  188. package/daemon/dist/domain/scope/scope-approve.d.ts +13 -0
  189. package/daemon/dist/domain/scope/scope-approve.d.ts.map +1 -1
  190. package/daemon/dist/domain/scope/scope-approve.js +50 -10
  191. package/daemon/dist/domain/scope/scope-approve.js.map +1 -1
  192. package/daemon/dist/domain/seat-handover-service.d.ts.map +1 -1
  193. package/daemon/dist/domain/seat-handover-service.js +7 -1
  194. package/daemon/dist/domain/seat-handover-service.js.map +1 -1
  195. package/daemon/dist/domain/startup-validation.d.ts.map +1 -1
  196. package/daemon/dist/domain/startup-validation.js +18 -54
  197. package/daemon/dist/domain/startup-validation.js.map +1 -1
  198. package/daemon/dist/domain/stream-store.d.ts +4 -0
  199. package/daemon/dist/domain/stream-store.d.ts.map +1 -1
  200. package/daemon/dist/domain/stream-store.js +15 -2
  201. package/daemon/dist/domain/stream-store.js.map +1 -1
  202. package/daemon/dist/domain/successor-session-launcher.d.ts +4 -0
  203. package/daemon/dist/domain/successor-session-launcher.d.ts.map +1 -1
  204. package/daemon/dist/domain/successor-session-launcher.js +2 -0
  205. package/daemon/dist/domain/successor-session-launcher.js.map +1 -1
  206. package/daemon/dist/domain/types.d.ts +19 -9
  207. package/daemon/dist/domain/types.d.ts.map +1 -1
  208. package/daemon/dist/domain/types.js.map +1 -1
  209. package/daemon/dist/domain/workspace/default-workspace-scaffold.js +1 -1
  210. package/daemon/dist/routes/agent-images.d.ts.map +1 -1
  211. package/daemon/dist/routes/agent-images.js +2 -0
  212. package/daemon/dist/routes/agent-images.js.map +1 -1
  213. package/daemon/dist/routes/context-packs.d.ts.map +1 -1
  214. package/daemon/dist/routes/context-packs.js +157 -75
  215. package/daemon/dist/routes/context-packs.js.map +1 -1
  216. package/daemon/dist/routes/provider.d.ts +3 -0
  217. package/daemon/dist/routes/provider.d.ts.map +1 -0
  218. package/daemon/dist/routes/provider.js +124 -0
  219. package/daemon/dist/routes/provider.js.map +1 -0
  220. package/daemon/dist/routes/rigs.js +8 -0
  221. package/daemon/dist/routes/rigs.js.map +1 -1
  222. package/daemon/dist/routes/scope-approve.d.ts.map +1 -1
  223. package/daemon/dist/routes/scope-approve.js +6 -3
  224. package/daemon/dist/routes/scope-approve.js.map +1 -1
  225. package/daemon/dist/routes/scope-audit.d.ts.map +1 -1
  226. package/daemon/dist/routes/scope-audit.js +4 -1
  227. package/daemon/dist/routes/scope-audit.js.map +1 -1
  228. package/daemon/dist/routes/stream.d.ts.map +1 -1
  229. package/daemon/dist/routes/stream.js +71 -1
  230. package/daemon/dist/routes/stream.js.map +1 -1
  231. package/daemon/dist/server.d.ts +3 -0
  232. package/daemon/dist/server.d.ts.map +1 -1
  233. package/daemon/dist/server.js +5 -0
  234. package/daemon/dist/server.js.map +1 -1
  235. package/daemon/dist/startup.d.ts.map +1 -1
  236. package/daemon/dist/startup.js +38 -12
  237. package/daemon/dist/startup.js.map +1 -1
  238. package/daemon/docs/reference/developing.md +39 -0
  239. package/daemon/docs/reference/rig-spec.md +19 -0
  240. package/daemon/policies/builtin/locked.policy.md +24 -0
  241. package/daemon/policies/builtin/open.policy.md +24 -0
  242. package/daemon/policies/builtin/standard.policy.md +25 -0
  243. package/daemon/policies/builtin/yolo.policy.md +20 -0
  244. package/daemon/policies/examples/my-cautious-dev.policy.md +40 -0
  245. package/daemon/specs/agents/apps/vault-specialist/agent.yaml +1 -1
  246. package/daemon/specs/agents/conveyor/builder/agent.yaml +1 -1
  247. package/daemon/specs/agents/conveyor/lead/agent.yaml +1 -1
  248. package/daemon/specs/agents/conveyor/planner/agent.yaml +1 -1
  249. package/daemon/specs/agents/conveyor/reviewer/agent.yaml +1 -1
  250. package/daemon/specs/agents/design/product-designer/agent.yaml +1 -1
  251. package/daemon/specs/agents/development/implementer/agent.yaml +1 -1
  252. package/daemon/specs/agents/development/qa/agent.yaml +1 -1
  253. package/daemon/specs/agents/factory-rsi/dogfood/agent.yaml +1 -1
  254. package/daemon/specs/agents/factory-rsi/release-manager/agent.yaml +1 -1
  255. package/daemon/specs/agents/orchestration/orchestrator/agent.yaml +1 -1
  256. package/daemon/specs/agents/product-management/pm/agent.yaml +1 -0
  257. package/daemon/specs/agents/research/analyst/agent.yaml +1 -1
  258. package/daemon/specs/agents/research/synthesizer/agent.yaml +1 -1
  259. package/daemon/specs/agents/review/independent-reviewer/agent.yaml +1 -1
  260. package/daemon/specs/agents/shared/agent.yaml +6 -0
  261. package/daemon/specs/agents/shared/runtime/claude-activity-hooks.json +4 -0
  262. package/daemon/specs/agents/shared/runtime/claude-settings.fragment.json +1 -20
  263. package/daemon/specs/agents/shared/skills/core/openrig-architect/SKILL.md +0 -2
  264. package/daemon/specs/agents/shared/skills/core/watchdog/SKILL.md +1 -0
  265. package/daemon/specs/agents/shared/skills/process/systematic-debugging/find-polluter.sh +0 -0
  266. package/daemon/specs/agents/shared/skills/process/verification-before-completion/SKILL.md +1 -0
  267. package/dist/bin-wrapper.d.ts.map +1 -1
  268. package/dist/bin-wrapper.js +7 -0
  269. package/dist/bin-wrapper.js.map +1 -1
  270. package/dist/build-info.js +3 -3
  271. package/dist/commands/agent-image.d.ts.map +1 -1
  272. package/dist/commands/agent-image.js +2 -1
  273. package/dist/commands/agent-image.js.map +1 -1
  274. package/dist/commands/broadcast.d.ts.map +1 -1
  275. package/dist/commands/broadcast.js +37 -2
  276. package/dist/commands/broadcast.js.map +1 -1
  277. package/dist/commands/context.d.ts +2 -7
  278. package/dist/commands/context.d.ts.map +1 -1
  279. package/dist/commands/context.js +391 -213
  280. package/dist/commands/context.js.map +1 -1
  281. package/dist/commands/provider.d.ts +4 -0
  282. package/dist/commands/provider.d.ts.map +1 -0
  283. package/dist/commands/provider.js +218 -0
  284. package/dist/commands/provider.js.map +1 -0
  285. package/dist/commands/ps.d.ts +7 -0
  286. package/dist/commands/ps.d.ts.map +1 -1
  287. package/dist/commands/ps.js +34 -4
  288. package/dist/commands/ps.js.map +1 -1
  289. package/dist/commands/queue.d.ts.map +1 -1
  290. package/dist/commands/queue.js +38 -8
  291. package/dist/commands/queue.js.map +1 -1
  292. package/dist/commands/scope.d.ts.map +1 -1
  293. package/dist/commands/scope.js +48 -4
  294. package/dist/commands/scope.js.map +1 -1
  295. package/dist/commands/send.d.ts.map +1 -1
  296. package/dist/commands/send.js +70 -11
  297. package/dist/commands/send.js.map +1 -1
  298. package/dist/commands/setup.d.ts +14 -0
  299. package/dist/commands/setup.d.ts.map +1 -1
  300. package/dist/commands/setup.js +131 -8
  301. package/dist/commands/setup.js.map +1 -1
  302. package/dist/commands/stream.d.ts +1 -0
  303. package/dist/commands/stream.d.ts.map +1 -1
  304. package/dist/commands/stream.js +93 -0
  305. package/dist/commands/stream.js.map +1 -1
  306. package/dist/commands/tui.d.ts +4 -0
  307. package/dist/commands/tui.d.ts.map +1 -0
  308. package/dist/commands/tui.js +29 -0
  309. package/dist/commands/tui.js.map +1 -0
  310. package/dist/commands/walk.d.ts +19 -0
  311. package/dist/commands/walk.d.ts.map +1 -0
  312. package/dist/commands/walk.js +139 -0
  313. package/dist/commands/walk.js.map +1 -0
  314. package/dist/context-resolve.d.ts +14 -0
  315. package/dist/context-resolve.d.ts.map +1 -0
  316. package/dist/context-resolve.js +40 -0
  317. package/dist/context-resolve.js.map +1 -0
  318. package/dist/front-door.d.ts +31 -0
  319. package/dist/front-door.d.ts.map +1 -0
  320. package/dist/front-door.js +114 -0
  321. package/dist/front-door.js.map +1 -0
  322. package/dist/index.d.ts +3 -1
  323. package/dist/index.d.ts.map +1 -1
  324. package/dist/index.js +19 -6
  325. package/dist/index.js.map +1 -1
  326. package/dist/lib/scope/attestation-lineage.d.ts +14 -0
  327. package/dist/lib/scope/attestation-lineage.d.ts.map +1 -0
  328. package/dist/lib/scope/attestation-lineage.js +34 -0
  329. package/dist/lib/scope/attestation-lineage.js.map +1 -0
  330. package/package.json +4 -2
  331. package/tui/dist/daemon-client.d.ts +56 -0
  332. package/tui/dist/daemon-client.d.ts.map +1 -0
  333. package/tui/dist/daemon-client.js +99 -0
  334. package/tui/dist/daemon-client.js.map +1 -0
  335. package/tui/dist/demo-data.d.ts +3 -0
  336. package/tui/dist/demo-data.d.ts.map +1 -0
  337. package/tui/dist/demo-data.js +52 -0
  338. package/tui/dist/demo-data.js.map +1 -0
  339. package/tui/dist/detail.d.ts +34 -0
  340. package/tui/dist/detail.d.ts.map +1 -0
  341. package/tui/dist/detail.js +47 -0
  342. package/tui/dist/detail.js.map +1 -0
  343. package/tui/dist/grammar.d.ts +3 -0
  344. package/tui/dist/grammar.d.ts.map +1 -0
  345. package/tui/dist/grammar.js +66 -0
  346. package/tui/dist/grammar.js.map +1 -0
  347. package/tui/dist/hydrate.d.ts +78 -0
  348. package/tui/dist/hydrate.d.ts.map +1 -0
  349. package/tui/dist/hydrate.js +294 -0
  350. package/tui/dist/hydrate.js.map +1 -0
  351. package/tui/dist/index.d.ts +12 -0
  352. package/tui/dist/index.d.ts.map +1 -0
  353. package/tui/dist/index.js +12 -0
  354. package/tui/dist/index.js.map +1 -0
  355. package/tui/dist/input.d.ts +21 -0
  356. package/tui/dist/input.d.ts.map +1 -0
  357. package/tui/dist/input.js +128 -0
  358. package/tui/dist/input.js.map +1 -0
  359. package/tui/dist/live.d.ts +20 -0
  360. package/tui/dist/live.d.ts.map +1 -0
  361. package/tui/dist/live.js +67 -0
  362. package/tui/dist/live.js.map +1 -0
  363. package/tui/dist/main.d.ts +3 -0
  364. package/tui/dist/main.d.ts.map +1 -0
  365. package/tui/dist/main.js +184 -0
  366. package/tui/dist/main.js.map +1 -0
  367. package/tui/dist/motion.d.ts +13 -0
  368. package/tui/dist/motion.d.ts.map +1 -0
  369. package/tui/dist/motion.js +31 -0
  370. package/tui/dist/motion.js.map +1 -0
  371. package/tui/dist/navigator.d.ts +21 -0
  372. package/tui/dist/navigator.d.ts.map +1 -0
  373. package/tui/dist/navigator.js +168 -0
  374. package/tui/dist/navigator.js.map +1 -0
  375. package/tui/dist/refresh.d.ts +3 -0
  376. package/tui/dist/refresh.d.ts.map +1 -0
  377. package/tui/dist/refresh.js +9 -0
  378. package/tui/dist/refresh.js.map +1 -0
  379. package/tui/dist/render.d.ts +21 -0
  380. package/tui/dist/render.d.ts.map +1 -0
  381. package/tui/dist/render.js +807 -0
  382. package/tui/dist/render.js.map +1 -0
  383. package/tui/dist/sections.d.ts +4 -0
  384. package/tui/dist/sections.d.ts.map +1 -0
  385. package/tui/dist/sections.js +19 -0
  386. package/tui/dist/sections.js.map +1 -0
  387. package/tui/dist/socket-server.d.ts +24 -0
  388. package/tui/dist/socket-server.d.ts.map +1 -0
  389. package/tui/dist/socket-server.js +85 -0
  390. package/tui/dist/socket-server.js.map +1 -0
  391. package/tui/dist/state.d.ts +51 -0
  392. package/tui/dist/state.d.ts.map +1 -0
  393. package/tui/dist/state.js +480 -0
  394. package/tui/dist/state.js.map +1 -0
  395. package/tui/dist/stylize.d.ts +4 -0
  396. package/tui/dist/stylize.d.ts.map +1 -0
  397. package/tui/dist/stylize.js +248 -0
  398. package/tui/dist/stylize.js.map +1 -0
  399. package/tui/dist/theme.d.ts +19 -0
  400. package/tui/dist/theme.d.ts.map +1 -0
  401. package/tui/dist/theme.js +86 -0
  402. package/tui/dist/theme.js.map +1 -0
  403. package/tui/dist/topology/canvas.d.ts +43 -0
  404. package/tui/dist/topology/canvas.d.ts.map +1 -0
  405. package/tui/dist/topology/canvas.js +131 -0
  406. package/tui/dist/topology/canvas.js.map +1 -0
  407. package/tui/dist/topology/fixture.d.ts +4 -0
  408. package/tui/dist/topology/fixture.d.ts.map +1 -0
  409. package/tui/dist/topology/fixture.js +71 -0
  410. package/tui/dist/topology/fixture.js.map +1 -0
  411. package/tui/dist/topology/glyphs.d.ts +21 -0
  412. package/tui/dist/topology/glyphs.d.ts.map +1 -0
  413. package/tui/dist/topology/glyphs.js +49 -0
  414. package/tui/dist/topology/glyphs.js.map +1 -0
  415. package/tui/dist/topology/graph-types.d.ts +39 -0
  416. package/tui/dist/topology/graph-types.d.ts.map +1 -0
  417. package/tui/dist/topology/graph-types.js +2 -0
  418. package/tui/dist/topology/graph-types.js.map +1 -0
  419. package/tui/dist/topology/layout.d.ts +52 -0
  420. package/tui/dist/topology/layout.d.ts.map +1 -0
  421. package/tui/dist/topology/layout.js +118 -0
  422. package/tui/dist/topology/layout.js.map +1 -0
  423. package/tui/dist/topology/render-graph.d.ts +8 -0
  424. package/tui/dist/topology/render-graph.d.ts.map +1 -0
  425. package/tui/dist/topology/render-graph.js +20 -0
  426. package/tui/dist/topology/render-graph.js.map +1 -0
  427. package/tui/dist/topology/runtime-marks.d.ts +53 -0
  428. package/tui/dist/topology/runtime-marks.d.ts.map +1 -0
  429. package/tui/dist/topology/runtime-marks.js +185 -0
  430. package/tui/dist/topology/runtime-marks.js.map +1 -0
  431. package/tui/dist/topology/styles/braille.d.ts +5 -0
  432. package/tui/dist/topology/styles/braille.d.ts.map +1 -0
  433. package/tui/dist/topology/styles/braille.js +84 -0
  434. package/tui/dist/topology/styles/braille.js.map +1 -0
  435. package/tui/dist/topology/styles/hatchet.d.ts +41 -0
  436. package/tui/dist/topology/styles/hatchet.d.ts.map +1 -0
  437. package/tui/dist/topology/styles/hatchet.js +146 -0
  438. package/tui/dist/topology/styles/hatchet.js.map +1 -0
  439. package/tui/dist/types.d.ts +362 -0
  440. package/tui/dist/types.d.ts.map +1 -0
  441. package/tui/dist/types.js +6 -0
  442. package/tui/dist/types.js.map +1 -0
  443. package/ui/dist/assets/{index-DkNi0RT8.js → index-Dv5VaLCN.js} +135 -135
  444. package/ui/dist/index.html +1 -1
  445. package/daemon/specs/agents/shared/skills/pm/backlog-capture/SKILL.md +0 -43
  446. package/daemon/specs/agents/shared/skills/pm/context-builder/SKILL.md +0 -87
  447. package/daemon/specs/agents/shared/skills/pm/exec-summary/SKILL.md +0 -84
  448. package/daemon/specs/agents/shared/skills/pm/office-hours/SKILL.md +0 -129
  449. package/daemon/specs/agents/shared/skills/pm/plan-review/SKILL.md +0 -98
  450. package/daemon/specs/agents/shared/skills/pm/requirements-writer/SKILL.md +0 -113
  451. package/daemon/specs/agents/shared/skills/pm/ui-mockup/SKILL.md +0 -76
  452. package/daemon/specs/agents/shared/skills/pods/development-team/SKILL.md +0 -148
  453. package/daemon/specs/agents/shared/skills/pods/orchestration-team/SKILL.md +0 -266
  454. package/daemon/specs/agents/shared/skills/pods/review-team/SKILL.md +0 -213
  455. package/daemon/specs/agents/shared/skills/process/systematic-debugging/CREATION-LOG.md +0 -119
  456. package/daemon/specs/agents/shared/skills/process/systematic-debugging/test-academic.md +0 -14
  457. package/daemon/specs/agents/shared/skills/process/systematic-debugging/test-pressure-1.md +0 -58
  458. package/daemon/specs/agents/shared/skills/process/systematic-debugging/test-pressure-2.md +0 -68
  459. package/daemon/specs/agents/shared/skills/process/systematic-debugging/test-pressure-3.md +0 -69
  460. package/dist/commands/context-pack.d.ts +0 -4
  461. package/dist/commands/context-pack.d.ts.map +0 -1
  462. package/dist/commands/context-pack.js +0 -357
  463. package/dist/commands/context-pack.js.map +0 -1
@@ -1,139 +1,191 @@
1
+ // Rig Context / Composable Context Injection — the `rig context` CLI verb
2
+ // family (Atom-7 renamed the retired `context-pack` grammar to `rig context`;
3
+ // the pack STORE contract — kind/id/API/on-disk dir — is unchanged).
4
+ //
5
+ // Delivery-free subcommands parallel to `rig specs`:
6
+ // list / show / preview / compose / add / rm / sync
7
+ //
8
+ // Each delegates to /api/context-packs/library/* against the daemon.
9
+ // The `add` verb installs a pack from a directory at
10
+ // ~/.openrig/context-packs/<name>/ — host-symlink-free contract,
11
+ // matches `rig specs add` shape (regular files only; no symlinks).
1
12
  import { Command } from "commander";
13
+ import { cpSync, existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, } from "node:fs";
14
+ import { basename, extname, isAbsolute, join, resolve } from "node:path";
15
+ import { parse as parseYaml } from "yaml";
16
+ import { getDefaultOpenRigPath } from "../openrig-compat.js";
2
17
  import { DaemonClient } from "../client.js";
3
18
  import { getDaemonStatus, getDaemonUrl } from "../daemon-lifecycle.js";
4
19
  import { realDeps } from "./daemon.js";
5
- const FRESHNESS_THRESHOLD_S = 600; // 10 minutes
6
- function ageLabel(sampledAt) {
7
- if (!sampledAt)
8
- return "\u2014";
9
- const age = Math.max(0, Math.floor((Date.now() - new Date(sampledAt).getTime()) / 1000));
10
- if (age < 60)
11
- return "<1m ago";
12
- const minutes = Math.floor(age / 60);
13
- if (minutes < 60)
14
- return `${minutes}m ago`;
15
- const hours = Math.floor(minutes / 60);
16
- if (hours < 48)
17
- return `${hours}h ago`;
18
- const days = Math.floor(hours / 24);
19
- return `${days}d ago`;
20
+ // Slice-03 Atom 2 mirror the daemon's per-segment ref contract at the
21
+ // local install boundary. This must run before creating the context store.
22
+ const SAFE_REF_SEGMENT = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
23
+ // Slice-03 lineage repair (R2 HIGH-2): the install boundary mirrors the daemon
24
+ // bounded, delimiter-free version token (ref-safety.SAFE_VERSION) so an unsafe
25
+ // version is rejected BEFORE any local write — matching the per-segment ref
26
+ // mirror above.
27
+ const SAFE_INSTALL_VERSION = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,31}$/;
28
+ function assertSafeInstallRef(ref) {
29
+ const safe = ref.length > 0 &&
30
+ ref.split("/").every((segment) => segment.length > 0 && segment !== "." && segment !== ".." && SAFE_REF_SEGMENT.test(segment));
31
+ if (!safe) {
32
+ throw new Error(`unsafe install ref '${ref}' — a ref must be one or more '/'-separated segments, each matching ` +
33
+ `[A-Za-z0-9][A-Za-z0-9._-]{0,63} (no '.'/'..', no absolute path, no empty segment, no ` +
34
+ `whitespace or injection), so packs stay inside the context store root.`);
35
+ }
20
36
  }
21
- function computeFreshness(sampledAt) {
22
- if (!sampledAt)
23
- return "none";
24
- const age = (Date.now() - new Date(sampledAt).getTime()) / 1000;
25
- return age <= FRESHNESS_THRESHOLD_S ? "fresh" : "stale";
37
+ function assertTreeHasNoSymlinks(root) {
38
+ const stack = [root];
39
+ while (stack.length > 0) {
40
+ const current = stack.pop();
41
+ for (const entry of readdirSync(current, { withFileTypes: true })) {
42
+ const absPath = join(current, entry.name);
43
+ if (entry.isSymbolicLink()) {
44
+ throw new Error(`Context pack directories must not contain symlinks: ${absPath}`);
45
+ }
46
+ if (entry.isDirectory())
47
+ stack.push(absPath);
48
+ }
49
+ }
50
+ }
51
+ // Slice-03 lineage repair (R2 HIGH-1): a lexically-safe path-like install ref
52
+ // can still escape the store if one of its parent namespace segments is a
53
+ // symlink (or a non-directory). Walk every ANCESTOR segment under the store root
54
+ // and reject before the copy — the FS-canonical containment the lexical ref
55
+ // check alone cannot give, mirroring the daemon compose namespace walk
56
+ // (context-pack-library-service.ts). A not-yet-created segment (ENOENT) is safe:
57
+ // cpSync will materialize it as a real directory.
58
+ function assertDestinationNamespaceContained(targetRoot, installName) {
59
+ const segments = installName.split("/");
60
+ let cursor = targetRoot;
61
+ for (const segment of segments.slice(0, -1)) {
62
+ cursor = join(cursor, segment);
63
+ let stat;
64
+ try {
65
+ stat = lstatSync(cursor);
66
+ }
67
+ catch (err) {
68
+ if (err.code === "ENOENT")
69
+ break;
70
+ throw err;
71
+ }
72
+ if (stat.isSymbolicLink() || !stat.isDirectory()) {
73
+ throw new Error(`unsafe install ref '${installName}' — its namespace segment '${cursor}' is a symlink or non-directory, ` +
74
+ `so the copy would escape the context store root. Remove it or install under a different --name.`);
75
+ }
76
+ }
26
77
  }
27
- function analyze(node) {
28
- const ctx = node.contextUsage ?? {};
29
- const used = ctx.usedPercentage != null ? Math.round(ctx.usedPercentage) : null;
30
- const remaining = ctx.remainingPercentage != null ? Math.round(ctx.remainingPercentage) : null;
31
- const window = ctx.contextWindowSize ?? null;
32
- const sampledAt = ctx.sampledAt ?? null;
33
- const source = ctx.source ?? null;
34
- const availability = ctx.availability ?? (used != null ? "known" : "unknown");
35
- if (used == null) {
36
- return {
37
- session: node.canonicalSessionName ?? "",
38
- rig: node.rigName ?? "",
39
- logicalId: node.logicalId ?? "",
40
- runtime: node.runtime ?? "unknown",
41
- usedPercentage: null, remainingPercentage: null, contextWindowSize: null,
42
- urgency: "unknown", freshness: "none", status: "unknown", displayStatus: "unknown",
43
- source, availability, sampledAt, staleness: "\u2014", fresh: false,
44
- };
78
+ const ALLOWED_CONTEXT_PACK_SUFFIXES = new Set([".md", ".markdown", ".yaml", ".yml", ".txt"]);
79
+ function validateContextPackManifestForInstall(manifestPath) {
80
+ let parsed;
81
+ try {
82
+ parsed = parseYaml(readFileSync(manifestPath, "utf-8"));
45
83
  }
46
- const urgency = used >= 80 ? "critical" : used >= 60 ? "warning" : "low";
47
- const freshness = computeFreshness(sampledAt);
48
- let status;
49
- let displayStatus;
50
- if (urgency === "critical") {
51
- status = freshness === "fresh" ? "critical" : "critical_stale";
52
- displayStatus = freshness === "fresh" ? "CRITICAL" : "CRITICAL (stale)";
84
+ catch (err) {
85
+ throw new Error(`manifest at ${manifestPath} is not valid YAML: ${err.message}`);
53
86
  }
54
- else if (urgency === "warning") {
55
- status = freshness === "fresh" ? "warning" : "warning_stale";
56
- displayStatus = freshness === "fresh" ? "WARNING" : "WARNING (stale)";
87
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
88
+ throw new Error(`manifest at ${manifestPath} must be a YAML object at the root`);
57
89
  }
58
- else if (freshness === "fresh") {
59
- status = "ok";
60
- displayStatus = "ok";
90
+ const obj = parsed;
91
+ if (typeof obj["name"] !== "string" || obj["name"].length === 0) {
92
+ throw new Error(`manifest at ${manifestPath} is missing required field 'name' (string)`);
61
93
  }
62
- else {
63
- status = "stale";
64
- displayStatus = "stale";
94
+ if (obj["version"] === undefined || obj["version"] === null) {
95
+ throw new Error(`manifest at ${manifestPath} is missing required field 'version'`);
96
+ }
97
+ const versionStr = String(obj["version"]);
98
+ if (!SAFE_INSTALL_VERSION.test(versionStr)) {
99
+ throw new Error(`manifest at ${manifestPath} has an invalid version '${versionStr}' — a version must be a single bounded ` +
100
+ `token [A-Za-z0-9][A-Za-z0-9._+-]{0,31} (no ':' or separator, no whitespace, ≤32 chars).`);
101
+ }
102
+ const files = obj["files"];
103
+ if (!Array.isArray(files)) {
104
+ throw new Error(`manifest at ${manifestPath} must declare 'files: [...]'`);
105
+ }
106
+ for (let i = 0; i < files.length; i++) {
107
+ const entry = files[i];
108
+ if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
109
+ throw new Error(`manifest at ${manifestPath} has malformed entry at files[${i}]`);
110
+ }
111
+ const file = entry;
112
+ const relPath = file["path"];
113
+ if (typeof relPath !== "string" || relPath.length === 0) {
114
+ throw new Error(`manifest at ${manifestPath} files[${i}] missing 'path' (string)`);
115
+ }
116
+ if (relPath.includes("..") || isAbsolute(relPath) || relPath.startsWith("\\")) {
117
+ throw new Error(`manifest at ${manifestPath} files[${i}].path '${relPath}' must be a relative path inside the pack (no '..' segments, no leading '/')`);
118
+ }
119
+ if (!ALLOWED_CONTEXT_PACK_SUFFIXES.has(extname(relPath))) {
120
+ throw new Error(`manifest at ${manifestPath} files[${i}].path '${relPath}' has an unsupported suffix; allowed: ${Array.from(ALLOWED_CONTEXT_PACK_SUFFIXES).join(", ")}`);
121
+ }
122
+ if (typeof file["role"] !== "string" || file["role"].length === 0) {
123
+ throw new Error(`manifest at ${manifestPath} files[${i}] missing 'role' (string)`);
124
+ }
65
125
  }
66
- return {
67
- session: node.canonicalSessionName ?? "",
68
- rig: node.rigName ?? "",
69
- logicalId: node.logicalId ?? "",
70
- runtime: node.runtime ?? "unknown",
71
- usedPercentage: used, remainingPercentage: remaining, contextWindowSize: window,
72
- urgency, freshness, status, displayStatus,
73
- source, availability, sampledAt, staleness: ageLabel(sampledAt), fresh: freshness === "fresh",
74
- };
75
- }
76
- const STATUS_RANK = {
77
- critical: 0, critical_stale: 0,
78
- warning: 1, warning_stale: 1,
79
- stale: 2, ok: 3, unknown: 4,
80
- };
81
- function sortSeats(seats) {
82
- return seats.sort((a, b) => {
83
- const ra = STATUS_RANK[a.status] ?? 9;
84
- const rb = STATUS_RANK[b.status] ?? 9;
85
- if (ra !== rb)
86
- return ra - rb;
87
- const pa = a.usedPercentage ?? -1;
88
- const pb = b.usedPercentage ?? -1;
89
- if (pa !== pb)
90
- return pb - pa; // higher percentage first
91
- if (a.rig !== b.rig)
92
- return a.rig.localeCompare(b.rig);
93
- return a.session.localeCompare(b.session);
94
- });
95
126
  }
96
- function isVisible(seat, threshold) {
97
- if (threshold == null)
98
- return true;
99
- if (seat.status === "unknown")
100
- return true;
101
- if (seat.freshness === "stale")
102
- return true;
103
- return seat.usedPercentage != null && seat.usedPercentage >= threshold;
127
+ async function resolvePack(client, nameOrRef) {
128
+ if (nameOrRef.startsWith("context-pack:")) {
129
+ throw new Error("Context pack colon-id addressing ('context-pack:<name>:<version>') was removed. " +
130
+ "Address a pack by its path-like ref instead (for example 'packs/compaction-restore').");
131
+ }
132
+ if (nameOrRef.includes("/")) {
133
+ const res = await client.get(`/api/context-packs/library/by-ref?ref=${encodeURIComponent(nameOrRef)}`);
134
+ if (res.status === 200)
135
+ return res.data;
136
+ if (res.status === 404)
137
+ throw new Error(`Context pack '${nameOrRef}' not found in library. Run 'rig context list' to see what's available.`);
138
+ if (res.status === 400)
139
+ throw new Error(res.data?.message ?? `Unsafe context pack ref '${nameOrRef}'.`);
140
+ throw new Error(`Daemon returned HTTP ${res.status} for /api/context-packs/library/by-ref`);
141
+ }
142
+ const res = await client.get("/api/context-packs/library");
143
+ if (res.status !== 200)
144
+ throw new Error(`Daemon returned HTTP ${res.status} for /api/context-packs/library`);
145
+ const entries = res.data ?? [];
146
+ const exactRef = entries.find((entry) => entry.relativePath === nameOrRef);
147
+ if (exactRef)
148
+ return exactRef;
149
+ const matches = entries.filter((e) => e.name === nameOrRef);
150
+ if (matches.length === 0) {
151
+ throw new Error(`Context pack '${nameOrRef}' not found in library. Run 'rig context list' to see what's available.`);
152
+ }
153
+ if (matches.length > 1) {
154
+ const refs = matches.map((entry) => entry.relativePath).join(", ");
155
+ throw new Error(`Context pack name '${nameOrRef}' is ambiguous across refs: ${refs}. Address it by path-like ref.`);
156
+ }
157
+ return matches[0];
104
158
  }
105
159
  export function contextCommand(depsOverride) {
106
160
  const cmd = new Command("context")
107
- .description("Show context-usage across running agents")
161
+ .description("Browse, preview, compose, and manage operator-authored context packs")
108
162
  .addHelpText("after", `
109
163
  Examples:
110
- rig context Show all seats with context usage
111
- rig context --rig openrig-pm Show one rig
112
- rig context --threshold 80 Show seats at or above 80% (plus unknown + stale)
113
- rig context --refresh Re-sample context before displaying
114
- rig context --json Compact JSON (slim per-seat projection, non-pretty)
115
- rig context --full --json Complete per-seat payload (all fields; lossless)
116
- rig context --full Widened human table (adds remaining/source/freshness)`);
117
- const getDepsF = () => depsOverride ?? { lifecycleDeps: realDeps(), clientFactory: (url) => new DaemonClient(url) };
118
- cmd
119
- .option("--json", "Compact JSON for agents (use --full --json for the complete payload)")
120
- .option("--full", "Include every field: --full --json is the complete Seat[]; --full widens the human table")
121
- .option("--rig <name>", "Show one rig only")
122
- .option("--threshold <pct>", "Show seats at or above this percentage")
123
- .option("--refresh", "Re-sample context usage before displaying")
124
- .action(async (opts) => {
125
- const deps = getDepsF();
126
- // Strict threshold validation — reject non-integer input
127
- let threshold = null;
128
- if (opts.threshold != null) {
129
- const parsed = Number(opts.threshold);
130
- if (!Number.isInteger(parsed) || parsed < 0 || parsed > 100) {
131
- console.error("rig context: --threshold must be an integer percentage (0-100)");
132
- process.exitCode = 2;
133
- return;
134
- }
135
- threshold = parsed;
164
+ rig context list
165
+ rig context show pl-005-phase-a-priming
166
+ rig context preview pl-005-phase-a-priming
167
+ rig context add ./my-pack
168
+ rig context rm packs/compaction-restore
169
+ rig context sync
170
+ `);
171
+ const getDeps = () => depsOverride ?? {
172
+ lifecycleDeps: realDeps(),
173
+ clientFactory: (url) => new DaemonClient(url),
174
+ };
175
+ async function getClient() {
176
+ const deps = getDeps();
177
+ const status = await getDaemonStatus(deps.lifecycleDeps);
178
+ if (status.state !== "running" || status.healthy === false) {
179
+ throw new Error("Daemon not running. Start it with: rig daemon start");
136
180
  }
181
+ return deps.clientFactory(getDaemonUrl(status));
182
+ }
183
+ cmd.command("compose")
184
+ .description("Compose ordered files into a durable context-pack ref (never delivers)")
185
+ .requiredOption("--out <ref>", "Path-like durable output ref")
186
+ .requiredOption("--from <files...>", "Ordered source files")
187
+ .action(async (opts) => {
188
+ const deps = getDeps();
137
189
  const status = await getDaemonStatus(deps.lifecycleDeps);
138
190
  if (status.state !== "running" || status.healthy === false) {
139
191
  console.error("Daemon is not running. Start it with: rig daemon start");
@@ -142,113 +194,239 @@ Examples:
142
194
  }
143
195
  const client = deps.clientFactory(getDaemonUrl(status));
144
196
  try {
145
- // Get rig list to iterate
146
- const psResult = await client.get("/api/ps");
147
- const rigs = psResult.data ?? [];
148
- const targetRigs = opts.rig
149
- ? rigs.filter((r) => r.name === opts.rig)
150
- : rigs;
151
- if (opts.rig && targetRigs.length === 0) {
152
- console.error(`Rig "${opts.rig}" not found. List rigs with: rig ps`);
153
- process.exitCode = 1;
197
+ const res = await client.post("/api/context-packs/library/compose", {
198
+ outRef: opts.out,
199
+ sources: opts.from.map((path) => ({ path: resolve(path), label: path })),
200
+ });
201
+ if (res.status !== 201) {
202
+ throw new Error(res.data.message ?? res.data.error ?? `Daemon returned HTTP ${res.status}`);
203
+ }
204
+ console.log(`Composed ${res.data.files?.length ?? opts.from.length} file(s) -> ${res.data.ref} ` +
205
+ `(${res.data.bytes ?? 0} bytes, ~${res.data.estimatedTokens ?? 0} tokens).`);
206
+ }
207
+ catch (err) {
208
+ console.error(err.message);
209
+ process.exitCode = 1;
210
+ }
211
+ });
212
+ cmd.command("list")
213
+ .description("List all context packs in the library")
214
+ .option("--json", "JSON output")
215
+ .action(async (opts) => {
216
+ try {
217
+ const client = await getClient();
218
+ const res = await client.get("/api/context-packs/library");
219
+ const entries = res.data ?? [];
220
+ if (opts.json) {
221
+ console.log(JSON.stringify(entries, null, 2));
154
222
  return;
155
223
  }
156
- // Refresh once globally if requested (pollOnce samples all active Claude sessions).
157
- // Refresh failure is a hard error do not silently display stale data as if refreshed.
158
- if (opts.refresh && targetRigs.length > 0) {
159
- const firstRig = targetRigs[0];
160
- try {
161
- const refreshResult = await client.get(`/api/rigs/${firstRig.rigId}/nodes?refresh=true`);
162
- if (refreshResult.status >= 400) {
163
- console.error("Context refresh failed. Data may be stale.");
164
- console.error(`Detail: ${JSON.stringify(refreshResult.data)}`);
165
- console.error("Fix: retry without --refresh to see stale data, or check daemon logs.");
166
- process.exitCode = 2;
167
- return;
168
- }
169
- }
170
- catch (refreshErr) {
171
- console.error("Context refresh failed. Data may be stale.");
172
- console.error(`Detail: ${refreshErr instanceof Error ? refreshErr.message : String(refreshErr)}`);
173
- console.error("Fix: retry without --refresh to see stale data, or check daemon logs.");
174
- process.exitCode = 2;
175
- return;
176
- }
224
+ if (entries.length === 0) {
225
+ console.log("No context packs in library. Author one at ~/.openrig/context-packs/<name>/ then run: rig context sync");
226
+ return;
177
227
  }
178
- // Fetch node inventory per rig (without refresh already done globally)
179
- const allNodes = [];
180
- for (const rig of targetRigs) {
181
- const nodesResult = await client.get(`/api/rigs/${rig.rigId}/nodes`);
182
- if (Array.isArray(nodesResult.data)) {
183
- allNodes.push(...nodesResult.data);
184
- }
228
+ for (const e of entries) {
229
+ console.log(`${e.relativePath.padEnd(36)} ${e.name.padEnd(24)} v${String(e.version).padEnd(6)} ${String(e.files.length).padStart(2)} files ~${String(e.derivedEstimatedTokens).padStart(6)} tokens ${e.sourceType} ${e.sourcePath}`);
230
+ }
231
+ }
232
+ catch (err) {
233
+ console.error(err.message);
234
+ process.exitCode = 1;
235
+ }
236
+ });
237
+ cmd.command("show")
238
+ .argument("<name-or-ref>", "Context pack name or path-like ref")
239
+ .description("Show pack manifest + per-file metadata")
240
+ .option("--json", "JSON output")
241
+ .action(async (nameOrId, opts) => {
242
+ try {
243
+ const client = await getClient();
244
+ const entry = await resolvePack(client, nameOrId);
245
+ if (opts.json) {
246
+ console.log(JSON.stringify(entry, null, 2));
247
+ return;
185
248
  }
186
- const seats = sortSeats(allNodes
187
- .map(analyze)
188
- .filter((s) => isVisible(s, threshold)));
189
- const summary = {
190
- total: seats.length,
191
- known: seats.filter((s) => s.usedPercentage != null).length,
192
- critical: seats.filter((s) => s.urgency === "critical").length,
193
- warning: seats.filter((s) => s.urgency === "warning").length,
194
- ok: seats.filter((s) => s.status === "ok").length,
195
- stale: seats.filter((s) => s.freshness === "stale").length,
196
- unknown: seats.filter((s) => s.status === "unknown").length,
197
- };
249
+ console.log(`Ref: ${entry.relativePath}`);
250
+ console.log(`Name: ${entry.name}`);
251
+ console.log(`Version: ${entry.version}`);
252
+ console.log(`Source: ${entry.sourceType} (${entry.sourcePath})`);
253
+ console.log(`Files: ${entry.files.length}`);
254
+ console.log(`Tokens (~): ${entry.derivedEstimatedTokens}${entry.manifestEstimatedTokens !== null ? ` (manifest: ${entry.manifestEstimatedTokens})` : ""}`);
255
+ if (entry.purpose) {
256
+ console.log("");
257
+ console.log("Purpose:");
258
+ console.log(` ${entry.purpose.replaceAll("\n", "\n ")}`);
259
+ }
260
+ console.log("");
261
+ for (const f of entry.files) {
262
+ const sizeStr = f.bytes === null ? "(missing)" : `${f.bytes}B`;
263
+ const tokenStr = f.estimatedTokens === null ? "—" : `~${f.estimatedTokens} tokens`;
264
+ console.log(` ${f.path.padEnd(40)} role=${f.role.padEnd(20)} ${sizeStr.padEnd(12)} ${tokenStr}`);
265
+ if (f.summary)
266
+ console.log(` ${f.summary}`);
267
+ }
268
+ }
269
+ catch (err) {
270
+ console.error(err.message);
271
+ process.exitCode = 1;
272
+ }
273
+ });
274
+ cmd.command("preview")
275
+ .argument("<name-or-ref>", "Context pack name or path-like ref")
276
+ .description("Show the assembled bundle without delivering it")
277
+ .option("--json", "JSON output")
278
+ .action(async (nameOrRef, opts) => {
279
+ try {
280
+ const client = await getClient();
281
+ const entry = await resolvePack(client, nameOrRef);
282
+ const res = await client.get(`/api/context-packs/library/by-ref/preview?ref=${encodeURIComponent(entry.relativePath)}`);
283
+ if (res.status !== 200)
284
+ throw new Error(`Daemon returned HTTP ${res.status}`);
285
+ const preview = res.data;
198
286
  if (opts.json) {
199
- if (opts.full) {
200
- // --full --json: the complete Seat[] + summary. Lossless parity
201
- // with the pre-0.4.0.30 --json output (pretty-printed). This is
202
- // the ONLY full-payload surface.
203
- console.log(JSON.stringify({ seats, summary }, null, 2));
204
- }
205
- else {
206
- // Compact default (OPR.0.4.0.30): a slim, non-pretty actionable
207
- // projection — exactly the columns the human table shows. The
208
- // other Seat fields move to --full --json.
209
- const compactSeats = seats.map((s) => ({
210
- session: s.session,
211
- rig: s.rig,
212
- runtime: s.runtime,
213
- usedPercentage: s.usedPercentage,
214
- contextWindowSize: s.contextWindowSize,
215
- staleness: s.staleness,
216
- displayStatus: s.displayStatus,
217
- }));
218
- console.log(JSON.stringify({ seats: compactSeats, summary }));
219
- }
287
+ console.log(JSON.stringify(preview, null, 2));
220
288
  return;
221
289
  }
222
- // Human-readable output
223
- const title = opts.rig ? `CONTEXT USAGE - ${opts.rig}` : "CONTEXT USAGE - all rigs";
224
- console.log(title);
225
- // Default table is unchanged; --full appends remaining/source/freshness
226
- // columns (a defined additive widening, not multi-line).
227
- const baseHeader = `${"seat".padEnd(42)} ${"runtime".padEnd(12)} ${"context".padStart(7)} ${"window".padStart(8)} ${"sampled".padStart(10)} ${opts.full ? "status".padEnd(16) : "status"}`;
228
- console.log(opts.full
229
- ? `${baseHeader} ${"remaining".padStart(9)} ${"source".padEnd(22)} freshness`
230
- : baseHeader);
231
- for (const seat of seats) {
232
- const context = seat.usedPercentage == null ? "?" : `${seat.usedPercentage}%`;
233
- const window = seat.contextWindowSize == null ? "?" : String(seat.contextWindowSize);
234
- const baseRow = `${seat.session.slice(0, 42).padEnd(42)} ${seat.runtime.slice(0, 12).padEnd(12)} ${context.padStart(7)} ${window.padStart(8)} ${seat.staleness.padStart(10)} ${opts.full ? seat.displayStatus.padEnd(16) : seat.displayStatus}`;
235
- if (opts.full) {
236
- const remaining = seat.remainingPercentage == null ? "?" : `${seat.remainingPercentage}%`;
237
- const source = seat.source ?? "\u2014";
238
- console.log(`${baseRow} ${remaining.padStart(9)} ${source.padEnd(22)} ${seat.freshness}`);
290
+ if (preview.missingFiles.length > 0) {
291
+ console.error(`Warning: ${preview.missingFiles.length} file(s) referenced by manifest are missing on disk:`);
292
+ for (const m of preview.missingFiles)
293
+ console.error(` - ${m.path} (role: ${m.role})`);
294
+ console.error("");
295
+ }
296
+ console.log(`# Preview: ${preview.name} v${preview.version}`);
297
+ console.log(`# Bundle: ${preview.bundleBytes} bytes (~${preview.estimatedTokens} tokens), ${preview.files.length} files`);
298
+ console.log("# ---");
299
+ console.log(preview.bundleText);
300
+ }
301
+ catch (err) {
302
+ console.error(err.message);
303
+ process.exitCode = 1;
304
+ }
305
+ });
306
+ cmd.command("sync")
307
+ .description("Re-walk discovery roots and refresh the library index")
308
+ .option("--json", "JSON output")
309
+ .action(async (opts) => {
310
+ try {
311
+ const client = await getClient();
312
+ const res = await client.post("/api/context-packs/library/sync");
313
+ if (res.status !== 200)
314
+ throw new Error(`Daemon returned HTTP ${res.status}`);
315
+ const data = res.data;
316
+ if (opts.json) {
317
+ console.log(JSON.stringify(data, null, 2));
318
+ return;
319
+ }
320
+ console.log(`Indexed ${data.count} context pack(s).`);
321
+ if (data.errors.length > 0) {
322
+ console.log(`Encountered ${data.errors.length} parse error(s):`);
323
+ for (const e of data.errors)
324
+ console.log(` - ${e.source}: ${e.error}`);
325
+ }
326
+ }
327
+ catch (err) {
328
+ console.error(err.message);
329
+ process.exitCode = 1;
330
+ }
331
+ });
332
+ cmd.command("add")
333
+ .argument("<source-dir>", "Directory containing manifest.yaml + included files")
334
+ .description("Install a context pack from a local directory into ~/.openrig/context-packs/")
335
+ .option("--name <name>", "Override the install name (defaults to source directory basename)")
336
+ .option("--json", "JSON output")
337
+ .action(async (sourceDir, opts) => {
338
+ try {
339
+ if (!existsSync(sourceDir))
340
+ throw new Error(`Source directory not found: ${sourceDir}`);
341
+ const stat = lstatSync(sourceDir);
342
+ if (stat.isSymbolicLink())
343
+ throw new Error(`Source must not be a symlink: ${sourceDir}`);
344
+ if (!stat.isDirectory())
345
+ throw new Error(`Source must be a directory containing manifest.yaml: ${sourceDir}`);
346
+ const manifestPath = join(sourceDir, "manifest.yaml");
347
+ if (!existsSync(manifestPath)) {
348
+ throw new Error(`Source directory must contain manifest.yaml: ${sourceDir}`);
349
+ }
350
+ validateContextPackManifestForInstall(manifestPath);
351
+ // Read the manifest's name as the canonical install name when
352
+ // --name not given. Cheap parse: trust the daemon to validate
353
+ // on next sync; here we just need the name.
354
+ const installName = opts.name ?? (() => {
355
+ try {
356
+ const raw = readFileSync(manifestPath, "utf-8");
357
+ const m = raw.match(/^name:\s*['"]?([^'"\n]+)['"]?\s*$/m);
358
+ return m?.[1]?.trim() || basename(sourceDir);
239
359
  }
240
- else {
241
- console.log(baseRow);
360
+ catch {
361
+ return basename(sourceDir);
242
362
  }
363
+ })();
364
+ assertSafeInstallRef(installName);
365
+ assertTreeHasNoSymlinks(sourceDir);
366
+ const targetRoot = getDefaultOpenRigPath("context-packs");
367
+ mkdirSync(targetRoot, { recursive: true });
368
+ assertDestinationNamespaceContained(targetRoot, installName);
369
+ const targetDir = join(targetRoot, installName);
370
+ let targetExists = false;
371
+ try {
372
+ lstatSync(targetDir);
373
+ targetExists = true;
374
+ }
375
+ catch (err) {
376
+ if (err.code !== "ENOENT")
377
+ throw err;
378
+ }
379
+ if (targetExists) {
380
+ throw new Error(`A context pack named '${installName}' already exists at ${targetDir}. Remove it first or use --name to install under a different name.`);
381
+ }
382
+ cpSync(sourceDir, targetDir, { recursive: true });
383
+ // Sync the daemon library so the new pack appears immediately.
384
+ const client = await getClient();
385
+ const syncRes = await client.post("/api/context-packs/library/sync");
386
+ if (syncRes.status !== 200) {
387
+ // Install succeeded; sync failed → still surface install path.
388
+ if (opts.json)
389
+ console.log(JSON.stringify({ installedAt: targetDir, syncError: `HTTP ${syncRes.status}` }, null, 2));
390
+ else
391
+ console.log(`Installed at ${targetDir}; daemon sync failed (HTTP ${syncRes.status}). Run 'rig context sync' manually.`);
392
+ return;
393
+ }
394
+ const syncError = syncRes.data.errors?.find((e) => e.source === targetDir);
395
+ if (syncError) {
396
+ throw new Error(`Installed at ${targetDir}, but daemon rejected the pack during sync: ${syncError.error}`);
397
+ }
398
+ if (opts.json) {
399
+ console.log(JSON.stringify({ installedAt: targetDir, count: syncRes.data.count }, null, 2));
400
+ }
401
+ else {
402
+ console.log(`Installed at ${targetDir}. Library now has ${syncRes.data.count} context pack(s).`);
243
403
  }
244
- console.log();
245
- console.log(`FLEET SUMMARY: ${summary.known}/${summary.total} known | ` +
246
- `${summary.critical} CRITICAL | ${summary.warning} WARNING | ` +
247
- `${summary.ok} ok | ${summary.stale} stale | ${summary.unknown} unknown`);
248
404
  }
249
405
  catch (err) {
250
- console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
251
- process.exitCode = 2;
406
+ console.error(err.message);
407
+ process.exitCode = 1;
408
+ }
409
+ });
410
+ cmd.command("rm")
411
+ .argument("<ref>", "Path-like ref of the context pack to remove (e.g. packs/compaction-restore)")
412
+ .description("Remove a context pack from the library by its path-like ref")
413
+ .option("--json", "JSON output")
414
+ .action(async (ref, opts) => {
415
+ try {
416
+ const client = await getClient();
417
+ const res = await client.delete(`/api/context-packs/library/by-ref?ref=${encodeURIComponent(ref)}`);
418
+ if (res.status !== 200) {
419
+ throw new Error(res.data?.message ?? res.data?.error ?? `Daemon returned HTTP ${res.status}`);
420
+ }
421
+ if (opts.json) {
422
+ console.log(JSON.stringify(res.data, null, 2));
423
+ return;
424
+ }
425
+ console.log(`Removed context pack '${res.data.ref}'.${typeof res.data.count === "number" ? ` Library now has ${res.data.count} context pack(s).` : ""}`);
426
+ }
427
+ catch (err) {
428
+ console.error(err.message);
429
+ process.exitCode = 1;
252
430
  }
253
431
  });
254
432
  return cmd;