@openrig/cli 0.3.1 → 0.3.3-rc.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 (358) hide show
  1. package/daemon/assets/plugins/openrig-core/skills/forming-an-openrig-mental-model/SKILL.md +1 -1
  2. package/daemon/assets/plugins/openrig-core/skills/openrig-user/SKILL.md +8 -8
  3. package/daemon/dist/adapters/cmux-transport.d.ts.map +1 -1
  4. package/daemon/dist/adapters/cmux-transport.js +51 -9
  5. package/daemon/dist/adapters/cmux-transport.js.map +1 -1
  6. package/daemon/dist/adapters/codex-runtime-adapter.d.ts.map +1 -1
  7. package/daemon/dist/adapters/codex-runtime-adapter.js +34 -5
  8. package/daemon/dist/adapters/codex-runtime-adapter.js.map +1 -1
  9. package/daemon/dist/adapters/tmux.d.ts +68 -1
  10. package/daemon/dist/adapters/tmux.d.ts.map +1 -1
  11. package/daemon/dist/adapters/tmux.js +141 -2
  12. package/daemon/dist/adapters/tmux.js.map +1 -1
  13. package/daemon/dist/db/migrations/037_mission_control_actions.d.ts +5 -1
  14. package/daemon/dist/db/migrations/037_mission_control_actions.d.ts.map +1 -1
  15. package/daemon/dist/db/migrations/037_mission_control_actions.js +5 -1
  16. package/daemon/dist/db/migrations/037_mission_control_actions.js.map +1 -1
  17. package/daemon/dist/db/migrations/041_rig_policy.d.ts +32 -0
  18. package/daemon/dist/db/migrations/041_rig_policy.d.ts.map +1 -0
  19. package/daemon/dist/db/migrations/041_rig_policy.js +47 -0
  20. package/daemon/dist/db/migrations/041_rig_policy.js.map +1 -0
  21. package/daemon/dist/db/migrations/042_rig_archive.d.ts +16 -0
  22. package/daemon/dist/db/migrations/042_rig_archive.d.ts.map +1 -0
  23. package/daemon/dist/db/migrations/042_rig_archive.js +21 -0
  24. package/daemon/dist/db/migrations/042_rig_archive.js.map +1 -0
  25. package/daemon/dist/domain/agent-images/resume-token-discovery.js +1 -1
  26. package/daemon/dist/domain/agent-images/resume-token-discovery.js.map +1 -1
  27. package/daemon/dist/domain/agent-images/snapshot-capturer.d.ts.map +1 -1
  28. package/daemon/dist/domain/agent-images/snapshot-capturer.js +2 -1
  29. package/daemon/dist/domain/agent-images/snapshot-capturer.js.map +1 -1
  30. package/daemon/dist/domain/agent-manifest.js +27 -0
  31. package/daemon/dist/domain/agent-manifest.js.map +1 -1
  32. package/daemon/dist/domain/bootstrap-orchestrator.d.ts.map +1 -1
  33. package/daemon/dist/domain/bootstrap-orchestrator.js +86 -6
  34. package/daemon/dist/domain/bootstrap-orchestrator.js.map +1 -1
  35. package/daemon/dist/domain/bundle-agent-images-router.d.ts +95 -0
  36. package/daemon/dist/domain/bundle-agent-images-router.d.ts.map +1 -0
  37. package/daemon/dist/domain/bundle-agent-images-router.js +140 -0
  38. package/daemon/dist/domain/bundle-agent-images-router.js.map +1 -0
  39. package/daemon/dist/domain/bundle-assembler.d.ts +18 -1
  40. package/daemon/dist/domain/bundle-assembler.d.ts.map +1 -1
  41. package/daemon/dist/domain/bundle-assembler.js +11 -1
  42. package/daemon/dist/domain/bundle-assembler.js.map +1 -1
  43. package/daemon/dist/domain/bundle-audit.d.ts +89 -0
  44. package/daemon/dist/domain/bundle-audit.d.ts.map +1 -0
  45. package/daemon/dist/domain/bundle-audit.js +87 -0
  46. package/daemon/dist/domain/bundle-audit.js.map +1 -0
  47. package/daemon/dist/domain/bundle-conflict-detector.d.ts +57 -0
  48. package/daemon/dist/domain/bundle-conflict-detector.d.ts.map +1 -0
  49. package/daemon/dist/domain/bundle-conflict-detector.js +49 -0
  50. package/daemon/dist/domain/bundle-conflict-detector.js.map +1 -0
  51. package/daemon/dist/domain/bundle-context-packs-router.d.ts +100 -0
  52. package/daemon/dist/domain/bundle-context-packs-router.d.ts.map +1 -0
  53. package/daemon/dist/domain/bundle-context-packs-router.js +158 -0
  54. package/daemon/dist/domain/bundle-context-packs-router.js.map +1 -0
  55. package/daemon/dist/domain/bundle-plugins-router.d.ts +69 -0
  56. package/daemon/dist/domain/bundle-plugins-router.d.ts.map +1 -0
  57. package/daemon/dist/domain/bundle-plugins-router.js +87 -0
  58. package/daemon/dist/domain/bundle-plugins-router.js.map +1 -0
  59. package/daemon/dist/domain/bundle-skills-router.d.ts +62 -0
  60. package/daemon/dist/domain/bundle-skills-router.d.ts.map +1 -0
  61. package/daemon/dist/domain/bundle-skills-router.js +90 -0
  62. package/daemon/dist/domain/bundle-skills-router.js.map +1 -0
  63. package/daemon/dist/domain/bundle-types.d.ts +106 -0
  64. package/daemon/dist/domain/bundle-types.d.ts.map +1 -1
  65. package/daemon/dist/domain/bundle-types.js +375 -0
  66. package/daemon/dist/domain/bundle-types.js.map +1 -1
  67. package/daemon/dist/domain/bundle-workflow-specs-router.d.ts +94 -0
  68. package/daemon/dist/domain/bundle-workflow-specs-router.d.ts.map +1 -0
  69. package/daemon/dist/domain/bundle-workflow-specs-router.js +144 -0
  70. package/daemon/dist/domain/bundle-workflow-specs-router.js.map +1 -0
  71. package/daemon/dist/domain/context-monitor.d.ts +5 -1
  72. package/daemon/dist/domain/context-monitor.d.ts.map +1 -1
  73. package/daemon/dist/domain/context-monitor.js +28 -15
  74. package/daemon/dist/domain/context-monitor.js.map +1 -1
  75. package/daemon/dist/domain/graph-projection.d.ts +6 -0
  76. package/daemon/dist/domain/graph-projection.d.ts.map +1 -1
  77. package/daemon/dist/domain/graph-projection.js +6 -0
  78. package/daemon/dist/domain/graph-projection.js.map +1 -1
  79. package/daemon/dist/domain/native-resume-probe.js +7 -7
  80. package/daemon/dist/domain/native-resume-probe.js.map +1 -1
  81. package/daemon/dist/domain/node-inventory.d.ts +18 -0
  82. package/daemon/dist/domain/node-inventory.d.ts.map +1 -1
  83. package/daemon/dist/domain/node-inventory.js +98 -0
  84. package/daemon/dist/domain/node-inventory.js.map +1 -1
  85. package/daemon/dist/domain/node-launcher.d.ts +12 -0
  86. package/daemon/dist/domain/node-launcher.d.ts.map +1 -1
  87. package/daemon/dist/domain/node-launcher.js +25 -1
  88. package/daemon/dist/domain/node-launcher.js.map +1 -1
  89. package/daemon/dist/domain/pod-bundle-assembler.d.ts +16 -1
  90. package/daemon/dist/domain/pod-bundle-assembler.d.ts.map +1 -1
  91. package/daemon/dist/domain/pod-bundle-assembler.js +11 -1
  92. package/daemon/dist/domain/pod-bundle-assembler.js.map +1 -1
  93. package/daemon/dist/domain/profile-resolver.d.ts +10 -0
  94. package/daemon/dist/domain/profile-resolver.d.ts.map +1 -1
  95. package/daemon/dist/domain/profile-resolver.js +4 -0
  96. package/daemon/dist/domain/profile-resolver.js.map +1 -1
  97. package/daemon/dist/domain/ps-projection.d.ts +28 -1
  98. package/daemon/dist/domain/ps-projection.d.ts.map +1 -1
  99. package/daemon/dist/domain/ps-projection.js +67 -1
  100. package/daemon/dist/domain/ps-projection.js.map +1 -1
  101. package/daemon/dist/domain/queue-repository.d.ts +37 -1
  102. package/daemon/dist/domain/queue-repository.d.ts.map +1 -1
  103. package/daemon/dist/domain/queue-repository.js +99 -2
  104. package/daemon/dist/domain/queue-repository.js.map +1 -1
  105. package/daemon/dist/domain/restore-check-service.d.ts +4 -0
  106. package/daemon/dist/domain/restore-check-service.d.ts.map +1 -1
  107. package/daemon/dist/domain/restore-check-service.js +16 -7
  108. package/daemon/dist/domain/restore-check-service.js.map +1 -1
  109. package/daemon/dist/domain/rig-expansion-service.d.ts +1 -1
  110. package/daemon/dist/domain/rig-expansion-service.d.ts.map +1 -1
  111. package/daemon/dist/domain/rig-expansion-service.js +12 -10
  112. package/daemon/dist/domain/rig-expansion-service.js.map +1 -1
  113. package/daemon/dist/domain/rig-policy/rig-policy-defaults.d.ts +48 -0
  114. package/daemon/dist/domain/rig-policy/rig-policy-defaults.d.ts.map +1 -0
  115. package/daemon/dist/domain/rig-policy/rig-policy-defaults.js +96 -0
  116. package/daemon/dist/domain/rig-policy/rig-policy-defaults.js.map +1 -0
  117. package/daemon/dist/domain/rig-policy/rig-policy-store.d.ts +46 -0
  118. package/daemon/dist/domain/rig-policy/rig-policy-store.d.ts.map +1 -0
  119. package/daemon/dist/domain/rig-policy/rig-policy-store.js +171 -0
  120. package/daemon/dist/domain/rig-policy/rig-policy-store.js.map +1 -0
  121. package/daemon/dist/domain/rig-policy/rig-policy-types.d.ts +145 -0
  122. package/daemon/dist/domain/rig-policy/rig-policy-types.d.ts.map +1 -0
  123. package/daemon/dist/domain/rig-policy/rig-policy-types.js +52 -0
  124. package/daemon/dist/domain/rig-policy/rig-policy-types.js.map +1 -0
  125. package/daemon/dist/domain/rig-policy/rig-policy-validator.d.ts +58 -0
  126. package/daemon/dist/domain/rig-policy/rig-policy-validator.d.ts.map +1 -0
  127. package/daemon/dist/domain/rig-policy/rig-policy-validator.js +211 -0
  128. package/daemon/dist/domain/rig-policy/rig-policy-validator.js.map +1 -0
  129. package/daemon/dist/domain/rig-repository.d.ts +28 -2
  130. package/daemon/dist/domain/rig-repository.d.ts.map +1 -1
  131. package/daemon/dist/domain/rig-repository.js +40 -3
  132. package/daemon/dist/domain/rig-repository.js.map +1 -1
  133. package/daemon/dist/domain/rigspec-instantiator.d.ts +177 -1
  134. package/daemon/dist/domain/rigspec-instantiator.d.ts.map +1 -1
  135. package/daemon/dist/domain/rigspec-instantiator.js +414 -55
  136. package/daemon/dist/domain/rigspec-instantiator.js.map +1 -1
  137. package/daemon/dist/domain/rigspec-preflight.d.ts +19 -1
  138. package/daemon/dist/domain/rigspec-preflight.d.ts.map +1 -1
  139. package/daemon/dist/domain/rigspec-preflight.js +30 -12
  140. package/daemon/dist/domain/rigspec-preflight.js.map +1 -1
  141. package/daemon/dist/domain/rigspec-schema.d.ts +1 -0
  142. package/daemon/dist/domain/rigspec-schema.d.ts.map +1 -1
  143. package/daemon/dist/domain/rigspec-schema.js +4 -1
  144. package/daemon/dist/domain/rigspec-schema.js.map +1 -1
  145. package/daemon/dist/domain/seat-activity-service.d.ts +79 -0
  146. package/daemon/dist/domain/seat-activity-service.d.ts.map +1 -0
  147. package/daemon/dist/domain/seat-activity-service.js +123 -0
  148. package/daemon/dist/domain/seat-activity-service.js.map +1 -0
  149. package/daemon/dist/domain/session-transport.d.ts +15 -0
  150. package/daemon/dist/domain/session-transport.d.ts.map +1 -1
  151. package/daemon/dist/domain/session-transport.js +8 -3
  152. package/daemon/dist/domain/session-transport.js.map +1 -1
  153. package/daemon/dist/domain/slices/slice-indexer.d.ts +12 -0
  154. package/daemon/dist/domain/slices/slice-indexer.d.ts.map +1 -1
  155. package/daemon/dist/domain/slices/slice-indexer.js +23 -0
  156. package/daemon/dist/domain/slices/slice-indexer.js.map +1 -1
  157. package/daemon/dist/domain/spec-library-service.d.ts.map +1 -1
  158. package/daemon/dist/domain/spec-library-service.js +19 -0
  159. package/daemon/dist/domain/spec-library-service.js.map +1 -1
  160. package/daemon/dist/domain/topology-converge.d.ts +97 -0
  161. package/daemon/dist/domain/topology-converge.d.ts.map +1 -0
  162. package/daemon/dist/domain/topology-converge.js +70 -0
  163. package/daemon/dist/domain/topology-converge.js.map +1 -0
  164. package/daemon/dist/domain/types.d.ts +85 -3
  165. package/daemon/dist/domain/types.d.ts.map +1 -1
  166. package/daemon/dist/domain/types.js.map +1 -1
  167. package/daemon/dist/domain/whoami-service.d.ts +8 -0
  168. package/daemon/dist/domain/whoami-service.d.ts.map +1 -1
  169. package/daemon/dist/domain/whoami-service.js +1 -0
  170. package/daemon/dist/domain/whoami-service.js.map +1 -1
  171. package/daemon/dist/domain/workflow-runtime.d.ts.map +1 -1
  172. package/daemon/dist/domain/workflow-runtime.js +9 -1
  173. package/daemon/dist/domain/workflow-runtime.js.map +1 -1
  174. package/daemon/dist/domain/workflow-spec-cache.d.ts +41 -0
  175. package/daemon/dist/domain/workflow-spec-cache.d.ts.map +1 -1
  176. package/daemon/dist/domain/workflow-spec-cache.js +63 -0
  177. package/daemon/dist/domain/workflow-spec-cache.js.map +1 -1
  178. package/daemon/dist/domain/workspace/default-workspace-scaffold.d.ts +7 -0
  179. package/daemon/dist/domain/workspace/default-workspace-scaffold.d.ts.map +1 -1
  180. package/daemon/dist/domain/workspace/default-workspace-scaffold.js +156 -3
  181. package/daemon/dist/domain/workspace/default-workspace-scaffold.js.map +1 -1
  182. package/daemon/dist/domain/workspace/workspace-doctor.d.ts +197 -0
  183. package/daemon/dist/domain/workspace/workspace-doctor.d.ts.map +1 -0
  184. package/daemon/dist/domain/workspace/workspace-doctor.js +448 -0
  185. package/daemon/dist/domain/workspace/workspace-doctor.js.map +1 -0
  186. package/daemon/dist/index.d.ts.map +1 -1
  187. package/daemon/dist/index.js +11 -0
  188. package/daemon/dist/index.js.map +1 -1
  189. package/daemon/dist/routes/bundles.d.ts.map +1 -1
  190. package/daemon/dist/routes/bundles.js +966 -7
  191. package/daemon/dist/routes/bundles.js.map +1 -1
  192. package/daemon/dist/routes/config.d.ts.map +1 -1
  193. package/daemon/dist/routes/config.js +19 -2
  194. package/daemon/dist/routes/config.js.map +1 -1
  195. package/daemon/dist/routes/info.d.ts +3 -0
  196. package/daemon/dist/routes/info.d.ts.map +1 -0
  197. package/daemon/dist/routes/info.js +20 -0
  198. package/daemon/dist/routes/info.js.map +1 -0
  199. package/daemon/dist/routes/ps.js +4 -1
  200. package/daemon/dist/routes/ps.js.map +1 -1
  201. package/daemon/dist/routes/queue.d.ts +18 -0
  202. package/daemon/dist/routes/queue.d.ts.map +1 -1
  203. package/daemon/dist/routes/queue.js +97 -5
  204. package/daemon/dist/routes/queue.js.map +1 -1
  205. package/daemon/dist/routes/rig-policy.d.ts +9 -0
  206. package/daemon/dist/routes/rig-policy.d.ts.map +1 -0
  207. package/daemon/dist/routes/rig-policy.js +174 -0
  208. package/daemon/dist/routes/rig-policy.js.map +1 -0
  209. package/daemon/dist/routes/rigs.d.ts.map +1 -1
  210. package/daemon/dist/routes/rigs.js +134 -4
  211. package/daemon/dist/routes/rigs.js.map +1 -1
  212. package/daemon/dist/routes/sessions.d.ts.map +1 -1
  213. package/daemon/dist/routes/sessions.js +26 -3
  214. package/daemon/dist/routes/sessions.js.map +1 -1
  215. package/daemon/dist/routes/up.d.ts +25 -0
  216. package/daemon/dist/routes/up.d.ts.map +1 -1
  217. package/daemon/dist/routes/up.js +70 -3
  218. package/daemon/dist/routes/up.js.map +1 -1
  219. package/daemon/dist/routes/workspace.d.ts.map +1 -1
  220. package/daemon/dist/routes/workspace.js +80 -1
  221. package/daemon/dist/routes/workspace.js.map +1 -1
  222. package/daemon/dist/server.d.ts +10 -0
  223. package/daemon/dist/server.d.ts.map +1 -1
  224. package/daemon/dist/server.js +11 -0
  225. package/daemon/dist/server.js.map +1 -1
  226. package/daemon/dist/startup.d.ts.map +1 -1
  227. package/daemon/dist/startup.js +46 -4
  228. package/daemon/dist/startup.js.map +1 -1
  229. package/daemon/docs/reference/getting-started.md +69 -0
  230. package/daemon/specs/agents/orchestration/orchestrator/guidance/role.md +28 -4
  231. package/daemon/specs/agents/shared/skills/core/openrig-user/SKILL.md +361 -15
  232. package/daemon/specs/agents/shared/skills/core/rig-lifecycle/SKILL.md +2 -2
  233. package/daemon/specs/rigs/launch/conveyor/rig.yaml +1 -1
  234. package/dist/client.d.ts +3 -0
  235. package/dist/client.d.ts.map +1 -1
  236. package/dist/client.js +13 -1
  237. package/dist/client.js.map +1 -1
  238. package/dist/commands/add.d.ts +4 -0
  239. package/dist/commands/add.d.ts.map +1 -0
  240. package/dist/commands/add.js +115 -0
  241. package/dist/commands/add.js.map +1 -0
  242. package/dist/commands/archive.d.ts +10 -0
  243. package/dist/commands/archive.d.ts.map +1 -0
  244. package/dist/commands/archive.js +68 -0
  245. package/dist/commands/archive.js.map +1 -0
  246. package/dist/commands/bootstrap.js +2 -2
  247. package/dist/commands/bootstrap.js.map +1 -1
  248. package/dist/commands/bundle.d.ts.map +1 -1
  249. package/dist/commands/bundle.js +123 -2
  250. package/dist/commands/bundle.js.map +1 -1
  251. package/dist/commands/config-init-workspace.d.ts.map +1 -1
  252. package/dist/commands/config-init-workspace.js +40 -5
  253. package/dist/commands/config-init-workspace.js.map +1 -1
  254. package/dist/commands/discover.js +2 -2
  255. package/dist/commands/discover.js.map +1 -1
  256. package/dist/commands/down.d.ts +1 -1
  257. package/dist/commands/down.d.ts.map +1 -1
  258. package/dist/commands/down.js +91 -3
  259. package/dist/commands/down.js.map +1 -1
  260. package/dist/commands/ps.d.ts.map +1 -1
  261. package/dist/commands/ps.js +72 -10
  262. package/dist/commands/ps.js.map +1 -1
  263. package/dist/commands/queue.d.ts +6 -0
  264. package/dist/commands/queue.d.ts.map +1 -1
  265. package/dist/commands/queue.js +103 -5
  266. package/dist/commands/queue.js.map +1 -1
  267. package/dist/commands/rig-policy.d.ts +48 -0
  268. package/dist/commands/rig-policy.d.ts.map +1 -0
  269. package/dist/commands/rig-policy.js +429 -0
  270. package/dist/commands/rig-policy.js.map +1 -0
  271. package/dist/commands/scope.d.ts +6 -0
  272. package/dist/commands/scope.d.ts.map +1 -0
  273. package/dist/commands/scope.js +659 -0
  274. package/dist/commands/scope.js.map +1 -0
  275. package/dist/commands/send.d.ts.map +1 -1
  276. package/dist/commands/send.js +11 -0
  277. package/dist/commands/send.js.map +1 -1
  278. package/dist/commands/setup.d.ts +7 -0
  279. package/dist/commands/setup.d.ts.map +1 -1
  280. package/dist/commands/setup.js +28 -1
  281. package/dist/commands/setup.js.map +1 -1
  282. package/dist/commands/status.d.ts.map +1 -1
  283. package/dist/commands/status.js +35 -2
  284. package/dist/commands/status.js.map +1 -1
  285. package/dist/commands/unarchive.d.ts +10 -0
  286. package/dist/commands/unarchive.d.ts.map +1 -0
  287. package/dist/commands/unarchive.js +53 -0
  288. package/dist/commands/unarchive.js.map +1 -0
  289. package/dist/commands/up.d.ts.map +1 -1
  290. package/dist/commands/up.js +97 -0
  291. package/dist/commands/up.js.map +1 -1
  292. package/dist/commands/whoami.d.ts.map +1 -1
  293. package/dist/commands/whoami.js +4 -1
  294. package/dist/commands/whoami.js.map +1 -1
  295. package/dist/commands/workflow.d.ts +9 -0
  296. package/dist/commands/workflow.d.ts.map +1 -1
  297. package/dist/commands/workflow.js +141 -4
  298. package/dist/commands/workflow.js.map +1 -1
  299. package/dist/commands/workspace.d.ts +20 -0
  300. package/dist/commands/workspace.d.ts.map +1 -1
  301. package/dist/commands/workspace.js +140 -10
  302. package/dist/commands/workspace.js.map +1 -1
  303. package/dist/daemon-lifecycle.d.ts +48 -1
  304. package/dist/daemon-lifecycle.d.ts.map +1 -1
  305. package/dist/daemon-lifecycle.js +57 -2
  306. package/dist/daemon-lifecycle.js.map +1 -1
  307. package/dist/index.d.ts +5 -0
  308. package/dist/index.d.ts.map +1 -1
  309. package/dist/index.js +12 -0
  310. package/dist/index.js.map +1 -1
  311. package/dist/lib/scope/dot-id.d.ts +43 -0
  312. package/dist/lib/scope/dot-id.d.ts.map +1 -0
  313. package/dist/lib/scope/dot-id.js +165 -0
  314. package/dist/lib/scope/dot-id.js.map +1 -0
  315. package/dist/lib/scope/scope-fs.d.ts +79 -0
  316. package/dist/lib/scope/scope-fs.d.ts.map +1 -0
  317. package/dist/lib/scope/scope-fs.js +468 -0
  318. package/dist/lib/scope/scope-fs.js.map +1 -0
  319. package/dist/lib/scope/templates.d.ts +38 -0
  320. package/dist/lib/scope/templates.d.ts.map +1 -0
  321. package/dist/lib/scope/templates.js +109 -0
  322. package/dist/lib/scope/templates.js.map +1 -0
  323. package/dist/lib/scope/types.d.ts +61 -0
  324. package/dist/lib/scope/types.d.ts.map +1 -0
  325. package/dist/lib/scope/types.js +38 -0
  326. package/dist/lib/scope/types.js.map +1 -0
  327. package/dist/lib/scope-templates/backlog-deprecation.md +26 -0
  328. package/dist/lib/scope-templates/backlog-tech-debt.md +22 -0
  329. package/dist/lib/scope-templates/bug-fix.md +30 -0
  330. package/dist/lib/scope-templates/mission-notes.md +97 -0
  331. package/dist/lib/scope-templates/mission-placeholder.md +20 -0
  332. package/dist/lib/scope-templates/mission-release.md +25 -0
  333. package/dist/lib/scope-templates/placeholder.md +30 -0
  334. package/dist/lib/scope-templates/release-feature.md +26 -0
  335. package/dist/lib/scope-templates/research.md +22 -0
  336. package/dist/mcp-server.d.ts.map +1 -1
  337. package/dist/mcp-server.js +29 -0
  338. package/dist/mcp-server.js.map +1 -1
  339. package/dist/release-surface/affected-skills.d.ts +49 -0
  340. package/dist/release-surface/affected-skills.d.ts.map +1 -0
  341. package/dist/release-surface/affected-skills.js +153 -0
  342. package/dist/release-surface/affected-skills.js.map +1 -0
  343. package/dist/release-surface/extract-surface.d.ts +23 -0
  344. package/dist/release-surface/extract-surface.d.ts.map +1 -0
  345. package/dist/release-surface/extract-surface.js +193 -0
  346. package/dist/release-surface/extract-surface.js.map +1 -0
  347. package/dist/release-surface/generate.d.ts +2 -0
  348. package/dist/release-surface/generate.d.ts.map +1 -0
  349. package/dist/release-surface/generate.js +51 -0
  350. package/dist/release-surface/generate.js.map +1 -0
  351. package/dist/release-surface/surface-diff.d.ts +40 -0
  352. package/dist/release-surface/surface-diff.d.ts.map +1 -0
  353. package/dist/release-surface/surface-diff.js +212 -0
  354. package/dist/release-surface/surface-diff.js.map +1 -0
  355. package/package.json +2 -2
  356. package/ui/dist/assets/index-CrJgCmkX.js +552 -0
  357. package/ui/dist/index.html +1 -1
  358. package/ui/dist/assets/index-Rl3ZBrUg.js +0 -547
