panopticon-cli 0.6.5 → 0.6.6

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 (311) hide show
  1. package/README.md +2 -2
  2. package/dist/{agents-DfYify9s.js → agents-CfFDs52G.js} +14 -14
  3. package/dist/{agents-DfYify9s.js.map → agents-CfFDs52G.js.map} +1 -1
  4. package/dist/{agents-BKsVoIc9.js → agents-D_2oRFVf.js} +1 -1
  5. package/dist/{archive-planning-BJrZ3tmN.js → archive-planning-D97ziGec.js} +3 -3
  6. package/dist/{archive-planning-BJrZ3tmN.js.map → archive-planning-D97ziGec.js.map} +1 -1
  7. package/dist/{archive-planning-C3m3hfa5.js → archive-planning-DK90wn9Q.js} +1 -1
  8. package/dist/{browser-Cvdznzc0.js → browser-CX7jXfXX.js} +1 -1
  9. package/dist/{browser-Cvdznzc0.js.map → browser-CX7jXfXX.js.map} +1 -1
  10. package/dist/{clean-planning-DvhZAUv4.js → clean-planning-D_lz4aQq.js} +2 -2
  11. package/dist/{clean-planning-DvhZAUv4.js.map → clean-planning-D_lz4aQq.js.map} +1 -1
  12. package/dist/clean-planning-x1S-JdmO.js +2 -0
  13. package/dist/cli/index.js +291 -760
  14. package/dist/cli/index.js.map +1 -1
  15. package/dist/{close-issue-Dr7yZmrr.js → close-issue-CaFE0stN.js} +11 -7
  16. package/dist/close-issue-CaFE0stN.js.map +1 -0
  17. package/dist/close-issue-CjcfZI9s.js +2 -0
  18. package/dist/compact-beads-B0_qE1w3.js +2 -0
  19. package/dist/{compact-beads-BCOtIIRl.js → compact-beads-CjFkteSU.js} +2 -2
  20. package/dist/{compact-beads-BCOtIIRl.js.map → compact-beads-CjFkteSU.js.map} +1 -1
  21. package/dist/{config-CRzMQRgA.js → config-BQNKsi9G.js} +2 -2
  22. package/dist/{config-CRzMQRgA.js.map → config-BQNKsi9G.js.map} +1 -1
  23. package/dist/{config-BYgUzQ21.js → config-agyKgF5C.js} +1 -1
  24. package/dist/{config-yaml-BgOACZAB.js → config-yaml-DGbLSMCa.js} +1 -1
  25. package/dist/{config-yaml-BgOACZAB.js.map → config-yaml-DGbLSMCa.js.map} +1 -1
  26. package/dist/{config-yaml-fdyvyL0S.js → config-yaml-Dqt4FWQH.js} +1 -1
  27. package/dist/dashboard/{acceptance-criteria-e5iiHlRx.js → acceptance-criteria-Dk9hhiYj.js} +1 -1
  28. package/dist/dashboard/{acceptance-criteria-e5iiHlRx.js.map → acceptance-criteria-Dk9hhiYj.js.map} +1 -1
  29. package/dist/dashboard/{agent-enrichment-C67LJBgD.js → agent-enrichment-DdO7ZqjI.js} +11 -7
  30. package/dist/dashboard/agent-enrichment-DdO7ZqjI.js.map +1 -0
  31. package/dist/dashboard/{agent-enrichment-Cq0P1cNZ.js → agent-enrichment-dLeGE1fX.js} +1 -1
  32. package/dist/dashboard/{agents-YyO6t5Xa.js → agents-DCpQQ_W5.js} +14 -14
  33. package/dist/dashboard/{agents-YyO6t5Xa.js.map → agents-DCpQQ_W5.js.map} +1 -1
  34. package/dist/dashboard/{agents-BVBVCyat.js → agents-Dgh2TjSp.js} +1 -1
  35. package/dist/dashboard/{archive-planning-h-hAjk0P.js → archive-planning-BmW9UDTr.js} +3 -3
  36. package/dist/dashboard/{archive-planning-h-hAjk0P.js.map → archive-planning-BmW9UDTr.js.map} +1 -1
  37. package/dist/dashboard/{archive-planning-CScs1MOC.js → archive-planning-C3Ebf9yC.js} +1 -1
  38. package/dist/dashboard/{beads-qNB0yAHV.js → beads-Bv-AdX7G.js} +3 -3
  39. package/dist/dashboard/{beads-qNB0yAHV.js.map → beads-Bv-AdX7G.js.map} +1 -1
  40. package/dist/dashboard/{beads-D_FRedEJ.js → beads-By6-X07V.js} +1 -1
  41. package/dist/dashboard/clean-planning-D60L8rPY.js +2 -0
  42. package/dist/dashboard/{clean-planning-qafw99vY.js → clean-planning-VEJu5suh.js} +2 -2
  43. package/dist/dashboard/{clean-planning-qafw99vY.js.map → clean-planning-VEJu5suh.js.map} +1 -1
  44. package/dist/dashboard/close-issue-C2KeSKKJ.js +2 -0
  45. package/dist/dashboard/{close-issue-DfIggeZD.js → close-issue-DtKdsSTm.js} +11 -7
  46. package/dist/dashboard/close-issue-DtKdsSTm.js.map +1 -0
  47. package/dist/dashboard/compact-beads-C7BN5N11.js +2 -0
  48. package/dist/dashboard/{compact-beads-Dt0qTqsC.js → compact-beads-D8Vt3qyv.js} +2 -2
  49. package/dist/dashboard/{compact-beads-Dt0qTqsC.js.map → compact-beads-D8Vt3qyv.js.map} +1 -1
  50. package/dist/dashboard/{config-CUREjHP7.js → config-CDkGjnwy.js} +2 -2
  51. package/dist/dashboard/{config-CUREjHP7.js.map → config-CDkGjnwy.js.map} +1 -1
  52. package/dist/dashboard/{config-BeI3uy-8.js → config-CTXkBATQ.js} +1 -1
  53. package/dist/dashboard/{database-CozA13Wy.js → database-DhqASALP.js} +1 -1
  54. package/dist/dashboard/{database-C0y0hXBx.js → database-cxmQryoh.js} +2 -2
  55. package/dist/dashboard/{database-C0y0hXBx.js.map → database-cxmQryoh.js.map} +1 -1
  56. package/dist/dashboard/{dist-src-oG2iHzgI.js → dist-src-DTm11oQr.js} +1 -1
  57. package/dist/dashboard/{dist-src-oG2iHzgI.js.map → dist-src-DTm11oQr.js.map} +1 -1
  58. package/dist/dashboard/{event-store-D7kLBd07.js → event-store-VWWUmOfn.js} +1 -1
  59. package/dist/dashboard/{event-store-O9q0Gweh.js → event-store-vSmAA3Zp.js} +9 -4
  60. package/dist/dashboard/event-store-vSmAA3Zp.js.map +1 -0
  61. package/dist/dashboard/{factory-BnLdiQW-.js → factory-C8nhLGHB.js} +3 -3
  62. package/dist/dashboard/{factory-BnLdiQW-.js.map → factory-C8nhLGHB.js.map} +1 -1
  63. package/dist/dashboard/{feedback-writer-DyovUANg.js → feedback-writer-CudSe1WK.js} +2 -2
  64. package/dist/dashboard/{feedback-writer-DyovUANg.js.map → feedback-writer-CudSe1WK.js.map} +1 -1
  65. package/dist/dashboard/{feedback-writer-gSUv_W0h.js → feedback-writer-Wgv1cd1r.js} +1 -1
  66. package/dist/dashboard/{git-utils-BJRioREj.js → git-utils-C1m4SwAe.js} +1 -1
  67. package/dist/dashboard/{git-utils-BJRioREj.js.map → git-utils-C1m4SwAe.js.map} +1 -1
  68. package/dist/dashboard/{git-utils-BtCRddq3.js → git-utils-DQI8EYoj.js} +1 -1
  69. package/dist/dashboard/{github-app-XO-LBUGk.js → github-app-DClWjjHr.js} +1 -1
  70. package/dist/dashboard/{github-app-XO-LBUGk.js.map → github-app-DClWjjHr.js.map} +1 -1
  71. package/dist/dashboard/{health-events-db-584nYgJB.js → health-events-db-BMXQfInV.js} +1 -1
  72. package/dist/dashboard/{health-events-db-B3ChzN65.js → health-events-db-Do4NrOhC.js} +2 -2
  73. package/dist/dashboard/{health-events-db-B3ChzN65.js.map → health-events-db-Do4NrOhC.js.map} +1 -1
  74. package/dist/dashboard/{hooks-CKhs3N68.js → hooks-CB4T47NC.js} +1 -1
  75. package/dist/dashboard/{hooks-CErbP8Oq.js → hooks-CjqXOlNb.js} +2 -2
  76. package/dist/dashboard/{hooks-CErbP8Oq.js.map → hooks-CjqXOlNb.js.map} +1 -1
  77. package/dist/dashboard/hume-CA2pftu_.js +3 -0
  78. package/dist/dashboard/{hume-CX_U3Qha.js → hume-JsAlMOJC.js} +2 -2
  79. package/dist/dashboard/{hume-CX_U3Qha.js.map → hume-JsAlMOJC.js.map} +1 -1
  80. package/dist/dashboard/{inspect-agent-B57kGDUV.js → inspect-agent-7eour7EA.js} +3 -3
  81. package/dist/dashboard/{inspect-agent-B57kGDUV.js.map → inspect-agent-7eour7EA.js.map} +1 -1
  82. package/dist/dashboard/{io-yGovuG4U.js → io-CWlFW78i.js} +1 -1
  83. package/dist/dashboard/{io-AJg-mzFi.js → io-DKS6359z.js} +1 -1
  84. package/dist/dashboard/{io-AJg-mzFi.js.map → io-DKS6359z.js.map} +1 -1
  85. package/dist/dashboard/issue-id-vwYJdsf8.js +62 -0
  86. package/dist/dashboard/issue-id-vwYJdsf8.js.map +1 -0
  87. package/dist/dashboard/{issue-service-singleton-DQK42EqH.js → issue-service-singleton-Co__-6kL.js} +1 -1
  88. package/dist/dashboard/{issue-service-singleton-sb2HkB9f.js → issue-service-singleton-Wv4xBm3y.js} +7 -7
  89. package/dist/dashboard/{issue-service-singleton-sb2HkB9f.js.map → issue-service-singleton-Wv4xBm3y.js.map} +1 -1
  90. package/dist/dashboard/{label-cleanup-CZEsbtq9.js → label-cleanup-nVKTmIIW.js} +7 -4
  91. package/dist/dashboard/label-cleanup-nVKTmIIW.js.map +1 -0
  92. package/dist/dashboard/lifecycle-BcUmtkR4.js +7 -0
  93. package/dist/dashboard/{merge-agent-GLtMEsTu.js → merge-agent-CGN3TT0a.js} +1 -1
  94. package/dist/dashboard/{merge-agent-twroFuAh.js → merge-agent-yudQOPZc.js} +148 -46
  95. package/dist/dashboard/merge-agent-yudQOPZc.js.map +1 -0
  96. package/dist/dashboard/{paths-COdEvoXR.js → paths-BDyJ7BiV.js} +19 -2
  97. package/dist/dashboard/{paths-COdEvoXR.js.map → paths-BDyJ7BiV.js.map} +1 -1
  98. package/dist/dashboard/{pipeline-notifier-DM5AHG5Q.js → pipeline-notifier-CCSN-jar.js} +1 -1
  99. package/dist/dashboard/{pipeline-notifier-DM5AHG5Q.js.map → pipeline-notifier-CCSN-jar.js.map} +1 -1
  100. package/dist/dashboard/{plan-utils-BkCIhn3B.js → plan-utils-Bkcsqr_s.js} +3 -3
  101. package/dist/dashboard/{plan-utils-BkCIhn3B.js.map → plan-utils-Bkcsqr_s.js.map} +1 -1
  102. package/dist/dashboard/{prd-draft-D09Afalc.js → prd-draft-BD8oMkZ1.js} +2 -2
  103. package/dist/dashboard/{prd-draft-D09Afalc.js.map → prd-draft-BD8oMkZ1.js.map} +1 -1
  104. package/dist/dashboard/{projection-cache-DQ9zegkK.js → projection-cache-C0EL8s8h.js} +1 -1
  105. package/dist/dashboard/{projection-cache-DQ9zegkK.js.map → projection-cache-C0EL8s8h.js.map} +1 -1
  106. package/dist/dashboard/{projects-DyT3vSy-.js → projects-C5ozxjwP.js} +1 -1
  107. package/dist/dashboard/{projects-Cq3TWdPS.js → projects-CFVl4oHn.js} +25 -13
  108. package/dist/dashboard/projects-CFVl4oHn.js.map +1 -0
  109. package/dist/dashboard/{providers-Ck2sQd_F.js → providers-B5Y4H2Mg.js} +4 -4
  110. package/dist/dashboard/providers-B5Y4H2Mg.js.map +1 -0
  111. package/dist/dashboard/{providers-DVQnDekG.js → providers-csVZVPkE.js} +1 -1
  112. package/dist/dashboard/public/assets/{dist-CCJbQrSB.js → dist-BaQPC-c6.js} +1 -1
  113. package/dist/dashboard/public/assets/index-ByLmYGhW.js +212 -0
  114. package/dist/dashboard/public/assets/index-OEEbThNN.css +1 -0
  115. package/dist/dashboard/public/index.html +2 -2
  116. package/dist/dashboard/rally-6McpKKRa.js +3 -0
  117. package/dist/dashboard/{rally-Cwuae-4C.js → rally-YjFRxIiC.js} +2 -2
  118. package/dist/dashboard/{rally-Cwuae-4C.js.map → rally-YjFRxIiC.js.map} +1 -1
  119. package/dist/dashboard/{rally-api-DSUxm7EO.js → rally-api-C0WqCSkT.js} +1 -1
  120. package/dist/dashboard/{rally-api-DSUxm7EO.js.map → rally-api-C0WqCSkT.js.map} +1 -1
  121. package/dist/dashboard/{rally-api-CEH5KZi4.js → rally-api-DNttdCW4.js} +1 -1
  122. package/dist/dashboard/{remote-BHTTMpJJ.js → remote-Cigqjj3f.js} +2 -2
  123. package/dist/dashboard/{remote-BXo_iIku.js → remote-ObpNZ7hF.js} +2 -2
  124. package/dist/dashboard/{remote-BXo_iIku.js.map → remote-ObpNZ7hF.js.map} +1 -1
  125. package/dist/dashboard/{remote-agents-CTKVhFFY.js → remote-agents-Bf3GuM7t.js} +1 -1
  126. package/dist/dashboard/{remote-agents-C0_0LLNd.js → remote-agents-DFyjT1Le.js} +1 -1
  127. package/dist/dashboard/{remote-agents-C0_0LLNd.js.map → remote-agents-DFyjT1Le.js.map} +1 -1
  128. package/dist/dashboard/{review-status-CK3eBGyb.js → review-status-BtXqWBhS.js} +1 -1
  129. package/dist/dashboard/{review-status-CV55Tl-n.js → review-status-Bymwzh2i.js} +44 -4
  130. package/dist/dashboard/{review-status-CV55Tl-n.js.map → review-status-Bymwzh2i.js.map} +1 -1
  131. package/dist/dashboard/server.js +559 -253
  132. package/dist/dashboard/server.js.map +1 -1
  133. package/dist/dashboard/{settings-CuHV-wcv.js → settings-BHlDG7TK.js} +2 -2
  134. package/dist/dashboard/settings-BHlDG7TK.js.map +1 -0
  135. package/dist/dashboard/settings-XWvDcj-D.js +2 -0
  136. package/dist/dashboard/{shadow-engineering-BUeZunaE.js → shadow-engineering-lIn1W_95.js} +1 -1
  137. package/dist/dashboard/{shadow-engineering-BUeZunaE.js.map → shadow-engineering-lIn1W_95.js.map} +1 -1
  138. package/dist/dashboard/{shadow-state-DHQ-kASN.js → shadow-state-BIexcxkv.js} +1 -1
  139. package/dist/dashboard/{shadow-state-DHQ-kASN.js.map → shadow-state-BIexcxkv.js.map} +1 -1
  140. package/dist/dashboard/{spawn-planning-session-8FFAqLdK.js → spawn-planning-session-33Jf-d5T.js} +6 -6
  141. package/dist/dashboard/{spawn-planning-session-8FFAqLdK.js.map → spawn-planning-session-33Jf-d5T.js.map} +1 -1
  142. package/dist/dashboard/{spawn-planning-session-U0Lqpjen.js → spawn-planning-session-D5hrVdWM.js} +1 -1
  143. package/dist/dashboard/{specialist-context-ColzlmGE.js → specialist-context-DGukHSn8.js} +6 -6
  144. package/dist/dashboard/{specialist-context-ColzlmGE.js.map → specialist-context-DGukHSn8.js.map} +1 -1
  145. package/dist/dashboard/{specialist-logs-BhmDpFIq.js → specialist-logs-CIw4qfTy.js} +1 -1
  146. package/dist/dashboard/{specialists-C6s3U6tX.js → specialists-B_zrayaP.js} +37 -36
  147. package/dist/dashboard/specialists-B_zrayaP.js.map +1 -0
  148. package/dist/dashboard/{specialists-Cny632-T.js → specialists-Cp-PgspS.js} +1 -1
  149. package/dist/dashboard/{test-agent-queue-tqI4VDsu.js → test-agent-queue-ypF_ecHo.js} +4 -4
  150. package/dist/dashboard/{test-agent-queue-tqI4VDsu.js.map → test-agent-queue-ypF_ecHo.js.map} +1 -1
  151. package/dist/dashboard/{tldr-daemon-BNFyS7W_.js → tldr-daemon-B_oLRD8z.js} +2 -2
  152. package/dist/dashboard/{tldr-daemon-BNFyS7W_.js.map → tldr-daemon-B_oLRD8z.js.map} +1 -1
  153. package/dist/dashboard/{tldr-daemon-A6JqC59u.js → tldr-daemon-Cfs0bXTi.js} +1 -1
  154. package/dist/dashboard/{tmux-DYGAVJfb.js → tmux-BzxdKItf.js} +1 -1
  155. package/dist/dashboard/{tmux-IlN1Slv-.js → tmux-LwG0tHhU.js} +2 -2
  156. package/dist/dashboard/{tmux-IlN1Slv-.js.map → tmux-LwG0tHhU.js.map} +1 -1
  157. package/dist/dashboard/{tracker-config-BzNLnmcE.js → tracker-config-BP59uH4V.js} +1 -1
  158. package/dist/dashboard/{tracker-config-CNM_5rEf.js → tracker-config-e7ph1QqT.js} +2 -2
  159. package/dist/dashboard/{tracker-config-CNM_5rEf.js.map → tracker-config-e7ph1QqT.js.map} +1 -1
  160. package/dist/dashboard/{tunnel-D2BkwU7k.js → tunnel-0RzzuXPf.js} +1 -1
  161. package/dist/dashboard/{tunnel-Dub2hiAA.js → tunnel-DldbBPWL.js} +2 -2
  162. package/dist/dashboard/{tunnel-Dub2hiAA.js.map → tunnel-DldbBPWL.js.map} +1 -1
  163. package/dist/dashboard/{types-CWA-o4UN.js → types-RKZjGE5N.js} +1 -1
  164. package/dist/dashboard/{types-CWA-o4UN.js.map → types-RKZjGE5N.js.map} +1 -1
  165. package/dist/dashboard/{vtt-parser-BAXygRf0.js → vtt-parser-99vFekRQ.js} +1 -1
  166. package/dist/dashboard/{vtt-parser-BAXygRf0.js.map → vtt-parser-99vFekRQ.js.map} +1 -1
  167. package/dist/dashboard/{work-agent-prompt-JYq_OugP.js → work-agent-prompt-fCg67nyo.js} +65 -10
  168. package/dist/dashboard/{work-agent-prompt-JYq_OugP.js.map → work-agent-prompt-fCg67nyo.js.map} +1 -1
  169. package/dist/dashboard/{work-type-router-Cxp8_ur2.js → work-type-router-CWVW2Wk_.js} +1 -1
  170. package/dist/dashboard/{work-type-router-Cxp8_ur2.js.map → work-type-router-CWVW2Wk_.js.map} +1 -1
  171. package/dist/dashboard/{work-type-router-Com2amST.js → work-type-router-Di5gCQwh.js} +1 -1
  172. package/dist/dashboard/{workflows-N1UTipYl.js → workflows-BSMipN07.js} +35 -17
  173. package/dist/dashboard/workflows-BSMipN07.js.map +1 -0
  174. package/dist/dashboard/workflows-DaYWQIS2.js +2 -0
  175. package/dist/dashboard/{workspace-config-cmp5_ipD.js → workspace-config-DVDR-Ukh.js} +1 -1
  176. package/dist/dashboard/workspace-config-DVDR-Ukh.js.map +1 -0
  177. package/dist/dashboard/{workspace-manager-CjpWPgzL.js → workspace-manager-BYfzs_t2.js} +1 -1
  178. package/dist/dashboard/{workspace-manager-D_y9ZmW_.js → workspace-manager-C7OfT62A.js} +44 -24
  179. package/dist/dashboard/workspace-manager-C7OfT62A.js.map +1 -0
  180. package/dist/{dns-BKzHm-2q.js → dns-D_aKQJjb.js} +1 -1
  181. package/dist/{dns-DZwOWvVO.js → dns-Yxq4NNS7.js} +1 -1
  182. package/dist/{dns-DZwOWvVO.js.map → dns-Yxq4NNS7.js.map} +1 -1
  183. package/dist/{factory-DFu3IT4r.js → factory-BRBGw6OB.js} +1 -1
  184. package/dist/{factory-DfzczxN1.js → factory-DzsOiZVc.js} +3 -3
  185. package/dist/{factory-DfzczxN1.js.map → factory-DzsOiZVc.js.map} +1 -1
  186. package/dist/{feedback-writer-CwdnOkPO.js → feedback-writer-ygXN5F9N.js} +2 -2
  187. package/dist/{feedback-writer-CwdnOkPO.js.map → feedback-writer-ygXN5F9N.js.map} +1 -1
  188. package/dist/{github-app-CHKwxOeQ.js → github-app-DykduJ0X.js} +1 -1
  189. package/dist/{github-app-CHKwxOeQ.js.map → github-app-DykduJ0X.js.map} +1 -1
  190. package/dist/hume-9nv1VmMV.js +3 -0
  191. package/dist/{hume-DnV-tDsh.js → hume-DoCbph2h.js} +2 -2
  192. package/dist/{hume-DnV-tDsh.js.map → hume-DoCbph2h.js.map} +1 -1
  193. package/dist/index.d.ts +17 -2
  194. package/dist/index.d.ts.map +1 -1
  195. package/dist/index.js +8 -7
  196. package/dist/issue-id-CAcekoIw.js +62 -0
  197. package/dist/issue-id-CAcekoIw.js.map +1 -0
  198. package/dist/{label-cleanup-31ElPqqv.js → label-cleanup-C8R9Rspn.js} +7 -4
  199. package/dist/label-cleanup-C8R9Rspn.js.map +1 -0
  200. package/dist/{manifest-DL0oDbpv.js → manifest-B4ghOD-V.js} +1 -1
  201. package/dist/{manifest-DL0oDbpv.js.map → manifest-B4ghOD-V.js.map} +1 -1
  202. package/dist/{merge-agent-VQH9z9t8.js → merge-agent-DlUiUanN.js} +86 -33
  203. package/dist/merge-agent-DlUiUanN.js.map +1 -0
  204. package/dist/{paths-lMaxrYtT.js → paths-CDJ_HsbN.js} +19 -2
  205. package/dist/{paths-lMaxrYtT.js.map → paths-CDJ_HsbN.js.map} +1 -1
  206. package/dist/{pipeline-notifier-OJ-d3Y60.js → pipeline-notifier-XgDdCdvT.js} +1 -1
  207. package/dist/{pipeline-notifier-OJ-d3Y60.js.map → pipeline-notifier-XgDdCdvT.js.map} +1 -1
  208. package/dist/{projects-CvLepaxC.js → projects-Bk-5QhFQ.js} +25 -13
  209. package/dist/projects-Bk-5QhFQ.js.map +1 -0
  210. package/dist/{projects-DMWmPeIU.js → projects-DhU7rAVN.js} +1 -1
  211. package/dist/{providers-DcCPZ5K4.js → providers-DSU1vfQF.js} +4 -4
  212. package/dist/providers-DSU1vfQF.js.map +1 -0
  213. package/dist/rally-DdPvGa-w.js +3 -0
  214. package/dist/{rally-uUUZXp1h.js → rally-Dy00NElU.js} +1 -1
  215. package/dist/{rally-uUUZXp1h.js.map → rally-Dy00NElU.js.map} +1 -1
  216. package/dist/{remote-CkLBqLJc.js → remote-CYiOJg0q.js} +2 -2
  217. package/dist/{remote-CkLBqLJc.js.map → remote-CYiOJg0q.js.map} +1 -1
  218. package/dist/{remote-agents-C5Bd2fgt.js → remote-agents-CZXrUF4f.js} +1 -1
  219. package/dist/{remote-agents-C5Bd2fgt.js.map → remote-agents-CZXrUF4f.js.map} +1 -1
  220. package/dist/{remote-agents-BTzD-wMQ.js → remote-agents-ycHHVsgf.js} +1 -1
  221. package/dist/{remote-workspace-Dxghqiti.js → remote-workspace-CA33UuVI.js} +4 -4
  222. package/dist/{remote-workspace-Dxghqiti.js.map → remote-workspace-CA33UuVI.js.map} +1 -1
  223. package/dist/{review-status-2TdtHNcs.js → review-status-D6H2WOw8.js} +1 -1
  224. package/dist/{review-status-Bm1bWNEa.js → review-status-DEDvCKMP.js} +44 -4
  225. package/dist/{review-status-Bm1bWNEa.js.map → review-status-DEDvCKMP.js.map} +1 -1
  226. package/dist/{tracker-C_62ukEq.js → settings-BcWPTrua.js} +7 -199
  227. package/dist/settings-BcWPTrua.js.map +1 -0
  228. package/dist/shadow-state-BZzxfEGw.js +2 -0
  229. package/dist/{shadow-state-CFFHf05M.js → shadow-state-CE3dQfll.js} +1 -1
  230. package/dist/{shadow-state-CFFHf05M.js.map → shadow-state-CE3dQfll.js.map} +1 -1
  231. package/dist/{specialist-context-BdNFsfMG.js → specialist-context-BAUWL1Fl.js} +6 -6
  232. package/dist/{specialist-context-BdNFsfMG.js.map → specialist-context-BAUWL1Fl.js.map} +1 -1
  233. package/dist/{specialist-logs-CLztE_bE.js → specialist-logs-DQKKQV9B.js} +1 -1
  234. package/dist/{specialists-aUoUVWsN.js → specialists-Bfb9ATzw.js} +1 -1
  235. package/dist/{specialists-DEKqgkxp.js → specialists-D7Kj5o6s.js} +35 -34
  236. package/dist/specialists-D7Kj5o6s.js.map +1 -0
  237. package/dist/sync-DMfgd389.js +693 -0
  238. package/dist/sync-DMfgd389.js.map +1 -0
  239. package/dist/sync-TL6y-8K6.js +2 -0
  240. package/dist/{tldr-daemon-BCEFPItr.js → tldr-daemon-CFx4LXAl.js} +2 -2
  241. package/dist/{tldr-daemon-BCEFPItr.js.map → tldr-daemon-CFx4LXAl.js.map} +1 -1
  242. package/dist/{tldr-daemon-xBAx4cBE.js → tldr-daemon-D_EooADG.js} +1 -1
  243. package/dist/{tmux-DN6H886Y.js → tmux-CBtui_Cl.js} +1 -1
  244. package/dist/{tmux-CKdNxxJx.js → tmux-D6Ah4I8z.js} +2 -2
  245. package/dist/{tmux-CKdNxxJx.js.map → tmux-D6Ah4I8z.js.map} +1 -1
  246. package/dist/tracker-BhYYvU3p.js +198 -0
  247. package/dist/tracker-BhYYvU3p.js.map +1 -0
  248. package/dist/{tracker-utils-CVU2W1sX.js → tracker-utils-ChQyut8w.js} +34 -12
  249. package/dist/tracker-utils-ChQyut8w.js.map +1 -0
  250. package/dist/{traefik-DHgBoWXX.js → traefik-C80EbDu_.js} +4 -4
  251. package/dist/{traefik-DHgBoWXX.js.map → traefik-C80EbDu_.js.map} +1 -1
  252. package/dist/{traefik-BR-edbZv.js → traefik-CgHl7Bge.js} +1 -1
  253. package/dist/{tunnel-BZO9Q5oe.js → tunnel-DXOJ1wMM.js} +1 -1
  254. package/dist/{tunnel-Bl1qNSyQ.js → tunnel-DzXEPwIc.js} +2 -2
  255. package/dist/{tunnel-Bl1qNSyQ.js.map → tunnel-DzXEPwIc.js.map} +1 -1
  256. package/dist/{types-DewGdaIP.js → types-BhJj1SP1.js} +1 -1
  257. package/dist/{types-DewGdaIP.js.map → types-BhJj1SP1.js.map} +1 -1
  258. package/dist/{work-type-router-CS2BB1vS.js → work-type-router-CHjciPyS.js} +3 -3
  259. package/dist/{work-type-router-CS2BB1vS.js.map → work-type-router-CHjciPyS.js.map} +1 -1
  260. package/dist/{workspace-config-CNXOpKuj.js → workspace-config-fUafvYMp.js} +1 -1
  261. package/dist/workspace-config-fUafvYMp.js.map +1 -0
  262. package/dist/workspace-manager-B9jS4Dsq.js +3 -0
  263. package/dist/{workspace-manager-CncdZkIy.js → workspace-manager-DuLhnzJV.js} +112 -27
  264. package/dist/workspace-manager-DuLhnzJV.js.map +1 -0
  265. package/package.json +2 -1
  266. package/scripts/post-merge-deploy.sh +25 -5
  267. package/scripts/record-cost-event.js +57 -7
  268. package/scripts/record-cost-event.js.map +1 -1
  269. package/skills/pan-help/SKILL.md +1 -1
  270. package/skills/pan-sync/SKILL.md +6 -6
  271. package/skills/workspace-add-repo/skill.md +46 -0
  272. package/templates/claude-md/sections/warnings.md +15 -2
  273. package/dist/clean-planning-sZXvy3Y5.js +0 -2
  274. package/dist/close-issue-Dml437qV.js +0 -2
  275. package/dist/close-issue-Dr7yZmrr.js.map +0 -1
  276. package/dist/compact-beads-iu218JcO.js +0 -2
  277. package/dist/dashboard/agent-enrichment-C67LJBgD.js.map +0 -1
  278. package/dist/dashboard/clean-planning-DCu3cOTu.js +0 -2
  279. package/dist/dashboard/close-issue-DfIggeZD.js.map +0 -1
  280. package/dist/dashboard/close-issue-DwdwYtar.js +0 -2
  281. package/dist/dashboard/compact-beads-DXY2fK2s.js +0 -2
  282. package/dist/dashboard/event-store-O9q0Gweh.js.map +0 -1
  283. package/dist/dashboard/hume-MZndNDVU.js +0 -3
  284. package/dist/dashboard/label-cleanup-CZEsbtq9.js.map +0 -1
  285. package/dist/dashboard/lifecycle-ZTYdrr2O.js +0 -7
  286. package/dist/dashboard/merge-agent-twroFuAh.js.map +0 -1
  287. package/dist/dashboard/projects-Cq3TWdPS.js.map +0 -1
  288. package/dist/dashboard/providers-Ck2sQd_F.js.map +0 -1
  289. package/dist/dashboard/public/assets/index-CpSmB2ts.css +0 -1
  290. package/dist/dashboard/public/assets/index-yarWhi0M.js +0 -214
  291. package/dist/dashboard/rally-CQ1OBJrJ.js +0 -3
  292. package/dist/dashboard/settings-CuHV-wcv.js.map +0 -1
  293. package/dist/dashboard/settings-DMeGBRsk.js +0 -2
  294. package/dist/dashboard/specialists-C6s3U6tX.js.map +0 -1
  295. package/dist/dashboard/workflows-B2ARUpOa.js +0 -2
  296. package/dist/dashboard/workflows-N1UTipYl.js.map +0 -1
  297. package/dist/dashboard/workspace-config-cmp5_ipD.js.map +0 -1
  298. package/dist/dashboard/workspace-manager-D_y9ZmW_.js.map +0 -1
  299. package/dist/hume-BjmwmJ9E.js +0 -3
  300. package/dist/label-cleanup-31ElPqqv.js.map +0 -1
  301. package/dist/merge-agent-VQH9z9t8.js.map +0 -1
  302. package/dist/projects-CvLepaxC.js.map +0 -1
  303. package/dist/providers-DcCPZ5K4.js.map +0 -1
  304. package/dist/rally-DR9x8--6.js +0 -3
  305. package/dist/shadow-state-p3jpGRPJ.js +0 -2
  306. package/dist/specialists-DEKqgkxp.js.map +0 -1
  307. package/dist/tracker-C_62ukEq.js.map +0 -1
  308. package/dist/tracker-utils-CVU2W1sX.js.map +0 -1
  309. package/dist/workspace-config-CNXOpKuj.js.map +0 -1
  310. package/dist/workspace-manager-CncdZkIy.js.map +0 -1
  311. package/dist/workspace-manager-Cx0r2Jnv.js +0 -3
