@knpkv/control-center 0.9.4 → 0.9.5
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/dist/client/.vite/manifest.json +406 -406
- package/dist/client/assets/ActiveWorkPage-CeWw2uZl.js +2 -0
- package/dist/client/assets/ActiveWorkPage-CeWw2uZl.js.map +1 -0
- package/dist/client/assets/{AgentPage-YiYORLod.js → AgentPage-BAy7IgjJ.js} +3 -3
- package/dist/client/assets/AgentPage-BAy7IgjJ.js.map +1 -0
- package/dist/client/assets/{AtlassianOAuthCallbackPage-PfsrTytb.js → AtlassianOAuthCallbackPage-DDCTmcmB.js} +2 -2
- package/dist/client/assets/AtlassianOAuthCallbackPage-DDCTmcmB.js.map +1 -0
- package/dist/client/assets/{AuthorizedSharePage-BCwnILXF.js → AuthorizedSharePage-BZPfotuK.js} +2 -2
- package/dist/client/assets/AuthorizedSharePage-BZPfotuK.js.map +1 -0
- package/dist/client/assets/{BrowserSessionHydrator-BAb76EvO.js → BrowserSessionHydrator-B3yI9F2z.js} +2 -2
- package/dist/client/assets/{BrowserSessionHydrator-BAb76EvO.js.map → BrowserSessionHydrator-B3yI9F2z.js.map} +1 -1
- package/dist/client/assets/{CommandSearch-BSVXQfjF.js → CommandSearch-BrwiVFBI.js} +2 -2
- package/dist/client/assets/{CommandSearch-BSVXQfjF.js.map → CommandSearch-BrwiVFBI.js.map} +1 -1
- package/dist/client/assets/Domain-DH_T_LJ8.js.map +1 -1
- package/dist/client/assets/{ItemsPage-BzinDuxs.js → ItemsPage-CYmo7Dkm.js} +2 -2
- package/dist/client/assets/ItemsPage-CYmo7Dkm.js.map +1 -0
- package/dist/client/assets/{OpenPullRequestPage-BABGk9v2.js → OpenPullRequestPage-BcwTerpY.js} +2 -2
- package/dist/client/assets/OpenPullRequestPage-BcwTerpY.js.map +1 -0
- package/dist/client/assets/{Pages-Bfn7_LhJ.js → Pages-Cj24BSjm.js} +2 -2
- package/dist/client/assets/{Pages-Bfn7_LhJ.js.map → Pages-Cj24BSjm.js.map} +1 -1
- package/dist/client/assets/{PairPage-4meDmW_A.js → PairPage-JhivkRf1.js} +2 -2
- package/dist/client/assets/PairPage-JhivkRf1.js.map +1 -0
- package/dist/client/assets/PortfolioOverview-C0RZCx6V.js +2 -0
- package/dist/client/assets/PortfolioOverview-C0RZCx6V.js.map +1 -0
- package/dist/client/assets/{PullRequestReviewPanel-68vgbLzs.js → PullRequestReviewPanel-BeYAld4m.js} +4 -4
- package/dist/client/assets/{PullRequestReviewPanel-68vgbLzs.js.map → PullRequestReviewPanel-BeYAld4m.js.map} +1 -1
- package/dist/client/assets/ReleaseRoute-1bUQCSJi.js +2 -0
- package/dist/client/assets/ReleaseRoute-1bUQCSJi.js.map +1 -0
- package/dist/client/assets/{ReleaseWorkset-DcI6qwPE.js → ReleaseWorkset-DGufwIFe.js} +2 -2
- package/dist/client/assets/ReleaseWorkset-DGufwIFe.js.map +1 -0
- package/dist/client/assets/{ReviewSuggestionOverview-kNqjbwKQ.js → ReviewSuggestionOverview-CfU-Ynzq.js} +2 -2
- package/dist/client/assets/{ReviewSuggestionOverview-kNqjbwKQ.js.map → ReviewSuggestionOverview-CfU-Ynzq.js.map} +1 -1
- package/dist/client/assets/{ReviewSuggestionPublicationSurface-BtoYEprT.js → ReviewSuggestionPublicationSurface-DA-3PPs_.js} +2 -2
- package/dist/client/assets/ReviewSuggestionPublicationSurface-DA-3PPs_.js.map +1 -0
- package/dist/client/assets/{ServicesPage-DihUx1kr.js → ServicesPage-6G9OTRDn.js} +2 -2
- package/dist/client/assets/ServicesPage-6G9OTRDn.js.map +1 -0
- package/dist/client/assets/{TimelinePage-DyluBeEt.js → TimelinePage-D6YUtggO.js} +2 -2
- package/dist/client/assets/TimelinePage-D6YUtggO.js.map +1 -0
- package/dist/client/assets/{WorkspaceEntityLink-DjonIGqM.js → WorkspaceEntityLink-BqUurz8P.js} +2 -2
- package/dist/client/assets/{WorkspaceEntityLink-DjonIGqM.js.map → WorkspaceEntityLink-BqUurz8P.js.map} +1 -1
- package/dist/client/assets/{WorkspaceEntityRoute-DUVwW5WN.js → WorkspaceEntityRoute-CfupCFGN.js} +4 -4
- package/dist/client/assets/{WorkspaceEntityRoute-DUVwW5WN.js.map → WorkspaceEntityRoute-CfupCFGN.js.map} +1 -1
- package/dist/client/assets/{WorkspaceHomeLink-DSGM8jZK.js → WorkspaceHomeLink-DkAnxFk1.js} +2 -2
- package/dist/client/assets/{WorkspaceHomeLink-DSGM8jZK.js.map → WorkspaceHomeLink-DkAnxFk1.js.map} +1 -1
- package/dist/client/assets/{WorkspacePullRequestDetails-Z3MfihsH.js → WorkspacePullRequestDetails-SexYOZUB.js} +3 -3
- package/dist/client/assets/{WorkspacePullRequestDetails-Z3MfihsH.js.map → WorkspacePullRequestDetails-SexYOZUB.js.map} +1 -1
- package/dist/client/assets/{WorkspaceReleaseLayout-S6XHWEwh.js → WorkspaceReleaseLayout-J_IWrKc9.js} +2 -2
- package/dist/client/assets/{WorkspaceReleaseLayout-S6XHWEwh.js.map → WorkspaceReleaseLayout-J_IWrKc9.js.map} +1 -1
- package/dist/client/assets/{WorkspaceSettingsPage-Dn_eDC3m.js → WorkspaceSettingsPage-CFB0X_Oz.js} +2 -2
- package/dist/client/assets/WorkspaceSettingsPage-CFB0X_Oz.js.map +1 -0
- package/dist/client/assets/{angular-html-B-gwpVlh-DEM_d4RI.js → angular-html-B-gwpVlh-BHk2rITT.js} +2 -2
- package/dist/client/assets/{angular-html-B-gwpVlh-DEM_d4RI.js.map → angular-html-B-gwpVlh-BHk2rITT.js.map} +1 -1
- package/dist/client/assets/{angular-ts-BdaH9qH_-6UMLodBB.js → angular-ts-BdaH9qH_-DDpR3-gU.js} +2 -2
- package/dist/client/assets/{angular-ts-BdaH9qH_-6UMLodBB.js.map → angular-ts-BdaH9qH_-DDpR3-gU.js.map} +1 -1
- package/dist/client/assets/{apl-BLTDDucx-DIkkahEc.js → apl-BLTDDucx-C5lAAuBL.js} +2 -2
- package/dist/client/assets/{apl-BLTDDucx-DIkkahEc.js.map → apl-BLTDDucx-C5lAAuBL.js.map} +1 -1
- package/dist/client/assets/{astro-CM3EIsEH-D5DYxAYu.js → astro-CM3EIsEH-C-4mMpDY.js} +2 -2
- package/dist/client/assets/{astro-CM3EIsEH-D5DYxAYu.js.map → astro-CM3EIsEH-C-4mMpDY.js.map} +1 -1
- package/dist/client/assets/{blade-BuLZ1b4i-CBKkB_Nt.js → blade-BuLZ1b4i-Bo26Vrie.js} +2 -2
- package/dist/client/assets/{blade-BuLZ1b4i-CBKkB_Nt.js.map → blade-BuLZ1b4i-Bo26Vrie.js.map} +1 -1
- package/dist/client/assets/{c-BOe7FNWg-C15nlYFX.js → c-BOe7FNWg-Bn-hh2gC.js} +2 -2
- package/dist/client/assets/{c-BOe7FNWg-C15nlYFX.js.map → c-BOe7FNWg-Bn-hh2gC.js.map} +1 -1
- package/dist/client/assets/{chapel-DS426I0C-DoL0pgIr.js → chapel-DS426I0C-DZfMl2AF.js} +2 -2
- package/dist/client/assets/{chapel-DS426I0C-DoL0pgIr.js.map → chapel-DS426I0C-DZfMl2AF.js.map} +1 -1
- package/dist/client/assets/{cobol-D88xw2SU-DlPiznQQ.js → cobol-D88xw2SU-Dszzocsd.js} +2 -2
- package/dist/client/assets/{cobol-D88xw2SU-DlPiznQQ.js.map → cobol-D88xw2SU-Dszzocsd.js.map} +1 -1
- package/dist/client/assets/{coffee-9O-pYXz5-QB78c27T.js → coffee-9O-pYXz5-B-EAY7Cr.js} +2 -2
- package/dist/client/assets/{coffee-9O-pYXz5-QB78c27T.js.map → coffee-9O-pYXz5-B-EAY7Cr.js.map} +1 -1
- package/dist/client/assets/{controlCenterRelayDock-CDyCPu8u.js → controlCenterRelayDock-Bq4z8Xad.js} +3 -3
- package/dist/client/assets/{controlCenterRelayDock-CDyCPu8u.js.map → controlCenterRelayDock-Bq4z8Xad.js.map} +1 -1
- package/dist/client/assets/{controlCenterRelayDockChrome-BWLgzJhc.js → controlCenterRelayDockChrome-M45VQcSE.js} +2 -2
- package/dist/client/assets/{controlCenterRelayDockChrome-BWLgzJhc.js.map → controlCenterRelayDockChrome-M45VQcSE.js.map} +1 -1
- package/dist/client/assets/{cpp-CPk7VU6o-XEasjJQb.js → cpp-CPk7VU6o-B1PTCDWN.js} +2 -2
- package/dist/client/assets/{cpp-CPk7VU6o-XEasjJQb.js.map → cpp-CPk7VU6o-B1PTCDWN.js.map} +1 -1
- package/dist/client/assets/{crystal-CRftOMVe-Cl7VOKqv.js → crystal-CRftOMVe-3NFSGC4Y.js} +2 -2
- package/dist/client/assets/{crystal-CRftOMVe-Cl7VOKqv.js.map → crystal-CRftOMVe-3NFSGC4Y.js.map} +1 -1
- package/dist/client/assets/{css-DKjIhbA_-BqYkMclh.js → css-DKjIhbA_-BZzy1gno.js} +2 -2
- package/dist/client/assets/{css-DKjIhbA_-BqYkMclh.js.map → css-DKjIhbA_-BZzy1gno.js.map} +1 -1
- package/dist/client/assets/{diff-c2VIds2u.js → diff-CuvBMVEl.js} +3 -3
- package/dist/client/assets/{diff-c2VIds2u.js.map → diff-CuvBMVEl.js.map} +1 -1
- package/dist/client/assets/{edge-CZci3foK-CcvbLJND.js → edge-CZci3foK-BdZTWeOq.js} +2 -2
- package/dist/client/assets/{edge-CZci3foK-CcvbLJND.js.map → edge-CZci3foK-BdZTWeOq.js.map} +1 -1
- package/dist/client/assets/{elixir-BFbWRTPN-DCo1tsYk.js → elixir-BFbWRTPN-BSsfSNAc.js} +2 -2
- package/dist/client/assets/{elixir-BFbWRTPN-DCo1tsYk.js.map → elixir-BFbWRTPN-BSsfSNAc.js.map} +1 -1
- package/dist/client/assets/{elm-BFCSOEGh-KAuEEkOS.js → elm-BFCSOEGh-B7etdM00.js} +2 -2
- package/dist/client/assets/{elm-BFCSOEGh-KAuEEkOS.js.map → elm-BFCSOEGh-B7etdM00.js.map} +1 -1
- package/dist/client/assets/{erb-C0EkZJvn-3O5TlDRJ.js → erb-C0EkZJvn-BUpElafA.js} +2 -2
- package/dist/client/assets/{erb-C0EkZJvn-3O5TlDRJ.js.map → erb-C0EkZJvn-BUpElafA.js.map} +1 -1
- package/dist/client/assets/{git-rebase-DBDs07B2-BKfziPiX.js → git-rebase-DBDs07B2-3YW7dddl.js} +2 -2
- package/dist/client/assets/{git-rebase-DBDs07B2-BKfziPiX.js.map → git-rebase-DBDs07B2-3YW7dddl.js.map} +1 -1
- package/dist/client/assets/{glimmer-js-oqYt1Bty-oOPiIwDh.js → glimmer-js-oqYt1Bty-Q18N5198.js} +2 -2
- package/dist/client/assets/{glimmer-js-oqYt1Bty-oOPiIwDh.js.map → glimmer-js-oqYt1Bty-Q18N5198.js.map} +1 -1
- package/dist/client/assets/{glimmer-ts-CjmgbZTn-C8gjUbKN.js → glimmer-ts-CjmgbZTn-DflPUBBN.js} +2 -2
- package/dist/client/assets/{glimmer-ts-CjmgbZTn-C8gjUbKN.js.map → glimmer-ts-CjmgbZTn-DflPUBBN.js.map} +1 -1
- package/dist/client/assets/{glsl-BqUMGrwT-5PoVKbXD.js → glsl-BqUMGrwT-DZSnNyRQ.js} +2 -2
- package/dist/client/assets/{glsl-BqUMGrwT-5PoVKbXD.js.map → glsl-BqUMGrwT-DZSnNyRQ.js.map} +1 -1
- package/dist/client/assets/{graphql-CEJryLGF-Bx3HP-fV.js → graphql-CEJryLGF-BxoDC-bv.js} +2 -2
- package/dist/client/assets/{graphql-CEJryLGF-Bx3HP-fV.js.map → graphql-CEJryLGF-BxoDC-bv.js.map} +1 -1
- package/dist/client/assets/{hack-DwBIwaGr-C2bRI1k_.js → hack-DwBIwaGr-BD9UbS9V.js} +2 -2
- package/dist/client/assets/{hack-DwBIwaGr-C2bRI1k_.js.map → hack-DwBIwaGr-BD9UbS9V.js.map} +1 -1
- package/dist/client/assets/{haml-BgD6GFV2-C-E92qmq.js → haml-BgD6GFV2-tYRnxnkA.js} +2 -2
- package/dist/client/assets/{haml-BgD6GFV2-C-E92qmq.js.map → haml-BgD6GFV2-tYRnxnkA.js.map} +1 -1
- package/dist/client/assets/{handlebars-DAEAtsmp-B3Qkz-fG.js → handlebars-DAEAtsmp-CzuHoTaP.js} +2 -2
- package/dist/client/assets/{handlebars-DAEAtsmp-B3Qkz-fG.js.map → handlebars-DAEAtsmp-CzuHoTaP.js.map} +1 -1
- package/dist/client/assets/{html-B63qAdeQ-mzUq7RfB.js → html-B63qAdeQ-BvgXBi7v.js} +2 -2
- package/dist/client/assets/{html-B63qAdeQ-mzUq7RfB.js.map → html-B63qAdeQ-BvgXBi7v.js.map} +1 -1
- package/dist/client/assets/{html-derivative-DliF0Izh-DKttJgx1.js → html-derivative-DliF0Izh-BdazZa_A.js} +2 -2
- package/dist/client/assets/{html-derivative-DliF0Izh-DKttJgx1.js.map → html-derivative-DliF0Izh-BdazZa_A.js.map} +1 -1
- package/dist/client/assets/{http-BPdteiK2-BzL978Ty.js → http-BPdteiK2-DscIPq9Z.js} +2 -2
- package/dist/client/assets/{http-BPdteiK2-BzL978Ty.js.map → http-BPdteiK2-DscIPq9Z.js.map} +1 -1
- package/dist/client/assets/{hurl-y6bQoMbn-VmDIgNNg.js → hurl-y6bQoMbn-BniTWOKW.js} +2 -2
- package/dist/client/assets/{hurl-y6bQoMbn-VmDIgNNg.js.map → hurl-y6bQoMbn-BniTWOKW.js.map} +1 -1
- package/dist/client/assets/{index-BHQ_NP1r.js → index-DlDEYM2e.js} +3 -3
- package/dist/client/assets/{index-BHQ_NP1r.js.map → index-DlDEYM2e.js.map} +1 -1
- package/dist/client/assets/index-vGJLpF-N.css +1 -0
- package/dist/client/assets/{java-HDTZqoJ--r_CiLO3G.js → java-HDTZqoJ--DonfC-m-.js} +2 -2
- package/dist/client/assets/{java-HDTZqoJ--r_CiLO3G.js.map → java-HDTZqoJ--DonfC-m-.js.map} +1 -1
- package/dist/client/assets/{javascript-B8-PXjxO-D8IL8RVw.js → javascript-B8-PXjxO-DrojTnjU.js} +2 -2
- package/dist/client/assets/{javascript-B8-PXjxO-D8IL8RVw.js.map → javascript-B8-PXjxO-DrojTnjU.js.map} +1 -1
- package/dist/client/assets/{jinja-Li2helwk-iQ5WpNSs.js → jinja-Li2helwk-Bn7ViII1.js} +2 -2
- package/dist/client/assets/{jinja-Li2helwk-iQ5WpNSs.js.map → jinja-Li2helwk-Bn7ViII1.js.map} +1 -1
- package/dist/client/assets/{jison-D4pd2L4r-CnB2TCTC.js → jison-D4pd2L4r-CURwtPm2.js} +2 -2
- package/dist/client/assets/{jison-D4pd2L4r-CnB2TCTC.js.map → jison-D4pd2L4r-CURwtPm2.js.map} +1 -1
- package/dist/client/assets/{json-CHeq_08V-BzfhDAQG.js → json-CHeq_08V-DGJ-08B3.js} +2 -2
- package/dist/client/assets/{json-CHeq_08V-BzfhDAQG.js.map → json-CHeq_08V-DGJ-08B3.js.map} +1 -1
- package/dist/client/assets/{jsx-CTDAtxCE-BHaCLB5C.js → jsx-CTDAtxCE-B7AjYoF3.js} +2 -2
- package/dist/client/assets/{jsx-CTDAtxCE-BHaCLB5C.js.map → jsx-CTDAtxCE-B7AjYoF3.js.map} +1 -1
- package/dist/client/assets/{julia-B8HGxjvO-DUNXU97h.js → julia-B8HGxjvO-CX2HXF0x.js} +2 -2
- package/dist/client/assets/{julia-B8HGxjvO-DUNXU97h.js.map → julia-B8HGxjvO-CX2HXF0x.js.map} +1 -1
- package/dist/client/assets/{just-C1IY8eCo-CwcMki68.js → just-C1IY8eCo-194MeSWx.js} +2 -2
- package/dist/client/assets/{just-C1IY8eCo-CwcMki68.js.map → just-C1IY8eCo-194MeSWx.js.map} +1 -1
- package/dist/client/assets/{latex-CWjLpLhK-C2bYvB1V.js → latex-CWjLpLhK-CJV_bAR4.js} +2 -2
- package/dist/client/assets/{latex-CWjLpLhK-C2bYvB1V.js.map → latex-CWjLpLhK-CJV_bAR4.js.map} +1 -1
- package/dist/client/assets/{liquid-DO0vm52w-5ftSWtSQ.js → liquid-DO0vm52w-C-oH3gBH.js} +2 -2
- package/dist/client/assets/{liquid-DO0vm52w-5ftSWtSQ.js.map → liquid-DO0vm52w-C-oH3gBH.js.map} +1 -1
- package/dist/client/assets/{lua-rOZn354j-BFEal9UY.js → lua-rOZn354j-CWNr0VLI.js} +2 -2
- package/dist/client/assets/{lua-rOZn354j-BFEal9UY.js.map → lua-rOZn354j-CWNr0VLI.js.map} +1 -1
- package/dist/client/assets/{marko-CiZdnOV9-VE4QpTYR.js → marko-CiZdnOV9-D1oeBgJ5.js} +2 -2
- package/dist/client/assets/{marko-CiZdnOV9-VE4QpTYR.js.map → marko-CiZdnOV9-D1oeBgJ5.js.map} +1 -1
- package/dist/client/assets/{mdc-D1ADfxGi-DASKK9_I.js → mdc-D1ADfxGi-DDe8MjBS.js} +2 -2
- package/dist/client/assets/{mdc-D1ADfxGi-DASKK9_I.js.map → mdc-D1ADfxGi-DDe8MjBS.js.map} +1 -1
- package/dist/client/assets/{nginx-8KXIzHX2-OWn8Z957.js → nginx-8KXIzHX2-76JDQPWv.js} +2 -2
- package/dist/client/assets/{nginx-8KXIzHX2-OWn8Z957.js.map → nginx-8KXIzHX2-76JDQPWv.js.map} +1 -1
- package/dist/client/assets/{nim-CbBDSJf5-DzS23snq.js → nim-CbBDSJf5-Bg0Tpvlj.js} +2 -2
- package/dist/client/assets/{nim-CbBDSJf5-DzS23snq.js.map → nim-CbBDSJf5-Bg0Tpvlj.js.map} +1 -1
- package/dist/client/assets/{org-BlnOvN6p-mzfee9SX.js → org-BlnOvN6p-CpQvn0Ms.js} +2 -2
- package/dist/client/assets/{org-BlnOvN6p-mzfee9SX.js.map → org-BlnOvN6p-CpQvn0Ms.js.map} +1 -1
- package/dist/client/assets/patterns-CJ4c7F5A.js +2 -0
- package/dist/client/assets/patterns-CJ4c7F5A.js.map +1 -0
- package/dist/client/assets/{perl-CntHWu4k-C3Q6THHX.js → perl-CntHWu4k-R8g6ivQx.js} +2 -2
- package/dist/client/assets/{perl-CntHWu4k-C3Q6THHX.js.map → perl-CntHWu4k-R8g6ivQx.js.map} +1 -1
- package/dist/client/assets/{php-VF06KE26-uqmHEtRE.js → php-VF06KE26-qz2OohxQ.js} +2 -2
- package/dist/client/assets/{php-VF06KE26-uqmHEtRE.js.map → php-VF06KE26-qz2OohxQ.js.map} +1 -1
- package/dist/client/assets/primitives-Dj-qYrUZ-BIf5RLs4.js +2 -0
- package/dist/client/assets/primitives-Dj-qYrUZ-BIf5RLs4.js.map +1 -0
- package/dist/client/assets/{pug-DeZwH1tK-Dy2R8X_Z.js → pug-DeZwH1tK-hE7p1XRn.js} +2 -2
- package/dist/client/assets/{pug-DeZwH1tK-Dy2R8X_Z.js.map → pug-DeZwH1tK-hE7p1XRn.js.map} +1 -1
- package/dist/client/assets/{pullRequestReviewThreadReplay-Dhslqjta.js → pullRequestReviewThreadReplay-D-FuOlQ0.js} +2 -2
- package/dist/client/assets/{pullRequestReviewThreadReplay-Dhslqjta.js.map → pullRequestReviewThreadReplay-D-FuOlQ0.js.map} +1 -1
- package/dist/client/assets/{qml-CQhAR2tt-CkperL57.js → qml-CQhAR2tt-Blcerr_b.js} +2 -2
- package/dist/client/assets/{qml-CQhAR2tt-CkperL57.js.map → qml-CQhAR2tt-Blcerr_b.js.map} +1 -1
- package/dist/client/assets/{r-CGShpgkr-BeuwoEHJ.js → r-CGShpgkr-Bu3ifplH.js} +2 -2
- package/dist/client/assets/{r-CGShpgkr-BeuwoEHJ.js.map → r-CGShpgkr-Bu3ifplH.js.map} +1 -1
- package/dist/client/assets/{razor-CgB2QCs6-C9kZAmAY.js → razor-CgB2QCs6-C0YckD9e.js} +2 -2
- package/dist/client/assets/{razor-CgB2QCs6-C9kZAmAY.js.map → razor-CgB2QCs6-C0YckD9e.js.map} +1 -1
- package/dist/client/assets/{regexp-go_CdRjx-BvThUXwF.js → regexp-go_CdRjx-FwuQxSe1.js} +2 -2
- package/dist/client/assets/{regexp-go_CdRjx-BvThUXwF.js.map → regexp-go_CdRjx-FwuQxSe1.js.map} +1 -1
- package/dist/client/assets/{releaseRoutes-D04aOk03.js → releaseRoutes-Bpw_kfZI.js} +2 -2
- package/dist/client/assets/{releaseRoutes-D04aOk03.js.map → releaseRoutes-Bpw_kfZI.js.map} +1 -1
- package/dist/client/assets/{rst-CbWMI8ou-B_CNFtWj.js → rst-CbWMI8ou-_a-jzVR0.js} +2 -2
- package/dist/client/assets/{rst-CbWMI8ou-B_CNFtWj.js.map → rst-CbWMI8ou-_a-jzVR0.js.map} +1 -1
- package/dist/client/assets/{ruby-DsGwIs06-BNNoCsny.js → ruby-DsGwIs06-CvuKCvaN.js} +2 -2
- package/dist/client/assets/{ruby-DsGwIs06-BNNoCsny.js.map → ruby-DsGwIs06-CvuKCvaN.js.map} +1 -1
- package/dist/client/assets/{sas-DjxN8J4Z-DQwiaVY0.js → sas-DjxN8J4Z-6vMiHBWz.js} +2 -2
- package/dist/client/assets/{sas-DjxN8J4Z-DQwiaVY0.js.map → sas-DjxN8J4Z-6vMiHBWz.js.map} +1 -1
- package/dist/client/assets/{scss-bkiiULjK-BdNohiDl.js → scss-bkiiULjK-RWkdLi31.js} +2 -2
- package/dist/client/assets/{scss-bkiiULjK-BdNohiDl.js.map → scss-bkiiULjK-RWkdLi31.js.map} +1 -1
- package/dist/client/assets/{shellscript-Cuh1SIPr-CH9Y9Zzx.js → shellscript-Cuh1SIPr-xep8lhFb.js} +2 -2
- package/dist/client/assets/{shellscript-Cuh1SIPr-CH9Y9Zzx.js.map → shellscript-Cuh1SIPr-xep8lhFb.js.map} +1 -1
- package/dist/client/assets/{shellsession-C4UOwxb7-BVPXZqFb.js → shellsession-C4UOwxb7-B2Mjt8G4.js} +2 -2
- package/dist/client/assets/{shellsession-C4UOwxb7-BVPXZqFb.js.map → shellsession-C4UOwxb7-B2Mjt8G4.js.map} +1 -1
- package/dist/client/assets/{soy-CeGFXpLT-bVeC_qdu.js → soy-CeGFXpLT-DB96q8ji.js} +2 -2
- package/dist/client/assets/{soy-CeGFXpLT-bVeC_qdu.js.map → soy-CeGFXpLT-DB96q8ji.js.map} +1 -1
- package/dist/client/assets/{sql-qDYmMTO1-DRMw6L4F.js → sql-qDYmMTO1-Dp7sA9Pq.js} +2 -2
- package/dist/client/assets/{sql-qDYmMTO1-DRMw6L4F.js.map → sql-qDYmMTO1-Dp7sA9Pq.js.map} +1 -1
- package/dist/client/assets/{stata-Dzus_rwP-DcGzBrZt.js → stata-Dzus_rwP-Bk81H3oK.js} +2 -2
- package/dist/client/assets/{stata-Dzus_rwP-DcGzBrZt.js.map → stata-Dzus_rwP-Bk81H3oK.js.map} +1 -1
- package/dist/client/assets/{surrealql-DmTrf8uR-BGVhamzy.js → surrealql-DmTrf8uR-BAVDL68E.js} +2 -2
- package/dist/client/assets/{surrealql-DmTrf8uR-BGVhamzy.js.map → surrealql-DmTrf8uR-BAVDL68E.js.map} +1 -1
- package/dist/client/assets/{svelte-CWlRonoS-d0HsRKWL.js → svelte-CWlRonoS-g4MbXmCf.js} +2 -2
- package/dist/client/assets/{svelte-CWlRonoS-d0HsRKWL.js.map → svelte-CWlRonoS-g4MbXmCf.js.map} +1 -1
- package/dist/client/assets/{templ-EuFg1gKs-BBJ25IwK.js → templ-EuFg1gKs-B9lc3TqB.js} +2 -2
- package/dist/client/assets/{templ-EuFg1gKs-BBJ25IwK.js.map → templ-EuFg1gKs-B9lc3TqB.js.map} +1 -1
- package/dist/client/assets/{tex-Cbbx1SXS-Dh8M7x1F.js → tex-Cbbx1SXS-DPEKlVuI.js} +2 -2
- package/dist/client/assets/{tex-Cbbx1SXS-Dh8M7x1F.js.map → tex-Cbbx1SXS-DPEKlVuI.js.map} +1 -1
- package/dist/client/assets/{ts-tags-DOHpIWV2-DXabLRoX.js → ts-tags-DOHpIWV2-DN6mmSGx.js} +2 -2
- package/dist/client/assets/{ts-tags-DOHpIWV2-DXabLRoX.js.map → ts-tags-DOHpIWV2-DN6mmSGx.js.map} +1 -1
- package/dist/client/assets/{tsx-DmRL3u_2-Cn0tVC2C.js → tsx-DmRL3u_2-DulNQGwe.js} +2 -2
- package/dist/client/assets/{tsx-DmRL3u_2-Cn0tVC2C.js.map → tsx-DmRL3u_2-DulNQGwe.js.map} +1 -1
- package/dist/client/assets/{twig-BzcHspK1-BW8kSayf.js → twig-BzcHspK1-j95wbDo4.js} +2 -2
- package/dist/client/assets/{twig-BzcHspK1-BW8kSayf.js.map → twig-BzcHspK1-j95wbDo4.js.map} +1 -1
- package/dist/client/assets/{typescript-BYTx4UxO-XIX20smz.js → typescript-BYTx4UxO-C2eU2nTQ.js} +2 -2
- package/dist/client/assets/{typescript-BYTx4UxO-XIX20smz.js.map → typescript-BYTx4UxO-C2eU2nTQ.js.map} +1 -1
- package/dist/client/assets/{typst-BrfC91e7-BTQczO73.js → typst-BrfC91e7-Bry73qoG.js} +2 -2
- package/dist/client/assets/{typst-BrfC91e7-BTQczO73.js.map → typst-BrfC91e7-Bry73qoG.js.map} +1 -1
- package/dist/client/assets/{useWorkspaceDefaultLanding-DygvrKuK.js → useWorkspaceDefaultLanding-DPM3tzSI.js} +2 -2
- package/dist/client/assets/{useWorkspaceDefaultLanding-DygvrKuK.js.map → useWorkspaceDefaultLanding-DPM3tzSI.js.map} +1 -1
- package/dist/client/assets/{vue-B92PIQFm-Bo7Ratnf.js → vue-B92PIQFm-_KBJBFm9.js} +2 -2
- package/dist/client/assets/{vue-B92PIQFm-Bo7Ratnf.js.map → vue-B92PIQFm-_KBJBFm9.js.map} +1 -1
- package/dist/client/assets/{vue-html-EDHI-aeE-DZaGT8SW.js → vue-html-EDHI-aeE-Cx5Qo046.js} +2 -2
- package/dist/client/assets/{vue-html-EDHI-aeE-DZaGT8SW.js.map → vue-html-EDHI-aeE-Cx5Qo046.js.map} +1 -1
- package/dist/client/assets/{vue-vine-CmMdgoEY-D5tBNukX.js → vue-vine-CmMdgoEY-CDgVVhf3.js} +2 -2
- package/dist/client/assets/{vue-vine-CmMdgoEY-D5tBNukX.js.map → vue-vine-CmMdgoEY-CDgVVhf3.js.map} +1 -1
- package/dist/client/assets/{workspaceEntityRoutes-FAiial9O.js → workspaceEntityRoutes-Cc_RtLvy.js} +2 -2
- package/dist/client/assets/{workspaceEntityRoutes-FAiial9O.js.map → workspaceEntityRoutes-Cc_RtLvy.js.map} +1 -1
- package/dist/client/assets/{workspaceScrollCapture-AJpPgzgz.js → workspaceScrollCapture-Dg3Pebh8.js} +2 -2
- package/dist/client/assets/{workspaceScrollCapture-AJpPgzgz.js.map → workspaceScrollCapture-Dg3Pebh8.js.map} +1 -1
- package/dist/client/assets/{xml-Bz9Nzp99-Bj4-GEHY.js → xml-Bz9Nzp99-bfRaCa2x.js} +2 -2
- package/dist/client/assets/{xml-Bz9Nzp99-Bj4-GEHY.js.map → xml-Bz9Nzp99-bfRaCa2x.js.map} +1 -1
- package/dist/client/assets/{xsl-D0pOnfMq-9186FOf_.js → xsl-D0pOnfMq-BaQuui65.js} +2 -2
- package/dist/client/assets/{xsl-D0pOnfMq-9186FOf_.js.map → xsl-D0pOnfMq-BaQuui65.js.map} +1 -1
- package/dist/client/assets/{yaml-DKDHNCIP-ISipY-zA.js → yaml-DKDHNCIP-B5ot5BQr.js} +2 -2
- package/dist/client/assets/{yaml-DKDHNCIP-ISipY-zA.js.map → yaml-DKDHNCIP-B5ot5BQr.js.map} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/server/assets/controlCenterApi-CIz0g85O.js.map +1 -1
- package/package.json +8 -8
- package/dist/client/assets/ActiveWorkPage-BxSGZWS_.js +0 -2
- package/dist/client/assets/ActiveWorkPage-BxSGZWS_.js.map +0 -1
- package/dist/client/assets/AgentPage-YiYORLod.js.map +0 -1
- package/dist/client/assets/AtlassianOAuthCallbackPage-PfsrTytb.js.map +0 -1
- package/dist/client/assets/AuthorizedSharePage-BCwnILXF.js.map +0 -1
- package/dist/client/assets/ItemsPage-BzinDuxs.js.map +0 -1
- package/dist/client/assets/OpenPullRequestPage-BABGk9v2.js.map +0 -1
- package/dist/client/assets/PairPage-4meDmW_A.js.map +0 -1
- package/dist/client/assets/PortfolioOverview-BRB_qe4T.js +0 -2
- package/dist/client/assets/PortfolioOverview-BRB_qe4T.js.map +0 -1
- package/dist/client/assets/ReleaseRoute-D1srSd83.js +0 -2
- package/dist/client/assets/ReleaseRoute-D1srSd83.js.map +0 -1
- package/dist/client/assets/ReleaseWorkset-DcI6qwPE.js.map +0 -1
- package/dist/client/assets/ReviewSuggestionPublicationSurface-BtoYEprT.js.map +0 -1
- package/dist/client/assets/ServicesPage-DihUx1kr.js.map +0 -1
- package/dist/client/assets/TimelinePage-DyluBeEt.js.map +0 -1
- package/dist/client/assets/WorkspaceSettingsPage-Dn_eDC3m.js.map +0 -1
- package/dist/client/assets/index-BZ52pCV1.css +0 -1
- package/dist/client/assets/patterns-D0U0WCQS.js +0 -2
- package/dist/client/assets/patterns-D0U0WCQS.js.map +0 -1
- package/dist/client/assets/primitives-CjQX0eVM-BPKvllZ_.js +0 -2
- package/dist/client/assets/primitives-CjQX0eVM-BPKvllZ_.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AgentPage-YiYORLod.js","names":["Schema.Struct","Schema.isNonEmpty","Schema.isMaxLength","Schema.optionalKey","Schema.Literals","Schema.Array","Schema.makeFilter","Schema.fromJsonString","Schema.is","Schema.decodeUnknownResult","Result.isSuccess","Schema.encodeUnknownResult","Result.isFailure","Predicate.isTagged","DateTime.nowUnsafe","DateTime.formatIso","DateTime.formatLocal","Predicate.hasProperty","Predicate.isString","StatePanel","styles","Field","Button","useState","useRef","useMemo","Text","ReleaseRelay","PeopleStrip","AgentThread","Surface","_Fragment","__toESM","useParams","useOutletContext","useLocation","V","Je","He","require_jsx_runtime","useSearchParams","useBrowserSession","Navigate","releaseFullPath","contextualReleaseAgentPath","Link","browserReadableSessionKey","We","je","Un","H","A","Revision","isString","formatLocal","hasProperty","decodeUnknownResult","EventCursor","isTagged","String","Struct","Literals","fromJsonString","formatIso","UtcTimestamp","nowUnsafe","encodeUnknownResult","ReleaseVersion","SessionId","ArraySchema","isNonEmpty","isFailure","is","ReleaseServiceName","optionalKey","isMaxLength","isSuccess","makeFilter","ReleaseRelayCodename","useWorkspaceEntity","browserWorkspaceEntityTransport","runBrowserReleaseAgentTurn","presentWorkspaceConfluencePage","submitBrowserReleasePublication","loadBrowserReleaseAgentPresets","releaseTransitionNames","decodeReleaseRouteId","decodeWorkspaceRouteId","workspaceEntityTargetFromHref","decodeEntityRouteId","browserWorkspaceItemsTransport","import_react","require_react","canonicalReleasePublicationTitle","version","MAXIMUM_STORED_MESSAGES","MAXIMUM_STORED_CONTENT","StoredReleaseAgentTurnContext","StoredReleaseAgentThreadMessage","StoredReleaseAgentThread","messages","length","message","ids","StoredReleaseAgentThreadJson","storageKey","sessionId","releaseId","boundedStoredMessages","bounded","contentLength","readReleaseAgentThread","key","source","decoded","writeReleaseAgentThread","encoded","MAXIMUM_CONFLUENCE_TEMPLATES","CONFLUENCE_TEMPLATE_BATCH_SIZE","TEMPLATE_TITLE_PATTERN","templateFor","details","projection","orderTemplates","templates","left","right","isTemplateSummary","loadBrowserConfluenceTemplates","summaries","signal","offset","batch","projections","entityId","result","template","AgentPage_module_default","import_jsx_runtime","contextualSingleReleaseAgentPath","release","releases","workspaceId","originPath","DEFAULT_CONTEXT","contexts","AGENT_CONTEXT_BASE","SAME_ORIGIN_PATH","safeOriginPath","candidate","fallback","contextFor","path","contextUrl","safePath","knownContext","routeSegments","routeKind","releaseSuffix","isWorkspaceCollectionRoute","isReleaseRoute","selectedEntityId","exactEntityId","selectedEvent","activeWorkRelease","hasValidActiveWorkRelease","timestamp","now","failureTag","failure","classifyTurnFailure","failurePanel","RUN_PRESETS","PROMPT_TEMPLATES","MAXIMUM_HISTORY_MESSAGE_LENGTH","MAXIMUM_HISTORY_CONTENT_LENGTH","HISTORY_TRUNCATION_MARKER","boundedReleaseAgentHistory","history","content","humanActor","agentActor","presentMessages","nextThreadSequence","sequence","id","next","ReleaseAgentComposer","controlProps","onPromptChange","event","prompt","disabled","isRunning","provider","pageAwareAgentPrompt","header","page","bodyPrefix","suffix","request","fixedCharacters","availableBodyCharacters","confluencePageDraftTarget","state","entity","ReleaseAgentRoom","location","searchParams","callingContext","setPrompt","setProvider","providerWasSelected","setMessages","setFailure","setIsRunning","announcement","setAnnouncement","exactPage","confluencePage","publicationDefaultTitle","publicationDefaultMarkdown","publicationTitle","setPublicationTitle","publicationMarkdown","setPublicationMarkdown","publicationBusy","setPublicationBusy","templateState","setTemplateState","loadConfluenceTemplates","templateEntityId","setTemplateEntityId","nextMessage","activeTurn","publicationRef","transitionNames","currentTurn","abort","threadMessages","lastProvider","runtimeUnavailable","runTurn","selectedProviderUnavailable","providerCatalogPending","availableProviders","providerCatalogEmpty","pageAwareness","selectedTemplate","confluenceCreateReady","confluenceUpdateReady","confluencePublicationReady","confluenceAwarenessUnknown","latestRelayAnswer","role","onSubmit","submittedPrompt","humanMessage","abortController","current","reply","cause","publish","publicationProvider","updatingConfluence","submitPublication","preset","selected","EntityContextReleaseAgentRoom","roomProps","browserSession","sessionKey","controller","target","ContextualReleaseAgentRoom","props","CanonicalAgentState","context","LegacyAgentPage","ContextualAgentPage","usePortfolioOverviewController","singleReleasePath","portfolio","AgentPage","params","ConnectedAgentPage","catalog","setCatalog","catalogRequest","setCatalogRequest","loadPresets","isCanonicalRoute"],"sources":["../../../src/domain/releasePublication.ts","../../../src/client/releases/releaseAgentThreadStorage.ts","../../../src/client/releases/confluenceTemplateTransport.ts","../../../src/client/AgentPage.module.css","../../../src/client/AgentPage.tsx"],"sourcesContent":["import type { ReleaseVersion } from \"./release.js\"\n\n/** Canonical owner-visible title shared by explicit and natural-language publication paths. */\nexport const canonicalReleasePublicationTitle = (version: ReleaseVersion): string => `${version} release`\n","import * as Result from \"effect/Result\"\nimport * as Schema from \"effect/Schema\"\n\nimport { SessionId } from \"../../api/session.js\"\nimport { EventCursor, type ReleaseId } from \"../../domain/identifiers.js\"\nimport { ReleaseServiceName, ReleaseVersion } from \"../../domain/release.js\"\nimport { ReleaseRelayCodename } from \"../../domain/releaseRelay.js\"\nimport { UtcTimestamp } from \"../../domain/utcTimestamp.js\"\n\nconst MAXIMUM_STORED_MESSAGES = 24\nconst MAXIMUM_STORED_CONTENT = 256_000\n\nconst StoredReleaseAgentTurnContext = Schema.Struct({\n eventCursor: EventCursor,\n relayCodename: ReleaseRelayCodename,\n serviceName: ReleaseServiceName,\n updatedAt: UtcTimestamp,\n version: ReleaseVersion\n})\n\nconst StoredReleaseAgentThreadMessage = Schema.Struct({\n content: Schema.String.check(Schema.isNonEmpty(), Schema.isMaxLength(32_000)),\n context: Schema.optionalKey(StoredReleaseAgentTurnContext),\n dateTime: Schema.String.check(Schema.isNonEmpty(), Schema.isMaxLength(64)),\n id: Schema.String.check(Schema.isNonEmpty(), Schema.isMaxLength(100)),\n provider: Schema.optionalKey(Schema.Literals([\"codex\", \"claude\"])),\n role: Schema.Literals([\"user\", \"assistant\"]),\n time: Schema.String.check(Schema.isNonEmpty(), Schema.isMaxLength(32))\n})\n\nconst hasUniqueMessageIds = (messages: ReadonlyArray<{ readonly id: string }>): boolean => {\n const ids = new Set<string>()\n for (const message of messages) {\n if (ids.has(message.id)) return false\n ids.add(message.id)\n }\n return true\n}\n\nconst StoredReleaseAgentThread = Schema.Array(StoredReleaseAgentThreadMessage).check(\n Schema.makeFilter((messages) => messages.length <= MAXIMUM_STORED_MESSAGES, {\n expected: `at most ${MAXIMUM_STORED_MESSAGES} stored release-agent messages`\n }),\n Schema.makeFilter(\n (messages) => messages.reduce((length, message) => length + message.content.length, 0) <= MAXIMUM_STORED_CONTENT,\n { expected: `at most ${MAXIMUM_STORED_CONTENT} stored release-agent characters` }\n ),\n Schema.makeFilter(hasUniqueMessageIds, {\n expected: \"unique stored release-agent message ids\"\n })\n)\n\nconst StoredReleaseAgentThreadJson = Schema.fromJsonString(StoredReleaseAgentThread)\n\nexport type StoredReleaseAgentThreadMessage = typeof StoredReleaseAgentThreadMessage.Type\n\nconst storageKey = (releaseId: ReleaseId): string | null => {\n const sessionId = sessionStorage.getItem(\"cc_session_id\")\n if (sessionId === null || !Schema.is(SessionId)(sessionId)) return null\n return `cc_release_agent_thread:${sessionId}:${releaseId}`\n}\n\nconst boundedStoredMessages = (\n messages: ReadonlyArray<StoredReleaseAgentThreadMessage>\n): ReadonlyArray<StoredReleaseAgentThreadMessage> => {\n const bounded: Array<StoredReleaseAgentThreadMessage> = []\n let contentLength = 0\n for (const message of messages.slice(-MAXIMUM_STORED_MESSAGES).reverse()) {\n if (contentLength + message.content.length > MAXIMUM_STORED_CONTENT) break\n bounded.unshift(message)\n contentLength += message.content.length\n }\n return bounded\n}\n\n/** Recover only Schema-valid tab-local thread state for the exact release. */\nexport const readReleaseAgentThread = (\n releaseId: ReleaseId\n): ReadonlyArray<StoredReleaseAgentThreadMessage> => {\n try {\n const key = storageKey(releaseId)\n if (key === null) return []\n const source = sessionStorage.getItem(key)\n if (source === null) return []\n const decoded = Schema.decodeUnknownResult(StoredReleaseAgentThreadJson)(source)\n return Result.isSuccess(decoded) ? decoded.success : []\n } catch {\n return []\n }\n}\n\n/** Persist a bounded release thread for the lifetime of the current browser tab. */\nexport const writeReleaseAgentThread = (\n releaseId: ReleaseId,\n messages: ReadonlyArray<StoredReleaseAgentThreadMessage>\n): void => {\n const encoded = Schema.encodeUnknownResult(StoredReleaseAgentThreadJson)(boundedStoredMessages(messages))\n if (Result.isFailure(encoded)) return\n try {\n const key = storageKey(releaseId)\n if (key === null) return\n sessionStorage.setItem(key, encoded.success)\n } catch {\n // Storage can be unavailable in hardened browser contexts; the in-memory thread still works.\n }\n}\n","import * as Predicate from \"effect/Predicate\"\nimport type { DeliveryEntityProjection } from \"../../domain/deliveryGraph.js\"\nimport type { EntityId } from \"../../domain/identifiers.js\"\nimport { browserWorkspaceEntityTransport } from \"../entities/useWorkspaceEntity.js\"\nimport { browserWorkspaceItemsTransport } from \"../items/useWorkspaceItems.js\"\n\nconst MAXIMUM_CONFLUENCE_TEMPLATES = 50\nconst CONFLUENCE_TEMPLATE_BATCH_SIZE = 8\nconst TEMPLATE_TITLE_PATTERN = /\\btemplate\\b/iu\n\nexport interface ConfluenceReleaseTemplate {\n readonly entityId: EntityId\n readonly markdown: string\n readonly revision: string\n readonly title: string\n}\n\nexport type ConfluenceTemplateLoader = (\n signal: AbortSignal\n) => Promise<ReadonlyArray<ConfluenceReleaseTemplate>>\n\nexport interface ConfluenceTemplateSource {\n readonly list: (signal: AbortSignal) => Promise<ReadonlyArray<DeliveryEntityProjection>>\n readonly load: (entityId: EntityId, signal: AbortSignal) => Promise<DeliveryEntityProjection>\n}\n\nconst templateFor = (projection: DeliveryEntityProjection): ConfluenceReleaseTemplate | null => {\n const details = projection.details\n return projection.entityState === \"present\" &&\n details._tag === \"page\" &&\n details.contentState === \"loaded\" &&\n details.content?.markdown !== undefined &&\n details.content.markdown.trim().length > 0\n ? {\n entityId: projection.entityId,\n markdown: details.content.markdown,\n revision: details.revision,\n title: projection.title\n }\n : null\n}\n\nconst orderTemplates = (\n templates: ReadonlyArray<ConfluenceReleaseTemplate>\n): ReadonlyArray<ConfluenceReleaseTemplate> =>\n [...templates].sort((left, right) => {\n const leftTemplate = TEMPLATE_TITLE_PATTERN.test(left.title) ? 0 : 1\n const rightTemplate = TEMPLATE_TITLE_PATTERN.test(right.title) ? 0 : 1\n return leftTemplate - rightTemplate || left.title.localeCompare(right.title)\n })\n\nconst isTemplateSummary = (projection: DeliveryEntityProjection): boolean =>\n projection.entityState === \"present\" &&\n projection.details._tag === \"page\" &&\n TEMPLATE_TITLE_PATTERN.test(projection.title)\n\n/**\n * Hydrate exact page projections behind the summarized workspace index.\n *\n * The Items boundary deliberately removes document bodies, so template content\n * must come from the existing exact-entity read instead of the summary payload.\n */\nexport const makeConfluenceTemplateLoader = (\n source: ConfluenceTemplateSource\n): ConfluenceTemplateLoader => {\n return async (signal) => {\n const summaries = (await source.list(signal)).filter(isTemplateSummary).slice(0, MAXIMUM_CONFLUENCE_TEMPLATES)\n const templates: Array<ConfluenceReleaseTemplate> = []\n for (let offset = 0; offset < summaries.length; offset += CONFLUENCE_TEMPLATE_BATCH_SIZE) {\n const batch = summaries.slice(offset, offset + CONFLUENCE_TEMPLATE_BATCH_SIZE)\n const projections = await Promise.allSettled(\n batch.map(({ entityId }) => source.load(entityId, signal))\n )\n for (const result of projections) {\n if (result.status === \"rejected\") {\n if (Predicate.isTagged(\"NotFoundApiError\")(result.reason)) continue\n throw result.reason\n }\n const template = templateFor(result.value)\n if (template !== null) templates.push(template)\n }\n }\n return orderTemplates(templates)\n }\n}\n\nexport const loadBrowserConfluenceTemplates = makeConfluenceTemplateLoader({\n list: async (signal) => {\n const index = await browserWorkspaceItemsTransport.load(signal, {\n owner: \"all\",\n query: \"\",\n service: \"all\",\n status: \"all\",\n type: \"page\"\n })\n return index.items.map(({ projection }) => projection)\n },\n load: async (entityId, signal) => (await browserWorkspaceEntityTransport.load(entityId, signal)).entity.projection\n})\n",".room,\n.hero,\n.heroCopy,\n.people,\n.starters,\n.composer,\n.templatePicker,\n.legacy,\n.legacyHeader,\n.legacyContext {\n display: grid;\n}\n\n.room,\n.legacy {\n gap: clamp(4rem, 9vw, 8rem);\n}\n\n.back {\n inline-size: fit-content;\n color: var(--rly-color-text-2);\n font: var(--rly-type-label-weight) var(--rly-type-label-size) / var(--rly-type-label-line-height)\n var(--rly-type-label-font);\n text-decoration: none;\n}\n\n.back:hover,\n.back:focus-visible {\n color: var(--rly-color-text-1);\n text-decoration: underline;\n text-underline-offset: var(--rly-space-4);\n}\n\n.hero,\n.legacyHeader {\n gap: var(--rly-space-32);\n}\n\n.heroCopy,\n.legacyHeader {\n max-inline-size: 58rem;\n}\n\n.heroCopy {\n gap: var(--rly-space-16);\n}\n\n.heroCopy h1,\n.legacyHeader h1 {\n max-inline-size: 11ch;\n letter-spacing: -0.065em;\n text-wrap: balance;\n}\n\n.heroCopy p,\n.legacyHeader p {\n max-inline-size: 46rem;\n}\n\n.eyebrow {\n letter-spacing: 0.08em;\n text-transform: uppercase;\n}\n\n.people,\n.starters {\n gap: var(--rly-space-24);\n}\n\n.publication {\n scroll-margin-block-start: 6rem;\n}\n\n.publicationAction {\n display: grid;\n}\n\n.templatePicker {\n background: color-mix(in srgb, var(--rly-color-service-confluence) 6%, var(--rly-color-surface-2));\n border-inline-start: var(--rly-space-4) solid var(--rly-color-service-confluence);\n gap: var(--rly-space-16);\n padding: var(--rly-space-20);\n}\n\n.templatePicker > div:first-child {\n display: grid;\n gap: var(--rly-space-8);\n}\n\n.presetList {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: var(--rly-space-12);\n}\n\n.preset,\n.suggestionList {\n display: grid;\n}\n\n.suggestionList {\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: var(--rly-space-12);\n}\n\n.preset,\n.suggestion {\n min-block-size: 7rem;\n padding: var(--rly-space-20);\n border: 1px solid var(--rly-color-border-1);\n border-radius: var(--rly-radius-group);\n background: var(--rly-color-surface-1);\n color: var(--rly-color-text-1);\n cursor: pointer;\n font: var(--rly-type-card-title-weight) var(--rly-type-card-title-size) / var(--rly-type-card-title-line-height)\n var(--rly-type-card-title-font);\n text-align: start;\n transition:\n border-color var(--rly-motion-fast-duration) var(--rly-motion-fast-easing),\n background-color var(--rly-motion-fast-duration) var(--rly-motion-fast-easing),\n box-shadow var(--rly-motion-fast-duration) var(--rly-motion-fast-easing);\n}\n\n.preset {\n gap: var(--rly-space-8);\n}\n\n.preset span,\n.suggestion span {\n color: var(--rly-color-text-2);\n font: var(--rly-type-body-weight) var(--rly-type-body-size) / var(--rly-type-body-line-height)\n var(--rly-type-body-font);\n}\n\n.preset small {\n color: var(--rly-color-text-2);\n font: var(--rly-type-meta-weight) var(--rly-type-meta-size) / var(--rly-type-meta-line-height)\n var(--rly-type-meta-font);\n text-transform: uppercase;\n}\n\n.preset[aria-checked=\"true\"] {\n border-color: var(--rly-color-agent);\n background: var(--rly-color-surface-2);\n box-shadow: inset 0 0 0 1px var(--rly-color-agent);\n}\n\n.preset:hover,\n.suggestion:hover {\n border-color: var(--rly-color-agent);\n background: var(--rly-color-surface-2);\n}\n\n.preset:focus-visible,\n.suggestion:focus-visible {\n border-color: var(--rly-color-agent);\n background: var(--rly-color-surface-2);\n outline: 2px solid var(--rly-color-focus);\n outline-offset: 2px;\n}\n\n.preset:disabled,\n.suggestion:disabled {\n cursor: not-allowed;\n opacity: 0.45;\n}\n\n.thread {\n border-color: var(--rly-color-border-2);\n}\n\n.threadContext {\n display: flex;\n flex-wrap: wrap;\n gap: var(--rly-space-8) var(--rly-space-16);\n color: var(--rly-color-text-2);\n font: var(--rly-type-label-weight) var(--rly-type-label-size) / var(--rly-type-label-line-height)\n var(--rly-type-label-font);\n}\n\n.threadContext strong {\n color: var(--rly-color-text-1);\n}\n\n.threadContext span + span::before {\n margin-inline-end: var(--rly-space-16);\n color: var(--rly-color-border-2);\n content: \"·\";\n}\n\n.composer {\n gap: var(--rly-space-16);\n}\n\n.composer textarea {\n min-block-size: 10rem;\n resize: vertical;\n font: var(--rly-type-body-large-weight) var(--rly-type-body-large-size) / var(--rly-type-body-large-line-height)\n var(--rly-type-body-large-font);\n}\n\n.failure {\n scroll-margin-block-start: 6rem;\n}\n\n.state {\n display: grid;\n min-block-size: 60dvh;\n place-items: center;\n}\n\n.legacyHeader,\n.legacyContext {\n gap: var(--rly-space-16);\n}\n\n.legacyContext {\n max-inline-size: 52rem;\n}\n\n@media (max-width: 48rem) {\n .suggestionList {\n grid-template-columns: 1fr;\n }\n\n .presetList {\n grid-template-columns: 1fr;\n }\n\n .preset,\n .suggestion {\n min-block-size: 5rem;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .preset,\n .suggestion {\n transition: none;\n }\n}\n","import { AgentThread, PeopleStrip, ReleaseRelay, type RlyAgentThreadMessage } from \"@knpkv/rly/patterns\"\nimport { Button, Field, StatePanel, Surface, Text } from \"@knpkv/rly/primitives\"\nimport * as DateTime from \"effect/DateTime\"\nimport * as Predicate from \"effect/Predicate\"\nimport { type FormEvent, type ReactElement, useEffect, useMemo, useRef, useState } from \"react\"\nimport { Link, Navigate, useLocation, useOutletContext, useParams, useSearchParams } from \"react-router\"\n\nimport type { PortfolioReleaseSummary } from \"../api/portfolio.js\"\nimport type { EntityId, EventCursor, ReleaseId, WorkspaceId } from \"../domain/identifiers.js\"\nimport { canonicalReleasePublicationTitle } from \"../domain/releasePublication.js\"\nimport { Revision } from \"../domain/sourceRevision.js\"\nimport { browserReadableSessionKey, useBrowserSession } from \"./BrowserSession.js\"\nimport { contextualReleaseAgentPath } from \"./contextualAgentPath.js\"\nimport { presentWorkspaceConfluencePage } from \"./entities/presentWorkspaceConfluencePage.js\"\nimport { useWorkspaceEntity, type WorkspaceEntityState } from \"./entities/useWorkspaceEntity.js\"\nimport { usePortfolioOverviewController } from \"./portfolio/PortfolioOverview.js\"\nimport type { PortfolioReleasePresentation } from \"./portfolio/presentPortfolio.js\"\nimport {\n decodeReleaseRouteId,\n decodeWorkspaceRouteId,\n releaseFullPath,\n releaseTransitionNames\n} from \"./releases/releaseRoutes.js\"\nimport { decodeEntityRouteId, workspaceEntityTargetFromHref } from \"./items/workspaceEntityRoutes.js\"\nimport {\n readReleaseAgentThread,\n type StoredReleaseAgentThreadMessage,\n writeReleaseAgentThread\n} from \"./releases/releaseAgentThreadStorage.js\"\nimport {\n type ConfluenceReleaseTemplate,\n type ConfluenceTemplateLoader,\n loadBrowserConfluenceTemplates\n} from \"./releases/confluenceTemplateTransport.js\"\nimport type { WorkspaceReleaseOutletContext } from \"./releases/WorkspaceReleaseLayout.js\"\nimport {\n loadBrowserReleaseAgentPresets,\n runBrowserReleaseAgentTurn,\n submitBrowserReleasePublication\n} from \"./releases/releaseAgentTransport.js\"\nimport styles from \"./AgentPage.module.css\"\n\n/** Resolve a single unambiguous release while retaining the page that launched Relay. */\nexport const contextualSingleReleaseAgentPath = (\n workspaceId: WorkspaceId,\n releases: ReadonlyArray<PortfolioReleasePresentation>,\n originPath: string\n): string | undefined => {\n const release = releases.length === 1 ? releases[0] : undefined\n return release === undefined ? undefined : contextualReleaseAgentPath(workspaceId, release.id, originPath)\n}\n\nexport interface ReleaseAgentHistoryMessage {\n readonly content: string\n readonly role: \"assistant\" | \"user\"\n}\n\nexport interface ReleaseAgentTurnInput {\n readonly history: ReadonlyArray<ReleaseAgentHistoryMessage>\n /** Same-origin page that launched Relay; omitted only for a direct release route. */\n readonly originPath?: string\n readonly prompt: string\n readonly provider: \"claude\" | \"codex\"\n readonly releaseId: ReleaseId\n readonly workspaceId: WorkspaceId\n}\n\nexport interface ReleaseAgentTurnResult {\n readonly eventCursor: EventCursor\n readonly provider: \"claude\" | \"codex\"\n readonly release: PortfolioReleaseSummary\n readonly reply: string\n}\n\nexport type ReleaseAgentTurn = (\n input: ReleaseAgentTurnInput,\n options: { readonly signal: AbortSignal }\n) => Promise<ReleaseAgentTurnResult>\n\nexport type ReleaseAgentPresetLoader = (signal: AbortSignal) => Promise<ReadonlyArray<\"claude\" | \"codex\">>\nexport type { ConfluenceTemplateLoader } from \"./releases/confluenceTemplateTransport.js\"\n\nexport interface AgentPageProps {\n /** Application-owned local runtime boundary. Omit it to render an honest unavailable state. */\n readonly runTurn?: ReleaseAgentTurn\n /** Configured local presets. Omit only at deterministic/test boundaries. */\n readonly availableProviders?: ReadonlyArray<\"claude\" | \"codex\">\n /** Whether the connected route is still establishing a trustworthy provider catalog. */\n readonly providerCatalogPending?: boolean\n /** Workspace page catalog used only by the connected route's Confluence template picker. */\n readonly loadConfluenceTemplates?: ConfluenceTemplateLoader\n /** Governed publication transport; injectable for deterministic route tests. */\n readonly submitPublication?: typeof submitBrowserReleasePublication\n}\n\ninterface AgentPageContext {\n readonly description: string\n readonly label: string\n readonly path: string | null\n}\n\ntype LocalThreadMessage = StoredReleaseAgentThreadMessage\n\ntype TurnFailure =\n \"blocked\" | \"conflict\" | \"failed\" | \"not-found\" | \"rate-limited\" | \"session-expired\" | \"timed-out\" | \"unavailable\"\n\nconst DEFAULT_CONTEXT: AgentPageContext = {\n description: \"The workspace-wide view of release readiness, people, source health, and agent work.\",\n label: \"Overview\",\n path: \"/\"\n}\n\ninterface AgentContextLookup extends Readonly<Record<string, AgentPageContext>> {}\n\nconst contexts: AgentContextLookup = {\n \"/\": DEFAULT_CONTEXT,\n \"/pair\": {\n description: \"The private browser-pairing flow. Credentials never become part of the agent context.\",\n label: \"Browser pairing\",\n path: \"/pair\"\n },\n \"/releases\": {\n description: \"Release relationships, blockers, collaborators, pull requests, and deployment evidence.\",\n label: \"Releases\",\n path: \"/releases\"\n },\n \"/services\": {\n description: \"Negotiated plugin health and the connections that provide delivery evidence.\",\n label: \"Services\",\n path: \"/services\"\n }\n}\n\nconst AGENT_CONTEXT_BASE = \"https://control-center.invalid\"\nconst SAME_ORIGIN_PATH = /^\\/(?![\\\\/])[^\\\\]*$/u\n\nconst safeOriginPath = (candidate: string | null, fallback: string): string =>\n candidate !== null && SAME_ORIGIN_PATH.test(candidate) ? candidate : fallback\n\nexport const contextFor = (path: string | null): AgentPageContext => {\n if (path === null) return DEFAULT_CONTEXT\n const contextUrl = URL.parse(path, AGENT_CONTEXT_BASE)\n if (contextUrl === null || contextUrl.origin !== AGENT_CONTEXT_BASE) {\n return {\n description:\n \"The calling page is not a recognized Control Center context. No fallback workspace or entity is substituted.\",\n label: \"Context unavailable\",\n path: null\n }\n }\n const safePath = `${contextUrl.pathname}${contextUrl.search}${contextUrl.hash}`\n const knownContext = contexts[contextUrl.pathname]\n if (knownContext !== undefined) return { ...knownContext, path: safePath }\n const routeSegments = contextUrl.pathname.split(\"/\")\n const workspaceId = decodeWorkspaceRouteId(routeSegments[2])\n const routeKind = routeSegments[3]\n const releaseId = decodeReleaseRouteId(routeSegments[4])\n const releaseSuffix = routeSegments[5]\n const isWorkspaceCollectionRoute = routeSegments[1] === \"w\" && routeSegments[4] === undefined\n const isReleaseRoute =\n routeSegments[1] === \"w\" &&\n workspaceId !== null &&\n routeKind === \"releases\" &&\n releaseId !== null &&\n (releaseSuffix === undefined || releaseSuffix === \"preview\" || releaseSuffix === \"agent\")\n if (isWorkspaceCollectionRoute && workspaceId !== null && routeKind === \"overview\" && releaseId === null) {\n return {\n description: `Workspace ${workspaceId} release readiness, people, source health, and agent work.`,\n label: \"Workspace overview\",\n path: safePath\n }\n }\n if (isWorkspaceCollectionRoute && workspaceId !== null && routeKind === \"items\" && releaseId === null) {\n const selectedEntityId = decodeEntityRouteId(contextUrl.searchParams.get(\"object\"))\n if (selectedEntityId !== null) {\n return {\n description: `Workspace item ${selectedEntityId} is selected in the normalized delivery view. Relay will keep this exact entity selection and the surrounding item filters in context.`,\n label: `Workspace item ${selectedEntityId.slice(-6)}`,\n path: safePath\n }\n }\n return {\n description: `Current normalized delivery items in workspace ${workspaceId}, including the exact active filters and selection.`,\n label: \"Workspace items\",\n path: safePath\n }\n }\n const exactEntityId =\n routeSegments[1] === \"w\" && workspaceId !== null && routeKind === \"items\" && releaseSuffix === undefined\n ? decodeEntityRouteId(routeSegments[4])\n : null\n if (exactEntityId !== null) {\n return {\n description: `Workspace item ${exactEntityId} is open in the normalized delivery view. Relay will keep this exact entity in context.`,\n label: `Workspace item ${exactEntityId.slice(-6)}`,\n path: safePath\n }\n }\n if (isWorkspaceCollectionRoute && workspaceId !== null && routeKind === \"timeline\" && releaseId === null) {\n const selectedEvent = contextUrl.searchParams.get(\"event\")\n return {\n description:\n selectedEvent === null\n ? `Attributable delivery activity in workspace ${workspaceId}, including the exact actor and date filters.`\n : `Timeline event ${selectedEvent} in workspace ${workspaceId}, including the exact actor and date filters.`,\n label: \"Workspace timeline\",\n path: safePath\n }\n }\n const activeWorkRelease = contextUrl.searchParams.get(\"release\")\n const hasValidActiveWorkRelease = activeWorkRelease === null || decodeReleaseRouteId(activeWorkRelease) !== null\n if (\n isWorkspaceCollectionRoute &&\n workspaceId !== null &&\n routeKind === \"work\" &&\n releaseId === null &&\n hasValidActiveWorkRelease\n ) {\n return {\n description: `Active release decisions in workspace ${workspaceId}, including the exact selected release and filters.`,\n label: \"Active work\",\n path: safePath\n }\n }\n if (isReleaseRoute) {\n return {\n description: `Release ${releaseId} in workspace ${workspaceId}. Relay will resolve current release facts on the server before answering.`,\n label: `Release ${releaseId.slice(-6)}`,\n path: safePath\n }\n }\n return {\n description:\n \"The calling page is not a recognized Control Center context. No fallback workspace or entity is substituted.\",\n label: \"Context unavailable\",\n path: null\n }\n}\n\nconst timestamp = (): Pick<LocalThreadMessage, \"dateTime\" | \"time\"> => {\n const now = DateTime.nowUnsafe()\n return {\n dateTime: DateTime.formatIso(now),\n time: DateTime.formatLocal(now, { hour: \"2-digit\", minute: \"2-digit\" })\n }\n}\n\nconst failureTag = <UnparsedInput,>(failure: UnparsedInput): string | null => {\n if (!Predicate.hasProperty(failure, \"_tag\") || !Predicate.isString(failure._tag)) return null\n return failure._tag\n}\n\nconst classifyTurnFailure = <UnparsedInput,>(failure: UnparsedInput): TurnFailure => {\n switch (failureTag(failure)) {\n case \"UnauthorizedApiError\":\n return \"session-expired\"\n case \"ForbiddenApiError\":\n return \"blocked\"\n case \"NotFoundApiError\":\n case \"ApplicationResourceNotFound\":\n return \"not-found\"\n case \"ConflictApiError\":\n return \"conflict\"\n case \"ServiceUnavailableApiError\":\n case \"ApplicationServiceUnavailable\":\n return \"unavailable\"\n case \"RateLimitedApiError\":\n return \"rate-limited\"\n case \"RequestTimedOutApiError\":\n return \"timed-out\"\n default:\n return \"failed\"\n }\n}\n\nconst failurePanel = (failure: TurnFailure): ReactElement => {\n switch (failure) {\n case \"session-expired\":\n return (\n <StatePanel\n action={<Link to=\"/pair\">Pair this browser</Link>}\n announce=\"assertive\"\n description=\"Pair this browser again, then return to the release thread. Your local messages remain in this tab.\"\n title=\"Session expired\"\n tone=\"caution\"\n />\n )\n case \"blocked\":\n return (\n <StatePanel\n announce=\"assertive\"\n description=\"This connection cannot run a release agent. Use an allowed Control Center address.\"\n title=\"Agent access blocked\"\n tone=\"critical\"\n />\n )\n case \"not-found\":\n return (\n <StatePanel\n announce=\"assertive\"\n description=\"This release is no longer in the current workspace snapshot. Return to the release before asking again.\"\n title=\"Release not found\"\n tone=\"caution\"\n />\n )\n case \"conflict\":\n return (\n <StatePanel\n announce=\"assertive\"\n description=\"The release publication state changed or its destination is ambiguous. Refresh the release context and use the explicit publication controls.\"\n title=\"Release publication needs attention\"\n tone=\"caution\"\n />\n )\n case \"unavailable\":\n return (\n <StatePanel\n announce=\"assertive\"\n description=\"Start the configured local Codex or Claude runner, then ask again.\"\n title=\"Relay is unavailable\"\n tone=\"caution\"\n />\n )\n case \"rate-limited\":\n return (\n <StatePanel\n announce=\"assertive\"\n description=\"Relay has reached its local turn budget. Wait a moment, then submit the message again.\"\n title=\"Too many agent turns\"\n tone=\"caution\"\n />\n )\n case \"timed-out\":\n return (\n <StatePanel\n announce=\"assertive\"\n description=\"The local model exceeded this turn's deadline. Narrow the question, then submit it again.\"\n title=\"Relay took too long\"\n tone=\"caution\"\n />\n )\n case \"failed\":\n return (\n <StatePanel\n announce=\"assertive\"\n description=\"The agent did not complete this turn. Your message is still here; ask again when the runtime is ready.\"\n title=\"Relay could not answer\"\n tone=\"critical\"\n />\n )\n }\n}\n\nconst RUN_PRESETS: ReadonlyArray<{\n readonly description: string\n readonly label: string\n readonly provider: \"claude\" | \"codex\"\n}> = [\n {\n description: \"Fast, repository-aware release work with the configured Codex CLI.\",\n label: \"Run with Codex\",\n provider: \"codex\"\n },\n {\n description: \"Use the configured Claude CLI for a second agent perspective.\",\n label: \"Run with Claude\",\n provider: \"claude\"\n }\n]\n\nconst PROMPT_TEMPLATES: ReadonlyArray<{\n readonly label: string\n readonly prompt: string\n}> = [\n { label: \"Release blockers\", prompt: \"What blocks this release?\" },\n { label: \"Release summary\", prompt: \"Write a concise release summary.\" },\n { label: \"Missing evidence\", prompt: \"Which evidence is still missing?\" }\n]\n\nconst MAXIMUM_HISTORY_MESSAGES = 12\nconst MAXIMUM_HISTORY_MESSAGE_LENGTH = 12_000\nconst MAXIMUM_HISTORY_CONTENT_LENGTH = 64_000\nconst HISTORY_TRUNCATION_MARKER = \"\\n[earlier content truncated]\"\n\n/** Keep browser-owned thread history inside the public agent-turn payload contract. */\nexport const boundedReleaseAgentHistory = (\n messages: ReadonlyArray<ReleaseAgentHistoryMessage>\n): ReadonlyArray<ReleaseAgentHistoryMessage> => {\n const history: Array<ReleaseAgentHistoryMessage> = []\n let contentLength = 0\n for (const message of messages.slice(-MAXIMUM_HISTORY_MESSAGES).reverse()) {\n const content =\n message.content.length <= MAXIMUM_HISTORY_MESSAGE_LENGTH\n ? message.content\n : `${message.content.slice(0, MAXIMUM_HISTORY_MESSAGE_LENGTH - HISTORY_TRUNCATION_MARKER.length)}${HISTORY_TRUNCATION_MARKER}`\n if (contentLength + content.length > MAXIMUM_HISTORY_CONTENT_LENGTH) break\n history.unshift({ content, role: message.role })\n contentLength += content.length\n }\n return history\n}\n\nconst humanActor = {\n kind: \"human\",\n person: { avatarFallback: \"YO\", id: \"current-operator\", name: \"You\", role: \"Release operator\" }\n} satisfies RlyAgentThreadMessage[\"actor\"]\n\nconst agentActor = {\n avatarFallback: \"AI\",\n id: \"relay\",\n kind: \"agent\",\n name: \"Relay\",\n role: \"Release agent\"\n} satisfies RlyAgentThreadMessage[\"actor\"]\n\nconst presentMessages = (messages: ReadonlyArray<LocalThreadMessage>): ReadonlyArray<RlyAgentThreadMessage> =>\n messages.map((message) => ({\n actor: message.role === \"user\" ? humanActor : agentActor,\n content: message.content,\n dateTime: message.dateTime,\n id: message.id,\n time: message.time,\n ...(!(message.context === undefined) && {\n evidence: (\n <span>\n Answered from {message.context.serviceName} {message.context.version} · {message.context.relayCodename} ·\n snapshot {message.context.eventCursor}\n </span>\n )\n })\n }))\n\nconst nextThreadSequence = (messages: ReadonlyArray<LocalThreadMessage>): number =>\n messages.reduce((next, { id }) => {\n const sequence = Number(id.split(\"-\")[1])\n return Number.isSafeInteger(sequence) && sequence >= next ? sequence + 1 : next\n }, 0)\n\nconst ReleaseAgentComposer = ({\n disabled,\n isRunning,\n onPromptChange,\n onSubmit,\n prompt,\n provider\n}: {\n readonly disabled: boolean\n readonly isRunning: boolean\n readonly onPromptChange: (prompt: string) => void\n readonly onSubmit: (event: FormEvent<HTMLFormElement>) => void\n readonly prompt: string\n readonly provider: \"claude\" | \"codex\"\n}): ReactElement => (\n <form className={styles.composer} onSubmit={onSubmit}>\n <Field label=\"What do you need?\">\n {(controlProps) => (\n <textarea\n {...controlProps}\n autoFocus\n disabled={disabled}\n maxLength={8_000}\n onChange={(event) => onPromptChange(event.currentTarget.value)}\n placeholder=\"Ask about blockers, people, checks, or release notes…\"\n rows={4}\n value={prompt}\n />\n )}\n </Field>\n <Button\n disabled={disabled || prompt.trim().length === 0}\n loading={isRunning}\n size=\"principal\"\n stretch\n type=\"submit\"\n variant=\"primary\"\n >\n {`Ask Relay with ${provider === \"codex\" ? \"Codex\" : \"Claude\"}`}\n </Button>\n </form>\n)\n\nexport interface ConfluencePageDraftTarget {\n readonly contentState: \"empty\" | \"lazy\" | \"loaded\"\n readonly entityId: EntityId\n readonly markdown: string\n readonly revision: string\n readonly title: string\n}\n\ntype ConfluencePageDraftContext =\n | { readonly _tag: \"none\" }\n | { readonly _tag: \"loading\" }\n | { readonly _tag: \"unavailable\" }\n | { readonly _tag: \"ready\"; readonly target: ConfluencePageDraftTarget }\n\ntype ConfluenceTemplateState =\n | { readonly _tag: \"loading\" }\n | { readonly _tag: \"failed\" }\n | { readonly _tag: \"ready\"; readonly templates: ReadonlyArray<ConfluenceReleaseTemplate> }\n\nexport const pageAwareAgentPrompt = (request: string, page: ConfluencePageDraftTarget): string => {\n const header = [\n \"Work on the exact synchronized Confluence page below.\",\n `Page title: ${page.title}`,\n `Current revision: ${page.revision}`,\n page.contentState === \"loaded\"\n ? \"Current safe-Markdown page body:\"\n : \"The current page body was not synchronized. Draft a complete replacement body.\"\n ].join(\"\\n\")\n const bodyPrefix = page.contentState === \"loaded\" ? \"\\n\" : \"\\nNo current body is available.\"\n const suffix = `\\n\\nUser request:\\n${request}`\n const fixedCharacters = header.length + bodyPrefix.length + suffix.length\n // At the input limit, preserve the complete owner instruction instead of\n // producing an invalid oversized prompt with partial page context.\n if (fixedCharacters > 8_000) return request\n const availableBodyCharacters = 8_000 - fixedCharacters\n const body = page.contentState === \"loaded\" ? page.markdown.slice(0, availableBodyCharacters) : \"\"\n return `${header}${bodyPrefix}${body}${suffix}`\n}\n\n/** Adopt only an exact synchronized Confluence page that belongs to this release. */\nexport const confluencePageDraftTarget = (\n state: WorkspaceEntityState,\n releaseId: ReleaseId\n): ConfluencePageDraftTarget | null => {\n if (state._tag !== \"ready\" && state._tag !== \"stale\") return null\n const { entity, source } = state.inspection\n const details = entity.projection.details\n if (source.providerId !== \"confluence\" || details._tag !== \"page\" || !entity.releaseIds.includes(releaseId))\n return null\n const page = presentWorkspaceConfluencePage(details, state.inspection)\n return {\n contentState: page.contentState,\n entityId: entity.projection.entityId,\n markdown: page.content ?? \"\",\n revision: page.revision,\n title: entity.projection.title\n }\n}\n\nconst ReleaseAgentRoom = ({\n availableProviders,\n confluencePage,\n loadConfluenceTemplates,\n providerCatalogPending,\n release,\n runTurn,\n submitPublication,\n workspaceId\n}: {\n readonly release: PortfolioReleasePresentation\n readonly runTurn: ReleaseAgentTurn | undefined\n readonly availableProviders: ReadonlyArray<\"claude\" | \"codex\"> | undefined\n readonly confluencePage: ConfluencePageDraftContext\n readonly loadConfluenceTemplates?: ConfluenceTemplateLoader\n readonly providerCatalogPending: boolean\n readonly submitPublication: typeof submitBrowserReleasePublication\n readonly workspaceId: WorkspaceId\n}): ReactElement => {\n const location = useLocation()\n const [searchParams] = useSearchParams()\n const callingContext = contextFor(searchParams.get(\"from\"))\n const [prompt, setPrompt] = useState(\"\")\n const [provider, setProvider] = useState<\"claude\" | \"codex\">(\"codex\")\n const providerWasSelected = useRef(false)\n const [messages, setMessages] = useState<ReadonlyArray<LocalThreadMessage>>(() => readReleaseAgentThread(release.id))\n const [failure, setFailure] = useState<TurnFailure | null>(null)\n const [isRunning, setIsRunning] = useState(false)\n const [announcement, setAnnouncement] = useState(\"\")\n const exactPage = confluencePage._tag === \"ready\" ? confluencePage.target : null\n const publicationDefaultTitle = exactPage?.title ?? canonicalReleasePublicationTitle(release.version)\n const publicationDefaultMarkdown =\n exactPage?.markdown ??\n \"Release \" + release.version + \" for \" + release.serviceName + \". Published by Relay after human confirmation.\"\n const [publicationTitle, setPublicationTitle] = useState(publicationDefaultTitle)\n const [publicationMarkdown, setPublicationMarkdown] = useState(publicationDefaultMarkdown)\n const [publicationBusy, setPublicationBusy] = useState<\"jira\" | \"confluence\" | null>(null)\n const [templateState, setTemplateState] = useState<ConfluenceTemplateState>(\n loadConfluenceTemplates === undefined ? { _tag: \"ready\", templates: [] } : { _tag: \"loading\" }\n )\n const [templateEntityId, setTemplateEntityId] = useState<EntityId | null>(null)\n const nextMessage = useRef(nextThreadSequence(messages))\n const activeTurn = useRef<AbortController | null>(null)\n const publicationRef = useRef<HTMLElement | null>(null)\n const transitionNames = releaseTransitionNames(release.id)\n\n useEffect(\n () => () => {\n const currentTurn = activeTurn.current\n activeTurn.current = null\n currentTurn?.abort()\n },\n []\n )\n\n useEffect(() => {\n writeReleaseAgentThread(release.id, messages)\n }, [messages, release.id])\n\n useEffect(() => {\n setPublicationTitle(publicationDefaultTitle)\n setPublicationMarkdown(publicationDefaultMarkdown)\n }, [exactPage?.entityId, exactPage?.revision, publicationDefaultMarkdown, publicationDefaultTitle])\n\n useEffect(() => {\n if (exactPage !== null) publicationRef.current?.scrollIntoView({ block: \"start\" })\n }, [exactPage?.entityId])\n\n useEffect(() => {\n if (loadConfluenceTemplates === undefined || exactPage !== null) return\n const abort = new AbortController()\n setTemplateState({ _tag: \"loading\" })\n loadConfluenceTemplates(abort.signal).then(\n (templates) => {\n if (abort.signal.aborted) return\n setTemplateState({ _tag: \"ready\", templates })\n },\n () => {\n if (!abort.signal.aborted) setTemplateState({ _tag: \"failed\" })\n }\n )\n return () => abort.abort()\n }, [exactPage?.entityId, loadConfluenceTemplates])\n\n const threadMessages = useMemo(() => presentMessages(messages), [messages])\n const lastProvider = [...messages].reverse().find((message) => message.provider !== undefined)?.provider\n const runtimeUnavailable = runTurn === undefined\n const selectedProviderUnavailable =\n providerCatalogPending || (availableProviders !== undefined && !availableProviders.includes(provider))\n const providerCatalogEmpty = availableProviders?.length === 0\n const pageAwareness = release.releasePageAwareness\n const selectedTemplate =\n templateState._tag === \"ready\"\n ? (templateState.templates.find(({ entityId }) => entityId === templateEntityId) ?? null)\n : null\n const confluenceCreateReady = pageAwareness?.state === \"not-published\"\n const confluenceUpdateReady = pageAwareness?.state === \"stale\" && pageAwareness.publicationActionId !== undefined\n const confluencePublicationReady =\n exactPage !== null || selectedTemplate !== null || confluenceCreateReady || confluenceUpdateReady\n const confluenceAwarenessUnknown = pageAwareness === undefined || pageAwareness.state === \"unknown\"\n const latestRelayAnswer = [...messages].reverse().find(({ role }) => role === \"assistant\")?.content\n\n useEffect(() => {\n if (availableProviders === undefined || (providerWasSelected.current && availableProviders.includes(provider)))\n return\n const fallback = availableProviders[0]\n if (fallback !== undefined) setProvider(fallback)\n }, [availableProviders, provider])\n\n const onSubmit = (event: FormEvent<HTMLFormElement>): void => {\n event.preventDefault()\n const submittedPrompt = prompt.trim()\n if (submittedPrompt.length === 0 || runTurn === undefined || selectedProviderUnavailable || isRunning) return\n const history = boundedReleaseAgentHistory(messages)\n const humanMessage = {\n ...timestamp(),\n content: submittedPrompt,\n id: `turn-${nextMessage.current++}-human`,\n role: \"user\"\n } satisfies LocalThreadMessage\n const abortController = new AbortController()\n activeTurn.current?.abort()\n activeTurn.current = abortController\n setMessages((current) => [...current, humanMessage])\n setPrompt(\"\")\n setFailure(null)\n setIsRunning(true)\n setAnnouncement(\"Relay is reading the release context.\")\n\n const originPath = safeOriginPath(searchParams.get(\"from\"), `${location.pathname}${location.hash}`)\n const modelPrompt =\n exactPage !== null\n ? pageAwareAgentPrompt(submittedPrompt, exactPage)\n : selectedTemplate === null\n ? submittedPrompt\n : pageAwareAgentPrompt(submittedPrompt, {\n contentState: \"loaded\",\n entityId: selectedTemplate.entityId,\n markdown: selectedTemplate.markdown,\n revision: selectedTemplate.revision,\n title: selectedTemplate.title\n })\n runTurn(\n { history, originPath, prompt: modelPrompt, provider, releaseId: release.id, workspaceId },\n { signal: abortController.signal }\n )\n .then(\n (result) => {\n if (abortController.signal.aborted) return\n const reply = result.reply.trim()\n if (reply.length === 0) {\n setFailure(\"failed\")\n setAnnouncement(\"Relay returned an empty answer.\")\n return\n }\n setMessages((current) => [\n ...current,\n {\n ...timestamp(),\n content: reply,\n context: {\n eventCursor: result.eventCursor,\n relayCodename: result.release.relay.codename,\n serviceName: result.release.serviceName,\n updatedAt: result.release.updatedAt,\n version: result.release.version\n },\n id: `turn-${nextMessage.current++}-agent`,\n provider: result.provider,\n role: \"assistant\"\n }\n ])\n setAnnouncement(\"Relay answered in this release thread.\")\n },\n (cause: unknown) => {\n if (abortController.signal.aborted) return\n setFailure(classifyTurnFailure(cause))\n setAnnouncement(\"Relay could not complete this turn.\")\n }\n )\n .finally(() => {\n if (activeTurn.current !== abortController) return\n activeTurn.current = null\n setIsRunning(false)\n })\n }\n\n const publish = (publicationProvider: \"jira\" | \"confluence\"): void => {\n if (publicationBusy !== null || publicationTitle.trim() === \"\" || publicationMarkdown.trim() === \"\") return\n if (publicationProvider === \"confluence\" && !confluencePublicationReady) return\n setPublicationBusy(publicationProvider)\n const updatingConfluence = publicationProvider === \"confluence\" && (exactPage !== null || confluenceUpdateReady)\n setAnnouncement(\n \"Relay is \" +\n (updatingConfluence ? \"updating\" : \"creating\") +\n \" the \" +\n publicationProvider +\n \" release artifact.\"\n )\n submitPublication({\n releaseId: release.id,\n provider: publicationProvider,\n title: publicationTitle.trim(),\n markdown: publicationMarkdown.trim(),\n ...(updatingConfluence &&\n exactPage === null &&\n pageAwareness?.publicationActionId !== undefined && { publicationActionId: pageAwareness.publicationActionId }),\n ...(publicationProvider === \"confluence\" &&\n exactPage !== null && {\n targetEntityId: exactPage.entityId,\n targetRevision: Revision.make(exactPage.revision)\n }),\n ...(publicationProvider === \"confluence\" &&\n exactPage === null &&\n selectedTemplate !== null && { templateEntityId: selectedTemplate.entityId })\n })\n .then(\n (result) =>\n setAnnouncement(\n \"Relay submitted a governed \" +\n (updatingConfluence ? \"Confluence page update\" : publicationProvider + \" publication\") +\n \" (\" +\n result.state +\n \").\"\n ),\n () => setAnnouncement(\"Relay could not publish the \" + publicationProvider + \" release artifact.\")\n )\n .finally(() => setPublicationBusy(null))\n }\n\n return (\n <article className={styles.room} data-release-agent-id={release.id}>\n <Link className={styles.back} state={location.state} to={releaseFullPath(workspaceId, release.id)}>\n Back to release\n </Link>\n {callingContext.path !== null ? (\n <Link className={styles.back} to={callingContext.path}>\n Return to calling page\n </Link>\n ) : null}\n {callingContext.path !== null ? (\n <Text className={styles.eyebrow} tone=\"secondary\" variant=\"label\">\n {callingContext.label}\n </Text>\n ) : null}\n <header className={styles.hero}>\n <ReleaseRelay\n algorithm={release.relay.algorithm}\n codename={release.relay.codename}\n data-rly-release-transition-name={transitionNames.relay}\n data-rly-release-transition-part=\"relay\"\n size=\"hero\"\n style={{ viewTransitionName: transitionNames.relay }}\n symbolIndices={release.relay.symbolIndices}\n />\n <div className={styles.heroCopy}>\n <Text className={styles.eyebrow} tone=\"secondary\" variant=\"label\">\n {release.lifecycleLabel} · {release.version}\n </Text>\n <Text as=\"h1\" id=\"agent-title\" variant=\"verdict\">\n Ask {release.relay.codename}.\n </Text>\n <Text tone=\"secondary\" variant=\"body-large\">\n Relay resolves the current release before every answer. This thread stays in this tab.\n </Text>\n </div>\n </header>\n\n <section aria-labelledby=\"agent-collaborators\" className={styles.people}>\n <Text as=\"h2\" id=\"agent-collaborators\" variant=\"section-title\">\n In this release\n </Text>\n {release.collaborators.length === 0 ? (\n <Text tone=\"secondary\">No owner or approver is assigned yet.</Text>\n ) : (\n <PeopleStrip\n aria-label={`${release.serviceName} release collaborators`}\n expanded\n limit={release.collaborators.length}\n onExpandedChange={() => undefined}\n people={release.collaborators}\n />\n )}\n </section>\n\n <section aria-labelledby=\"agent-presets\" className={styles.starters}>\n <Text as=\"h2\" id=\"agent-presets\" tone=\"secondary\" variant=\"label\">\n Agent preset\n </Text>\n <div aria-label=\"Agent presets\" className={styles.presetList} role=\"radiogroup\">\n {RUN_PRESETS.map((preset) => (\n <button\n aria-checked={provider === preset.provider}\n className={styles.preset}\n disabled={\n runtimeUnavailable ||\n isRunning ||\n providerCatalogPending ||\n (availableProviders !== undefined && !availableProviders.includes(preset.provider))\n }\n key={preset.provider}\n onClick={() => {\n providerWasSelected.current = true\n setProvider(preset.provider)\n }}\n role=\"radio\"\n type=\"button\"\n >\n <strong>{preset.label}</strong>\n <span>{preset.description}</span>\n {availableProviders !== undefined && !availableProviders.includes(preset.provider) ? (\n <small>Not configured</small>\n ) : null}\n </button>\n ))}\n </div>\n <Text as=\"h2\" id=\"agent-starters\" tone=\"secondary\" variant=\"label\">\n Prompt templates\n </Text>\n <div className={styles.suggestionList}>\n {[\n ...(exactPage === null\n ? []\n : [\n {\n label: \"Draft this page\",\n prompt:\n \"Draft the complete updated Confluence page in Markdown for this release. Return only the page body, ready for owner review.\"\n }\n ]),\n ...PROMPT_TEMPLATES\n ].map((template) => (\n <button\n className={styles.suggestion}\n disabled={runtimeUnavailable || selectedProviderUnavailable || isRunning}\n key={template.label}\n onClick={() => setPrompt(template.prompt)}\n type=\"button\"\n >\n <strong>{template.label}</strong>\n <span>{template.prompt}</span>\n </button>\n ))}\n </div>\n </section>\n\n {runtimeUnavailable ? (\n <StatePanel\n description=\"Connect the server to a local Codex or Claude runner. Provider credentials and repository access stay server-side; this tab stores its bounded thread locally.\"\n title=\"Local agent not connected\"\n />\n ) : providerCatalogPending ? null : providerCatalogEmpty ? (\n <StatePanel\n action={<Link to=\"/settings\">Configure an agent</Link>}\n description=\"Enable a local Codex or Claude runner in Settings, then return here to draft or review this release.\"\n title=\"No agent is configured\"\n tone=\"caution\"\n />\n ) : selectedProviderUnavailable ? (\n <StatePanel\n description=\"Choose a configured Codex or Claude preset before starting this turn.\"\n title=\"Selected agent is not configured\"\n tone=\"caution\"\n />\n ) : null}\n {failure === null ? null : <div className={styles.failure}>{failurePanel(failure)}</div>}\n\n <AgentThread\n {...(announcement.length === 0 ? {} : { announcement })}\n className={styles.thread}\n composer={\n <ReleaseAgentComposer\n disabled={runtimeUnavailable || selectedProviderUnavailable}\n isRunning={isRunning}\n onPromptChange={setPrompt}\n onSubmit={onSubmit}\n prompt={prompt}\n provider={provider}\n />\n }\n context={\n <div className={styles.threadContext}>\n <strong>{release.serviceName}</strong>\n <span>{release.version}</span>\n <span>{release.relay.codename}</span>\n <span>Preset {provider}</span>\n {lastProvider === undefined ? null : <span>Last answer {lastProvider}</span>}\n </div>\n }\n emptyLabel=\"Ask one useful question. Relay will answer only for this release.\"\n heading=\"Release thread\"\n messages={threadMessages}\n />\n <Surface\n as=\"section\"\n aria-labelledby=\"relay-publication\"\n className={`${styles.people} ${styles.publication}`}\n padding=\"spacious\"\n ref={publicationRef}\n form=\"grouped\"\n >\n <Text as=\"h2\" id=\"relay-publication\" variant=\"section-title\">\n {exactPage === null ? \"Publish a release artifact\" : \"Edit this Confluence page\"}\n </Text>\n <Text tone=\"secondary\">\n {exactPage === null\n ? \"These governed actions use the current release context and require your workspace-owner confirmation. Jira issue edits remain proposal-only.\"\n : `You are editing the synchronized page at revision ${exactPage.revision}. Type directly, or ask Relay for a draft and bring its latest answer into the editor. Publishing is an explicit, revision-guarded owner action.`}\n </Text>\n {exactPage === null ? (\n <div className={styles.templatePicker}>\n <div>\n <Text as=\"h3\" variant=\"card-title\">\n Start from a Confluence template\n </Text>\n <Text tone=\"secondary\">\n Choose any synchronized Confluence page. Control Center creates a separate release-owned copy; the\n source page remains unchanged.\n </Text>\n </div>\n {templateState._tag === \"loading\" ? <Text tone=\"secondary\">Loading Confluence templates…</Text> : null}\n {templateState._tag === \"failed\" ? (\n <Text tone=\"secondary\">Templates could not be loaded. You can still write a new page from scratch.</Text>\n ) : null}\n {templateState._tag === \"ready\" && templateState.templates.length === 0 ? (\n <Text tone=\"secondary\">\n No synchronized page body is available yet. Synchronize Confluence, then return here.\n </Text>\n ) : null}\n {templateState._tag === \"ready\" && templateState.templates.length > 0 ? (\n <Field label=\"Existing Confluence page\">\n {(controlProps) => (\n <select\n {...controlProps}\n onChange={(event) => {\n const selected = templateState.templates.find(({ entityId }) => entityId === event.target.value)\n if (selected === undefined) {\n setTemplateEntityId(null)\n return\n }\n setTemplateEntityId(selected.entityId)\n setPublicationTitle(`${selected.title} — ${release.version}`)\n setPublicationMarkdown(selected.markdown)\n setAnnouncement(\"A copy of the template is now in the editor. The source page is unchanged.\")\n }}\n value={templateEntityId ?? \"\"}\n >\n <option value=\"\">Write a new page</option>\n {templateState.templates.map((template) => (\n <option key={template.entityId} value={template.entityId}>\n {template.title} · revision {template.revision}\n </option>\n ))}\n </select>\n )}\n </Field>\n ) : null}\n {selectedTemplate === null ? null : (\n <Button\n disabled={runtimeUnavailable || selectedProviderUnavailable || isRunning}\n onClick={() =>\n setPrompt(\n \"Adapt the selected Confluence template for this release. Preserve its useful structure, replace placeholders with current release facts, and return only the complete Markdown body.\"\n )\n }\n variant=\"secondary\"\n >\n Ask Relay to adapt this copy\n </Button>\n )}\n </div>\n ) : null}\n {confluencePage._tag === \"loading\" ? (\n <Text tone=\"secondary\">Loading the exact Confluence page that opened Relay…</Text>\n ) : null}\n {confluencePage._tag === \"unavailable\" ? (\n <Text tone=\"secondary\">\n The calling item is not an editable Confluence page in this release. The generic release publication\n controls remain available.\n </Text>\n ) : null}\n {exactPage?.contentState === \"lazy\" ? (\n <Text tone=\"secondary\">\n The existing page body was not synchronized. Start from a complete Relay draft or paste the complete page\n body before publishing; an empty replacement is blocked.\n </Text>\n ) : null}\n {pageAwareness?.state === \"stale\" ? (\n <Text tone=\"secondary\">\n The release changed after the last successful Confluence publication. Relay suggests updating the page;\n publishing requires an explicit owner confirmation.\n </Text>\n ) : null}\n <Field label={exactPage === null ? \"Title\" : \"Confluence page title\"}>\n {(controlProps) => (\n <input\n {...controlProps}\n value={publicationTitle}\n onChange={(event) => setPublicationTitle(event.target.value)}\n />\n )}\n </Field>\n <Field label={exactPage === null ? \"Release notes\" : \"Page body (Markdown)\"}>\n {(controlProps) => (\n <textarea\n {...controlProps}\n rows={exactPage === null ? 6 : 10}\n value={publicationMarkdown}\n onChange={(event) => setPublicationMarkdown(event.target.value)}\n />\n )}\n </Field>\n {(exactPage !== null || selectedTemplate !== null) && latestRelayAnswer !== undefined ? (\n <Button\n disabled={publicationBusy !== null}\n onClick={() => {\n setPublicationMarkdown(latestRelayAnswer)\n setAnnouncement(\"The latest Relay answer is now in the page editor. Review it before publishing.\")\n }}\n variant=\"secondary\"\n >\n Use latest Relay answer\n </Button>\n ) : null}\n <div className={exactPage === null ? styles.presetList : styles.publicationAction}>\n {exactPage === null ? (\n <Button\n disabled={publicationBusy !== null}\n loading={publicationBusy === \"jira\"}\n onClick={() => publish(\"jira\")}\n >\n Create Jira release version\n </Button>\n ) : null}\n <Button\n disabled={\n publicationBusy !== null ||\n !confluencePublicationReady ||\n confluencePage._tag === \"loading\" ||\n publicationTitle.trim() === \"\" ||\n publicationMarkdown.trim() === \"\"\n }\n loading={publicationBusy === \"confluence\"}\n onClick={() => publish(\"confluence\")}\n >\n {exactPage !== null\n ? \"Publish page update\"\n : selectedTemplate !== null\n ? \"Create template copy in Confluence\"\n : pageAwareness?.state === \"stale\"\n ? \"Update Confluence release page\"\n : pageAwareness?.state === \"current\"\n ? \"Confluence release page is current\"\n : \"Create Confluence release page\"}\n </Button>\n {pageAwareness?.state === \"current\" ? (\n <Text tone=\"secondary\">\n Relay will suggest an update after synchronized release changes make this page stale.\n </Text>\n ) : null}\n {pageAwareness?.state === \"stale\" && !confluenceUpdateReady ? (\n <Text tone=\"secondary\">\n The existing page identity is unavailable, so Relay will not create a duplicate page.\n </Text>\n ) : null}\n {confluenceAwarenessUnknown ? (\n <Text tone=\"secondary\">\n Confluence publication status is unavailable. Refresh the release context before publishing to avoid\n creating a duplicate page.\n </Text>\n ) : null}\n </div>\n </Surface>\n </article>\n )\n}\n\ntype ReleaseAgentRoomProps = Omit<Parameters<typeof ReleaseAgentRoom>[0], \"confluencePage\">\n\nconst EntityContextReleaseAgentRoom = ({\n entityId,\n ...roomProps\n}: ReleaseAgentRoomProps & { readonly entityId: EntityId }): ReactElement => {\n const browserSession = useBrowserSession()\n const sessionKey = browserReadableSessionKey(browserSession.state)\n const controller = useWorkspaceEntity(\n roomProps.workspaceId,\n entityId,\n `${roomProps.release.id}:${roomProps.release.version}`,\n sessionKey,\n browserSession.invalidateSession\n )\n const target = confluencePageDraftTarget(controller.state, roomProps.release.id)\n const confluencePage: ConfluencePageDraftContext =\n controller.state._tag === \"idle\" || controller.state._tag === \"loading\"\n ? { _tag: \"loading\" }\n : target === null\n ? { _tag: \"unavailable\" }\n : { _tag: \"ready\", target }\n return <ReleaseAgentRoom {...roomProps} confluencePage={confluencePage} />\n}\n\nconst ContextualReleaseAgentRoom = (props: ReleaseAgentRoomProps): ReactElement => {\n const [searchParams] = useSearchParams()\n const target = workspaceEntityTargetFromHref(searchParams.get(\"from\") ?? \"\")\n return target !== null && target.workspaceId === props.workspaceId ? (\n <EntityContextReleaseAgentRoom {...props} entityId={target.entityId} />\n ) : (\n <ReleaseAgentRoom {...props} confluencePage={{ _tag: \"none\" }} />\n )\n}\n\nconst CanonicalAgentState = ({ context }: { readonly context: WorkspaceReleaseOutletContext }): ReactElement => {\n switch (context.controller.state._tag) {\n case \"loading\":\n return (\n <StatePanel\n description=\"Control Center is loading the exact release and its collaborators.\"\n title=\"Loading release context\"\n />\n )\n case \"session\":\n return (\n <StatePanel\n action={\n context.controller.state.reason === \"anonymous\" ? <Link to=\"/pair\">Pair this browser</Link> : undefined\n }\n description=\"Release context must be available before Relay can answer.\"\n title={\n context.controller.state.reason === \"blocked\" ? \"Release access blocked\" : \"Release context unavailable\"\n }\n tone={context.controller.state.reason === \"blocked\" ? \"critical\" : \"caution\"}\n />\n )\n case \"failed\":\n return (\n <StatePanel\n action={<Button onClick={context.controller.onRetry}>Try again</Button>}\n description=\"Control Center could not load the release. Check the server, then try again.\"\n title=\"Release context unavailable\"\n tone=\"critical\"\n />\n )\n case \"ready\":\n return <></>\n }\n}\n\nconst LegacyAgentPage = (): ReactElement => {\n const [searchParams] = useSearchParams()\n const context = contextFor(searchParams.get(\"from\"))\n return (\n <section aria-labelledby=\"agent-title\" className={styles.legacy}>\n <header className={styles.legacyHeader}>\n <Text className={styles.eyebrow} tone=\"secondary\" variant=\"label\">\n Relay\n </Text>\n <Text as=\"h1\" id=\"agent-title\" variant=\"verdict\">\n Ask in context.\n </Text>\n <Text tone=\"secondary\" variant=\"body-large\">\n Open Relay from a release to start an exact, release-owned thread.\n </Text>\n </header>\n <Surface as=\"section\" className={styles.legacyContext} padding=\"spacious\" form=\"grouped\" tone=\"secondary\">\n <Text tone=\"secondary\" variant=\"label\">\n Current context\n </Text>\n <Text as=\"h2\" variant=\"section-title\">\n {context.label}\n </Text>\n <Text tone=\"secondary\">{context.description}</Text>\n {context.path === null ? null : (\n <Link className={styles.back} to={context.path}>\n Return to {context.label}\n </Link>\n )}\n </Surface>\n <Surface as=\"section\" className={styles.legacyContext} padding=\"spacious\" form=\"grouped\">\n <Text tone=\"secondary\" variant=\"label\">\n Choose a release\n </Text>\n <Text as=\"h2\" variant=\"section-title\">\n Run Relay with an exact release context\n </Text>\n <Text tone=\"secondary\">\n Relay never runs as an unscoped chatbot. Choose the release whose evidence, freshness, and permissions should\n bound the thread before sending a message.\n </Text>\n <Link className={styles.back} to=\"/releases\">\n Choose a release to run Relay\n </Link>\n </Surface>\n </section>\n )\n}\n\n/** Choose an exact release while retaining the page that launched Relay. */\nconst ContextualAgentPage = ({ originPath }: { readonly originPath: string }): ReactElement => {\n const controller = usePortfolioOverviewController()\n const context = contextFor(originPath)\n switch (controller.state._tag) {\n case \"session\":\n return (\n <section aria-labelledby=\"agent-title\" className={styles.state}>\n <Text as=\"h2\" id=\"agent-title\" variant=\"section-title\">\n Release context stays private\n </Text>\n <StatePanel\n action={controller.state.reason === \"anonymous\" ? <Link to=\"/pair\">Pair this browser</Link> : undefined}\n description=\"Pair this browser before Relay reads a workspace release.\"\n title=\"Pairing required\"\n tone=\"caution\"\n />\n </section>\n )\n case \"loading\":\n return (\n <section aria-labelledby=\"agent-title\" className={styles.state}>\n <Text as=\"h2\" id=\"agent-title\" variant=\"section-title\">\n Choosing a release\n </Text>\n <StatePanel description=\"Loading the releases for this page context.\" title=\"Choosing a release\" />\n </section>\n )\n case \"failed\":\n return (\n <section aria-labelledby=\"agent-title\" className={styles.state}>\n <Text as=\"h2\" id=\"agent-title\" variant=\"section-title\">\n Release context unavailable\n </Text>\n <StatePanel\n action={<Button onClick={controller.onRetry}>Try again</Button>}\n description=\"Relay could not load the releases needed to preserve this page context.\"\n title=\"Release context unavailable\"\n tone=\"critical\"\n />\n </section>\n )\n case \"ready\": {\n const { portfolio } = controller.state\n const singleReleasePath = contextualSingleReleaseAgentPath(portfolio.workspaceId, portfolio.releases, originPath)\n if (singleReleasePath !== undefined) return <Navigate replace to={singleReleasePath} />\n return (\n <section aria-labelledby=\"agent-title\" className={styles.legacy}>\n <header className={styles.legacyHeader}>\n <Text className={styles.eyebrow} tone=\"secondary\" variant=\"label\">\n Relay\n </Text>\n <Text as=\"h1\" id=\"agent-title\" variant=\"verdict\">\n Choose a release.\n </Text>\n <Text tone=\"secondary\" variant=\"body-large\">\n Relay will keep the exact page context below and answer inside the release you choose.\n </Text>\n </header>\n <Surface as=\"section\" className={styles.legacyContext} padding=\"spacious\" form=\"grouped\" tone=\"secondary\">\n <Text tone=\"secondary\" variant=\"label\">\n Calling page\n </Text>\n <Text as=\"h2\" variant=\"section-title\">\n {context.label}\n </Text>\n <Text tone=\"secondary\">{context.description}</Text>\n {context.path !== null ? (\n <Link className={styles.back} to={context.path}>\n Return to calling page\n </Link>\n ) : null}\n </Surface>\n {portfolio.releases.length === 0 ? (\n <StatePanel\n action={<Link to=\"/services\">Connect a service</Link>}\n description=\"Relay needs one synchronized release before it can start a scoped thread.\"\n title=\"No releases available\"\n />\n ) : (\n <div aria-label=\"Releases available to Relay\" className={styles.presetList}>\n {portfolio.releases.map((release) => (\n <Link\n className={styles.preset}\n key={release.id}\n to={contextualReleaseAgentPath(portfolio.workspaceId, release.id, originPath)}\n >\n <strong>{release.relay.codename}</strong>\n <span>\n {release.serviceName} · {release.version}\n </span>\n <small>{release.lifecycleLabel}</small>\n </Link>\n ))}\n </div>\n )}\n </section>\n )\n }\n }\n}\n\n/** Render an exact release-owned local agent thread, with a safe legacy context preview. */\nexport const AgentPage = ({\n availableProviders,\n loadConfluenceTemplates,\n providerCatalogPending = false,\n runTurn,\n submitPublication = submitBrowserReleasePublication\n}: AgentPageProps): ReactElement => {\n const context = useOutletContext<WorkspaceReleaseOutletContext | null>()\n const params = useParams()\n const workspaceId = decodeWorkspaceRouteId(params.workspaceId)\n const releaseId = decodeReleaseRouteId(params.releaseId)\n const isCanonicalRoute = params.workspaceId !== undefined || params.releaseId !== undefined\n\n if (!isCanonicalRoute) return <LegacyAgentPage />\n if (workspaceId === null || releaseId === null || context === null || context.workspaceId !== workspaceId) {\n return (\n <section className={styles.state}>\n <StatePanel\n action={workspaceId === null ? <Link to=\"/\">Return to Control Center</Link> : undefined}\n description=\"This address does not identify a release in the current workspace.\"\n title=\"Release not found\"\n />\n </section>\n )\n }\n if (context.controller.state._tag !== \"ready\") return <CanonicalAgentState context={context} />\n const release = context.controller.state.portfolio.releases.find((candidate) => candidate.id === releaseId)\n if (release === undefined) {\n return (\n <section className={styles.state}>\n <StatePanel\n action={\n <Link\n to={context.controller.state.portfolio.workspaceId === workspaceId ? `/w/${workspaceId}/overview` : \"/\"}\n >\n Return to workspace\n </Link>\n }\n description=\"This release does not exist in the current workspace snapshot.\"\n title=\"Release not found\"\n />\n </section>\n )\n }\n return (\n <ContextualReleaseAgentRoom\n availableProviders={availableProviders}\n key={release.id}\n {...(loadConfluenceTemplates === undefined ? {} : { loadConfluenceTemplates })}\n providerCatalogPending={providerCatalogPending}\n release={release}\n runTurn={runTurn}\n submitPublication={submitPublication}\n workspaceId={workspaceId}\n />\n )\n}\n\ntype ProviderCatalogState =\n | { readonly _tag: \"loading\" }\n | { readonly _tag: \"ready\"; readonly providers: ReadonlyArray<\"claude\" | \"codex\"> }\n | { readonly _tag: \"failed\" }\n\n/** Route entry wired to the authenticated Control Center release-agent API. */\nexport const ConnectedAgentPage = ({\n loadConfluenceTemplates = loadBrowserConfluenceTemplates,\n loadPresets = loadBrowserReleaseAgentPresets,\n runTurn = runBrowserReleaseAgentTurn\n}: {\n readonly loadConfluenceTemplates?: ConfluenceTemplateLoader\n readonly loadPresets?: ReleaseAgentPresetLoader\n readonly runTurn?: ReleaseAgentTurn\n} = {}): ReactElement => {\n const location = useLocation()\n const [searchParams] = useSearchParams()\n const params = useParams()\n const [catalog, setCatalog] = useState<ProviderCatalogState>({ _tag: \"loading\" })\n const [catalogRequest, setCatalogRequest] = useState(0)\n useEffect(() => {\n const abort = new AbortController()\n setCatalog({ _tag: \"loading\" })\n loadPresets(abort.signal).then(\n (providers) => {\n if (!abort.signal.aborted) setCatalog({ _tag: \"ready\", providers })\n },\n () => {\n if (!abort.signal.aborted) setCatalog({ _tag: \"failed\" })\n }\n )\n return () => abort.abort()\n }, [catalogRequest, loadPresets])\n const availableProviders = catalog._tag === \"ready\" ? catalog.providers : undefined\n const isCanonicalRoute = params.workspaceId !== undefined || params.releaseId !== undefined\n const originPath = safeOriginPath(searchParams.get(\"from\"), `${location.pathname}${location.hash}`)\n return (\n <>\n {catalog._tag === \"failed\" ? (\n <section className={styles.state}>\n <StatePanel\n action={<Button onClick={() => setCatalogRequest((request) => request + 1)}>Retry agent presets</Button>}\n description=\"Relay could not confirm the configured local runners. You can retry without leaving this release.\"\n title=\"Agent presets could not be refreshed\"\n tone=\"caution\"\n />\n </section>\n ) : null}\n {isCanonicalRoute ? (\n <AgentPage\n {...(availableProviders === undefined ? {} : { availableProviders })}\n loadConfluenceTemplates={loadConfluenceTemplates}\n providerCatalogPending={catalog._tag !== \"ready\"}\n runTurn={runTurn}\n />\n ) : (\n <ContextualAgentPage originPath={originPath} />\n )}\n </>\n )\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AtlassianOAuthCallbackPage-PfsrTytb.js","names":["Schema.isTrimmed","Schema.isNonEmpty","Schema.isMaxLength","useRef","useState","Schema.decodeUnknownResult","Result.isFailure","styles","StatePanel","Button","Text","Surface","__toESM","useNavigate","V","He","require_jsx_runtime","useSearchParams","useBrowserSession","H","A","decodeUnknownResult","String","AtlassianOAuthGrantId","isNonEmpty","isFailure","isMaxLength","isTrimmed","atlassianOAuthSetupPath","atlassianOAuthRecoveryPath","browserConnectionTestTransport","readAtlassianOAuthSetupIntent","forgetAtlassianOAuthSetupIntent","import_react","require_react","AtlassianOAuthCallbackPage_module_default","import_jsx_runtime","AuthorizationCode","AtlassianOAuthCallbackPage","navigate","searchParams","setSearchParams","callbackGrantState","setupIntent","sessionState","state","setState","exchangeStarted","exchangeRequest","saveRequest","effectGeneration","generation","cleanup","grantId","code","exchange","transport","request","complete","cloudId","save","grant","profile","leaveCallback","site"],"sources":["../../../src/client/services/AtlassianOAuthCallbackPage.module.css","../../../src/client/services/AtlassianOAuthCallbackPage.tsx"],"sourcesContent":[".page {\n display: grid;\n gap: var(--rly-space-6);\n margin: 0 auto;\n max-width: 44rem;\n padding: var(--rly-space-8) var(--rly-space-4);\n}\n\n.heading,\n.sites {\n display: grid;\n gap: var(--rly-space-4);\n}\n\n.site {\n align-items: center;\n display: flex;\n gap: var(--rly-space-4);\n justify-content: space-between;\n}\n\n.identity {\n display: grid;\n gap: var(--rly-space-2);\n}\n","import { Button, StatePanel, Surface, Text } from \"@knpkv/rly/primitives\"\nimport * as Result from \"effect/Result\"\nimport * as Schema from \"effect/Schema\"\nimport { type ReactElement, useEffect, useRef, useState } from \"react\"\nimport { useNavigate, useSearchParams } from \"react-router\"\n\nimport { AtlassianOAuthGrantId, type AtlassianOAuthGrantExchangeResponse } from \"../../api/plugins.js\"\nimport { useBrowserSession } from \"../BrowserSession.js\"\nimport { forgetAtlassianOAuthSetupIntent, readAtlassianOAuthSetupIntent } from \"./atlassianOAuthSetupIntentStorage.js\"\nimport { browserConnectionTestTransport, type ConnectionTestTransport } from \"./connectionTestTransport.js\"\nimport { atlassianOAuthRecoveryPath, atlassianOAuthSetupPath } from \"./serviceOnboarding.js\"\nimport styles from \"./AtlassianOAuthCallbackPage.module.css\"\n\nconst AuthorizationCode = Schema.String.check(Schema.isTrimmed(), Schema.isNonEmpty(), Schema.isMaxLength(4_096))\n\ntype CallbackState =\n | { readonly _tag: \"waiting\" }\n | { readonly _tag: \"exchanging\" }\n | { readonly _tag: \"selecting\"; readonly grant: AtlassianOAuthGrantExchangeResponse; readonly saveFailed: boolean }\n | { readonly _tag: \"saving\"; readonly grant: AtlassianOAuthGrantExchangeResponse; readonly cloudId: string }\n | { readonly _tag: \"failed\" }\n\ntype CallbackTransport = Pick<ConnectionTestTransport, \"completeAtlassianOAuthGrant\" | \"exchangeAtlassianOAuthGrant\">\n\n/** Complete a browser OAuth redirect without exposing provider tokens to the browser. */\nexport const AtlassianOAuthCallbackPage = ({\n transport = browserConnectionTestTransport\n}: {\n readonly transport?: CallbackTransport | undefined\n} = {}): ReactElement => {\n const navigate = useNavigate()\n const [searchParams, setSearchParams] = useSearchParams()\n const callbackGrantState = useRef(searchParams.get(\"state\")).current\n const [setupIntent] = useState(() => readAtlassianOAuthSetupIntent(callbackGrantState))\n const { state: sessionState } = useBrowserSession()\n const [state, setState] = useState<CallbackState>({ _tag: \"waiting\" })\n const exchangeStarted = useRef(false)\n const exchangeRequest = useRef<AbortController | null>(null)\n const saveRequest = useRef<AbortController | null>(null)\n const effectGeneration = useRef(0)\n\n useEffect(() => {\n const generation = ++effectGeneration.current\n const cleanup = (): void => {\n saveRequest.current?.abort()\n void Promise.resolve().then(() => {\n if (effectGeneration.current !== generation) return\n exchangeRequest.current?.abort()\n })\n }\n if (sessionState._tag !== \"authenticated\" || exchangeStarted.current) return cleanup\n exchangeStarted.current = true\n if (searchParams.has(\"error\")) {\n setState({ _tag: \"failed\" })\n return cleanup\n }\n const grantId = Schema.decodeUnknownResult(AtlassianOAuthGrantId)(searchParams.get(\"state\"))\n const code = Schema.decodeUnknownResult(AuthorizationCode)(searchParams.get(\"code\"))\n const exchange = transport.exchangeAtlassianOAuthGrant\n if (Result.isFailure(grantId) || Result.isFailure(code) || exchange === undefined) {\n setState({ _tag: \"failed\" })\n return cleanup\n }\n setSearchParams({}, { replace: true })\n const request = new AbortController()\n exchangeRequest.current = request\n setState({ _tag: \"exchanging\" })\n exchange(grantId.success, code.success, request.signal).then(\n (grant) => {\n if (!request.signal.aborted) setState({ _tag: \"selecting\", grant, saveFailed: false })\n },\n () => {\n if (!request.signal.aborted) setState({ _tag: \"failed\" })\n }\n )\n return cleanup\n }, [searchParams, sessionState, setSearchParams, transport])\n\n const complete = (grant: AtlassianOAuthGrantExchangeResponse, cloudId: string): void => {\n if (setupIntent !== null && setupIntent.preferredSiteId !== null && setupIntent.preferredSiteId !== cloudId) return\n const save = transport.completeAtlassianOAuthGrant\n if (save === undefined) {\n setState({ _tag: \"failed\" })\n return\n }\n const request = new AbortController()\n saveRequest.current?.abort()\n saveRequest.current = request\n setState({ _tag: \"saving\", grant, cloudId })\n void save(grant.grantId, cloudId, request.signal).then(\n (profile) => {\n if (request.signal.aborted) return\n forgetAtlassianOAuthSetupIntent(callbackGrantState)\n navigate(\n setupIntent === null\n ? \"/services\"\n : setupIntent.recoveryConnectionId === undefined\n ? atlassianOAuthSetupPath(setupIntent.providers, profile.profileId, setupIntent.preferredSiteId)\n : atlassianOAuthRecoveryPath(setupIntent.recoveryConnectionId, profile.profileId),\n { replace: true }\n )\n },\n () => {\n if (!request.signal.aborted) setState({ _tag: \"selecting\", grant, saveFailed: true })\n }\n )\n }\n\n const leaveCallback = (): void => {\n forgetAtlassianOAuthSetupIntent(callbackGrantState)\n navigate(\n setupIntent === null\n ? \"/services\"\n : setupIntent.recoveryConnectionId === undefined\n ? atlassianOAuthSetupPath(setupIntent.providers, null, setupIntent.preferredSiteId)\n : \"/services\"\n )\n }\n\n if (sessionState._tag === \"checking\") {\n return (\n <section className={styles.page}>\n <StatePanel description=\"Restoring the browser session that started this sign-in.\" title=\"Finishing sign-in\" />\n </section>\n )\n }\n\n if (sessionState._tag !== \"authenticated\") {\n return (\n <section className={styles.page}>\n <StatePanel\n action={<Button onClick={leaveCallback}>Return to Services</Button>}\n description=\"Return to the paired browser session that started this sign-in.\"\n title=\"Paired session required\"\n />\n </section>\n )\n }\n\n if (state._tag === \"failed\") {\n return (\n <section className={styles.page}>\n <StatePanel\n action={<Button onClick={leaveCallback}>Try again</Button>}\n description=\"The grant may have expired, been denied, or already been used. No provider token was saved.\"\n title=\"Atlassian sign-in did not finish\"\n />\n </section>\n )\n }\n\n if (state._tag !== \"selecting\" && state._tag !== \"saving\") {\n return (\n <section className={styles.page}>\n <StatePanel description=\"Verifying the single-use grant with Atlassian.\" title=\"Finishing sign-in\" />\n </section>\n )\n }\n\n if (\n setupIntent !== null &&\n setupIntent.preferredSiteId !== null &&\n !state.grant.sites.some(({ cloudId }) => cloudId === setupIntent.preferredSiteId)\n ) {\n return (\n <section className={styles.page}>\n <StatePanel\n action={<Button onClick={leaveCallback}>Return to Services</Button>}\n description=\"Sign in with an Atlassian account that can access the site selected from the account card.\"\n title=\"Selected Atlassian site unavailable\"\n />\n </section>\n )\n }\n\n return (\n <section aria-labelledby=\"atlassian-site-title\" className={styles.page}>\n <header className={styles.heading}>\n <Text as=\"h1\" id=\"atlassian-site-title\" variant=\"page-title\">\n Choose your Atlassian site\n </Text>\n <Text tone=\"secondary\" variant=\"body-large\">\n Signed in as {state.grant.accountName}\n {state.grant.accountEmail === null ? \"\" : ` · ${state.grant.accountEmail}`}. Jira and Confluence will share\n this machine-local profile.\n </Text>\n </header>\n <div className={styles.sites}>\n {state._tag === \"selecting\" && state.saveFailed ? (\n <Text as=\"p\" tone=\"secondary\" variant=\"body\">\n The shared profile could not be saved to both tools. Fix the local profile store and retry this site.\n </Text>\n ) : null}\n {state.grant.sites.map((site) => (\n <Surface as=\"article\" className={styles.site} key={site.cloudId} padding=\"default\" form=\"grouped\">\n <div className={styles.identity}>\n <Text as=\"h2\" variant=\"card-title\">\n {site.name}\n </Text>\n <Text tone=\"secondary\" variant=\"body\">\n {site.siteUrl}\n </Text>\n </div>\n <Button\n disabled={\n state._tag === \"saving\" ||\n (setupIntent !== null &&\n setupIntent.preferredSiteId !== null &&\n setupIntent.preferredSiteId !== site.cloudId)\n }\n loading={state._tag === \"saving\" && state.cloudId === site.cloudId}\n onClick={() => complete(state.grant, site.cloudId)}\n variant=\"primary\"\n >\n Use this site\n </Button>\n </Surface>\n ))}\n </div>\n </section>\n )\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AuthorizedSharePage-BCwnILXF.js","names":["Predicate.hasProperty","Data.TaggedError","Schema.decodeUnknownOption","Option.isSome","useState","Effect.tryPromise","Effect.tap","Effect.sync","Effect.repeat","Schedule.spaced","Duration.millis","Effect.catch","StatePanel","styles","Skeleton","Button","Text","Surface","ServiceMark","StateLabel","DateTime.formatIso","__toESM","useParams","Le","V","He","ve","require_jsx_runtime","useBrowserSession","Link","B","H","A","repeat","runPromise","hasProperty","spaced","sync","tap","isSome","tryPromise","formatIso","TaggedError","millis","ShareId","decodeUnknownOption","catch_","WorkspaceId","statusPresentation","serviceFor","statusFor","browserAuthorizedShareTransport","import_react","require_react","AuthorizedSharePage_module_default","import_jsx_runtime","SHARE_REVALIDATION_MILLISECONDS","isTaggedFailure","failure","tag","isNotFound","isUnauthorized","AuthorizedShareResolveError","AuthorizedSharePage","params","browserSession","decodedShareId","decodedWorkspaceId","shareId","workspaceId","authenticatedSession","session","requestRevision","setRequestRevision","state","setState","request","resolveOnce","transport","program","revision","projection","status","presentation"],"sources":["../../../src/client/items/AuthorizedSharePage.module.css","../../../src/client/items/AuthorizedSharePage.tsx"],"sourcesContent":[".page,\n.hero,\n.item,\n.facts {\n display: grid;\n}\n\n.page {\n gap: var(--rly-space-32);\n max-inline-size: 58rem;\n margin-inline: auto;\n}\n\n.hero,\n.item {\n gap: var(--rly-space-12);\n}\n\n.hero > *,\n.item > * {\n margin: 0;\n}\n\n.itemHeader {\n display: flex;\n align-items: center;\n gap: var(--rly-space-12);\n}\n\n.facts {\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: var(--rly-space-12);\n margin-block: var(--rly-space-8);\n}\n\n.facts div {\n display: grid;\n gap: var(--rly-space-4);\n}\n\n.facts dt {\n color: var(--rly-color-text-2);\n font: var(--rly-type-label-weight) var(--rly-type-label-size) / var(--rly-type-label-line-height)\n var(--rly-type-label-font);\n}\n\n.facts dd {\n margin: 0;\n overflow-wrap: anywhere;\n}\n\n.item a {\n justify-self: start;\n min-block-size: 3rem;\n padding: var(--rly-space-8) var(--rly-space-12);\n border: 1px solid var(--rly-color-border-2);\n border-radius: var(--rly-radius-control);\n background: var(--rly-color-surface-1);\n color: var(--rly-color-text-1);\n font: var(--rly-type-label-weight) var(--rly-type-label-size) / var(--rly-type-label-line-height)\n var(--rly-type-label-font);\n text-decoration: none;\n}\n\n.item a:focus-visible {\n outline: 2px solid var(--rly-color-focus);\n outline-offset: var(--rly-space-2);\n}\n\n@media (max-width: 40rem) {\n .facts {\n grid-template-columns: minmax(0, 1fr);\n }\n}\n","import { ServiceMark } from \"@knpkv/rly/patterns\"\nimport { Button, Skeleton, StateLabel, StatePanel, Surface, Text } from \"@knpkv/rly/primitives\"\nimport * as Data from \"effect/Data\"\nimport * as DateTime from \"effect/DateTime\"\nimport * as Duration from \"effect/Duration\"\nimport * as Effect from \"effect/Effect\"\nimport * as Option from \"effect/Option\"\nimport * as Predicate from \"effect/Predicate\"\nimport * as Schedule from \"effect/Schedule\"\nimport * as Schema from \"effect/Schema\"\nimport { type ReactElement, useEffect, useState } from \"react\"\nimport { Link, useParams } from \"react-router\"\n\nimport type { AuthorizedShareResolution } from \"../../api/shares.js\"\nimport { ShareId, WorkspaceId } from \"../../domain/identifiers.js\"\nimport { useBrowserSession } from \"../BrowserSession.js\"\nimport { browserAuthorizedShareTransport, type AuthorizedShareTransport } from \"./authorizedShareTransport.js\"\nimport { serviceFor, statusFor, statusPresentation } from \"./presentWorkspaceItems.js\"\nimport styles from \"./AuthorizedSharePage.module.css\"\n\ntype AuthorizedSharePageState =\n | { readonly _tag: \"idle\" }\n | { readonly _tag: \"loading\" }\n | { readonly _tag: \"failed\" }\n | { readonly _tag: \"not-found\" }\n | { readonly _tag: \"ready\"; readonly resolution: AuthorizedShareResolution }\n\nconst SHARE_REVALIDATION_MILLISECONDS = 30_000\n\nconst isTaggedFailure =\n (tag: string) =>\n <UnparsedInput,>(failure: UnparsedInput): boolean =>\n Predicate.hasProperty(failure, \"_tag\") && failure._tag === tag\n\nconst isNotFound = isTaggedFailure(\"NotFoundApiError\")\nconst isUnauthorized = isTaggedFailure(\"UnauthorizedApiError\")\n\nclass AuthorizedShareResolveError extends Data.TaggedError(\"AuthorizedShareResolveError\")<{\n readonly cause: unknown\n}> {}\n\nexport interface AuthorizedSharePageProps {\n readonly transport?: AuthorizedShareTransport\n}\n\n/** Direct-load authenticated page for one exact shared normalized item. */\nexport const AuthorizedSharePage = ({\n transport = browserAuthorizedShareTransport\n}: AuthorizedSharePageProps = {}): ReactElement => {\n const params = useParams()\n const browserSession = useBrowserSession()\n const decodedShareId = Schema.decodeUnknownOption(ShareId)(params.shareId)\n const decodedWorkspaceId = Schema.decodeUnknownOption(WorkspaceId)(params.workspaceId)\n const shareId = Option.isSome(decodedShareId) ? decodedShareId.value : null\n const workspaceId = Option.isSome(decodedWorkspaceId) ? decodedWorkspaceId.value : null\n const authenticatedSession =\n browserSession.state._tag === \"authenticated\"\n ? browserSession.state.session\n : browserSession.state._tag === \"storage-unavailable\"\n ? browserSession.state.session\n : null\n const session =\n authenticatedSession !== null && authenticatedSession.workspaceId === workspaceId ? authenticatedSession : null\n const [requestRevision, setRequestRevision] = useState(0)\n const [state, setState] = useState<AuthorizedSharePageState>({ _tag: \"idle\" })\n\n useEffect(() => {\n if (shareId === null || workspaceId === null || session === null) {\n setState({ _tag: \"idle\" })\n return\n }\n const request = new AbortController()\n setState({ _tag: \"loading\" })\n const resolveOnce = Effect.tryPromise({\n try: () => transport.resolve(workspaceId, shareId, request.signal),\n catch: (cause) => new AuthorizedShareResolveError({ cause })\n }).pipe(\n Effect.tap((resolution) =>\n Effect.sync(() => {\n if (!request.signal.aborted) setState({ _tag: \"ready\", resolution })\n })\n )\n )\n const program = Effect.repeat(resolveOnce, Schedule.spaced(Duration.millis(SHARE_REVALIDATION_MILLISECONDS))).pipe(\n Effect.catch((failure) =>\n Effect.sync(() => {\n if (request.signal.aborted) return\n if (isUnauthorized(failure.cause)) browserSession.invalidateSession(session.sessionId)\n setState(isNotFound(failure.cause) ? { _tag: \"not-found\" } : { _tag: \"failed\" })\n })\n )\n )\n Effect.runPromise(program, { signal: request.signal }).catch(() => {\n if (!request.signal.aborted) setState({ _tag: \"failed\" })\n })\n return () => request.abort()\n }, [browserSession, requestRevision, session, shareId, transport, workspaceId])\n\n if (shareId === null || workspaceId === null) {\n return (\n <StatePanel\n action={<Link to=\"/\">Return to Control Center</Link>}\n description=\"This authorized link is malformed. No item was substituted.\"\n title=\"Share unavailable\"\n tone=\"caution\"\n />\n )\n }\n\n if (browserSession.state._tag === \"checking\" || state._tag === \"loading\") {\n return (\n <section aria-label=\"Loading authorized share\" className={styles.page}>\n <Skeleton height=\"8rem\" variant=\"block\" />\n <Skeleton height=\"18rem\" variant=\"block\" />\n </section>\n )\n }\n\n if (authenticatedSession === null) {\n return (\n <StatePanel\n action={<Link to=\"/pair\">Pair this browser</Link>}\n description=\"This link grants no bearer access. Pair as the selected person, then reopen it.\"\n title=\"Authentication required\"\n tone=\"caution\"\n />\n )\n }\n\n if (authenticatedSession.workspaceId !== workspaceId) {\n return (\n <StatePanel\n description=\"This link is scoped to another workspace. No item was substituted.\"\n title=\"Share unavailable\"\n tone=\"caution\"\n />\n )\n }\n\n if (state._tag === \"not-found\") {\n return (\n <StatePanel\n description=\"The link may target another person, be expired or revoked, or point to a deleted item.\"\n title=\"Share unavailable\"\n tone=\"caution\"\n />\n )\n }\n\n if (state._tag === \"failed\" || state._tag === \"idle\") {\n return (\n <StatePanel\n action={<Button onClick={() => setRequestRevision((revision) => revision + 1)}>Try again</Button>}\n description=\"Control Center could not resolve this authorized link.\"\n title=\"Share unavailable\"\n tone=\"caution\"\n />\n )\n }\n\n const projection = state.resolution.item.projection\n const status = statusFor(projection.details)\n const presentation = statusPresentation(projection.entityType, status)\n return (\n <article className={styles.page}>\n <header className={styles.hero}>\n <Text as=\"p\" tone=\"secondary\" variant=\"label\">\n Authorized item\n </Text>\n <Text as=\"h1\" variant=\"verdict\">\n Exact scope. Nothing adjacent.\n </Text>\n <Text tone=\"secondary\" variant=\"body-large\">\n This view contains only the granted current item projection. Releases, relationships, and evidence remain\n private.\n </Text>\n </header>\n <Surface as=\"section\" className={styles.item} padding=\"spacious\" tone=\"secondary\">\n <div className={styles.itemHeader}>\n <ServiceMark service={serviceFor(projection.entityType)} size=\"compact\" />\n <StateLabel label={status} size=\"compact\" tone={presentation.tone} />\n </div>\n <Text as=\"p\" tone=\"secondary\" variant=\"label\">\n {projection.displayKey}\n </Text>\n <Text as=\"h2\" variant=\"section-title\">\n {projection.title}\n </Text>\n <dl className={styles.facts}>\n <div>\n <dt>Type</dt>\n <dd>{projection.entityType}</dd>\n </div>\n <div>\n <dt>Observed</dt>\n <dd>{DateTime.formatIso(state.resolution.item.recordedAt)}</dd>\n </div>\n <div>\n <dt>Expires</dt>\n <dd>{DateTime.formatIso(state.resolution.share.expiresAt)}</dd>\n </div>\n </dl>\n </Surface>\n </article>\n )\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ItemsPage-BzinDuxs.js","names":["useMemo","useState","useRef","DateTime.formatIso","styles","Text","Button","StateLabel","Schema.decodeUnknownOption","Option.isSome","useState","styles","PeopleStrip","useMemo","Skeleton","StatePanel","Button","Text","Surface","ServiceMark","StateLabel","__toESM","useOutletContext","useLocation","useNavigate","V","He","ve","require_jsx_runtime","useSearchParams","useBrowserSession","Link","We","B","H","A","PersonId","isSome","formatIso","decodeUnknownOption","makeReleaseRouteState","releaseOriginFromLocation","entityOriginFromLocation","makeWorkspaceEntityRouteState","workspaceItemReleaseHref","useWorkspaceItems","browserWorkspaceItemsTransport","shouldRememberWorkspaceScrollPosition","rememberWorkspaceScrollPosition","browserAuthorizedShareTransport","releaseWorksetSessionKey","import_react","require_react","ItemsPage_module_default","import_jsx_runtime","shareLifetime","value","shareGrantees","byId","currentPersonId","grantee","grantees","AuthorizedSharePanel","options","granteePersonId","setGranteePersonId","lifetime","setLifetime","state","setState","createIntent","currentRequest","statusRegion","create","event","request","existingIntent","entityId","transport","nextIntent","currentIntent","share","revoke","workspaceId","shareId","selectGrantee","selectLifetime","createAnother","sharePath","option","entityKinds","services","freshnessFormatter","formatItemFreshness","freshness","itemsLocationWithSearch","location","params","unlinkedItemLocation","next","entityKind","candidate","itemStatus","itemOwner","decoded","filtersFrom","filterWorkspaceItems","query","filters","items","item","id","ItemOwners","expanded","setExpanded","selectWorkspaceItem","labelForKind","kind","part","workspaceItemMembershipDescription","ItemsPage","context","browserSession","navigate","searchParams","portfolio","releaseById","release","routableReleaseIds","refreshKey","sessionKey","controller","replaceSearch","update","key","portfolioBoundary","Le","PortfolioOverviewView","visibleItems","hasSelectedOwnerOption","personId","selectedOwner","owners","selectedEntityId","selectedItem","shareOwnerPersonId","clearSelection","service","owner","shareTransport","releaseId"],"sources":["../../../src/client/items/ItemsPage.module.css","../../../src/client/items/AuthorizedSharePanel.tsx","../../../src/client/items/ItemsPage.tsx"],"sourcesContent":[".page,\n.hero,\n.filters,\n.items,\n.item,\n.itemLink,\n.meta,\n.selection {\n display: grid;\n}\n\n.page {\n gap: var(--rly-space-32);\n}\n\n.hero {\n gap: var(--rly-space-8);\n max-inline-size: 52rem;\n}\n\n.hero > * {\n margin: 0;\n}\n\n.filters {\n grid-template-columns: minmax(16rem, 2fr) repeat(4, minmax(9rem, 1fr));\n gap: var(--rly-space-12);\n align-items: end;\n}\n\n.filters label {\n display: grid;\n gap: var(--rly-space-6);\n color: var(--rly-color-text-2);\n font: var(--rly-type-label-weight) var(--rly-type-label-size) / var(--rly-type-label-line-height)\n var(--rly-type-label-font);\n}\n\n.filters input,\n.filters select {\n min-block-size: 3.5rem;\n inline-size: 100%;\n padding-inline: var(--rly-space-16);\n border: 1px solid var(--rly-color-border-2);\n border-radius: var(--rly-radius-control);\n background: var(--rly-color-surface-1);\n color: var(--rly-color-text-1);\n font: inherit;\n}\n\n.filters input:focus-visible,\n.filters select:focus-visible,\n.itemLink:focus-visible,\n.membershipChoices a:focus-visible,\n.shareLink:focus-visible {\n outline: 2px solid var(--rly-color-focus);\n outline-offset: var(--rly-space-2);\n}\n\n.resultHeading {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--rly-space-12);\n}\n\n.resultHeading h2 {\n margin: 0;\n}\n\n.selection {\n gap: var(--rly-space-12);\n scroll-margin-block-start: var(--rly-space-24);\n}\n\n.selection > * {\n margin: 0;\n}\n\n.selectionHeader,\n.selectionActions,\n.membershipChoices {\n display: flex;\n align-items: center;\n gap: var(--rly-space-12);\n}\n\n.selectionActions {\n justify-content: space-between;\n}\n\n.membershipChoices {\n flex-wrap: wrap;\n}\n\n.membershipChoices a {\n display: grid;\n gap: var(--rly-space-2);\n min-block-size: 3rem;\n padding: var(--rly-space-8) var(--rly-space-12);\n border: 1px solid var(--rly-color-border-2);\n border-radius: var(--rly-radius-control);\n background: var(--rly-color-surface-1);\n color: var(--rly-color-text-1);\n font: var(--rly-type-label-weight) var(--rly-type-label-size) / var(--rly-type-label-line-height)\n var(--rly-type-label-font);\n text-decoration: none;\n}\n\n.membershipChoices a span {\n color: var(--rly-color-text-2);\n font: var(--rly-type-meta-weight) var(--rly-type-meta-size) / var(--rly-type-meta-line-height)\n var(--rly-type-meta-font);\n}\n\n.items {\n gap: var(--rly-space-8);\n}\n\n.item {\n grid-template-columns: auto minmax(0, 1fr) auto auto;\n align-items: center;\n gap: var(--rly-space-16);\n min-block-size: 5.5rem;\n padding: var(--rly-space-16) var(--rly-space-20);\n}\n\n.itemLink {\n gap: var(--rly-space-2);\n min-inline-size: 0;\n color: inherit;\n text-decoration: none;\n}\n\n.shareLink {\n min-block-size: 2.5rem;\n padding: var(--rly-space-8) var(--rly-space-12);\n border: 1px solid var(--rly-color-border-2);\n border-radius: var(--rly-radius-control);\n color: var(--rly-color-text-1);\n font: var(--rly-type-label-weight) var(--rly-type-label-size) / var(--rly-type-label-line-height)\n var(--rly-type-label-font);\n text-decoration: none;\n}\n\n.itemLink span,\n.meta {\n color: var(--rly-color-text-2);\n font: var(--rly-type-meta-weight) var(--rly-type-meta-size) / var(--rly-type-meta-line-height)\n var(--rly-type-meta-font);\n}\n\n.owners {\n min-inline-size: max-content;\n}\n\n.ownerGroup {\n display: grid;\n gap: var(--rly-space-4);\n min-inline-size: 0;\n}\n\n.ownerLimit {\n color: var(--rly-color-text-2);\n font: var(--rly-type-meta-weight) var(--rly-type-meta-size) / var(--rly-type-meta-line-height)\n var(--rly-type-meta-font);\n}\n\n.itemLink strong {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.meta {\n grid-auto-flow: column;\n align-items: center;\n gap: var(--rly-space-12);\n}\n\n.shareForm,\n.shareResult {\n display: grid;\n grid-template-columns: minmax(12rem, 1fr) minmax(8rem, auto) minmax(8rem, auto) auto;\n gap: var(--rly-space-12);\n align-items: end;\n padding-block: var(--rly-space-12);\n border-block: 1px solid var(--rly-color-border-2);\n}\n\n.shareForm > div,\n.shareResult > div {\n display: grid;\n gap: var(--rly-space-4);\n}\n\n.shareForm h3,\n.shareForm p,\n.shareResult h3,\n.shareResult p {\n margin: 0;\n}\n\n.shareForm label {\n display: grid;\n gap: var(--rly-space-6);\n color: var(--rly-color-text-2);\n font: var(--rly-type-label-weight) var(--rly-type-label-size) / var(--rly-type-label-line-height)\n var(--rly-type-label-font);\n}\n\n.shareForm select {\n min-block-size: 3rem;\n padding-inline: var(--rly-space-12);\n border: 1px solid var(--rly-color-border-2);\n border-radius: var(--rly-radius-control);\n background: var(--rly-color-surface-1);\n color: var(--rly-color-text-1);\n font: inherit;\n}\n\n.shareForm select:focus-visible,\n.shareResult a:focus-visible {\n outline: 2px solid var(--rly-color-focus);\n outline-offset: var(--rly-space-2);\n}\n\n.shareResult {\n grid-template-columns: minmax(0, 1fr) auto auto;\n}\n\n.shareResult a {\n overflow-wrap: anywhere;\n color: var(--rly-color-text-1);\n}\n\n@media (max-width: 64rem) {\n .filters {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n }\n\n .search {\n grid-column: 1 / -1;\n }\n\n .item {\n grid-template-columns: auto minmax(0, 1fr);\n }\n\n .meta {\n grid-column: 2;\n grid-auto-flow: row;\n grid-template-columns: repeat(2, minmax(0, max-content));\n }\n\n .shareLink {\n grid-column: 2;\n justify-self: start;\n }\n\n .shareForm,\n .shareResult {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n align-items: end;\n }\n\n .shareForm > div,\n .shareResult > div {\n grid-column: 1 / -1;\n }\n}\n\n@media (max-width: 40rem) {\n .filters {\n grid-template-columns: minmax(0, 1fr);\n }\n\n .search {\n grid-column: auto;\n }\n\n .meta,\n .shareForm,\n .shareResult {\n grid-template-columns: minmax(0, 1fr);\n }\n\n .shareForm > div,\n .shareResult > div {\n grid-column: auto;\n }\n}\n","import { Button, StateLabel, Text } from \"@knpkv/rly/primitives\"\nimport * as DateTime from \"effect/DateTime\"\nimport { type FormEvent, type ReactElement, useEffect, useMemo, useRef, useState } from \"react\"\nimport { Link } from \"react-router\"\n\nimport type { WorkspaceEntityOwner } from \"../../api/deliveryGraph.js\"\nimport type { EntityId, ShareId, WorkspaceId } from \"../../domain/identifiers.js\"\nimport { PersonId } from \"../../domain/identifiers.js\"\nimport {\n browserAuthorizedShareTransport,\n type AuthorizedShareLifetime,\n type AuthorizedShareTransport,\n type CreateAuthorizedShareTransportInput\n} from \"./authorizedShareTransport.js\"\nimport styles from \"./ItemsPage.module.css\"\n\ninterface ShareGrantee {\n readonly displayName: string\n readonly personId: PersonId\n}\n\ntype AuthorizedSharePanelState =\n | { readonly _tag: \"idle\" }\n | { readonly _tag: \"creating\" }\n | { readonly _tag: \"failed\" }\n | { readonly _tag: \"ready\"; readonly shareId: ShareId; readonly expiresAt: string }\n | { readonly _tag: \"revoking\"; readonly shareId: ShareId; readonly expiresAt: string }\n | { readonly _tag: \"revoked\" }\n\nexport interface AuthorizedSharePanelProps {\n readonly currentPersonId: PersonId\n readonly entityId: EntityId\n readonly grantees: ReadonlyArray<WorkspaceEntityOwner>\n readonly transport?: AuthorizedShareTransport\n readonly workspaceId: WorkspaceId\n}\n\nconst shareLifetime = (value: string): AuthorizedShareLifetime => (value === \"hour\" || value === \"week\" ? value : \"day\")\n\nconst shareGrantees = (\n currentPersonId: PersonId,\n grantees: ReadonlyArray<WorkspaceEntityOwner>\n): ReadonlyArray<ShareGrantee> => {\n const byId = new Map<PersonId, ShareGrantee>()\n byId.set(currentPersonId, { displayName: \"You\", personId: currentPersonId })\n for (const grantee of grantees) {\n byId.set(grantee.personId, { displayName: grantee.displayName, personId: grantee.personId })\n }\n return [...byId.values()]\n}\n\n/** Owner-only creation and revocation controls for one exact item share. */\nexport const AuthorizedSharePanel = ({\n currentPersonId,\n entityId,\n grantees,\n transport = browserAuthorizedShareTransport,\n workspaceId\n}: AuthorizedSharePanelProps): ReactElement => {\n const options = useMemo(() => shareGrantees(currentPersonId, grantees), [currentPersonId, grantees])\n const [granteePersonId, setGranteePersonId] = useState<PersonId>(options[0]?.personId ?? currentPersonId)\n const [lifetime, setLifetime] = useState<AuthorizedShareLifetime>(\"day\")\n const [state, setState] = useState<AuthorizedSharePanelState>({ _tag: \"idle\" })\n const createIntent = useRef<CreateAuthorizedShareTransportInput | null>(null)\n const currentRequest = useRef<AbortController | null>(null)\n const statusRegion = useRef<HTMLElement | null>(null)\n\n useEffect(() => () => currentRequest.current?.abort(), [])\n useEffect(() => {\n if (state._tag === \"ready\" || state._tag === \"revoked\") statusRegion.current?.focus()\n }, [state._tag])\n\n const create = (event: FormEvent<HTMLFormElement>): void => {\n event.preventDefault()\n currentRequest.current?.abort()\n const request = new AbortController()\n currentRequest.current = request\n setState({ _tag: \"creating\" })\n const existingIntent = createIntent.current\n const intent =\n existingIntent !== null &&\n existingIntent.entityId === entityId &&\n existingIntent.granteePersonId === granteePersonId &&\n existingIntent.lifetime === lifetime\n ? Promise.resolve(existingIntent)\n : transport.prepareCreate({ entityId, granteePersonId, lifetime }).then((nextIntent) => {\n createIntent.current = nextIntent\n return nextIntent\n })\n intent\n .then((currentIntent) => transport.create(currentIntent, request.signal))\n .then(\n (share) => {\n if (request.signal.aborted) return\n const currentIntent = createIntent.current\n if (\n currentIntent === null ||\n share.shareId !== currentIntent.shareId ||\n share.entityId !== currentIntent.entityId ||\n share.granteePersonId !== currentIntent.granteePersonId\n ) {\n setState({ _tag: \"failed\" })\n return\n }\n if (share.revokedAt !== null) {\n setState({ _tag: \"revoked\" })\n return\n }\n setState({\n _tag: \"ready\",\n shareId: share.shareId,\n expiresAt: DateTime.formatIso(share.expiresAt)\n })\n },\n () => {\n if (!request.signal.aborted) setState({ _tag: \"failed\" })\n }\n )\n }\n\n const revoke = (shareId: ShareId, expiresAt: string): void => {\n currentRequest.current?.abort()\n const request = new AbortController()\n currentRequest.current = request\n setState({ _tag: \"revoking\", shareId, expiresAt })\n transport.revoke(workspaceId, shareId, request.signal).then(\n () => {\n if (!request.signal.aborted) setState({ _tag: \"revoked\" })\n },\n () => {\n if (!request.signal.aborted) setState({ _tag: \"ready\", shareId, expiresAt })\n }\n )\n }\n\n const selectGrantee = (value: string): void => {\n createIntent.current = null\n setGranteePersonId(PersonId.make(value))\n }\n const selectLifetime = (value: string): void => {\n createIntent.current = null\n setLifetime(shareLifetime(value))\n }\n const createAnother = (): void => {\n createIntent.current = null\n setState({ _tag: \"idle\" })\n }\n\n if (state._tag === \"ready\" || state._tag === \"revoking\") {\n const sharePath = `/shares/${workspaceId}/${state.shareId}`\n return (\n <section\n aria-label=\"Authorized share\"\n aria-live=\"polite\"\n className={styles.shareResult}\n ref={statusRegion}\n role=\"status\"\n tabIndex={-1}\n >\n <div>\n <Text as=\"h3\" variant=\"body-large\">\n Authorized link ready\n </Text>\n <Text tone=\"secondary\">Only the selected person can open this exact item. Expires {state.expiresAt}.</Text>\n </div>\n <Link to={sharePath}>{sharePath}</Link>\n <Button disabled={state._tag === \"revoking\"} onClick={() => revoke(state.shareId, state.expiresAt)}>\n {state._tag === \"revoking\" ? \"Revoking…\" : \"Revoke link\"}\n </Button>\n </section>\n )\n }\n\n if (state._tag === \"revoked\") {\n return (\n <section\n aria-label=\"Authorized share\"\n aria-live=\"polite\"\n className={styles.shareResult}\n ref={statusRegion}\n role=\"status\"\n tabIndex={-1}\n >\n <StateLabel label=\"Revoked\" size=\"compact\" tone=\"neutral\" />\n <Text tone=\"secondary\">This link no longer resolves.</Text>\n <Button onClick={createAnother}>Create another</Button>\n </section>\n )\n }\n\n return (\n <form className={styles.shareForm} onSubmit={create}>\n <div>\n <Text as=\"h3\" variant=\"body-large\">\n Share this exact item\n </Text>\n <Text tone=\"secondary\">Authenticated access only. Related releases and relationships stay private.</Text>\n </div>\n <label>\n <span>Person</span>\n <select\n disabled={state._tag === \"creating\"}\n onChange={(event) => selectGrantee(event.currentTarget.value)}\n value={granteePersonId}\n >\n {options.map((option) => (\n <option key={option.personId} value={option.personId}>\n {option.displayName}\n </option>\n ))}\n </select>\n </label>\n <label>\n <span>Expires</span>\n <select\n disabled={state._tag === \"creating\"}\n onChange={(event) => selectLifetime(event.currentTarget.value)}\n value={lifetime}\n >\n <option value=\"hour\">In 1 hour</option>\n <option value=\"day\">In 1 day</option>\n <option value=\"week\">In 7 days</option>\n </select>\n </label>\n <Button disabled={state._tag === \"creating\"} type=\"submit\">\n {state._tag === \"creating\" ? \"Creating…\" : \"Create authorized link\"}\n </Button>\n {state._tag === \"failed\" ? (\n <Text role=\"alert\" tone=\"secondary\">\n Could not create the link. Check the person and try again.\n </Text>\n ) : null}\n </form>\n )\n}\n","import { PeopleStrip, ServiceMark } from \"@knpkv/rly/patterns\"\nimport { Button, Skeleton, StateLabel, StatePanel, Surface, Text } from \"@knpkv/rly/primitives\"\nimport * as Option from \"effect/Option\"\nimport * as Schema from \"effect/Schema\"\nimport { type ReactElement, useMemo, useState } from \"react\"\nimport { Link, useLocation, useNavigate, useOutletContext, useSearchParams } from \"react-router\"\n\nimport type { DeliveryEntityKind, DeliveryEntityService } from \"../../domain/deliveryGraph.js\"\nimport { PersonId } from \"../../domain/identifiers.js\"\nimport { useBrowserSession } from \"../BrowserSession.js\"\nimport { PortfolioOverviewView, type PortfolioOverviewState } from \"../portfolio/PortfolioOverview.js\"\nimport type { WorkspaceReleaseOutletContext } from \"../releases/WorkspaceReleaseLayout.js\"\nimport { makeReleaseRouteState, releaseOriginFromLocation } from \"../releases/releaseRoutes.js\"\nimport { releaseWorksetSessionKey } from \"../releases/ReleaseWorkset.js\"\nimport { rememberWorkspaceScrollPosition, shouldRememberWorkspaceScrollPosition } from \"../workspaceScrollCapture.js\"\nimport {\n type WorkspaceItemPresentation,\n type WorkspaceItemStatus,\n workspaceItemReleaseHref\n} from \"./presentWorkspaceItems.js\"\nimport { browserWorkspaceItemsTransport, useWorkspaceItems, type WorkspaceItemsTransport } from \"./useWorkspaceItems.js\"\nimport { AuthorizedSharePanel } from \"./AuthorizedSharePanel.js\"\nimport type { AuthorizedShareTransport } from \"./authorizedShareTransport.js\"\nimport styles from \"./ItemsPage.module.css\"\nimport { entityOriginFromLocation, makeWorkspaceEntityRouteState } from \"./workspaceEntityRoutes.js\"\n\ninterface ItemFilters {\n readonly query: string\n readonly owner: PersonId | \"all\"\n readonly service: DeliveryEntityService | \"all\"\n readonly status: WorkspaceItemStatus | \"all\"\n readonly type: DeliveryEntityKind | \"all\"\n}\n\nexport interface ItemsPageProps {\n readonly shareTransport?: AuthorizedShareTransport\n readonly transport?: WorkspaceItemsTransport\n}\n\nconst entityKinds: ReadonlyArray<DeliveryEntityKind> = [\n \"issue\",\n \"pull-request\",\n \"page\",\n \"pipeline-execution\",\n \"deployment\",\n \"time-entry\"\n]\nconst services: ReadonlyArray<DeliveryEntityService> = [\"jira\", \"codecommit\", \"confluence\", \"codepipeline\", \"clockify\"]\nconst freshnessFormatter = new Intl.DateTimeFormat(\"en-GB\", {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n timeZone: \"UTC\"\n})\n\nexport const formatItemFreshness = (freshness: string): string => freshnessFormatter.format(Date.parse(freshness))\n\nexport const itemsLocationWithSearch = (location: Pick<Location, \"hash\" | \"pathname\">, params: URLSearchParams) => ({\n hash: location.hash,\n pathname: location.pathname,\n search: params.size === 0 ? \"\" : `?${params.toString()}`\n})\n\nexport const unlinkedItemLocation = (pathname: string, params: URLSearchParams, entityId: string) => {\n const next = new URLSearchParams(params)\n next.set(\"object\", entityId)\n return {\n hash: \"#item-details\",\n pathname,\n search: `?${next.toString()}`\n }\n}\n\nconst entityKind = (value: string | null): DeliveryEntityKind | \"all\" =>\n entityKinds.find((candidate) => candidate === value) ?? \"all\"\n\nconst itemStatus = (value: string | null): WorkspaceItemStatus | \"all\" =>\n value === \"active\" || value === \"done\" || value === \"failed\" ? value : \"all\"\n\nconst itemOwner = (value: string | null): PersonId | \"all\" => {\n const decoded = Schema.decodeUnknownOption(PersonId)(value)\n return Option.isSome(decoded) ? decoded.value : \"all\"\n}\n\nconst filtersFrom = (params: URLSearchParams): ItemFilters => ({\n owner: itemOwner(params.get(\"owner\")),\n query: params.get(\"q\")?.trim() ?? \"\",\n service: services.find((candidate) => candidate === params.get(\"service\")) ?? \"all\",\n status: itemStatus(params.get(\"status\")),\n type: entityKind(params.get(\"type\"))\n})\n\nexport const filterWorkspaceItems = (\n items: ReadonlyArray<WorkspaceItemPresentation>,\n filters: ItemFilters\n): ReadonlyArray<WorkspaceItemPresentation> => {\n const query = filters.query.toLocaleLowerCase(\"en-US\")\n return items.filter(\n (item) =>\n (query.length === 0 || `${item.key} ${item.title} ${item.status}`.toLocaleLowerCase(\"en-US\").includes(query)) &&\n (filters.service === \"all\" || item.service === filters.service) &&\n (filters.owner === \"all\" || item.owners.some(({ id }) => id === filters.owner)) &&\n (filters.status === \"all\" || item.statusGroup === filters.status) &&\n (filters.type === \"all\" || item.kind === filters.type)\n )\n}\n\nconst ItemOwners = ({ item }: { readonly item: WorkspaceItemPresentation }): ReactElement => {\n const [expanded, setExpanded] = useState(false)\n if (item.owners.length === 0) return <span>Unassigned</span>\n return (\n <span className={styles.ownerGroup}>\n <PeopleStrip\n aria-label={`${item.key} collaborators${item.ownersTruncated ? \", more collaborators not shown\" : \"\"}`}\n className={styles.owners}\n expanded={expanded}\n limit={2}\n onExpandedChange={setExpanded}\n people={item.owners}\n size=\"compact\"\n />\n {item.ownersTruncated ? <span className={styles.ownerLimit}>20+ people · More not shown</span> : null}\n </span>\n )\n}\n\nexport const selectWorkspaceItem = (\n items: ReadonlyArray<WorkspaceItemPresentation>,\n entityId: string | null\n): WorkspaceItemPresentation | null =>\n entityId === null ? null : (items.find((item) => item.entityId === entityId) ?? null)\n\nconst labelForKind = (kind: DeliveryEntityKind): string =>\n kind\n .split(\"-\")\n .map((part) => `${part.charAt(0).toLocaleUpperCase(\"en-US\")}${part.slice(1)}`)\n .join(\" \")\n\nexport const workspaceItemMembershipDescription = (item: WorkspaceItemPresentation): string => {\n if (item.releaseIds.length === 0) {\n return \"This current object is not linked to a release yet. Its provider-specific full view will remain available here when that integration is connected.\"\n }\n if (item.routableReleaseIds.length === 0) {\n return `This object is linked to ${item.releaseIds.length}${item.releaseMembershipsTruncated ? \"+\" : \"\"} release${item.releaseIds.length === 1 ? \"\" : \"s\"} outside the current portfolio. Its membership remains visible without routing to an unavailable release page.`\n }\n if (item.releaseIds.length === 1) {\n return \"This object is linked to one release and can be opened in its complete delivery context.\"\n }\n return `This object is linked to ${item.releaseIds.length}${item.releaseMembershipsTruncated ? \"+\" : \"\"} releases. Choose the exact release context to avoid silently substituting another delivery trace.`\n}\n\n/** Compact workspace-wide index of normalized delivery objects. */\nexport const ItemsPage = ({\n shareTransport,\n transport = browserWorkspaceItemsTransport\n}: ItemsPageProps = {}): ReactElement => {\n const context = useOutletContext<WorkspaceReleaseOutletContext>()\n const browserSession = useBrowserSession()\n const location = useLocation()\n const navigate = useNavigate()\n const [searchParams] = useSearchParams()\n const portfolio = context.controller.state._tag === \"ready\" ? context.controller.state.portfolio : null\n const releaseById = useMemo(\n () => new Map(portfolio?.releases.map((release) => [release.id, release]) ?? []),\n [portfolio]\n )\n const routableReleaseIds = useMemo(() => new Set(portfolio?.releases.map(({ id }) => id) ?? []), [portfolio])\n const refreshKey =\n context.controller.state._tag === \"ready\" ? context.controller.state.portfolio.generatedAt : \"pending\"\n const sessionKey = releaseWorksetSessionKey(browserSession.state)\n const filters = filtersFrom(searchParams)\n const controller = useWorkspaceItems(\n context.workspaceId,\n routableReleaseIds,\n filters,\n refreshKey,\n sessionKey,\n browserSession.invalidateSession,\n transport\n )\n const replaceSearch = (next: URLSearchParams): void => {\n navigate(itemsLocationWithSearch(location, next), { replace: true })\n }\n const update = (key: keyof ItemFilters, value: string): void => {\n const next = new URLSearchParams(searchParams)\n if (value.length === 0 || value === \"all\") next.delete(key === \"query\" ? \"q\" : key)\n else next.set(key === \"query\" ? \"q\" : key, value)\n replaceSearch(next)\n }\n\n const portfolioBoundary: PortfolioOverviewState | null =\n context.controller.state._tag !== \"ready\"\n ? context.controller.state\n : sessionKey === null\n ? {\n _tag: \"session\",\n reason: browserSession.state._tag === \"authenticated\" ? \"checking\" : browserSession.state._tag\n }\n : null\n if (portfolioBoundary?._tag === \"loading\") {\n return (\n <section aria-label=\"Loading delivery items\" className={styles.page}>\n <Skeleton height=\"8rem\" variant=\"block\" />\n <Skeleton height=\"20rem\" variant=\"block\" />\n </section>\n )\n }\n if (portfolioBoundary !== null) {\n return (\n <PortfolioOverviewView\n onPreviewRelease={() => undefined}\n onRetry={context.controller.onRetry}\n state={portfolioBoundary}\n />\n )\n }\n if (controller.state._tag === \"idle\" || controller.state._tag === \"loading\") {\n return (\n <section aria-label=\"Loading delivery items\" className={styles.page}>\n <Skeleton height=\"8rem\" variant=\"block\" />\n <Skeleton height=\"20rem\" variant=\"block\" />\n </section>\n )\n }\n if (controller.state._tag === \"failed\") {\n return (\n <StatePanel\n action={<Button onClick={controller.retry}>Try again</Button>}\n description=\"Control Center could not read the normalized delivery index. Saved source facts remain unchanged.\"\n title=\"Items unavailable\"\n tone=\"caution\"\n />\n )\n }\n\n const visibleItems = controller.state.items\n const hasSelectedOwnerOption =\n filters.owner === \"all\" || controller.state.ownerOptions.some(({ personId }) => personId === filters.owner)\n const selectedOwner =\n filters.owner === \"all\"\n ? undefined\n : controller.state.items.flatMap(({ owners }) => owners).find(({ id }) => id === filters.owner)\n const selectedEntityId = searchParams.get(\"object\")\n const selectedItem = selectWorkspaceItem(controller.state.items, selectedEntityId)\n const shareOwnerPersonId =\n browserSession.state._tag === \"authenticated\" &&\n browserSession.state.session.permission === \"workspace-owner\" &&\n browserSession.state.session.actor._tag === \"human\"\n ? browserSession.state.session.actor.personId\n : null\n const clearSelection = (): void => {\n const next = new URLSearchParams(searchParams)\n next.delete(\"object\")\n navigate(\n {\n hash: \"#results\",\n pathname: location.pathname,\n search: next.size === 0 ? \"\" : `?${next.toString()}`\n },\n { replace: true }\n )\n }\n return (\n <article className={styles.page}>\n <header className={styles.hero}>\n <Text as=\"p\" tone=\"secondary\" variant=\"label\">\n Workspace items\n </Text>\n <Text as=\"h1\" variant=\"verdict\">\n Find release work.\n </Text>\n <Text tone=\"secondary\" variant=\"body-large\">\n One quiet index across tickets, pull requests, docs, pipelines, deployments, and time.\n </Text>\n </header>\n\n <section aria-label=\"Item filters\" className={styles.filters}>\n <label className={styles.search}>\n <span>Search</span>\n <input\n maxLength={200}\n onChange={(event) => update(\"query\", event.currentTarget.value)}\n placeholder=\"Key, title, or status\"\n type=\"search\"\n value={filters.query}\n />\n </label>\n <label>\n <span>Service</span>\n <select onChange={(event) => update(\"service\", event.currentTarget.value)} value={filters.service}>\n <option value=\"all\">All services</option>\n {services.map((service) => (\n <option key={service} value={service}>\n {service}\n </option>\n ))}\n </select>\n </label>\n <label>\n <span>Owner</span>\n <select onChange={(event) => update(\"owner\", event.currentTarget.value)} value={filters.owner}>\n <option value=\"all\">Anyone</option>\n {filters.owner !== \"all\" && !hasSelectedOwnerOption ? (\n <option value={filters.owner}>{selectedOwner?.name ?? `Owner …${filters.owner.slice(-6)}`}</option>\n ) : null}\n {controller.state.ownerOptions.map((owner) => (\n <option key={owner.personId} value={owner.personId}>\n {owner.displayName}\n </option>\n ))}\n {controller.state.ownerOptionsTruncated ? <option disabled>More owners not shown</option> : null}\n </select>\n </label>\n <label>\n <span>Type</span>\n <select onChange={(event) => update(\"type\", event.currentTarget.value)} value={filters.type}>\n <option value=\"all\">All types</option>\n {entityKinds.map((kind) => (\n <option key={kind} value={kind}>\n {labelForKind(kind)}\n </option>\n ))}\n </select>\n </label>\n <label>\n <span>Status</span>\n <select onChange={(event) => update(\"status\", event.currentTarget.value)} value={filters.status}>\n <option value=\"all\">Any status</option>\n <option value=\"active\">Active</option>\n <option value=\"done\">Done</option>\n <option value=\"failed\">Needs attention</option>\n </select>\n </label>\n </section>\n\n {selectedEntityId === null ? null : selectedItem === null ? (\n <div id=\"item-details\">\n <StatePanel\n action={<Button onClick={clearSelection}>Back to items</Button>}\n description=\"This item is not present in the current bounded workspace index. It may have been deleted or fall outside this result prefix.\"\n title=\"Item unavailable\"\n tone=\"caution\"\n />\n </div>\n ) : (\n <Surface as=\"section\" className={styles.selection} id=\"item-details\" padding=\"spacious\" tone=\"secondary\">\n <div className={styles.selectionHeader}>\n <ServiceMark service={selectedItem.service} size=\"compact\" />\n <StateLabel label={selectedItem.status} size=\"compact\" tone={selectedItem.tone} />\n </div>\n <Text as=\"p\" tone=\"secondary\" variant=\"label\">\n {selectedItem.key} · {labelForKind(selectedItem.kind)}\n </Text>\n <Text as=\"h2\" variant=\"section-title\">\n {selectedItem.title}\n </Text>\n <Text tone=\"secondary\" variant=\"body-large\">\n {workspaceItemMembershipDescription(selectedItem)}\n </Text>\n <ItemOwners item={selectedItem} />\n {shareOwnerPersonId === null ? null : (\n <AuthorizedSharePanel\n key={selectedItem.entityId}\n currentPersonId={shareOwnerPersonId}\n entityId={selectedItem.entityId}\n grantees={controller.state.ownerOptions}\n workspaceId={context.workspaceId}\n {...(shareTransport === undefined ? {} : { transport: shareTransport })}\n />\n )}\n <div className={styles.selectionActions}>\n <div className={styles.membershipChoices}>\n {selectedItem.routableReleaseIds.map((releaseId) => {\n const release = releaseById.get(releaseId)\n return (\n <Link\n key={releaseId}\n state={makeReleaseRouteState(context.workspaceId, releaseId, releaseOriginFromLocation(location))}\n to={workspaceItemReleaseHref(context.workspaceId, releaseId, selectedItem.entityId)}\n >\n Open {release === undefined ? `release ${releaseId.slice(-6)}` : release.relay.codename}\n {release === undefined ? null : <span>{release.version}</span>}\n </Link>\n )\n })}\n </div>\n <Button onClick={clearSelection}>Back to items</Button>\n </div>\n </Surface>\n )}\n\n <div className={styles.resultHeading} id=\"results\">\n <Text as=\"h2\" variant=\"section-title\">\n {controller.state.matchedCount} of {controller.state.totalCount} workspace items\n </Text>\n <StateLabel\n label={\n controller.state.refreshing\n ? \"Updating results\"\n : controller.state.truncated\n ? \"Bounded workspace result\"\n : \"Workspace scope\"\n }\n size=\"compact\"\n tone={controller.state.truncated && !controller.state.refreshing ? \"caution\" : \"neutral\"}\n />\n </div>\n\n {visibleItems.length === 0 ? (\n <StatePanel\n action={<Button onClick={() => replaceSearch(new URLSearchParams())}>Clear filters</Button>}\n description=\"Try a broader word, owner, service, type, or status. No demo object is substituted.\"\n title=\"No matching items\"\n />\n ) : (\n <div className={styles.items}>\n {visibleItems.map((item) => (\n <Surface as=\"article\" className={styles.item} key={item.entityId} padding=\"none\" tone=\"secondary\">\n <ServiceMark service={item.service} size=\"compact\" />\n <Link\n className={styles.itemLink}\n onClick={(event) => {\n if (shouldRememberWorkspaceScrollPosition(event, event.currentTarget.target)) {\n rememberWorkspaceScrollPosition(location, item.href)\n }\n }}\n state={makeWorkspaceEntityRouteState(\n location.state,\n context.workspaceId,\n item.entityId,\n entityOriginFromLocation(location)\n )}\n to={item.href}\n >\n <span>{item.key}</span>\n <strong>{item.title}</strong>\n </Link>\n <div className={styles.meta}>\n <StateLabel label={item.status} size=\"compact\" tone={item.tone} />\n <span>{labelForKind(item.kind)}</span>\n <span>\n {item.releaseIds.length === 0\n ? \"Unlinked\"\n : `${item.releaseIds.length}${item.releaseMembershipsTruncated ? \"+\" : \"\"} release${item.releaseIds.length === 1 ? \"\" : \"s\"}`}\n </span>\n <ItemOwners item={item} />\n <time dateTime={item.freshness} title={`Synchronized ${item.freshness}`}>\n {formatItemFreshness(item.freshness)}\n </time>\n </div>\n {shareOwnerPersonId === null ? null : (\n <Link\n className={styles.shareLink}\n to={unlinkedItemLocation(location.pathname, searchParams, item.entityId)}\n >\n Share\n </Link>\n )}\n </Surface>\n ))}\n </div>\n )}\n </article>\n )\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"OpenPullRequestPage-BABGk9v2.js","names":["useState","Option.getOrNull","Schema.decodeUnknownOption","Domain.CodeCommitPullRequestUrl","Predicate.isTagged","StatePanel","styles","Text","Surface","Button","__toESM","useNavigate","V","He","require_jsx_runtime","useBrowserSession","H","A","isTagged","getOrNull","decodeUnknownOption","CodeCommitPullRequestUrl","workspaceEntityPath","import_react","require_react","OpenPullRequestPage_module_default","import_jsx_runtime","OpenPullRequestPage","browserOpenPullRequestTransport","browserSession","navigate","input","setInput","requestedUrl","setRequestedUrl","lookup","setLookup","lookupAttempt","setLookupAttempt","readableSession","session","locator","abort","transport","resolution","failure","event","url","current","candidate"],"sources":["../../../src/client/openPullRequest/OpenPullRequestPage.module.css","../../../src/client/openPullRequest/OpenPullRequestPage.tsx"],"sourcesContent":[".page,\n.hero,\n.form,\n.matches {\n display: grid;\n}\n\n.page {\n gap: var(--rly-space-32);\n}\n\n.hero,\n.matches {\n gap: var(--rly-space-8);\n max-inline-size: 52rem;\n}\n\n.hero > *,\n.matches > * {\n margin: 0;\n}\n\n.card {\n max-inline-size: 52rem;\n}\n\n.form {\n gap: var(--rly-space-16);\n}\n\n.form label {\n display: grid;\n gap: var(--rly-space-6);\n color: var(--rly-color-text-2);\n font: var(--rly-type-label-weight) var(--rly-type-label-size) / var(--rly-type-label-line-height)\n var(--rly-type-label-font);\n}\n\n.form input {\n min-block-size: 3.5rem;\n inline-size: 100%;\n padding-inline: var(--rly-space-16);\n border: 1px solid var(--rly-color-border-2);\n border-radius: var(--rly-radius-control);\n background: var(--rly-color-surface-1);\n color: var(--rly-color-text-1);\n font: inherit;\n}\n\n.form input:focus-visible {\n outline: 2px solid var(--rly-color-focus);\n outline-offset: var(--rly-space-2);\n}\n","import * as Domain from \"@knpkv/codecommit-core/Domain.js\"\nimport { Button, StatePanel, Surface, Text } from \"@knpkv/rly/primitives\"\nimport * as Option from \"effect/Option\"\nimport * as Predicate from \"effect/Predicate\"\nimport * as Schema from \"effect/Schema\"\nimport { type FormEvent, type ReactElement, useEffect, useState } from \"react\"\nimport { useNavigate } from \"react-router\"\n\nimport { useBrowserSession } from \"../BrowserSession.js\"\nimport { workspaceEntityPath } from \"../workspaceEntityPaths.js\"\nimport {\n browserOpenPullRequestTransport,\n type OpenPullRequestResolution,\n type OpenPullRequestTransport\n} from \"./openPullRequest.js\"\nimport styles from \"./OpenPullRequestPage.module.css\"\n\ntype LookupState =\n | { readonly _tag: \"idle\" }\n | { readonly _tag: \"loading\" }\n | { readonly _tag: \"invalid\" }\n | { readonly _tag: \"failed\" }\n | OpenPullRequestResolution\n\nexport interface OpenPullRequestPageProps {\n readonly transport?: OpenPullRequestTransport\n}\n\n/** Open one followed CodeCommit PR from the console URL another person shared. */\nexport const OpenPullRequestPage = ({\n transport = browserOpenPullRequestTransport\n}: OpenPullRequestPageProps = {}): ReactElement => {\n const browserSession = useBrowserSession()\n const navigate = useNavigate()\n const [input, setInput] = useState(\"\")\n const [requestedUrl, setRequestedUrl] = useState(\"\")\n const [lookup, setLookup] = useState<LookupState>({ _tag: \"idle\" })\n const [lookupAttempt, setLookupAttempt] = useState(0)\n const readableSession =\n browserSession.state._tag === \"authenticated\" || browserSession.state._tag === \"storage-unavailable\"\n ? browserSession.state.session\n : null\n const session =\n browserSession.state._tag === \"authenticated\" &&\n (browserSession.state.session.permission === \"workspace-owner\" ||\n browserSession.state.session.permission === \"workspace-approver\")\n ? browserSession.state.session\n : null\n\n useEffect(() => {\n if (requestedUrl.length === 0) {\n setLookup({ _tag: \"idle\" })\n return\n }\n if (session === null) return\n const locator = Option.getOrNull(Schema.decodeUnknownOption(Domain.CodeCommitPullRequestUrl)(requestedUrl))\n if (locator === null) {\n setLookup({ _tag: \"invalid\" })\n return\n }\n const abort = new AbortController()\n setLookup({ _tag: \"loading\" })\n transport.resolve(locator, abort.signal).then(\n (resolution) => {\n if (abort.signal.aborted) return\n if (resolution._tag === \"found\") {\n navigate(workspaceEntityPath(session.workspaceId, resolution.candidate.entityId), { replace: true })\n return\n }\n setLookup(resolution)\n },\n (failure) => {\n if (abort.signal.aborted) return\n if (Predicate.isTagged(\"UnauthorizedApiError\")(failure)) {\n browserSession.invalidateSession(session.sessionId)\n return\n }\n setLookup({ _tag: \"failed\" })\n }\n )\n return () => abort.abort()\n }, [browserSession, lookupAttempt, navigate, requestedUrl, session, transport])\n\n const submit = (event: FormEvent<HTMLFormElement>): void => {\n event.preventDefault()\n const url = input.trim()\n setRequestedUrl(url)\n setLookupAttempt((current) => current + 1)\n }\n\n if (readableSession === null) {\n return (\n <StatePanel\n description=\"Pair this browser with Control Center before resolving a private CodeCommit pull request.\"\n title=\"Browser session required\"\n tone=\"caution\"\n />\n )\n }\n\n if (browserSession.state._tag === \"storage-unavailable\") {\n return (\n <StatePanel\n description=\"Enable session storage, then pair this browser again before resolving a private CodeCommit pull request.\"\n title=\"Browser storage required\"\n tone=\"caution\"\n />\n )\n }\n\n if (session === null) {\n return (\n <StatePanel\n description=\"Opening a shared CodeCommit PR requires workspace-wide read access.\"\n title=\"Workspace reader required\"\n tone=\"caution\"\n />\n )\n }\n\n return (\n <section className={styles.page}>\n <header className={styles.hero}>\n <Text as=\"h1\" variant=\"page-title\">\n Open CodeCommit PR\n </Text>\n <Text tone=\"secondary\" variant=\"body-large\">\n Paste a CodeCommit PR URL from any AWS region. Control Center resolves it inside this workspace; no PR search\n required.\n </Text>\n </header>\n <Surface as=\"section\" className={styles.card} form=\"grouped\" padding=\"spacious\" tone=\"secondary\">\n <form className={styles.form} onSubmit={submit}>\n <label>\n <span>Pull request URL</span>\n <input\n autoComplete=\"url\"\n onChange={(event) => setInput(event.currentTarget.value)}\n placeholder=\"https://REGION.console.aws.amazon.com/codesuite/codecommit/repositories/…\"\n spellCheck={false}\n type=\"url\"\n value={input}\n />\n </label>\n <Button loading={lookup._tag === \"loading\"} size=\"principal\" type=\"submit\" variant=\"primary\">\n Open pull request\n </Button>\n </form>\n </Surface>\n {lookup._tag === \"invalid\" ? (\n <StatePanel\n description=\"Use the full AWS CodeCommit pull-request console URL.\"\n title=\"Link not recognized\"\n tone=\"caution\"\n />\n ) : lookup._tag === \"failed\" ? (\n <StatePanel\n description=\"The workspace index could not be read. Nothing was changed.\"\n title=\"Lookup failed\"\n tone=\"caution\"\n />\n ) : lookup._tag === \"not-found\" ? (\n <StatePanel\n description={\n lookup.indexTruncated\n ? \"The bounded workspace result was incomplete. Narrow the followed CodeCommit resources, then retry.\"\n : \"This PR is not synchronized into the current workspace yet. Follow its CodeCommit account or repository, then retry.\"\n }\n title=\"PR not found\"\n tone=\"neutral\"\n />\n ) : lookup._tag === \"account-identity-unavailable\" ? (\n <StatePanel\n description=\"Control Center could not map every match to a browser-safe AWS account identity. Refresh Services, then retry.\"\n title=\"Account identity unavailable\"\n tone=\"caution\"\n />\n ) : lookup._tag === \"ambiguous\" ? (\n <Surface as=\"section\" className={styles.matches} form=\"grouped\" padding=\"spacious\" tone=\"secondary\">\n <Text as=\"h2\" variant=\"section-title\">\n Choose the connected account\n </Text>\n <Text tone=\"secondary\" variant=\"body\">\n AWS Console links omit the account. These followed connections contain the same repository and PR number.\n </Text>\n {lookup.candidates.map((candidate) => (\n <Button\n key={candidate.entityId}\n onClick={() => navigate(workspaceEntityPath(session.workspaceId, candidate.entityId))}\n variant=\"secondary\"\n >\n {`${candidate.accountLabel} · ${candidate.title}`}\n </Button>\n ))}\n </Surface>\n ) : null}\n </section>\n )\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PairPage-4meDmW_A.js","names":["Predicate.hasProperty","Predicate.isString","Effect.fn","Effect.gen","Schema.decodeUnknownEffect","Effect.provide","FetchHttpClient.layer","useState","styles","Text","Surface","Field","Button","__toESM","useNavigate","V","require_jsx_runtime","useSearchParams","useBrowserSession","H","A","runPromise","isString","hasProperty","decodeUnknownEffect","provide","fn","PairingCode","gen","layer","makeControlCenterApiClient","selectedServiceProvider","serviceSetupPath","pages_module_default","import_react","require_react","CREDENTIAL_FAILURE_TAGS","failureTag","failure","pairingFailureMessage","tag","import_jsx_runtime","pairBrowser","pairingCode","rawPairingCode","pairedBrowserDestination","selectedProvider","PairPage","navigate","searchParams","setPairingCode","error","setError","isPairing","setIsPairing","event","establishSession","result","Je","controlProps"],"sources":["../../../src/client/PairingFailure.ts","../../../src/client/PairPage.tsx"],"sourcesContent":["import * as Predicate from \"effect/Predicate\"\n\nconst CREDENTIAL_FAILURE_TAGS = new Set([\n \"ConflictApiError\",\n \"InvalidRequestApiError\",\n \"ParseError\",\n \"UnauthorizedApiError\"\n])\n\nconst failureTag = <UnparsedInput>(failure: UnparsedInput): string | undefined => {\n if (!Predicate.hasProperty(failure, \"_tag\")) return undefined\n return Predicate.isString(failure._tag) ? failure._tag : undefined\n}\n\n/** Convert pairing failures into honest, actionable browser copy. */\nexport const pairingFailureMessage = <UnparsedInput>(failure: UnparsedInput): string => {\n const tag = failureTag(failure)\n if (tag !== undefined && CREDENTIAL_FAILURE_TAGS.has(tag)) {\n return \"That code is invalid, expired, or already used.\"\n }\n if (tag === \"ForbiddenApiError\") {\n return \"Pairing is blocked on this connection. Open Control Center through trusted HTTPS and try again.\"\n }\n return \"Control Center is unavailable right now. Check that the server is running, then try again.\"\n}\n","import { Button, Field, Surface, Text } from \"@knpkv/rly/primitives\"\nimport * as Effect from \"effect/Effect\"\nimport * as Schema from \"effect/Schema\"\nimport * as FetchHttpClient from \"effect/http/FetchHttpClient\"\nimport { type FormEvent, type ReactElement, useState } from \"react\"\nimport { useNavigate, useSearchParams } from \"react-router\"\n\nimport { makeControlCenterApiClient } from \"../api/client.js\"\nimport { PairingCode } from \"../api/session.js\"\nimport type { ProviderId } from \"../domain/sourceRevision.js\"\nimport { useBrowserSession } from \"./BrowserSession.js\"\nimport { pairingFailureMessage } from \"./PairingFailure.js\"\nimport { selectedServiceProvider, serviceSetupPath } from \"./services/serviceOnboarding.js\"\nimport styles from \"./pages.module.css\"\n\nconst pairBrowser = Effect.fn(\"PairPage.pairBrowser\")((rawPairingCode: string) =>\n Effect.gen(function* () {\n const pairingCode = yield* Schema.decodeUnknownEffect(PairingCode)(rawPairingCode.trim())\n const client = yield* makeControlCenterApiClient()\n return yield* client.session.pair({ payload: { pairingCode } })\n }).pipe(Effect.provide(FetchHttpClient.layer))\n)\n\n/** Preserve explicit service onboarding while ordinary pairing resolves workspace settings. */\nexport const pairedBrowserDestination = (selectedProvider: ProviderId | null): string =>\n selectedProvider === null ? \"/\" : serviceSetupPath(selectedProvider)\n\n/** Pair the current tab without ever exposing the opaque session cookie to JavaScript. */\nexport const PairPage = (): ReactElement => {\n const navigate = useNavigate()\n const [searchParams] = useSearchParams()\n const { establishSession } = useBrowserSession()\n const [pairingCode, setPairingCode] = useState(\"\")\n const [error, setError] = useState<string | undefined>()\n const [isPairing, setIsPairing] = useState(false)\n\n const submit = (event: FormEvent<HTMLFormElement>): void => {\n event.preventDefault()\n setError(undefined)\n setIsPairing(true)\n Effect.runPromise(pairBrowser(pairingCode)).then(\n (result) => {\n establishSession(result.csrfToken, result.session)\n const selectedProvider = selectedServiceProvider(searchParams, \"service\")\n navigate(pairedBrowserDestination(selectedProvider), { replace: true })\n },\n (failure) => {\n setError(pairingFailureMessage(failure))\n setIsPairing(false)\n }\n )\n }\n\n return (\n <section aria-labelledby=\"pair-title\" className={styles.page}>\n <header className={styles.sectionHeading}>\n <Text as=\"h1\" id=\"pair-title\" variant=\"page-title\">\n Pair this browser\n </Text>\n <Text tone=\"secondary\" variant=\"body-large\">\n Use the one-time code printed by the local Control Center server. It expires after ten minutes.\n </Text>\n </header>\n <Surface as=\"section\" className={styles.pairCard} padding=\"spacious\" form=\"grouped\" tone=\"secondary\">\n <form className={styles.pairForm} onSubmit={submit}>\n <Field\n description=\"The code stays in this request and is never placed in a URL.\"\n label=\"Pairing code\"\n required\n {...(error === undefined ? {} : { error })}\n >\n {(controlProps) => (\n <input\n {...controlProps}\n autoComplete=\"one-time-code\"\n inputMode=\"text\"\n maxLength={64}\n onChange={(event) => setPairingCode(event.currentTarget.value)}\n spellCheck={false}\n value={pairingCode}\n />\n )}\n </Field>\n <Button\n disabled={pairingCode.trim().length !== 64}\n loading={isPairing}\n size=\"principal\"\n type=\"submit\"\n variant=\"primary\"\n >\n Pair browser\n </Button>\n </form>\n </Surface>\n </section>\n )\n}\n"],"mappings":"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"}
|