panopticon-cli 0.6.4 → 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.
- package/README.md +2 -2
- package/dist/{agents-DfYify9s.js → agents-CfFDs52G.js} +14 -14
- package/dist/{agents-DfYify9s.js.map → agents-CfFDs52G.js.map} +1 -1
- package/dist/{agents-BKsVoIc9.js → agents-D_2oRFVf.js} +1 -1
- package/dist/{archive-planning-BJrZ3tmN.js → archive-planning-D97ziGec.js} +3 -3
- package/dist/{archive-planning-BJrZ3tmN.js.map → archive-planning-D97ziGec.js.map} +1 -1
- package/dist/{archive-planning-C3m3hfa5.js → archive-planning-DK90wn9Q.js} +1 -1
- package/dist/{browser-Cvdznzc0.js → browser-CX7jXfXX.js} +1 -1
- package/dist/{browser-Cvdznzc0.js.map → browser-CX7jXfXX.js.map} +1 -1
- package/dist/{clean-planning-DvhZAUv4.js → clean-planning-D_lz4aQq.js} +2 -2
- package/dist/{clean-planning-DvhZAUv4.js.map → clean-planning-D_lz4aQq.js.map} +1 -1
- package/dist/clean-planning-x1S-JdmO.js +2 -0
- package/dist/cli/index.js +291 -760
- package/dist/cli/index.js.map +1 -1
- package/dist/{close-issue-Dr7yZmrr.js → close-issue-CaFE0stN.js} +11 -7
- package/dist/close-issue-CaFE0stN.js.map +1 -0
- package/dist/close-issue-CjcfZI9s.js +2 -0
- package/dist/compact-beads-B0_qE1w3.js +2 -0
- package/dist/{compact-beads-BCOtIIRl.js → compact-beads-CjFkteSU.js} +2 -2
- package/dist/{compact-beads-BCOtIIRl.js.map → compact-beads-CjFkteSU.js.map} +1 -1
- package/dist/{config-CRzMQRgA.js → config-BQNKsi9G.js} +2 -2
- package/dist/{config-CRzMQRgA.js.map → config-BQNKsi9G.js.map} +1 -1
- package/dist/{config-BYgUzQ21.js → config-agyKgF5C.js} +1 -1
- package/dist/{config-yaml-BgOACZAB.js → config-yaml-DGbLSMCa.js} +1 -1
- package/dist/{config-yaml-BgOACZAB.js.map → config-yaml-DGbLSMCa.js.map} +1 -1
- package/dist/{config-yaml-fdyvyL0S.js → config-yaml-Dqt4FWQH.js} +1 -1
- package/dist/dashboard/{acceptance-criteria-e5iiHlRx.js → acceptance-criteria-Dk9hhiYj.js} +1 -1
- package/dist/dashboard/{acceptance-criteria-e5iiHlRx.js.map → acceptance-criteria-Dk9hhiYj.js.map} +1 -1
- package/dist/dashboard/{agent-enrichment-C67LJBgD.js → agent-enrichment-DdO7ZqjI.js} +11 -7
- package/dist/dashboard/agent-enrichment-DdO7ZqjI.js.map +1 -0
- package/dist/dashboard/{agent-enrichment-Cq0P1cNZ.js → agent-enrichment-dLeGE1fX.js} +1 -1
- package/dist/dashboard/{agents-YyO6t5Xa.js → agents-DCpQQ_W5.js} +14 -14
- package/dist/dashboard/{agents-YyO6t5Xa.js.map → agents-DCpQQ_W5.js.map} +1 -1
- package/dist/dashboard/{agents-BVBVCyat.js → agents-Dgh2TjSp.js} +1 -1
- package/dist/dashboard/{archive-planning-h-hAjk0P.js → archive-planning-BmW9UDTr.js} +3 -3
- package/dist/dashboard/{archive-planning-h-hAjk0P.js.map → archive-planning-BmW9UDTr.js.map} +1 -1
- package/dist/dashboard/{archive-planning-CScs1MOC.js → archive-planning-C3Ebf9yC.js} +1 -1
- package/dist/dashboard/{beads-qNB0yAHV.js → beads-Bv-AdX7G.js} +3 -3
- package/dist/dashboard/{beads-qNB0yAHV.js.map → beads-Bv-AdX7G.js.map} +1 -1
- package/dist/dashboard/{beads-D_FRedEJ.js → beads-By6-X07V.js} +1 -1
- package/dist/dashboard/clean-planning-D60L8rPY.js +2 -0
- package/dist/dashboard/{clean-planning-qafw99vY.js → clean-planning-VEJu5suh.js} +2 -2
- package/dist/dashboard/{clean-planning-qafw99vY.js.map → clean-planning-VEJu5suh.js.map} +1 -1
- package/dist/dashboard/close-issue-C2KeSKKJ.js +2 -0
- package/dist/dashboard/{close-issue-DfIggeZD.js → close-issue-DtKdsSTm.js} +11 -7
- package/dist/dashboard/close-issue-DtKdsSTm.js.map +1 -0
- package/dist/dashboard/compact-beads-C7BN5N11.js +2 -0
- package/dist/dashboard/{compact-beads-Dt0qTqsC.js → compact-beads-D8Vt3qyv.js} +2 -2
- package/dist/dashboard/{compact-beads-Dt0qTqsC.js.map → compact-beads-D8Vt3qyv.js.map} +1 -1
- package/dist/dashboard/{config-CUREjHP7.js → config-CDkGjnwy.js} +2 -2
- package/dist/dashboard/{config-CUREjHP7.js.map → config-CDkGjnwy.js.map} +1 -1
- package/dist/dashboard/{config-BeI3uy-8.js → config-CTXkBATQ.js} +1 -1
- package/dist/dashboard/{database-CozA13Wy.js → database-DhqASALP.js} +1 -1
- package/dist/dashboard/{database-C0y0hXBx.js → database-cxmQryoh.js} +2 -2
- package/dist/dashboard/{database-C0y0hXBx.js.map → database-cxmQryoh.js.map} +1 -1
- package/dist/dashboard/{dist-src-oG2iHzgI.js → dist-src-DTm11oQr.js} +1 -1
- package/dist/dashboard/{dist-src-oG2iHzgI.js.map → dist-src-DTm11oQr.js.map} +1 -1
- package/dist/dashboard/{event-store-D7kLBd07.js → event-store-VWWUmOfn.js} +1 -1
- package/dist/dashboard/{event-store-O9q0Gweh.js → event-store-vSmAA3Zp.js} +9 -4
- package/dist/dashboard/event-store-vSmAA3Zp.js.map +1 -0
- package/dist/dashboard/{factory-BnLdiQW-.js → factory-C8nhLGHB.js} +3 -3
- package/dist/dashboard/{factory-BnLdiQW-.js.map → factory-C8nhLGHB.js.map} +1 -1
- package/dist/dashboard/{feedback-writer-DyovUANg.js → feedback-writer-CudSe1WK.js} +2 -2
- package/dist/dashboard/{feedback-writer-DyovUANg.js.map → feedback-writer-CudSe1WK.js.map} +1 -1
- package/dist/dashboard/{feedback-writer-gSUv_W0h.js → feedback-writer-Wgv1cd1r.js} +1 -1
- package/dist/dashboard/{git-utils-BJRioREj.js → git-utils-C1m4SwAe.js} +1 -1
- package/dist/dashboard/{git-utils-BJRioREj.js.map → git-utils-C1m4SwAe.js.map} +1 -1
- package/dist/dashboard/{git-utils-BtCRddq3.js → git-utils-DQI8EYoj.js} +1 -1
- package/dist/dashboard/{github-app-XO-LBUGk.js → github-app-DClWjjHr.js} +1 -1
- package/dist/dashboard/{github-app-XO-LBUGk.js.map → github-app-DClWjjHr.js.map} +1 -1
- package/dist/dashboard/{health-events-db-584nYgJB.js → health-events-db-BMXQfInV.js} +1 -1
- package/dist/dashboard/{health-events-db-B3ChzN65.js → health-events-db-Do4NrOhC.js} +2 -2
- package/dist/dashboard/{health-events-db-B3ChzN65.js.map → health-events-db-Do4NrOhC.js.map} +1 -1
- package/dist/dashboard/{hooks-CKhs3N68.js → hooks-CB4T47NC.js} +1 -1
- package/dist/dashboard/{hooks-CErbP8Oq.js → hooks-CjqXOlNb.js} +2 -2
- package/dist/dashboard/{hooks-CErbP8Oq.js.map → hooks-CjqXOlNb.js.map} +1 -1
- package/dist/dashboard/hume-CA2pftu_.js +3 -0
- package/dist/dashboard/{hume-CX_U3Qha.js → hume-JsAlMOJC.js} +2 -2
- package/dist/dashboard/{hume-CX_U3Qha.js.map → hume-JsAlMOJC.js.map} +1 -1
- package/dist/dashboard/{inspect-agent-B57kGDUV.js → inspect-agent-7eour7EA.js} +3 -3
- package/dist/dashboard/{inspect-agent-B57kGDUV.js.map → inspect-agent-7eour7EA.js.map} +1 -1
- package/dist/dashboard/{io-yGovuG4U.js → io-CWlFW78i.js} +1 -1
- package/dist/dashboard/{io-AJg-mzFi.js → io-DKS6359z.js} +1 -1
- package/dist/dashboard/{io-AJg-mzFi.js.map → io-DKS6359z.js.map} +1 -1
- package/dist/dashboard/issue-id-vwYJdsf8.js +62 -0
- package/dist/dashboard/issue-id-vwYJdsf8.js.map +1 -0
- package/dist/dashboard/{issue-service-singleton-DQK42EqH.js → issue-service-singleton-Co__-6kL.js} +1 -1
- package/dist/dashboard/{issue-service-singleton-sb2HkB9f.js → issue-service-singleton-Wv4xBm3y.js} +7 -7
- package/dist/dashboard/{issue-service-singleton-sb2HkB9f.js.map → issue-service-singleton-Wv4xBm3y.js.map} +1 -1
- package/dist/dashboard/{label-cleanup-CZEsbtq9.js → label-cleanup-nVKTmIIW.js} +7 -4
- package/dist/dashboard/label-cleanup-nVKTmIIW.js.map +1 -0
- package/dist/dashboard/lifecycle-BcUmtkR4.js +7 -0
- package/dist/dashboard/{merge-agent-GLtMEsTu.js → merge-agent-CGN3TT0a.js} +1 -1
- package/dist/dashboard/{merge-agent-twroFuAh.js → merge-agent-yudQOPZc.js} +148 -46
- package/dist/dashboard/merge-agent-yudQOPZc.js.map +1 -0
- package/dist/dashboard/{paths-COdEvoXR.js → paths-BDyJ7BiV.js} +19 -2
- package/dist/dashboard/{paths-COdEvoXR.js.map → paths-BDyJ7BiV.js.map} +1 -1
- package/dist/dashboard/{pipeline-notifier-DM5AHG5Q.js → pipeline-notifier-CCSN-jar.js} +1 -1
- package/dist/dashboard/{pipeline-notifier-DM5AHG5Q.js.map → pipeline-notifier-CCSN-jar.js.map} +1 -1
- package/dist/dashboard/{plan-utils-BkCIhn3B.js → plan-utils-Bkcsqr_s.js} +3 -3
- package/dist/dashboard/{plan-utils-BkCIhn3B.js.map → plan-utils-Bkcsqr_s.js.map} +1 -1
- package/dist/dashboard/{prd-draft-D09Afalc.js → prd-draft-BD8oMkZ1.js} +2 -2
- package/dist/dashboard/{prd-draft-D09Afalc.js.map → prd-draft-BD8oMkZ1.js.map} +1 -1
- package/dist/dashboard/{projection-cache-DQ9zegkK.js → projection-cache-C0EL8s8h.js} +1 -1
- package/dist/dashboard/{projection-cache-DQ9zegkK.js.map → projection-cache-C0EL8s8h.js.map} +1 -1
- package/dist/dashboard/{projects-DyT3vSy-.js → projects-C5ozxjwP.js} +1 -1
- package/dist/dashboard/{projects-Cq3TWdPS.js → projects-CFVl4oHn.js} +25 -13
- package/dist/dashboard/projects-CFVl4oHn.js.map +1 -0
- package/dist/dashboard/{providers-Ck2sQd_F.js → providers-B5Y4H2Mg.js} +4 -4
- package/dist/dashboard/providers-B5Y4H2Mg.js.map +1 -0
- package/dist/dashboard/{providers-DVQnDekG.js → providers-csVZVPkE.js} +1 -1
- package/dist/dashboard/public/assets/{dist-CCJbQrSB.js → dist-BaQPC-c6.js} +1 -1
- package/dist/dashboard/public/assets/index-ByLmYGhW.js +212 -0
- package/dist/dashboard/public/assets/index-OEEbThNN.css +1 -0
- package/dist/dashboard/public/index.html +2 -2
- package/dist/dashboard/rally-6McpKKRa.js +3 -0
- package/dist/dashboard/{rally-Cwuae-4C.js → rally-YjFRxIiC.js} +2 -2
- package/dist/dashboard/{rally-Cwuae-4C.js.map → rally-YjFRxIiC.js.map} +1 -1
- package/dist/dashboard/{rally-api-DSUxm7EO.js → rally-api-C0WqCSkT.js} +1 -1
- package/dist/dashboard/{rally-api-DSUxm7EO.js.map → rally-api-C0WqCSkT.js.map} +1 -1
- package/dist/dashboard/{rally-api-CEH5KZi4.js → rally-api-DNttdCW4.js} +1 -1
- package/dist/dashboard/{remote-BHTTMpJJ.js → remote-Cigqjj3f.js} +2 -2
- package/dist/dashboard/{remote-BXo_iIku.js → remote-ObpNZ7hF.js} +2 -2
- package/dist/dashboard/{remote-BXo_iIku.js.map → remote-ObpNZ7hF.js.map} +1 -1
- package/dist/dashboard/{remote-agents-CTKVhFFY.js → remote-agents-Bf3GuM7t.js} +1 -1
- package/dist/dashboard/{remote-agents-C0_0LLNd.js → remote-agents-DFyjT1Le.js} +1 -1
- package/dist/dashboard/{remote-agents-C0_0LLNd.js.map → remote-agents-DFyjT1Le.js.map} +1 -1
- package/dist/dashboard/{review-status-CK3eBGyb.js → review-status-BtXqWBhS.js} +1 -1
- package/dist/dashboard/{review-status-CV55Tl-n.js → review-status-Bymwzh2i.js} +44 -4
- package/dist/dashboard/{review-status-CV55Tl-n.js.map → review-status-Bymwzh2i.js.map} +1 -1
- package/dist/dashboard/server.js +565 -265
- package/dist/dashboard/server.js.map +1 -1
- package/dist/dashboard/{settings-CuHV-wcv.js → settings-BHlDG7TK.js} +2 -2
- package/dist/dashboard/settings-BHlDG7TK.js.map +1 -0
- package/dist/dashboard/settings-XWvDcj-D.js +2 -0
- package/dist/dashboard/{shadow-engineering-BUeZunaE.js → shadow-engineering-lIn1W_95.js} +1 -1
- package/dist/dashboard/{shadow-engineering-BUeZunaE.js.map → shadow-engineering-lIn1W_95.js.map} +1 -1
- package/dist/dashboard/{shadow-state-DHQ-kASN.js → shadow-state-BIexcxkv.js} +1 -1
- package/dist/dashboard/{shadow-state-DHQ-kASN.js.map → shadow-state-BIexcxkv.js.map} +1 -1
- package/dist/dashboard/{spawn-planning-session-8FFAqLdK.js → spawn-planning-session-33Jf-d5T.js} +6 -6
- package/dist/dashboard/{spawn-planning-session-8FFAqLdK.js.map → spawn-planning-session-33Jf-d5T.js.map} +1 -1
- package/dist/dashboard/{spawn-planning-session-U0Lqpjen.js → spawn-planning-session-D5hrVdWM.js} +1 -1
- package/dist/dashboard/{specialist-context-ColzlmGE.js → specialist-context-DGukHSn8.js} +6 -6
- package/dist/dashboard/{specialist-context-ColzlmGE.js.map → specialist-context-DGukHSn8.js.map} +1 -1
- package/dist/dashboard/{specialist-logs-BhmDpFIq.js → specialist-logs-CIw4qfTy.js} +1 -1
- package/dist/dashboard/{specialists-C6s3U6tX.js → specialists-B_zrayaP.js} +37 -36
- package/dist/dashboard/specialists-B_zrayaP.js.map +1 -0
- package/dist/dashboard/{specialists-Cny632-T.js → specialists-Cp-PgspS.js} +1 -1
- package/dist/dashboard/{test-agent-queue-tqI4VDsu.js → test-agent-queue-ypF_ecHo.js} +4 -4
- package/dist/dashboard/{test-agent-queue-tqI4VDsu.js.map → test-agent-queue-ypF_ecHo.js.map} +1 -1
- package/dist/dashboard/{tldr-daemon-BNFyS7W_.js → tldr-daemon-B_oLRD8z.js} +2 -2
- package/dist/dashboard/{tldr-daemon-BNFyS7W_.js.map → tldr-daemon-B_oLRD8z.js.map} +1 -1
- package/dist/dashboard/{tldr-daemon-A6JqC59u.js → tldr-daemon-Cfs0bXTi.js} +1 -1
- package/dist/dashboard/{tmux-DYGAVJfb.js → tmux-BzxdKItf.js} +1 -1
- package/dist/dashboard/{tmux-IlN1Slv-.js → tmux-LwG0tHhU.js} +2 -2
- package/dist/dashboard/{tmux-IlN1Slv-.js.map → tmux-LwG0tHhU.js.map} +1 -1
- package/dist/dashboard/{tracker-config-BzNLnmcE.js → tracker-config-BP59uH4V.js} +1 -1
- package/dist/dashboard/{tracker-config-CNM_5rEf.js → tracker-config-e7ph1QqT.js} +2 -2
- package/dist/dashboard/{tracker-config-CNM_5rEf.js.map → tracker-config-e7ph1QqT.js.map} +1 -1
- package/dist/dashboard/{tunnel-D2BkwU7k.js → tunnel-0RzzuXPf.js} +1 -1
- package/dist/dashboard/{tunnel-Dub2hiAA.js → tunnel-DldbBPWL.js} +2 -2
- package/dist/dashboard/{tunnel-Dub2hiAA.js.map → tunnel-DldbBPWL.js.map} +1 -1
- package/dist/dashboard/{types-CWA-o4UN.js → types-RKZjGE5N.js} +1 -1
- package/dist/dashboard/{types-CWA-o4UN.js.map → types-RKZjGE5N.js.map} +1 -1
- package/dist/dashboard/{vtt-parser-BAXygRf0.js → vtt-parser-99vFekRQ.js} +1 -1
- package/dist/dashboard/{vtt-parser-BAXygRf0.js.map → vtt-parser-99vFekRQ.js.map} +1 -1
- package/dist/dashboard/{work-agent-prompt-JYq_OugP.js → work-agent-prompt-fCg67nyo.js} +65 -10
- package/dist/dashboard/{work-agent-prompt-JYq_OugP.js.map → work-agent-prompt-fCg67nyo.js.map} +1 -1
- package/dist/dashboard/{work-type-router-Cxp8_ur2.js → work-type-router-CWVW2Wk_.js} +1 -1
- package/dist/dashboard/{work-type-router-Cxp8_ur2.js.map → work-type-router-CWVW2Wk_.js.map} +1 -1
- package/dist/dashboard/{work-type-router-Com2amST.js → work-type-router-Di5gCQwh.js} +1 -1
- package/dist/dashboard/{workflows-N1UTipYl.js → workflows-BSMipN07.js} +35 -17
- package/dist/dashboard/workflows-BSMipN07.js.map +1 -0
- package/dist/dashboard/workflows-DaYWQIS2.js +2 -0
- package/dist/dashboard/{workspace-config-cmp5_ipD.js → workspace-config-DVDR-Ukh.js} +1 -1
- package/dist/dashboard/workspace-config-DVDR-Ukh.js.map +1 -0
- package/dist/dashboard/{workspace-manager-CjpWPgzL.js → workspace-manager-BYfzs_t2.js} +1 -1
- package/dist/dashboard/{workspace-manager-D_y9ZmW_.js → workspace-manager-C7OfT62A.js} +44 -24
- package/dist/dashboard/workspace-manager-C7OfT62A.js.map +1 -0
- package/dist/{dns-BKzHm-2q.js → dns-D_aKQJjb.js} +1 -1
- package/dist/{dns-DZwOWvVO.js → dns-Yxq4NNS7.js} +1 -1
- package/dist/{dns-DZwOWvVO.js.map → dns-Yxq4NNS7.js.map} +1 -1
- package/dist/{factory-DFu3IT4r.js → factory-BRBGw6OB.js} +1 -1
- package/dist/{factory-DfzczxN1.js → factory-DzsOiZVc.js} +3 -3
- package/dist/{factory-DfzczxN1.js.map → factory-DzsOiZVc.js.map} +1 -1
- package/dist/{feedback-writer-CwdnOkPO.js → feedback-writer-ygXN5F9N.js} +2 -2
- package/dist/{feedback-writer-CwdnOkPO.js.map → feedback-writer-ygXN5F9N.js.map} +1 -1
- package/dist/{github-app-CHKwxOeQ.js → github-app-DykduJ0X.js} +1 -1
- package/dist/{github-app-CHKwxOeQ.js.map → github-app-DykduJ0X.js.map} +1 -1
- package/dist/hume-9nv1VmMV.js +3 -0
- package/dist/{hume-DnV-tDsh.js → hume-DoCbph2h.js} +2 -2
- package/dist/{hume-DnV-tDsh.js.map → hume-DoCbph2h.js.map} +1 -1
- package/dist/index.d.ts +17 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -7
- package/dist/issue-id-CAcekoIw.js +62 -0
- package/dist/issue-id-CAcekoIw.js.map +1 -0
- package/dist/{label-cleanup-31ElPqqv.js → label-cleanup-C8R9Rspn.js} +7 -4
- package/dist/label-cleanup-C8R9Rspn.js.map +1 -0
- package/dist/{manifest-DL0oDbpv.js → manifest-B4ghOD-V.js} +1 -1
- package/dist/{manifest-DL0oDbpv.js.map → manifest-B4ghOD-V.js.map} +1 -1
- package/dist/{merge-agent-VQH9z9t8.js → merge-agent-DlUiUanN.js} +86 -33
- package/dist/merge-agent-DlUiUanN.js.map +1 -0
- package/dist/{paths-lMaxrYtT.js → paths-CDJ_HsbN.js} +19 -2
- package/dist/{paths-lMaxrYtT.js.map → paths-CDJ_HsbN.js.map} +1 -1
- package/dist/{pipeline-notifier-OJ-d3Y60.js → pipeline-notifier-XgDdCdvT.js} +1 -1
- package/dist/{pipeline-notifier-OJ-d3Y60.js.map → pipeline-notifier-XgDdCdvT.js.map} +1 -1
- package/dist/{projects-CvLepaxC.js → projects-Bk-5QhFQ.js} +25 -13
- package/dist/projects-Bk-5QhFQ.js.map +1 -0
- package/dist/{projects-DMWmPeIU.js → projects-DhU7rAVN.js} +1 -1
- package/dist/{providers-DcCPZ5K4.js → providers-DSU1vfQF.js} +4 -4
- package/dist/providers-DSU1vfQF.js.map +1 -0
- package/dist/rally-DdPvGa-w.js +3 -0
- package/dist/{rally-uUUZXp1h.js → rally-Dy00NElU.js} +1 -1
- package/dist/{rally-uUUZXp1h.js.map → rally-Dy00NElU.js.map} +1 -1
- package/dist/{remote-CkLBqLJc.js → remote-CYiOJg0q.js} +2 -2
- package/dist/{remote-CkLBqLJc.js.map → remote-CYiOJg0q.js.map} +1 -1
- package/dist/{remote-agents-C5Bd2fgt.js → remote-agents-CZXrUF4f.js} +1 -1
- package/dist/{remote-agents-C5Bd2fgt.js.map → remote-agents-CZXrUF4f.js.map} +1 -1
- package/dist/{remote-agents-BTzD-wMQ.js → remote-agents-ycHHVsgf.js} +1 -1
- package/dist/{remote-workspace-Dxghqiti.js → remote-workspace-CA33UuVI.js} +4 -4
- package/dist/{remote-workspace-Dxghqiti.js.map → remote-workspace-CA33UuVI.js.map} +1 -1
- package/dist/{review-status-2TdtHNcs.js → review-status-D6H2WOw8.js} +1 -1
- package/dist/{review-status-Bm1bWNEa.js → review-status-DEDvCKMP.js} +44 -4
- package/dist/{review-status-Bm1bWNEa.js.map → review-status-DEDvCKMP.js.map} +1 -1
- package/dist/{tracker-C_62ukEq.js → settings-BcWPTrua.js} +7 -199
- package/dist/settings-BcWPTrua.js.map +1 -0
- package/dist/shadow-state-BZzxfEGw.js +2 -0
- package/dist/{shadow-state-CFFHf05M.js → shadow-state-CE3dQfll.js} +1 -1
- package/dist/{shadow-state-CFFHf05M.js.map → shadow-state-CE3dQfll.js.map} +1 -1
- package/dist/{specialist-context-BdNFsfMG.js → specialist-context-BAUWL1Fl.js} +6 -6
- package/dist/{specialist-context-BdNFsfMG.js.map → specialist-context-BAUWL1Fl.js.map} +1 -1
- package/dist/{specialist-logs-CLztE_bE.js → specialist-logs-DQKKQV9B.js} +1 -1
- package/dist/{specialists-aUoUVWsN.js → specialists-Bfb9ATzw.js} +1 -1
- package/dist/{specialists-DEKqgkxp.js → specialists-D7Kj5o6s.js} +35 -34
- package/dist/specialists-D7Kj5o6s.js.map +1 -0
- package/dist/sync-DMfgd389.js +693 -0
- package/dist/sync-DMfgd389.js.map +1 -0
- package/dist/sync-TL6y-8K6.js +2 -0
- package/dist/{tldr-daemon-BCEFPItr.js → tldr-daemon-CFx4LXAl.js} +2 -2
- package/dist/{tldr-daemon-BCEFPItr.js.map → tldr-daemon-CFx4LXAl.js.map} +1 -1
- package/dist/{tldr-daemon-xBAx4cBE.js → tldr-daemon-D_EooADG.js} +1 -1
- package/dist/{tmux-DN6H886Y.js → tmux-CBtui_Cl.js} +1 -1
- package/dist/{tmux-CKdNxxJx.js → tmux-D6Ah4I8z.js} +2 -2
- package/dist/{tmux-CKdNxxJx.js.map → tmux-D6Ah4I8z.js.map} +1 -1
- package/dist/tracker-BhYYvU3p.js +198 -0
- package/dist/tracker-BhYYvU3p.js.map +1 -0
- package/dist/{tracker-utils-CVU2W1sX.js → tracker-utils-ChQyut8w.js} +34 -12
- package/dist/tracker-utils-ChQyut8w.js.map +1 -0
- package/dist/{traefik-DHgBoWXX.js → traefik-C80EbDu_.js} +4 -4
- package/dist/{traefik-DHgBoWXX.js.map → traefik-C80EbDu_.js.map} +1 -1
- package/dist/{traefik-BR-edbZv.js → traefik-CgHl7Bge.js} +1 -1
- package/dist/{tunnel-BZO9Q5oe.js → tunnel-DXOJ1wMM.js} +1 -1
- package/dist/{tunnel-Bl1qNSyQ.js → tunnel-DzXEPwIc.js} +2 -2
- package/dist/{tunnel-Bl1qNSyQ.js.map → tunnel-DzXEPwIc.js.map} +1 -1
- package/dist/{types-DewGdaIP.js → types-BhJj1SP1.js} +1 -1
- package/dist/{types-DewGdaIP.js.map → types-BhJj1SP1.js.map} +1 -1
- package/dist/{work-type-router-CS2BB1vS.js → work-type-router-CHjciPyS.js} +3 -3
- package/dist/{work-type-router-CS2BB1vS.js.map → work-type-router-CHjciPyS.js.map} +1 -1
- package/dist/{workspace-config-CNXOpKuj.js → workspace-config-fUafvYMp.js} +1 -1
- package/dist/workspace-config-fUafvYMp.js.map +1 -0
- package/dist/workspace-manager-B9jS4Dsq.js +3 -0
- package/dist/{workspace-manager-CncdZkIy.js → workspace-manager-DuLhnzJV.js} +112 -27
- package/dist/workspace-manager-DuLhnzJV.js.map +1 -0
- package/package.json +2 -1
- package/scripts/post-merge-deploy.sh +25 -5
- package/scripts/record-cost-event.js +57 -7
- package/scripts/record-cost-event.js.map +1 -1
- package/skills/pan-help/SKILL.md +1 -1
- package/skills/pan-sync/SKILL.md +6 -6
- package/skills/workspace-add-repo/skill.md +46 -0
- package/templates/claude-md/sections/warnings.md +15 -2
- package/dist/clean-planning-sZXvy3Y5.js +0 -2
- package/dist/close-issue-Dml437qV.js +0 -2
- package/dist/close-issue-Dr7yZmrr.js.map +0 -1
- package/dist/compact-beads-iu218JcO.js +0 -2
- package/dist/dashboard/agent-enrichment-C67LJBgD.js.map +0 -1
- package/dist/dashboard/clean-planning-DCu3cOTu.js +0 -2
- package/dist/dashboard/close-issue-DfIggeZD.js.map +0 -1
- package/dist/dashboard/close-issue-DwdwYtar.js +0 -2
- package/dist/dashboard/compact-beads-DXY2fK2s.js +0 -2
- package/dist/dashboard/event-store-O9q0Gweh.js.map +0 -1
- package/dist/dashboard/hume-MZndNDVU.js +0 -3
- package/dist/dashboard/label-cleanup-CZEsbtq9.js.map +0 -1
- package/dist/dashboard/lifecycle-ZTYdrr2O.js +0 -7
- package/dist/dashboard/merge-agent-twroFuAh.js.map +0 -1
- package/dist/dashboard/projects-Cq3TWdPS.js.map +0 -1
- package/dist/dashboard/providers-Ck2sQd_F.js.map +0 -1
- package/dist/dashboard/public/assets/index-CpSmB2ts.css +0 -1
- package/dist/dashboard/public/assets/index-yarWhi0M.js +0 -214
- package/dist/dashboard/rally-CQ1OBJrJ.js +0 -3
- package/dist/dashboard/settings-CuHV-wcv.js.map +0 -1
- package/dist/dashboard/settings-DMeGBRsk.js +0 -2
- package/dist/dashboard/specialists-C6s3U6tX.js.map +0 -1
- package/dist/dashboard/workflows-B2ARUpOa.js +0 -2
- package/dist/dashboard/workflows-N1UTipYl.js.map +0 -1
- package/dist/dashboard/workspace-config-cmp5_ipD.js.map +0 -1
- package/dist/dashboard/workspace-manager-D_y9ZmW_.js.map +0 -1
- package/dist/hume-BjmwmJ9E.js +0 -3
- package/dist/label-cleanup-31ElPqqv.js.map +0 -1
- package/dist/merge-agent-VQH9z9t8.js.map +0 -1
- package/dist/projects-CvLepaxC.js.map +0 -1
- package/dist/providers-DcCPZ5K4.js.map +0 -1
- package/dist/rally-DR9x8--6.js +0 -3
- package/dist/shadow-state-p3jpGRPJ.js +0 -2
- package/dist/specialists-DEKqgkxp.js.map +0 -1
- package/dist/tracker-C_62ukEq.js.map +0 -1
- package/dist/tracker-utils-CVU2W1sX.js.map +0 -1
- package/dist/workspace-config-CNXOpKuj.js.map +0 -1
- package/dist/workspace-manager-CncdZkIy.js.map +0 -1
- package/dist/workspace-manager-Cx0r2Jnv.js +0 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dns-DZwOWvVO.js","names":[],"sources":["../src/lib/platform.ts","../src/lib/dns.ts"],"sourcesContent":["/**\n * Platform Detection\n *\n * Shared platform detection utility. Distinguishes between\n * native Linux, macOS, Windows, and WSL2.\n */\n\nimport { readFileSync } from 'fs';\nimport { platform } from 'os';\n\nexport type Platform = 'linux' | 'darwin' | 'win32' | 'wsl';\n\nexport function detectPlatform(): Platform {\n const os = platform();\n if (os === 'linux') {\n // Check for WSL\n try {\n const release = readFileSync('/proc/version', 'utf8').toLowerCase();\n if (release.includes('microsoft') || release.includes('wsl')) {\n return 'wsl';\n }\n } catch {}\n return 'linux';\n }\n return os as 'darwin' | 'win32';\n}\n","/**\n * DNS Management\n *\n * Centralized DNS entry management for Panopticon.\n * Supports three sync methods:\n * - wsl2hosts: WSL2 → Windows hosts file sync via PowerShell scheduled task\n * - hosts_file: Direct /etc/hosts manipulation with managed block markers\n * - dnsmasq: System-wide dnsmasq configuration (Linux/macOS)\n */\n\nimport { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\nimport { exec, execSync } from 'child_process';\nimport { promisify } from 'util';\nimport { detectPlatform } from './platform.js';\n\nconst execAsync = promisify(exec);\n\nexport type DnsSyncMethod = 'wsl2hosts' | 'hosts_file' | 'dnsmasq';\n\n// ---- Detection ----\n\n/**\n * Detect the best DNS sync method for the current platform.\n */\nexport function detectDnsSyncMethod(): DnsSyncMethod {\n const plat = detectPlatform();\n switch (plat) {\n case 'wsl':\n return 'wsl2hosts';\n case 'darwin':\n return isDnsmasqInstalled() ? 'dnsmasq' : 'hosts_file';\n case 'linux':\n return isDnsmasqInstalled() ? 'dnsmasq' : 'hosts_file';\n default:\n return 'hosts_file';\n }\n}\n\n/**\n * Check if dnsmasq is installed.\n * Note: Uses execSync intentionally — this only runs in CLI context (pan install/up),\n * never from the dashboard server.\n */\nfunction isDnsmasqInstalled(): boolean {\n try {\n execSync('which dnsmasq', { stdio: 'pipe' });\n return true;\n } catch {\n return false;\n }\n}\n\n// ---- wsl2hosts method ----\n\nexport function addWsl2HostEntry(hostname: string): boolean {\n const wsl2hostsPath = join(homedir(), '.wsl2hosts');\n\n try {\n let content = '';\n if (existsSync(wsl2hostsPath)) {\n content = readFileSync(wsl2hostsPath, 'utf-8');\n }\n\n if (!content.includes(hostname)) {\n writeFileSync(wsl2hostsPath, content + (content.endsWith('\\n') ? '' : '\\n') + hostname + '\\n');\n }\n return true;\n } catch {\n return false;\n }\n}\n\nexport function removeWsl2HostEntry(hostname: string): boolean {\n const wsl2hostsPath = join(homedir(), '.wsl2hosts');\n\n try {\n if (!existsSync(wsl2hostsPath)) return true;\n\n const content = readFileSync(wsl2hostsPath, 'utf-8');\n const lines = content.split('\\n').filter(line => line.trim() !== hostname);\n writeFileSync(wsl2hostsPath, lines.join('\\n'));\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function syncDnsToWindows(): Promise<boolean> {\n try {\n await execAsync('powershell.exe -Command \"Start-ScheduledTask -TaskName \\'PanopticonWsl2HostsSync\\'\"');\n return true;\n } catch {\n // Fall back to legacy task name\n try {\n await execAsync('powershell.exe -Command \"Start-ScheduledTask -TaskName \\'SyncMynHosts\\'\"');\n return true;\n } catch {\n return false;\n }\n }\n}\n\n// ---- hosts_file method ----\n\nconst HOSTS_FILE = '/etc/hosts';\nconst MARKER_START = '# BEGIN panopticon managed entries';\nconst MARKER_END = '# END panopticon managed entries';\n\nexport function addHostsFileEntry(hostname: string, ip: string = '127.0.0.1'): boolean {\n try {\n let content = existsSync(HOSTS_FILE) ? readFileSync(HOSTS_FILE, 'utf-8') : '';\n const entry = `${ip}\\t${hostname}`;\n\n // Already present anywhere in file\n if (content.includes(`\\t${hostname}`) || content.includes(` ${hostname}`)) return true;\n\n const startIdx = content.indexOf(MARKER_START);\n const endIdx = content.indexOf(MARKER_END);\n\n if (startIdx !== -1 && endIdx !== -1) {\n // Managed block exists — insert entry before MARKER_END\n const before = content.substring(0, endIdx);\n const after = content.substring(endIdx);\n content = before + entry + '\\n' + after;\n } else {\n // Create managed block at end\n content = content.trimEnd() + '\\n\\n' + MARKER_START + '\\n' + entry + '\\n' + MARKER_END + '\\n';\n }\n\n writeFileSync(HOSTS_FILE, content);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function removeHostsFileEntry(hostname: string): boolean {\n try {\n if (!existsSync(HOSTS_FILE)) return true;\n\n const content = readFileSync(HOSTS_FILE, 'utf-8');\n const lines = content.split('\\n').filter(line => {\n const parts = line.trim().split(/\\s+/);\n return parts[1] !== hostname;\n });\n writeFileSync(HOSTS_FILE, lines.join('\\n'));\n return true;\n } catch {\n return false;\n }\n}\n\n// ---- dnsmasq method ----\n\nfunction getDnsmasqConfigDir(): string {\n const plat = detectPlatform();\n if (plat === 'darwin') {\n // Homebrew Intel location; Apple Silicon uses /opt/homebrew/etc/dnsmasq.d\n const brewPrefix = existsSync('/opt/homebrew') ? '/opt/homebrew' : '/usr/local';\n return `${brewPrefix}/etc/dnsmasq.d`;\n }\n return '/etc/dnsmasq.d';\n}\n\nconst PANOPTICON_DNSMASQ_CONF = 'panopticon.conf';\n\nexport function addDnsmasqEntry(hostname: string, ip: string = '127.0.0.1'): boolean {\n try {\n const configDir = getDnsmasqConfigDir();\n mkdirSync(configDir, { recursive: true });\n const confPath = join(configDir, PANOPTICON_DNSMASQ_CONF);\n\n let content = '';\n if (existsSync(confPath)) {\n content = readFileSync(confPath, 'utf-8');\n }\n\n const entry = `address=/${hostname}/${ip}`;\n if (content.includes(entry)) return true;\n\n content = content.trimEnd() + (content.length > 0 ? '\\n' : '') + entry + '\\n';\n writeFileSync(confPath, content);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function removeDnsmasqEntry(hostname: string): boolean {\n try {\n const configDir = getDnsmasqConfigDir();\n const confPath = join(configDir, PANOPTICON_DNSMASQ_CONF);\n if (!existsSync(confPath)) return true;\n\n const content = readFileSync(confPath, 'utf-8');\n const lines = content.split('\\n').filter(line => !line.includes(`/${hostname}/`));\n writeFileSync(confPath, lines.join('\\n'));\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function restartDnsmasq(): Promise<boolean> {\n const plat = detectPlatform();\n try {\n if (plat === 'darwin') {\n await execAsync('brew services restart dnsmasq');\n } else {\n await execAsync('sudo systemctl restart dnsmasq');\n }\n return true;\n } catch {\n return false;\n }\n}\n\n// ---- Unified interface ----\n\n/**\n * Add a DNS entry using the specified sync method.\n */\nexport function addDnsEntry(method: DnsSyncMethod, hostname: string): boolean {\n switch (method) {\n case 'wsl2hosts':\n return addWsl2HostEntry(hostname);\n case 'hosts_file':\n return addHostsFileEntry(hostname);\n case 'dnsmasq':\n return addDnsmasqEntry(hostname);\n }\n}\n\n/**\n * Remove a DNS entry using the specified sync method.\n */\nexport function removeDnsEntry(method: DnsSyncMethod, hostname: string): boolean {\n switch (method) {\n case 'wsl2hosts':\n return removeWsl2HostEntry(hostname);\n case 'hosts_file':\n return removeHostsFileEntry(hostname);\n case 'dnsmasq':\n return removeDnsmasqEntry(hostname);\n }\n}\n\n/**\n * Ensure the base Panopticon domain is resolvable.\n * Called during `pan install` and `pan up`.\n */\nexport function ensureBaseDomain(method: DnsSyncMethod, domain: string = 'pan.localhost'): boolean {\n return addDnsEntry(method, domain);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dns-Yxq4NNS7.js","names":[],"sources":["../src/lib/platform.ts","../src/lib/dns.ts"],"sourcesContent":["/**\n * Platform Detection\n *\n * Shared platform detection utility. Distinguishes between\n * native Linux, macOS, Windows, and WSL2.\n */\n\nimport { readFileSync } from 'fs';\nimport { platform } from 'os';\n\nexport type Platform = 'linux' | 'darwin' | 'win32' | 'wsl';\n\nexport function detectPlatform(): Platform {\n const os = platform();\n if (os === 'linux') {\n // Check for WSL\n try {\n const release = readFileSync('/proc/version', 'utf8').toLowerCase();\n if (release.includes('microsoft') || release.includes('wsl')) {\n return 'wsl';\n }\n } catch {}\n return 'linux';\n }\n return os as 'darwin' | 'win32';\n}\n","/**\n * DNS Management\n *\n * Centralized DNS entry management for Panopticon.\n * Supports three sync methods:\n * - wsl2hosts: WSL2 → Windows hosts file sync via PowerShell scheduled task\n * - hosts_file: Direct /etc/hosts manipulation with managed block markers\n * - dnsmasq: System-wide dnsmasq configuration (Linux/macOS)\n */\n\nimport { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\nimport { exec, execSync } from 'child_process';\nimport { promisify } from 'util';\nimport { detectPlatform } from './platform.js';\n\nconst execAsync = promisify(exec);\n\nexport type DnsSyncMethod = 'wsl2hosts' | 'hosts_file' | 'dnsmasq';\n\n// ---- Detection ----\n\n/**\n * Detect the best DNS sync method for the current platform.\n */\nexport function detectDnsSyncMethod(): DnsSyncMethod {\n const plat = detectPlatform();\n switch (plat) {\n case 'wsl':\n return 'wsl2hosts';\n case 'darwin':\n return isDnsmasqInstalled() ? 'dnsmasq' : 'hosts_file';\n case 'linux':\n return isDnsmasqInstalled() ? 'dnsmasq' : 'hosts_file';\n default:\n return 'hosts_file';\n }\n}\n\n/**\n * Check if dnsmasq is installed.\n * Note: Uses execSync intentionally — this only runs in CLI context (pan install/up),\n * never from the dashboard server.\n */\nfunction isDnsmasqInstalled(): boolean {\n try {\n execSync('which dnsmasq', { stdio: 'pipe' });\n return true;\n } catch {\n return false;\n }\n}\n\n// ---- wsl2hosts method ----\n\nexport function addWsl2HostEntry(hostname: string): boolean {\n const wsl2hostsPath = join(homedir(), '.wsl2hosts');\n\n try {\n let content = '';\n if (existsSync(wsl2hostsPath)) {\n content = readFileSync(wsl2hostsPath, 'utf-8');\n }\n\n if (!content.includes(hostname)) {\n writeFileSync(wsl2hostsPath, content + (content.endsWith('\\n') ? '' : '\\n') + hostname + '\\n');\n }\n return true;\n } catch {\n return false;\n }\n}\n\nexport function removeWsl2HostEntry(hostname: string): boolean {\n const wsl2hostsPath = join(homedir(), '.wsl2hosts');\n\n try {\n if (!existsSync(wsl2hostsPath)) return true;\n\n const content = readFileSync(wsl2hostsPath, 'utf-8');\n const lines = content.split('\\n').filter(line => line.trim() !== hostname);\n writeFileSync(wsl2hostsPath, lines.join('\\n'));\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function syncDnsToWindows(): Promise<boolean> {\n try {\n await execAsync('powershell.exe -Command \"Start-ScheduledTask -TaskName \\'PanopticonWsl2HostsSync\\'\"');\n return true;\n } catch {\n // Fall back to legacy task name\n try {\n await execAsync('powershell.exe -Command \"Start-ScheduledTask -TaskName \\'SyncMynHosts\\'\"');\n return true;\n } catch {\n return false;\n }\n }\n}\n\n// ---- hosts_file method ----\n\nconst HOSTS_FILE = '/etc/hosts';\nconst MARKER_START = '# BEGIN panopticon managed entries';\nconst MARKER_END = '# END panopticon managed entries';\n\nexport function addHostsFileEntry(hostname: string, ip: string = '127.0.0.1'): boolean {\n try {\n let content = existsSync(HOSTS_FILE) ? readFileSync(HOSTS_FILE, 'utf-8') : '';\n const entry = `${ip}\\t${hostname}`;\n\n // Already present anywhere in file\n if (content.includes(`\\t${hostname}`) || content.includes(` ${hostname}`)) return true;\n\n const startIdx = content.indexOf(MARKER_START);\n const endIdx = content.indexOf(MARKER_END);\n\n if (startIdx !== -1 && endIdx !== -1) {\n // Managed block exists — insert entry before MARKER_END\n const before = content.substring(0, endIdx);\n const after = content.substring(endIdx);\n content = before + entry + '\\n' + after;\n } else {\n // Create managed block at end\n content = content.trimEnd() + '\\n\\n' + MARKER_START + '\\n' + entry + '\\n' + MARKER_END + '\\n';\n }\n\n writeFileSync(HOSTS_FILE, content);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function removeHostsFileEntry(hostname: string): boolean {\n try {\n if (!existsSync(HOSTS_FILE)) return true;\n\n const content = readFileSync(HOSTS_FILE, 'utf-8');\n const lines = content.split('\\n').filter(line => {\n const parts = line.trim().split(/\\s+/);\n return parts[1] !== hostname;\n });\n writeFileSync(HOSTS_FILE, lines.join('\\n'));\n return true;\n } catch {\n return false;\n }\n}\n\n// ---- dnsmasq method ----\n\nfunction getDnsmasqConfigDir(): string {\n const plat = detectPlatform();\n if (plat === 'darwin') {\n // Homebrew Intel location; Apple Silicon uses /opt/homebrew/etc/dnsmasq.d\n const brewPrefix = existsSync('/opt/homebrew') ? '/opt/homebrew' : '/usr/local';\n return `${brewPrefix}/etc/dnsmasq.d`;\n }\n return '/etc/dnsmasq.d';\n}\n\nconst PANOPTICON_DNSMASQ_CONF = 'panopticon.conf';\n\nexport function addDnsmasqEntry(hostname: string, ip: string = '127.0.0.1'): boolean {\n try {\n const configDir = getDnsmasqConfigDir();\n mkdirSync(configDir, { recursive: true });\n const confPath = join(configDir, PANOPTICON_DNSMASQ_CONF);\n\n let content = '';\n if (existsSync(confPath)) {\n content = readFileSync(confPath, 'utf-8');\n }\n\n const entry = `address=/${hostname}/${ip}`;\n if (content.includes(entry)) return true;\n\n content = content.trimEnd() + (content.length > 0 ? '\\n' : '') + entry + '\\n';\n writeFileSync(confPath, content);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function removeDnsmasqEntry(hostname: string): boolean {\n try {\n const configDir = getDnsmasqConfigDir();\n const confPath = join(configDir, PANOPTICON_DNSMASQ_CONF);\n if (!existsSync(confPath)) return true;\n\n const content = readFileSync(confPath, 'utf-8');\n const lines = content.split('\\n').filter(line => !line.includes(`/${hostname}/`));\n writeFileSync(confPath, lines.join('\\n'));\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function restartDnsmasq(): Promise<boolean> {\n const plat = detectPlatform();\n try {\n if (plat === 'darwin') {\n await execAsync('brew services restart dnsmasq');\n } else {\n await execAsync('sudo systemctl restart dnsmasq');\n }\n return true;\n } catch {\n return false;\n }\n}\n\n// ---- Unified interface ----\n\n/**\n * Add a DNS entry using the specified sync method.\n */\nexport function addDnsEntry(method: DnsSyncMethod, hostname: string): boolean {\n switch (method) {\n case 'wsl2hosts':\n return addWsl2HostEntry(hostname);\n case 'hosts_file':\n return addHostsFileEntry(hostname);\n case 'dnsmasq':\n return addDnsmasqEntry(hostname);\n }\n}\n\n/**\n * Remove a DNS entry using the specified sync method.\n */\nexport function removeDnsEntry(method: DnsSyncMethod, hostname: string): boolean {\n switch (method) {\n case 'wsl2hosts':\n return removeWsl2HostEntry(hostname);\n case 'hosts_file':\n return removeHostsFileEntry(hostname);\n case 'dnsmasq':\n return removeDnsmasqEntry(hostname);\n }\n}\n\n/**\n * Ensure the base Panopticon domain is resolvable.\n * Called during `pan install` and `pan up`.\n */\nexport function ensureBaseDomain(method: DnsSyncMethod, domain: string = 'pan.localhost'): boolean {\n return addDnsEntry(method, domain);\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as __esmMin } from "./chunk-ruWRV7i3.js";
|
|
2
|
-
import { n as init_config_yaml, r as loadConfig } from "./config-yaml-
|
|
3
|
-
import { a as TrackerAuthError, i as NotImplementedError, n as init_rally, o as init_interface, r as IssueNotFoundError, t as RallyTracker } from "./rally-
|
|
2
|
+
import { n as init_config_yaml, r as loadConfig } from "./config-yaml-DGbLSMCa.js";
|
|
3
|
+
import { a as TrackerAuthError, i as NotImplementedError, n as init_rally, o as init_interface, r as IssueNotFoundError, t as RallyTracker } from "./rally-Dy00NElU.js";
|
|
4
4
|
import { LinearClient } from "@linear/sdk";
|
|
5
5
|
import { Octokit } from "@octokit/rest";
|
|
6
6
|
//#region src/lib/tracker/linear.ts
|
|
@@ -524,4 +524,4 @@ var init_factory = __esmMin((() => {
|
|
|
524
524
|
//#endregion
|
|
525
525
|
export { getSecondaryTracker as a, init_gitlab as c, LinearTracker as d, init_linear as f, getPrimaryTracker as i, GitHubTracker as l, createTrackerFromConfig as n, init_factory as o, getAllTrackers as r, GitLabTracker as s, createTracker as t, init_github as u };
|
|
526
526
|
|
|
527
|
-
//# sourceMappingURL=factory-
|
|
527
|
+
//# sourceMappingURL=factory-DzsOiZVc.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory-DfzczxN1.js","names":["loadYamlConfig"],"sources":["../src/lib/tracker/linear.ts","../src/lib/tracker/github.ts","../src/lib/tracker/gitlab.ts","../src/lib/tracker/factory.ts"],"sourcesContent":["/**\n * Linear Issue Tracker Adapter\n *\n * Implements IssueTracker interface for Linear.\n */\n\nimport { LinearClient } from '@linear/sdk';\nimport type {\n Issue,\n IssueFilters,\n IssueState,\n IssueTracker,\n IssueUpdate,\n NewIssue,\n Comment,\n TrackerType,\n} from './interface.js';\nimport { IssueNotFoundError, TrackerAuthError } from './interface.js';\n\n// Map Linear state types to our normalized states\nconst STATE_MAP: Record<string, IssueState> = {\n backlog: 'open',\n unstarted: 'open',\n started: 'in_progress',\n completed: 'closed',\n canceled: 'closed',\n};\n\nexport class LinearTracker implements IssueTracker {\n readonly name: TrackerType = 'linear';\n private client: LinearClient;\n private defaultTeam?: string;\n\n constructor(apiKey: string, options?: { team?: string }) {\n if (!apiKey) {\n throw new TrackerAuthError('linear', 'API key is required');\n }\n this.client = new LinearClient({ apiKey });\n this.defaultTeam = options?.team;\n }\n\n async listIssues(filters?: IssueFilters): Promise<Issue[]> {\n const team = filters?.team ?? this.defaultTeam;\n\n const result = await this.client.issues({\n first: filters?.limit ?? 50,\n filter: {\n team: team ? { key: { eq: team } } : undefined,\n state: filters?.state\n ? { type: { eq: this.reverseMapState(filters.state) } }\n : filters?.includeClosed\n ? undefined\n : { type: { neq: 'completed' } },\n labels: filters?.labels?.length\n ? { name: { in: filters.labels } }\n : undefined,\n assignee: filters?.assignee\n ? { name: { containsIgnoreCase: filters.assignee } }\n : undefined,\n },\n });\n\n const issues: Issue[] = [];\n for (const node of result.nodes) {\n issues.push(await this.normalizeIssue(node));\n }\n return issues;\n }\n\n async getIssue(id: string): Promise<Issue> {\n try {\n // Check if it's a UUID (36 chars with hyphens)\n const isUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id);\n\n if (isUuid) {\n // Fetch directly by UUID\n const issue = await this.client.issue(id);\n if (issue) {\n return this.normalizeIssue(issue);\n }\n } else {\n // Parse identifier (e.g., MIN-630) and search\n const match = id.match(/^([A-Z]+)-(\\d+)$/i);\n if (match) {\n const [, teamKey, number] = match;\n // Use searchIssues which supports identifier matching\n const results = await this.client.searchIssues(id, { first: 1 });\n if (results.nodes.length > 0) {\n return this.normalizeIssue(results.nodes[0]);\n }\n }\n }\n\n throw new IssueNotFoundError(id, 'linear');\n } catch (error) {\n if (error instanceof IssueNotFoundError) throw error;\n throw new IssueNotFoundError(id, 'linear');\n }\n }\n\n async updateIssue(id: string, update: IssueUpdate): Promise<Issue> {\n const issue = await this.getIssue(id);\n\n const updatePayload: Record<string, unknown> = {};\n\n if (update.title !== undefined) {\n updatePayload.title = update.title;\n }\n if (update.description !== undefined) {\n updatePayload.description = update.description;\n }\n if (update.priority !== undefined) {\n updatePayload.priority = update.priority;\n }\n if (update.dueDate !== undefined) {\n updatePayload.dueDate = update.dueDate;\n }\n if (update.state !== undefined) {\n // Need to find the state ID - this is complex in Linear\n // For now, we'll use the transition method\n await this.transitionIssue(id, update.state);\n }\n if (update.labels !== undefined) {\n // Need to look up label IDs - complex operation\n // TODO: Implement label updates\n }\n\n if (Object.keys(updatePayload).length > 0) {\n await this.client.updateIssue(issue.id, updatePayload);\n }\n\n return this.getIssue(id);\n }\n\n async createIssue(newIssue: NewIssue): Promise<Issue> {\n const team = newIssue.team ?? this.defaultTeam;\n\n if (!team) {\n throw new Error('Team is required to create an issue');\n }\n\n // Get team ID from key\n const teams = await this.client.teams({\n filter: { key: { eq: team } },\n });\n\n if (teams.nodes.length === 0) {\n throw new Error(`Team not found: ${team}`);\n }\n\n const teamId = teams.nodes[0].id;\n\n const result = await this.client.createIssue({\n teamId,\n title: newIssue.title,\n description: newIssue.description,\n priority: newIssue.priority,\n dueDate: newIssue.dueDate,\n });\n\n const created = await result.issue;\n if (!created) {\n throw new Error('Failed to create issue');\n }\n\n return this.normalizeIssue(created);\n }\n\n async getComments(issueId: string): Promise<Comment[]> {\n const issue = await this.client.issue(issueId);\n const comments = await issue.comments();\n\n return comments.nodes.map((c) => ({\n id: c.id,\n issueId,\n body: c.body,\n author: c.user?.then((u) => u?.name ?? 'Unknown') as unknown as string, // Simplified\n createdAt: c.createdAt.toISOString(),\n updatedAt: c.updatedAt.toISOString(),\n }));\n }\n\n async addComment(issueId: string, body: string): Promise<Comment> {\n const result = await this.client.createComment({\n issueId,\n body,\n });\n\n const comment = await result.comment;\n if (!comment) {\n throw new Error('Failed to create comment');\n }\n\n return {\n id: comment.id,\n issueId,\n body: comment.body,\n author: 'Panopticon', // Simplified\n createdAt: comment.createdAt.toISOString(),\n updatedAt: comment.updatedAt.toISOString(),\n };\n }\n\n async transitionIssue(id: string, state: IssueState): Promise<void> {\n // Resolve the Linear issue directly (avoid normalizeIssue which may fail on SDK edge cases)\n let linearIssue: any;\n const isUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id);\n if (isUuid) {\n linearIssue = await this.client.issue(id);\n } else {\n const results = await this.client.searchIssues(id, { first: 1 });\n if (results.nodes.length > 0) {\n linearIssue = results.nodes[0];\n } else {\n throw new IssueNotFoundError(id, 'linear');\n }\n }\n\n // Get workflow states for the issue's team\n const team = await linearIssue.team;\n if (!team) {\n throw new Error('Could not determine issue team');\n }\n\n const states = await team.states();\n\n let targetState: any;\n if (state === 'in_review') {\n // Find a state named \"In Review\" (case-insensitive) — more precise than matching by type,\n // since \"In Progress\" and \"In Review\" are both type \"started\" in Linear.\n targetState = states.nodes.find((s: any) => s.name.toLowerCase() === 'in review');\n if (!targetState) {\n // Fall back to lowest-position \"started\" state if no \"In Review\" state exists\n const startedStates = states.nodes\n .filter((s: any) => s.type === 'started')\n .sort((a: any, b: any) => (a.position ?? 0) - (b.position ?? 0));\n targetState = startedStates[0];\n if (!targetState) {\n throw new Error('No \"In Review\" or \"started\" state found in Linear');\n }\n }\n } else {\n const targetStateType = this.reverseMapState(state);\n\n // Find a state matching the target type.\n // Multiple states can share the same type (e.g., \"In Planning\", \"In Progress\", \"In Review\"\n // are all type \"started\"). Prefer the one with the lowest position (most basic/default state\n // for that type), which matches Linear's convention.\n const matchingStates = states.nodes\n .filter((s: any) => s.type === targetStateType)\n .sort((a: any, b: any) => (a.position ?? 0) - (b.position ?? 0));\n targetState = matchingStates[0];\n if (!targetState) {\n throw new Error(`No state found matching type: ${targetStateType}`);\n }\n }\n\n await this.client.updateIssue(linearIssue.id, {\n stateId: targetState.id,\n });\n }\n\n async linkPR(issueId: string, prUrl: string): Promise<void> {\n const issue = await this.getIssue(issueId);\n\n await this.client.createAttachment({\n issueId: issue.id,\n title: 'Pull Request',\n url: prUrl,\n });\n }\n\n private async normalizeIssue(linearIssue: any): Promise<Issue> {\n const state = await linearIssue.state;\n const assignee = await linearIssue.assignee;\n const labels = await linearIssue.labels();\n\n // Handle dueDate - can be Date, string, or undefined\n let dueDate: string | undefined;\n if (linearIssue.dueDate) {\n dueDate = linearIssue.dueDate instanceof Date\n ? linearIssue.dueDate.toISOString()\n : String(linearIssue.dueDate);\n }\n\n return {\n id: linearIssue.id,\n ref: linearIssue.identifier,\n title: linearIssue.title,\n description: linearIssue.description ?? '',\n state: this.mapState(state?.type ?? 'backlog'),\n labels: labels?.nodes?.map((l: any) => l.name) ?? [],\n assignee: assignee?.name,\n url: linearIssue.url,\n tracker: 'linear',\n priority: linearIssue.priority,\n dueDate,\n createdAt: linearIssue.createdAt instanceof Date\n ? linearIssue.createdAt.toISOString()\n : String(linearIssue.createdAt),\n updatedAt: linearIssue.updatedAt instanceof Date\n ? linearIssue.updatedAt.toISOString()\n : String(linearIssue.updatedAt),\n };\n }\n\n private mapState(linearState: string): IssueState {\n return STATE_MAP[linearState] ?? 'open';\n }\n\n private reverseMapState(state: IssueState): string {\n switch (state) {\n case 'open':\n return 'unstarted';\n case 'in_progress':\n case 'in_review':\n return 'started';\n case 'closed':\n return 'completed';\n default:\n return 'unstarted';\n }\n }\n}\n","/**\n * GitHub Issues Tracker Adapter\n *\n * Implements IssueTracker interface for GitHub Issues.\n */\n\nimport { Octokit } from '@octokit/rest';\nimport type {\n Issue,\n IssueFilters,\n IssueState,\n IssueTracker,\n IssueUpdate,\n NewIssue,\n Comment,\n TrackerType,\n} from './interface.js';\nimport { IssueNotFoundError, TrackerAuthError } from './interface.js';\n\n/**\n * Extract issue number from various formats: \"300\", \"#300\", \"PAN-300\"\n */\nfunction parseIssueNumber(id: string): number {\n const match = id.match(/(\\d+)$/);\n return match ? parseInt(match[1], 10) : NaN;\n}\n\nexport class GitHubTracker implements IssueTracker {\n readonly name: TrackerType = 'github';\n private octokit: Octokit;\n private owner: string;\n private repo: string;\n\n constructor(token: string, owner: string, repo: string) {\n if (!token) {\n throw new TrackerAuthError('github', 'Token is required');\n }\n if (!owner || !repo) {\n throw new Error('GitHub owner and repo are required');\n }\n\n this.octokit = new Octokit({ auth: token });\n this.owner = owner;\n this.repo = repo;\n }\n\n async listIssues(filters?: IssueFilters): Promise<Issue[]> {\n const state = this.mapStateToGitHub(filters?.state);\n\n const response = await this.octokit.issues.listForRepo({\n owner: this.owner,\n repo: this.repo,\n state: filters?.includeClosed ? 'all' : state,\n labels: filters?.labels?.join(',') || undefined,\n assignee: filters?.assignee || undefined,\n per_page: filters?.limit ?? 50,\n });\n\n // Filter out pull requests (GitHub API returns both)\n const issues = response.data.filter((item) => !item.pull_request);\n\n return issues.map((issue) => this.normalizeIssue(issue));\n }\n\n async getIssue(id: string): Promise<Issue> {\n try {\n // Parse the issue number from refs like \"#42\" or just \"42\"\n const issueNumber = parseIssueNumber(id);\n\n if (isNaN(issueNumber)) {\n throw new IssueNotFoundError(id, 'github');\n }\n\n const { data: issue } = await this.octokit.issues.get({\n owner: this.owner,\n repo: this.repo,\n issue_number: issueNumber,\n });\n\n return this.normalizeIssue(issue);\n } catch (error: any) {\n if (error?.status === 404) {\n throw new IssueNotFoundError(id, 'github');\n }\n throw error;\n }\n }\n\n async updateIssue(id: string, update: IssueUpdate): Promise<Issue> {\n const issueNumber = parseIssueNumber(id);\n\n const updatePayload: Record<string, unknown> = {};\n\n if (update.title !== undefined) {\n updatePayload.title = update.title;\n }\n if (update.description !== undefined) {\n updatePayload.body = update.description;\n }\n if (update.state !== undefined) {\n updatePayload.state = update.state === 'closed' ? 'closed' : 'open';\n }\n if (update.labels !== undefined) {\n updatePayload.labels = update.labels;\n }\n if (update.assignee !== undefined) {\n updatePayload.assignees = update.assignee ? [update.assignee] : [];\n }\n\n await this.octokit.issues.update({\n owner: this.owner,\n repo: this.repo,\n issue_number: issueNumber,\n ...updatePayload,\n });\n\n return this.getIssue(id);\n }\n\n async createIssue(newIssue: NewIssue): Promise<Issue> {\n const { data: issue } = await this.octokit.issues.create({\n owner: this.owner,\n repo: this.repo,\n title: newIssue.title,\n body: newIssue.description,\n labels: newIssue.labels,\n assignees: newIssue.assignee ? [newIssue.assignee] : undefined,\n });\n\n return this.normalizeIssue(issue);\n }\n\n async getComments(issueId: string): Promise<Comment[]> {\n const issueNumber = parseIssueNumber(issueId);\n\n const { data: comments } = await this.octokit.issues.listComments({\n owner: this.owner,\n repo: this.repo,\n issue_number: issueNumber,\n });\n\n return comments.map((c) => ({\n id: String(c.id),\n issueId,\n body: c.body ?? '',\n author: c.user?.login ?? 'Unknown',\n createdAt: c.created_at,\n updatedAt: c.updated_at,\n }));\n }\n\n async addComment(issueId: string, body: string): Promise<Comment> {\n const issueNumber = parseIssueNumber(issueId);\n\n const { data: comment } = await this.octokit.issues.createComment({\n owner: this.owner,\n repo: this.repo,\n issue_number: issueNumber,\n body,\n });\n\n return {\n id: String(comment.id),\n issueId,\n body: comment.body ?? '',\n author: comment.user?.login ?? 'Unknown',\n createdAt: comment.created_at,\n updatedAt: comment.updated_at,\n };\n }\n\n async transitionIssue(id: string, state: IssueState): Promise<void> {\n const issueNumber = parseIssueNumber(id);\n\n if (state === 'in_progress') {\n // GitHub has no native \"in progress\" state — use a label instead.\n await this.ensureLabelExists('in-progress', 'In progress', '0075ca');\n await this.octokit.issues.addLabels({\n owner: this.owner,\n repo: this.repo,\n issue_number: issueNumber,\n labels: ['in-progress'],\n });\n } else if (state === 'in_review') {\n // Swap in-progress label for in-review label\n await this.ensureLabelExists('in-review', 'In review', 'e4e669');\n await this.octokit.issues.addLabels({\n owner: this.owner,\n repo: this.repo,\n issue_number: issueNumber,\n labels: ['in-review'],\n });\n // Remove in-progress label if present\n await this.octokit.issues.removeLabel({\n owner: this.owner,\n repo: this.repo,\n issue_number: issueNumber,\n name: 'in-progress',\n }).catch(() => {/* label may not exist, ignore */});\n } else {\n // Remove in-progress and in-review labels when moving to open or closed\n const issue = await this.getIssue(id);\n for (const label of ['in-progress', 'in-review']) {\n if (issue.labels?.includes(label)) {\n await this.octokit.issues.removeLabel({\n owner: this.owner,\n repo: this.repo,\n issue_number: issueNumber,\n name: label,\n }).catch(() => {/* label may not exist, ignore */});\n }\n }\n await this.updateIssue(id, { state });\n }\n }\n\n /** Ensure a label exists in the repo, creating it if needed. */\n private async ensureLabelExists(name: string, description: string, color: string): Promise<void> {\n try {\n await this.octokit.issues.getLabel({ owner: this.owner, repo: this.repo, name });\n } catch {\n await this.octokit.issues.createLabel({\n owner: this.owner,\n repo: this.repo,\n name,\n description,\n color,\n }).catch(() => {/* race condition: another process created it first */});\n }\n }\n\n async linkPR(issueId: string, prUrl: string): Promise<void> {\n // GitHub auto-links PRs that mention issues\n // Add a comment with the PR link\n await this.addComment(\n issueId,\n `Linked Pull Request: ${prUrl}`\n );\n }\n\n private normalizeIssue(ghIssue: any): Issue {\n const labels: string[] = ghIssue.labels.map((l: any) =>\n typeof l === 'string' ? l : l.name\n );\n return {\n id: String(ghIssue.id),\n ref: `#${ghIssue.number}`,\n title: ghIssue.title,\n description: ghIssue.body ?? '',\n state: this.mapStateFromGitHub(ghIssue.state, labels),\n labels,\n assignee: ghIssue.assignee?.login,\n url: ghIssue.html_url,\n tracker: 'github',\n priority: undefined, // GitHub doesn't have priority\n dueDate: undefined, // GitHub doesn't have due dates on issues\n createdAt: ghIssue.created_at,\n updatedAt: ghIssue.updated_at,\n };\n }\n\n private mapStateFromGitHub(ghState: string, labels: string[] = []): IssueState {\n if (ghState === 'closed') return 'closed';\n if (labels.includes('in-progress')) return 'in_progress';\n return 'open';\n }\n\n private mapStateToGitHub(\n state?: IssueState\n ): 'open' | 'closed' | 'all' {\n if (!state) return 'open';\n if (state === 'closed') return 'closed';\n return 'open'; // Both 'open' and 'in_progress' map to 'open'\n }\n}\n","/**\n * GitLab Issues Tracker Adapter (Stub)\n *\n * Placeholder implementation for GitLab Issues support.\n * Full implementation will use @gitbeaker/rest.\n */\n\nimport type {\n Issue,\n IssueFilters,\n IssueState,\n IssueTracker,\n IssueUpdate,\n NewIssue,\n Comment,\n TrackerType,\n} from './interface.js';\nimport { NotImplementedError } from './interface.js';\n\nexport class GitLabTracker implements IssueTracker {\n readonly name: TrackerType = 'gitlab';\n\n constructor(\n private token: string,\n private projectId: string\n ) {\n // Stub - will initialize @gitbeaker client when implemented\n }\n\n async listIssues(_filters?: IssueFilters): Promise<Issue[]> {\n throw new NotImplementedError(\n 'GitLab tracker is not yet implemented. Coming soon!'\n );\n }\n\n async getIssue(_id: string): Promise<Issue> {\n throw new NotImplementedError(\n 'GitLab tracker is not yet implemented. Coming soon!'\n );\n }\n\n async updateIssue(_id: string, _update: IssueUpdate): Promise<Issue> {\n throw new NotImplementedError(\n 'GitLab tracker is not yet implemented. Coming soon!'\n );\n }\n\n async createIssue(_issue: NewIssue): Promise<Issue> {\n throw new NotImplementedError(\n 'GitLab tracker is not yet implemented. Coming soon!'\n );\n }\n\n async getComments(_issueId: string): Promise<Comment[]> {\n throw new NotImplementedError(\n 'GitLab tracker is not yet implemented. Coming soon!'\n );\n }\n\n async addComment(_issueId: string, _body: string): Promise<Comment> {\n throw new NotImplementedError(\n 'GitLab tracker is not yet implemented. Coming soon!'\n );\n }\n\n async transitionIssue(_id: string, _state: IssueState): Promise<void> {\n throw new NotImplementedError(\n 'GitLab tracker is not yet implemented. Coming soon!'\n );\n }\n\n async linkPR(_issueId: string, _prUrl: string): Promise<void> {\n throw new NotImplementedError(\n 'GitLab tracker is not yet implemented. Coming soon!'\n );\n }\n}\n","/**\n * Tracker Factory\n *\n * Creates appropriate tracker instances based on configuration.\n */\n\nimport type { IssueTracker, TrackerType } from './interface.js';\nimport { TrackerAuthError } from './interface.js';\nimport { LinearTracker } from './linear.js';\nimport { GitHubTracker } from './github.js';\nimport { GitLabTracker } from './gitlab.js';\nimport { RallyTracker } from './rally.js';\nimport type { TrackersConfig } from '../config.js';\nimport { loadConfig as loadYamlConfig } from '../config-yaml.js';\n\n// Configuration for a single tracker\nexport interface TrackerConfig {\n type: TrackerType;\n\n // Linear-specific\n apiKeyEnv?: string;\n team?: string;\n\n // GitHub-specific\n tokenEnv?: string;\n owner?: string;\n repo?: string;\n\n // GitLab-specific\n projectId?: string;\n\n // Rally-specific\n server?: string;\n workspace?: string;\n project?: string;\n}\n\n// Multi-tracker configuration (re-exported from config.ts)\n// Note: Use TrackersConfig from config.ts for full type with nested configs\n\n/**\n * Get tracker API key from config.yaml (Settings page).\n * This is checked FIRST — env vars are the fallback, not the other way around.\n */\nfunction getTrackerKeyFromConfig(trackerType: TrackerType): string | undefined {\n try {\n const { config: yamlConfig } = loadYamlConfig();\n return yamlConfig.trackerKeys[trackerType];\n } catch {\n return undefined;\n }\n}\n\n/**\n * Create a tracker instance from configuration.\n * Priority: config.yaml (Settings) > environment variable > custom env var name\n */\nexport function createTracker(config: TrackerConfig): IssueTracker {\n switch (config.type) {\n case 'linear': {\n const configKey = getTrackerKeyFromConfig('linear');\n const envKey = config.apiKeyEnv\n ? process.env[config.apiKeyEnv]\n : process.env.LINEAR_API_KEY;\n const apiKey = configKey || envKey;\n\n if (!apiKey) {\n throw new TrackerAuthError(\n 'linear',\n `API key not found. Configure in Settings or set ${config.apiKeyEnv ?? 'LINEAR_API_KEY'} environment variable.`\n );\n }\n\n return new LinearTracker(apiKey, { team: config.team });\n }\n\n case 'github': {\n const configKey = getTrackerKeyFromConfig('github');\n const envToken = config.tokenEnv\n ? process.env[config.tokenEnv]\n : process.env.GITHUB_TOKEN;\n const token = configKey || envToken;\n\n if (!token) {\n throw new TrackerAuthError(\n 'github',\n `Token not found. Configure in Settings or set ${config.tokenEnv ?? 'GITHUB_TOKEN'} environment variable.`\n );\n }\n\n if (!config.owner || !config.repo) {\n throw new Error(\n 'GitHub tracker requires owner and repo configuration'\n );\n }\n\n return new GitHubTracker(token, config.owner, config.repo);\n }\n\n case 'gitlab': {\n const configKey = getTrackerKeyFromConfig('gitlab');\n const envToken = config.tokenEnv\n ? process.env[config.tokenEnv]\n : process.env.GITLAB_TOKEN;\n const token = configKey || envToken;\n\n if (!token) {\n throw new TrackerAuthError(\n 'gitlab',\n `Token not found. Configure in Settings or set ${config.tokenEnv ?? 'GITLAB_TOKEN'} environment variable.`\n );\n }\n\n if (!config.projectId) {\n throw new Error('GitLab tracker requires projectId configuration');\n }\n\n return new GitLabTracker(token, config.projectId);\n }\n\n case 'rally': {\n const configKey = getTrackerKeyFromConfig('rally');\n const envKey = config.apiKeyEnv\n ? process.env[config.apiKeyEnv]\n : process.env.RALLY_API_KEY;\n const apiKey = configKey || envKey;\n\n if (!apiKey) {\n throw new TrackerAuthError(\n 'rally',\n `API key not found. Configure in Settings or set ${config.apiKeyEnv ?? 'RALLY_API_KEY'} environment variable.`\n );\n }\n\n return new RallyTracker({\n apiKey,\n server: config.server,\n workspace: config.workspace,\n project: config.project,\n });\n }\n\n default:\n throw new Error(`Unknown tracker type: ${config.type}`);\n }\n}\n\n/**\n * Create tracker from trackers configuration section\n */\nexport function createTrackerFromConfig(\n trackersConfig: TrackersConfig,\n trackerType: TrackerType\n): IssueTracker {\n const config = trackersConfig[trackerType];\n\n if (!config) {\n throw new Error(\n `No configuration found for tracker: ${trackerType}. Add [trackers.${trackerType}] to config.`\n );\n }\n\n return createTracker({ ...config, type: trackerType });\n}\n\n/**\n * Get the primary tracker from configuration\n */\nexport function getPrimaryTracker(trackersConfig: TrackersConfig): IssueTracker {\n return createTrackerFromConfig(trackersConfig, trackersConfig.primary);\n}\n\n/**\n * Get the secondary tracker from configuration (if configured)\n */\nexport function getSecondaryTracker(\n trackersConfig: TrackersConfig\n): IssueTracker | null {\n if (!trackersConfig.secondary) {\n return null;\n }\n return createTrackerFromConfig(trackersConfig, trackersConfig.secondary);\n}\n\n/**\n * Get all configured trackers\n */\nexport function getAllTrackers(trackersConfig: TrackersConfig): IssueTracker[] {\n const trackers: IssueTracker[] = [getPrimaryTracker(trackersConfig)];\n\n const secondary = getSecondaryTracker(trackersConfig);\n if (secondary) {\n trackers.push(secondary);\n }\n\n return trackers;\n}\n"],"mappings":";;;;;;;;;;;;;iBAiBsE;AAGhE,aAAwC;EAC5C,SAAS;EACT,WAAW;EACX,SAAS;EACT,WAAW;EACX,UAAU;EACX;AAEY,iBAAb,MAAmD;EACjD,OAA6B;EAC7B;EACA;EAEA,YAAY,QAAgB,SAA6B;AACvD,OAAI,CAAC,OACH,OAAM,IAAI,iBAAiB,UAAU,sBAAsB;AAE7D,QAAK,SAAS,IAAI,aAAa,EAAE,QAAQ,CAAC;AAC1C,QAAK,cAAc,SAAS;;EAG9B,MAAM,WAAW,SAA0C;GACzD,MAAM,OAAO,SAAS,QAAQ,KAAK;GAEnC,MAAM,SAAS,MAAM,KAAK,OAAO,OAAO;IACtC,OAAO,SAAS,SAAS;IACzB,QAAQ;KACN,MAAM,OAAO,EAAE,KAAK,EAAE,IAAI,MAAM,EAAE,GAAG,KAAA;KACrC,OAAO,SAAS,QACZ,EAAE,MAAM,EAAE,IAAI,KAAK,gBAAgB,QAAQ,MAAM,EAAE,EAAE,GACrD,SAAS,gBACP,KAAA,IACA,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE;KACpC,QAAQ,SAAS,QAAQ,SACrB,EAAE,MAAM,EAAE,IAAI,QAAQ,QAAQ,EAAE,GAChC,KAAA;KACJ,UAAU,SAAS,WACf,EAAE,MAAM,EAAE,oBAAoB,QAAQ,UAAU,EAAE,GAClD,KAAA;KACL;IACF,CAAC;GAEF,MAAM,SAAkB,EAAE;AAC1B,QAAK,MAAM,QAAQ,OAAO,MACxB,QAAO,KAAK,MAAM,KAAK,eAAe,KAAK,CAAC;AAE9C,UAAO;;EAGT,MAAM,SAAS,IAA4B;AACzC,OAAI;AAIF,QAFe,kEAAkE,KAAK,GAAG,EAE7E;KAEV,MAAM,QAAQ,MAAM,KAAK,OAAO,MAAM,GAAG;AACzC,SAAI,MACF,QAAO,KAAK,eAAe,MAAM;WAE9B;KAEL,MAAM,QAAQ,GAAG,MAAM,oBAAoB;AAC3C,SAAI,OAAO;MACT,MAAM,GAAG,SAAS,UAAU;MAE5B,MAAM,UAAU,MAAM,KAAK,OAAO,aAAa,IAAI,EAAE,OAAO,GAAG,CAAC;AAChE,UAAI,QAAQ,MAAM,SAAS,EACzB,QAAO,KAAK,eAAe,QAAQ,MAAM,GAAG;;;AAKlD,UAAM,IAAI,mBAAmB,IAAI,SAAS;YACnC,OAAO;AACd,QAAI,iBAAiB,mBAAoB,OAAM;AAC/C,UAAM,IAAI,mBAAmB,IAAI,SAAS;;;EAI9C,MAAM,YAAY,IAAY,QAAqC;GACjE,MAAM,QAAQ,MAAM,KAAK,SAAS,GAAG;GAErC,MAAM,gBAAyC,EAAE;AAEjD,OAAI,OAAO,UAAU,KAAA,EACnB,eAAc,QAAQ,OAAO;AAE/B,OAAI,OAAO,gBAAgB,KAAA,EACzB,eAAc,cAAc,OAAO;AAErC,OAAI,OAAO,aAAa,KAAA,EACtB,eAAc,WAAW,OAAO;AAElC,OAAI,OAAO,YAAY,KAAA,EACrB,eAAc,UAAU,OAAO;AAEjC,OAAI,OAAO,UAAU,KAAA,EAGnB,OAAM,KAAK,gBAAgB,IAAI,OAAO,MAAM;AAE9C,OAAI,OAAO,WAAW,KAAA,GAAW;AAKjC,OAAI,OAAO,KAAK,cAAc,CAAC,SAAS,EACtC,OAAM,KAAK,OAAO,YAAY,MAAM,IAAI,cAAc;AAGxD,UAAO,KAAK,SAAS,GAAG;;EAG1B,MAAM,YAAY,UAAoC;GACpD,MAAM,OAAO,SAAS,QAAQ,KAAK;AAEnC,OAAI,CAAC,KACH,OAAM,IAAI,MAAM,sCAAsC;GAIxD,MAAM,QAAQ,MAAM,KAAK,OAAO,MAAM,EACpC,QAAQ,EAAE,KAAK,EAAE,IAAI,MAAM,EAAE,EAC9B,CAAC;AAEF,OAAI,MAAM,MAAM,WAAW,EACzB,OAAM,IAAI,MAAM,mBAAmB,OAAO;GAG5C,MAAM,SAAS,MAAM,MAAM,GAAG;GAU9B,MAAM,UAAU,OARD,MAAM,KAAK,OAAO,YAAY;IAC3C;IACA,OAAO,SAAS;IAChB,aAAa,SAAS;IACtB,UAAU,SAAS;IACnB,SAAS,SAAS;IACnB,CAAC,EAE2B;AAC7B,OAAI,CAAC,QACH,OAAM,IAAI,MAAM,yBAAyB;AAG3C,UAAO,KAAK,eAAe,QAAQ;;EAGrC,MAAM,YAAY,SAAqC;AAIrD,WAFiB,OADH,MAAM,KAAK,OAAO,MAAM,QAAQ,EACjB,UAAU,EAEvB,MAAM,KAAK,OAAO;IAChC,IAAI,EAAE;IACN;IACA,MAAM,EAAE;IACR,QAAQ,EAAE,MAAM,MAAM,MAAM,GAAG,QAAQ,UAAU;IACjD,WAAW,EAAE,UAAU,aAAa;IACpC,WAAW,EAAE,UAAU,aAAa;IACrC,EAAE;;EAGL,MAAM,WAAW,SAAiB,MAAgC;GAMhE,MAAM,UAAU,OALD,MAAM,KAAK,OAAO,cAAc;IAC7C;IACA;IACD,CAAC,EAE2B;AAC7B,OAAI,CAAC,QACH,OAAM,IAAI,MAAM,2BAA2B;AAG7C,UAAO;IACL,IAAI,QAAQ;IACZ;IACA,MAAM,QAAQ;IACd,QAAQ;IACR,WAAW,QAAQ,UAAU,aAAa;IAC1C,WAAW,QAAQ,UAAU,aAAa;IAC3C;;EAGH,MAAM,gBAAgB,IAAY,OAAkC;GAElE,IAAI;AAEJ,OADe,kEAAkE,KAAK,GAAG,CAEvF,eAAc,MAAM,KAAK,OAAO,MAAM,GAAG;QACpC;IACL,MAAM,UAAU,MAAM,KAAK,OAAO,aAAa,IAAI,EAAE,OAAO,GAAG,CAAC;AAChE,QAAI,QAAQ,MAAM,SAAS,EACzB,eAAc,QAAQ,MAAM;QAE5B,OAAM,IAAI,mBAAmB,IAAI,SAAS;;GAK9C,MAAM,OAAO,MAAM,YAAY;AAC/B,OAAI,CAAC,KACH,OAAM,IAAI,MAAM,iCAAiC;GAGnD,MAAM,SAAS,MAAM,KAAK,QAAQ;GAElC,IAAI;AACJ,OAAI,UAAU,aAAa;AAGzB,kBAAc,OAAO,MAAM,MAAM,MAAW,EAAE,KAAK,aAAa,KAAK,YAAY;AACjF,QAAI,CAAC,aAAa;AAKhB,mBAHsB,OAAO,MAC1B,QAAQ,MAAW,EAAE,SAAS,UAAU,CACxC,MAAM,GAAQ,OAAY,EAAE,YAAY,MAAM,EAAE,YAAY,GAAG,CACtC;AAC5B,SAAI,CAAC,YACH,OAAM,IAAI,MAAM,wDAAoD;;UAGnE;IACL,MAAM,kBAAkB,KAAK,gBAAgB,MAAM;AASnD,kBAHuB,OAAO,MAC3B,QAAQ,MAAW,EAAE,SAAS,gBAAgB,CAC9C,MAAM,GAAQ,OAAY,EAAE,YAAY,MAAM,EAAE,YAAY,GAAG,CACrC;AAC7B,QAAI,CAAC,YACH,OAAM,IAAI,MAAM,iCAAiC,kBAAkB;;AAIvE,SAAM,KAAK,OAAO,YAAY,YAAY,IAAI,EAC5C,SAAS,YAAY,IACtB,CAAC;;EAGJ,MAAM,OAAO,SAAiB,OAA8B;GAC1D,MAAM,QAAQ,MAAM,KAAK,SAAS,QAAQ;AAE1C,SAAM,KAAK,OAAO,iBAAiB;IACjC,SAAS,MAAM;IACf,OAAO;IACP,KAAK;IACN,CAAC;;EAGJ,MAAc,eAAe,aAAkC;GAC7D,MAAM,QAAQ,MAAM,YAAY;GAChC,MAAM,WAAW,MAAM,YAAY;GACnC,MAAM,SAAS,MAAM,YAAY,QAAQ;GAGzC,IAAI;AACJ,OAAI,YAAY,QACd,WAAU,YAAY,mBAAmB,OACrC,YAAY,QAAQ,aAAa,GACjC,OAAO,YAAY,QAAQ;AAGjC,UAAO;IACL,IAAI,YAAY;IAChB,KAAK,YAAY;IACjB,OAAO,YAAY;IACnB,aAAa,YAAY,eAAe;IACxC,OAAO,KAAK,SAAS,OAAO,QAAQ,UAAU;IAC9C,QAAQ,QAAQ,OAAO,KAAK,MAAW,EAAE,KAAK,IAAI,EAAE;IACpD,UAAU,UAAU;IACpB,KAAK,YAAY;IACjB,SAAS;IACT,UAAU,YAAY;IACtB;IACA,WAAW,YAAY,qBAAqB,OACxC,YAAY,UAAU,aAAa,GACnC,OAAO,YAAY,UAAU;IACjC,WAAW,YAAY,qBAAqB,OACxC,YAAY,UAAU,aAAa,GACnC,OAAO,YAAY,UAAU;IAClC;;EAGH,SAAiB,aAAiC;AAChD,UAAO,UAAU,gBAAgB;;EAGnC,gBAAwB,OAA2B;AACjD,WAAQ,OAAR;IACE,KAAK,OACH,QAAO;IACT,KAAK;IACL,KAAK,YACH,QAAO;IACT,KAAK,SACH,QAAO;IACT,QACE,QAAO;;;;;;;;;;;;;;;AC1Sf,SAAS,iBAAiB,IAAoB;CAC5C,MAAM,QAAQ,GAAG,MAAM,SAAS;AAChC,QAAO,QAAQ,SAAS,MAAM,IAAI,GAAG,GAAG;;;;iBAP4B;AAUzD,iBAAb,MAAmD;EACjD,OAA6B;EAC7B;EACA;EACA;EAEA,YAAY,OAAe,OAAe,MAAc;AACtD,OAAI,CAAC,MACH,OAAM,IAAI,iBAAiB,UAAU,oBAAoB;AAE3D,OAAI,CAAC,SAAS,CAAC,KACb,OAAM,IAAI,MAAM,qCAAqC;AAGvD,QAAK,UAAU,IAAI,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC3C,QAAK,QAAQ;AACb,QAAK,OAAO;;EAGd,MAAM,WAAW,SAA0C;GACzD,MAAM,QAAQ,KAAK,iBAAiB,SAAS,MAAM;AAcnD,WAZiB,MAAM,KAAK,QAAQ,OAAO,YAAY;IACrD,OAAO,KAAK;IACZ,MAAM,KAAK;IACX,OAAO,SAAS,gBAAgB,QAAQ;IACxC,QAAQ,SAAS,QAAQ,KAAK,IAAI,IAAI,KAAA;IACtC,UAAU,SAAS,YAAY,KAAA;IAC/B,UAAU,SAAS,SAAS;IAC7B,CAAC,EAGsB,KAAK,QAAQ,SAAS,CAAC,KAAK,aAAa,CAEnD,KAAK,UAAU,KAAK,eAAe,MAAM,CAAC;;EAG1D,MAAM,SAAS,IAA4B;AACzC,OAAI;IAEF,MAAM,cAAc,iBAAiB,GAAG;AAExC,QAAI,MAAM,YAAY,CACpB,OAAM,IAAI,mBAAmB,IAAI,SAAS;IAG5C,MAAM,EAAE,MAAM,UAAU,MAAM,KAAK,QAAQ,OAAO,IAAI;KACpD,OAAO,KAAK;KACZ,MAAM,KAAK;KACX,cAAc;KACf,CAAC;AAEF,WAAO,KAAK,eAAe,MAAM;YAC1B,OAAY;AACnB,QAAI,OAAO,WAAW,IACpB,OAAM,IAAI,mBAAmB,IAAI,SAAS;AAE5C,UAAM;;;EAIV,MAAM,YAAY,IAAY,QAAqC;GACjE,MAAM,cAAc,iBAAiB,GAAG;GAExC,MAAM,gBAAyC,EAAE;AAEjD,OAAI,OAAO,UAAU,KAAA,EACnB,eAAc,QAAQ,OAAO;AAE/B,OAAI,OAAO,gBAAgB,KAAA,EACzB,eAAc,OAAO,OAAO;AAE9B,OAAI,OAAO,UAAU,KAAA,EACnB,eAAc,QAAQ,OAAO,UAAU,WAAW,WAAW;AAE/D,OAAI,OAAO,WAAW,KAAA,EACpB,eAAc,SAAS,OAAO;AAEhC,OAAI,OAAO,aAAa,KAAA,EACtB,eAAc,YAAY,OAAO,WAAW,CAAC,OAAO,SAAS,GAAG,EAAE;AAGpE,SAAM,KAAK,QAAQ,OAAO,OAAO;IAC/B,OAAO,KAAK;IACZ,MAAM,KAAK;IACX,cAAc;IACd,GAAG;IACJ,CAAC;AAEF,UAAO,KAAK,SAAS,GAAG;;EAG1B,MAAM,YAAY,UAAoC;GACpD,MAAM,EAAE,MAAM,UAAU,MAAM,KAAK,QAAQ,OAAO,OAAO;IACvD,OAAO,KAAK;IACZ,MAAM,KAAK;IACX,OAAO,SAAS;IAChB,MAAM,SAAS;IACf,QAAQ,SAAS;IACjB,WAAW,SAAS,WAAW,CAAC,SAAS,SAAS,GAAG,KAAA;IACtD,CAAC;AAEF,UAAO,KAAK,eAAe,MAAM;;EAGnC,MAAM,YAAY,SAAqC;GACrD,MAAM,cAAc,iBAAiB,QAAQ;GAE7C,MAAM,EAAE,MAAM,aAAa,MAAM,KAAK,QAAQ,OAAO,aAAa;IAChE,OAAO,KAAK;IACZ,MAAM,KAAK;IACX,cAAc;IACf,CAAC;AAEF,UAAO,SAAS,KAAK,OAAO;IAC1B,IAAI,OAAO,EAAE,GAAG;IAChB;IACA,MAAM,EAAE,QAAQ;IAChB,QAAQ,EAAE,MAAM,SAAS;IACzB,WAAW,EAAE;IACb,WAAW,EAAE;IACd,EAAE;;EAGL,MAAM,WAAW,SAAiB,MAAgC;GAChE,MAAM,cAAc,iBAAiB,QAAQ;GAE7C,MAAM,EAAE,MAAM,YAAY,MAAM,KAAK,QAAQ,OAAO,cAAc;IAChE,OAAO,KAAK;IACZ,MAAM,KAAK;IACX,cAAc;IACd;IACD,CAAC;AAEF,UAAO;IACL,IAAI,OAAO,QAAQ,GAAG;IACtB;IACA,MAAM,QAAQ,QAAQ;IACtB,QAAQ,QAAQ,MAAM,SAAS;IAC/B,WAAW,QAAQ;IACnB,WAAW,QAAQ;IACpB;;EAGH,MAAM,gBAAgB,IAAY,OAAkC;GAClE,MAAM,cAAc,iBAAiB,GAAG;AAExC,OAAI,UAAU,eAAe;AAE3B,UAAM,KAAK,kBAAkB,eAAe,eAAe,SAAS;AACpE,UAAM,KAAK,QAAQ,OAAO,UAAU;KAClC,OAAO,KAAK;KACZ,MAAM,KAAK;KACX,cAAc;KACd,QAAQ,CAAC,cAAc;KACxB,CAAC;cACO,UAAU,aAAa;AAEhC,UAAM,KAAK,kBAAkB,aAAa,aAAa,SAAS;AAChE,UAAM,KAAK,QAAQ,OAAO,UAAU;KAClC,OAAO,KAAK;KACZ,MAAM,KAAK;KACX,cAAc;KACd,QAAQ,CAAC,YAAY;KACtB,CAAC;AAEF,UAAM,KAAK,QAAQ,OAAO,YAAY;KACpC,OAAO,KAAK;KACZ,MAAM,KAAK;KACX,cAAc;KACd,MAAM;KACP,CAAC,CAAC,YAAY,GAAoC;UAC9C;IAEL,MAAM,QAAQ,MAAM,KAAK,SAAS,GAAG;AACrC,SAAK,MAAM,SAAS,CAAC,eAAe,YAAY,CAC9C,KAAI,MAAM,QAAQ,SAAS,MAAM,CAC/B,OAAM,KAAK,QAAQ,OAAO,YAAY;KACpC,OAAO,KAAK;KACZ,MAAM,KAAK;KACX,cAAc;KACd,MAAM;KACP,CAAC,CAAC,YAAY,GAAoC;AAGvD,UAAM,KAAK,YAAY,IAAI,EAAE,OAAO,CAAC;;;;EAKzC,MAAc,kBAAkB,MAAc,aAAqB,OAA8B;AAC/F,OAAI;AACF,UAAM,KAAK,QAAQ,OAAO,SAAS;KAAE,OAAO,KAAK;KAAO,MAAM,KAAK;KAAM;KAAM,CAAC;WAC1E;AACN,UAAM,KAAK,QAAQ,OAAO,YAAY;KACpC,OAAO,KAAK;KACZ,MAAM,KAAK;KACX;KACA;KACA;KACD,CAAC,CAAC,YAAY,GAAyD;;;EAI5E,MAAM,OAAO,SAAiB,OAA8B;AAG1D,SAAM,KAAK,WACT,SACA,wBAAwB,QACzB;;EAGH,eAAuB,SAAqB;GAC1C,MAAM,SAAmB,QAAQ,OAAO,KAAK,MAC3C,OAAO,MAAM,WAAW,IAAI,EAAE,KAC/B;AACD,UAAO;IACL,IAAI,OAAO,QAAQ,GAAG;IACtB,KAAK,IAAI,QAAQ;IACjB,OAAO,QAAQ;IACf,aAAa,QAAQ,QAAQ;IAC7B,OAAO,KAAK,mBAAmB,QAAQ,OAAO,OAAO;IACrD;IACA,UAAU,QAAQ,UAAU;IAC5B,KAAK,QAAQ;IACb,SAAS;IACT,UAAU,KAAA;IACV,SAAS,KAAA;IACT,WAAW,QAAQ;IACnB,WAAW,QAAQ;IACpB;;EAGH,mBAA2B,SAAiB,SAAmB,EAAE,EAAc;AAC7E,OAAI,YAAY,SAAU,QAAO;AACjC,OAAI,OAAO,SAAS,cAAc,CAAE,QAAO;AAC3C,UAAO;;EAGT,iBACE,OAC2B;AAC3B,OAAI,CAAC,MAAO,QAAO;AACnB,OAAI,UAAU,SAAU,QAAO;AAC/B,UAAO;;;;;;;;iBC/P0C;AAExC,iBAAb,MAAmD;EACjD,OAA6B;EAE7B,YACE,OACA,WACA;AAFQ,QAAA,QAAA;AACA,QAAA,YAAA;;EAKV,MAAM,WAAW,UAA2C;AAC1D,SAAM,IAAI,oBACR,sDACD;;EAGH,MAAM,SAAS,KAA6B;AAC1C,SAAM,IAAI,oBACR,sDACD;;EAGH,MAAM,YAAY,KAAa,SAAsC;AACnE,SAAM,IAAI,oBACR,sDACD;;EAGH,MAAM,YAAY,QAAkC;AAClD,SAAM,IAAI,oBACR,sDACD;;EAGH,MAAM,YAAY,UAAsC;AACtD,SAAM,IAAI,oBACR,sDACD;;EAGH,MAAM,WAAW,UAAkB,OAAiC;AAClE,SAAM,IAAI,oBACR,sDACD;;EAGH,MAAM,gBAAgB,KAAa,QAAmC;AACpE,SAAM,IAAI,oBACR,sDACD;;EAGH,MAAM,OAAO,UAAkB,QAA+B;AAC5D,SAAM,IAAI,oBACR,sDACD;;;;;;;;;;AC9BL,SAAS,wBAAwB,aAA8C;AAC7E,KAAI;EACF,MAAM,EAAE,QAAQ,eAAeA,YAAgB;AAC/C,SAAO,WAAW,YAAY;SACxB;AACN;;;;;;;AAQJ,SAAgB,cAAc,QAAqC;AACjE,SAAQ,OAAO,MAAf;EACE,KAAK,UAAU;GACb,MAAM,YAAY,wBAAwB,SAAS;GACnD,MAAM,SAAS,OAAO,YAClB,QAAQ,IAAI,OAAO,aACnB,QAAQ,IAAI;GAChB,MAAM,SAAS,aAAa;AAE5B,OAAI,CAAC,OACH,OAAM,IAAI,iBACR,UACA,mDAAmD,OAAO,aAAa,iBAAiB,wBACzF;AAGH,UAAO,IAAI,cAAc,QAAQ,EAAE,MAAM,OAAO,MAAM,CAAC;;EAGzD,KAAK,UAAU;GACb,MAAM,YAAY,wBAAwB,SAAS;GACnD,MAAM,WAAW,OAAO,WACpB,QAAQ,IAAI,OAAO,YACnB,QAAQ,IAAI;GAChB,MAAM,QAAQ,aAAa;AAE3B,OAAI,CAAC,MACH,OAAM,IAAI,iBACR,UACA,iDAAiD,OAAO,YAAY,eAAe,wBACpF;AAGH,OAAI,CAAC,OAAO,SAAS,CAAC,OAAO,KAC3B,OAAM,IAAI,MACR,uDACD;AAGH,UAAO,IAAI,cAAc,OAAO,OAAO,OAAO,OAAO,KAAK;;EAG5D,KAAK,UAAU;GACb,MAAM,YAAY,wBAAwB,SAAS;GACnD,MAAM,WAAW,OAAO,WACpB,QAAQ,IAAI,OAAO,YACnB,QAAQ,IAAI;GAChB,MAAM,QAAQ,aAAa;AAE3B,OAAI,CAAC,MACH,OAAM,IAAI,iBACR,UACA,iDAAiD,OAAO,YAAY,eAAe,wBACpF;AAGH,OAAI,CAAC,OAAO,UACV,OAAM,IAAI,MAAM,kDAAkD;AAGpE,UAAO,IAAI,cAAc,OAAO,OAAO,UAAU;;EAGnD,KAAK,SAAS;GACZ,MAAM,YAAY,wBAAwB,QAAQ;GAClD,MAAM,SAAS,OAAO,YAClB,QAAQ,IAAI,OAAO,aACnB,QAAQ,IAAI;GAChB,MAAM,SAAS,aAAa;AAE5B,OAAI,CAAC,OACH,OAAM,IAAI,iBACR,SACA,mDAAmD,OAAO,aAAa,gBAAgB,wBACxF;AAGH,UAAO,IAAI,aAAa;IACtB;IACA,QAAQ,OAAO;IACf,WAAW,OAAO;IAClB,SAAS,OAAO;IACjB,CAAC;;EAGJ,QACE,OAAM,IAAI,MAAM,yBAAyB,OAAO,OAAO;;;;;;AAO7D,SAAgB,wBACd,gBACA,aACc;CACd,MAAM,SAAS,eAAe;AAE9B,KAAI,CAAC,OACH,OAAM,IAAI,MACR,uCAAuC,YAAY,kBAAkB,YAAY,cAClF;AAGH,QAAO,cAAc;EAAE,GAAG;EAAQ,MAAM;EAAa,CAAC;;;;;AAMxD,SAAgB,kBAAkB,gBAA8C;AAC9E,QAAO,wBAAwB,gBAAgB,eAAe,QAAQ;;;;;AAMxE,SAAgB,oBACd,gBACqB;AACrB,KAAI,CAAC,eAAe,UAClB,QAAO;AAET,QAAO,wBAAwB,gBAAgB,eAAe,UAAU;;;;;AAM1E,SAAgB,eAAe,gBAAgD;CAC7E,MAAM,WAA2B,CAAC,kBAAkB,eAAe,CAAC;CAEpE,MAAM,YAAY,oBAAoB,eAAe;AACrD,KAAI,UACF,UAAS,KAAK,UAAU;AAG1B,QAAO;;;iBA5LyC;cACN;cACA;cACA;aACF;mBAEuB"}
|
|
1
|
+
{"version":3,"file":"factory-DzsOiZVc.js","names":["loadYamlConfig"],"sources":["../src/lib/tracker/linear.ts","../src/lib/tracker/github.ts","../src/lib/tracker/gitlab.ts","../src/lib/tracker/factory.ts"],"sourcesContent":["/**\n * Linear Issue Tracker Adapter\n *\n * Implements IssueTracker interface for Linear.\n */\n\nimport { LinearClient } from '@linear/sdk';\nimport type {\n Issue,\n IssueFilters,\n IssueState,\n IssueTracker,\n IssueUpdate,\n NewIssue,\n Comment,\n TrackerType,\n} from './interface.js';\nimport { IssueNotFoundError, TrackerAuthError } from './interface.js';\n\n// Map Linear state types to our normalized states\nconst STATE_MAP: Record<string, IssueState> = {\n backlog: 'open',\n unstarted: 'open',\n started: 'in_progress',\n completed: 'closed',\n canceled: 'closed',\n};\n\nexport class LinearTracker implements IssueTracker {\n readonly name: TrackerType = 'linear';\n private client: LinearClient;\n private defaultTeam?: string;\n\n constructor(apiKey: string, options?: { team?: string }) {\n if (!apiKey) {\n throw new TrackerAuthError('linear', 'API key is required');\n }\n this.client = new LinearClient({ apiKey });\n this.defaultTeam = options?.team;\n }\n\n async listIssues(filters?: IssueFilters): Promise<Issue[]> {\n const team = filters?.team ?? this.defaultTeam;\n\n const result = await this.client.issues({\n first: filters?.limit ?? 50,\n filter: {\n team: team ? { key: { eq: team } } : undefined,\n state: filters?.state\n ? { type: { eq: this.reverseMapState(filters.state) } }\n : filters?.includeClosed\n ? undefined\n : { type: { neq: 'completed' } },\n labels: filters?.labels?.length\n ? { name: { in: filters.labels } }\n : undefined,\n assignee: filters?.assignee\n ? { name: { containsIgnoreCase: filters.assignee } }\n : undefined,\n },\n });\n\n const issues: Issue[] = [];\n for (const node of result.nodes) {\n issues.push(await this.normalizeIssue(node));\n }\n return issues;\n }\n\n async getIssue(id: string): Promise<Issue> {\n try {\n // Check if it's a UUID (36 chars with hyphens)\n const isUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id);\n\n if (isUuid) {\n // Fetch directly by UUID\n const issue = await this.client.issue(id);\n if (issue) {\n return this.normalizeIssue(issue);\n }\n } else {\n // Parse identifier (e.g., MIN-630) and search\n const match = id.match(/^([A-Z]+)-(\\d+)$/i);\n if (match) {\n const [, teamKey, number] = match;\n // Use searchIssues which supports identifier matching\n const results = await this.client.searchIssues(id, { first: 1 });\n if (results.nodes.length > 0) {\n return this.normalizeIssue(results.nodes[0]);\n }\n }\n }\n\n throw new IssueNotFoundError(id, 'linear');\n } catch (error) {\n if (error instanceof IssueNotFoundError) throw error;\n throw new IssueNotFoundError(id, 'linear');\n }\n }\n\n async updateIssue(id: string, update: IssueUpdate): Promise<Issue> {\n const issue = await this.getIssue(id);\n\n const updatePayload: Record<string, unknown> = {};\n\n if (update.title !== undefined) {\n updatePayload.title = update.title;\n }\n if (update.description !== undefined) {\n updatePayload.description = update.description;\n }\n if (update.priority !== undefined) {\n updatePayload.priority = update.priority;\n }\n if (update.dueDate !== undefined) {\n updatePayload.dueDate = update.dueDate;\n }\n if (update.state !== undefined) {\n // Need to find the state ID - this is complex in Linear\n // For now, we'll use the transition method\n await this.transitionIssue(id, update.state);\n }\n if (update.labels !== undefined) {\n // Need to look up label IDs - complex operation\n // TODO: Implement label updates\n }\n\n if (Object.keys(updatePayload).length > 0) {\n await this.client.updateIssue(issue.id, updatePayload);\n }\n\n return this.getIssue(id);\n }\n\n async createIssue(newIssue: NewIssue): Promise<Issue> {\n const team = newIssue.team ?? this.defaultTeam;\n\n if (!team) {\n throw new Error('Team is required to create an issue');\n }\n\n // Get team ID from key\n const teams = await this.client.teams({\n filter: { key: { eq: team } },\n });\n\n if (teams.nodes.length === 0) {\n throw new Error(`Team not found: ${team}`);\n }\n\n const teamId = teams.nodes[0].id;\n\n const result = await this.client.createIssue({\n teamId,\n title: newIssue.title,\n description: newIssue.description,\n priority: newIssue.priority,\n dueDate: newIssue.dueDate,\n });\n\n const created = await result.issue;\n if (!created) {\n throw new Error('Failed to create issue');\n }\n\n return this.normalizeIssue(created);\n }\n\n async getComments(issueId: string): Promise<Comment[]> {\n const issue = await this.client.issue(issueId);\n const comments = await issue.comments();\n\n return comments.nodes.map((c) => ({\n id: c.id,\n issueId,\n body: c.body,\n author: c.user?.then((u) => u?.name ?? 'Unknown') as unknown as string, // Simplified\n createdAt: c.createdAt.toISOString(),\n updatedAt: c.updatedAt.toISOString(),\n }));\n }\n\n async addComment(issueId: string, body: string): Promise<Comment> {\n const result = await this.client.createComment({\n issueId,\n body,\n });\n\n const comment = await result.comment;\n if (!comment) {\n throw new Error('Failed to create comment');\n }\n\n return {\n id: comment.id,\n issueId,\n body: comment.body,\n author: 'Panopticon', // Simplified\n createdAt: comment.createdAt.toISOString(),\n updatedAt: comment.updatedAt.toISOString(),\n };\n }\n\n async transitionIssue(id: string, state: IssueState): Promise<void> {\n // Resolve the Linear issue directly (avoid normalizeIssue which may fail on SDK edge cases)\n let linearIssue: any;\n const isUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id);\n if (isUuid) {\n linearIssue = await this.client.issue(id);\n } else {\n const results = await this.client.searchIssues(id, { first: 1 });\n if (results.nodes.length > 0) {\n linearIssue = results.nodes[0];\n } else {\n throw new IssueNotFoundError(id, 'linear');\n }\n }\n\n // Get workflow states for the issue's team\n const team = await linearIssue.team;\n if (!team) {\n throw new Error('Could not determine issue team');\n }\n\n const states = await team.states();\n\n let targetState: any;\n if (state === 'in_review') {\n // Find a state named \"In Review\" (case-insensitive) — more precise than matching by type,\n // since \"In Progress\" and \"In Review\" are both type \"started\" in Linear.\n targetState = states.nodes.find((s: any) => s.name.toLowerCase() === 'in review');\n if (!targetState) {\n // Fall back to lowest-position \"started\" state if no \"In Review\" state exists\n const startedStates = states.nodes\n .filter((s: any) => s.type === 'started')\n .sort((a: any, b: any) => (a.position ?? 0) - (b.position ?? 0));\n targetState = startedStates[0];\n if (!targetState) {\n throw new Error('No \"In Review\" or \"started\" state found in Linear');\n }\n }\n } else {\n const targetStateType = this.reverseMapState(state);\n\n // Find a state matching the target type.\n // Multiple states can share the same type (e.g., \"In Planning\", \"In Progress\", \"In Review\"\n // are all type \"started\"). Prefer the one with the lowest position (most basic/default state\n // for that type), which matches Linear's convention.\n const matchingStates = states.nodes\n .filter((s: any) => s.type === targetStateType)\n .sort((a: any, b: any) => (a.position ?? 0) - (b.position ?? 0));\n targetState = matchingStates[0];\n if (!targetState) {\n throw new Error(`No state found matching type: ${targetStateType}`);\n }\n }\n\n await this.client.updateIssue(linearIssue.id, {\n stateId: targetState.id,\n });\n }\n\n async linkPR(issueId: string, prUrl: string): Promise<void> {\n const issue = await this.getIssue(issueId);\n\n await this.client.createAttachment({\n issueId: issue.id,\n title: 'Pull Request',\n url: prUrl,\n });\n }\n\n private async normalizeIssue(linearIssue: any): Promise<Issue> {\n const state = await linearIssue.state;\n const assignee = await linearIssue.assignee;\n const labels = await linearIssue.labels();\n\n // Handle dueDate - can be Date, string, or undefined\n let dueDate: string | undefined;\n if (linearIssue.dueDate) {\n dueDate = linearIssue.dueDate instanceof Date\n ? linearIssue.dueDate.toISOString()\n : String(linearIssue.dueDate);\n }\n\n return {\n id: linearIssue.id,\n ref: linearIssue.identifier,\n title: linearIssue.title,\n description: linearIssue.description ?? '',\n state: this.mapState(state?.type ?? 'backlog'),\n labels: labels?.nodes?.map((l: any) => l.name) ?? [],\n assignee: assignee?.name,\n url: linearIssue.url,\n tracker: 'linear',\n priority: linearIssue.priority,\n dueDate,\n createdAt: linearIssue.createdAt instanceof Date\n ? linearIssue.createdAt.toISOString()\n : String(linearIssue.createdAt),\n updatedAt: linearIssue.updatedAt instanceof Date\n ? linearIssue.updatedAt.toISOString()\n : String(linearIssue.updatedAt),\n };\n }\n\n private mapState(linearState: string): IssueState {\n return STATE_MAP[linearState] ?? 'open';\n }\n\n private reverseMapState(state: IssueState): string {\n switch (state) {\n case 'open':\n return 'unstarted';\n case 'in_progress':\n case 'in_review':\n return 'started';\n case 'closed':\n return 'completed';\n default:\n return 'unstarted';\n }\n }\n}\n","/**\n * GitHub Issues Tracker Adapter\n *\n * Implements IssueTracker interface for GitHub Issues.\n */\n\nimport { Octokit } from '@octokit/rest';\nimport type {\n Issue,\n IssueFilters,\n IssueState,\n IssueTracker,\n IssueUpdate,\n NewIssue,\n Comment,\n TrackerType,\n} from './interface.js';\nimport { IssueNotFoundError, TrackerAuthError } from './interface.js';\n\n/**\n * Extract issue number from various formats: \"300\", \"#300\", \"PAN-300\"\n */\nfunction parseIssueNumber(id: string): number {\n const match = id.match(/(\\d+)$/);\n return match ? parseInt(match[1], 10) : NaN;\n}\n\nexport class GitHubTracker implements IssueTracker {\n readonly name: TrackerType = 'github';\n private octokit: Octokit;\n private owner: string;\n private repo: string;\n\n constructor(token: string, owner: string, repo: string) {\n if (!token) {\n throw new TrackerAuthError('github', 'Token is required');\n }\n if (!owner || !repo) {\n throw new Error('GitHub owner and repo are required');\n }\n\n this.octokit = new Octokit({ auth: token });\n this.owner = owner;\n this.repo = repo;\n }\n\n async listIssues(filters?: IssueFilters): Promise<Issue[]> {\n const state = this.mapStateToGitHub(filters?.state);\n\n const response = await this.octokit.issues.listForRepo({\n owner: this.owner,\n repo: this.repo,\n state: filters?.includeClosed ? 'all' : state,\n labels: filters?.labels?.join(',') || undefined,\n assignee: filters?.assignee || undefined,\n per_page: filters?.limit ?? 50,\n });\n\n // Filter out pull requests (GitHub API returns both)\n const issues = response.data.filter((item) => !item.pull_request);\n\n return issues.map((issue) => this.normalizeIssue(issue));\n }\n\n async getIssue(id: string): Promise<Issue> {\n try {\n // Parse the issue number from refs like \"#42\" or just \"42\"\n const issueNumber = parseIssueNumber(id);\n\n if (isNaN(issueNumber)) {\n throw new IssueNotFoundError(id, 'github');\n }\n\n const { data: issue } = await this.octokit.issues.get({\n owner: this.owner,\n repo: this.repo,\n issue_number: issueNumber,\n });\n\n return this.normalizeIssue(issue);\n } catch (error: any) {\n if (error?.status === 404) {\n throw new IssueNotFoundError(id, 'github');\n }\n throw error;\n }\n }\n\n async updateIssue(id: string, update: IssueUpdate): Promise<Issue> {\n const issueNumber = parseIssueNumber(id);\n\n const updatePayload: Record<string, unknown> = {};\n\n if (update.title !== undefined) {\n updatePayload.title = update.title;\n }\n if (update.description !== undefined) {\n updatePayload.body = update.description;\n }\n if (update.state !== undefined) {\n updatePayload.state = update.state === 'closed' ? 'closed' : 'open';\n }\n if (update.labels !== undefined) {\n updatePayload.labels = update.labels;\n }\n if (update.assignee !== undefined) {\n updatePayload.assignees = update.assignee ? [update.assignee] : [];\n }\n\n await this.octokit.issues.update({\n owner: this.owner,\n repo: this.repo,\n issue_number: issueNumber,\n ...updatePayload,\n });\n\n return this.getIssue(id);\n }\n\n async createIssue(newIssue: NewIssue): Promise<Issue> {\n const { data: issue } = await this.octokit.issues.create({\n owner: this.owner,\n repo: this.repo,\n title: newIssue.title,\n body: newIssue.description,\n labels: newIssue.labels,\n assignees: newIssue.assignee ? [newIssue.assignee] : undefined,\n });\n\n return this.normalizeIssue(issue);\n }\n\n async getComments(issueId: string): Promise<Comment[]> {\n const issueNumber = parseIssueNumber(issueId);\n\n const { data: comments } = await this.octokit.issues.listComments({\n owner: this.owner,\n repo: this.repo,\n issue_number: issueNumber,\n });\n\n return comments.map((c) => ({\n id: String(c.id),\n issueId,\n body: c.body ?? '',\n author: c.user?.login ?? 'Unknown',\n createdAt: c.created_at,\n updatedAt: c.updated_at,\n }));\n }\n\n async addComment(issueId: string, body: string): Promise<Comment> {\n const issueNumber = parseIssueNumber(issueId);\n\n const { data: comment } = await this.octokit.issues.createComment({\n owner: this.owner,\n repo: this.repo,\n issue_number: issueNumber,\n body,\n });\n\n return {\n id: String(comment.id),\n issueId,\n body: comment.body ?? '',\n author: comment.user?.login ?? 'Unknown',\n createdAt: comment.created_at,\n updatedAt: comment.updated_at,\n };\n }\n\n async transitionIssue(id: string, state: IssueState): Promise<void> {\n const issueNumber = parseIssueNumber(id);\n\n if (state === 'in_progress') {\n // GitHub has no native \"in progress\" state — use a label instead.\n await this.ensureLabelExists('in-progress', 'In progress', '0075ca');\n await this.octokit.issues.addLabels({\n owner: this.owner,\n repo: this.repo,\n issue_number: issueNumber,\n labels: ['in-progress'],\n });\n } else if (state === 'in_review') {\n // Swap in-progress label for in-review label\n await this.ensureLabelExists('in-review', 'In review', 'e4e669');\n await this.octokit.issues.addLabels({\n owner: this.owner,\n repo: this.repo,\n issue_number: issueNumber,\n labels: ['in-review'],\n });\n // Remove in-progress label if present\n await this.octokit.issues.removeLabel({\n owner: this.owner,\n repo: this.repo,\n issue_number: issueNumber,\n name: 'in-progress',\n }).catch(() => {/* label may not exist, ignore */});\n } else {\n // Remove in-progress and in-review labels when moving to open or closed\n const issue = await this.getIssue(id);\n for (const label of ['in-progress', 'in-review']) {\n if (issue.labels?.includes(label)) {\n await this.octokit.issues.removeLabel({\n owner: this.owner,\n repo: this.repo,\n issue_number: issueNumber,\n name: label,\n }).catch(() => {/* label may not exist, ignore */});\n }\n }\n await this.updateIssue(id, { state });\n }\n }\n\n /** Ensure a label exists in the repo, creating it if needed. */\n private async ensureLabelExists(name: string, description: string, color: string): Promise<void> {\n try {\n await this.octokit.issues.getLabel({ owner: this.owner, repo: this.repo, name });\n } catch {\n await this.octokit.issues.createLabel({\n owner: this.owner,\n repo: this.repo,\n name,\n description,\n color,\n }).catch(() => {/* race condition: another process created it first */});\n }\n }\n\n async linkPR(issueId: string, prUrl: string): Promise<void> {\n // GitHub auto-links PRs that mention issues\n // Add a comment with the PR link\n await this.addComment(\n issueId,\n `Linked Pull Request: ${prUrl}`\n );\n }\n\n private normalizeIssue(ghIssue: any): Issue {\n const labels: string[] = ghIssue.labels.map((l: any) =>\n typeof l === 'string' ? l : l.name\n );\n return {\n id: String(ghIssue.id),\n ref: `#${ghIssue.number}`,\n title: ghIssue.title,\n description: ghIssue.body ?? '',\n state: this.mapStateFromGitHub(ghIssue.state, labels),\n labels,\n assignee: ghIssue.assignee?.login,\n url: ghIssue.html_url,\n tracker: 'github',\n priority: undefined, // GitHub doesn't have priority\n dueDate: undefined, // GitHub doesn't have due dates on issues\n createdAt: ghIssue.created_at,\n updatedAt: ghIssue.updated_at,\n };\n }\n\n private mapStateFromGitHub(ghState: string, labels: string[] = []): IssueState {\n if (ghState === 'closed') return 'closed';\n if (labels.includes('in-progress')) return 'in_progress';\n return 'open';\n }\n\n private mapStateToGitHub(\n state?: IssueState\n ): 'open' | 'closed' | 'all' {\n if (!state) return 'open';\n if (state === 'closed') return 'closed';\n return 'open'; // Both 'open' and 'in_progress' map to 'open'\n }\n}\n","/**\n * GitLab Issues Tracker Adapter (Stub)\n *\n * Placeholder implementation for GitLab Issues support.\n * Full implementation will use @gitbeaker/rest.\n */\n\nimport type {\n Issue,\n IssueFilters,\n IssueState,\n IssueTracker,\n IssueUpdate,\n NewIssue,\n Comment,\n TrackerType,\n} from './interface.js';\nimport { NotImplementedError } from './interface.js';\n\nexport class GitLabTracker implements IssueTracker {\n readonly name: TrackerType = 'gitlab';\n\n constructor(\n private token: string,\n private projectId: string\n ) {\n // Stub - will initialize @gitbeaker client when implemented\n }\n\n async listIssues(_filters?: IssueFilters): Promise<Issue[]> {\n throw new NotImplementedError(\n 'GitLab tracker is not yet implemented. Coming soon!'\n );\n }\n\n async getIssue(_id: string): Promise<Issue> {\n throw new NotImplementedError(\n 'GitLab tracker is not yet implemented. Coming soon!'\n );\n }\n\n async updateIssue(_id: string, _update: IssueUpdate): Promise<Issue> {\n throw new NotImplementedError(\n 'GitLab tracker is not yet implemented. Coming soon!'\n );\n }\n\n async createIssue(_issue: NewIssue): Promise<Issue> {\n throw new NotImplementedError(\n 'GitLab tracker is not yet implemented. Coming soon!'\n );\n }\n\n async getComments(_issueId: string): Promise<Comment[]> {\n throw new NotImplementedError(\n 'GitLab tracker is not yet implemented. Coming soon!'\n );\n }\n\n async addComment(_issueId: string, _body: string): Promise<Comment> {\n throw new NotImplementedError(\n 'GitLab tracker is not yet implemented. Coming soon!'\n );\n }\n\n async transitionIssue(_id: string, _state: IssueState): Promise<void> {\n throw new NotImplementedError(\n 'GitLab tracker is not yet implemented. Coming soon!'\n );\n }\n\n async linkPR(_issueId: string, _prUrl: string): Promise<void> {\n throw new NotImplementedError(\n 'GitLab tracker is not yet implemented. Coming soon!'\n );\n }\n}\n","/**\n * Tracker Factory\n *\n * Creates appropriate tracker instances based on configuration.\n */\n\nimport type { IssueTracker, TrackerType } from './interface.js';\nimport { TrackerAuthError } from './interface.js';\nimport { LinearTracker } from './linear.js';\nimport { GitHubTracker } from './github.js';\nimport { GitLabTracker } from './gitlab.js';\nimport { RallyTracker } from './rally.js';\nimport type { TrackersConfig } from '../config.js';\nimport { loadConfig as loadYamlConfig } from '../config-yaml.js';\n\n// Configuration for a single tracker\nexport interface TrackerConfig {\n type: TrackerType;\n\n // Linear-specific\n apiKeyEnv?: string;\n team?: string;\n\n // GitHub-specific\n tokenEnv?: string;\n owner?: string;\n repo?: string;\n\n // GitLab-specific\n projectId?: string;\n\n // Rally-specific\n server?: string;\n workspace?: string;\n project?: string;\n}\n\n// Multi-tracker configuration (re-exported from config.ts)\n// Note: Use TrackersConfig from config.ts for full type with nested configs\n\n/**\n * Get tracker API key from config.yaml (Settings page).\n * This is checked FIRST — env vars are the fallback, not the other way around.\n */\nfunction getTrackerKeyFromConfig(trackerType: TrackerType): string | undefined {\n try {\n const { config: yamlConfig } = loadYamlConfig();\n return yamlConfig.trackerKeys[trackerType];\n } catch {\n return undefined;\n }\n}\n\n/**\n * Create a tracker instance from configuration.\n * Priority: config.yaml (Settings) > environment variable > custom env var name\n */\nexport function createTracker(config: TrackerConfig): IssueTracker {\n switch (config.type) {\n case 'linear': {\n const configKey = getTrackerKeyFromConfig('linear');\n const envKey = config.apiKeyEnv\n ? process.env[config.apiKeyEnv]\n : process.env.LINEAR_API_KEY;\n const apiKey = configKey || envKey;\n\n if (!apiKey) {\n throw new TrackerAuthError(\n 'linear',\n `API key not found. Configure in Settings or set ${config.apiKeyEnv ?? 'LINEAR_API_KEY'} environment variable.`\n );\n }\n\n return new LinearTracker(apiKey, { team: config.team });\n }\n\n case 'github': {\n const configKey = getTrackerKeyFromConfig('github');\n const envToken = config.tokenEnv\n ? process.env[config.tokenEnv]\n : process.env.GITHUB_TOKEN;\n const token = configKey || envToken;\n\n if (!token) {\n throw new TrackerAuthError(\n 'github',\n `Token not found. Configure in Settings or set ${config.tokenEnv ?? 'GITHUB_TOKEN'} environment variable.`\n );\n }\n\n if (!config.owner || !config.repo) {\n throw new Error(\n 'GitHub tracker requires owner and repo configuration'\n );\n }\n\n return new GitHubTracker(token, config.owner, config.repo);\n }\n\n case 'gitlab': {\n const configKey = getTrackerKeyFromConfig('gitlab');\n const envToken = config.tokenEnv\n ? process.env[config.tokenEnv]\n : process.env.GITLAB_TOKEN;\n const token = configKey || envToken;\n\n if (!token) {\n throw new TrackerAuthError(\n 'gitlab',\n `Token not found. Configure in Settings or set ${config.tokenEnv ?? 'GITLAB_TOKEN'} environment variable.`\n );\n }\n\n if (!config.projectId) {\n throw new Error('GitLab tracker requires projectId configuration');\n }\n\n return new GitLabTracker(token, config.projectId);\n }\n\n case 'rally': {\n const configKey = getTrackerKeyFromConfig('rally');\n const envKey = config.apiKeyEnv\n ? process.env[config.apiKeyEnv]\n : process.env.RALLY_API_KEY;\n const apiKey = configKey || envKey;\n\n if (!apiKey) {\n throw new TrackerAuthError(\n 'rally',\n `API key not found. Configure in Settings or set ${config.apiKeyEnv ?? 'RALLY_API_KEY'} environment variable.`\n );\n }\n\n return new RallyTracker({\n apiKey,\n server: config.server,\n workspace: config.workspace,\n project: config.project,\n });\n }\n\n default:\n throw new Error(`Unknown tracker type: ${config.type}`);\n }\n}\n\n/**\n * Create tracker from trackers configuration section\n */\nexport function createTrackerFromConfig(\n trackersConfig: TrackersConfig,\n trackerType: TrackerType\n): IssueTracker {\n const config = trackersConfig[trackerType];\n\n if (!config) {\n throw new Error(\n `No configuration found for tracker: ${trackerType}. Add [trackers.${trackerType}] to config.`\n );\n }\n\n return createTracker({ ...config, type: trackerType });\n}\n\n/**\n * Get the primary tracker from configuration\n */\nexport function getPrimaryTracker(trackersConfig: TrackersConfig): IssueTracker {\n return createTrackerFromConfig(trackersConfig, trackersConfig.primary);\n}\n\n/**\n * Get the secondary tracker from configuration (if configured)\n */\nexport function getSecondaryTracker(\n trackersConfig: TrackersConfig\n): IssueTracker | null {\n if (!trackersConfig.secondary) {\n return null;\n }\n return createTrackerFromConfig(trackersConfig, trackersConfig.secondary);\n}\n\n/**\n * Get all configured trackers\n */\nexport function getAllTrackers(trackersConfig: TrackersConfig): IssueTracker[] {\n const trackers: IssueTracker[] = [getPrimaryTracker(trackersConfig)];\n\n const secondary = getSecondaryTracker(trackersConfig);\n if (secondary) {\n trackers.push(secondary);\n }\n\n return trackers;\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __esmMin } from "./chunk-ruWRV7i3.js";
|
|
2
|
-
import { p as init_projects, y as resolveProjectFromIssue } from "./projects-
|
|
2
|
+
import { p as init_projects, y as resolveProjectFromIssue } from "./projects-Bk-5QhFQ.js";
|
|
3
3
|
import { existsSync } from "fs";
|
|
4
4
|
import { join } from "path";
|
|
5
5
|
import { mkdir, readFile, readdir, writeFile } from "fs/promises";
|
|
@@ -122,4 +122,4 @@ __esmMin((() => {
|
|
|
122
122
|
}))();
|
|
123
123
|
export { writeFeedbackFile };
|
|
124
124
|
|
|
125
|
-
//# sourceMappingURL=feedback-writer-
|
|
125
|
+
//# sourceMappingURL=feedback-writer-ygXN5F9N.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feedback-writer-
|
|
1
|
+
{"version":3,"file":"feedback-writer-ygXN5F9N.js","names":[],"sources":["../src/lib/cloister/feedback-writer.ts"],"sourcesContent":["/**\n * Feedback Writer — writes specialist feedback to workspace files.\n *\n * All specialist feedback (review, test, merge) is written to\n * .planning/feedback/ in the workspace, with a breadcrumb in STATE.md.\n * The work agent reads these on startup or after crash recovery.\n *\n * All I/O is async (fs/promises) — never execSync.\n */\n\nimport { writeFile, readFile, mkdir, readdir } from 'fs/promises';\nimport { existsSync } from 'fs';\nimport { join } from 'path';\nimport { resolveProjectFromIssue } from '../projects.js';\n\nexport interface WriteFeedbackOptions {\n issueId: string;\n workspacePath?: string;\n specialist: 'verification-gate' | 'review-agent' | 'test-agent' | 'inspect-agent' | 'uat-agent' | 'merge-agent';\n outcome: string;\n summary: string;\n markdownBody: string;\n}\n\nexport interface WriteFeedbackResult {\n success: boolean;\n /** Relative path from workspace root */\n relativePath?: string;\n /** Absolute path */\n filePath?: string;\n error?: string;\n}\n\n/**\n * Resolve workspace path from an issue ID.\n */\nfunction resolveWorkspacePath(issueId: string): string | null {\n const resolved = resolveProjectFromIssue(issueId);\n if (!resolved) return null;\n\n const wsPath = join(resolved.projectPath, 'workspaces', `feature-${issueId.toLowerCase()}`);\n return existsSync(wsPath) ? wsPath : null;\n}\n\n/**\n * Get the next sequence number from existing files in the feedback directory.\n */\nasync function getNextSequenceNumber(feedbackDir: string): Promise<number> {\n try {\n const files = await readdir(feedbackDir);\n let max = 0;\n for (const file of files) {\n const match = file.match(/^(\\d{3})-/);\n if (match) {\n const n = parseInt(match[1], 10);\n if (n > max) max = n;\n }\n }\n return max + 1;\n } catch {\n return 1;\n }\n}\n\n/**\n * Append a feedback entry to STATE.md's \"Specialist Feedback\" section.\n * Creates the section if it doesn't exist. Creates STATE.md if it doesn't exist.\n */\nasync function appendToStateMd(\n planningDir: string,\n entry: { timestamp: string; specialist: string; outcome: string; relativePath: string; issueId: string }\n): Promise<void> {\n const statePath = join(planningDir, 'STATE.md');\n const line = `- **[${entry.timestamp}] ${entry.specialist} → ${entry.outcome.toUpperCase()}** — \\`${entry.relativePath}\\``;\n\n let content: string;\n try {\n content = await readFile(statePath, 'utf-8');\n } catch {\n // STATE.md doesn't exist — create a minimal one\n content = `# Agent State: ${entry.issueId}\\n`;\n }\n\n const sectionHeader = '## Specialist Feedback';\n const sectionIndex = content.indexOf(sectionHeader);\n\n if (sectionIndex >= 0) {\n // Find the end of the section (next ## or EOF)\n const afterHeader = sectionIndex + sectionHeader.length;\n const nextSection = content.indexOf('\\n## ', afterHeader);\n const insertPos = nextSection >= 0 ? nextSection : content.length;\n content = content.slice(0, insertPos).trimEnd() + '\\n' + line + '\\n' + content.slice(insertPos);\n } else {\n // Append the section at the end\n content = content.trimEnd() + '\\n\\n' + sectionHeader + '\\n\\n' + line + '\\n';\n }\n\n await writeFile(statePath, content, 'utf-8');\n}\n\n/**\n * Write specialist feedback to a file in the workspace and update STATE.md.\n */\nexport async function writeFeedbackFile(opts: WriteFeedbackOptions): Promise<WriteFeedbackResult> {\n // Validate workspacePath — reject project roots (must contain /workspaces/ or have .planning dir)\n let providedPath = opts.workspacePath;\n if (providedPath && !existsSync(join(providedPath, '.planning')) && !providedPath.includes('/workspaces/')) {\n // Looks like a project root, not a workspace — fall back to resolution\n providedPath = undefined;\n }\n const workspacePath = providedPath || resolveWorkspacePath(opts.issueId);\n if (!workspacePath) {\n return { success: false, error: `Workspace not found for ${opts.issueId}` };\n }\n\n const planningDir = join(workspacePath, '.planning');\n const feedbackDir = join(planningDir, 'feedback');\n\n try {\n await mkdir(feedbackDir, { recursive: true });\n\n const seq = await getNextSequenceNumber(feedbackDir);\n const seqStr = String(seq).padStart(3, '0');\n const filename = `${seqStr}-${opts.specialist}-${opts.outcome}.md`;\n const filePath = join(feedbackDir, filename);\n const relativePath = `.planning/feedback/${filename}`;\n\n const timestamp = new Date().toISOString().replace(/\\.\\d+Z$/, 'Z');\n const shortTimestamp = timestamp.replace(/:\\d{2}Z$/, 'Z');\n\n const content = [\n '---',\n `specialist: ${opts.specialist}`,\n `issueId: ${opts.issueId}`,\n `outcome: ${opts.outcome}`,\n `timestamp: ${timestamp}`,\n '---',\n '',\n opts.markdownBody,\n '',\n ].join('\\n');\n\n await writeFile(filePath, content, 'utf-8');\n\n // Update STATE.md with breadcrumb\n await appendToStateMd(planningDir, {\n timestamp: shortTimestamp,\n specialist: opts.specialist,\n outcome: opts.outcome,\n relativePath,\n issueId: opts.issueId,\n });\n\n console.log(`[feedback-writer] Wrote ${relativePath} for ${opts.issueId}`);\n return { success: true, relativePath, filePath };\n } catch (error: any) {\n console.error(`[feedback-writer] Failed to write feedback for ${opts.issueId}:`, error);\n return { success: false, error: error.message };\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github-app-CHKwxOeQ.js","names":[],"sources":["../src/lib/github-app.ts"],"sourcesContent":["/**\n * GitHub App Integration (PAN-536)\n *\n * Generates short-lived installation access tokens for the panopticon-agent GitHub App.\n * Agents push via HTTPS with these tokens instead of the user's SSH key, so commits\n * show as `panopticon-agent[bot]` with a verified badge.\n *\n * Credentials stored at: ~/.panopticon/github-app/\n * - app-id, private-key.pem, installation-id\n */\n\nimport { readFileSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\nimport { createSign } from 'crypto';\n\nconst APP_DIR = join(homedir(), '.panopticon', 'github-app');\n\nexport interface GitHubAppConfig {\n appId: string;\n installationId: string;\n privateKey: string;\n}\n\nexport interface InstallationToken {\n token: string;\n expiresAt: string; // ISO timestamp\n}\n\n/**\n * Check if the GitHub App is configured (credentials exist)\n */\nexport function isGitHubAppConfigured(): boolean {\n return (\n existsSync(join(APP_DIR, 'app-id')) &&\n existsSync(join(APP_DIR, 'private-key.pem')) &&\n existsSync(join(APP_DIR, 'installation-id'))\n );\n}\n\n/**\n * Load GitHub App credentials from ~/.panopticon/github-app/\n */\nexport function loadGitHubAppConfig(): GitHubAppConfig | null {\n if (!isGitHubAppConfigured()) return null;\n try {\n return {\n appId: readFileSync(join(APP_DIR, 'app-id'), 'utf-8').trim(),\n installationId: readFileSync(join(APP_DIR, 'installation-id'), 'utf-8').trim(),\n privateKey: readFileSync(join(APP_DIR, 'private-key.pem'), 'utf-8'),\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Generate a JWT for GitHub App authentication\n */\nfunction generateJWT(appId: string, privateKey: string): string {\n const now = Math.floor(Date.now() / 1000);\n const header = Buffer.from(JSON.stringify({ alg: 'RS256', typ: 'JWT' })).toString('base64url');\n const payload = Buffer.from(JSON.stringify({\n iat: now - 60, // 60s clock drift allowance\n exp: now + 600, // 10 minute expiry\n iss: appId,\n })).toString('base64url');\n\n const signer = createSign('SHA256');\n signer.update(`${header}.${payload}`);\n const signature = signer.sign(privateKey, 'base64url');\n\n return `${header}.${payload}.${signature}`;\n}\n\n/**\n * Generate a short-lived installation access token (~1 hour TTL).\n * Used for git push and PR operations by agent workspaces.\n */\nexport async function generateInstallationToken(\n config?: GitHubAppConfig\n): Promise<InstallationToken> {\n const appConfig = config || loadGitHubAppConfig();\n if (!appConfig) {\n throw new Error('GitHub App not configured. Run: node scripts/create-github-app.mjs');\n }\n\n const jwt = generateJWT(appConfig.appId, appConfig.privateKey);\n\n const response = await fetch(\n `https://api.github.com/app/installations/${appConfig.installationId}/access_tokens`,\n {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${jwt}`,\n 'Accept': 'application/vnd.github+json',\n 'User-Agent': 'panopticon-cli',\n },\n }\n );\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(`Failed to generate installation token: ${response.status} ${text}`);\n }\n\n const data = await response.json() as { token: string; expires_at: string };\n return {\n token: data.token,\n expiresAt: data.expires_at,\n };\n}\n\n/**\n * Get the bot identity for git config\n */\nexport function getBotIdentity(appConfig?: GitHubAppConfig): { name: string; email: string } {\n const config = appConfig || loadGitHubAppConfig();\n const appId = config?.appId || '0';\n return {\n name: 'panopticon-agent[bot]',\n email: `${appId}+panopticon-agent[bot]@users.noreply.github.com`,\n };\n}\n\n/**\n * Configure a workspace to push as the bot identity.\n * Sets git remote to HTTPS with token auth and configures bot user.\n *\n * @param workspacePath - Path to the git workspace\n * @param owner - GitHub repo owner\n * @param repo - GitHub repo name\n * @param token - Installation access token\n */\nexport async function configureWorkspaceForBot(\n workspacePath: string,\n owner: string,\n repo: string,\n token: string,\n): Promise<void> {\n const { exec } = await import('child_process');\n const { promisify } = await import('util');\n const { writeFileSync } = await import('fs');\n const execAsync = promisify(exec);\n const { name, email } = getBotIdentity();\n\n // Set git user identity for this workspace\n await execAsync(`git config user.name \"${name}\"`, { cwd: workspacePath, encoding: 'utf-8' });\n await execAsync(`git config user.email \"${email}\"`, { cwd: workspacePath, encoding: 'utf-8' });\n\n // Use git credential store with a workspace-local credential file.\n // Token is refreshed at workspace creation (~1hr TTL). For long sessions,\n // call refreshWorkspaceToken() to get a fresh one.\n const credFile = join(workspacePath, '.git', 'pan-credentials');\n writeFileSync(credFile, `https://x-access-token:${token}@github.com\\n`, { mode: 0o600 });\n\n // Set remote to HTTPS and configure credential store\n const httpsUrl = `https://github.com/${owner}/${repo}.git`;\n await execAsync(`git remote set-url origin \"${httpsUrl}\"`, { cwd: workspacePath, encoding: 'utf-8' });\n await execAsync(`git config credential.helper \"store --file=${credFile}\"`, { cwd: workspacePath, encoding: 'utf-8' });\n}\n\n/**\n * Report a check status on a commit (replaces the need for CI)\n *\n * @param owner - Repo owner\n * @param repo - Repo name\n * @param sha - Commit SHA\n * @param status - Check status\n * @param context - Check name (e.g. \"panopticon/review\", \"panopticon/test\")\n * @param description - Short description\n */\nexport async function reportCommitStatus(\n owner: string,\n repo: string,\n sha: string,\n status: 'pending' | 'success' | 'failure' | 'error',\n context: string,\n description: string,\n): Promise<void> {\n const config = loadGitHubAppConfig();\n if (!config) return; // Silently skip in fallback mode\n\n const { token } = await generateInstallationToken(config);\n\n const response = await fetch(\n `https://api.github.com/repos/${owner}/${repo}/statuses/${sha}`,\n {\n method: 'POST',\n headers: {\n 'Authorization': `token ${token}`,\n 'Accept': 'application/vnd.github+json',\n 'User-Agent': 'panopticon-cli',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ state: status, context, description }),\n }\n );\n\n if (!response.ok) {\n const text = await response.text();\n console.warn(`[github-app] Failed to report status: ${response.status} ${text}`);\n }\n}\n\n/**\n * Refresh the installation token for a workspace (call when token expires).\n * Updates the credential file in-place.\n */\nexport async function refreshWorkspaceToken(\n workspacePath: string,\n): Promise<void> {\n const config = loadGitHubAppConfig();\n if (!config) throw new Error('GitHub App not configured');\n\n const { token } = await generateInstallationToken(config);\n const { writeFileSync } = await import('fs');\n const credFile = join(workspacePath, '.git', 'pan-credentials');\n writeFileSync(credFile, `https://x-access-token:${token}@github.com\\n`, { mode: 0o600 });\n}\n\n/**\n * Get GitHub App status for `pan status` display\n */\nexport function getAppStatus(): {\n configured: boolean;\n appId?: string;\n installationId?: string;\n mode: 'app' | 'fallback';\n} {\n const config = loadGitHubAppConfig();\n if (config) {\n return {\n configured: true,\n appId: config.appId,\n installationId: config.installationId,\n mode: 'app',\n };\n }\n return { configured: false, mode: 'fallback' };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"github-app-DykduJ0X.js","names":[],"sources":["../src/lib/github-app.ts"],"sourcesContent":["/**\n * GitHub App Integration (PAN-536)\n *\n * Generates short-lived installation access tokens for the panopticon-agent GitHub App.\n * Agents push via HTTPS with these tokens instead of the user's SSH key, so commits\n * show as `panopticon-agent[bot]` with a verified badge.\n *\n * Credentials stored at: ~/.panopticon/github-app/\n * - app-id, private-key.pem, installation-id\n */\n\nimport { readFileSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\nimport { createSign } from 'crypto';\n\nconst APP_DIR = join(homedir(), '.panopticon', 'github-app');\n\nexport interface GitHubAppConfig {\n appId: string;\n installationId: string;\n privateKey: string;\n}\n\nexport interface InstallationToken {\n token: string;\n expiresAt: string; // ISO timestamp\n}\n\n/**\n * Check if the GitHub App is configured (credentials exist)\n */\nexport function isGitHubAppConfigured(): boolean {\n return (\n existsSync(join(APP_DIR, 'app-id')) &&\n existsSync(join(APP_DIR, 'private-key.pem')) &&\n existsSync(join(APP_DIR, 'installation-id'))\n );\n}\n\n/**\n * Load GitHub App credentials from ~/.panopticon/github-app/\n */\nexport function loadGitHubAppConfig(): GitHubAppConfig | null {\n if (!isGitHubAppConfigured()) return null;\n try {\n return {\n appId: readFileSync(join(APP_DIR, 'app-id'), 'utf-8').trim(),\n installationId: readFileSync(join(APP_DIR, 'installation-id'), 'utf-8').trim(),\n privateKey: readFileSync(join(APP_DIR, 'private-key.pem'), 'utf-8'),\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Generate a JWT for GitHub App authentication\n */\nfunction generateJWT(appId: string, privateKey: string): string {\n const now = Math.floor(Date.now() / 1000);\n const header = Buffer.from(JSON.stringify({ alg: 'RS256', typ: 'JWT' })).toString('base64url');\n const payload = Buffer.from(JSON.stringify({\n iat: now - 60, // 60s clock drift allowance\n exp: now + 600, // 10 minute expiry\n iss: appId,\n })).toString('base64url');\n\n const signer = createSign('SHA256');\n signer.update(`${header}.${payload}`);\n const signature = signer.sign(privateKey, 'base64url');\n\n return `${header}.${payload}.${signature}`;\n}\n\n/**\n * Generate a short-lived installation access token (~1 hour TTL).\n * Used for git push and PR operations by agent workspaces.\n */\nexport async function generateInstallationToken(\n config?: GitHubAppConfig\n): Promise<InstallationToken> {\n const appConfig = config || loadGitHubAppConfig();\n if (!appConfig) {\n throw new Error('GitHub App not configured. Run: node scripts/create-github-app.mjs');\n }\n\n const jwt = generateJWT(appConfig.appId, appConfig.privateKey);\n\n const response = await fetch(\n `https://api.github.com/app/installations/${appConfig.installationId}/access_tokens`,\n {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${jwt}`,\n 'Accept': 'application/vnd.github+json',\n 'User-Agent': 'panopticon-cli',\n },\n }\n );\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(`Failed to generate installation token: ${response.status} ${text}`);\n }\n\n const data = await response.json() as { token: string; expires_at: string };\n return {\n token: data.token,\n expiresAt: data.expires_at,\n };\n}\n\n/**\n * Get the bot identity for git config\n */\nexport function getBotIdentity(appConfig?: GitHubAppConfig): { name: string; email: string } {\n const config = appConfig || loadGitHubAppConfig();\n const appId = config?.appId || '0';\n return {\n name: 'panopticon-agent[bot]',\n email: `${appId}+panopticon-agent[bot]@users.noreply.github.com`,\n };\n}\n\n/**\n * Configure a workspace to push as the bot identity.\n * Sets git remote to HTTPS with token auth and configures bot user.\n *\n * @param workspacePath - Path to the git workspace\n * @param owner - GitHub repo owner\n * @param repo - GitHub repo name\n * @param token - Installation access token\n */\nexport async function configureWorkspaceForBot(\n workspacePath: string,\n owner: string,\n repo: string,\n token: string,\n): Promise<void> {\n const { exec } = await import('child_process');\n const { promisify } = await import('util');\n const { writeFileSync } = await import('fs');\n const execAsync = promisify(exec);\n const { name, email } = getBotIdentity();\n\n // Set git user identity for this workspace\n await execAsync(`git config user.name \"${name}\"`, { cwd: workspacePath, encoding: 'utf-8' });\n await execAsync(`git config user.email \"${email}\"`, { cwd: workspacePath, encoding: 'utf-8' });\n\n // Use git credential store with a workspace-local credential file.\n // Token is refreshed at workspace creation (~1hr TTL). For long sessions,\n // call refreshWorkspaceToken() to get a fresh one.\n const credFile = join(workspacePath, '.git', 'pan-credentials');\n writeFileSync(credFile, `https://x-access-token:${token}@github.com\\n`, { mode: 0o600 });\n\n // Set remote to HTTPS and configure credential store\n const httpsUrl = `https://github.com/${owner}/${repo}.git`;\n await execAsync(`git remote set-url origin \"${httpsUrl}\"`, { cwd: workspacePath, encoding: 'utf-8' });\n await execAsync(`git config credential.helper \"store --file=${credFile}\"`, { cwd: workspacePath, encoding: 'utf-8' });\n}\n\n/**\n * Report a check status on a commit (replaces the need for CI)\n *\n * @param owner - Repo owner\n * @param repo - Repo name\n * @param sha - Commit SHA\n * @param status - Check status\n * @param context - Check name (e.g. \"panopticon/review\", \"panopticon/test\")\n * @param description - Short description\n */\nexport async function reportCommitStatus(\n owner: string,\n repo: string,\n sha: string,\n status: 'pending' | 'success' | 'failure' | 'error',\n context: string,\n description: string,\n): Promise<void> {\n const config = loadGitHubAppConfig();\n if (!config) return; // Silently skip in fallback mode\n\n const { token } = await generateInstallationToken(config);\n\n const response = await fetch(\n `https://api.github.com/repos/${owner}/${repo}/statuses/${sha}`,\n {\n method: 'POST',\n headers: {\n 'Authorization': `token ${token}`,\n 'Accept': 'application/vnd.github+json',\n 'User-Agent': 'panopticon-cli',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ state: status, context, description }),\n }\n );\n\n if (!response.ok) {\n const text = await response.text();\n console.warn(`[github-app] Failed to report status: ${response.status} ${text}`);\n }\n}\n\n/**\n * Refresh the installation token for a workspace (call when token expires).\n * Updates the credential file in-place.\n */\nexport async function refreshWorkspaceToken(\n workspacePath: string,\n): Promise<void> {\n const config = loadGitHubAppConfig();\n if (!config) throw new Error('GitHub App not configured');\n\n const { token } = await generateInstallationToken(config);\n const { writeFileSync } = await import('fs');\n const credFile = join(workspacePath, '.git', 'pan-credentials');\n writeFileSync(credFile, `https://x-access-token:${token}@github.com\\n`, { mode: 0o600 });\n}\n\n/**\n * Get GitHub App status for `pan status` display\n */\nexport function getAppStatus(): {\n configured: boolean;\n appId?: string;\n installationId?: string;\n mode: 'app' | 'fallback';\n} {\n const config = loadGitHubAppConfig();\n if (config) {\n return {\n configured: true,\n appId: config.appId,\n installationId: config.installationId,\n mode: 'app',\n };\n }\n return { configured: false, mode: 'fallback' };\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __esmMin } from "./chunk-ruWRV7i3.js";
|
|
2
|
-
import { n as init_workspace_config, r as replacePlaceholders } from "./workspace-config-
|
|
2
|
+
import { n as init_workspace_config, r as replacePlaceholders } from "./workspace-config-fUafvYMp.js";
|
|
3
3
|
//#region src/lib/hume.ts
|
|
4
4
|
/**
|
|
5
5
|
* Make an authenticated Hume API request.
|
|
@@ -179,4 +179,4 @@ var init_hume = __esmMin((() => {
|
|
|
179
179
|
//#endregion
|
|
180
180
|
export { deleteHumeConfig as n, init_hume as r, createHumeConfig as t };
|
|
181
181
|
|
|
182
|
-
//# sourceMappingURL=hume-
|
|
182
|
+
//# sourceMappingURL=hume-DoCbph2h.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hume-DnV-tDsh.js","names":[],"sources":["../src/lib/hume.ts"],"sourcesContent":["/**\n * Hume EVI Config Management\n *\n * Manages per-workspace Hume EVI configs for BYOLLM (Bring Your Own LLM).\n * Called during workspace create (createHumeConfig) and workspace remove/deep-wipe (deleteHumeConfig).\n *\n * Pattern mirrors tunnel.ts — stateless CRUD against external API.\n */\n\nimport { HumeConfig, TemplatePlaceholders, replacePlaceholders } from './workspace-config.js';\n\nexport interface HumeResult {\n success: boolean;\n steps: string[];\n /** Populated on successful create */\n configId?: string;\n configName?: string;\n}\n\nconst HUME_API = 'https://api.hume.ai/v0/evi';\nconst FETCH_TIMEOUT = 15_000;\n\n/**\n * Make an authenticated Hume API request.\n * Auth via X-Hume-Api-Key header.\n */\nasync function humeFetch(\n path: string,\n apiKey: string,\n method: 'GET' | 'POST' | 'DELETE' = 'GET',\n body?: unknown,\n): Promise<{ ok: boolean; status: number; data: any }> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT);\n\n try {\n const resp = await fetch(`${HUME_API}${path}`, {\n method,\n headers: {\n 'X-Hume-Api-Key': apiKey,\n 'Content-Type': 'application/json',\n },\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n // DELETE returns 204 No Content\n if (resp.status === 204) {\n return { ok: true, status: 204, data: null };\n }\n\n const json = await resp.json();\n return { ok: resp.ok, status: resp.status, data: json };\n } catch (err: any) {\n return { ok: false, status: 0, data: { message: err.message } };\n } finally {\n clearTimeout(timeout);\n }\n}\n\n/**\n * Create a workspace-specific Hume EVI config by cloning the template config.\n *\n * Steps:\n * 1. Resolve config name from name_pattern with placeholders\n * 2. Check if config already exists (idempotent)\n * 3. GET template config to extract voice, prompt, tools, etc.\n * 4. POST new config with workspace-specific BYOLLM URL\n */\nexport async function createHumeConfig(\n config: HumeConfig,\n placeholders: TemplatePlaceholders,\n): Promise<HumeResult> {\n const steps: string[] = [];\n\n // Resolve API key\n const apiKey = process.env[config.api_key_env || 'HUME_API_KEY'];\n if (!apiKey) {\n return { success: false, steps: [`[hume] API key not found in env var ${config.api_key_env || 'HUME_API_KEY'}`] };\n }\n\n // Resolve config name and BYOLLM URL\n const configName = replacePlaceholders(config.name_pattern, placeholders);\n const byollmUrl = replacePlaceholders(config.byollm_url_pattern, placeholders);\n steps.push(`[hume] Target config: ${configName}`);\n steps.push(`[hume] BYOLLM URL: ${byollmUrl}`);\n\n // Check if config already exists (idempotent)\n const listResult = await humeFetch(`/configs?name=${encodeURIComponent(configName)}`, apiKey);\n if (listResult.ok) {\n const configs = listResult.data?.configs_page ?? [];\n const existing = Array.isArray(configs)\n ? configs.find((c: any) => c.name === configName)\n : null;\n if (existing) {\n steps.push(`[hume] Config \"${configName}\" already exists (ID: ${existing.id}), skipping creation`);\n return { success: true, steps, configId: existing.id, configName };\n }\n }\n\n // GET template config (API returns paginated format even for single-config lookup)\n const templateResult = await humeFetch(`/configs/${config.template_config_id}`, apiKey);\n if (!templateResult.ok) {\n steps.push(`[hume] Failed to get template config ${config.template_config_id}: ${JSON.stringify(templateResult.data)}`);\n return { success: false, steps };\n }\n\n // Extract config from paginated response\n const templatePage = templateResult.data?.configs_page;\n const template = Array.isArray(templatePage) ? templatePage[0] : templateResult.data;\n if (!template || !template.id) {\n steps.push(`[hume] Template config ${config.template_config_id} not found in response`);\n return { success: false, steps };\n }\n steps.push(`[hume] Read template config: ${template.name || config.template_config_id}`);\n\n // Build new config payload — clone template but override name and BYOLLM URL\n const newConfig: Record<string, any> = {\n name: configName,\n evi_version: template.evi_version || '3',\n language_model: {\n model_provider: 'CUSTOM_LANGUAGE_MODEL',\n model_resource: byollmUrl,\n },\n };\n\n // Preserve voice from template\n if (template.voice) {\n newConfig.voice = template.voice;\n }\n\n // Preserve prompt from template\n if (template.prompt) {\n newConfig.prompt = template.prompt;\n }\n\n // Preserve event messages from template\n if (template.event_messages) {\n newConfig.event_messages = template.event_messages;\n }\n\n // Preserve timeouts from template\n if (template.timeouts) {\n newConfig.timeouts = template.timeouts;\n }\n\n // Preserve tools from template\n if (template.tools) {\n newConfig.tools = template.tools;\n }\n\n // Preserve builtin_tools from template\n if (template.builtin_tools) {\n newConfig.builtin_tools = template.builtin_tools;\n }\n\n // Preserve ellm_model (quick responses) from template\n if (template.ellm_model) {\n newConfig.ellm_model = template.ellm_model;\n }\n\n // Create new config\n const createResult = await humeFetch('/configs', apiKey, 'POST', newConfig);\n if (!createResult.ok) {\n steps.push(`[hume] Failed to create config: ${JSON.stringify(createResult.data)}`);\n return { success: false, steps };\n }\n\n const newId = createResult.data?.id;\n steps.push(`[hume] Created config \"${configName}\" (ID: ${newId})`);\n\n return { success: true, steps, configId: newId, configName };\n}\n\n/**\n * Delete a workspace-specific Hume EVI config.\n *\n * Steps:\n * 1. List configs matching the workspace name\n * 2. DELETE each match\n */\nexport async function deleteHumeConfig(\n config: HumeConfig,\n placeholders: TemplatePlaceholders,\n): Promise<HumeResult> {\n const steps: string[] = [];\n\n // Resolve API key\n const apiKey = process.env[config.api_key_env || 'HUME_API_KEY'];\n if (!apiKey) {\n return { success: false, steps: [`[hume] API key not found in env var ${config.api_key_env || 'HUME_API_KEY'}`] };\n }\n\n const configName = replacePlaceholders(config.name_pattern, placeholders);\n steps.push(`[hume] Looking for config: ${configName}`);\n\n // List configs matching the name\n const listResult = await humeFetch(`/configs?name=${encodeURIComponent(configName)}`, apiKey);\n if (!listResult.ok) {\n steps.push(`[hume] Failed to list configs: ${JSON.stringify(listResult.data)}`);\n return { success: false, steps };\n }\n\n const configs = listResult.data?.configs_page ?? [];\n const matches = Array.isArray(configs)\n ? configs.filter((c: any) => c.name === configName)\n : [];\n\n if (matches.length === 0) {\n steps.push(`[hume] No config found with name \"${configName}\"`);\n return { success: true, steps };\n }\n\n let allOk = true;\n for (const match of matches) {\n const delResult = await humeFetch(`/configs/${match.id}`, apiKey, 'DELETE');\n if (delResult.ok) {\n steps.push(`[hume] Deleted config \"${configName}\" (ID: ${match.id})`);\n } else {\n steps.push(`[hume] Failed to delete config ${match.id}: ${JSON.stringify(delResult.data)}`);\n allOk = false;\n }\n }\n\n return { success: allOk, steps };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"hume-DoCbph2h.js","names":[],"sources":["../src/lib/hume.ts"],"sourcesContent":["/**\n * Hume EVI Config Management\n *\n * Manages per-workspace Hume EVI configs for BYOLLM (Bring Your Own LLM).\n * Called during workspace create (createHumeConfig) and workspace remove/deep-wipe (deleteHumeConfig).\n *\n * Pattern mirrors tunnel.ts — stateless CRUD against external API.\n */\n\nimport { HumeConfig, TemplatePlaceholders, replacePlaceholders } from './workspace-config.js';\n\nexport interface HumeResult {\n success: boolean;\n steps: string[];\n /** Populated on successful create */\n configId?: string;\n configName?: string;\n}\n\nconst HUME_API = 'https://api.hume.ai/v0/evi';\nconst FETCH_TIMEOUT = 15_000;\n\n/**\n * Make an authenticated Hume API request.\n * Auth via X-Hume-Api-Key header.\n */\nasync function humeFetch(\n path: string,\n apiKey: string,\n method: 'GET' | 'POST' | 'DELETE' = 'GET',\n body?: unknown,\n): Promise<{ ok: boolean; status: number; data: any }> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT);\n\n try {\n const resp = await fetch(`${HUME_API}${path}`, {\n method,\n headers: {\n 'X-Hume-Api-Key': apiKey,\n 'Content-Type': 'application/json',\n },\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n // DELETE returns 204 No Content\n if (resp.status === 204) {\n return { ok: true, status: 204, data: null };\n }\n\n const json = await resp.json();\n return { ok: resp.ok, status: resp.status, data: json };\n } catch (err: any) {\n return { ok: false, status: 0, data: { message: err.message } };\n } finally {\n clearTimeout(timeout);\n }\n}\n\n/**\n * Create a workspace-specific Hume EVI config by cloning the template config.\n *\n * Steps:\n * 1. Resolve config name from name_pattern with placeholders\n * 2. Check if config already exists (idempotent)\n * 3. GET template config to extract voice, prompt, tools, etc.\n * 4. POST new config with workspace-specific BYOLLM URL\n */\nexport async function createHumeConfig(\n config: HumeConfig,\n placeholders: TemplatePlaceholders,\n): Promise<HumeResult> {\n const steps: string[] = [];\n\n // Resolve API key\n const apiKey = process.env[config.api_key_env || 'HUME_API_KEY'];\n if (!apiKey) {\n return { success: false, steps: [`[hume] API key not found in env var ${config.api_key_env || 'HUME_API_KEY'}`] };\n }\n\n // Resolve config name and BYOLLM URL\n const configName = replacePlaceholders(config.name_pattern, placeholders);\n const byollmUrl = replacePlaceholders(config.byollm_url_pattern, placeholders);\n steps.push(`[hume] Target config: ${configName}`);\n steps.push(`[hume] BYOLLM URL: ${byollmUrl}`);\n\n // Check if config already exists (idempotent)\n const listResult = await humeFetch(`/configs?name=${encodeURIComponent(configName)}`, apiKey);\n if (listResult.ok) {\n const configs = listResult.data?.configs_page ?? [];\n const existing = Array.isArray(configs)\n ? configs.find((c: any) => c.name === configName)\n : null;\n if (existing) {\n steps.push(`[hume] Config \"${configName}\" already exists (ID: ${existing.id}), skipping creation`);\n return { success: true, steps, configId: existing.id, configName };\n }\n }\n\n // GET template config (API returns paginated format even for single-config lookup)\n const templateResult = await humeFetch(`/configs/${config.template_config_id}`, apiKey);\n if (!templateResult.ok) {\n steps.push(`[hume] Failed to get template config ${config.template_config_id}: ${JSON.stringify(templateResult.data)}`);\n return { success: false, steps };\n }\n\n // Extract config from paginated response\n const templatePage = templateResult.data?.configs_page;\n const template = Array.isArray(templatePage) ? templatePage[0] : templateResult.data;\n if (!template || !template.id) {\n steps.push(`[hume] Template config ${config.template_config_id} not found in response`);\n return { success: false, steps };\n }\n steps.push(`[hume] Read template config: ${template.name || config.template_config_id}`);\n\n // Build new config payload — clone template but override name and BYOLLM URL\n const newConfig: Record<string, any> = {\n name: configName,\n evi_version: template.evi_version || '3',\n language_model: {\n model_provider: 'CUSTOM_LANGUAGE_MODEL',\n model_resource: byollmUrl,\n },\n };\n\n // Preserve voice from template\n if (template.voice) {\n newConfig.voice = template.voice;\n }\n\n // Preserve prompt from template\n if (template.prompt) {\n newConfig.prompt = template.prompt;\n }\n\n // Preserve event messages from template\n if (template.event_messages) {\n newConfig.event_messages = template.event_messages;\n }\n\n // Preserve timeouts from template\n if (template.timeouts) {\n newConfig.timeouts = template.timeouts;\n }\n\n // Preserve tools from template\n if (template.tools) {\n newConfig.tools = template.tools;\n }\n\n // Preserve builtin_tools from template\n if (template.builtin_tools) {\n newConfig.builtin_tools = template.builtin_tools;\n }\n\n // Preserve ellm_model (quick responses) from template\n if (template.ellm_model) {\n newConfig.ellm_model = template.ellm_model;\n }\n\n // Create new config\n const createResult = await humeFetch('/configs', apiKey, 'POST', newConfig);\n if (!createResult.ok) {\n steps.push(`[hume] Failed to create config: ${JSON.stringify(createResult.data)}`);\n return { success: false, steps };\n }\n\n const newId = createResult.data?.id;\n steps.push(`[hume] Created config \"${configName}\" (ID: ${newId})`);\n\n return { success: true, steps, configId: newId, configName };\n}\n\n/**\n * Delete a workspace-specific Hume EVI config.\n *\n * Steps:\n * 1. List configs matching the workspace name\n * 2. DELETE each match\n */\nexport async function deleteHumeConfig(\n config: HumeConfig,\n placeholders: TemplatePlaceholders,\n): Promise<HumeResult> {\n const steps: string[] = [];\n\n // Resolve API key\n const apiKey = process.env[config.api_key_env || 'HUME_API_KEY'];\n if (!apiKey) {\n return { success: false, steps: [`[hume] API key not found in env var ${config.api_key_env || 'HUME_API_KEY'}`] };\n }\n\n const configName = replacePlaceholders(config.name_pattern, placeholders);\n steps.push(`[hume] Looking for config: ${configName}`);\n\n // List configs matching the name\n const listResult = await humeFetch(`/configs?name=${encodeURIComponent(configName)}`, apiKey);\n if (!listResult.ok) {\n steps.push(`[hume] Failed to list configs: ${JSON.stringify(listResult.data)}`);\n return { success: false, steps };\n }\n\n const configs = listResult.data?.configs_page ?? [];\n const matches = Array.isArray(configs)\n ? configs.filter((c: any) => c.name === configName)\n : [];\n\n if (matches.length === 0) {\n steps.push(`[hume] No config found with name \"${configName}\"`);\n return { success: true, steps };\n }\n\n let allOk = true;\n for (const match of matches) {\n const delResult = await humeFetch(`/configs/${match.id}`, apiKey, 'DELETE');\n if (delResult.ok) {\n steps.push(`[hume] Deleted config \"${configName}\" (ID: ${match.id})`);\n } else {\n steps.push(`[hume] Failed to delete config ${match.id}: ${JSON.stringify(delResult.data)}`);\n allOk = false;\n }\n }\n\n return { success: allOk, steps };\n}\n"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -59,6 +59,21 @@ declare const PROJECT_PRDS_COMPLETED_SUBDIR = "completed";
|
|
|
59
59
|
* 2. The SOURCE_DEV_SKILLS_DIR exists (only present in repo, not in npm package)
|
|
60
60
|
*/
|
|
61
61
|
declare function isDevMode(): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Encode a filesystem path to match Claude Code's project directory naming.
|
|
64
|
+
*
|
|
65
|
+
* Claude Code replaces ALL non-alphanumeric characters (except hyphens) with
|
|
66
|
+
* hyphens when encoding the CWD into the project directory name under
|
|
67
|
+
* ~/.claude/projects/. For example:
|
|
68
|
+
*
|
|
69
|
+
* /Users/edward.becker/Projects → -Users-edward-becker-Projects
|
|
70
|
+
* /home/eltmon/Projects → -home-eltmon-Projects
|
|
71
|
+
* /tmp/test_under.dot+plus@at → -tmp-test-under-dot-plus-at
|
|
72
|
+
*
|
|
73
|
+
* This is critical for session file lookup — a mismatch means JSONL files
|
|
74
|
+
* are never found and conversation messages appear permanently empty.
|
|
75
|
+
*/
|
|
76
|
+
declare function encodeClaudeProjectDir(cwdPath: string): string;
|
|
62
77
|
declare const INIT_DIRS: string[];
|
|
63
78
|
//#endregion
|
|
64
79
|
//#region src/lib/tracker/interface.d.ts
|
|
@@ -670,7 +685,7 @@ declare function getLinkManager(): LinkManager;
|
|
|
670
685
|
type AnthropicModel = 'claude-opus-4-6' | 'claude-sonnet-4-6' | 'claude-sonnet-4-5' | 'claude-haiku-4-5';
|
|
671
686
|
type OpenAIModel = 'gpt-5.2-codex' | 'o3-deep-research' | 'gpt-4o' | 'gpt-4o-mini';
|
|
672
687
|
type GoogleModel = 'gemini-3-pro-preview' | 'gemini-3-flash-preview' | 'gemini-2.5-pro' | 'gemini-2.5-flash';
|
|
673
|
-
type ZAIModel = 'glm-4.7
|
|
688
|
+
type ZAIModel = 'glm-4.7-flash';
|
|
674
689
|
type KimiModel = 'kimi-k2' | 'kimi-k2.5';
|
|
675
690
|
type MiniMaxModel = 'minimax-m2.7' | 'minimax-m2.7-highspeed';
|
|
676
691
|
type ModelId = AnthropicModel | OpenAIModel | GoogleModel | ZAIModel | KimiModel | MiniMaxModel;
|
|
@@ -828,5 +843,5 @@ declare function setupCredentialFileAuth(provider: ProviderConfig, workspacePath
|
|
|
828
843
|
*/
|
|
829
844
|
declare function clearCredentialFileAuth(workspacePath: string): void;
|
|
830
845
|
//#endregion
|
|
831
|
-
export { AGENTS_DIR, ARCHIVES_DIR, AnthropicModel, ApiKeysConfig, BACKUPS_DIR, BIN_DIR, BackupInfo, 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, Comment, ComplexityLevel, ComplexityModels, DOCS_DIR, DevrootSyncItem, GitHubConfig, GitHubTracker, GitLabConfig, GitLabTracker, GoogleModel, HEARTBEATS_DIR, HookItem, INIT_DIRS, Issue, IssueFilters, IssueNotFoundError, IssueState, IssueTracker, IssueUpdate, KimiModel, LEGACY_RUNTIME_DIRS, LinearConfig, LinearTracker, LinkDirection, LinkManager, MigrationResult, MiniMaxModel, ModelId, ModelsConfig, NewIssue, NotImplementedError, OpenAIModel, 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, PanopticonConfig, ProviderAuthType, ProviderCompatibility, ProviderConfig, ProviderName, RallyConfig, RefreshCacheResult, RemoteConfig, RemoteFlyConfig, 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, SettingsConfig, ShadowConfig, Shell, SpecialistModels, SyncItem, SyncOptions, SyncPlan, SyncResult, TEMPLATES_DIR, TRAEFIK_CERTS_DIR, TRAEFIK_DIR, TRAEFIK_DYNAMIC_DIR, TrackerAuthError, TrackerConfig, TrackerConfigItem, TrackerLink, TrackerType, TrackersConfig, ZAIModel, 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 };
|
|
846
|
+
export { AGENTS_DIR, ARCHIVES_DIR, AnthropicModel, ApiKeysConfig, BACKUPS_DIR, BIN_DIR, BackupInfo, 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, Comment, ComplexityLevel, ComplexityModels, DOCS_DIR, DevrootSyncItem, GitHubConfig, GitHubTracker, GitLabConfig, GitLabTracker, GoogleModel, HEARTBEATS_DIR, HookItem, INIT_DIRS, Issue, IssueFilters, IssueNotFoundError, IssueState, IssueTracker, IssueUpdate, KimiModel, LEGACY_RUNTIME_DIRS, LinearConfig, LinearTracker, LinkDirection, LinkManager, MigrationResult, MiniMaxModel, ModelId, ModelsConfig, NewIssue, NotImplementedError, OpenAIModel, 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, PanopticonConfig, ProviderAuthType, ProviderCompatibility, ProviderConfig, ProviderName, RallyConfig, RefreshCacheResult, RemoteConfig, RemoteFlyConfig, 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, SettingsConfig, ShadowConfig, Shell, SpecialistModels, SyncItem, SyncOptions, SyncPlan, SyncResult, TEMPLATES_DIR, TRAEFIK_CERTS_DIR, TRAEFIK_DIR, TRAEFIK_DYNAMIC_DIR, TrackerAuthError, TrackerConfig, TrackerConfigItem, TrackerLink, TrackerType, TrackersConfig, ZAIModel, 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 };
|
|
832
847
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/lib/paths.ts","../src/lib/tracker/interface.ts","../src/lib/config.ts","../src/lib/shell.ts","../src/lib/backup.ts","../src/lib/manifest.ts","../src/lib/sync.ts","../src/lib/tracker/linear.ts","../src/lib/tracker/github.ts","../src/lib/tracker/gitlab.ts","../src/lib/tracker/factory.ts","../src/lib/tracker/linking.ts","../src/lib/settings.ts","../src/lib/providers.ts"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/lib/paths.ts","../src/lib/tracker/interface.ts","../src/lib/config.ts","../src/lib/shell.ts","../src/lib/backup.ts","../src/lib/manifest.ts","../src/lib/sync.ts","../src/lib/tracker/linear.ts","../src/lib/tracker/github.ts","../src/lib/tracker/gitlab.ts","../src/lib/tracker/factory.ts","../src/lib/tracker/linking.ts","../src/lib/settings.ts","../src/lib/providers.ts"],"mappings":"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"}
|