package/dist/index.js CHANGED
@@ -1,14 +1,15 @@
1
- import { A as SKILLS_DIR, B as TRAEFIK_CERTS_DIR, C as PRD_PUBLISHED_DIR, D as PROJECT_PRDS_PLANNED_SUBDIR, E as PROJECT_PRDS_COMPLETED_SUBDIR, F as SOURCE_SKILLS_DIR, G as isDevMode, H as TRAEFIK_DYNAMIC_DIR, I as SOURCE_TEMPLATES_DIR, L as SOURCE_TRAEFIK_TEMPLATES, M as SOURCE_DEV_SKILLS_DIR, N as SOURCE_RULES_DIR, O as PROJECT_PRDS_SUBDIR, P as SOURCE_SCRIPTS_DIR, R as SYNC_TARGET, S as PRD_DRAFTS_DIR, T as PROJECT_PRDS_ACTIVE_SUBDIR, U as getPanopticonHome, V as TRAEFIK_DIR, W as init_paths, _ as HEARTBEATS_DIR, a as CACHE_AGENTS_DIR, b as PANOPTICON_HOME, c as CACHE_SKILLS_DIR, d as CLAUDE_MD_TEMPLATES, f as COMMANDS_DIR, g as DOCS_DIR, h as COSTS_DIR, i as BIN_DIR, j as SOURCE_AGENTS_DIR, k as SETTINGS_FILE, l as CERTS_DIR, m as CONFIG_FILE, n as ARCHIVES_DIR, o as CACHE_MANIFEST, p as CONFIG_DIR, r as BACKUPS_DIR, s as CACHE_RULES_DIR, t as AGENTS_DIR, u as CLAUDE_DIR, v as INIT_DIRS, w as PROJECT_DOCS_SUBDIR, x as PRDS_DIR, y as LEGACY_RUNTIME_DIRS, z as TEMPLATES_DIR } from "./paths-lMaxrYtT.js";
2
- import { a as init_config, i as getDevrootPath, n as getDashboardApiUrl, o as loadConfig, r as getDefaultConfig, s as saveConfig, t as findDevrootForProject } from "./config-CRzMQRgA.js";
3
- import { A as hasAlias, C as createBackupTimestamp, D as detectShell, E as addAlias, O as getAliasInstructions, S as createBackup, T as restoreBackup, _ as planSync, a as getAgentCommand, b as syncStatusline, c as getDefaultSettings, d as saveSettings, f as validateSettings, g as planHooksSync, h as migrateStalePersonalContent, i as parseIssueRef, k as getShellRcFile, l as isAnthropicModel, m as isPanopticonSymlink, n as formatIssueRef, o as getAvailableModels, p as executeSync, r as getLinkManager, s as getClaudeModelFlag, t as LinkManager, u as loadSettings, v as refreshCache, w as listBackups, x as cleanOldBackups, y as syncHooks } from "./tracker-C_62ukEq.js";
4
- import { a as getProviderForModel, c as needsRouter, i as getProviderEnv, l as requiresRouter, n as clearCredentialFileAuth, o as getRouterProviders, r as getDirectProviders, s as init_providers, t as PROVIDERS, u as setupCredentialFileAuth } from "./providers-DcCPZ5K4.js";
5
- import { a as TrackerAuthError, i as NotImplementedError, r as IssueNotFoundError } from "./rally-uUUZXp1h.js";
6
- import { a as getSecondaryTracker, d as LinearTracker, i as getPrimaryTracker, l as GitHubTracker, n as createTrackerFromConfig, r as getAllTrackers, s as GitLabTracker, t as createTracker } from "./factory-DfzczxN1.js";
1
+ import { A as SKILLS_DIR, B as TRAEFIK_CERTS_DIR, C as PRD_PUBLISHED_DIR, D as PROJECT_PRDS_PLANNED_SUBDIR, E as PROJECT_PRDS_COMPLETED_SUBDIR, F as SOURCE_SKILLS_DIR, G as init_paths, H as TRAEFIK_DYNAMIC_DIR, I as SOURCE_TEMPLATES_DIR, K as isDevMode, L as SOURCE_TRAEFIK_TEMPLATES, M as SOURCE_DEV_SKILLS_DIR, N as SOURCE_RULES_DIR, O as PROJECT_PRDS_SUBDIR, P as SOURCE_SCRIPTS_DIR, R as SYNC_TARGET, S as PRD_DRAFTS_DIR, T as PROJECT_PRDS_ACTIVE_SUBDIR, U as encodeClaudeProjectDir, V as TRAEFIK_DIR, W as getPanopticonHome, _ as HEARTBEATS_DIR, a as CACHE_AGENTS_DIR, b as PANOPTICON_HOME, c as CACHE_SKILLS_DIR, d as CLAUDE_MD_TEMPLATES, f as COMMANDS_DIR, g as DOCS_DIR, h as COSTS_DIR, i as BIN_DIR, j as SOURCE_AGENTS_DIR, k as SETTINGS_FILE, l as CERTS_DIR, m as CONFIG_FILE, n as ARCHIVES_DIR, o as CACHE_MANIFEST, p as CONFIG_DIR, r as BACKUPS_DIR, s as CACHE_RULES_DIR, t as AGENTS_DIR, u as CLAUDE_DIR, v as INIT_DIRS, w as PROJECT_DOCS_SUBDIR, x as PRDS_DIR, y as LEGACY_RUNTIME_DIRS, z as TEMPLATES_DIR } from "./paths-CDJ_HsbN.js";
2
+ import { a as init_config, i as getDevrootPath, n as getDashboardApiUrl, o as loadConfig, r as getDefaultConfig, s as saveConfig, t as findDevrootForProject } from "./config-BQNKsi9G.js";
3
+ import { a as addAlias, c as getShellRcFile, i as parseIssueRef, l as hasAlias, n as formatIssueRef, o as detectShell, r as getLinkManager, s as getAliasInstructions, t as LinkManager } from "./tracker-BhYYvU3p.js";
4
+ import { _ as cleanOldBackups, a as isAnthropicModel, b as listBackups, c as validateSettings, d as migrateStalePersonalContent, f as planHooksSync, g as syncStatusline, h as syncHooks, i as getDefaultSettings, l as executeSync, m as refreshCache, n as getAvailableModels, o as loadSettings, p as planSync, r as getClaudeModelFlag, s as saveSettings, t as getAgentCommand, u as isPanopticonSymlink, v as createBackup, x as restoreBackup, y as createBackupTimestamp } from "./settings-BcWPTrua.js";
5
+ import { a as getProviderForModel, c as needsRouter, i as getProviderEnv, l as requiresRouter, n as clearCredentialFileAuth, o as getRouterProviders, r as getDirectProviders, s as init_providers, t as PROVIDERS, u as setupCredentialFileAuth } from "./providers-DSU1vfQF.js";
6
+ import { a as TrackerAuthError, i as NotImplementedError, r as IssueNotFoundError } from "./rally-Dy00NElU.js";
7
+ import { a as getSecondaryTracker, d as LinearTracker, i as getPrimaryTracker, l as GitHubTracker, n as createTrackerFromConfig, r as getAllTrackers, s as GitLabTracker, t as createTracker } from "./factory-DzsOiZVc.js";
7
8
  //#region src/index.ts
