@slope-dev/slope 1.64.1 → 2.0.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 (461) hide show
  1. package/README.md +4 -0
  2. package/dist/cli/commands/agent.d.ts +3 -3
  3. package/dist/cli/commands/agent.d.ts.map +1 -1
  4. package/dist/cli/commands/agent.js +20 -12
  5. package/dist/cli/commands/agent.js.map +1 -1
  6. package/dist/cli/commands/auto-card.d.ts +2 -1
  7. package/dist/cli/commands/auto-card.d.ts.map +1 -1
  8. package/dist/cli/commands/auto-card.js +7 -7
  9. package/dist/cli/commands/auto-card.js.map +1 -1
  10. package/dist/cli/commands/briefing.d.ts.map +1 -1
  11. package/dist/cli/commands/briefing.js +16 -9
  12. package/dist/cli/commands/briefing.js.map +1 -1
  13. package/dist/cli/commands/claim.d.ts.map +1 -1
  14. package/dist/cli/commands/claim.js +6 -4
  15. package/dist/cli/commands/claim.js.map +1 -1
  16. package/dist/cli/commands/commit-ready.d.ts.map +1 -1
  17. package/dist/cli/commands/commit-ready.js.map +1 -1
  18. package/dist/cli/commands/context.d.ts.map +1 -1
  19. package/dist/cli/commands/context.js +2 -1
  20. package/dist/cli/commands/context.js.map +1 -1
  21. package/dist/cli/commands/dashboard.d.ts.map +1 -1
  22. package/dist/cli/commands/dashboard.js +3 -3
  23. package/dist/cli/commands/dashboard.js.map +1 -1
  24. package/dist/cli/commands/distill.d.ts.map +1 -1
  25. package/dist/cli/commands/distill.js +8 -20
  26. package/dist/cli/commands/distill.js.map +1 -1
  27. package/dist/cli/commands/enrich.d.ts.map +1 -1
  28. package/dist/cli/commands/enrich.js +2 -1
  29. package/dist/cli/commands/enrich.js.map +1 -1
  30. package/dist/cli/commands/escalate.d.ts.map +1 -1
  31. package/dist/cli/commands/escalate.js +11 -3
  32. package/dist/cli/commands/escalate.js.map +1 -1
  33. package/dist/cli/commands/extract.d.ts.map +1 -1
  34. package/dist/cli/commands/extract.js +20 -6
  35. package/dist/cli/commands/extract.js.map +1 -1
  36. package/dist/cli/commands/gate.d.ts.map +1 -1
  37. package/dist/cli/commands/gate.js +10 -7
  38. package/dist/cli/commands/gate.js.map +1 -1
  39. package/dist/cli/commands/index-cmd.d.ts.map +1 -1
  40. package/dist/cli/commands/index-cmd.js +2 -1
  41. package/dist/cli/commands/index-cmd.js.map +1 -1
  42. package/dist/cli/commands/init.d.ts.map +1 -1
  43. package/dist/cli/commands/init.js +26 -12
  44. package/dist/cli/commands/init.js.map +1 -1
  45. package/dist/cli/commands/initiative.d.ts.map +1 -1
  46. package/dist/cli/commands/initiative.js +9 -8
  47. package/dist/cli/commands/initiative.js.map +1 -1
  48. package/dist/cli/commands/inspirations.js +5 -5
  49. package/dist/cli/commands/inspirations.js.map +1 -1
  50. package/dist/cli/commands/interview.d.ts.map +1 -1
  51. package/dist/cli/commands/interview.js +2 -2
  52. package/dist/cli/commands/interview.js.map +1 -1
  53. package/dist/cli/commands/issue.d.ts.map +1 -1
  54. package/dist/cli/commands/issue.js +6 -9
  55. package/dist/cli/commands/issue.js.map +1 -1
  56. package/dist/cli/commands/map.d.ts +1 -1
  57. package/dist/cli/commands/map.d.ts.map +1 -1
  58. package/dist/cli/commands/map.js +34 -10
  59. package/dist/cli/commands/map.js.map +1 -1
  60. package/dist/cli/commands/next.js +2 -2
  61. package/dist/cli/commands/next.js.map +1 -1
  62. package/dist/cli/commands/now.d.ts +2 -2
  63. package/dist/cli/commands/now.d.ts.map +1 -1
  64. package/dist/cli/commands/now.js +23 -15
  65. package/dist/cli/commands/now.js.map +1 -1
  66. package/dist/cli/commands/pr.d.ts +3 -3
  67. package/dist/cli/commands/pr.d.ts.map +1 -1
  68. package/dist/cli/commands/pr.js +9 -8
  69. package/dist/cli/commands/pr.js.map +1 -1
  70. package/dist/cli/commands/prep.d.ts.map +1 -1
  71. package/dist/cli/commands/prep.js +2 -1
  72. package/dist/cli/commands/prep.js.map +1 -1
  73. package/dist/cli/commands/release.d.ts.map +1 -1
  74. package/dist/cli/commands/release.js +9 -11
  75. package/dist/cli/commands/release.js.map +1 -1
  76. package/dist/cli/commands/retro.d.ts +1 -1
  77. package/dist/cli/commands/retro.d.ts.map +1 -1
  78. package/dist/cli/commands/retro.js +35 -11
  79. package/dist/cli/commands/retro.js.map +1 -1
  80. package/dist/cli/commands/review-packet.d.ts +2 -2
  81. package/dist/cli/commands/review-packet.d.ts.map +1 -1
  82. package/dist/cli/commands/review-packet.js +3 -3
  83. package/dist/cli/commands/review-packet.js.map +1 -1
  84. package/dist/cli/commands/review-run.d.ts +3 -2
  85. package/dist/cli/commands/review-run.d.ts.map +1 -1
  86. package/dist/cli/commands/review-run.js +4 -4
  87. package/dist/cli/commands/review-run.js.map +1 -1
  88. package/dist/cli/commands/review-state.d.ts.map +1 -1
  89. package/dist/cli/commands/review-state.js +57 -30
  90. package/dist/cli/commands/review-state.js.map +1 -1
  91. package/dist/cli/commands/review.js +6 -6
  92. package/dist/cli/commands/review.js.map +1 -1
  93. package/dist/cli/commands/roadmap.d.ts.map +1 -1
  94. package/dist/cli/commands/roadmap.js +138 -78
  95. package/dist/cli/commands/roadmap.js.map +1 -1
  96. package/dist/cli/commands/session.d.ts.map +1 -1
  97. package/dist/cli/commands/session.js +47 -16
  98. package/dist/cli/commands/session.js.map +1 -1
  99. package/dist/cli/commands/sprint-plan.d.ts.map +1 -1
  100. package/dist/cli/commands/sprint-plan.js +10 -8
  101. package/dist/cli/commands/sprint-plan.js.map +1 -1
  102. package/dist/cli/commands/sprint.d.ts.map +1 -1
  103. package/dist/cli/commands/sprint.js +253 -38
  104. package/dist/cli/commands/sprint.js.map +1 -1
  105. package/dist/cli/commands/standup.d.ts.map +1 -1
  106. package/dist/cli/commands/standup.js +9 -4
  107. package/dist/cli/commands/standup.js.map +1 -1
  108. package/dist/cli/commands/start.js +2 -2
  109. package/dist/cli/commands/start.js.map +1 -1
  110. package/dist/cli/commands/stats.d.ts +4 -4
  111. package/dist/cli/commands/stats.d.ts.map +1 -1
  112. package/dist/cli/commands/stats.js +5 -5
  113. package/dist/cli/commands/stats.js.map +1 -1
  114. package/dist/cli/commands/status.d.ts +1 -1
  115. package/dist/cli/commands/status.d.ts.map +1 -1
  116. package/dist/cli/commands/status.js +12 -8
  117. package/dist/cli/commands/status.js.map +1 -1
  118. package/dist/cli/commands/store.d.ts +37 -0
  119. package/dist/cli/commands/store.d.ts.map +1 -1
  120. package/dist/cli/commands/store.js +262 -12
  121. package/dist/cli/commands/store.js.map +1 -1
  122. package/dist/cli/commands/ticket.d.ts.map +1 -1
  123. package/dist/cli/commands/ticket.js +4 -4
  124. package/dist/cli/commands/ticket.js.map +1 -1
  125. package/dist/cli/commands/tournament.d.ts.map +1 -1
  126. package/dist/cli/commands/tournament.js +7 -6
  127. package/dist/cli/commands/tournament.js.map +1 -1
  128. package/dist/cli/commands/validate.d.ts +4 -3
  129. package/dist/cli/commands/validate.d.ts.map +1 -1
  130. package/dist/cli/commands/validate.js +37 -10
  131. package/dist/cli/commands/validate.js.map +1 -1
  132. package/dist/cli/commands/version.d.ts +1 -1
  133. package/dist/cli/commands/version.d.ts.map +1 -1
  134. package/dist/cli/commands/version.js +13 -10
  135. package/dist/cli/commands/version.js.map +1 -1
  136. package/dist/cli/commands/worktree.d.ts.map +1 -1
  137. package/dist/cli/commands/worktree.js +36 -31
  138. package/dist/cli/commands/worktree.js.map +1 -1
  139. package/dist/cli/guards/claim-required.d.ts.map +1 -1
  140. package/dist/cli/guards/claim-required.js +2 -3
  141. package/dist/cli/guards/claim-required.js.map +1 -1
  142. package/dist/cli/guards/compaction.d.ts.map +1 -1
  143. package/dist/cli/guards/git-utils.d.ts +5 -0
  144. package/dist/cli/guards/git-utils.d.ts.map +1 -1
  145. package/dist/cli/guards/git-utils.js +36 -8
  146. package/dist/cli/guards/git-utils.js.map +1 -1
  147. package/dist/cli/guards/hazard.d.ts.map +1 -1
  148. package/dist/cli/guards/hazard.js +8 -7
  149. package/dist/cli/guards/hazard.js.map +1 -1
  150. package/dist/cli/guards/next-action.d.ts +5 -5
  151. package/dist/cli/guards/next-action.d.ts.map +1 -1
  152. package/dist/cli/guards/next-action.js +8 -8
  153. package/dist/cli/guards/next-action.js.map +1 -1
  154. package/dist/cli/guards/phase-boundary.d.ts.map +1 -1
  155. package/dist/cli/guards/phase-boundary.js +24 -14
  156. package/dist/cli/guards/phase-boundary.js.map +1 -1
  157. package/dist/cli/guards/post-hole-enforcement.d.ts.map +1 -1
  158. package/dist/cli/guards/post-hole-enforcement.js +9 -8
  159. package/dist/cli/guards/post-hole-enforcement.js.map +1 -1
  160. package/dist/cli/guards/post-push.d.ts.map +1 -1
  161. package/dist/cli/guards/post-push.js +7 -3
  162. package/dist/cli/guards/post-push.js.map +1 -1
  163. package/dist/cli/guards/review-stale.d.ts.map +1 -1
  164. package/dist/cli/guards/review-stale.js +6 -4
  165. package/dist/cli/guards/review-stale.js.map +1 -1
  166. package/dist/cli/guards/review-tier.d.ts.map +1 -1
  167. package/dist/cli/guards/review-tier.js +6 -7
  168. package/dist/cli/guards/review-tier.js.map +1 -1
  169. package/dist/cli/guards/roadmap-edit-shipped.d.ts.map +1 -1
  170. package/dist/cli/guards/roadmap-edit-shipped.js +34 -21
  171. package/dist/cli/guards/roadmap-edit-shipped.js.map +1 -1
  172. package/dist/cli/guards/scope-drift.d.ts.map +1 -1
  173. package/dist/cli/guards/scope-drift.js +2 -1
  174. package/dist/cli/guards/scope-drift.js.map +1 -1
  175. package/dist/cli/guards/session-briefing.d.ts.map +1 -1
  176. package/dist/cli/guards/session-briefing.js +34 -13
  177. package/dist/cli/guards/session-briefing.js.map +1 -1
  178. package/dist/cli/guards/sprint-completion.d.ts.map +1 -1
  179. package/dist/cli/guards/sprint-completion.js +32 -16
  180. package/dist/cli/guards/sprint-completion.js.map +1 -1
  181. package/dist/cli/guards/stop-check.d.ts.map +1 -1
  182. package/dist/cli/guards/stop-check.js +8 -10
  183. package/dist/cli/guards/stop-check.js.map +1 -1
  184. package/dist/cli/guards/transcript.d.ts.map +1 -1
  185. package/dist/cli/guards/transcript.js +2 -1
  186. package/dist/cli/guards/transcript.js.map +1 -1
  187. package/dist/cli/guards/workflow-step-gate.d.ts.map +1 -1
  188. package/dist/cli/guards/workflow-step-gate.js +25 -28
  189. package/dist/cli/guards/workflow-step-gate.js.map +1 -1
  190. package/dist/cli/guards/worktree-check.d.ts.map +1 -1
  191. package/dist/cli/guards/worktree-check.js +38 -13
  192. package/dist/cli/guards/worktree-check.js.map +1 -1
  193. package/dist/cli/hooks-config.d.ts.map +1 -1
  194. package/dist/cli/hooks-config.js +6 -4
  195. package/dist/cli/hooks-config.js.map +1 -1
  196. package/dist/cli/index.js +1 -1
  197. package/dist/cli/index.js.map +1 -1
  198. package/dist/cli/loop/executor.d.ts +1 -0
  199. package/dist/cli/loop/executor.d.ts.map +1 -1
  200. package/dist/cli/loop/executor.js +20 -13
  201. package/dist/cli/loop/executor.js.map +1 -1
  202. package/dist/cli/loop/pr-lifecycle.d.ts +2 -1
  203. package/dist/cli/loop/pr-lifecycle.d.ts.map +1 -1
  204. package/dist/cli/loop/pr-lifecycle.js +14 -8
  205. package/dist/cli/loop/pr-lifecycle.js.map +1 -1
  206. package/dist/cli/loop/worktree.d.ts.map +1 -1
  207. package/dist/cli/loop/worktree.js +1 -48
  208. package/dist/cli/loop/worktree.js.map +1 -1
  209. package/dist/cli/pr-closeout.d.ts +3 -2
  210. package/dist/cli/pr-closeout.d.ts.map +1 -1
  211. package/dist/cli/pr-closeout.js +14 -6
  212. package/dist/cli/pr-closeout.js.map +1 -1
  213. package/dist/cli/pr-review-state.d.ts +8 -7
  214. package/dist/cli/pr-review-state.d.ts.map +1 -1
  215. package/dist/cli/pr-review-state.js +3 -2
  216. package/dist/cli/pr-review-state.js.map +1 -1
  217. package/dist/cli/pre-sprint-reality.d.ts +4 -4
  218. package/dist/cli/pre-sprint-reality.d.ts.map +1 -1
  219. package/dist/cli/pre-sprint-reality.js +9 -2
  220. package/dist/cli/pre-sprint-reality.js.map +1 -1
  221. package/dist/cli/registries/api-registry.d.ts +2 -2
  222. package/dist/cli/registries/api-registry.d.ts.map +1 -1
  223. package/dist/cli/registries/api-registry.js +1 -1
  224. package/dist/cli/registries/api-registry.js.map +1 -1
  225. package/dist/cli/registries/file-registry.d.ts +3 -3
  226. package/dist/cli/registries/file-registry.d.ts.map +1 -1
  227. package/dist/cli/registries/file-registry.js +12 -2
  228. package/dist/cli/registries/file-registry.js.map +1 -1
  229. package/dist/cli/registries/index.d.ts +1 -1
  230. package/dist/cli/registries/index.d.ts.map +1 -1
  231. package/dist/cli/registries/index.js +2 -2
  232. package/dist/cli/registries/index.js.map +1 -1
  233. package/dist/cli/registry.d.ts.map +1 -1
  234. package/dist/cli/registry.js +4 -0
  235. package/dist/cli/registry.js.map +1 -1
  236. package/dist/cli/reviewer-agents.d.ts +2 -1
  237. package/dist/cli/reviewer-agents.d.ts.map +1 -1
  238. package/dist/cli/reviewer-agents.js.map +1 -1
  239. package/dist/cli/roadmap-source-migration.d.ts.map +1 -1
  240. package/dist/cli/roadmap-source-migration.js +15 -13
  241. package/dist/cli/roadmap-source-migration.js.map +1 -1
  242. package/dist/cli/roadmap-source-store.d.ts +4 -4
  243. package/dist/cli/roadmap-source-store.d.ts.map +1 -1
  244. package/dist/cli/roadmap-source-store.js +38 -32
  245. package/dist/cli/roadmap-source-store.js.map +1 -1
  246. package/dist/cli/session-heartbeat.d.ts +12 -0
  247. package/dist/cli/session-heartbeat.d.ts.map +1 -0
  248. package/dist/cli/session-heartbeat.js +46 -0
  249. package/dist/cli/session-heartbeat.js.map +1 -0
  250. package/dist/cli/session-scope.d.ts.map +1 -1
  251. package/dist/cli/session-scope.js +4 -16
  252. package/dist/cli/session-scope.js.map +1 -1
  253. package/dist/cli/session-state.js +5 -5
  254. package/dist/cli/session-state.js.map +1 -1
  255. package/dist/cli/sprint-inference.d.ts +5 -5
  256. package/dist/cli/sprint-inference.d.ts.map +1 -1
  257. package/dist/cli/sprint-inference.js +63 -33
  258. package/dist/cli/sprint-inference.js.map +1 -1
  259. package/dist/cli/sprint-resume.d.ts +7 -7
  260. package/dist/cli/sprint-resume.d.ts.map +1 -1
  261. package/dist/cli/sprint-resume.js +43 -21
  262. package/dist/cli/sprint-resume.js.map +1 -1
  263. package/dist/cli/sprint-rollover.d.ts +19 -19
  264. package/dist/cli/sprint-rollover.d.ts.map +1 -1
  265. package/dist/cli/sprint-rollover.js +116 -69
  266. package/dist/cli/sprint-rollover.js.map +1 -1
  267. package/dist/cli/sprint-state.d.ts +8 -6
  268. package/dist/cli/sprint-state.d.ts.map +1 -1
  269. package/dist/cli/sprint-state.js +39 -12
  270. package/dist/cli/sprint-state.js.map +1 -1
  271. package/dist/cli/store.d.ts.map +1 -1
  272. package/dist/cli/store.js +5 -3
  273. package/dist/cli/store.js.map +1 -1
  274. package/dist/cli/workflow-closeout.d.ts +11 -0
  275. package/dist/cli/workflow-closeout.d.ts.map +1 -0
  276. package/dist/cli/workflow-closeout.js +30 -0
  277. package/dist/cli/workflow-closeout.js.map +1 -0
  278. package/dist/cli/workflow-resync.d.ts +13 -9
  279. package/dist/cli/workflow-resync.d.ts.map +1 -1
  280. package/dist/cli/workflow-resync.js +75 -22
  281. package/dist/cli/workflow-resync.js.map +1 -1
  282. package/dist/core/advisor.d.ts.map +1 -1
  283. package/dist/core/advisor.js +5 -2
  284. package/dist/core/advisor.js.map +1 -1
  285. package/dist/core/analytics.d.ts +2 -2
  286. package/dist/core/analytics.d.ts.map +1 -1
  287. package/dist/core/analytics.js +4 -3
  288. package/dist/core/analytics.js.map +1 -1
  289. package/dist/core/analyzers/git.d.ts +3 -2
  290. package/dist/core/analyzers/git.d.ts.map +1 -1
  291. package/dist/core/analyzers/git.js +6 -5
  292. package/dist/core/analyzers/git.js.map +1 -1
  293. package/dist/core/briefing.d.ts +6 -5
  294. package/dist/core/briefing.d.ts.map +1 -1
  295. package/dist/core/briefing.js +52 -36
  296. package/dist/core/briefing.js.map +1 -1
  297. package/dist/core/builder.d.ts +3 -1
  298. package/dist/core/builder.d.ts.map +1 -1
  299. package/dist/core/builder.js +6 -4
  300. package/dist/core/builder.js.map +1 -1
  301. package/dist/core/config.d.ts +2 -1
  302. package/dist/core/config.d.ts.map +1 -1
  303. package/dist/core/config.js +26 -6
  304. package/dist/core/config.js.map +1 -1
  305. package/dist/core/dashboard.d.ts +2 -2
  306. package/dist/core/dashboard.d.ts.map +1 -1
  307. package/dist/core/dashboard.js +2 -1
  308. package/dist/core/dashboard.js.map +1 -1
  309. package/dist/core/deferred.d.ts +7 -6
  310. package/dist/core/deferred.d.ts.map +1 -1
  311. package/dist/core/deferred.js +30 -7
  312. package/dist/core/deferred.js.map +1 -1
  313. package/dist/core/enrich.d.ts +1 -1
  314. package/dist/core/escalation.d.ts +2 -1
  315. package/dist/core/escalation.d.ts.map +1 -1
  316. package/dist/core/escalation.js +3 -1
  317. package/dist/core/escalation.js.map +1 -1
  318. package/dist/core/event-ingestion.d.ts.map +1 -1
  319. package/dist/core/event-ingestion.js +8 -3
  320. package/dist/core/event-ingestion.js.map +1 -1
  321. package/dist/core/findings.d.ts +6 -4
  322. package/dist/core/findings.d.ts.map +1 -1
  323. package/dist/core/findings.js +30 -7
  324. package/dist/core/findings.js.map +1 -1
  325. package/dist/core/formatter.d.ts +2 -1
  326. package/dist/core/formatter.d.ts.map +1 -1
  327. package/dist/core/formatter.js.map +1 -1
  328. package/dist/core/generators/roadmap.js +2 -2
  329. package/dist/core/generators/roadmap.js.map +1 -1
  330. package/dist/core/index.d.ts +8 -5
  331. package/dist/core/index.d.ts.map +1 -1
  332. package/dist/core/index.js +4 -2
  333. package/dist/core/index.js.map +1 -1
  334. package/dist/core/initiative.d.ts +5 -4
  335. package/dist/core/initiative.d.ts.map +1 -1
  336. package/dist/core/initiative.js +39 -11
  337. package/dist/core/initiative.js.map +1 -1
  338. package/dist/core/inspirations.d.ts +4 -3
  339. package/dist/core/inspirations.d.ts.map +1 -1
  340. package/dist/core/inspirations.js +19 -4
  341. package/dist/core/inspirations.js.map +1 -1
  342. package/dist/core/interview-engine.d.ts +2 -1
  343. package/dist/core/interview-engine.d.ts.map +1 -1
  344. package/dist/core/interview-engine.js +26 -17
  345. package/dist/core/interview-engine.js.map +1 -1
  346. package/dist/core/interview-steps.d.ts.map +1 -1
  347. package/dist/core/interview-steps.js +7 -6
  348. package/dist/core/interview-steps.js.map +1 -1
  349. package/dist/core/interview.d.ts +2 -1
  350. package/dist/core/interview.d.ts.map +1 -1
  351. package/dist/core/interview.js +13 -7
  352. package/dist/core/interview.js.map +1 -1
  353. package/dist/core/issue-scout.d.ts +2 -1
  354. package/dist/core/issue-scout.d.ts.map +1 -1
  355. package/dist/core/issue-scout.js.map +1 -1
  356. package/dist/core/loader.d.ts +4 -4
  357. package/dist/core/loader.d.ts.map +1 -1
  358. package/dist/core/loader.js +71 -33
  359. package/dist/core/loader.js.map +1 -1
  360. package/dist/core/memory.d.ts.map +1 -1
  361. package/dist/core/memory.js +16 -6
  362. package/dist/core/memory.js.map +1 -1
  363. package/dist/core/org.d.ts +1 -1
  364. package/dist/core/org.d.ts.map +1 -1
  365. package/dist/core/org.js +2 -1
  366. package/dist/core/org.js.map +1 -1
  367. package/dist/core/pipeline.d.ts +1 -1
  368. package/dist/core/pipeline.d.ts.map +1 -1
  369. package/dist/core/pipeline.js +10 -6
  370. package/dist/core/pipeline.js.map +1 -1
  371. package/dist/core/player.d.ts.map +1 -1
  372. package/dist/core/player.js +2 -1
  373. package/dist/core/player.js.map +1 -1
  374. package/dist/core/prep.d.ts +3 -3
  375. package/dist/core/registry.d.ts +6 -2
  376. package/dist/core/registry.d.ts.map +1 -1
  377. package/dist/core/registry.js +2 -1
  378. package/dist/core/registry.js.map +1 -1
  379. package/dist/core/repo-state-scope.d.ts +27 -0
  380. package/dist/core/repo-state-scope.d.ts.map +1 -0
  381. package/dist/core/repo-state-scope.js +105 -0
  382. package/dist/core/repo-state-scope.js.map +1 -0
  383. package/dist/core/report.d.ts +1 -1
  384. package/dist/core/report.d.ts.map +1 -1
  385. package/dist/core/report.js +2 -1
  386. package/dist/core/report.js.map +1 -1
  387. package/dist/core/retro.d.ts +3 -2
  388. package/dist/core/retro.d.ts.map +1 -1
  389. package/dist/core/retro.js +6 -3
  390. package/dist/core/retro.js.map +1 -1
  391. package/dist/core/roadmap-focus.d.ts +8 -7
  392. package/dist/core/roadmap-focus.d.ts.map +1 -1
  393. package/dist/core/roadmap-focus.js +45 -34
  394. package/dist/core/roadmap-focus.js.map +1 -1
  395. package/dist/core/roadmap-migration.d.ts +2 -1
  396. package/dist/core/roadmap-migration.d.ts.map +1 -1
  397. package/dist/core/roadmap-migration.js +110 -51
  398. package/dist/core/roadmap-migration.js.map +1 -1
  399. package/dist/core/roadmap-source-patch.d.ts +2 -1
  400. package/dist/core/roadmap-source-patch.d.ts.map +1 -1
  401. package/dist/core/roadmap-source-patch.js +9 -4
  402. package/dist/core/roadmap-source-patch.js.map +1 -1
  403. package/dist/core/roadmap-sources.d.ts +2 -1
  404. package/dist/core/roadmap-sources.d.ts.map +1 -1
  405. package/dist/core/roadmap-sources.js +38 -26
  406. package/dist/core/roadmap-sources.js.map +1 -1
  407. package/dist/core/roadmap.d.ts +22 -16
  408. package/dist/core/roadmap.d.ts.map +1 -1
  409. package/dist/core/roadmap.js +152 -84
  410. package/dist/core/roadmap.js.map +1 -1
  411. package/dist/core/session-branch.d.ts +17 -0
  412. package/dist/core/session-branch.d.ts.map +1 -0
  413. package/dist/core/session-branch.js +85 -0
  414. package/dist/core/session-branch.js.map +1 -0
  415. package/dist/core/sprint-id.d.ts +13 -5
  416. package/dist/core/sprint-id.d.ts.map +1 -1
  417. package/dist/core/sprint-id.js +16 -0
  418. package/dist/core/sprint-id.js.map +1 -1
  419. package/dist/core/standup.d.ts +2 -1
  420. package/dist/core/standup.d.ts.map +1 -1
  421. package/dist/core/standup.js.map +1 -1
  422. package/dist/core/store.d.ts +16 -8
  423. package/dist/core/store.d.ts.map +1 -1
  424. package/dist/core/store.js +34 -0
  425. package/dist/core/store.js.map +1 -1
  426. package/dist/core/tournament.d.ts.map +1 -1
  427. package/dist/core/tournament.js +4 -3
  428. package/dist/core/tournament.js.map +1 -1
  429. package/dist/core/types.d.ts +9 -7
  430. package/dist/core/types.d.ts.map +1 -1
  431. package/dist/core/validation.d.ts +2 -1
  432. package/dist/core/validation.d.ts.map +1 -1
  433. package/dist/core/validation.js +2 -1
  434. package/dist/core/validation.js.map +1 -1
  435. package/dist/core/webhooks.d.ts +3 -2
  436. package/dist/core/webhooks.d.ts.map +1 -1
  437. package/dist/core/webhooks.js +9 -2
  438. package/dist/core/webhooks.js.map +1 -1
  439. package/dist/core/workflow-loader.d.ts.map +1 -1
  440. package/dist/core/workflow-loader.js +2 -1
  441. package/dist/core/workflow-loader.js.map +1 -1
  442. package/dist/mcp/index.d.ts +5 -1
  443. package/dist/mcp/index.d.ts.map +1 -1
  444. package/dist/mcp/index.js +97 -59
  445. package/dist/mcp/index.js.map +1 -1
  446. package/dist/mcp/index.test.js +14 -3
  447. package/dist/mcp/index.test.js.map +1 -1
  448. package/dist/mcp/registry.d.ts +1 -1
  449. package/dist/mcp/registry.d.ts.map +1 -1
  450. package/dist/mcp/registry.js +36 -28
  451. package/dist/mcp/registry.js.map +1 -1
  452. package/dist/store/index.d.ts +13 -11
  453. package/dist/store/index.d.ts.map +1 -1
  454. package/dist/store/index.js +217 -36
  455. package/dist/store/index.js.map +1 -1
  456. package/dist/store-pg/index.d.ts +18 -12
  457. package/dist/store-pg/index.d.ts.map +1 -1
  458. package/dist/store-pg/index.js +124 -38
  459. package/dist/store-pg/index.js.map +1 -1
  460. package/package.json +1 -1
  461. package/templates/codex/plugins/slope/.codex-plugin/plugin.json +1 -1