@@ -0,0 +1,659 @@
1
+ // release-0.3.2 slice 12 — `rig scope` CLI primitive.
2
+ //
3
+ // Command grammar: rig scope <tier> <verb>. v0 ships `mission` +
4
+ // `slice` tiers; `project` and `sub-slice` are reserved per the
5
+ // substrate convention `conventions/scope-and-versioning/README.md`
6
+ // (stage: provisional). The CLI mints stable dot-IDs into created
7
+ // mission/slice frontmatter per §1 of that convention.
8
+ import fs from "node:fs";
9
+ import path from "node:path";
10
+ import { Command } from "commander";
11
+ import { CLOSE_REASONS, MISSION_TEMPLATE_KINDS, SLICE_TEMPLATE_KINDS, ScopeCliError, } from "../lib/scope/types.js";
12
+ import { DEFAULT_PROJECT_PREFIX, inferMissionDotId, isMissionDotId, nextEscapeBandOrdinal, sliceIdFromMission, } from "../lib/scope/dot-id.js";
13
+ import { ensureMissionIdPersisted, findMission, findSlice, listMissions, listSlices, moveSlice, nextSliceNN, pad2, resolveMissionsRoot, splitFrontmatter, todayDateISO, updateFrontmatter, } from "../lib/scope/scope-fs.js";
14
+ import { renderMissionNotesTemplate, renderMissionTemplate, renderSliceTemplate, titleFromSlug, } from "../lib/scope/templates.js";
15
+ function makeStdout() {
16
+ return { write: (text) => process.stdout.write(text) };
17
+ }
18
+ function emit(out, payload, json, lines) {
19
+ if (json) {
20
+ out.write(JSON.stringify(payload, null, 2) + "\n");
21
+ return;
22
+ }
23
+ if (lines) {
24
+ for (const line of lines)
25
+ out.write(line + "\n");
26
+ return;
27
+ }
28
+ out.write(JSON.stringify(payload, null, 2) + "\n");
29
+ }
30
+ function fail(err, json, out) {
31
+ if (err instanceof ScopeCliError) {
32
+ if (json) {
33
+ out.write(JSON.stringify({
34
+ ok: false,
35
+ error: { fact: err.fact, consequence: err.consequence, action: err.action },
36
+ }, null, 2) + "\n");
37
+ }
38
+ else {
39
+ process.stderr.write(`Error: ${err.fact}\n${err.consequence}\n${err.action}\n`);
40
+ }
41
+ }
42
+ else {
43
+ const message = err instanceof Error ? err.message : String(err);
44
+ process.stderr.write(`Error: ${message}\n`);
45
+ }
46
+ process.exit(1);
47
+ }
48
+ function slugify(raw) {
49
+ return raw
50
+ .toLowerCase()
51
+ .trim()
52
+ .replace(/[^a-z0-9]+/g, "-")
53
+ .replace(/^-+|-+$/g, "");
54
+ }
55
+ function getOpts(cmd) {
56
+ // commander v13 attaches opts on the parent.
57
+ let walker = cmd;
58
+ while (walker) {
59
+ const o = walker.opts();
60
+ if (o.workspace)
61
+ return o;
62
+ walker = walker.parent;
63
+ }
64
+ return {};
65
+ }
66
+ // ---------------------------------------------------------------------
67
+ // rig scope slice ls
68
+ // ---------------------------------------------------------------------
69
+ function buildSliceLsCommand() {
70
+ const cmd = new Command("ls")
71
+ .description("List slices in a mission (or across all missions)")
72
+ .option("--mission <name>", "Restrict to a single mission")
73
+ .option("--state <state>", "Filter: active | closed | shipped | all", "active")
74
+ .option("--json", "Machine-readable output")
75
+ .action(async (opts, command) => {
76
+ const out = makeStdout();
77
+ const json = Boolean(opts.json);
78
+ const state = opts.state ?? "active";
79
+ if (!["active", "closed", "shipped", "all"].includes(state)) {
80
+ fail(new ScopeCliError({
81
+ fact: `Unknown --state value "${state}".`,
82
+ consequence: "Command did not run.",
83
+ action: "Pick one of: active, closed, shipped, all.",
84
+ }), json, out);
85
+ }
86
+ try {
87
+ const missionsRoot = resolveMissionsRoot({ override: getOpts(command).workspace });
88
+ const missions = opts.mission
89
+ ? [findMission(missionsRoot, opts.mission)]
90
+ : listMissions(missionsRoot);
91
+ const rows = [];
92
+ const lines = [];
93
+ for (const mission of missions) {
94
+ const slices = listSlices(mission, state);
95
+ for (const slice of slices) {
96
+ rows.push({
97
+ mission: mission.name,
98
+ name: slice.name,
99
+ nn: slice.nn,
100
+ slug: slice.slug,
101
+ id: slice.id,
102
+ status: slice.status,
103
+ path: slice.absPath,
104
+ });
105
+ lines.push(`${mission.name}/${slice.name} ${slice.id ?? "—"} ${slice.status ?? "—"}`);
106
+ }
107
+ }
108
+ emit(out, { ok: true, count: rows.length, slices: rows }, json, lines.length === 0 ? ["(no slices)"] : lines);
109
+ }
110
+ catch (err) {
111
+ fail(err, json, out);
112
+ }
113
+ });
114
+ return cmd;
115
+ }
116
+ // ---------------------------------------------------------------------
117
+ // rig scope slice show
118
+ // ---------------------------------------------------------------------
119
+ function buildSliceShowCommand() {
120
+ return new Command("show")
121
+ .description("Inspect a single slice (frontmatter + README + children)")
122
+ .argument("<slice-path>", "Slice path (absolute, relative-to-substrate, or NN-slug)")
123
+ .option("--mission <name>", "Hint mission when path is just NN-slug")
124
+ .option("--json", "Machine-readable output")
125
+ .action(async (slicePath, opts, command) => {
126
+ const out = makeStdout();
127
+ const json = Boolean(opts.json);
128
+ try {
129
+ const missionsRoot = resolveMissionsRoot({ override: getOpts(command).workspace });
130
+ const slice = findSlice(missionsRoot, slicePath, opts.mission ?? null);
131
+ const readme = slice.readmePath ? fs.readFileSync(slice.readmePath, "utf8") : null;
132
+ const children = fs.readdirSync(slice.absPath, { withFileTypes: true })
133
+ .map((e) => ({ name: e.name, kind: e.isDirectory() ? "dir" : "file" }));
134
+ const payload = {
135
+ ok: true,
136
+ slice: {
137
+ mission: slice.missionName,
138
+ name: slice.name,
139
+ id: slice.id,
140
+ status: slice.status,
141
+ path: slice.absPath,
142
+ frontmatter: slice.frontmatter,
143
+ readme,
144
+ children,
145
+ },
146
+ };
147
+ if (json) {
148
+ out.write(JSON.stringify(payload, null, 2) + "\n");
149
+ }
150
+ else {
151
+ out.write(`Slice: ${slice.missionName}/${slice.name}\n`);
152
+ out.write(` id: ${slice.id ?? "—"}\n`);
153
+ out.write(` status: ${slice.status ?? "—"}\n`);
154
+ out.write(` path: ${slice.absPath}\n`);
155
+ out.write(` children: ${children.length}\n`);
156
+ if (readme) {
157
+ out.write("\n--- README ---\n");
158
+ out.write(readme);
159
+ if (!readme.endsWith("\n"))
160
+ out.write("\n");
161
+ }
162
+ }
163
+ }
164
+ catch (err) {
165
+ fail(err, json, out);
166
+ }
167
+ });
168
+ }
169
+ // ---------------------------------------------------------------------
170
+ // rig scope slice create
171
+ // ---------------------------------------------------------------------
172
+ function buildSliceCreateCommand() {
173
+ return new Command("create")
174
+ .description("Create a new slice in a mission")
175
+ .argument("<mission>", "Mission name")
176
+ .argument("<slug>", "Short slug (becomes the folder name's suffix)")
177
+ .option("--template <kind>", `Template: ${SLICE_TEMPLATE_KINDS.join(" | ")}`, "placeholder")
178
+ .option("--title <text>", "Display title (defaults to titlecased slug)")
179
+ .option("--json", "Machine-readable output")
180
+ .action(async (missionName, rawSlug, opts, command) => {
181
+ const out = makeStdout();
182
+ const json = Boolean(opts.json);
183
+ try {
184
+ const kind = opts.template;
185
+ if (!SLICE_TEMPLATE_KINDS.includes(kind)) {
186
+ throw new ScopeCliError({
187
+ fact: `Unknown --template kind "${kind}".`,
188
+ consequence: "Slice not created.",
189
+ action: `Pick one of: ${SLICE_TEMPLATE_KINDS.join(", ")}.`,
190
+ });
191
+ }
192
+ const slug = slugify(rawSlug);
193
+ if (!slug) {
194
+ throw new ScopeCliError({
195
+ fact: `Slug "${rawSlug}" reduces to empty after slugification.`,
196
+ consequence: "Slice not created.",
197
+ action: "Pick a slug containing letters or digits.",
198
+ });
199
+ }
200
+ const missionsRoot = resolveMissionsRoot({ override: getOpts(command).workspace });
201
+ const mission = findMission(missionsRoot, missionName);
202
+ // Persist the parent mission's id back into its README at the
203
+ // SAME moment we mint the child's id (per convention §1
204
+ // lazy-adoption rule + guard BC BLOCK 3 — every child-mint site
205
+ // must persist the parent's id, not just slice create).
206
+ const missionId = ensureMissionIdPersisted(mission, missionsRoot);
207
+ const nn = nextSliceNN(mission.absPath);
208
+ const sliceFolder = `${pad2(nn)}-${slug}`;
209
+ const sliceAbs = path.join(mission.absPath, "slices", sliceFolder);
210
+ if (fs.existsSync(sliceAbs)) {
211
+ throw new ScopeCliError({
212
+ fact: `Slice folder ${sliceAbs} already exists.`,
213
+ consequence: "Refusing to overwrite.",
214
+ action: "Pick a different slug, or rm -rf the existing folder first.",
215
+ });
216
+ }
217
+ const id = sliceIdFromMission(missionId, nn);
218
+ const title = opts.title ?? titleFromSlug(slug);
219
+ const body = renderSliceTemplate(kind, {
220
+ id,
221
+ slice_number: pad2(nn),
222
+ slug,
223
+ mission: mission.name,
224
+ title,
225
+ created_date: todayDateISO(),
226
+ });
227
+ fs.mkdirSync(sliceAbs, { recursive: true });
228
+ const readmePath = path.join(sliceAbs, "README.md");
229
+ fs.writeFileSync(readmePath, body, "utf8");
230
+ const payload = {
231
+ ok: true,
232
+ slice: {
233
+ mission: mission.name,
234
+ name: sliceFolder,
235
+ id,
236
+ path: sliceAbs,
237
+ readmePath,
238
+ template: kind,
239
+ },
240
+ };
241
+ emit(out, payload, json, [
242
+ `Created ${mission.name}/slices/${sliceFolder}`,
243
+ ` id: ${id}`,
244
+ ` template: ${kind}`,
245
+ ` path: ${sliceAbs}`,
246
+ ]);
247
+ }
248
+ catch (err) {
249
+ fail(err, json, out);
250
+ }
251
+ });
252
+ }
253
+ // ---------------------------------------------------------------------
254
+ // rig scope slice ship
255
+ // ---------------------------------------------------------------------
256
+ function buildSliceShipCommand() {
257
+ return new Command("ship")
258
+ .description("Ship a slice to a release mission (preserves git history)")
259
+ .argument("<slice-path>", "Slice path (absolute, relative, or NN-slug)")
260
+ .argument("<release-mission>", "Target release mission name")
261
+ .option("--mission <name>", "Hint mission when slice-path is just NN-slug")
262
+ .option("--json", "Machine-readable output")
263
+ .action(async (slicePath, releaseMission, opts, command) => {
264
+ const out = makeStdout();
265
+ const json = Boolean(opts.json);
266
+ try {
267
+ const missionsRoot = resolveMissionsRoot({ override: getOpts(command).workspace });
268
+ const slice = findSlice(missionsRoot, slicePath, opts.mission ?? null);
269
+ const target = findMission(missionsRoot, releaseMission);
270
+ const targetSlicesDir = path.join(target.absPath, "slices");
271
+ fs.mkdirSync(targetSlicesDir, { recursive: true });
272
+ const newNN = nextSliceNN(target.absPath);
273
+ const slug = slice.slug ?? slugify(slice.name);
274
+ const newName = `${pad2(newNN)}-${slug}`;
275
+ const destAbs = path.join(targetSlicesDir, newName);
276
+ const { usedGit, repoRoot } = moveSlice(slice.absPath, destAbs);
277
+ const targetId = ensureMissionIdPersisted(target, missionsRoot);
278
+ const newSliceId = sliceIdFromMission(targetId, newNN);
279
+ const newReadme = path.join(destAbs, "README.md");
280
+ if (fs.existsSync(newReadme)) {
281
+ updateFrontmatter(newReadme, {
282
+ id: newSliceId,
283
+ mission: target.name,
284
+ status: `shipped-to-${target.name}`,
285
+ "shipped-on": todayDateISO(),
286
+ "shipped-from": slice.missionName,
287
+ });
288
+ }
289
+ emit(out, {
290
+ ok: true,
291
+ shipped: {
292
+ from: { mission: slice.missionName, name: slice.name, id: slice.id },
293
+ to: { mission: target.name, name: newName, id: newSliceId, path: destAbs },
294
+ git: { usedGit, repoRoot },
295
+ },
296
+ }, json, [
297
+ `Shipped ${slice.missionName}/${slice.name} → ${target.name}/slices/${newName}`,
298
+ ` id: ${newSliceId}`,
299
+ ` git: ${usedGit ? "git mv" : "fs.rename (not in a git repo)"}`,
300
+ ]);
301
+ }
302
+ catch (err) {
303
+ fail(err, json, out);
304
+ }
305
+ });
306
+ }
307
+ // ---------------------------------------------------------------------
308
+ // rig scope slice close
309
+ // ---------------------------------------------------------------------
310
+ function buildSliceCloseCommand() {
311
+ return new Command("close")
312
+ .description("Close a slice (move to <mission>/closed/, update status)")
313
+ .argument("<slice-path>", "Slice path (absolute, relative, or NN-slug)")
314
+ .requiredOption("--reason <reason>", `Closure reason: ${CLOSE_REASONS.join(" | ")}`)
315
+ .option("--note <text>", "Optional closure note")
316
+ .option("--mission <name>", "Hint mission when slice-path is just NN-slug")
317
+ .option("--json", "Machine-readable output")
318
+ .action(async (slicePath, opts, command) => {
319
+ const out = makeStdout();
320
+ const json = Boolean(opts.json);
321
+ try {
322
+ const reason = opts.reason;
323
+ if (!CLOSE_REASONS.includes(reason)) {
324
+ throw new ScopeCliError({
325
+ fact: `Unknown --reason "${reason}".`,
326
+ consequence: "Slice not closed.",
327
+ action: `Pick one of: ${CLOSE_REASONS.join(", ")}.`,
328
+ });
329
+ }
330
+ const missionsRoot = resolveMissionsRoot({ override: getOpts(command).workspace });
331
+ const slice = findSlice(missionsRoot, slicePath, opts.mission ?? null);
332
+ const mission = findMission(missionsRoot, slice.missionName);
333
+ const closedDir = path.join(mission.absPath, "closed");
334
+ fs.mkdirSync(closedDir, { recursive: true });
335
+ const destName = slice.name;
336
+ const destAbs = path.join(closedDir, destName);
337
+ const { usedGit, repoRoot } = moveSlice(slice.absPath, destAbs);
338
+ const newReadme = path.join(destAbs, "README.md");
339
+ if (fs.existsSync(newReadme)) {
340
+ const updates = {
341
+ status: `closed-${reason}`,
342
+ "closed-on": todayDateISO(),
343
+ };
344
+ if (opts.note)
345
+ updates["closure-note"] = opts.note;
346
+ updateFrontmatter(newReadme, updates);
347
+ }
348
+ emit(out, {
349
+ ok: true,
350
+ closed: {
351
+ mission: slice.missionName,
352
+ name: destName,
353
+ id: slice.id,
354
+ reason,
355
+ note: opts.note ?? null,
356
+ path: destAbs,
357
+ git: { usedGit, repoRoot },
358
+ },
359
+ }, json, [
360
+ `Closed ${slice.missionName}/${slice.name} → ${slice.missionName}/closed/${destName}`,
361
+ ` reason: ${reason}`,
362
+ ` git: ${usedGit ? "git mv" : "fs.rename (not in a git repo)"}`,
363
+ ]);
364
+ }
365
+ catch (err) {
366
+ fail(err, json, out);
367
+ }
368
+ });
369
+ }
370
+ // ---------------------------------------------------------------------
371
+ // rig scope slice move
372
+ // ---------------------------------------------------------------------
373
+ function buildSliceMoveCommand() {
374
+ return new Command("move")
375
+ .description("Move a slice between missions (re-numbers in destination)")
376
+ .argument("<slice-path>", "Slice path (absolute, relative, or NN-slug)")
377
+ .argument("<dest-mission>", "Destination mission name")
378
+ .option("--mission <name>", "Hint source mission when slice-path is just NN-slug")
379
+ .option("--json", "Machine-readable output")
380
+ .action(async (slicePath, destMission, opts, command) => {
381
+ const out = makeStdout();
382
+ const json = Boolean(opts.json);
383
+ try {
384
+ const missionsRoot = resolveMissionsRoot({ override: getOpts(command).workspace });
385
+ const slice = findSlice(missionsRoot, slicePath, opts.mission ?? null);
386
+ const target = findMission(missionsRoot, destMission);
387
+ const targetSlicesDir = path.join(target.absPath, "slices");
388
+ fs.mkdirSync(targetSlicesDir, { recursive: true });
389
+ const newNN = nextSliceNN(target.absPath);
390
+ const slug = slice.slug ?? slugify(slice.name);
391
+ const newName = `${pad2(newNN)}-${slug}`;
392
+ const destAbs = path.join(targetSlicesDir, newName);
393
+ const { usedGit, repoRoot } = moveSlice(slice.absPath, destAbs);
394
+ const targetId = ensureMissionIdPersisted(target, missionsRoot);
395
+ const newSliceId = sliceIdFromMission(targetId, newNN);
396
+ const newReadme = path.join(destAbs, "README.md");
397
+ if (fs.existsSync(newReadme)) {
398
+ updateFrontmatter(newReadme, {
399
+ id: newSliceId,
400
+ mission: target.name,
401
+ "moved-on": todayDateISO(),
402
+ "moved-from": slice.missionName,
403
+ });
404
+ }
405
+ emit(out, {
406
+ ok: true,
407
+ moved: {
408
+ from: { mission: slice.missionName, name: slice.name, id: slice.id },
409
+ to: { mission: target.name, name: newName, id: newSliceId, path: destAbs },
410
+ git: { usedGit, repoRoot },
411
+ },
412
+ }, json, [
413
+ `Moved ${slice.missionName}/${slice.name} → ${target.name}/slices/${newName}`,
414
+ ` id: ${newSliceId}`,
415
+ ` git: ${usedGit ? "git mv" : "fs.rename (not in a git repo)"}`,
416
+ ]);
417
+ }
418
+ catch (err) {
419
+ fail(err, json, out);
420
+ }
421
+ });
422
+ }
423
+ // ---------------------------------------------------------------------
424
+ // rig scope mission ls / show / create
425
+ // ---------------------------------------------------------------------
426
+ function buildMissionLsCommand() {
427
+ return new Command("ls")
428
+ .description("List missions (top-level folders with README.md)")
429
+ .option("--json", "Machine-readable output")
430
+ .action(async (opts, command) => {
431
+ const out = makeStdout();
432
+ const json = Boolean(opts.json);
433
+ try {
434
+ const missionsRoot = resolveMissionsRoot({ override: getOpts(command).workspace });
435
+ const missions = listMissions(missionsRoot);
436
+ const rows = missions.map((m) => ({
437
+ name: m.name,
438
+ id: m.id,
439
+ path: m.absPath,
440
+ activeSliceCount: m.activeSliceCount,
441
+ closedSliceCount: m.closedSliceCount,
442
+ }));
443
+ emit(out, { ok: true, count: rows.length, missions: rows }, json, rows.length === 0
444
+ ? ["(no missions)"]
445
+ : rows.map((r) => `${r.name} ${r.id ?? "—"} active=${r.activeSliceCount} closed=${r.closedSliceCount}`));
446
+ }
447
+ catch (err) {
448
+ fail(err, json, out);
449
+ }
450
+ });
451
+ }
452
+ function buildMissionShowCommand() {
453
+ return new Command("show")
454
+ .description("Inspect a single mission")
455
+ .argument("<mission>", "Mission name")
456
+ .option("--json", "Machine-readable output")
457
+ .action(async (missionName, opts, command) => {
458
+ const out = makeStdout();
459
+ const json = Boolean(opts.json);
460
+ try {
461
+ const missionsRoot = resolveMissionsRoot({ override: getOpts(command).workspace });
462
+ const mission = findMission(missionsRoot, missionName);
463
+ const readme = mission.readmePath ? fs.readFileSync(mission.readmePath, "utf8") : null;
464
+ const slices = listSlices(mission, "all").map((s) => ({
465
+ name: s.name, id: s.id, status: s.status, nn: s.nn,
466
+ }));
467
+ const payload = {
468
+ ok: true,
469
+ mission: {
470
+ name: mission.name,
471
+ id: mission.id,
472
+ path: mission.absPath,
473
+ activeSliceCount: mission.activeSliceCount,
474
+ closedSliceCount: mission.closedSliceCount,
475
+ frontmatter: mission.frontmatter,
476
+ readme,
477
+ slices,
478
+ },
479
+ };
480
+ if (json) {
481
+ out.write(JSON.stringify(payload, null, 2) + "\n");
482
+ }
483
+ else {
484
+ out.write(`Mission: ${mission.name}\n`);
485
+ out.write(` id: ${mission.id ?? "—"}\n`);
486
+ out.write(` active slices: ${mission.activeSliceCount}\n`);
487
+ out.write(` closed slices: ${mission.closedSliceCount}\n`);
488
+ out.write(` path: ${mission.absPath}\n`);
489
+ if (readme) {
490
+ out.write("\n--- README ---\n");
491
+ out.write(readme);
492
+ if (!readme.endsWith("\n"))
493
+ out.write("\n");
494
+ }
495
+ }
496
+ }
497
+ catch (err) {
498
+ fail(err, json, out);
499
+ }
500
+ });
501
+ }
502
+ function buildMissionCreateCommand() {
503
+ return new Command("create")
504
+ .description("Create a new mission (mints a stable dot-ID into frontmatter)")
505
+ .argument("<name>", "Mission folder name (e.g., release-0.4.0, backlog-foo)")
506
+ .option("--template <kind>", `Template: ${MISSION_TEMPLATE_KINDS.join(" | ")} (auto when name matches release-X.Y.Z)`, "")
507
+ .option("--id <dot-id>", "Explicit dot-ID. Overrides name-pattern inference.")
508
+ .option("--title <text>", "Display title (defaults to titlecased name)")
509
+ .option("--no-mission-notes", "Skip the auto-scaffold of MISSION_NOTES.md (rare; default is to scaffold from conventions/mission-notes/TEMPLATE.md)")
510
+ .option("--json", "Machine-readable output")
511
+ .action(async (rawName, opts, command) => {
512
+ const out = makeStdout();
513
+ const json = Boolean(opts.json);
514
+ try {
515
+ const name = rawName.trim();
516
+ if (!name || /[\\/\s]/.test(name)) {
517
+ throw new ScopeCliError({
518
+ fact: `Invalid mission name "${rawName}".`,
519
+ consequence: "Mission not created.",
520
+ action: "Pick a name with no whitespace or path separators.",
521
+ });
522
+ }
523
+ const missionsRoot = resolveMissionsRoot({ override: getOpts(command).workspace });
524
+ const absPath = path.join(missionsRoot, name);
525
+ if (fs.existsSync(absPath)) {
526
+ throw new ScopeCliError({
527
+ fact: `Mission folder ${absPath} already exists.`,
528
+ consequence: "Refusing to overwrite.",
529
+ action: "Pick a different name, or use `rig scope mission show <name>` to inspect the existing mission.",
530
+ });
531
+ }
532
+ // Resolve template kind: explicit > release-pattern auto > placeholder.
533
+ const isReleaseName = /^release-\d+\.\d+(?:\.\d+)?$/.test(name);
534
+ let templateKind = opts.template;
535
+ if (!templateKind)
536
+ templateKind = isReleaseName ? "release" : "placeholder";
537
+ if (!MISSION_TEMPLATE_KINDS.includes(templateKind)) {
538
+ throw new ScopeCliError({
539
+ fact: `Unknown --template kind "${templateKind}".`,
540
+ consequence: "Mission not created.",
541
+ action: `Pick one of: ${MISSION_TEMPLATE_KINDS.join(", ")}.`,
542
+ });
543
+ }
544
+ // Mint the dot-ID.
545
+ let id;
546
+ if (opts.id) {
547
+ // Tier-aware validation per guard BC verdict (BLOCK 1).
548
+ // A mission ID has 2-3 numeric segments after the prefix
549
+ // (release X.Y or X.Y.Z; escape-band 99.x.y). Reject
550
+ // slice-shaped IDs (4 segments) so the parent identity stays
551
+ // unambiguous.
552
+ if (!isMissionDotId(opts.id)) {
553
+ throw new ScopeCliError({
554
+ fact: `Supplied --id "${opts.id}" is not a mission-tier dot-ID.`,
555
+ consequence: "Mission not created. A mission ID has the shape <PFX>.<ver> (2-3 numeric segments), not a slice shape <PFX>.<ver>.<n>.",
556
+ action: "Use a mission-shaped dot-ID like OPR.0.3.2 (release) or OPR.99.0.1 (escape band). For slice IDs, scope automatically mints them when you create a slice.",
557
+ });
558
+ }
559
+ id = opts.id;
560
+ }
561
+ else if (isReleaseName) {
562
+ id = inferMissionDotId(name, null);
563
+ }
564
+ else {
565
+ const peers = listMissions(missionsRoot);
566
+ const ordinal = nextEscapeBandOrdinal(peers.map((p) => p.id));
567
+ id = inferMissionDotId(name, ordinal);
568
+ }
569
+ // Resolve titles + render templates BEFORE any filesystem side
570
+ // effects (banked verify-first-then-write — guard catch on
571
+ // OPR.0.3.2.21.FR-3 qitem-20260601121058: a stale
572
+ // OPENRIG_MISSION_NOTES_TEMPLATE_PATH used to throw AFTER
573
+ // mkdirSync + README write, leaking a half-created mission dir
574
+ // that future `mission create <same-name>` would reject as
575
+ // already-existing). Rendering MISSION_NOTES first means a
576
+ // stale env-var fails before any disk mutation.
577
+ const title = opts.title ?? titleFromSlug(name.replace(/^release-/, ""));
578
+ const releaseVersion = isReleaseName ? name.replace(/^release-/, "") : "";
579
+ const readmeBody = renderMissionTemplate(templateKind, {
580
+ id,
581
+ slug: name,
582
+ mission: name,
583
+ title,
584
+ created_date: todayDateISO(),
585
+ release_version: releaseVersion,
586
+ });
587
+ let missionNotesRendered = null;
588
+ if (opts.missionNotes !== false) {
589
+ const r = renderMissionNotesTemplate({
590
+ mission_id: id,
591
+ mission_name: title,
592
+ created_date: todayDateISO(),
593
+ });
594
+ missionNotesRendered = { rendered: r.rendered, resolvedFrom: r.resolvedFrom };
595
+ }
596
+ // All renders succeeded — safe to touch the filesystem.
597
+ fs.mkdirSync(absPath, { recursive: true });
598
+ fs.mkdirSync(path.join(absPath, "slices"), { recursive: true });
599
+ const readmePath = path.join(absPath, "README.md");
600
+ fs.writeFileSync(readmePath, readmeBody, "utf8");
601
+ let missionNotesPath = null;
602
+ let missionNotesResolvedFrom = null;
603
+ if (missionNotesRendered) {
604
+ missionNotesPath = path.join(absPath, "MISSION_NOTES.md");
605
+ fs.writeFileSync(missionNotesPath, missionNotesRendered.rendered, "utf8");
606
+ missionNotesResolvedFrom = missionNotesRendered.resolvedFrom;
607
+ }
608
+ const humanLines = [
609
+ `Created mission ${name}`,
610
+ ` id: ${id}`,
611
+ ` template: ${templateKind}`,
612
+ ` path: ${absPath}`,
613
+ ];
614
+ if (missionNotesPath) {
615
+ humanLines.push(` mission-notes: ${missionNotesPath} (template: ${missionNotesResolvedFrom})`);
616
+ }
617
+ emit(out, {
618
+ ok: true,
619
+ mission: {
620
+ name,
621
+ id,
622
+ template: templateKind,
623
+ path: absPath,
624
+ readmePath,
625
+ missionNotesPath,
626
+ missionNotesResolvedFrom,
627
+ },
628
+ }, json, humanLines);
629
+ }
630
+ catch (err) {
631
+ fail(err, json, out);
632
+ }
633
+ });
634
+ }
635
+ // ---------------------------------------------------------------------
636
+ // Aggregate
637
+ // ---------------------------------------------------------------------
638
+ export function scopeCommand() {
639
+ const cmd = new Command("scope")
640
+ .description("Scope tree primitive: missions, slices, sub-slices (per conventions/scope-and-versioning)")
641
+ .option("--workspace <path>", "Override workspace root (otherwise inferred from cwd or $OPENRIG_WORK_ROOT)");
642
+ const slice = new Command("slice").description("Slice-tier commands");
643
+ slice.addCommand(buildSliceLsCommand());
644
+ slice.addCommand(buildSliceShowCommand());
645
+ slice.addCommand(buildSliceCreateCommand());
646
+ slice.addCommand(buildSliceShipCommand());
647
+ slice.addCommand(buildSliceCloseCommand());
648
+ slice.addCommand(buildSliceMoveCommand());
649
+ cmd.addCommand(slice);
650
+ const mission = new Command("mission").description("Mission-tier commands");
651
+ mission.addCommand(buildMissionLsCommand());
652
+ mission.addCommand(buildMissionShowCommand());
653
+ mission.addCommand(buildMissionCreateCommand());
654
+ cmd.addCommand(mission);
655
+ return cmd;
656
+ }
657
+ // Re-exports for tests.
658
+ export { DEFAULT_PROJECT_PREFIX, splitFrontmatter };
659
+ //# sourceMappingURL=scope.js.map