8
9
  init_paths();
9
10
  init_config();
10
11
  init_providers();
11
12
  //#endregion
12
- export { AGENTS_DIR, ARCHIVES_DIR, BACKUPS_DIR, BIN_DIR, CACHE_AGENTS_DIR, CACHE_MANIFEST, CACHE_RULES_DIR, CACHE_SKILLS_DIR, CERTS_DIR, CLAUDE_DIR, CLAUDE_MD_TEMPLATES, COMMANDS_DIR, CONFIG_DIR, CONFIG_FILE, COSTS_DIR, DOCS_DIR, GitHubTracker, GitLabTracker, HEARTBEATS_DIR, INIT_DIRS, IssueNotFoundError, LEGACY_RUNTIME_DIRS, LinearTracker, LinkManager, NotImplementedError, PANOPTICON_HOME, PRDS_DIR, PRD_DRAFTS_DIR, PRD_PUBLISHED_DIR, PROJECT_DOCS_SUBDIR, PROJECT_PRDS_ACTIVE_SUBDIR, PROJECT_PRDS_COMPLETED_SUBDIR, PROJECT_PRDS_PLANNED_SUBDIR, PROJECT_PRDS_SUBDIR, PROVIDERS, SETTINGS_FILE, SKILLS_DIR, SOURCE_AGENTS_DIR, SOURCE_DEV_SKILLS_DIR, SOURCE_RULES_DIR, SOURCE_SCRIPTS_DIR, SOURCE_SKILLS_DIR, SOURCE_TEMPLATES_DIR, SOURCE_TRAEFIK_TEMPLATES, SYNC_TARGET, TEMPLATES_DIR, TRAEFIK_CERTS_DIR, TRAEFIK_DIR, TRAEFIK_DYNAMIC_DIR, TrackerAuthError, addAlias, cleanOldBackups, clearCredentialFileAuth, createBackup, createBackupTimestamp, createTracker, createTrackerFromConfig, detectShell, executeSync, findDevrootForProject, formatIssueRef, getAgentCommand, getAliasInstructions, getAllTrackers, getAvailableModels, getClaudeModelFlag, getDashboardApiUrl, getDefaultConfig, getDefaultSettings, getDevrootPath, getDirectProviders, getLinkManager, getPanopticonHome, getPrimaryTracker, getProviderEnv, getProviderForModel, getRouterProviders, getSecondaryTracker, getShellRcFile, hasAlias, isAnthropicModel, isDevMode, isPanopticonSymlink, listBackups, loadConfig, loadSettings, migrateStalePersonalContent, needsRouter, parseIssueRef, planHooksSync, planSync, refreshCache, requiresRouter, restoreBackup, saveConfig, saveSettings, setupCredentialFileAuth, syncHooks, syncStatusline, validateSettings };
13
+ export { AGENTS_DIR, ARCHIVES_DIR, BACKUPS_DIR, BIN_DIR, CACHE_AGENTS_DIR, CACHE_MANIFEST, CACHE_RULES_DIR, CACHE_SKILLS_DIR, CERTS_DIR, CLAUDE_DIR, CLAUDE_MD_TEMPLATES, COMMANDS_DIR, CONFIG_DIR, CONFIG_FILE, COSTS_DIR, DOCS_DIR, GitHubTracker, GitLabTracker, HEARTBEATS_DIR, INIT_DIRS, IssueNotFoundError, LEGACY_RUNTIME_DIRS, LinearTracker, LinkManager, NotImplementedError, PANOPTICON_HOME, PRDS_DIR, PRD_DRAFTS_DIR, PRD_PUBLISHED_DIR, PROJECT_DOCS_SUBDIR, PROJECT_PRDS_ACTIVE_SUBDIR, PROJECT_PRDS_COMPLETED_SUBDIR, PROJECT_PRDS_PLANNED_SUBDIR, PROJECT_PRDS_SUBDIR, PROVIDERS, SETTINGS_FILE, SKILLS_DIR, SOURCE_AGENTS_DIR, SOURCE_DEV_SKILLS_DIR, SOURCE_RULES_DIR, SOURCE_SCRIPTS_DIR, SOURCE_SKILLS_DIR, SOURCE_TEMPLATES_DIR, SOURCE_TRAEFIK_TEMPLATES, SYNC_TARGET, TEMPLATES_DIR, TRAEFIK_CERTS_DIR, TRAEFIK_DIR, TRAEFIK_DYNAMIC_DIR, TrackerAuthError, addAlias, cleanOldBackups, clearCredentialFileAuth, createBackup, createBackupTimestamp, createTracker, createTrackerFromConfig, detectShell, encodeClaudeProjectDir, executeSync, findDevrootForProject, formatIssueRef, getAgentCommand, getAliasInstructions, getAllTrackers, getAvailableModels, getClaudeModelFlag, getDashboardApiUrl, getDefaultConfig, getDefaultSettings, getDevrootPath, getDirectProviders, getLinkManager, getPanopticonHome, getPrimaryTracker, getProviderEnv, getProviderForModel, getRouterProviders, getSecondaryTracker, getShellRcFile, hasAlias, isAnthropicModel, isDevMode, isPanopticonSymlink, listBackups, loadConfig, loadSettings, migrateStalePersonalContent, needsRouter, parseIssueRef, planHooksSync, planSync, refreshCache, requiresRouter, restoreBackup, saveConfig, saveSettings, setupCredentialFileAuth, syncHooks, syncStatusline, validateSettings };
13
14
 