@@ -1,5 +1,6 @@
1
1
  // SLOPE — Roadmap: Strategic planning types and compute functions
2
2
  // Course-level methodology — vision → roadmap → review → iteration
3
+ import { compareSprintIdKeys, parseSprintId, sprintIdKey } from './sprint-id.js';
3
4
  /** Return true for legacy encoded inserted half-sprint ids like 435 => S43.5.
4
5
  * Decimal roadmap ids such as 75.5 are already explicit and are left as-is.
5
6
  * The encoding is intentionally limited to pre-S100-style three-digit ids
@@ -19,6 +20,8 @@ export function sprintOrderValue(id) {
19
20
  }
20
21
  /** Format the numeric portion of a sprint id for human-facing output. */
21
22
  export function formatSprintNumber(id) {
23
+ if (typeof id === 'string')
24
+ return sprintIdKey(id) ?? id;
22
25
  if (isEncodedInsertedSprintId(id)) {
23
26
  return `${Math.floor(id / 10)}.${id % 10}`;
24
27
  }
@@ -91,13 +94,13 @@ export function compareSprintIds(a, b) {
91
94
  }
92
95
  /** Return the next canonical sprint id after a completed sprint/inserted sprint. */
93
96
  export function nextCanonicalSprintId(id) {
94
- if (isEncodedInsertedSprintId(id)) {
95
- return Math.floor(id / 10) + 1;
96
- }
97
- if (!Number.isInteger(id)) {
98
- return Math.floor(id) + 1;
97
+ if (typeof id === 'number' && isEncodedInsertedSprintId(id)) {
98
+ return String(Math.floor(id / 10) + 1);
99
99
  }
100
- return id + 1;
100
+ const parsed = parseSprintId(id);
101
+ if (!parsed)
102
+ return '1';
103
+ return String(parsed.base + 1);
101
104
  }
102
105
  export const ROADMAP_TERMINAL_STATUSES = new Set([
103
106
  'complete',
@@ -169,13 +172,31 @@ export function isEncodedInsertedSprintInRoadmap(roadmap, id) {
169
172
  return sprintIds.has(base) || sprintIds.has(base + 1);
170
173
  }
171
174
  export function roadmapSprintOrderValue(roadmap, id) {
172
- return isEncodedInsertedSprintInRoadmap(roadmap, id) ? sprintOrderValue(id) : id;
175
+ const key = roadmapSprintKeyFromId(roadmap, id);
176
+ const parsed = key ? parseSprintId(key) : null;
177
+ if (!parsed)
178
+ return typeof id === 'number' ? id : Number(id);
179
+ if (parsed.insert === null)
180
+ return parsed.base;
181
+ return parsed.base + parsed.insert / (10 ** parsed.insertDigits.length);
173
182
  }
174
183
  export function compareRoadmapSprintIds(roadmap, a, b) {
175
- return roadmapSprintOrderValue(roadmap, a) - roadmapSprintOrderValue(roadmap, b);
184
+ const ka = roadmapSprintKeyFromId(roadmap, a) ?? String(a);
185
+ const kb = roadmapSprintKeyFromId(roadmap, b) ?? String(b);
186
+ return compareSprintIdKeys(ka, kb);
187
+ }
188
+ function areAdjacentSprintKeys(previousKey, currentKey) {
189
+ const previous = parseSprintId(previousKey);
190
+ const current = parseSprintId(currentKey);
191
+ if (!previous || !current)
192
+ return false;
193
+ if (previous.base === current.base) {
194
+ return current.insert !== null && compareSprintIdKeys(previousKey, currentKey) < 0;
195
+ }
196
+ return current.base === previous.base + 1 && current.insert === null;
176
197
  }
177
198
  export function formatRoadmapSprintLabel(roadmap, id) {
178
- return isEncodedInsertedSprintInRoadmap(roadmap, id) ? formatSprintLabel(id) : `S${id}`;
199
+ return `S${roadmapSprintKeyFromId(roadmap, id) ?? id}`;
179
200
  }
180
201
  /**
181
202
  * Canonical string identity for a sprint: the authored `id_key` when present
@@ -190,6 +211,24 @@ export function roadmapSprintKey(roadmap, sprint) {
190
211
  ? formatSprintNumber(sprint.id)
191
212
  : String(sprint.id);
192
213
  }
214
+ /** Resolve a canonical sprint key from either a key or a legacy numeric mirror. */
215
+ export function roadmapSprintKeyFromId(roadmap, id) {
216
+ const inputKey = sprintIdKey(id);
217
+ if (inputKey === null)
218
+ return null;
219
+ const canonical = roadmap.sprints.find(sprint => roadmapSprintKey(roadmap, sprint) === inputKey);
220
+ if (canonical)
221
+ return roadmapSprintKey(roadmap, canonical);
222
+ const mirror = roadmap.sprints.find(sprint => sprint.id === Number(inputKey));
223
+ return mirror ? roadmapSprintKey(roadmap, mirror) : inputKey;
224
+ }
225
+ /** Find one roadmap sprint by canonical key, with numeric mirrors as legacy input. */
226
+ export function findRoadmapSprint(roadmap, id) {
227
+ const key = roadmapSprintKeyFromId(roadmap, id);
228
+ return key == null
229
+ ? undefined
230
+ : roadmap.sprints.find(sprint => roadmapSprintKey(roadmap, sprint) === key);
231
+ }
193
232
  /** Validate a roadmap definition for structural correctness.
194
233
  * Optionally cross-check sprint status against scorecards and/or shipped
195
234
  * sprint commits on main when provided. Caller is responsible for collecting
@@ -198,8 +237,7 @@ export function roadmapSprintKey(roadmap, sprint) {
198
237
  export function validateRoadmap(roadmap, scorecards, shippedSprintIds) {
199
238
  const errors = [];
200
239
  const warnings = [];
201
- const sprintIds = new Set(roadmap.sprints.map(s => s.id));
202
- const orderOf = (id) => roadmapSprintOrderValue(roadmap, id);
240
+ const sprintIds = new Set(roadmap.sprints.map(s => roadmapSprintKey(roadmap, s)));
203
241
  const labelOf = (id) => formatRoadmapSprintLabel(roadmap, id);
204
242
  // Canonical identity so 458.10 and 458.1 are distinct sprints with distinct
205
243
  // ticket-key prefixes (GH #635).
@@ -210,12 +248,9 @@ export function validateRoadmap(roadmap, scorecards, shippedSprintIds) {
210
248
  return { valid: false, errors, warnings };
211
249
  }
212
250
  // Check: sprint numbering continuity
213
- const sortedIds = [...sprintIds].sort((a, b) => orderOf(a) - orderOf(b));
251
+ const sortedIds = [...sprintIds].sort((a, b) => compareSprintIdKeys(a, b));
214
252
  for (let i = 1; i < sortedIds.length; i++) {
215
- const prev = orderOf(sortedIds[i - 1]);
216
- const current = orderOf(sortedIds[i]);
217
- const allowedInsertedStep = current > prev && current <= Math.floor(prev) + 1;
218
- if (!allowedInsertedStep && current !== prev + 1) {
253
+ if (!areAdjacentSprintKeys(sortedIds[i - 1], sortedIds[i])) {
219
254
  // A long-lived roadmap legitimately skips numbers as sprints are
220
255
  // absorbed, cancelled, or renumbered, so a numbering discontinuity is
221
256
  // informational rather than a structural error. Genuinely-structural
@@ -236,19 +271,20 @@ export function validateRoadmap(roadmap, scorecards, shippedSprintIds) {
236
271
  // Build a set of all ticket keys across all sprints for cross-sprint dependency validation
237
272
  const allTicketKeys = new Set(roadmap.sprints.flatMap(s => s.tickets.map(getRoadmapTicketKey).filter((key) => key !== null)));
238
273
  for (const sprint of roadmap.sprints) {
274
+ const sprintKey = roadmapSprintKey(roadmap, sprint);
239
275
  // Check: ticket count (3-4 per sprint)
240
276
  if (sprint.tickets.length < 3) {
241
277
  warnings.push({
242
278
  type: 'warning',
243
- sprint: sprint.id,
244
- message: `${labelOf(sprint.id)} has ${sprint.tickets.length} tickets (recommended 3-4)`,
279
+ sprint: sprintKey,
280
+ message: `${keyLabelOf(sprint)} has ${sprint.tickets.length} tickets (recommended 3-4)`,
245
281
  });
246
282
  }
247
283
  if (sprint.tickets.length > 4) {
248
284
  warnings.push({
249
285
  type: 'warning',
250
- sprint: sprint.id,
251
- message: `${labelOf(sprint.id)} has ${sprint.tickets.length} tickets (recommended 3-4)`,
286
+ sprint: sprintKey,
287
+ message: `${keyLabelOf(sprint)} has ${sprint.tickets.length} tickets (recommended 3-4)`,
252
288
  });
253
289
  }
254
290
  // Check: ticket key format matches sprint
@@ -258,15 +294,15 @@ export function validateRoadmap(roadmap, scorecards, shippedSprintIds) {
258
294
  if (!ticketKey) {
259
295
  errors.push({
260
296
  type: 'error',
261
- sprint: sprint.id,
262
- message: `Ticket in ${labelOf(sprint.id)} is missing key/id`,
297
+ sprint: sprintKey,
298
+ message: `Ticket in ${keyLabelOf(sprint)} is missing key/id`,
263
299
  });
264
300
  continue;
265
301
  }
266
302
  if (!ticketKey.startsWith(expected)) {
267
303
  errors.push({
268
304
  type: 'error',
269
- sprint: sprint.id,
305
+ sprint: sprintKey,
270
306
  ticket: ticketKey,
271
307
  message: `Ticket ${ticketKey} does not match sprint ${keyLabelOf(sprint)} (expected prefix ${expected})`,
272
308
  });
@@ -281,7 +317,7 @@ export function validateRoadmap(roadmap, scorecards, shippedSprintIds) {
281
317
  if (!allTicketKeys.has(dep)) {
282
318
  errors.push({
283
319
  type: 'error',
284
- sprint: sprint.id,
320
+ sprint: sprintKey,
285
321
  ticket: ticketKey,
286
322
  message: `Ticket ${ticketKey} depends on ${dep} which does not exist in the roadmap`,
287
323
  });
@@ -290,11 +326,12 @@ export function validateRoadmap(roadmap, scorecards, shippedSprintIds) {
290
326
  }
291
327
  // Check: sprint dependencies exist
292
328
  for (const dep of sprint.depends_on ?? []) {
293
- if (!sprintIds.has(dep)) {
329
+ const depKey = roadmapSprintKeyFromId(roadmap, dep);
330
+ if (depKey === null || !sprintIds.has(depKey)) {
294
331
  errors.push({
295
332
  type: 'error',
296
- sprint: sprint.id,
297
- message: `${labelOf(sprint.id)} depends on ${labelOf(dep)} which does not exist in the roadmap`,
333
+ sprint: sprintKey,
334
+ message: `${labelOf(roadmapSprintKey(roadmap, sprint))} depends on ${labelOf(dep)} which does not exist in the roadmap`,
298
335
  });
299
336
  }
300
337
  }
@@ -302,8 +339,8 @@ export function validateRoadmap(roadmap, scorecards, shippedSprintIds) {
302
339
  if (sprint.par < 3 || sprint.par > 5) {
303
340
  errors.push({
304
341
  type: 'error',
305
- sprint: sprint.id,
306
- message: `${labelOf(sprint.id)} has invalid par ${sprint.par} (must be 3, 4, or 5)`,
342
+ sprint: sprintKey,
343
+ message: `${keyLabelOf(sprint)} has invalid par ${sprint.par} (must be 3, 4, or 5)`,
307
344
  });
308
345
  }
309
346
  }
@@ -317,8 +354,10 @@ export function validateRoadmap(roadmap, scorecards, shippedSprintIds) {
317
354
  }
318
355
  // Check: phases reference valid sprint IDs
319
356
  for (const phase of roadmap.phases) {
320
- for (const sid of phase.sprints) {
321
- if (!sprintIds.has(sid)) {
357
+ const phaseSprintIds = phase.sprint_keys ?? phase.sprints;
358
+ for (const sid of phaseSprintIds) {
359
+ const sidKey = roadmapSprintKeyFromId(roadmap, sid);
360
+ if (sidKey === null || !sprintIds.has(sidKey)) {
322
361
  errors.push({
323
362
  type: 'error',
324
363
  message: `Phase "${phase.name}" references ${labelOf(sid)} which does not exist`,
@@ -328,22 +367,22 @@ export function validateRoadmap(roadmap, scorecards, shippedSprintIds) {
328
367
  }
329
368
  // Cross-validate sprint status against scorecards when provided
330
369
  if (scorecards) {
331
- const scorecardSprintIds = new Set(scorecards.map(s => s.sprint_number));
370
+ const scorecardSprintIds = new Set(scorecards.map(s => roadmapSprintKeyFromId(roadmap, s.sprint_number)));
332
371
  for (const sprint of roadmap.sprints) {
333
- const hasScorecard = scorecardSprintIds.has(sprint.id);
372
+ const hasScorecard = scorecardSprintIds.has(roadmapSprintKey(roadmap, sprint));
334
373
  const status = sprint.status;
335
374
  if (hasScorecard && status !== 'complete') {
336
375
  warnings.push({
337
376
  type: 'warning',
338
- sprint: sprint.id,
339
- message: `${labelOf(sprint.id)} has a scorecard but roadmap status is "${status ?? 'planned'}" — expected "complete"`,
377
+ sprint: roadmapSprintKey(roadmap, sprint),
378
+ message: `${keyLabelOf(sprint)} has a scorecard but roadmap status is "${status ?? 'planned'}" — expected "complete"`,
340
379
  });
341
380
  }
342
381
  if (!hasScorecard && status === 'complete') {
343
382
  warnings.push({
344
383
  type: 'warning',
345
- sprint: sprint.id,
346
- message: `${labelOf(sprint.id)} is marked "complete" in roadmap but no scorecard exists (phantom sprint)`,
384
+ sprint: roadmapSprintKey(roadmap, sprint),
385
+ message: `${keyLabelOf(sprint)} is marked "complete" in roadmap but no scorecard exists (phantom sprint)`,
347
386
  });
348
387
  }
349
388
  }
@@ -355,21 +394,25 @@ export function validateRoadmap(roadmap, scorecards, shippedSprintIds) {
355
394
  // bookkeeping, not a feature ship). Treat those terminal-but-not-complete
356
395
  // statuses as final rather than demanding "complete".
357
396
  const TERMINAL_NOT_COMPLETE = new Set(['superseded', 'skipped', 'cancelled', 'cancelled-absorbed', 'absorbed']);
397
+ const shippedSprintKeys = new Set([...shippedSprintIds]
398
+ .map(id => roadmapSprintKeyFromId(roadmap, id))
399
+ .filter((id) => id !== null));
358
400
  for (const sprint of roadmap.sprints) {
359
401
  const status = sprint.status;
360
- const isShipped = shippedSprintIds.has(sprint.id);
402
+ const key = roadmapSprintKey(roadmap, sprint);
403
+ const isShipped = shippedSprintKeys.has(key);
361
404
  if (isShipped && status !== 'complete' && !TERMINAL_NOT_COMPLETE.has(status ?? '')) {
362
405
  errors.push({
363
406
  type: 'error',
364
- sprint: sprint.id,
365
- message: `${labelOf(sprint.id)} has shipped commits on main but status is "${status ?? 'planned'}" — expected "complete"`,
407
+ sprint: key,
408
+ message: `${keyLabelOf(sprint)} has shipped commits on main but status is "${status ?? 'planned'}" — expected "complete"`,
366
409
  });
367
410
  }
368
411
  if (!isShipped && status === 'complete') {
369
412
  warnings.push({
370
413
  type: 'warning',
371
- sprint: sprint.id,
372
- message: `${labelOf(sprint.id)} is marked "complete" but no shipped commits found on main`,
414
+ sprint: key,
415
+ message: `${keyLabelOf(sprint)} is marked "complete" but no shipped commits found on main`,
373
416
  });
374
417
  }
375
418
  }
@@ -379,29 +422,34 @@ export function validateRoadmap(roadmap, scorecards, shippedSprintIds) {
379
422
  // --- Dependency Graph ---
380
423
  /** Detect cycles in sprint dependency graph. Returns cycle path or null. */
381
424
  function detectCycle(sprints) {
425
+ const roadmap = { name: '', phases: [], sprints };
426
+ const sprintMap = new Map(sprints.map(sprint => [roadmapSprintKey(roadmap, sprint), sprint]));
382
427
  const visited = new Set();
383
428
  const inStack = new Set();
384
429
  const parent = new Map();
385
430
  function dfs(id) {
386
431
  visited.add(id);
387
432
  inStack.add(id);
388
- const sprint = sprints.find(s => s.id === id);
433
+ const sprint = sprintMap.get(id);
389
434
  for (const dep of sprint?.depends_on ?? []) {
390
- if (!visited.has(dep)) {
391
- parent.set(dep, id);
392
- const result = dfs(dep);
435
+ const depKey = roadmapSprintKeyFromId(roadmap, dep);
436
+ if (depKey === null)
437
+ continue;
438
+ if (!visited.has(depKey)) {
439
+ parent.set(depKey, id);
440
+ const result = dfs(depKey);
393
441
  if (result)
394
442
  return result;
395
443
  }
396
- else if (inStack.has(dep)) {
444
+ else if (inStack.has(depKey)) {
397
445
  // Build cycle path
398
- const cycle = [dep];
446
+ const cycle = [depKey];
399
447
  let current = id;
400
- while (current !== dep) {
448
+ while (current !== depKey) {
401
449
  cycle.push(current);
402
450
  current = parent.get(current);
403
451
  }
404
- cycle.push(dep);
452
+ cycle.push(depKey);
405
453
  return cycle.reverse();
406
454
  }
407
455
  }
@@ -409,8 +457,9 @@ function detectCycle(sprints) {
409
457
  return null;
410
458
  }
411
459
  for (const sprint of sprints) {
412
- if (!visited.has(sprint.id)) {
413
- const result = dfs(sprint.id);
460
+ const key = roadmapSprintKey(roadmap, sprint);
461
+ if (!visited.has(key)) {
462
+ const result = dfs(key);
414
463
  if (result)
415
464
  return result;
416
465
  }
@@ -419,7 +468,7 @@ function detectCycle(sprints) {
419
468
  }
420
469
  /** Compute the critical path (longest dependency chain) through the roadmap */
421
470
  export function computeCriticalPath(roadmap) {
422
- const sprintMap = new Map(roadmap.sprints.map(s => [s.id, s]));
471
+ const sprintMap = new Map(roadmap.sprints.map(s => [roadmapSprintKey(roadmap, s), s]));
423
472
  // Compute longest path ending at each sprint via topological order
424
473
  const longestTo = new Map();
425
474
  // Topological sort
@@ -433,7 +482,8 @@ export function computeCriticalPath(roadmap) {
433
482
  else {
434
483
  let best = { length: 0, path: [] };
435
484
  for (const dep of deps) {
436
- const depPath = longestTo.get(dep);
485
+ const depKey = roadmapSprintKeyFromId(roadmap, dep);
486
+ const depPath = depKey ? longestTo.get(depKey) : undefined;
437
487
  if (depPath && depPath.length > best.length) {
438
488
  best = depPath;
439
489
  }
@@ -460,16 +510,22 @@ export function computeCriticalPath(roadmap) {
460
510
  }
461
511
  /** Topological sort of sprints by dependency order */
462
512
  function topologicalSort(sprints) {
513
+ const roadmap = { name: '', phases: [], sprints };
463
514
  const inDegree = new Map();
464
515
  const adjacency = new Map();
465
516
  for (const sprint of sprints) {
466
- inDegree.set(sprint.id, 0);
467
- adjacency.set(sprint.id, []);
517
+ const key = roadmapSprintKey(roadmap, sprint);
518
+ inDegree.set(key, 0);
519
+ adjacency.set(key, []);
468
520
  }
469
521
  for (const sprint of sprints) {
522
+ const key = roadmapSprintKey(roadmap, sprint);
470
523
  for (const dep of sprint.depends_on ?? []) {
471
- adjacency.get(dep)?.push(sprint.id);
472
- inDegree.set(sprint.id, (inDegree.get(sprint.id) ?? 0) + 1);
524
+ const depKey = roadmapSprintKeyFromId(roadmap, dep);
525
+ if (depKey === null)
526
+ continue;
527
+ adjacency.get(depKey)?.push(key);
528
+ inDegree.set(key, (inDegree.get(key) ?? 0) + 1);
473
529
  }
474
530
  }
475
531
  const queue = [];
@@ -504,7 +560,7 @@ export function findParallelOpportunities(roadmap) {
504
560
  for (const [depth, ids] of byDepth) {
505
561
  if (ids.length > 1) {
506
562
  groups.push({
507
- sprints: ids.sort((a, b) => a - b),
563
+ sprints: ids.sort(compareSprintIdKeys),
508
564
  reason: `Same dependency depth (${depth}) — no mutual dependencies`,
509
565
  });
510
566
  }
@@ -513,19 +569,23 @@ export function findParallelOpportunities(roadmap) {
513
569
  }
514
570
  /** Compute the depth (longest path from a root) of each sprint */
515
571
  function computeDepthMap(sprints) {
572
+ const roadmap = { name: '', phases: [], sprints };
516
573
  const depthMap = new Map();
517
- const sprintMap = new Map(sprints.map(s => [s.id, s]));
574
+ const sprintMap = new Map(sprints.map(s => [roadmapSprintKey(roadmap, s), s]));
518
575
  function getDepth(id) {
519
576
  if (depthMap.has(id))
520
577
  return depthMap.get(id);
521
578
  const sprint = sprintMap.get(id);
522
579
  const deps = sprint?.depends_on ?? [];
523
- const depth = deps.length === 0 ? 0 : Math.max(...deps.map(getDepth)) + 1;
580
+ const depKeys = deps
581
+ .map(dep => roadmapSprintKeyFromId(roadmap, dep))
582
+ .filter((dep) => dep !== null);
583
+ const depth = depKeys.length === 0 ? 0 : Math.max(...depKeys.map(getDepth)) + 1;
524
584
  depthMap.set(id, depth);
525
585
  return depth;
526
586
  }
527
587
  for (const sprint of sprints) {
528
- getDepth(sprint.id);
588
+ getDepth(roadmapSprintKey(roadmap, sprint));
529
589
  }
530
590
  return depthMap;
531
591
  }
@@ -593,29 +653,30 @@ export function formatRoadmapSummary(roadmap) {
593
653
  lines.push('');
594
654
  // Phases
595
655
  for (const phase of roadmap.phases) {
596
- const phaseSprintIds = phase.sprints;
597
- const phaseSprints = roadmap.sprints.filter(s => phaseSprintIds.includes(s.id));
656
+ const phaseSprintIds = phase.sprint_keys ?? phase.sprints;
657
+ const phaseSprintKeys = new Set(phaseSprintIds.map(id => roadmapSprintKeyFromId(roadmap, id)));
658
+ const phaseSprints = roadmap.sprints.filter(sprint => phaseSprintKeys.has(roadmapSprintKey(roadmap, sprint)));
598
659
  lines.push(`## ${phase.name}`);
599
660
  lines.push('');
600
661
  for (const sprint of phaseSprints) {
601
662
  const deps = sprint.depends_on?.length
602
- ? ` (depends on: ${sprint.depends_on.map(formatSprintLabel).join(', ')})`
663
+ ? ` (depends on: ${sprint.depends_on.map(id => formatRoadmapSprintLabel(roadmap, id)).join(', ')})`
603
664
  : ' (no dependencies)';
604
- lines.push(`- **${formatSprintLabel(sprint.id)}** — ${sprint.theme} | Par ${sprint.par} | ${sprint.tickets.length} tickets${deps}`);
665
+ lines.push(`- **${formatRoadmapSprintLabel(roadmap, roadmapSprintKey(roadmap, sprint))}** — ${sprint.theme} | Par ${sprint.par} | ${sprint.tickets.length} tickets${deps}`);
605
666
  }
606
667
  lines.push('');
607
668
  }
608
669
  // Critical path
609
670
  lines.push('## Critical Path');
610
671
  lines.push('');
611
- lines.push(`${criticalPath.path.map(formatSprintLabel).join(' → ')} (${criticalPath.length} sprints, par ${criticalPath.totalPar})`);
672
+ lines.push(`${criticalPath.path.map(id => formatRoadmapSprintLabel(roadmap, id)).join(' → ')} (${criticalPath.length} sprints, par ${criticalPath.totalPar})`);
612
673
  lines.push('');
613
674
  // Parallel opportunities
614
675
  if (parallelGroups.length > 0) {
615
676
  lines.push('## Parallel Opportunities');
616
677
  lines.push('');
617
678
  for (const group of parallelGroups) {
618
- lines.push(`- ${group.sprints.map(formatSprintLabel).join(', ')}: ${group.reason}`);
679
+ lines.push(`- ${group.sprints.map(id => formatRoadmapSprintLabel(roadmap, id)).join(', ')}: ${group.reason}`);
619
680
  }
620
681
  lines.push('');
621
682
  }
@@ -630,21 +691,23 @@ export function formatRoadmapSummary(roadmap) {
630
691
  }
631
692
  /** Format strategic context for briefings — concise 3-5 line summary */
632
693
  export function formatStrategicContext(roadmap, currentSprint) {
633
- const currentOrder = roadmapSprintOrderValue(roadmap, currentSprint);
634
- const sprint = roadmap.sprints.find(s => roadmapSprintOrderValue(roadmap, s.id) === currentOrder);
694
+ const sprint = findRoadmapSprint(roadmap, currentSprint);
635
695
  if (!sprint)
636
696
  return null;
637
- const resolvedSprint = sprint.id;
697
+ const resolvedSprint = roadmapSprintKey(roadmap, sprint);
638
698
  const criticalPath = computeCriticalPath(roadmap);
639
- const onCriticalPath = criticalPath.path.some(id => roadmapSprintOrderValue(roadmap, id) === currentOrder);
699
+ const onCriticalPath = criticalPath.path.includes(resolvedSprint);
640
700
  const totalSprints = roadmap.sprints.length;
641
- const sprintIndex = roadmap.sprints.findIndex(s => s.id === resolvedSprint) + 1;
701
+ const sprintIndex = roadmap.sprints.findIndex(s => roadmapSprintKey(roadmap, s) === resolvedSprint) + 1;
642
702
  // Find which phase this sprint belongs to
643
- const phase = roadmap.phases.find(p => p.sprints.some(id => roadmapSprintOrderValue(roadmap, id) === currentOrder));
703
+ const phase = roadmap.phases.find(p => {
704
+ const keys = p.sprint_keys ?? p.sprints;
705
+ return keys.some(id => roadmapSprintKeyFromId(roadmap, id) === resolvedSprint);
706
+ });
644
707
  // Find what depends on this sprint
645
708
  const dependents = roadmap.sprints
646
- .filter(s => s.depends_on?.some(id => roadmapSprintOrderValue(roadmap, id) === currentOrder))
647
- .map(s => formatRoadmapSprintLabel(roadmap, s.id));
709
+ .filter(s => s.depends_on?.some(id => roadmapSprintKeyFromId(roadmap, id) === resolvedSprint))
710
+ .map(s => formatRoadmapSprintLabel(roadmap, roadmapSprintKey(roadmap, s)));
648
711
  const lines = [];
649
712
  lines.push(`Sprint ${sprintIndex} of ${totalSprints} — ${formatRoadmapSprintLabel(roadmap, resolvedSprint)}: ${sprint.theme}`);
650
713
  if (phase) {
@@ -661,14 +724,13 @@ export function formatStrategicContext(roadmap, currentSprint) {
661
724
  if (next) {
662
725
  const blockers = (next.depends_on ?? [])
663
726
  .filter(d => {
664
- const depOrder = roadmapSprintOrderValue(roadmap, d);
665
- const dep = roadmap.sprints.find(s => roadmapSprintOrderValue(roadmap, s.id) === depOrder);
727
+ const dep = findRoadmapSprint(roadmap, d);
666
728
  return !dep || dep.status !== 'complete';
667
729
  });
668
730
  const status = blockers.length === 0
669
731
  ? 'ready'
670
732
  : `blocked by ${blockers.map(id => formatRoadmapSprintLabel(roadmap, id)).join(', ')}`;
671
- lines.push(`Next: ${formatRoadmapSprintLabel(roadmap, next.id)}: ${next.theme} (${status})`);
733
+ lines.push(`Next: ${formatRoadmapSprintLabel(roadmap, roadmapSprintKey(roadmap, next))}: ${next.theme} (${status})`);
672
734
  }
673
735
  return lines.join('\n');
674
736
  }
@@ -678,19 +740,25 @@ export function formatStrategicContext(roadmap, currentSprint) {
678
740
  * Returns null if no candidate found.
679
741
  */
680
742
  export function findNextPlannedSprint(roadmap, currentSprint) {
681
- const currentOrder = roadmapSprintOrderValue(roadmap, currentSprint);
743
+ const currentKey = roadmapSprintKeyFromId(roadmap, currentSprint);
744
+ if (currentKey === null)
745
+ return null;
682
746
  const candidates = roadmap.sprints
683
747
  .filter(s => {
684
- return isRoadmapSprintPending(s) && roadmapSprintOrderValue(roadmap, s.id) > currentOrder;
748
+ return isRoadmapSprintPending(s)
749
+ && compareSprintIdKeys(roadmapSprintKey(roadmap, s), currentKey) > 0;
685
750
  })
686
- .sort((a, b) => compareRoadmapSprintIds(roadmap, a.id, b.id));
751
+ .sort((a, b) => compareSprintIdKeys(roadmapSprintKey(roadmap, a), roadmapSprintKey(roadmap, b)));
687
752
  if (candidates.length === 0)
688
753
  return null;
689
754
  const completedIds = new Set(roadmap.sprints
690
755
  .filter(s => s.status === 'complete')
691
- .map(s => roadmapSprintOrderValue(roadmap, s.id)));
756
+ .map(s => roadmapSprintKey(roadmap, s)));
692
757
  // Prefer the lowest-id candidate whose dependencies are all complete
693
- const ready = candidates.find(s => (s.depends_on ?? []).every(d => completedIds.has(roadmapSprintOrderValue(roadmap, d))));
758
+ const ready = candidates.find(s => (s.depends_on ?? []).every(d => {
759
+ const key = roadmapSprintKeyFromId(roadmap, d);
760
+ return key !== null && completedIds.has(key);
761
+ }));
694
762
  return ready ?? candidates[0];
695
763
  }
696
764
  //# sourceMappingURL=roadmap.js.map