14
15
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,62 @@
1
+ import { t as __esmMin } from "./chunk-ruWRV7i3.js";
2
+ //#region src/lib/issue-id.ts
3
+ /**
4
+ * Parse an issue ID into its components.
5
+ *
6
+ * Supports:
7
+ * - Standard: PREFIX-NUMBER (e.g., MIN-123, PAN-456)
8
+ * - Rally: TYPENUMBER (e.g., F29698, US12345, DE118304, TA4567)
9
+ * - Custom: Per-project regex patterns
10
+ *
11
+ * @param issueId - The raw issue ID string
12
+ * @param projectConfig - Optional project config for custom patterns
13
+ * @returns ParsedIssueId or null if no format matches
14
+ */
15
+ function parseIssueId(issueId, projectConfig) {
16
+ const standardMatch = issueId.match(/^([A-Za-z]+)-(\d+)$/);
17
+ if (standardMatch) return {
18
+ raw: issueId,
19
+ prefix: standardMatch[1].toUpperCase(),
20
+ number: parseInt(standardMatch[2], 10),
21
+ normalized: issueId.toLowerCase(),
22
+ format: "standard"
23
+ };
24
+ const rallyMatch = issueId.match(/^(F|US|DE|TA|TC)(\d+)$/i);
25
+ if (rallyMatch) return {
26
+ raw: issueId,
27
+ prefix: rallyMatch[1].toUpperCase(),
28
+ number: parseInt(rallyMatch[2], 10),
29
+ normalized: issueId.toLowerCase(),
30
+ format: "rally"
31
+ };
32
+ if (projectConfig?.issue_pattern) {
33
+ const customMatch = issueId.match(new RegExp(projectConfig.issue_pattern, "i"));
34
+ if (customMatch && customMatch[1] && customMatch[2]) return {
35
+ raw: issueId,
36
+ prefix: customMatch[1].toUpperCase(),
37
+ number: parseInt(customMatch[2], 10),
38
+ normalized: issueId.toLowerCase(),
39
+ format: "custom"
40
+ };
41
+ }
42
+ return null;
43
+ }
44
+ /**
45
+ * Extract just the team/project prefix from an issue ID.
46
+ * Handles standard (MIN-123), Rally (F29698), and custom formats.
47
+ */
48
+ function extractPrefix(issueId) {
49
+ return parseIssueId(issueId)?.prefix ?? null;
50
+ }
51
+ /**
52
+ * Extract the numeric portion of an issue ID.
53
+ * Handles standard (MIN-123), Rally (F29698), and custom formats.
54
+ */
55
+ function extractNumber(issueId) {
56
+ return parseIssueId(issueId)?.number ?? null;
57
+ }
58
+ var init_issue_id = __esmMin((() => {}));
59
+ //#endregion
60
+ export { parseIssueId as i, extractPrefix as n, init_issue_id as r, extractNumber as t };
61
+
62
+ //# sourceMappingURL=issue-id-CAcekoIw.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issue-id-CAcekoIw.js","names":[],"sources":["../src/lib/issue-id.ts"],"sourcesContent":["/**\n * Unified Issue ID Parser\n *\n * Handles multiple issue ID formats:\n * - Standard: PREFIX-NUMBER (e.g., MIN-123, PAN-456)\n * - Rally: TYPENUMBER (e.g., F29698, US12345, DE118304, TA4567)\n * - Custom: Per-project regex patterns\n */\n\nimport type { ProjectConfig } from './projects.js';\n\n/**\n * Parsed representation of any issue ID format.\n */\nexport interface ParsedIssueId {\n /** Original ID as provided (e.g., \"MIN-123\", \"F29698\") */\n raw: string;\n /** Extracted prefix for project resolution (e.g., \"MIN\", \"F\", \"US\") */\n prefix: string;\n /** Numeric portion (e.g., 123, 29698) */\n number: number;\n /** Normalized lowercase form for filesystem use (e.g., \"min-123\", \"f29698\") */\n normalized: string;\n /** Format that was matched */\n format: 'standard' | 'rally' | 'custom';\n}\n\n/**\n * Parse an issue ID into its components.\n *\n * Supports:\n * - Standard: PREFIX-NUMBER (e.g., MIN-123, PAN-456)\n * - Rally: TYPENUMBER (e.g., F29698, US12345, DE118304, TA4567)\n * - Custom: Per-project regex patterns\n *\n * @param issueId - The raw issue ID string\n * @param projectConfig - Optional project config for custom patterns\n * @returns ParsedIssueId or null if no format matches\n */\nexport function parseIssueId(issueId: string, projectConfig?: ProjectConfig): ParsedIssueId | null {\n // Standard format first (most common): PREFIX-NUMBER\n const standardMatch = issueId.match(/^([A-Za-z]+)-(\\d+)$/);\n if (standardMatch) {\n return {\n raw: issueId,\n prefix: standardMatch[1].toUpperCase(),\n number: parseInt(standardMatch[2], 10),\n normalized: issueId.toLowerCase(),\n format: 'standard',\n };\n }\n\n // Rally format: TYPE_PREFIX followed by NUMBER (no separator)\n // Known Rally prefixes: F (Feature), US (User Story), DE (Defect),\n // TA (Task), TC (Test Case)\n const rallyMatch = issueId.match(/^(F|US|DE|TA|TC)(\\d+)$/i);\n if (rallyMatch) {\n return {\n raw: issueId,\n prefix: rallyMatch[1].toUpperCase(),\n number: parseInt(rallyMatch[2], 10),\n normalized: issueId.toLowerCase(),\n format: 'rally',\n };\n }\n\n // Custom project pattern if provided\n if (projectConfig?.issue_pattern) {\n const customMatch = issueId.match(new RegExp(projectConfig.issue_pattern, 'i'));\n if (customMatch && customMatch[1] && customMatch[2]) {\n return {\n raw: issueId,\n prefix: customMatch[1].toUpperCase(),\n number: parseInt(customMatch[2], 10),\n normalized: issueId.toLowerCase(),\n format: 'custom',\n };\n }\n }\n\n return null;\n}\n\n/**\n * Extract just the team/project prefix from an issue ID.\n * Handles standard (MIN-123), Rally (F29698), and custom formats.\n */\nexport function extractPrefix(issueId: string): string | null {\n const parsed = parseIssueId(issueId);\n return parsed?.prefix ?? null;\n}\n\n/**\n * Extract the numeric portion of an issue ID.\n * Handles standard (MIN-123), Rally (F29698), and custom formats.\n */\nexport function extractNumber(issueId: string): number | null {\n const parsed = parseIssueId(issueId);\n return parsed?.number ?? null;\n}\n\n/**\n * Get the normalized (lowercase, filesystem-safe) form of an issue ID.\n * Standard IDs keep the dash: \"min-123\". Rally IDs stay concatenated: \"f29698\".\n */\nexport function normalizeIssueId(issueId: string): string {\n const parsed = parseIssueId(issueId);\n return parsed?.normalized ?? issueId.toLowerCase();\n}\n\n/**\n * Extract prefix from a standard format issue ID (PREFIX-NUMBER).\n * Returns null for non-standard formats like Rally IDs.\n * Use extractPrefix() for unified handling of all formats.\n */\nexport function extractStandardPrefix(issueId: string): string | null {\n const match = issueId.match(/^([A-Za-z]+)-\\d+$/i);\n return match ? match[1].toUpperCase() : null;\n}\n\n/**\n * Extract number from a standard format issue ID (PREFIX-NUMBER).\n * Returns null for non-standard formats like Rally IDs.\n * Use extractNumber() for unified handling of all formats.\n */\nexport function extractStandardNumber(issueId: string): number | null {\n const match = issueId.match(/^([A-Za-z]+)-(\\d+)$/i);\n return match ? parseInt(match[2], 10) : null;\n}\n"],"mappings":";;;;;;;;;;;;;;AAuCA,SAAgB,aAAa,SAAiB,eAAqD;CAEjG,MAAM,gBAAgB,QAAQ,MAAM,sBAAsB;AAC1D,KAAI,cACF,QAAO;EACL,KAAK;EACL,QAAQ,cAAc,GAAG,aAAa;EACtC,QAAQ,SAAS,cAAc,IAAI,GAAG;EACtC,YAAY,QAAQ,aAAa;EACjC,QAAQ;EACT;CAMH,MAAM,aAAa,QAAQ,MAAM,0BAA0B;AAC3D,KAAI,WACF,QAAO;EACL,KAAK;EACL,QAAQ,WAAW,GAAG,aAAa;EACnC,QAAQ,SAAS,WAAW,IAAI,GAAG;EACnC,YAAY,QAAQ,aAAa;EACjC,QAAQ;EACT;AAIH,KAAI,eAAe,eAAe;EAChC,MAAM,cAAc,QAAQ,MAAM,IAAI,OAAO,cAAc,eAAe,IAAI,CAAC;AAC/E,MAAI,eAAe,YAAY,MAAM,YAAY,GAC/C,QAAO;GACL,KAAK;GACL,QAAQ,YAAY,GAAG,aAAa;GACpC,QAAQ,SAAS,YAAY,IAAI,GAAG;GACpC,YAAY,QAAQ,aAAa;GACjC,QAAQ;GACT;;AAIL,QAAO;;;;;;AAOT,SAAgB,cAAc,SAAgC;AAE5D,QADe,aAAa,QAAQ,EACrB,UAAU;;;;;;AAO3B,SAAgB,cAAc,SAAgC;AAE5D,QADe,aAAa,QAAQ,EACrB,UAAU"}
@@ -1,4 +1,5 @@
1
- import { i as stepSkipped, n as stepFailed, r as stepOk, t as getLinearApiKey } from "./types-DewGdaIP.js";
1
+ import { n as extractPrefix, r as init_issue_id, t as extractNumber } from "./issue-id-CAcekoIw.js";
2
+ import { i as stepSkipped, n as stepFailed, r as stepOk, t as getLinearApiKey } from "./types-BhJj1SP1.js";
2
3
  import { exec } from "child_process";
3
4
  import { promisify } from "util";
4
5
  //#region src/lib/lifecycle/label-cleanup.ts
@@ -11,6 +12,7 @@ import { promisify } from "util";
11
12
  * Removes: in-review, in-progress, merge-agent
12
13
  * Adds: merged
13
14
  */
15
+ init_issue_id();
14
16
  const execAsync = promisify(exec);
15
17
  const MERGED_LABEL = "merged";
16
18
  const MERGED_COLOR = "0e8a16";
@@ -48,8 +50,9 @@ async function cleanupLabelsLinear(ctx, apiKey) {
48
50
  try {
49
51
  const { LinearClient } = await import("@linear/sdk");
50
52
  const client = new LinearClient({ apiKey });
51
- const issueNum = parseInt(ctx.issueId.split("-").pop() || "0", 10);
52
- const teamKey = ctx.issueId.split("-")[0].toUpperCase();
53
+ const issueNum = extractNumber(ctx.issueId);
54
+ const teamKey = extractPrefix(ctx.issueId);
55
+ if (issueNum === null || teamKey === null) return stepFailed(step, `Could not parse issue ID: ${ctx.issueId}`);
53
56
  const results = await client.issues({
54
57
  filter: {
55
58
  number: { eq: issueNum },
@@ -82,4 +85,4 @@ async function cleanupLabelsLinear(ctx, apiKey) {
82
85
  //#endregion
83
86
  export { cleanupMergedLabels };
84
87
 
85
- //# sourceMappingURL=label-cleanup-31ElPqqv.js.map
88
+ //# sourceMappingURL=label-cleanup-C8R9Rspn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"label-cleanup-C8R9Rspn.js","names":[],"sources":["../src/lib/lifecycle/label-cleanup.ts"],"sourcesContent":["/**\n * label-cleanup — Remove workflow labels and apply 'merged' label after merge.\n *\n * Runs as part of postMergeLifecycle (step 3b), independently of close-issue.\n * Labels are cleaned even if the issue close step fails.\n *\n * Removes: in-review, in-progress, merge-agent\n * Adds: merged\n */\n\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\nimport type { LifecycleContext, StepResult } from './types.js';\nimport { stepOk, stepSkipped, stepFailed, getLinearApiKey } from './types.js';\nimport { extractNumber, extractPrefix } from '../issue-id.js';\n\nconst execAsync = promisify(exec);\n\nconst MERGED_LABEL = 'merged';\nconst MERGED_COLOR = '0e8a16'; // green\nconst LABELS_TO_REMOVE = ['in-review', 'in-progress', 'merge-agent'];\n\n/**\n * Remove workflow labels and apply 'merged' label.\n * Non-fatal: label management failure does not block the merge lifecycle.\n */\nexport async function cleanupMergedLabels(ctx: LifecycleContext): Promise<StepResult> {\n const step = 'label-cleanup:merged';\n\n if (ctx.github) {\n return cleanupLabelsGitHub(ctx);\n }\n\n const linearApiKey = getLinearApiKey();\n if (linearApiKey) {\n return cleanupLabelsLinear(ctx, linearApiKey);\n }\n\n return stepSkipped(step, ['No tracker available for label cleanup']);\n}\n\nasync function cleanupLabelsGitHub(ctx: LifecycleContext): Promise<StepResult> {\n const step = 'label-cleanup:merged';\n if (!ctx.github) return stepSkipped(step);\n const { owner, repo, number } = ctx.github;\n\n try {\n // Ensure merged label exists\n await execAsync(\n `gh label create \"${MERGED_LABEL}\" --repo ${owner}/${repo} --color \"${MERGED_COLOR}\" --description \"Merged to main\" --force 2>/dev/null || true`,\n { encoding: 'utf-8' },\n );\n\n // Add merged label\n await execAsync(\n `gh issue edit ${number} --repo ${owner}/${repo} --add-label \"${MERGED_LABEL}\"`,\n { encoding: 'utf-8' },\n );\n\n // Remove workflow labels (best-effort — skip if not present)\n for (const label of LABELS_TO_REMOVE) {\n await execAsync(\n `gh issue edit ${number} --repo ${owner}/${repo} --remove-label \"${label}\" 2>/dev/null || true`,\n { encoding: 'utf-8' },\n );\n }\n\n return stepOk(step, [\n `Applied '${MERGED_LABEL}' label on GitHub #${number}`,\n `Removed: ${LABELS_TO_REMOVE.join(', ')}`,\n ]);\n } catch (err) {\n return stepFailed(step, `Label cleanup failed: ${(err as Error).message}`);\n }\n}\n\nasync function cleanupLabelsLinear(ctx: LifecycleContext, apiKey: string): Promise<StepResult> {\n const step = 'label-cleanup:merged';\n try {\n const { LinearClient } = await import('@linear/sdk');\n const client = new LinearClient({ apiKey });\n\n const issueNum = extractNumber(ctx.issueId);\n const teamKey = extractPrefix(ctx.issueId);\n if (issueNum === null || teamKey === null) {\n return stepFailed(step, `Could not parse issue ID: ${ctx.issueId}`);\n }\n const results = await client.issues({\n filter: {\n number: { eq: issueNum },\n team: { key: { eq: teamKey } },\n },\n first: 1,\n });\n\n if (results.nodes.length === 0) {\n return stepSkipped(step, ['Issue not found for label cleanup']);\n }\n\n const issue = results.nodes[0];\n\n // Find or create merged label\n const labelSearch = await client.issueLabels({ filter: { name: { eq: MERGED_LABEL } } });\n let mergedLabelId: string;\n if (labelSearch.nodes.length > 0) {\n mergedLabelId = labelSearch.nodes[0].id;\n } else {\n const created = await client.createIssueLabel({ name: MERGED_LABEL, color: `#${MERGED_COLOR}` });\n const createdLabel = await created.issueLabel;\n mergedLabelId = createdLabel ? createdLabel.id : '';\n }\n\n if (mergedLabelId) {\n const existingLabels = await issue.labels();\n // Remove workflow labels, add merged\n const filteredIds = existingLabels.nodes\n .filter(l => !LABELS_TO_REMOVE.includes(l.name))\n .map(l => l.id);\n if (!filteredIds.includes(mergedLabelId)) {\n filteredIds.push(mergedLabelId);\n }\n await issue.update({ labelIds: filteredIds });\n }\n\n return stepOk(step, [\n `Applied '${MERGED_LABEL}' label on Linear ${ctx.issueId}`,\n `Removed: ${LABELS_TO_REMOVE.join(', ')}`,\n ]);\n } catch (err) {\n return stepFailed(step, `Linear label cleanup failed: ${(err as Error).message}`);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;eAc8D;AAE9D,MAAM,YAAY,UAAU,KAAK;AAEjC,MAAM,eAAe;AACrB,MAAM,eAAe;AACrB,MAAM,mBAAmB;CAAC;CAAa;CAAe;CAAc;;;;;AAMpE,eAAsB,oBAAoB,KAA4C;CACpF,MAAM,OAAO;AAEb,KAAI,IAAI,OACN,QAAO,oBAAoB,IAAI;CAGjC,MAAM,eAAe,iBAAiB;AACtC,KAAI,aACF,QAAO,oBAAoB,KAAK,aAAa;AAG/C,QAAO,YAAY,MAAM,CAAC,yCAAyC,CAAC;;AAGtE,eAAe,oBAAoB,KAA4C;CAC7E,MAAM,OAAO;AACb,KAAI,CAAC,IAAI,OAAQ,QAAO,YAAY,KAAK;CACzC,MAAM,EAAE,OAAO,MAAM,WAAW,IAAI;AAEpC,KAAI;AAEF,QAAM,UACJ,oBAAoB,aAAa,WAAW,MAAM,GAAG,KAAK,YAAY,aAAa,+DACnF,EAAE,UAAU,SAAS,CACtB;AAGD,QAAM,UACJ,iBAAiB,OAAO,UAAU,MAAM,GAAG,KAAK,gBAAgB,aAAa,IAC7E,EAAE,UAAU,SAAS,CACtB;AAGD,OAAK,MAAM,SAAS,iBAClB,OAAM,UACJ,iBAAiB,OAAO,UAAU,MAAM,GAAG,KAAK,mBAAmB,MAAM,wBACzE,EAAE,UAAU,SAAS,CACtB;AAGH,SAAO,OAAO,MAAM,CAClB,YAAY,aAAa,qBAAqB,UAC9C,YAAY,iBAAiB,KAAK,KAAK,GACxC,CAAC;UACK,KAAK;AACZ,SAAO,WAAW,MAAM,yBAA0B,IAAc,UAAU;;;AAI9E,eAAe,oBAAoB,KAAuB,QAAqC;CAC7F,MAAM,OAAO;AACb,KAAI;EACF,MAAM,EAAE,iBAAiB,MAAM,OAAO;EACtC,MAAM,SAAS,IAAI,aAAa,EAAE,QAAQ,CAAC;EAE3C,MAAM,WAAW,cAAc,IAAI,QAAQ;EAC3C,MAAM,UAAU,cAAc,IAAI,QAAQ;AAC1C,MAAI,aAAa,QAAQ,YAAY,KACnC,QAAO,WAAW,MAAM,6BAA6B,IAAI,UAAU;EAErE,MAAM,UAAU,MAAM,OAAO,OAAO;GAClC,QAAQ;IACN,QAAQ,EAAE,IAAI,UAAU;IACxB,MAAM,EAAE,KAAK,EAAE,IAAI,SAAS,EAAE;IAC/B;GACD,OAAO;GACR,CAAC;AAEF,MAAI,QAAQ,MAAM,WAAW,EAC3B,QAAO,YAAY,MAAM,CAAC,oCAAoC,CAAC;EAGjE,MAAM,QAAQ,QAAQ,MAAM;EAG5B,MAAM,cAAc,MAAM,OAAO,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,cAAc,EAAE,EAAE,CAAC;EACxF,IAAI;AACJ,MAAI,YAAY,MAAM,SAAS,EAC7B,iBAAgB,YAAY,MAAM,GAAG;OAChC;GAEL,MAAM,eAAe,OADL,MAAM,OAAO,iBAAiB;IAAE,MAAM;IAAc,OAAO,IAAI;IAAgB,CAAC,EAC7D;AACnC,mBAAgB,eAAe,aAAa,KAAK;;AAGnD,MAAI,eAAe;GAGjB,MAAM,eAFiB,MAAM,MAAM,QAAQ,EAER,MAChC,QAAO,MAAK,CAAC,iBAAiB,SAAS,EAAE,KAAK,CAAC,CAC/C,KAAI,MAAK,EAAE,GAAG;AACjB,OAAI,CAAC,YAAY,SAAS,cAAc,CACtC,aAAY,KAAK,cAAc;AAEjC,SAAM,MAAM,OAAO,EAAE,UAAU,aAAa,CAAC;;AAG/C,SAAO,OAAO,MAAM,CAClB,YAAY,aAAa,oBAAoB,IAAI,WACjD,YAAY,iBAAiB,KAAK,KAAK,GACxC,CAAC;UACK,KAAK;AACZ,SAAO,WAAW,MAAM,gCAAiC,IAAc,UAAU"}
@@ -123,4 +123,4 @@ var init_manifest = __esmMin((() => {}));
123
123
  //#endregion
124
124
  export { init_manifest as a, writeManifest as c, hashFile as i, collectSourceFiles as n, readManifest as o, compareFileToManifest as r, setManifestEntry as s, buildManifestFromDirectory as t };
125
125
 
126
- //# sourceMappingURL=manifest-DL0oDbpv.js.map
126
+ //# sourceMappingURL=manifest-B4ghOD-V.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"manifest-DL0oDbpv.js","names":[],"sources":["../src/lib/manifest.ts"],"sourcesContent":["import { createHash } from 'crypto';\nimport { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from 'fs';\nimport { join, relative } from 'path';\n\n/**\n * Manifest entry for a single distributed file.\n */\nexport interface ManifestEntry {\n hash: string; // sha256:<hex>\n source: string; // \"panopticon\" | \"project-template\" | custom\n installed_at: string; // ISO 8601 timestamp\n}\n\n/**\n * The manifest schema: tracks what Panopticon placed at a target location.\n */\nexport interface Manifest {\n version: 1;\n managed_by: 'panopticon';\n installed: Record<string, ManifestEntry>;\n}\n\n/**\n * Result of comparing a file against the manifest.\n */\nexport type FileStatus =\n | { action: 'new' } // File doesn't exist at target — safe to copy\n | { action: 'update'; currentHash: string } // File exists, hash matches manifest — we placed it, user didn't modify\n | { action: 'modified'; currentHash: string; manifestHash: string } // File exists, hash differs from manifest — user modified\n | { action: 'user-owned' } // File exists but NOT in manifest — user placed it, never touch\n ;\n\n/**\n * Compute SHA-256 hash of a file, prefixed with \"sha256:\".\n */\nexport function hashFile(filePath: string): string {\n const content = readFileSync(filePath);\n const hex = createHash('sha256').update(content).digest('hex');\n return `sha256:${hex}`;\n}\n\n/**\n * Create an empty manifest.\n */\nexport function createEmptyManifest(): Manifest {\n return {\n version: 1,\n managed_by: 'panopticon',\n installed: {},\n };\n}\n\n/**\n * Read a manifest from disk. Returns empty manifest if file doesn't exist or is invalid.\n */\nexport function readManifest(manifestPath: string): Manifest {\n if (!existsSync(manifestPath)) {\n return createEmptyManifest();\n }\n\n try {\n const raw = JSON.parse(readFileSync(manifestPath, 'utf-8'));\n if (raw.version === 1 && raw.managed_by === 'panopticon' && typeof raw.installed === 'object') {\n return raw as Manifest;\n }\n return createEmptyManifest();\n } catch {\n return createEmptyManifest();\n }\n}\n\n/**\n * Write a manifest to disk (creates parent directories if needed).\n */\nexport function writeManifest(manifestPath: string, manifest: Manifest): void {\n mkdirSync(join(manifestPath, '..'), { recursive: true });\n writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\\n', 'utf-8');\n}\n\n/**\n * Add or update an entry in a manifest.\n */\nexport function setManifestEntry(\n manifest: Manifest,\n relativePath: string,\n hash: string,\n source: string,\n): void {\n manifest.installed[relativePath] = {\n hash,\n source,\n installed_at: new Date().toISOString(),\n };\n}\n\n/**\n * Remove an entry from a manifest.\n */\nexport function removeManifestEntry(manifest: Manifest, relativePath: string): void {\n delete manifest.installed[relativePath];\n}\n\n/**\n * Compare a file on disk against the manifest to determine what action to take.\n *\n * @param targetFile - Absolute path to the file at the target location\n * @param relativePath - Relative path used as key in the manifest (e.g., \"skills/beads/SKILL.md\")\n * @param manifest - The manifest to compare against\n */\nexport function compareFileToManifest(\n targetFile: string,\n relativePath: string,\n manifest: Manifest,\n): FileStatus {\n if (!existsSync(targetFile)) {\n return { action: 'new' };\n }\n\n const entry = manifest.installed[relativePath];\n if (!entry) {\n return { action: 'user-owned' };\n }\n\n const currentHash = hashFile(targetFile);\n if (currentHash === entry.hash) {\n return { action: 'update', currentHash };\n }\n\n return { action: 'modified', currentHash, manifestHash: entry.hash };\n}\n\n/**\n * Walk a source directory and collect all files with their relative paths.\n * Used to build the list of files to distribute.\n *\n * @param sourceDir - Root directory to walk\n * @param prefix - Prefix for relative paths (e.g., \"skills/\" or \"agents/\")\n * @returns Array of { absolutePath, relativePath } for each file found\n */\nexport function collectSourceFiles(\n sourceDir: string,\n prefix: string,\n): Array<{ absolutePath: string; relativePath: string }> {\n const results: Array<{ absolutePath: string; relativePath: string }> = [];\n\n if (!existsSync(sourceDir)) {\n return results;\n }\n\n function walk(dir: string): void {\n const entries = readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n walk(fullPath);\n } else if (entry.isFile()) {\n const rel = relative(sourceDir, fullPath);\n results.push({\n absolutePath: fullPath,\n relativePath: `${prefix}${rel}`,\n });\n }\n }\n }\n\n walk(sourceDir);\n return results;\n}\n\n/**\n * Build a manifest from a directory by hashing all files.\n * Useful for generating the initial cache manifest.\n *\n * @param baseDir - The directory to scan (e.g., ~/.panopticon/)\n * @param categories - Which subdirectories to include (e.g., [\"skills\", \"agents\", \"rules\"])\n * @param source - The source label for all entries (e.g., \"panopticon\")\n */\nexport function buildManifestFromDirectory(\n baseDir: string,\n categories: string[],\n source: string,\n): Manifest {\n const manifest = createEmptyManifest();\n\n for (const category of categories) {\n const categoryDir = join(baseDir, category);\n const files = collectSourceFiles(categoryDir, `${category}/`);\n for (const file of files) {\n const hash = hashFile(file.absolutePath);\n setManifestEntry(manifest, file.relativePath, hash, source);\n }\n }\n\n return manifest;\n}\n"],"mappings":";;;;;;;;AAmCA,SAAgB,SAAS,UAA0B;CACjD,MAAM,UAAU,aAAa,SAAS;AAEtC,QAAO,UADK,WAAW,SAAS,CAAC,OAAO,QAAQ,CAAC,OAAO,MAAM;;;;;AAOhE,SAAgB,sBAAgC;AAC9C,QAAO;EACL,SAAS;EACT,YAAY;EACZ,WAAW,EAAE;EACd;;;;;AAMH,SAAgB,aAAa,cAAgC;AAC3D,KAAI,CAAC,WAAW,aAAa,CAC3B,QAAO,qBAAqB;AAG9B,KAAI;EACF,MAAM,MAAM,KAAK,MAAM,aAAa,cAAc,QAAQ,CAAC;AAC3D,MAAI,IAAI,YAAY,KAAK,IAAI,eAAe,gBAAgB,OAAO,IAAI,cAAc,SACnF,QAAO;AAET,SAAO,qBAAqB;SACtB;AACN,SAAO,qBAAqB;;;;;;AAOhC,SAAgB,cAAc,cAAsB,UAA0B;AAC5E,WAAU,KAAK,cAAc,KAAK,EAAE,EAAE,WAAW,MAAM,CAAC;AACxD,eAAc,cAAc,KAAK,UAAU,UAAU,MAAM,EAAE,GAAG,MAAM,QAAQ;;;;;AAMhF,SAAgB,iBACd,UACA,cACA,MACA,QACM;AACN,UAAS,UAAU,gBAAgB;EACjC;EACA;EACA,+BAAc,IAAI,MAAM,EAAC,aAAa;EACvC;;;;;;;;;AAiBH,SAAgB,sBACd,YACA,cACA,UACY;AACZ,KAAI,CAAC,WAAW,WAAW,CACzB,QAAO,EAAE,QAAQ,OAAO;CAG1B,MAAM,QAAQ,SAAS,UAAU;AACjC,KAAI,CAAC,MACH,QAAO,EAAE,QAAQ,cAAc;CAGjC,MAAM,cAAc,SAAS,WAAW;AACxC,KAAI,gBAAgB,MAAM,KACxB,QAAO;EAAE,QAAQ;EAAU;EAAa;AAG1C,QAAO;EAAE,QAAQ;EAAY;EAAa,cAAc,MAAM;EAAM;;;;;;;;;;AAWtE,SAAgB,mBACd,WACA,QACuD;CACvD,MAAM,UAAiE,EAAE;AAEzE,KAAI,CAAC,WAAW,UAAU,CACxB,QAAO;CAGT,SAAS,KAAK,KAAmB;EAC/B,MAAM,UAAU,YAAY,KAAK,EAAE,eAAe,MAAM,CAAC;AACzD,OAAK,MAAM,SAAS,SAAS;GAC3B,MAAM,WAAW,KAAK,KAAK,MAAM,KAAK;AACtC,OAAI,MAAM,aAAa,CACrB,MAAK,SAAS;YACL,MAAM,QAAQ,EAAE;IACzB,MAAM,MAAM,SAAS,WAAW,SAAS;AACzC,YAAQ,KAAK;KACX,cAAc;KACd,cAAc,GAAG,SAAS;KAC3B,CAAC;;;;AAKR,MAAK,UAAU;AACf,QAAO;;;;;;;;;;AAWT,SAAgB,2BACd,SACA,YACA,QACU;CACV,MAAM,WAAW,qBAAqB;AAEtC,MAAK,MAAM,YAAY,YAAY;EAEjC,MAAM,QAAQ,mBADM,KAAK,SAAS,SAAS,EACG,GAAG,SAAS,GAAG;AAC7D,OAAK,MAAM,QAAQ,OAAO;GACxB,MAAM,OAAO,SAAS,KAAK,aAAa;AACxC,oBAAiB,UAAU,KAAK,cAAc,MAAM,OAAO;;;AAI/D,QAAO"}
1
+ {"version":3,"file":"manifest-B4ghOD-V.js","names":[],"sources":["../src/lib/manifest.ts"],"sourcesContent":["import { createHash } from 'crypto';\nimport { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from 'fs';\nimport { join, relative } from 'path';\n\n/**\n * Manifest entry for a single distributed file.\n */\nexport interface ManifestEntry {\n hash: string; // sha256:<hex>\n source: string; // \"panopticon\" | \"project-template\" | custom\n installed_at: string; // ISO 8601 timestamp\n}\n\n/**\n * The manifest schema: tracks what Panopticon placed at a target location.\n */\nexport interface Manifest {\n version: 1;\n managed_by: 'panopticon';\n installed: Record<string, ManifestEntry>;\n}\n\n/**\n * Result of comparing a file against the manifest.\n */\nexport type FileStatus =\n | { action: 'new' } // File doesn't exist at target — safe to copy\n | { action: 'update'; currentHash: string } // File exists, hash matches manifest — we placed it, user didn't modify\n | { action: 'modified'; currentHash: string; manifestHash: string } // File exists, hash differs from manifest — user modified\n | { action: 'user-owned' } // File exists but NOT in manifest — user placed it, never touch\n ;\n\n/**\n * Compute SHA-256 hash of a file, prefixed with \"sha256:\".\n */\nexport function hashFile(filePath: string): string {\n const content = readFileSync(filePath);\n const hex = createHash('sha256').update(content).digest('hex');\n return `sha256:${hex}`;\n}\n\n/**\n * Create an empty manifest.\n */\nexport function createEmptyManifest(): Manifest {\n return {\n version: 1,\n managed_by: 'panopticon',\n installed: {},\n };\n}\n\n/**\n * Read a manifest from disk. Returns empty manifest if file doesn't exist or is invalid.\n */\nexport function readManifest(manifestPath: string): Manifest {\n if (!existsSync(manifestPath)) {\n return createEmptyManifest();\n }\n\n try {\n const raw = JSON.parse(readFileSync(manifestPath, 'utf-8'));\n if (raw.version === 1 && raw.managed_by === 'panopticon' && typeof raw.installed === 'object') {\n return raw as Manifest;\n }\n return createEmptyManifest();\n } catch {\n return createEmptyManifest();\n }\n}\n\n/**\n * Write a manifest to disk (creates parent directories if needed).\n */\nexport function writeManifest(manifestPath: string, manifest: Manifest): void {\n mkdirSync(join(manifestPath, '..'), { recursive: true });\n writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\\n', 'utf-8');\n}\n\n/**\n * Add or update an entry in a manifest.\n */\nexport function setManifestEntry(\n manifest: Manifest,\n relativePath: string,\n hash: string,\n source: string,\n): void {\n manifest.installed[relativePath] = {\n hash,\n source,\n installed_at: new Date().toISOString(),\n };\n}\n\n/**\n * Remove an entry from a manifest.\n */\nexport function removeManifestEntry(manifest: Manifest, relativePath: string): void {\n delete manifest.installed[relativePath];\n}\n\n/**\n * Compare a file on disk against the manifest to determine what action to take.\n *\n * @param targetFile - Absolute path to the file at the target location\n * @param relativePath - Relative path used as key in the manifest (e.g., \"skills/beads/SKILL.md\")\n * @param manifest - The manifest to compare against\n */\nexport function compareFileToManifest(\n targetFile: string,\n relativePath: string,\n manifest: Manifest,\n): FileStatus {\n if (!existsSync(targetFile)) {\n return { action: 'new' };\n }\n\n const entry = manifest.installed[relativePath];\n if (!entry) {\n return { action: 'user-owned' };\n }\n\n const currentHash = hashFile(targetFile);\n if (currentHash === entry.hash) {\n return { action: 'update', currentHash };\n }\n\n return { action: 'modified', currentHash, manifestHash: entry.hash };\n}\n\n/**\n * Walk a source directory and collect all files with their relative paths.\n * Used to build the list of files to distribute.\n *\n * @param sourceDir - Root directory to walk\n * @param prefix - Prefix for relative paths (e.g., \"skills/\" or \"agents/\")\n * @returns Array of { absolutePath, relativePath } for each file found\n */\nexport function collectSourceFiles(\n sourceDir: string,\n prefix: string,\n): Array<{ absolutePath: string; relativePath: string }> {\n const results: Array<{ absolutePath: string; relativePath: string }> = [];\n\n if (!existsSync(sourceDir)) {\n return results;\n }\n\n function walk(dir: string): void {\n const entries = readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n walk(fullPath);\n } else if (entry.isFile()) {\n const rel = relative(sourceDir, fullPath);\n results.push({\n absolutePath: fullPath,\n relativePath: `${prefix}${rel}`,\n });\n }\n }\n }\n\n walk(sourceDir);\n return results;\n}\n\n/**\n * Build a manifest from a directory by hashing all files.\n * Useful for generating the initial cache manifest.\n *\n * @param baseDir - The directory to scan (e.g., ~/.panopticon/)\n * @param categories - Which subdirectories to include (e.g., [\"skills\", \"agents\", \"rules\"])\n * @param source - The source label for all entries (e.g., \"panopticon\")\n */\nexport function buildManifestFromDirectory(\n baseDir: string,\n categories: string[],\n source: string,\n): Manifest {\n const manifest = createEmptyManifest();\n\n for (const category of categories) {\n const categoryDir = join(baseDir, category);\n const files = collectSourceFiles(categoryDir, `${category}/`);\n for (const file of files) {\n const hash = hashFile(file.absolutePath);\n setManifestEntry(manifest, file.relativePath, hash, source);\n }\n }\n\n return manifest;\n}\n"],"mappings":";;;;;;;;AAmCA,SAAgB,SAAS,UAA0B;CACjD,MAAM,UAAU,aAAa,SAAS;AAEtC,QAAO,UADK,WAAW,SAAS,CAAC,OAAO,QAAQ,CAAC,OAAO,MAAM;;;;;AAOhE,SAAgB,sBAAgC;AAC9C,QAAO;EACL,SAAS;EACT,YAAY;EACZ,WAAW,EAAE;EACd;;;;;AAMH,SAAgB,aAAa,cAAgC;AAC3D,KAAI,CAAC,WAAW,aAAa,CAC3B,QAAO,qBAAqB;AAG9B,KAAI;EACF,MAAM,MAAM,KAAK,MAAM,aAAa,cAAc,QAAQ,CAAC;AAC3D,MAAI,IAAI,YAAY,KAAK,IAAI,eAAe,gBAAgB,OAAO,IAAI,cAAc,SACnF,QAAO;AAET,SAAO,qBAAqB;SACtB;AACN,SAAO,qBAAqB;;;;;;AAOhC,SAAgB,cAAc,cAAsB,UAA0B;AAC5E,WAAU,KAAK,cAAc,KAAK,EAAE,EAAE,WAAW,MAAM,CAAC;AACxD,eAAc,cAAc,KAAK,UAAU,UAAU,MAAM,EAAE,GAAG,MAAM,QAAQ;;;;;AAMhF,SAAgB,iBACd,UACA,cACA,MACA,QACM;AACN,UAAS,UAAU,gBAAgB;EACjC;EACA;EACA,+BAAc,IAAI,MAAM,EAAC,aAAa;EACvC;;;;;;;;;AAiBH,SAAgB,sBACd,YACA,cACA,UACY;AACZ,KAAI,CAAC,WAAW,WAAW,CACzB,QAAO,EAAE,QAAQ,OAAO;CAG1B,MAAM,QAAQ,SAAS,UAAU;AACjC,KAAI,CAAC,MACH,QAAO,EAAE,QAAQ,cAAc;CAGjC,MAAM,cAAc,SAAS,WAAW;AACxC,KAAI,gBAAgB,MAAM,KACxB,QAAO;EAAE,QAAQ;EAAU;EAAa;AAG1C,QAAO;EAAE,QAAQ;EAAY;EAAa,cAAc,MAAM;EAAM;;;;;;;;;;AAWtE,SAAgB,mBACd,WACA,QACuD;CACvD,MAAM,UAAiE,EAAE;AAEzE,KAAI,CAAC,WAAW,UAAU,CACxB,QAAO;CAGT,SAAS,KAAK,KAAmB;EAC/B,MAAM,UAAU,YAAY,KAAK,EAAE,eAAe,MAAM,CAAC;AACzD,OAAK,MAAM,SAAS,SAAS;GAC3B,MAAM,WAAW,KAAK,KAAK,MAAM,KAAK;AACtC,OAAI,MAAM,aAAa,CACrB,MAAK,SAAS;YACL,MAAM,QAAQ,EAAE;IACzB,MAAM,MAAM,SAAS,WAAW,SAAS;AACzC,YAAQ,KAAK;KACX,cAAc;KACd,cAAc,GAAG,SAAS;KAC3B,CAAC;;;;AAKR,MAAK,UAAU;AACf,QAAO;;;;;;;;;;AAWT,SAAgB,2BACd,SACA,YACA,QACU;CACV,MAAM,WAAW,qBAAqB;AAEtC,MAAK,MAAM,YAAY,YAAY;EAEjC,MAAM,QAAQ,mBADM,KAAK,SAAS,SAAS,EACG,GAAG,SAAS,GAAG;AAC7D,OAAK,MAAM,QAAQ,OAAO;GACxB,MAAM,OAAO,SAAS,KAAK,aAAa;AACxC,oBAAiB,UAAU,KAAK,cAAc,MAAM,OAAO;;;AAI/D,QAAO"}
@@ -1,19 +1,70 @@
1
- import { W as init_paths, b as PANOPTICON_HOME } from "./paths-lMaxrYtT.js";
2
- import { a as init_config } from "./config-CRzMQRgA.js";
3
- import { p as init_projects } from "./projects-CvLepaxC.js";
4
- import { o as init_tmux } from "./tmux-CKdNxxJx.js";
5
- import { n as resolveGitHubIssue } from "./tracker-utils-CVU2W1sX.js";
6
- import { j as init_specialists } from "./specialists-DEKqgkxp.js";
7
- import { appendFileSync } from "fs";
1
+ import { G as init_paths, b as PANOPTICON_HOME } from "./paths-CDJ_HsbN.js";
2
+ import { a as init_config } from "./config-BQNKsi9G.js";
3
+ import { p as init_projects } from "./projects-Bk-5QhFQ.js";
4
+ import { o as init_tmux } from "./tmux-D6Ah4I8z.js";
5
+ import { n as resolveGitHubIssue } from "./tracker-utils-ChQyut8w.js";
6
+ import { j as init_specialists } from "./specialists-D7Kj5o6s.js";
7
+ import "fs";
8
8
  import { basename, dirname, join } from "path";
9
9
  import { fileURLToPath } from "url";
10
10
  import { exec, spawn } from "child_process";
11
+ import { randomUUID } from "crypto";
11
12
  import { promisify } from "util";
12
13
  import { writeFile } from "fs/promises";
13
- //#region src/lib/cloister/validation.ts
14
+ //#region src/dashboard/server/event-store.ts
15
+ init_tmux();
14
16
  init_paths();
17
+ /**
18
+ * Synchronous accessor — returns the store if already initialized, throws otherwise.
19
+ * Used by legacy callers that expect a sync API (event-store unit tests, etc.)
20
+ */
21
+ function getEventStore() {
22
+ throw new Error("[event-store] getEventStore() called before initEventStore() resolved. Use initEventStore() for async initialization.");
23
+ }
24
+ //#endregion
25
+ //#region src/lib/activity-logger.ts
26
+ /**
27
+ * Shared activity logger — emits activity.entry events to the SQLite event store.
28
+ *
29
+ * Replaces flat-file logActivity() in merge-agent.ts and provides a unified
30
+ * activity logging API for all Panopticon components (merge-agent, cloister,
31
+ * specialists, dashboard).
32
+ *
33
+ * Activity entries are persisted to the event store and flow through:
34
+ * event store → PubSub → WebSocket → EventRouter → Zustand store → ActivityPanel
35
+ *
36
+ * Usage:
37
+ * import { emitActivityEntry } from '../lib/activity-logger.js';
38
+ * emitActivityEntry({ source: 'merge-agent', level: 'info', message: '...', issueId: 'PAN-123' });
39
+ */
40
+ /**
41
+ * Emit an activity.entry domain event to the SQLite event store.
42
+ * Non-blocking — throws silently if event store is not yet initialized.
43
+ *
44
+ * The event is persisted to SQLite immediately and PubSub notifies all
45
+ * WebSocket subscribers so the ActivityPanel updates in real-time.
46
+ */
47
+ function emitActivityEntry(options) {
48
+ try {
49
+ const store = getEventStore();
50
+ const entry = {
51
+ type: "activity.entry",
52
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
53
+ payload: {
54
+ id: randomUUID(),
55
+ source: options.source,
56
+ level: options.level,
57
+ message: options.message,
58
+ details: options.details ?? null,
59
+ issueId: options.issueId ?? null
60
+ }
61
+ };
62
+ store.append(entry);
63
+ } catch {}
64
+ }
65
+ //#endregion
66
+ //#region src/lib/cloister/validation.ts
15
67
  init_projects();
16
- init_tmux();
17
68
  init_specialists();
18
69
  /**
19
70
  * Merge Validation - Validation utilities for merge completeness
@@ -26,6 +77,9 @@ init_specialists();
26
77
  init_config();
27
78
  promisify(exec);
28
79
  promisify(exec);
80
+ //#endregion
81
+ //#region src/lib/cloister/merge-agent.ts
82
+ init_paths();
29
83
  promisify(exec);
30
84
  const __dirname = dirname(fileURLToPath(import.meta.url));
31
85
  join(join(join(PANOPTICON_HOME, "specialists"), "merge-agent"), "history.jsonl");
@@ -57,14 +111,17 @@ async function postMergeLifecycle(issueId, projectPath, sourceBranch, options) {
57
111
  issueId,
58
112
  projectPath,
59
113
  sourceBranch: sourceBranch ?? "",
60
- timestamp: Date.now()
114
+ timestamp: Date.now(),
115
+ reason: "post-merge",
116
+ trigger: "merge-agent"
61
117
  }), "utf-8");
62
118
  console.log(`[merge-agent] Wrote pending lifecycle file: ${pendingFile}`);
63
119
  const child = spawn(deployScript, [
64
120
  repoRoot,
65
121
  issueId,
66
122
  projectPath,
67
- sourceBranch ?? ""
123
+ sourceBranch ?? "",
124
+ "post-merge"
68
125
  ], {
69
126
  detached: true,
70
127
  stdio: "ignore"
@@ -78,7 +135,7 @@ async function postMergeLifecycle(issueId, projectPath, sourceBranch, options) {
78
135
  }
79
136
  console.log(`[merge-agent] Running post-merge cleanup for ${issueId}`);
80
137
  try {
81
- const { movePrd } = await import("./archive-planning-C3m3hfa5.js");
138
+ const { movePrd } = await import("./archive-planning-DK90wn9Q.js");
82
139
  const prdResult = await movePrd({
83
140
  issueId,
84
141
  projectPath
@@ -92,7 +149,7 @@ async function postMergeLifecycle(issueId, projectPath, sourceBranch, options) {
92
149
  console.warn(`[merge-agent] Could not move PRD: ${err}`);
93
150
  }
94
151
  try {
95
- const { cleanPlanningArtifacts } = await import("./clean-planning-sZXvy3Y5.js");
152
+ const { cleanPlanningArtifacts } = await import("./clean-planning-x1S-JdmO.js");
96
153
  const cleanResult = await cleanPlanningArtifacts({
97
154
  issueId,
98
155
  projectPath
@@ -106,7 +163,7 @@ async function postMergeLifecycle(issueId, projectPath, sourceBranch, options) {
106
163
  console.warn(`[merge-agent] Could not clean planning artifacts: ${err}`);
107
164
  }
108
165
  try {
109
- const { cleanupMergedLabels } = await import("./label-cleanup-31ElPqqv.js");
166
+ const { cleanupMergedLabels } = await import("./label-cleanup-C8R9Rspn.js");
110
167
  const ghResolved = resolveGitHubIssue(issueId);
111
168
  const labelResult = await cleanupMergedLabels(ghResolved.isGitHub ? {
112
169
  issueId,
@@ -130,7 +187,7 @@ async function postMergeLifecycle(issueId, projectPath, sourceBranch, options) {
130
187
  }
131
188
  closeIssueWithCircuitBreaker(issueId, projectPath);
132
189
  try {
133
- const { compactBeads } = await import("./compact-beads-iu218JcO.js");
190
+ const { compactBeads } = await import("./compact-beads-B0_qE1w3.js");
134
191
  const beadsResult = await compactBeads({
135
192
  issueId,
136
193
  projectPath
@@ -143,8 +200,8 @@ async function postMergeLifecycle(issueId, projectPath, sourceBranch, options) {
143
200
  console.warn(`[merge-agent] Beads compaction failed: ${err}`);
144
201
  }
145
202
  try {
146
- const { getAgentState, saveAgentState } = await import("./agents-BKsVoIc9.js");
147
- const { killSession, sessionExists } = await import("./tmux-DN6H886Y.js");
203
+ const { getAgentState, saveAgentState } = await import("./agents-D_2oRFVf.js");
204
+ const { killSession, sessionExists } = await import("./tmux-CBtui_Cl.js");
148
205
  const agentId = `agent-${issueId.toLowerCase()}`;
149
206
  const agentState = getAgentState(agentId);
150
207
  if (agentState && sessionExists(agentId)) {
@@ -163,8 +220,8 @@ async function postMergeLifecycle(issueId, projectPath, sourceBranch, options) {
163
220
  console.warn(`[merge-agent] Could not kill agent sessions: ${err}`);
164
221
  }
165
222
  try {
166
- const { findWorkspacePath } = await import("./archive-planning-C3m3hfa5.js");
167
- const { stopWorkspaceDocker } = await import("./workspace-manager-Cx0r2Jnv.js");
223
+ const { findWorkspacePath } = await import("./archive-planning-DK90wn9Q.js");
224
+ const { stopWorkspaceDocker } = await import("./workspace-manager-B9jS4Dsq.js");
168
225
  const issueLower = issueId.toLowerCase();
169
226
  const workspacePath = findWorkspacePath(projectPath, issueLower);
170
227
  if (workspacePath) {
@@ -194,7 +251,7 @@ function closeIssueWithCircuitBreaker(issueId, projectPath) {
194
251
  }
195
252
  (async () => {
196
253
  try {
197
- const { closeIssue } = await import("./close-issue-Dml437qV.js");
254
+ const { closeIssue } = await import("./close-issue-CjcfZI9s.js");
198
255
  const ghResolved = resolveGitHubIssue(issueId);
199
256
  const results = await closeIssue(ghResolved.isGitHub ? {
200
257
  issueId,
@@ -232,21 +289,17 @@ function closeIssueWithCircuitBreaker(issueId, projectPath) {
232
289
  })();
233
290
  }
234
291
  /**
235
- * Log activity to the dashboard activity log
292
+ * Log activity to the dashboard activity log (event-sourced via emitActivityEntry)
236
293
  */
237
- function logActivity(action, details) {
238
- const ACTIVITY_LOG = "/tmp/panopticon-activity.log";
239
- try {
240
- const entry = {
241
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
242
- source: "merge-agent",
243
- action,
244
- details
245
- };
246
- appendFileSync(ACTIVITY_LOG, JSON.stringify(entry) + "\n");
247
- } catch {}
294
+ function logActivity(action, details, issueId) {
295
+ emitActivityEntry({
296
+ source: "merge-agent",
297
+ level: action.includes("fail") || action.includes("error") ? "error" : action.includes("warn") ? "warn" : "success",
298
+ message: `[merge-agent] ${action}: ${details}`,
299
+ issueId
300
+ });
248
301
  }
249
302
  //#endregion
250
303
  export { postMergeLifecycle };
251
304
 
252
- //# sourceMappingURL=merge-agent-VQH9z9t8.js.map
305
+ //# sourceMappingURL=merge-agent-DlUiUanN.js.map