@knpkv/control-center 0.7.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/dist/client/.vite/manifest.json +312 -255
  2. package/dist/client/assets/ActiveWorkPage-DKlotZGc.js +2 -0
  3. package/dist/client/assets/{ActiveWorkPage-BsaIr8ah.js.map → ActiveWorkPage-DKlotZGc.js.map} +1 -1
  4. package/dist/client/assets/AgentPage-Cxm1gj2C.js +6 -0
  5. package/dist/client/assets/{AgentPage-Cybynsnc.js.map → AgentPage-Cxm1gj2C.js.map} +1 -1
  6. package/dist/client/assets/{AtlassianOAuthCallbackPage-Du3pHuS9.js → AtlassianOAuthCallbackPage-fEFUJE2g.js} +2 -2
  7. package/dist/client/assets/{AtlassianOAuthCallbackPage-Du3pHuS9.js.map → AtlassianOAuthCallbackPage-fEFUJE2g.js.map} +1 -1
  8. package/dist/client/assets/AuthorizedSharePage-Dh7Y_gmJ.js +2 -0
  9. package/dist/client/assets/{AuthorizedSharePage-tfTdXNjt.js.map → AuthorizedSharePage-Dh7Y_gmJ.js.map} +1 -1
  10. package/dist/client/assets/BrowserCrypto-CoBR2WBd.js +2 -0
  11. package/dist/client/assets/{BrowserCrypto-DVxU0-Oc.js.map → BrowserCrypto-CoBR2WBd.js.map} +1 -1
  12. package/dist/client/assets/BrowserSessionHydrator-DkomS8Yl.js +2 -0
  13. package/dist/client/assets/{BrowserSessionHydrator-CvtvZstV.js.map → BrowserSessionHydrator-DkomS8Yl.js.map} +1 -1
  14. package/dist/client/assets/CommandSearch-nf16HEqz.js +2 -0
  15. package/dist/client/assets/{CommandSearch-Bf_oW_kD.js.map → CommandSearch-nf16HEqz.js.map} +1 -1
  16. package/dist/client/assets/Dialog-DSwimdwG-BeHnBpPp.js +42 -0
  17. package/dist/client/assets/Dialog-DSwimdwG-BeHnBpPp.js.map +1 -0
  18. package/dist/client/assets/Domain-cJ5aJFpE.js +2 -0
  19. package/dist/client/assets/Domain-cJ5aJFpE.js.map +1 -0
  20. package/dist/client/assets/ItemsPage-Bok8Vpy4.js +2 -0
  21. package/dist/client/assets/{ItemsPage-BmWEHinz.js.map → ItemsPage-Bok8Vpy4.js.map} +1 -1
  22. package/dist/client/assets/OpenPullRequestPage-DdL7PhKZ.js +2 -0
  23. package/dist/client/assets/OpenPullRequestPage-DdL7PhKZ.js.map +1 -0
  24. package/dist/client/assets/{Pages-BmZj4KzS.js → Pages-DrDuXLFH.js} +2 -2
  25. package/dist/client/assets/{Pages-BmZj4KzS.js.map → Pages-DrDuXLFH.js.map} +1 -1
  26. package/dist/client/assets/PairPage-BCtzYqK6.js +2 -0
  27. package/dist/client/assets/{PairPage-CLLUweYZ.js.map → PairPage-BCtzYqK6.js.map} +1 -1
  28. package/dist/client/assets/PortalProvider-CN_81Fy3-D_japesx.js +2 -0
  29. package/dist/client/assets/{PortalProvider-BpgZwSpw-nEH0TqWT.js.map → PortalProvider-CN_81Fy3-D_japesx.js.map} +1 -1
  30. package/dist/client/assets/PortfolioOverview-C-jqvYgQ.js +2 -0
  31. package/dist/client/assets/{PortfolioOverview-BBKSc-yI.js.map → PortfolioOverview-C-jqvYgQ.js.map} +1 -1
  32. package/dist/client/assets/{PullRequestReviewPanel-Boi0A6pq.js → PullRequestReviewPanel-DwVYuZ8Q.js} +5 -5
  33. package/dist/client/assets/{PullRequestReviewPanel-Boi0A6pq.js.map → PullRequestReviewPanel-DwVYuZ8Q.js.map} +1 -1
  34. package/dist/client/assets/ReleaseRoute-cuvP4ug5.js +2 -0
  35. package/dist/client/assets/{ReleaseRoute-D4CttCjC.js.map → ReleaseRoute-cuvP4ug5.js.map} +1 -1
  36. package/dist/client/assets/ReleaseWorkset-DImwmjS3.js +2 -0
  37. package/dist/client/assets/{ReleaseWorkset-Dt-ArwsN.js.map → ReleaseWorkset-DImwmjS3.js.map} +1 -1
  38. package/dist/client/assets/ReviewSuggestionPublicationSurface-BZIa-Vvc.js +2 -0
  39. package/dist/client/assets/{ReviewSuggestionPublicationSurface-N9Qwdh2n.js.map → ReviewSuggestionPublicationSurface-BZIa-Vvc.js.map} +1 -1
  40. package/dist/client/assets/ServicesPage-CrM8R820.js +2 -0
  41. package/dist/client/assets/{ServicesPage-D0ygZTFD.js.map → ServicesPage-CrM8R820.js.map} +1 -1
  42. package/dist/client/assets/TimelinePage-FrvepGa_.js +2 -0
  43. package/dist/client/assets/{TimelinePage-Bb2o9DGU.js.map → TimelinePage-FrvepGa_.js.map} +1 -1
  44. package/dist/client/assets/{WorkspaceEntityLink-Cw675wTN.js → WorkspaceEntityLink-CAj42f02.js} +2 -2
  45. package/dist/client/assets/{WorkspaceEntityLink-Cw675wTN.js.map → WorkspaceEntityLink-CAj42f02.js.map} +1 -1
  46. package/dist/client/assets/WorkspaceEntityRoute-rQ9ccetx.js +14 -0
  47. package/dist/client/assets/WorkspaceEntityRoute-rQ9ccetx.js.map +1 -0
  48. package/dist/client/assets/WorkspaceHomeLink-ObQ3AQVw.js +2 -0
  49. package/dist/client/assets/{WorkspaceHomeLink-FGslxXCu.js.map → WorkspaceHomeLink-ObQ3AQVw.js.map} +1 -1
  50. package/dist/client/assets/WorkspacePullRequestDetails-BhxoqR7V.js +3 -0
  51. package/dist/client/assets/{WorkspacePullRequestDetails-Dxg8argO.js.map → WorkspacePullRequestDetails-BhxoqR7V.js.map} +1 -1
  52. package/dist/client/assets/{WorkspaceReleaseLayout-BvEiZJEb.js → WorkspaceReleaseLayout-BWL66Fff.js} +2 -2
  53. package/dist/client/assets/{WorkspaceReleaseLayout-BvEiZJEb.js.map → WorkspaceReleaseLayout-BWL66Fff.js.map} +1 -1
  54. package/dist/client/assets/{WorkspaceRichText-CocmKQ4T.js → WorkspaceRichText-Beh64wsV.js} +2 -2
  55. package/dist/client/assets/{WorkspaceRichText-CocmKQ4T.js.map → WorkspaceRichText-Beh64wsV.js.map} +1 -1
  56. package/dist/client/assets/WorkspaceSettingsPage-DutfiGPe.js +2 -0
  57. package/dist/client/assets/{WorkspaceSettingsPage-iZhUs-pg.js.map → WorkspaceSettingsPage-DutfiGPe.js.map} +1 -1
  58. package/dist/client/assets/{agent-api-CzdQFCcD.js → agent-api-CUWP1qs8.js} +2 -2
  59. package/dist/client/assets/{agent-api-CzdQFCcD.js.map → agent-api-CUWP1qs8.js.map} +1 -1
  60. package/dist/client/assets/{atlassianOAuthSetupIntentStorage-BxsxmjSm.js → atlassianOAuthSetupIntentStorage-Cy1Gw639.js} +2 -2
  61. package/dist/client/assets/{atlassianOAuthSetupIntentStorage-BxsxmjSm.js.map → atlassianOAuthSetupIntentStorage-Cy1Gw639.js.map} +1 -1
  62. package/dist/client/assets/authenticatedMutationClient-Bc_-Jpbo.js +2 -0
  63. package/dist/client/assets/{authenticatedMutationClient-DUqEcJHu.js.map → authenticatedMutationClient-Bc_-Jpbo.js.map} +1 -1
  64. package/dist/client/assets/authorizedShareTransport-kkT3Jf6q.js +2 -0
  65. package/dist/client/assets/{authorizedShareTransport-7YCNH9l3.js.map → authorizedShareTransport-kkT3Jf6q.js.map} +1 -1
  66. package/dist/client/assets/client-D3WRV6yl.js +5 -0
  67. package/dist/client/assets/client-D3WRV6yl.js.map +1 -0
  68. package/dist/client/assets/{confluenceTasks-D9yrB-oV.js → confluenceTasks-By7BV0WN.js} +2 -2
  69. package/dist/client/assets/{confluenceTasks-D9yrB-oV.js.map → confluenceTasks-By7BV0WN.js.map} +1 -1
  70. package/dist/client/assets/connectionTestTransport-CRq7l9X0.js +2 -0
  71. package/dist/client/assets/{connectionTestTransport-D8tiZ4ym.js.map → connectionTestTransport-CRq7l9X0.js.map} +1 -1
  72. package/dist/client/assets/controlCenterRelayDock-CyYeXh75.js +3 -0
  73. package/dist/client/assets/controlCenterRelayDock-CyYeXh75.js.map +1 -0
  74. package/dist/client/assets/controlCenterRelayDockChrome-upgtq649.js +3 -0
  75. package/dist/client/assets/controlCenterRelayDockChrome-upgtq649.js.map +1 -0
  76. package/dist/client/assets/index-kmYFvwT0.js +11 -0
  77. package/dist/client/assets/index-kmYFvwT0.js.map +1 -0
  78. package/dist/client/assets/index-tjRpNCt_.css +1 -0
  79. package/dist/client/assets/openPullRequest-BMlmibLP.js +2 -0
  80. package/dist/client/assets/openPullRequest-BMlmibLP.js.map +1 -0
  81. package/dist/client/assets/patterns-DuFUSnJW.js +2 -0
  82. package/dist/client/assets/patterns-DuFUSnJW.js.map +1 -0
  83. package/dist/client/assets/{presentPortfolio-c8-wbodG.js → presentPortfolio-DVP-zqTg.js} +2 -2
  84. package/dist/client/assets/{presentPortfolio-c8-wbodG.js.map → presentPortfolio-DVP-zqTg.js.map} +1 -1
  85. package/dist/client/assets/{presentWorkspaceItems-DfhyQeSY.js → presentWorkspaceItems-BY8bmqjF.js} +2 -2
  86. package/dist/client/assets/{presentWorkspaceItems-DfhyQeSY.js.map → presentWorkspaceItems-BY8bmqjF.js.map} +1 -1
  87. package/dist/client/assets/primitives-DYGtIZqB-r-Glkv2i.js +2 -0
  88. package/dist/client/assets/primitives-DYGtIZqB-r-Glkv2i.js.map +1 -0
  89. package/dist/client/assets/pullRequestReviewFailures-CCNxSXP6.js +2 -0
  90. package/dist/client/assets/{pullRequestReviewFailures-QvtS729d.js.map → pullRequestReviewFailures-CCNxSXP6.js.map} +1 -1
  91. package/dist/client/assets/pullRequestReviewThreadReplay-eI3Y4i6s.js +2 -0
  92. package/dist/client/assets/{pullRequestReviewThreadReplay-CpPdYxQE.js.map → pullRequestReviewThreadReplay-eI3Y4i6s.js.map} +1 -1
  93. package/dist/client/assets/{releaseAgentTransport-BCQDYqZt.js → releaseAgentTransport-CJjWwE8y.js} +2 -2
  94. package/dist/client/assets/{releaseAgentTransport-BCQDYqZt.js.map → releaseAgentTransport-CJjWwE8y.js.map} +1 -1
  95. package/dist/client/assets/releaseRoutes-h4FVwFvJ.js +2 -0
  96. package/dist/client/assets/{releaseRoutes-CSP_eBj6.js.map → releaseRoutes-h4FVwFvJ.js.map} +1 -1
  97. package/dist/client/assets/{serviceOnboarding-B6v5VXTG.js → serviceOnboarding-F9Lj6a7y.js} +2 -2
  98. package/dist/client/assets/{serviceOnboarding-B6v5VXTG.js.map → serviceOnboarding-F9Lj6a7y.js.map} +1 -1
  99. package/dist/client/assets/useWorkspaceDefaultLanding-BmaR7aTj.js +3 -0
  100. package/dist/client/assets/{useWorkspaceDefaultLanding-C3PRrLgk.js.map → useWorkspaceDefaultLanding-BmaR7aTj.js.map} +1 -1
  101. package/dist/client/assets/useWorkspaceItems-6KWfmFtx.js +2 -0
  102. package/dist/client/assets/{useWorkspaceItems-CHYpfLmL.js.map → useWorkspaceItems-6KWfmFtx.js.map} +1 -1
  103. package/dist/client/assets/{workspaceEntityRoutes-CFPO-iFw.js → workspaceEntityRoutes-BHccxrFj.js} +2 -2
  104. package/dist/client/assets/{workspaceEntityRoutes-CFPO-iFw.js.map → workspaceEntityRoutes-BHccxrFj.js.map} +1 -1
  105. package/dist/client/assets/{workspaceScrollCapture-DUj-_YMd.js → workspaceScrollCapture-BzsNJoL7.js} +2 -2
  106. package/dist/client/assets/{workspaceScrollCapture-DUj-_YMd.js.map → workspaceScrollCapture-BzsNJoL7.js.map} +1 -1
  107. package/dist/client/assets/workspaceSettingsTransport-BwRQteEH.js +2 -0
  108. package/dist/client/assets/{workspaceSettingsTransport-Kq7lfPsC.js.map → workspaceSettingsTransport-BwRQteEH.js.map} +1 -1
  109. package/dist/client/build-graph.json +63 -0
  110. package/dist/client/index.html +3 -3
  111. package/dist/server/api/index.js +1 -1
  112. package/dist/server/assets/{BindConfig-hNWrGfu2.js → BindConfig-BG-FGtB5.js} +14 -5
  113. package/dist/server/assets/BindConfig-BG-FGtB5.js.map +1 -0
  114. package/dist/server/assets/{controlCenterApi-BcVWTP9F.js → controlCenterApi-WaKi6EUb.js} +2 -1
  115. package/dist/server/assets/controlCenterApi-WaKi6EUb.js.map +1 -0
  116. package/dist/server/index.js +1 -1
  117. package/dist/server/server/cli.js +1 -1
  118. package/dist/server/server/index.js +1 -1
  119. package/package.json +8 -7
  120. package/dist/client/assets/ActiveWorkPage-BsaIr8ah.js +0 -2
  121. package/dist/client/assets/AgentPage-Cybynsnc.js +0 -6
  122. package/dist/client/assets/AuthorizedSharePage-tfTdXNjt.js +0 -2
  123. package/dist/client/assets/BrowserCrypto-DVxU0-Oc.js +0 -2
  124. package/dist/client/assets/BrowserSessionHydrator-CvtvZstV.js +0 -2
  125. package/dist/client/assets/CommandSearch-Bf_oW_kD.js +0 -2
  126. package/dist/client/assets/Dialog-1WvU8GjA-C7r26HF0.js +0 -42
  127. package/dist/client/assets/Dialog-1WvU8GjA-C7r26HF0.js.map +0 -1
  128. package/dist/client/assets/ItemsPage-BmWEHinz.js +0 -2
  129. package/dist/client/assets/OpenPullRequestPage-DkCom6mf.js +0 -2
  130. package/dist/client/assets/OpenPullRequestPage-DkCom6mf.js.map +0 -1
  131. package/dist/client/assets/PairPage-CLLUweYZ.js +0 -2
  132. package/dist/client/assets/PortalProvider-BpgZwSpw-nEH0TqWT.js +0 -2
  133. package/dist/client/assets/PortfolioOverview-BBKSc-yI.js +0 -2
  134. package/dist/client/assets/ReleaseRoute-D4CttCjC.js +0 -2
  135. package/dist/client/assets/ReleaseWorkset-Dt-ArwsN.js +0 -2
  136. package/dist/client/assets/ReviewSuggestionPublicationSurface-N9Qwdh2n.js +0 -2
  137. package/dist/client/assets/ServicesPage-D0ygZTFD.js +0 -2
  138. package/dist/client/assets/TimelinePage-Bb2o9DGU.js +0 -2
  139. package/dist/client/assets/WorkspaceEntityRoute-rLRiaF8b.js +0 -14
  140. package/dist/client/assets/WorkspaceEntityRoute-rLRiaF8b.js.map +0 -1
  141. package/dist/client/assets/WorkspaceHomeLink-FGslxXCu.js +0 -2
  142. package/dist/client/assets/WorkspacePullRequestDetails-Dxg8argO.js +0 -3
  143. package/dist/client/assets/WorkspaceSettingsPage-iZhUs-pg.js +0 -2
  144. package/dist/client/assets/authenticatedMutationClient-DUqEcJHu.js +0 -2
  145. package/dist/client/assets/authorizedShareTransport-7YCNH9l3.js +0 -2
  146. package/dist/client/assets/client-D2F6HlDk.js +0 -5
  147. package/dist/client/assets/client-D2F6HlDk.js.map +0 -1
  148. package/dist/client/assets/connectionTestTransport-D8tiZ4ym.js +0 -2
  149. package/dist/client/assets/index-BWx9sNOT.js +0 -11
  150. package/dist/client/assets/index-BWx9sNOT.js.map +0 -1
  151. package/dist/client/assets/index-CIfiz7oF.css +0 -1
  152. package/dist/client/assets/patterns-CxMz8DKX-ByHwV03y.js +0 -2
  153. package/dist/client/assets/patterns-CxMz8DKX-ByHwV03y.js.map +0 -1
  154. package/dist/client/assets/primitives-CW89TsFB-BBLwFFPo.js +0 -2
  155. package/dist/client/assets/primitives-CW89TsFB-BBLwFFPo.js.map +0 -1
  156. package/dist/client/assets/pullRequestReviewFailures-QvtS729d.js +0 -2
  157. package/dist/client/assets/pullRequestReviewThreadReplay-CpPdYxQE.js +0 -2
  158. package/dist/client/assets/releaseRoutes-CSP_eBj6.js +0 -2
  159. package/dist/client/assets/useWorkspaceDefaultLanding-C3PRrLgk.js +0 -3
  160. package/dist/client/assets/useWorkspaceItems-CHYpfLmL.js +0 -2
  161. package/dist/client/assets/workspaceSettingsTransport-Kq7lfPsC.js +0 -2
  162. package/dist/server/assets/BindConfig-hNWrGfu2.js.map +0 -1
  163. package/dist/server/assets/controlCenterApi-BcVWTP9F.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"releaseAgentTransport-BCQDYqZt.js","names":[],"sources":["../../../src/client/entities/presentWorkspaceConfluencePage.ts","../../../src/client/entities/useWorkspaceEntity.ts","../../../src/client/releases/releaseAgentTransport.ts"],"sourcesContent":["import type { RlyPerson } from \"@knpkv/rly/patterns\"\nimport * as DateTime from \"effect/DateTime\"\n\nimport type { WorkspaceEntityInspection } from \"../../api/deliveryGraph.js\"\nimport type { DeliveryEntityDetails } from \"../../domain/deliveryGraph.js\"\n\ntype PageDetails = Extract<DeliveryEntityDetails, { readonly _tag: \"page\" }>\n\nexport interface WorkspacePageTimestamp {\n readonly dateTime: string\n readonly label: string\n}\n\nexport interface WorkspaceConfluencePagePresentation {\n readonly attachmentInventoryLabel: string\n readonly attachments: ReadonlyArray<{\n readonly createdAt: WorkspacePageTimestamp\n readonly fileSize: string\n readonly id: string\n readonly mediaType: string\n readonly title: string\n readonly version: string\n }>\n readonly content: string | null\n readonly contentState: \"empty\" | \"lazy\" | \"loaded\"\n readonly contributors: ReadonlyArray<RlyPerson>\n readonly createdAt: WorkspacePageTimestamp | null\n readonly historyInventoryLabel: string\n readonly revision: string\n readonly runbookEvidenceCount: number\n readonly sourceSpaceId: string\n readonly status: \"Current\" | \"Draft\" | \"Superseded\"\n readonly taskUpdatesSafe?: boolean\n readonly updatedAt: WorkspacePageTimestamp | null\n readonly versions: ReadonlyArray<{\n readonly author: string\n readonly createdAt: WorkspacePageTimestamp\n readonly message: string\n readonly minorEdit: boolean\n readonly number: number\n }>\n readonly watcherInventoryLabel: string\n}\n\nconst timestampFormatter = new Intl.DateTimeFormat(\"en-GB\", {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n timeZone: \"UTC\"\n})\n\nconst timestampFor = (value: DateTime.DateTime | undefined): WorkspacePageTimestamp | null =>\n value === undefined\n ? null\n : {\n dateTime: DateTime.formatIso(value),\n label: timestampFormatter.format(DateTime.toDateUtc(value))\n }\n\nconst inventoryLabel = (\n inventory: { readonly complete: boolean; readonly pagesFetched: number } | undefined,\n noun: string\n): string =>\n inventory === undefined\n ? `${noun} not synchronized`\n : `${inventory.complete ? \"Complete\" : \"Partial\"} · ${String(inventory.pagesFetched)} bounded page${\n inventory.pagesFetched === 1 ? \"\" : \"s\"\n } read`\n\nconst fileSizeLabel = (bytes: number | null): string => {\n if (bytes === null) return \"Size unavailable\"\n if (bytes < 1_024) return `${String(bytes)} B`\n if (bytes < 1_048_576) return `${(bytes / 1_024).toFixed(1)} KB`\n return `${(bytes / 1_048_576).toFixed(1)} MB`\n}\n\nconst roleLabel = (roles: ReadonlyArray<\"author\" | \"contributor\" | \"owner\" | \"watcher\">): string =>\n roles.map((role) => `${role.charAt(0).toLocaleUpperCase(\"en-US\")}${role.slice(1)}`).join(\" · \")\n\nconst uniqueContributors = (\n contributors: NonNullable<PageDetails[\"contributors\"]>\n): NonNullable<PageDetails[\"contributors\"]> => {\n const byId = new Map<string, NonNullable<PageDetails[\"contributors\"]>[number]>()\n for (const contributor of contributors) {\n const previous = byId.get(contributor.sourcePersonId)\n const roles = previous === undefined\n ? contributor.roles\n : [...new Set([...previous.roles, ...contributor.roles])]\n const identity = previous?.resolved === true && !contributor.resolved ? previous : contributor\n byId.set(contributor.sourcePersonId, { ...identity, roles })\n }\n return [...byId.values()]\n}\n\n/** Present one normalized page as a quiet read-only document with explicit provider boundaries. */\nexport const presentWorkspaceConfluencePage = (\n details: PageDetails,\n inspection: WorkspaceEntityInspection\n): WorkspaceConfluencePagePresentation => {\n const contributors = uniqueContributors(details.contributors ?? [])\n const contributorNameById = new Map(contributors.map(({ displayName, sourcePersonId }) => [\n sourcePersonId,\n displayName\n ]))\n const contentState = details.contentState === \"lazy\"\n ? \"lazy\"\n : details.content === null || details.content === undefined\n ? \"empty\"\n : \"loaded\"\n return {\n attachmentInventoryLabel: inventoryLabel(details.attachmentInventory, \"Attachment inventory\"),\n attachments: (details.attachments ?? []).map((attachment) => ({\n createdAt: timestampFor(attachment.createdAt)!,\n fileSize: fileSizeLabel(attachment.fileSize),\n id: attachment.id,\n mediaType: attachment.mediaType ?? \"Type unavailable\",\n title: attachment.title,\n version: attachment.version === null ? \"Version unavailable\" : `v${String(attachment.version)}`\n })),\n content: contentState === \"loaded\" ? (details.content?.markdown ?? null) : null,\n contentState,\n contributors: contributors.map((contributor) => ({\n id: contributor.sourcePersonId,\n name: contributor.displayName,\n role: `${roleLabel(contributor.roles)}${contributor.external ? \" · External\" : \"\"}${\n contributor.resolved ? \"\" : \" · Identity unresolved\"\n }`\n })),\n createdAt: timestampFor(details.createdAt),\n historyInventoryLabel: inventoryLabel(details.versionHistory, \"Revision history\"),\n revision: details.revision,\n runbookEvidenceCount: inspection.graph.evidenceItems.length,\n sourceSpaceId: details.sourceSpaceId ?? details.spaceKey,\n status: details.status === \"superseded\" ? \"Superseded\" : details.status === \"draft\" ? \"Draft\" : \"Current\",\n taskUpdatesSafe: details.taskUpdatesSafe === true,\n updatedAt: timestampFor(details.updatedAt),\n versions: (details.versions ?? []).map((version) => ({\n author: version.authorSourcePersonId === null\n ? \"Author unavailable\"\n : contributorNameById.get(version.authorSourcePersonId) ?? \"Identity not resolved\",\n createdAt: timestampFor(version.createdAt)!,\n message: version.message ?? \"No revision note\",\n minorEdit: version.minorEdit,\n number: version.number\n })),\n watcherInventoryLabel: inventoryLabel(details.watcherInventory, \"Watcher inventory\")\n }\n}\n","import * as Effect from \"effect/Effect\"\nimport * as Predicate from \"effect/Predicate\"\nimport * as FetchHttpClient from \"effect/unstable/http/FetchHttpClient\"\nimport { useCallback, useEffect, useState } from \"react\"\n\nimport { makeControlCenterApiClient } from \"../../api/client.js\"\nimport type { WorkspaceEntityInspection } from \"../../api/deliveryGraph.js\"\nimport type { EntityId, WorkspaceId } from \"../../domain/identifiers.js\"\n\ninterface WorkspaceEntityScope {\n readonly entityId: EntityId\n readonly refreshKey: string\n readonly sessionKey: string\n readonly workspaceId: WorkspaceId\n}\n\nexport type WorkspaceEntityStaleReason = \"refresh-failed\" | \"refreshing\" | \"source-stale\"\n\n/** Complete controller state for one exact canonical workspace entity read. */\nexport type WorkspaceEntityState =\n | { readonly _tag: \"idle\" }\n | ({ readonly _tag: \"loading\" } & WorkspaceEntityScope)\n | ({ readonly _tag: \"not-found\" } & WorkspaceEntityScope)\n | ({ readonly _tag: \"failed\" } & WorkspaceEntityScope)\n | ({ readonly _tag: \"ready\"; readonly inspection: WorkspaceEntityInspection } & WorkspaceEntityScope)\n | ({\n readonly _tag: \"stale\"\n readonly inspection: WorkspaceEntityInspection\n readonly reason: WorkspaceEntityStaleReason\n } & WorkspaceEntityScope)\n\n/** Browser boundary for one exact authenticated workspace entity read. */\nexport interface WorkspaceEntityTransport {\n readonly load: (entityId: EntityId, signal: AbortSignal) => Promise<WorkspaceEntityInspection>\n}\n\nconst isUnauthorizedFailure = Predicate.isTagged(\"UnauthorizedApiError\")\nconst isNotFoundFailure = Predicate.isTagged(\"NotFoundApiError\")\n\nconst sameIdentity = (state: WorkspaceEntityState, scope: WorkspaceEntityScope): boolean =>\n state._tag !== \"idle\" &&\n state.entityId === scope.entityId &&\n state.sessionKey === scope.sessionKey &&\n state.workspaceId === scope.workspaceId\n\nconst retainedInspection = (\n state: WorkspaceEntityState,\n scope: WorkspaceEntityScope\n): WorkspaceEntityInspection | null =>\n sameIdentity(state, scope) && (state._tag === \"ready\" || state._tag === \"stale\")\n ? state.inspection\n : null\n\nconst successfulState = (\n inspection: WorkspaceEntityInspection,\n scope: WorkspaceEntityScope\n): WorkspaceEntityState =>\n !inspection.isSourceCurrent || inspection.freshness?._tag === \"stale\"\n ? { _tag: \"stale\", inspection, reason: \"source-stale\", ...scope }\n : { _tag: \"ready\", inspection, ...scope }\n\n/** Generated-client transport for the canonical schema-decoded entity inspection. */\nexport const browserWorkspaceEntityTransport: WorkspaceEntityTransport = {\n load: (entityId, signal) =>\n Effect.runPromise(\n Effect.gen(function*() {\n const client = yield* makeControlCenterApiClient()\n return yield* client.deliveryGraph.workspaceEntity({ params: { entityId } })\n }).pipe(Effect.provide(FetchHttpClient.layer)),\n { signal }\n )\n}\n\n/** Keep one entity inspection scoped to the exact workspace, identity, refresh, and browser session. */\nexport const useWorkspaceEntity = (\n workspaceId: WorkspaceId,\n entityId: EntityId,\n refreshKey: string,\n sessionKey: string | null,\n onSessionExpired: (sessionKey: string) => void,\n transport: WorkspaceEntityTransport = browserWorkspaceEntityTransport\n) => {\n const [requestRevision, setRequestRevision] = useState(0)\n const [state, setState] = useState<WorkspaceEntityState>({ _tag: \"idle\" })\n\n useEffect(() => {\n if (sessionKey === null) {\n setState({ _tag: \"idle\" })\n return\n }\n const scope = { entityId, refreshKey, sessionKey, workspaceId } satisfies WorkspaceEntityScope\n const abort = new AbortController()\n setState((current) => {\n const inspection = retainedInspection(current, scope)\n return inspection === null\n ? { _tag: \"loading\", ...scope }\n : { _tag: \"stale\", inspection, reason: \"refreshing\", ...scope }\n })\n transport.load(entityId, abort.signal).then(\n (inspection) => {\n if (!abort.signal.aborted) setState(successfulState(inspection, scope))\n },\n (failure) => {\n if (abort.signal.aborted) return\n if (isUnauthorizedFailure(failure)) {\n onSessionExpired(sessionKey)\n setState({ _tag: \"failed\", ...scope })\n return\n }\n if (isNotFoundFailure(failure)) {\n setState({ _tag: \"not-found\", ...scope })\n return\n }\n setState((current) => {\n const inspection = retainedInspection(current, scope)\n return inspection === null\n ? { _tag: \"failed\", ...scope }\n : { _tag: \"stale\", inspection, reason: \"refresh-failed\", ...scope }\n })\n }\n )\n return () => abort.abort()\n }, [entityId, onSessionExpired, refreshKey, requestRevision, sessionKey, transport, workspaceId])\n\n const scope = sessionKey === null\n ? null\n : { entityId, refreshKey, sessionKey, workspaceId } satisfies WorkspaceEntityScope\n const currentState: WorkspaceEntityState = scope === null\n ? { _tag: \"idle\" }\n : state._tag === \"idle\" || !sameIdentity(state, scope)\n ? { _tag: \"loading\", ...scope }\n : state.refreshKey !== refreshKey && (state._tag === \"ready\" || state._tag === \"stale\")\n ? { _tag: \"stale\", inspection: state.inspection, reason: \"refreshing\", ...scope }\n : state.refreshKey !== refreshKey\n ? { _tag: \"loading\", ...scope }\n : state\n\n return {\n retry: useCallback(() => setRequestRevision((revision) => revision + 1), []),\n state: currentState\n }\n}\n","import * as Data from \"effect/Data\"\nimport * as Effect from \"effect/Effect\"\nimport * as FetchHttpClient from \"effect/unstable/http/FetchHttpClient\"\n\nimport type { ReleasePublicationProvider } from \"../../api/agent.js\"\nimport type { EntityId, GovernedActionId, ReleaseId } from \"../../domain/identifiers.js\"\nimport type { Revision } from \"../../domain/sourceRevision.js\"\nimport type { ReleaseAgentTurn } from \"../AgentPage.js\"\nimport { makeAuthenticatedMutationClient } from \"../authenticatedMutationClient.js\"\n\nexport const submitBrowserReleasePublication = (input: {\n readonly releaseId: ReleaseId\n readonly provider: ReleasePublicationProvider\n readonly title: string\n readonly markdown: string\n readonly publicationActionId?: GovernedActionId\n readonly templateEntityId?: EntityId\n readonly targetEntityId?: EntityId\n readonly targetRevision?: Revision\n readonly signal?: AbortSignal\n}): Promise<{ readonly actionId: string; readonly state: string }> =>\n Effect.runPromise(\n Effect.gen(function*() {\n const client = yield* makeAuthenticatedMutationClient\n return yield* client.agent.submitReleasePublication({\n params: { releaseId: input.releaseId },\n payload: {\n provider: input.provider,\n title: input.title,\n markdown: input.markdown,\n parentId: null,\n ...(!(input.publicationActionId === undefined) && {\n publicationActionId: input.publicationActionId\n }),\n ...(!(input.templateEntityId === undefined) && { templateEntityId: input.templateEntityId }),\n ...(!(input.targetEntityId === undefined) && { targetEntityId: input.targetEntityId }),\n ...(!(input.targetRevision === undefined) && { targetRevision: input.targetRevision })\n }\n })\n }).pipe(Effect.provide(FetchHttpClient.layer)),\n input.signal === undefined ? undefined : { signal: input.signal }\n )\n\nclass ReleaseAgentProtocolError extends Data.TaggedError(\"ReleaseAgentProtocolError\") {}\n\nconst runTurnEffect = Effect.fn(\"ReleaseAgentTransport.runTurn\")(function*(\n input: Parameters<ReleaseAgentTurn>[0]\n) {\n const client = yield* makeAuthenticatedMutationClient\n const response = yield* client.agent.turn({\n params: { releaseId: input.releaseId },\n payload: {\n history: input.history,\n ...(!(input.originPath === undefined) && { originPath: input.originPath }),\n prompt: input.prompt,\n provider: input.provider\n }\n })\n if (response.releaseId !== input.releaseId || response.release.releaseId !== input.releaseId) {\n return yield* new ReleaseAgentProtocolError()\n }\n return {\n eventCursor: response.eventCursor,\n provider: response.provider,\n release: response.release,\n reply: response.reply\n }\n})\n\nconst loadPresetsEffect = Effect.fn(\"ReleaseAgentTransport.loadPresets\")(function*() {\n const client = yield* makeAuthenticatedMutationClient\n const catalog = yield* client.agent.providers()\n const presets = new Array<\"claude\" | \"codex\">()\n for (const provider of catalog.providers) {\n const providerId = String(provider.providerId)\n if (\n provider.health === \"available\" &&\n provider.capabilities.includes(\"release-chat\") &&\n (providerId === \"codex\" || providerId === \"claude\")\n ) {\n presets.push(providerId)\n }\n }\n return presets\n})\n\n/** Browser transport for the selected read-only local release-agent preset. */\nexport const runBrowserReleaseAgentTurn: ReleaseAgentTurn = (input, { signal }) =>\n Effect.runPromise(runTurnEffect(input).pipe(Effect.provide(FetchHttpClient.layer)), { signal })\n\n/** Load only configured local release-agent presets from the redacted catalog. */\nexport const loadBrowserReleaseAgentPresets = (\n signal: AbortSignal\n): Promise<ReadonlyArray<\"claude\" | \"codex\">> =>\n Effect.runPromise(loadPresetsEffect().pipe(Effect.provide(FetchHttpClient.layer)), { signal })\n"],"mappings":"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"}
1
+ {"version":3,"file":"releaseAgentTransport-CJjWwE8y.js","names":[],"sources":["../../../src/client/entities/presentWorkspaceConfluencePage.ts","../../../src/client/entities/useWorkspaceEntity.ts","../../../src/client/releases/releaseAgentTransport.ts"],"sourcesContent":["import type { RlyPerson } from \"@knpkv/rly/patterns\"\nimport * as DateTime from \"effect/DateTime\"\n\nimport type { WorkspaceEntityInspection } from \"../../api/deliveryGraph.js\"\nimport type { DeliveryEntityDetails } from \"../../domain/deliveryGraph.js\"\n\ntype PageDetails = Extract<DeliveryEntityDetails, { readonly _tag: \"page\" }>\n\nexport interface WorkspacePageTimestamp {\n readonly dateTime: string\n readonly label: string\n}\n\nexport interface WorkspaceConfluencePagePresentation {\n readonly attachmentInventoryLabel: string\n readonly attachments: ReadonlyArray<{\n readonly createdAt: WorkspacePageTimestamp\n readonly fileSize: string\n readonly id: string\n readonly mediaType: string\n readonly title: string\n readonly version: string\n }>\n readonly content: string | null\n readonly contentState: \"empty\" | \"lazy\" | \"loaded\"\n readonly contributors: ReadonlyArray<RlyPerson>\n readonly createdAt: WorkspacePageTimestamp | null\n readonly historyInventoryLabel: string\n readonly revision: string\n readonly runbookEvidenceCount: number\n readonly sourceSpaceId: string\n readonly status: \"Current\" | \"Draft\" | \"Superseded\"\n readonly taskUpdatesSafe?: boolean\n readonly updatedAt: WorkspacePageTimestamp | null\n readonly versions: ReadonlyArray<{\n readonly author: string\n readonly createdAt: WorkspacePageTimestamp\n readonly message: string\n readonly minorEdit: boolean\n readonly number: number\n }>\n readonly watcherInventoryLabel: string\n}\n\nconst timestampFormatter = new Intl.DateTimeFormat(\"en-GB\", {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n timeZone: \"UTC\"\n})\n\nconst timestampFor = (value: DateTime.DateTime | undefined): WorkspacePageTimestamp | null =>\n value === undefined\n ? null\n : {\n dateTime: DateTime.formatIso(value),\n label: timestampFormatter.format(DateTime.toDateUtc(value))\n }\n\nconst inventoryLabel = (\n inventory: { readonly complete: boolean; readonly pagesFetched: number } | undefined,\n noun: string\n): string =>\n inventory === undefined\n ? `${noun} not synchronized`\n : `${inventory.complete ? \"Complete\" : \"Partial\"} · ${String(inventory.pagesFetched)} bounded page${\n inventory.pagesFetched === 1 ? \"\" : \"s\"\n } read`\n\nconst fileSizeLabel = (bytes: number | null): string => {\n if (bytes === null) return \"Size unavailable\"\n if (bytes < 1_024) return `${String(bytes)} B`\n if (bytes < 1_048_576) return `${(bytes / 1_024).toFixed(1)} KB`\n return `${(bytes / 1_048_576).toFixed(1)} MB`\n}\n\nconst roleLabel = (roles: ReadonlyArray<\"author\" | \"contributor\" | \"owner\" | \"watcher\">): string =>\n roles.map((role) => `${role.charAt(0).toLocaleUpperCase(\"en-US\")}${role.slice(1)}`).join(\" · \")\n\nconst uniqueContributors = (\n contributors: NonNullable<PageDetails[\"contributors\"]>\n): NonNullable<PageDetails[\"contributors\"]> => {\n const byId = new Map<string, NonNullable<PageDetails[\"contributors\"]>[number]>()\n for (const contributor of contributors) {\n const previous = byId.get(contributor.sourcePersonId)\n const roles = previous === undefined\n ? contributor.roles\n : [...new Set([...previous.roles, ...contributor.roles])]\n const identity = previous?.resolved === true && !contributor.resolved ? previous : contributor\n byId.set(contributor.sourcePersonId, { ...identity, roles })\n }\n return [...byId.values()]\n}\n\n/** Present one normalized page as a quiet read-only document with explicit provider boundaries. */\nexport const presentWorkspaceConfluencePage = (\n details: PageDetails,\n inspection: WorkspaceEntityInspection\n): WorkspaceConfluencePagePresentation => {\n const contributors = uniqueContributors(details.contributors ?? [])\n const contributorNameById = new Map(contributors.map(({ displayName, sourcePersonId }) => [\n sourcePersonId,\n displayName\n ]))\n const contentState = details.contentState === \"lazy\"\n ? \"lazy\"\n : details.content === null || details.content === undefined\n ? \"empty\"\n : \"loaded\"\n return {\n attachmentInventoryLabel: inventoryLabel(details.attachmentInventory, \"Attachment inventory\"),\n attachments: (details.attachments ?? []).map((attachment) => ({\n createdAt: timestampFor(attachment.createdAt)!,\n fileSize: fileSizeLabel(attachment.fileSize),\n id: attachment.id,\n mediaType: attachment.mediaType ?? \"Type unavailable\",\n title: attachment.title,\n version: attachment.version === null ? \"Version unavailable\" : `v${String(attachment.version)}`\n })),\n content: contentState === \"loaded\" ? (details.content?.markdown ?? null) : null,\n contentState,\n contributors: contributors.map((contributor) => ({\n id: contributor.sourcePersonId,\n name: contributor.displayName,\n role: `${roleLabel(contributor.roles)}${contributor.external ? \" · External\" : \"\"}${\n contributor.resolved ? \"\" : \" · Identity unresolved\"\n }`\n })),\n createdAt: timestampFor(details.createdAt),\n historyInventoryLabel: inventoryLabel(details.versionHistory, \"Revision history\"),\n revision: details.revision,\n runbookEvidenceCount: inspection.graph.evidenceItems.length,\n sourceSpaceId: details.sourceSpaceId ?? details.spaceKey,\n status: details.status === \"superseded\" ? \"Superseded\" : details.status === \"draft\" ? \"Draft\" : \"Current\",\n taskUpdatesSafe: details.taskUpdatesSafe === true,\n updatedAt: timestampFor(details.updatedAt),\n versions: (details.versions ?? []).map((version) => ({\n author: version.authorSourcePersonId === null\n ? \"Author unavailable\"\n : contributorNameById.get(version.authorSourcePersonId) ?? \"Identity not resolved\",\n createdAt: timestampFor(version.createdAt)!,\n message: version.message ?? \"No revision note\",\n minorEdit: version.minorEdit,\n number: version.number\n })),\n watcherInventoryLabel: inventoryLabel(details.watcherInventory, \"Watcher inventory\")\n }\n}\n","import * as Effect from \"effect/Effect\"\nimport * as Predicate from \"effect/Predicate\"\nimport * as FetchHttpClient from \"effect/unstable/http/FetchHttpClient\"\nimport { useCallback, useEffect, useState } from \"react\"\n\nimport { makeControlCenterApiClient } from \"../../api/client.js\"\nimport type { WorkspaceEntityInspection } from \"../../api/deliveryGraph.js\"\nimport type { EntityId, WorkspaceId } from \"../../domain/identifiers.js\"\n\ninterface WorkspaceEntityScope {\n readonly entityId: EntityId\n readonly refreshKey: string\n readonly sessionKey: string\n readonly workspaceId: WorkspaceId\n}\n\nexport type WorkspaceEntityStaleReason = \"refresh-failed\" | \"refreshing\" | \"source-stale\"\n\n/** Complete controller state for one exact canonical workspace entity read. */\nexport type WorkspaceEntityState =\n | { readonly _tag: \"idle\" }\n | ({ readonly _tag: \"loading\" } & WorkspaceEntityScope)\n | ({ readonly _tag: \"not-found\" } & WorkspaceEntityScope)\n | ({ readonly _tag: \"failed\" } & WorkspaceEntityScope)\n | ({ readonly _tag: \"ready\"; readonly inspection: WorkspaceEntityInspection } & WorkspaceEntityScope)\n | ({\n readonly _tag: \"stale\"\n readonly inspection: WorkspaceEntityInspection\n readonly reason: WorkspaceEntityStaleReason\n } & WorkspaceEntityScope)\n\n/** Browser boundary for one exact authenticated workspace entity read. */\nexport interface WorkspaceEntityTransport {\n readonly load: (entityId: EntityId, signal: AbortSignal) => Promise<WorkspaceEntityInspection>\n}\n\nconst isUnauthorizedFailure = Predicate.isTagged(\"UnauthorizedApiError\")\nconst isNotFoundFailure = Predicate.isTagged(\"NotFoundApiError\")\n\nconst sameIdentity = (state: WorkspaceEntityState, scope: WorkspaceEntityScope): boolean =>\n state._tag !== \"idle\" &&\n state.entityId === scope.entityId &&\n state.sessionKey === scope.sessionKey &&\n state.workspaceId === scope.workspaceId\n\nconst retainedInspection = (\n state: WorkspaceEntityState,\n scope: WorkspaceEntityScope\n): WorkspaceEntityInspection | null =>\n sameIdentity(state, scope) && (state._tag === \"ready\" || state._tag === \"stale\")\n ? state.inspection\n : null\n\nconst successfulState = (\n inspection: WorkspaceEntityInspection,\n scope: WorkspaceEntityScope\n): WorkspaceEntityState =>\n !inspection.isSourceCurrent || inspection.freshness?._tag === \"stale\"\n ? { _tag: \"stale\", inspection, reason: \"source-stale\", ...scope }\n : { _tag: \"ready\", inspection, ...scope }\n\n/** Generated-client transport for the canonical schema-decoded entity inspection. */\nexport const browserWorkspaceEntityTransport: WorkspaceEntityTransport = {\n load: (entityId, signal) =>\n Effect.runPromise(\n Effect.gen(function*() {\n const client = yield* makeControlCenterApiClient()\n return yield* client.deliveryGraph.workspaceEntity({ params: { entityId } })\n }).pipe(Effect.provide(FetchHttpClient.layer)),\n { signal }\n )\n}\n\n/** Keep one entity inspection scoped to the exact workspace, identity, refresh, and browser session. */\nexport const useWorkspaceEntity = (\n workspaceId: WorkspaceId,\n entityId: EntityId,\n refreshKey: string,\n sessionKey: string | null,\n onSessionExpired: (sessionKey: string) => void,\n transport: WorkspaceEntityTransport = browserWorkspaceEntityTransport\n) => {\n const [requestRevision, setRequestRevision] = useState(0)\n const [state, setState] = useState<WorkspaceEntityState>({ _tag: \"idle\" })\n\n useEffect(() => {\n if (sessionKey === null) {\n setState({ _tag: \"idle\" })\n return\n }\n const scope = { entityId, refreshKey, sessionKey, workspaceId } satisfies WorkspaceEntityScope\n const abort = new AbortController()\n setState((current) => {\n const inspection = retainedInspection(current, scope)\n return inspection === null\n ? { _tag: \"loading\", ...scope }\n : { _tag: \"stale\", inspection, reason: \"refreshing\", ...scope }\n })\n transport.load(entityId, abort.signal).then(\n (inspection) => {\n if (!abort.signal.aborted) setState(successfulState(inspection, scope))\n },\n (failure) => {\n if (abort.signal.aborted) return\n if (isUnauthorizedFailure(failure)) {\n onSessionExpired(sessionKey)\n setState({ _tag: \"failed\", ...scope })\n return\n }\n if (isNotFoundFailure(failure)) {\n setState({ _tag: \"not-found\", ...scope })\n return\n }\n setState((current) => {\n const inspection = retainedInspection(current, scope)\n return inspection === null\n ? { _tag: \"failed\", ...scope }\n : { _tag: \"stale\", inspection, reason: \"refresh-failed\", ...scope }\n })\n }\n )\n return () => abort.abort()\n }, [entityId, onSessionExpired, refreshKey, requestRevision, sessionKey, transport, workspaceId])\n\n const scope = sessionKey === null\n ? null\n : { entityId, refreshKey, sessionKey, workspaceId } satisfies WorkspaceEntityScope\n const currentState: WorkspaceEntityState = scope === null\n ? { _tag: \"idle\" }\n : state._tag === \"idle\" || !sameIdentity(state, scope)\n ? { _tag: \"loading\", ...scope }\n : state.refreshKey !== refreshKey && (state._tag === \"ready\" || state._tag === \"stale\")\n ? { _tag: \"stale\", inspection: state.inspection, reason: \"refreshing\", ...scope }\n : state.refreshKey !== refreshKey\n ? { _tag: \"loading\", ...scope }\n : state\n\n return {\n retry: useCallback(() => setRequestRevision((revision) => revision + 1), []),\n state: currentState\n }\n}\n","import * as Data from \"effect/Data\"\nimport * as Effect from \"effect/Effect\"\nimport * as FetchHttpClient from \"effect/unstable/http/FetchHttpClient\"\n\nimport type { ReleasePublicationProvider } from \"../../api/agent.js\"\nimport type { EntityId, GovernedActionId, ReleaseId } from \"../../domain/identifiers.js\"\nimport type { Revision } from \"../../domain/sourceRevision.js\"\nimport type { ReleaseAgentTurn } from \"../AgentPage.js\"\nimport { makeAuthenticatedMutationClient } from \"../authenticatedMutationClient.js\"\n\nexport const submitBrowserReleasePublication = (input: {\n readonly releaseId: ReleaseId\n readonly provider: ReleasePublicationProvider\n readonly title: string\n readonly markdown: string\n readonly publicationActionId?: GovernedActionId\n readonly templateEntityId?: EntityId\n readonly targetEntityId?: EntityId\n readonly targetRevision?: Revision\n readonly signal?: AbortSignal\n}): Promise<{ readonly actionId: string; readonly state: string }> =>\n Effect.runPromise(\n Effect.gen(function*() {\n const client = yield* makeAuthenticatedMutationClient\n return yield* client.agent.submitReleasePublication({\n params: { releaseId: input.releaseId },\n payload: {\n provider: input.provider,\n title: input.title,\n markdown: input.markdown,\n parentId: null,\n ...(!(input.publicationActionId === undefined) && {\n publicationActionId: input.publicationActionId\n }),\n ...(!(input.templateEntityId === undefined) && { templateEntityId: input.templateEntityId }),\n ...(!(input.targetEntityId === undefined) && { targetEntityId: input.targetEntityId }),\n ...(!(input.targetRevision === undefined) && { targetRevision: input.targetRevision })\n }\n })\n }).pipe(Effect.provide(FetchHttpClient.layer)),\n input.signal === undefined ? undefined : { signal: input.signal }\n )\n\nclass ReleaseAgentProtocolError extends Data.TaggedError(\"ReleaseAgentProtocolError\") {}\n\nconst runTurnEffect = Effect.fn(\"ReleaseAgentTransport.runTurn\")(function*(\n input: Parameters<ReleaseAgentTurn>[0]\n) {\n const client = yield* makeAuthenticatedMutationClient\n const response = yield* client.agent.turn({\n params: { releaseId: input.releaseId },\n payload: {\n history: input.history,\n ...(!(input.originPath === undefined) && { originPath: input.originPath }),\n prompt: input.prompt,\n provider: input.provider\n }\n })\n if (response.releaseId !== input.releaseId || response.release.releaseId !== input.releaseId) {\n return yield* new ReleaseAgentProtocolError()\n }\n return {\n eventCursor: response.eventCursor,\n provider: response.provider,\n release: response.release,\n reply: response.reply\n }\n})\n\nconst loadPresetsEffect = Effect.fn(\"ReleaseAgentTransport.loadPresets\")(function*() {\n const client = yield* makeAuthenticatedMutationClient\n const catalog = yield* client.agent.providers()\n const presets = new Array<\"claude\" | \"codex\">()\n for (const provider of catalog.providers) {\n const providerId = String(provider.providerId)\n if (\n provider.health === \"available\" &&\n provider.capabilities.includes(\"release-chat\") &&\n (providerId === \"codex\" || providerId === \"claude\")\n ) {\n presets.push(providerId)\n }\n }\n return presets\n})\n\n/** Browser transport for the selected read-only local release-agent preset. */\nexport const runBrowserReleaseAgentTurn: ReleaseAgentTurn = (input, { signal }) =>\n Effect.runPromise(runTurnEffect(input).pipe(Effect.provide(FetchHttpClient.layer)), { signal })\n\n/** Load only configured local release-agent presets from the redacted catalog. */\nexport const loadBrowserReleaseAgentPresets = (\n signal: AbortSignal\n): Promise<ReadonlyArray<\"claude\" | \"codex\">> =>\n Effect.runPromise(loadPresetsEffect().pipe(Effect.provide(FetchHttpClient.layer)), { signal })\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{i as e,s as t}from"./releasePaths-XoI2BHX3.js";import{Aa as n,Bn as r,Pn as i,dn as a,ja as o,mn as s,nr as c,zn as l}from"./agent-api-CUWP1qs8.js";var u=r({hash:l,pathname:l,search:l}),d=r({_tag:i(`release-origin/v1`),origin:u,releaseId:a,workspaceId:s}),f=(e,t,r)=>{let i=c(d)(e);return n(i)?null:x(i.value,t,r).isStored?i.value:null},p=e=>{let t=c(s)(e);return o(t)?t.value:null},m=e=>{let t=c(a)(e);return o(t)?t.value:null},h=e=>({relay:`release-${e}-relay`,verdict:`release-${e}-verdict`,version:`release-${e}-version`}),g=({hash:e,pathname:t,search:n})=>({hash:e,pathname:t,search:n}),_=e=>e.length<=2048&&(e.length===0||e.startsWith(`?`)),v=e=>e.length<=1024&&(e.length===0||e.startsWith(`#`)),y=(n,r)=>n===e(r)||n===t(r),b=(e,t,n)=>({_tag:`release-origin/v1`,origin:n,releaseId:t,workspaceId:e}),x=(t,r,i)=>{let a={hash:``,pathname:e(r),search:``},o=c(d)(t);if(n(o))return{isStored:!1,origin:a};let s=o.value,l=s.workspaceId===r&&s.releaseId===i,u=y(s.origin.pathname,r);return l&&u&&_(s.origin.search)&&v(s.origin.hash)?{isStored:!0,origin:s.origin}:{isStored:!1,origin:a}},S=(e,t,n)=>x(e,t,n).origin,C=({hash:e,pathname:t,search:n})=>`${t}${n}${e}`;export{S as a,h as c,b as i,x as l,m as n,g as o,p as r,C as s,d as t,f as u};
2
+ //# sourceMappingURL=releaseRoutes-h4FVwFvJ.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"releaseRoutes-CSP_eBj6.js","names":[],"sources":["../../../src/client/releases/releaseRoutes.ts"],"sourcesContent":["import type { RlyReleaseTransitionNames } from \"@knpkv/rly/patterns\"\nimport * as Option from \"effect/Option\"\nimport * as Schema from \"effect/Schema\"\n\nimport {\n ReleaseId,\n type ReleaseId as ReleaseIdType,\n WorkspaceId,\n type WorkspaceId as WorkspaceIdType\n} from \"../../domain/identifiers.js\"\nimport { releaseParentPath, workspaceItemsPath } from \"./releasePaths.js\"\n\nexport {\n releaseActiveWorkPath,\n releaseAgentPath,\n releaseFullPath,\n releaseParentPath,\n releasePreviewPath,\n workspaceActiveWorkPath,\n workspaceItemsPath\n} from \"./releasePaths.js\"\n\n/** Exact in-application location preserved while release routes are open. */\nexport interface ReleaseOrigin {\n readonly hash: string\n readonly pathname: string\n readonly search: string\n}\n\n/** Router state carried from a release activation through preview and full view. */\nexport interface ReleaseRouteState {\n readonly _tag: \"release-origin/v1\"\n readonly origin: ReleaseOrigin\n readonly releaseId: ReleaseIdType\n readonly workspaceId: WorkspaceIdType\n}\n\n/** Decoded release origin plus whether it came from trusted versioned history state. */\nexport interface ResolvedReleaseOrigin {\n readonly isStored: boolean\n readonly origin: ReleaseOrigin\n}\n\ninterface LocationParts {\n readonly hash: string\n readonly pathname: string\n readonly search: string\n}\n\nconst ReleaseOriginSchema = Schema.Struct({\n hash: Schema.String,\n pathname: Schema.String,\n search: Schema.String\n})\n\n/** Bounded decoder shared by nested client routes that need to retain a release activation. */\nexport const ReleaseRouteStateSchema = Schema.Struct({\n _tag: Schema.Literal(\"release-origin/v1\"),\n origin: ReleaseOriginSchema,\n releaseId: ReleaseId,\n workspaceId: WorkspaceId\n})\n\n/** Retain only safe state for the exact release target, dropping foreign or malformed history data. */\nexport const retainReleaseRouteState = <UnparsedInput>(\n state: UnparsedInput,\n workspaceId: WorkspaceIdType,\n releaseId: ReleaseIdType\n): ReleaseRouteState | null => {\n const decoded = Schema.decodeUnknownOption(ReleaseRouteStateSchema)(state)\n if (Option.isNone(decoded)) return null\n return resolveReleaseOrigin(decoded.value, workspaceId, releaseId).isStored ? decoded.value : null\n}\n\n/** Decode one workspace route segment at the browser boundary. */\nexport const decodeWorkspaceRouteId = <UnparsedInput>(value: UnparsedInput): WorkspaceIdType | null => {\n const decoded = Schema.decodeUnknownOption(WorkspaceId)(value)\n return Option.isSome(decoded) ? decoded.value : null\n}\n\n/** Decode one release route segment at the browser boundary. */\nexport const decodeReleaseRouteId = <UnparsedInput>(value: UnparsedInput): ReleaseIdType | null => {\n const decoded = Schema.decodeUnknownOption(ReleaseId)(value)\n return Option.isSome(decoded) ? decoded.value : null\n}\n\n/** Stable, collision-free geometry names for one release's orchestrated route transition. */\nexport const releaseTransitionNames = (releaseId: ReleaseIdType): RlyReleaseTransitionNames => ({\n relay: `release-${releaseId}-relay`,\n verdict: `release-${releaseId}-verdict`,\n version: `release-${releaseId}-version`\n})\n\n/** Capture a location without retaining mutable router objects. */\nexport const releaseOriginFromLocation = ({ hash, pathname, search }: LocationParts): ReleaseOrigin => ({\n hash,\n pathname,\n search\n})\n\nconst isSearch = (search: string): boolean => search.length <= 2_048 && (search.length === 0 || search.startsWith(\"?\"))\n\nconst isHash = (hash: string): boolean => hash.length <= 1_024 && (hash.length === 0 || hash.startsWith(\"#\"))\n\nconst isRecognizedOriginPath = (pathname: string, workspaceId: WorkspaceIdType): boolean =>\n pathname === releaseParentPath(workspaceId) || pathname === workspaceItemsPath(workspaceId)\n\n/** Construct bounded route state without retaining session or snapshot data. */\nexport const makeReleaseRouteState = (\n workspaceId: WorkspaceIdType,\n releaseId: ReleaseIdType,\n origin: ReleaseOrigin\n): ReleaseRouteState => ({ _tag: \"release-origin/v1\", origin, releaseId, workspaceId })\n\n/** Decode history state without permitting external or malformed navigation targets. */\nexport const resolveReleaseOrigin = <UnparsedInput>(\n state: UnparsedInput,\n workspaceId: WorkspaceIdType,\n releaseId: ReleaseIdType\n): ResolvedReleaseOrigin => {\n const fallback = { hash: \"\", pathname: releaseParentPath(workspaceId), search: \"\" }\n const decoded = Schema.decodeUnknownOption(ReleaseRouteStateSchema)(state)\n if (Option.isNone(decoded)) return { isStored: false, origin: fallback }\n const routeState = decoded.value\n const isMatchingTarget = routeState.workspaceId === workspaceId && routeState.releaseId === releaseId\n const isRecognizedOrigin = isRecognizedOriginPath(routeState.origin.pathname, workspaceId)\n return isMatchingTarget && isRecognizedOrigin && isSearch(routeState.origin.search) && isHash(routeState.origin.hash)\n ? { isStored: true, origin: routeState.origin }\n : { isStored: false, origin: fallback }\n}\n\n/** Decode the exact safe origin or return the release's semantic parent. */\nexport const readReleaseOrigin = <UnparsedInput>(\n state: UnparsedInput,\n workspaceId: WorkspaceIdType,\n releaseId: ReleaseIdType\n): ReleaseOrigin => resolveReleaseOrigin(state, workspaceId, releaseId).origin\n\n/** Serialize an exact origin for React Router navigation. */\nexport const releaseOriginHref = ({ hash, pathname, search }: ReleaseOrigin): string => `${pathname}${search}${hash}`\n"],"mappings":"2JAiDA,IAAM,EAAsB,EAAc,CACxC,KAAM,EACN,SAAU,EACV,OAAQ,CACV,CAAC,EAGY,EAA0B,EAAc,CACnD,KAAM,EAAe,mBAAmB,EACxC,OAAQ,EACR,UAAW,EACX,YAAa,CACf,CAAC,EAGY,GACX,EACA,EACA,IAC6B,CAC7B,IAAM,EAAU,EAA2B,CAAuB,CAAC,CAAC,CAAK,EAEzE,OADI,EAAc,CAAO,EAAU,KAC5B,EAAqB,EAAQ,MAAO,EAAa,CAAS,CAAC,CAAC,SAAW,EAAQ,MAAQ,IAChG,EAGa,EAAyC,GAAiD,CACrG,IAAM,EAAU,EAA2B,CAAW,CAAC,CAAC,CAAK,EAC7D,OAAO,EAAc,CAAO,EAAI,EAAQ,MAAQ,IAClD,EAGa,EAAuC,GAA+C,CACjG,IAAM,EAAU,EAA2B,CAAS,CAAC,CAAC,CAAK,EAC3D,OAAO,EAAc,CAAO,EAAI,EAAQ,MAAQ,IAClD,EAGa,EAA0B,IAAyD,CAC9F,MAAO,WAAW,EAAU,QAC5B,QAAS,WAAW,EAAU,UAC9B,QAAS,WAAW,EAAU,SAChC,GAGa,GAA6B,CAAE,OAAM,WAAU,aAA4C,CACtG,OACA,WACA,QACF,GAEM,EAAY,GAA4B,EAAO,QAAU,OAAU,EAAO,SAAW,GAAK,EAAO,WAAW,GAAG,GAE/G,EAAU,GAA0B,EAAK,QAAU,OAAU,EAAK,SAAW,GAAK,EAAK,WAAW,GAAG,GAErG,GAA0B,EAAkB,IAChD,IAAa,EAAkB,CAAW,GAAK,IAAa,EAAmB,CAAW,EAG/E,GACX,EACA,EACA,KACuB,CAAE,KAAM,oBAAqB,SAAQ,YAAW,aAAY,GAGxE,GACX,EACA,EACA,IAC0B,CAC1B,IAAM,EAAW,CAAE,KAAM,GAAI,SAAU,EAAkB,CAAW,EAAG,OAAQ,EAAG,EAC5E,EAAU,EAA2B,CAAuB,CAAC,CAAC,CAAK,EACzE,GAAI,EAAc,CAAO,EAAG,MAAO,CAAE,SAAU,GAAO,OAAQ,CAAS,EACvE,IAAM,EAAa,EAAQ,MACrB,EAAmB,EAAW,cAAgB,GAAe,EAAW,YAAc,EACtF,EAAqB,EAAuB,EAAW,OAAO,SAAU,CAAW,EACzF,OAAO,GAAoB,GAAsB,EAAS,EAAW,OAAO,MAAM,GAAK,EAAO,EAAW,OAAO,IAAI,EAChH,CAAE,SAAU,GAAM,OAAQ,EAAW,MAAO,EAC5C,CAAE,SAAU,GAAO,OAAQ,CAAS,CAC1C,EAGa,GACX,EACA,EACA,IACkB,EAAqB,EAAO,EAAa,CAAS,CAAC,CAAC,OAG3D,GAAqB,CAAE,OAAM,WAAU,YAAoC,GAAG,IAAW,IAAS"}
1
+ {"version":3,"file":"releaseRoutes-h4FVwFvJ.js","names":[],"sources":["../../../src/client/releases/releaseRoutes.ts"],"sourcesContent":["import type { RlyReleaseTransitionNames } from \"@knpkv/rly/patterns\"\nimport * as Option from \"effect/Option\"\nimport * as Schema from \"effect/Schema\"\n\nimport {\n ReleaseId,\n type ReleaseId as ReleaseIdType,\n WorkspaceId,\n type WorkspaceId as WorkspaceIdType\n} from \"../../domain/identifiers.js\"\nimport { releaseParentPath, workspaceItemsPath } from \"./releasePaths.js\"\n\nexport {\n releaseActiveWorkPath,\n releaseAgentPath,\n releaseFullPath,\n releaseParentPath,\n releasePreviewPath,\n workspaceActiveWorkPath,\n workspaceItemsPath\n} from \"./releasePaths.js\"\n\n/** Exact in-application location preserved while release routes are open. */\nexport interface ReleaseOrigin {\n readonly hash: string\n readonly pathname: string\n readonly search: string\n}\n\n/** Router state carried from a release activation through preview and full view. */\nexport interface ReleaseRouteState {\n readonly _tag: \"release-origin/v1\"\n readonly origin: ReleaseOrigin\n readonly releaseId: ReleaseIdType\n readonly workspaceId: WorkspaceIdType\n}\n\n/** Decoded release origin plus whether it came from trusted versioned history state. */\nexport interface ResolvedReleaseOrigin {\n readonly isStored: boolean\n readonly origin: ReleaseOrigin\n}\n\ninterface LocationParts {\n readonly hash: string\n readonly pathname: string\n readonly search: string\n}\n\nconst ReleaseOriginSchema = Schema.Struct({\n hash: Schema.String,\n pathname: Schema.String,\n search: Schema.String\n})\n\n/** Bounded decoder shared by nested client routes that need to retain a release activation. */\nexport const ReleaseRouteStateSchema = Schema.Struct({\n _tag: Schema.Literal(\"release-origin/v1\"),\n origin: ReleaseOriginSchema,\n releaseId: ReleaseId,\n workspaceId: WorkspaceId\n})\n\n/** Retain only safe state for the exact release target, dropping foreign or malformed history data. */\nexport const retainReleaseRouteState = <UnparsedInput>(\n state: UnparsedInput,\n workspaceId: WorkspaceIdType,\n releaseId: ReleaseIdType\n): ReleaseRouteState | null => {\n const decoded = Schema.decodeUnknownOption(ReleaseRouteStateSchema)(state)\n if (Option.isNone(decoded)) return null\n return resolveReleaseOrigin(decoded.value, workspaceId, releaseId).isStored ? decoded.value : null\n}\n\n/** Decode one workspace route segment at the browser boundary. */\nexport const decodeWorkspaceRouteId = <UnparsedInput>(value: UnparsedInput): WorkspaceIdType | null => {\n const decoded = Schema.decodeUnknownOption(WorkspaceId)(value)\n return Option.isSome(decoded) ? decoded.value : null\n}\n\n/** Decode one release route segment at the browser boundary. */\nexport const decodeReleaseRouteId = <UnparsedInput>(value: UnparsedInput): ReleaseIdType | null => {\n const decoded = Schema.decodeUnknownOption(ReleaseId)(value)\n return Option.isSome(decoded) ? decoded.value : null\n}\n\n/** Stable, collision-free geometry names for one release's orchestrated route transition. */\nexport const releaseTransitionNames = (releaseId: ReleaseIdType): RlyReleaseTransitionNames => ({\n relay: `release-${releaseId}-relay`,\n verdict: `release-${releaseId}-verdict`,\n version: `release-${releaseId}-version`\n})\n\n/** Capture a location without retaining mutable router objects. */\nexport const releaseOriginFromLocation = ({ hash, pathname, search }: LocationParts): ReleaseOrigin => ({\n hash,\n pathname,\n search\n})\n\nconst isSearch = (search: string): boolean => search.length <= 2_048 && (search.length === 0 || search.startsWith(\"?\"))\n\nconst isHash = (hash: string): boolean => hash.length <= 1_024 && (hash.length === 0 || hash.startsWith(\"#\"))\n\nconst isRecognizedOriginPath = (pathname: string, workspaceId: WorkspaceIdType): boolean =>\n pathname === releaseParentPath(workspaceId) || pathname === workspaceItemsPath(workspaceId)\n\n/** Construct bounded route state without retaining session or snapshot data. */\nexport const makeReleaseRouteState = (\n workspaceId: WorkspaceIdType,\n releaseId: ReleaseIdType,\n origin: ReleaseOrigin\n): ReleaseRouteState => ({ _tag: \"release-origin/v1\", origin, releaseId, workspaceId })\n\n/** Decode history state without permitting external or malformed navigation targets. */\nexport const resolveReleaseOrigin = <UnparsedInput>(\n state: UnparsedInput,\n workspaceId: WorkspaceIdType,\n releaseId: ReleaseIdType\n): ResolvedReleaseOrigin => {\n const fallback = { hash: \"\", pathname: releaseParentPath(workspaceId), search: \"\" }\n const decoded = Schema.decodeUnknownOption(ReleaseRouteStateSchema)(state)\n if (Option.isNone(decoded)) return { isStored: false, origin: fallback }\n const routeState = decoded.value\n const isMatchingTarget = routeState.workspaceId === workspaceId && routeState.releaseId === releaseId\n const isRecognizedOrigin = isRecognizedOriginPath(routeState.origin.pathname, workspaceId)\n return isMatchingTarget && isRecognizedOrigin && isSearch(routeState.origin.search) && isHash(routeState.origin.hash)\n ? { isStored: true, origin: routeState.origin }\n : { isStored: false, origin: fallback }\n}\n\n/** Decode the exact safe origin or return the release's semantic parent. */\nexport const readReleaseOrigin = <UnparsedInput>(\n state: UnparsedInput,\n workspaceId: WorkspaceIdType,\n releaseId: ReleaseIdType\n): ReleaseOrigin => resolveReleaseOrigin(state, workspaceId, releaseId).origin\n\n/** Serialize an exact origin for React Router navigation. */\nexport const releaseOriginHref = ({ hash, pathname, search }: ReleaseOrigin): string => `${pathname}${search}${hash}`\n"],"mappings":"2JAiDA,IAAM,EAAsB,EAAc,CACxC,KAAM,EACN,SAAU,EACV,OAAQ,CACV,CAAC,EAGY,EAA0B,EAAc,CACnD,KAAM,EAAe,mBAAmB,EACxC,OAAQ,EACR,UAAW,EACX,YAAa,CACf,CAAC,EAGY,GACX,EACA,EACA,IAC6B,CAC7B,IAAM,EAAU,EAA2B,CAAuB,CAAC,CAAC,CAAK,EAEzE,OADI,EAAc,CAAO,EAAU,KAC5B,EAAqB,EAAQ,MAAO,EAAa,CAAS,CAAC,CAAC,SAAW,EAAQ,MAAQ,IAChG,EAGa,EAAyC,GAAiD,CACrG,IAAM,EAAU,EAA2B,CAAW,CAAC,CAAC,CAAK,EAC7D,OAAO,EAAc,CAAO,EAAI,EAAQ,MAAQ,IAClD,EAGa,EAAuC,GAA+C,CACjG,IAAM,EAAU,EAA2B,CAAS,CAAC,CAAC,CAAK,EAC3D,OAAO,EAAc,CAAO,EAAI,EAAQ,MAAQ,IAClD,EAGa,EAA0B,IAAyD,CAC9F,MAAO,WAAW,EAAU,QAC5B,QAAS,WAAW,EAAU,UAC9B,QAAS,WAAW,EAAU,SAChC,GAGa,GAA6B,CAAE,OAAM,WAAU,aAA4C,CACtG,OACA,WACA,QACF,GAEM,EAAY,GAA4B,EAAO,QAAU,OAAU,EAAO,SAAW,GAAK,EAAO,WAAW,GAAG,GAE/G,EAAU,GAA0B,EAAK,QAAU,OAAU,EAAK,SAAW,GAAK,EAAK,WAAW,GAAG,GAErG,GAA0B,EAAkB,IAChD,IAAa,EAAkB,CAAW,GAAK,IAAa,EAAmB,CAAW,EAG/E,GACX,EACA,EACA,KACuB,CAAE,KAAM,oBAAqB,SAAQ,YAAW,aAAY,GAGxE,GACX,EACA,EACA,IAC0B,CAC1B,IAAM,EAAW,CAAE,KAAM,GAAI,SAAU,EAAkB,CAAW,EAAG,OAAQ,EAAG,EAC5E,EAAU,EAA2B,CAAuB,CAAC,CAAC,CAAK,EACzE,GAAI,EAAc,CAAO,EAAG,MAAO,CAAE,SAAU,GAAO,OAAQ,CAAS,EACvE,IAAM,EAAa,EAAQ,MACrB,EAAmB,EAAW,cAAgB,GAAe,EAAW,YAAc,EACtF,EAAqB,EAAuB,EAAW,OAAO,SAAU,CAAW,EACzF,OAAO,GAAoB,GAAsB,EAAS,EAAW,OAAO,MAAM,GAAK,EAAO,EAAW,OAAO,IAAI,EAChH,CAAE,SAAU,GAAM,OAAQ,EAAW,MAAO,EAC5C,CAAE,SAAU,GAAO,OAAQ,CAAS,CAC1C,EAGa,GACX,EACA,EACA,IACkB,EAAqB,EAAO,EAAa,CAAS,CAAC,CAAC,OAG3D,GAAqB,CAAE,OAAM,WAAU,YAAoC,GAAG,IAAW,IAAS"}
@@ -1,2 +1,2 @@
1
- import{Gt as e,Rn as t,fa as n,on as r,tr as i,zn as a}from"./agent-api-CzdQFCcD.js";a({providerId:e,displayName:t,description:t}).annotate({identifier:`FirstPartyServiceIdentity`});var o={codecommit:{providerId:`codecommit`,displayName:`CodeCommit`,description:`Read pull requests from one AWS CodeCommit repository.`},codepipeline:{providerId:`codepipeline`,displayName:`CodePipeline`,description:`Read pipeline and execution state from AWS CodePipeline.`},jira:{providerId:`jira`,displayName:`Jira`,description:`Read delivery issues from Jira Cloud.`},confluence:{providerId:`confluence`,displayName:`Confluence`,description:`Read release documentation from Confluence Cloud.`},clockify:{providerId:`clockify`,displayName:`Clockify`,description:`Read bounded time-entry evidence and govern association corrections and approvals.`}},s=[o.codecommit,o.codepipeline,o.jira,o.confluence,o.clockify],c=e=>s.find(({providerId:t})=>t===e)?.providerId??null,l=e=>`/pair?service=${e}`,u=(e,t)=>c(e.get(t)),d=e=>`/services?enable=${e}`,f=(e,t=null,n=null)=>{let r=new URLSearchParams({enable:e.includes(`jira`)?`jira`:`confluence`});t!==null&&r.set(`atlassianProfile`,t),n!==null&&r.set(`atlassianSite`,n);for(let t of e)r.append(`atlassianProvider`,t);return`/services?${r.toString()}`},p=(e,t)=>`/services?${new URLSearchParams({atlassianRecoveryConnection:e,atlassianRecoveryProfile:t}).toString()}`,m=e=>{let t=e.getAll(`atlassianRecoveryConnection`);if(t.length!==1)return null;let a=i(r)(t[0]);return n(a)?a.success:null},h=e=>{let t=e.getAll(`atlassianRecoveryProfile`);if(t.length!==1)return null;let[n]=t;return n!==void 0&&n.length>0&&n.length<=500&&n.trim()===n?n:null},g=e=>{let t=e.getAll(`atlassianSite`);if(t.length!==1)return null;let[n]=t;return n!==void 0&&n.length>0&&n.length<=512&&n.trim()===n?n:null},_=e=>{let t=e.getAll(`atlassianProfile`);if(t.length!==1)return null;let[n]=t;return n!==void 0&&n.length>0&&n.length<=500&&n.trim()===n?n:null},v=e=>{let t=e.getAll(`atlassianProvider`);return t.length===1&&t[0]===`jira`?[`jira`]:t.length===1&&t[0]===`confluence`?[`confluence`]:t.length===2&&t.includes(`jira`)&&t.includes(`confluence`)?[`jira`,`confluence`]:null};export{g as a,u as c,s as d,v as i,l,f as n,m as o,_ as r,h as s,p as t,d as u};
2
- //# sourceMappingURL=serviceOnboarding-B6v5VXTG.js.map
1
+ import{Bn as e,Kt as t,ga as n,rr as r,sn as i,zn as a}from"./agent-api-CUWP1qs8.js";e({providerId:t,displayName:a,description:a}).annotate({identifier:`FirstPartyServiceIdentity`});var o={codecommit:{providerId:`codecommit`,displayName:`CodeCommit`,description:`Read pull requests from one AWS CodeCommit repository.`},codepipeline:{providerId:`codepipeline`,displayName:`CodePipeline`,description:`Read pipeline and execution state from AWS CodePipeline.`},jira:{providerId:`jira`,displayName:`Jira`,description:`Read delivery issues from Jira Cloud.`},confluence:{providerId:`confluence`,displayName:`Confluence`,description:`Read release documentation from Confluence Cloud.`},clockify:{providerId:`clockify`,displayName:`Clockify`,description:`Read bounded time-entry evidence and govern association corrections and approvals.`}},s=[o.codecommit,o.codepipeline,o.jira,o.confluence,o.clockify],c=e=>s.find(({providerId:t})=>t===e)?.providerId??null,l=e=>`/pair?service=${e}`,u=(e,t)=>c(e.get(t)),d=e=>`/services?enable=${e}`,f=(e,t=null,n=null)=>{let r=new URLSearchParams({enable:e.includes(`jira`)?`jira`:`confluence`});t!==null&&r.set(`atlassianProfile`,t),n!==null&&r.set(`atlassianSite`,n);for(let t of e)r.append(`atlassianProvider`,t);return`/services?${r.toString()}`},p=(e,t)=>`/services?${new URLSearchParams({atlassianRecoveryConnection:e,atlassianRecoveryProfile:t}).toString()}`,m=e=>{let t=e.getAll(`atlassianRecoveryConnection`);if(t.length!==1)return null;let a=r(i)(t[0]);return n(a)?a.success:null},h=e=>{let t=e.getAll(`atlassianRecoveryProfile`);if(t.length!==1)return null;let[n]=t;return n!==void 0&&n.length>0&&n.length<=500&&n.trim()===n?n:null},g=e=>{let t=e.getAll(`atlassianSite`);if(t.length!==1)return null;let[n]=t;return n!==void 0&&n.length>0&&n.length<=512&&n.trim()===n?n:null},_=e=>{let t=e.getAll(`atlassianProfile`);if(t.length!==1)return null;let[n]=t;return n!==void 0&&n.length>0&&n.length<=500&&n.trim()===n?n:null},v=e=>{let t=e.getAll(`atlassianProvider`);return t.length===1&&t[0]===`jira`?[`jira`]:t.length===1&&t[0]===`confluence`?[`confluence`]:t.length===2&&t.includes(`jira`)&&t.includes(`confluence`)?[`jira`,`confluence`]:null};export{g as a,u as c,s as d,v as i,l,f as n,m as o,_ as r,h as s,p as t,d as u};
2
+ //# sourceMappingURL=serviceOnboarding-F9Lj6a7y.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"serviceOnboarding-B6v5VXTG.js","names":[],"sources":["../../../src/domain/firstPartyServices.ts","../../../src/client/services/serviceOnboarding.ts"],"sourcesContent":["import * as Schema from \"effect/Schema\"\n\nimport { ProviderId } from \"./sourceRevision.js\"\n\n/** Safe provider identity rendered before a browser has access to workspace connections. */\nexport const FirstPartyServiceIdentity = Schema.Struct({\n providerId: ProviderId,\n displayName: Schema.String,\n description: Schema.String\n}).annotate({ identifier: \"FirstPartyServiceIdentity\" })\n\n/** Decoded safe first-party provider identity. */\nexport type FirstPartyServiceIdentity = typeof FirstPartyServiceIdentity.Type\n\n/** Stable provider lookup shared by public previews and the server-owned setup catalog. */\nexport const firstPartyServiceIdentityByProvider = {\n codecommit: {\n providerId: \"codecommit\",\n displayName: \"CodeCommit\",\n description: \"Read pull requests from one AWS CodeCommit repository.\"\n },\n codepipeline: {\n providerId: \"codepipeline\",\n displayName: \"CodePipeline\",\n description: \"Read pipeline and execution state from AWS CodePipeline.\"\n },\n jira: {\n providerId: \"jira\",\n displayName: \"Jira\",\n description: \"Read delivery issues from Jira Cloud.\"\n },\n confluence: {\n providerId: \"confluence\",\n displayName: \"Confluence\",\n description: \"Read release documentation from Confluence Cloud.\"\n },\n clockify: {\n providerId: \"clockify\",\n displayName: \"Clockify\",\n description: \"Read bounded time-entry evidence and govern association corrections and approvals.\"\n }\n} satisfies Readonly<Record<typeof ProviderId.Type, FirstPartyServiceIdentity>>\n\n/** Stable first-party services available to every Control Center installation. */\nexport const firstPartyServiceIdentities = [\n firstPartyServiceIdentityByProvider.codecommit,\n firstPartyServiceIdentityByProvider.codepipeline,\n firstPartyServiceIdentityByProvider.jira,\n firstPartyServiceIdentityByProvider.confluence,\n firstPartyServiceIdentityByProvider.clockify\n] satisfies ReadonlyArray<FirstPartyServiceIdentity>\n","import * as Result from \"effect/Result\"\nimport * as Schema from \"effect/Schema\"\nimport type { AtlassianOAuthProviderIntent } from \"../../api/plugins.js\"\nimport { firstPartyServiceIdentities } from \"../../domain/firstPartyServices.js\"\nimport { PluginConnectionId, type PluginConnectionId as PluginConnectionIdType } from \"../../domain/identifiers.js\"\nimport type { ProviderId } from \"../../domain/sourceRevision.js\"\n\nconst providerFrom = (value: string | null): ProviderId | null =>\n firstPartyServiceIdentities.find(({ providerId }) => providerId === value)?.providerId ?? null\n\n/** Pairing route that remembers which service the person chose to enable. */\nexport const servicePairingPath = (providerId: ProviderId): string => `/pair?service=${providerId}`\n\n/** Service selected by an untrusted browser query parameter. */\nexport const selectedServiceProvider = (searchParams: URLSearchParams, key: \"enable\" | \"service\"): ProviderId | null =>\n providerFrom(searchParams.get(key))\n\n/** Post-pairing destination that opens the selected service setup in place. */\nexport const serviceSetupPath = (providerId: ProviderId): string => `/services?enable=${providerId}`\n\n/** Atlassian setup destination that preserves the initiating products and, when present, the completed profile. */\nexport const atlassianOAuthSetupPath = (\n providers: AtlassianOAuthProviderIntent,\n profileId: string | null = null,\n preferredSiteId: string | null = null\n): string => {\n const searchParams = new URLSearchParams({ enable: providers.includes(\"jira\") ? \"jira\" : \"confluence\" })\n if (profileId !== null) searchParams.set(\"atlassianProfile\", profileId)\n if (preferredSiteId !== null) searchParams.set(\"atlassianSite\", preferredSiteId)\n for (const provider of providers) searchParams.append(\"atlassianProvider\", provider)\n return `/services?${searchParams.toString()}`\n}\n\n/** Post-callback destination that applies a new local OAuth profile to one existing connection. */\nexport const atlassianOAuthRecoveryPath = (\n pluginConnectionId: PluginConnectionIdType,\n profileId: string\n): string => {\n const searchParams = new URLSearchParams({\n atlassianRecoveryConnection: pluginConnectionId,\n atlassianRecoveryProfile: profileId\n })\n return `/services?${searchParams.toString()}`\n}\n\n/** Existing connection selected for an exact OAuth recovery handoff. */\nexport const selectedAtlassianRecoveryConnectionId = (\n searchParams: URLSearchParams\n): PluginConnectionIdType | null => {\n const values = searchParams.getAll(\"atlassianRecoveryConnection\")\n if (values.length !== 1) return null\n const decoded = Schema.decodeUnknownResult(PluginConnectionId)(values[0])\n return Result.isSuccess(decoded) ? decoded.success : null\n}\n\n/** Completed local OAuth profile selected for an exact recovery handoff. */\nexport const selectedAtlassianRecoveryProfileId = (searchParams: URLSearchParams): string | null => {\n const values = searchParams.getAll(\"atlassianRecoveryProfile\")\n if (values.length !== 1) return null\n const [value] = values\n return value !== undefined && value.length > 0 && value.length <= 500 && value.trim() === value\n ? value\n : null\n}\n\n/** Atlassian site pinned by a bounded, untrusted browser query parameter. */\nexport const selectedAtlassianOAuthSiteId = (searchParams: URLSearchParams): string | null => {\n const sites = searchParams.getAll(\"atlassianSite\")\n if (sites.length !== 1) return null\n const [siteId] = sites\n return siteId !== undefined && siteId.length > 0 && siteId.length <= 512 && siteId.trim() === siteId ? siteId : null\n}\n\n/** Completed Atlassian profile selected by a bounded, untrusted browser query parameter. */\nexport const selectedAtlassianOAuthProfileId = (searchParams: URLSearchParams): string | null => {\n const profiles = searchParams.getAll(\"atlassianProfile\")\n if (profiles.length !== 1) return null\n const [profileId] = profiles\n return profileId !== undefined && profileId.length > 0 && profileId.length <= 500 && profileId.trim() === profileId\n ? profileId\n : null\n}\n\n/** Atlassian product intent selected by repeated, untrusted browser query parameters. */\nexport const selectedAtlassianOAuthProviders = (\n searchParams: URLSearchParams\n): AtlassianOAuthProviderIntent | null => {\n const providers = searchParams.getAll(\"atlassianProvider\")\n if (providers.length === 1 && providers[0] === \"jira\") return [\"jira\"]\n if (providers.length === 1 && providers[0] === \"confluence\") return [\"confluence\"]\n if (providers.length === 2 && providers.includes(\"jira\") && providers.includes(\"confluence\")) {\n return [\"jira\", \"confluence\"]\n }\n return null\n}\n"],"mappings":"qFAKyC,EAAc,CACrD,WAAY,EACZ,YAAa,EACb,YAAa,CACf,CAAC,CAAC,CAAC,SAAS,CAAE,WAAY,2BAA4B,CAAC,EAMvD,IAAa,EAAsC,CACjD,WAAY,CACV,WAAY,aACZ,YAAa,aACb,YAAa,wDACf,EACA,aAAc,CACZ,WAAY,eACZ,YAAa,eACb,YAAa,0DACf,EACA,KAAM,CACJ,WAAY,OACZ,YAAa,OACb,YAAa,uCACf,EACA,WAAY,CACV,WAAY,aACZ,YAAa,aACb,YAAa,mDACf,EACA,SAAU,CACR,WAAY,WACZ,YAAa,WACb,YAAa,oFACf,CACF,EAGa,EAA8B,CACzC,EAAoC,WACpC,EAAoC,aACpC,EAAoC,KACpC,EAAoC,WACpC,EAAoC,QACtC,EC3CM,EAAgB,GACpB,EAA4B,MAAM,CAAE,gBAAiB,IAAe,CAAK,CAAC,EAAE,YAAc,KAG/E,EAAsB,GAAmC,iBAAiB,IAG1E,GAA2B,EAA+B,IACrE,EAAa,EAAa,IAAI,CAAG,CAAC,EAGvB,EAAoB,GAAmC,oBAAoB,IAG3E,GACX,EACA,EAA2B,KAC3B,EAAiC,OACtB,CACX,IAAM,EAAe,IAAI,gBAAgB,CAAE,OAAQ,EAAU,SAAS,MAAM,EAAI,OAAS,YAAa,CAAC,EACnG,IAAc,MAAM,EAAa,IAAI,mBAAoB,CAAS,EAClE,IAAoB,MAAM,EAAa,IAAI,gBAAiB,CAAe,EAC/E,IAAK,IAAM,KAAY,EAAW,EAAa,OAAO,oBAAqB,CAAQ,EACnF,MAAO,aAAa,EAAa,SAAS,GAC5C,EAGa,GACX,EACA,IAMO,aAAa,IAJK,gBAAgB,CACvC,4BAA6B,EAC7B,yBAA0B,CAC5B,CACoB,CAAA,CAAa,SAAS,IAI/B,EACX,GACkC,CAClC,IAAM,EAAS,EAAa,OAAO,6BAA6B,EAChE,GAAI,EAAO,SAAW,EAAG,OAAO,KAChC,IAAM,EAAU,EAA2B,CAAkB,CAAC,CAAC,EAAO,EAAE,EACxE,OAAO,EAAiB,CAAO,EAAI,EAAQ,QAAU,IACvD,EAGa,EAAsC,GAAiD,CAClG,IAAM,EAAS,EAAa,OAAO,0BAA0B,EAC7D,GAAI,EAAO,SAAW,EAAG,OAAO,KAChC,GAAM,CAAC,GAAS,EAChB,OAAO,IAAU,IAAA,IAAa,EAAM,OAAS,GAAK,EAAM,QAAU,KAAO,EAAM,KAAK,IAAM,EACtF,EACA,IACN,EAGa,EAAgC,GAAiD,CAC5F,IAAM,EAAQ,EAAa,OAAO,eAAe,EACjD,GAAI,EAAM,SAAW,EAAG,OAAO,KAC/B,GAAM,CAAC,GAAU,EACjB,OAAO,IAAW,IAAA,IAAa,EAAO,OAAS,GAAK,EAAO,QAAU,KAAO,EAAO,KAAK,IAAM,EAAS,EAAS,IAClH,EAGa,EAAmC,GAAiD,CAC/F,IAAM,EAAW,EAAa,OAAO,kBAAkB,EACvD,GAAI,EAAS,SAAW,EAAG,OAAO,KAClC,GAAM,CAAC,GAAa,EACpB,OAAO,IAAc,IAAA,IAAa,EAAU,OAAS,GAAK,EAAU,QAAU,KAAO,EAAU,KAAK,IAAM,EACtG,EACA,IACN,EAGa,EACX,GACwC,CACxC,IAAM,EAAY,EAAa,OAAO,mBAAmB,EAMzD,OALI,EAAU,SAAW,GAAK,EAAU,KAAO,OAAe,CAAC,MAAM,EACjE,EAAU,SAAW,GAAK,EAAU,KAAO,aAAqB,CAAC,YAAY,EAC7E,EAAU,SAAW,GAAK,EAAU,SAAS,MAAM,GAAK,EAAU,SAAS,YAAY,EAClF,CAAC,OAAQ,YAAY,EAEvB,IACT"}
1
+ {"version":3,"file":"serviceOnboarding-F9Lj6a7y.js","names":[],"sources":["../../../src/domain/firstPartyServices.ts","../../../src/client/services/serviceOnboarding.ts"],"sourcesContent":["import * as Schema from \"effect/Schema\"\n\nimport { ProviderId } from \"./sourceRevision.js\"\n\n/** Safe provider identity rendered before a browser has access to workspace connections. */\nexport const FirstPartyServiceIdentity = Schema.Struct({\n providerId: ProviderId,\n displayName: Schema.String,\n description: Schema.String\n}).annotate({ identifier: \"FirstPartyServiceIdentity\" })\n\n/** Decoded safe first-party provider identity. */\nexport type FirstPartyServiceIdentity = typeof FirstPartyServiceIdentity.Type\n\n/** Stable provider lookup shared by public previews and the server-owned setup catalog. */\nexport const firstPartyServiceIdentityByProvider = {\n codecommit: {\n providerId: \"codecommit\",\n displayName: \"CodeCommit\",\n description: \"Read pull requests from one AWS CodeCommit repository.\"\n },\n codepipeline: {\n providerId: \"codepipeline\",\n displayName: \"CodePipeline\",\n description: \"Read pipeline and execution state from AWS CodePipeline.\"\n },\n jira: {\n providerId: \"jira\",\n displayName: \"Jira\",\n description: \"Read delivery issues from Jira Cloud.\"\n },\n confluence: {\n providerId: \"confluence\",\n displayName: \"Confluence\",\n description: \"Read release documentation from Confluence Cloud.\"\n },\n clockify: {\n providerId: \"clockify\",\n displayName: \"Clockify\",\n description: \"Read bounded time-entry evidence and govern association corrections and approvals.\"\n }\n} satisfies Readonly<Record<typeof ProviderId.Type, FirstPartyServiceIdentity>>\n\n/** Stable first-party services available to every Control Center installation. */\nexport const firstPartyServiceIdentities = [\n firstPartyServiceIdentityByProvider.codecommit,\n firstPartyServiceIdentityByProvider.codepipeline,\n firstPartyServiceIdentityByProvider.jira,\n firstPartyServiceIdentityByProvider.confluence,\n firstPartyServiceIdentityByProvider.clockify\n] satisfies ReadonlyArray<FirstPartyServiceIdentity>\n","import * as Result from \"effect/Result\"\nimport * as Schema from \"effect/Schema\"\nimport type { AtlassianOAuthProviderIntent } from \"../../api/plugins.js\"\nimport { firstPartyServiceIdentities } from \"../../domain/firstPartyServices.js\"\nimport { PluginConnectionId, type PluginConnectionId as PluginConnectionIdType } from \"../../domain/identifiers.js\"\nimport type { ProviderId } from \"../../domain/sourceRevision.js\"\n\nconst providerFrom = (value: string | null): ProviderId | null =>\n firstPartyServiceIdentities.find(({ providerId }) => providerId === value)?.providerId ?? null\n\n/** Pairing route that remembers which service the person chose to enable. */\nexport const servicePairingPath = (providerId: ProviderId): string => `/pair?service=${providerId}`\n\n/** Service selected by an untrusted browser query parameter. */\nexport const selectedServiceProvider = (searchParams: URLSearchParams, key: \"enable\" | \"service\"): ProviderId | null =>\n providerFrom(searchParams.get(key))\n\n/** Post-pairing destination that opens the selected service setup in place. */\nexport const serviceSetupPath = (providerId: ProviderId): string => `/services?enable=${providerId}`\n\n/** Atlassian setup destination that preserves the initiating products and, when present, the completed profile. */\nexport const atlassianOAuthSetupPath = (\n providers: AtlassianOAuthProviderIntent,\n profileId: string | null = null,\n preferredSiteId: string | null = null\n): string => {\n const searchParams = new URLSearchParams({ enable: providers.includes(\"jira\") ? \"jira\" : \"confluence\" })\n if (profileId !== null) searchParams.set(\"atlassianProfile\", profileId)\n if (preferredSiteId !== null) searchParams.set(\"atlassianSite\", preferredSiteId)\n for (const provider of providers) searchParams.append(\"atlassianProvider\", provider)\n return `/services?${searchParams.toString()}`\n}\n\n/** Post-callback destination that applies a new local OAuth profile to one existing connection. */\nexport const atlassianOAuthRecoveryPath = (\n pluginConnectionId: PluginConnectionIdType,\n profileId: string\n): string => {\n const searchParams = new URLSearchParams({\n atlassianRecoveryConnection: pluginConnectionId,\n atlassianRecoveryProfile: profileId\n })\n return `/services?${searchParams.toString()}`\n}\n\n/** Existing connection selected for an exact OAuth recovery handoff. */\nexport const selectedAtlassianRecoveryConnectionId = (\n searchParams: URLSearchParams\n): PluginConnectionIdType | null => {\n const values = searchParams.getAll(\"atlassianRecoveryConnection\")\n if (values.length !== 1) return null\n const decoded = Schema.decodeUnknownResult(PluginConnectionId)(values[0])\n return Result.isSuccess(decoded) ? decoded.success : null\n}\n\n/** Completed local OAuth profile selected for an exact recovery handoff. */\nexport const selectedAtlassianRecoveryProfileId = (searchParams: URLSearchParams): string | null => {\n const values = searchParams.getAll(\"atlassianRecoveryProfile\")\n if (values.length !== 1) return null\n const [value] = values\n return value !== undefined && value.length > 0 && value.length <= 500 && value.trim() === value\n ? value\n : null\n}\n\n/** Atlassian site pinned by a bounded, untrusted browser query parameter. */\nexport const selectedAtlassianOAuthSiteId = (searchParams: URLSearchParams): string | null => {\n const sites = searchParams.getAll(\"atlassianSite\")\n if (sites.length !== 1) return null\n const [siteId] = sites\n return siteId !== undefined && siteId.length > 0 && siteId.length <= 512 && siteId.trim() === siteId ? siteId : null\n}\n\n/** Completed Atlassian profile selected by a bounded, untrusted browser query parameter. */\nexport const selectedAtlassianOAuthProfileId = (searchParams: URLSearchParams): string | null => {\n const profiles = searchParams.getAll(\"atlassianProfile\")\n if (profiles.length !== 1) return null\n const [profileId] = profiles\n return profileId !== undefined && profileId.length > 0 && profileId.length <= 500 && profileId.trim() === profileId\n ? profileId\n : null\n}\n\n/** Atlassian product intent selected by repeated, untrusted browser query parameters. */\nexport const selectedAtlassianOAuthProviders = (\n searchParams: URLSearchParams\n): AtlassianOAuthProviderIntent | null => {\n const providers = searchParams.getAll(\"atlassianProvider\")\n if (providers.length === 1 && providers[0] === \"jira\") return [\"jira\"]\n if (providers.length === 1 && providers[0] === \"confluence\") return [\"confluence\"]\n if (providers.length === 2 && providers.includes(\"jira\") && providers.includes(\"confluence\")) {\n return [\"jira\", \"confluence\"]\n }\n return null\n}\n"],"mappings":"qFAKyC,EAAc,CACrD,WAAY,EACZ,YAAa,EACb,YAAa,CACf,CAAC,CAAC,CAAC,SAAS,CAAE,WAAY,2BAA4B,CAAC,EAMvD,IAAa,EAAsC,CACjD,WAAY,CACV,WAAY,aACZ,YAAa,aACb,YAAa,wDACf,EACA,aAAc,CACZ,WAAY,eACZ,YAAa,eACb,YAAa,0DACf,EACA,KAAM,CACJ,WAAY,OACZ,YAAa,OACb,YAAa,uCACf,EACA,WAAY,CACV,WAAY,aACZ,YAAa,aACb,YAAa,mDACf,EACA,SAAU,CACR,WAAY,WACZ,YAAa,WACb,YAAa,oFACf,CACF,EAGa,EAA8B,CACzC,EAAoC,WACpC,EAAoC,aACpC,EAAoC,KACpC,EAAoC,WACpC,EAAoC,QACtC,EC3CM,EAAgB,GACpB,EAA4B,MAAM,CAAE,gBAAiB,IAAe,CAAK,CAAC,EAAE,YAAc,KAG/E,EAAsB,GAAmC,iBAAiB,IAG1E,GAA2B,EAA+B,IACrE,EAAa,EAAa,IAAI,CAAG,CAAC,EAGvB,EAAoB,GAAmC,oBAAoB,IAG3E,GACX,EACA,EAA2B,KAC3B,EAAiC,OACtB,CACX,IAAM,EAAe,IAAI,gBAAgB,CAAE,OAAQ,EAAU,SAAS,MAAM,EAAI,OAAS,YAAa,CAAC,EACnG,IAAc,MAAM,EAAa,IAAI,mBAAoB,CAAS,EAClE,IAAoB,MAAM,EAAa,IAAI,gBAAiB,CAAe,EAC/E,IAAK,IAAM,KAAY,EAAW,EAAa,OAAO,oBAAqB,CAAQ,EACnF,MAAO,aAAa,EAAa,SAAS,GAC5C,EAGa,GACX,EACA,IAMO,aAAa,IAJK,gBAAgB,CACvC,4BAA6B,EAC7B,yBAA0B,CAC5B,CACoB,CAAA,CAAa,SAAS,IAI/B,EACX,GACkC,CAClC,IAAM,EAAS,EAAa,OAAO,6BAA6B,EAChE,GAAI,EAAO,SAAW,EAAG,OAAO,KAChC,IAAM,EAAU,EAA2B,CAAkB,CAAC,CAAC,EAAO,EAAE,EACxE,OAAO,EAAiB,CAAO,EAAI,EAAQ,QAAU,IACvD,EAGa,EAAsC,GAAiD,CAClG,IAAM,EAAS,EAAa,OAAO,0BAA0B,EAC7D,GAAI,EAAO,SAAW,EAAG,OAAO,KAChC,GAAM,CAAC,GAAS,EAChB,OAAO,IAAU,IAAA,IAAa,EAAM,OAAS,GAAK,EAAM,QAAU,KAAO,EAAM,KAAK,IAAM,EACtF,EACA,IACN,EAGa,EAAgC,GAAiD,CAC5F,IAAM,EAAQ,EAAa,OAAO,eAAe,EACjD,GAAI,EAAM,SAAW,EAAG,OAAO,KAC/B,GAAM,CAAC,GAAU,EACjB,OAAO,IAAW,IAAA,IAAa,EAAO,OAAS,GAAK,EAAO,QAAU,KAAO,EAAO,KAAK,IAAM,EAAS,EAAS,IAClH,EAGa,EAAmC,GAAiD,CAC/F,IAAM,EAAW,EAAa,OAAO,kBAAkB,EACvD,GAAI,EAAS,SAAW,EAAG,OAAO,KAClC,GAAM,CAAC,GAAa,EACpB,OAAO,IAAc,IAAA,IAAa,EAAU,OAAS,GAAK,EAAU,QAAU,KAAO,EAAU,KAAK,IAAM,EACtG,EACA,IACN,EAGa,EACX,GACwC,CACxC,IAAM,EAAY,EAAa,OAAO,mBAAmB,EAMzD,OALI,EAAU,SAAW,GAAK,EAAU,KAAO,OAAe,CAAC,MAAM,EACjE,EAAU,SAAW,GAAK,EAAU,KAAO,aAAqB,CAAC,YAAY,EAC7E,EAAU,SAAW,GAAK,EAAU,SAAS,MAAM,GAAK,EAAU,SAAS,YAAY,EAClF,CAAC,OAAQ,YAAY,EAEvB,IACT"}
@@ -0,0 +1,3 @@
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/workspaceSettingsTransport-BwRQteEH.js","assets/agent-api-CUWP1qs8.js","assets/client-D3WRV6yl.js","assets/Domain-cJ5aJFpE.js","assets/BrowserCrypto-CoBR2WBd.js","assets/authenticatedMutationClient-Bc_-Jpbo.js"])))=>i.map(i=>d[i]);
2
+ import{r as e}from"./rolldown-runtime-hePW80VL.js";import{t}from"./react-CwJFpaho.js";import{t as n}from"./preload-helper-Czpn1I53.js";import{i as r,o as i}from"./releasePaths-XoI2BHX3.js";import{f as a,i as o,o as s,p as c}from"./index-kmYFvwT0.js";import{Ya as l}from"./agent-api-CUWP1qs8.js";import"./releaseRoutes-h4FVwFvJ.js";var u=e(t(),1),d=l(`UnauthorizedApiError`),f=(e,t)=>t===`active-work`?i(e):r(e),p={load:async e=>{let{browserWorkspacePresentationTransport:t}=await n(async()=>{let{browserWorkspacePresentationTransport:e}=await import(`./workspaceSettingsTransport-BwRQteEH.js`);return{browserWorkspacePresentationTransport:e}},__vite__mapDeps([0,1,2,3,4,5]));return t.load(e)}},m=(e,t=p)=>{let{invalidateSession:n,state:i}=c(),l=a(i),m=i._tag===`authenticated`||i._tag===`storage-unavailable`?i.session?.workspaceId??null:null,h=e!==null&&m===e?l:null,[g,_]=(0,u.useState)(null);return(0,u.useEffect)(()=>s(t=>{e!==null&&h!==null&&t.workspaceId===e&&_(n=>n?.sessionKey===h&&n.workspaceId===e&&n.revision>t.revision?n:{path:f(e,t.presentation.defaultLanding),revision:t.revision,sessionKey:h,workspaceId:e})}),[h,e]),(0,u.useEffect)(()=>{if(e===null||h===null){_(null);return}let i=new AbortController;return t.load(i.signal).then(t=>{i.signal.aborted||t.workspaceId!==e||(o(t),_(n=>n?.sessionKey===h&&n.workspaceId===e&&n.revision>t.revision?n:{path:f(e,t.presentation.defaultLanding),revision:t.revision,sessionKey:h,workspaceId:e}))},t=>{i.signal.aborted||(d(t)&&n(h),_(t=>t?.sessionKey===h&&t.workspaceId===e?t:{path:r(e),revision:0,sessionKey:h,workspaceId:e}))}),()=>i.abort()},[n,h,t,e]),g?.sessionKey===h&&g.workspaceId===e?g.path:null};export{m as t};
3
+ //# sourceMappingURL=useWorkspaceDefaultLanding-BmaR7aTj.js.map
@@ -1 +1 @@
1
- {"version":3,"mappings":";0VAUM,EAAiB,EAAmB,sBAAsB,EAGnD,GACX,EACA,IAEA,IAAmB,cACf,EAAwB,CAAW,EACnC,EAAkB,CAAW,EAS7B,EAA4E,CAChF,KAAM,KAAO,IAAW,CACtB,GAAM,CAAE,2DAAF,IAAE,yCAA0C,MAAM,OACtD,2HAEF,OAAO,EAAsC,KAAK,CAAM,CAC1D,CACF,EAGa,GACX,EACA,EAA4C,IAC1B,CAClB,GAAM,CAAE,oBAAmB,MAAO,GAAmB,EAAkB,EACjE,EAAqB,EAA0B,CAAc,EAC7D,EAAqB,EAAe,OAAS,iBAC/C,EAAe,OAAS,sBACxB,EAAe,SAAS,aAAe,KACvC,KACE,EAAa,IAAgB,MAAQ,IAAuB,EAC9D,EACA,KACE,CAAC,EAAQ,MAAa,YAA+B,IAAI,EA0E/D,OAxEA,mBACE,EAAgC,GAAa,CAEzC,IAAgB,MAChB,IAAe,MACf,EAAS,cAAgB,GAE3B,EAAW,GAEP,GAAS,aAAe,GACxB,EAAQ,cAAgB,GACxB,EAAQ,SAAW,EAAS,SACrB,EACF,CACL,KAAM,EACJ,EACA,EAAS,aAAa,cACxB,EACA,SAAU,EAAS,SACnB,aACA,aACF,CACD,CACH,CAAC,EAAG,CAAC,EAAY,CAAW,CAAC,GAE/B,mBAAgB,CACd,GAAI,IAAgB,MAAQ,IAAe,KAAM,CAC/C,EAAU,IAAI,EACd,MACF,CACA,IAAM,EAAU,IAAI,gBAuCpB,OAtCA,EAAU,KAAK,EAAQ,MAAM,CAAC,CAAC,KAC5B,GAAa,CACR,EAAQ,OAAO,SAAW,EAAS,cAAgB,IACvD,EAA6B,CAAQ,EACrC,EAAW,GAEP,GAAS,aAAe,GACxB,EAAQ,cAAgB,GACxB,EAAQ,SAAW,EAAS,SACrB,EACF,CACL,KAAM,EACJ,EACA,EAAS,aAAa,cACxB,EACA,SAAU,EAAS,SACnB,aACA,aACF,CACD,EACH,EACC,GAAY,CACP,EAAQ,OAAO,UACf,EAAe,CAAO,GAAG,EAAkB,CAAU,EACzD,EAAW,GAEP,GAAS,aAAe,GACxB,EAAQ,cAAgB,EACjB,EACF,CACL,KAAM,EAAkB,CAAW,EACnC,SAAU,EACV,aACA,aACF,CACD,EACH,CACF,MACa,EAAQ,MAAM,CAC7B,EAAG,CAAC,EAAmB,EAAY,EAAW,CAAW,CAAC,EAEnD,GAAQ,aAAe,GAAc,EAAO,cAAgB,EAC/D,EAAO,KACP,IACN","names":[],"ignoreList":[],"sources":["../../../src/client/settings/useWorkspaceDefaultLanding.ts"],"sourcesContent":["import * as Predicate from \"effect/Predicate\"\nimport { useEffect, useState } from \"react\"\n\nimport type { WorkspacePresentationReadModel } from \"../../api/workspaceSettings.js\"\nimport type { WorkspaceId } from \"../../domain/identifiers.js\"\nimport { browserReadableSessionKey, useBrowserSession } from \"../BrowserSession.js\"\nimport { releaseParentPath, workspaceActiveWorkPath } from \"../releases/releaseRoutes.js\"\nimport { publishWorkspacePresentation, subscribeWorkspacePresentation } from \"./workspaceSettingsSignals.js\"\nimport type { WorkspacePresentationTransport } from \"./workspaceSettingsTransport.js\"\n\nconst isUnauthorized = Predicate.isTagged(\"UnauthorizedApiError\")\n\n/** Resolve the configured home destination without redirecting deep links. */\nexport const workspaceDefaultLandingPath = (\n workspaceId: WorkspaceId,\n defaultLanding: WorkspacePresentationReadModel[\"presentation\"][\"defaultLanding\"]\n): string =>\n defaultLanding === \"active-work\"\n ? workspaceActiveWorkPath(workspaceId)\n : releaseParentPath(workspaceId)\n\ninterface LoadedLanding {\n readonly path: string\n readonly revision: number\n readonly sessionKey: string\n readonly workspaceId: WorkspaceId\n}\n\nconst lazyBrowserWorkspacePresentationTransport: WorkspacePresentationTransport = {\n load: async (signal) => {\n const { browserWorkspacePresentationTransport } = await import(\n \"./workspaceSettingsTransport.js\"\n )\n return browserWorkspacePresentationTransport.load(signal)\n }\n}\n\n/** Read one workspace's server-owned home destination for brand and root navigation. */\nexport const useWorkspaceDefaultLandingPath = (\n workspaceId: WorkspaceId | null,\n transport: WorkspacePresentationTransport = lazyBrowserWorkspacePresentationTransport\n): string | null => {\n const { invalidateSession, state: browserSession } = useBrowserSession()\n const readableSessionKey = browserReadableSessionKey(browserSession)\n const browserWorkspaceId = browserSession._tag === \"authenticated\" ||\n browserSession._tag === \"storage-unavailable\"\n ? browserSession.session?.workspaceId ?? null\n : null\n const sessionKey = workspaceId !== null && browserWorkspaceId === workspaceId\n ? readableSessionKey\n : null\n const [loaded, setLoaded] = useState<LoadedLanding | null>(null)\n\n useEffect(() =>\n subscribeWorkspacePresentation((settings) => {\n if (\n workspaceId === null ||\n sessionKey === null ||\n settings.workspaceId !== workspaceId\n ) return\n setLoaded((current) => {\n if (\n current?.sessionKey === sessionKey &&\n current.workspaceId === workspaceId &&\n current.revision > settings.revision\n ) return current\n return {\n path: workspaceDefaultLandingPath(\n workspaceId,\n settings.presentation.defaultLanding\n ),\n revision: settings.revision,\n sessionKey,\n workspaceId\n }\n })\n }), [sessionKey, workspaceId])\n\n useEffect(() => {\n if (workspaceId === null || sessionKey === null) {\n setLoaded(null)\n return\n }\n const request = new AbortController()\n transport.load(request.signal).then(\n (settings) => {\n if (request.signal.aborted || settings.workspaceId !== workspaceId) return\n publishWorkspacePresentation(settings)\n setLoaded((current) => {\n if (\n current?.sessionKey === sessionKey &&\n current.workspaceId === workspaceId &&\n current.revision > settings.revision\n ) return current\n return {\n path: workspaceDefaultLandingPath(\n workspaceId,\n settings.presentation.defaultLanding\n ),\n revision: settings.revision,\n sessionKey,\n workspaceId\n }\n })\n },\n (failure) => {\n if (request.signal.aborted) return\n if (isUnauthorized(failure)) invalidateSession(sessionKey)\n setLoaded((current) => {\n if (\n current?.sessionKey === sessionKey &&\n current.workspaceId === workspaceId\n ) return current\n return {\n path: releaseParentPath(workspaceId),\n revision: 0,\n sessionKey,\n workspaceId\n }\n })\n }\n )\n return () => request.abort()\n }, [invalidateSession, sessionKey, transport, workspaceId])\n\n return loaded?.sessionKey === sessionKey && loaded.workspaceId === workspaceId\n ? loaded.path\n : null\n}\n"],"file":"useWorkspaceDefaultLanding-C3PRrLgk.js"}
1
+ {"version":3,"mappings":";0VAUM,EAAiB,EAAmB,sBAAsB,EAGnD,GACX,EACA,IAEA,IAAmB,cACf,EAAwB,CAAW,EACnC,EAAkB,CAAW,EAS7B,EAA4E,CAChF,KAAM,KAAO,IAAW,CACtB,GAAM,CAAE,2DAAF,IAAE,yCAA0C,MAAM,OACtD,6HAEF,OAAO,EAAsC,KAAK,CAAM,CAC1D,CACF,EAGa,GACX,EACA,EAA4C,IAC1B,CAClB,GAAM,CAAE,oBAAmB,MAAO,GAAmB,EAAkB,EACjE,EAAqB,EAA0B,CAAc,EAC7D,EAAqB,EAAe,OAAS,iBAC/C,EAAe,OAAS,sBACxB,EAAe,SAAS,aAAe,KACvC,KACE,EAAa,IAAgB,MAAQ,IAAuB,EAC9D,EACA,KACE,CAAC,EAAQ,MAAa,YAA+B,IAAI,EA0E/D,OAxEA,mBACE,EAAgC,GAAa,CAEzC,IAAgB,MAChB,IAAe,MACf,EAAS,cAAgB,GAE3B,EAAW,GAEP,GAAS,aAAe,GACxB,EAAQ,cAAgB,GACxB,EAAQ,SAAW,EAAS,SACrB,EACF,CACL,KAAM,EACJ,EACA,EAAS,aAAa,cACxB,EACA,SAAU,EAAS,SACnB,aACA,aACF,CACD,CACH,CAAC,EAAG,CAAC,EAAY,CAAW,CAAC,GAE/B,mBAAgB,CACd,GAAI,IAAgB,MAAQ,IAAe,KAAM,CAC/C,EAAU,IAAI,EACd,MACF,CACA,IAAM,EAAU,IAAI,gBAuCpB,OAtCA,EAAU,KAAK,EAAQ,MAAM,CAAC,CAAC,KAC5B,GAAa,CACR,EAAQ,OAAO,SAAW,EAAS,cAAgB,IACvD,EAA6B,CAAQ,EACrC,EAAW,GAEP,GAAS,aAAe,GACxB,EAAQ,cAAgB,GACxB,EAAQ,SAAW,EAAS,SACrB,EACF,CACL,KAAM,EACJ,EACA,EAAS,aAAa,cACxB,EACA,SAAU,EAAS,SACnB,aACA,aACF,CACD,EACH,EACC,GAAY,CACP,EAAQ,OAAO,UACf,EAAe,CAAO,GAAG,EAAkB,CAAU,EACzD,EAAW,GAEP,GAAS,aAAe,GACxB,EAAQ,cAAgB,EACjB,EACF,CACL,KAAM,EAAkB,CAAW,EACnC,SAAU,EACV,aACA,aACF,CACD,EACH,CACF,MACa,EAAQ,MAAM,CAC7B,EAAG,CAAC,EAAmB,EAAY,EAAW,CAAW,CAAC,EAEnD,GAAQ,aAAe,GAAc,EAAO,cAAgB,EAC/D,EAAO,KACP,IACN","names":[],"ignoreList":[],"sources":["../../../src/client/settings/useWorkspaceDefaultLanding.ts"],"sourcesContent":["import * as Predicate from \"effect/Predicate\"\nimport { useEffect, useState } from \"react\"\n\nimport type { WorkspacePresentationReadModel } from \"../../api/workspaceSettings.js\"\nimport type { WorkspaceId } from \"../../domain/identifiers.js\"\nimport { browserReadableSessionKey, useBrowserSession } from \"../BrowserSession.js\"\nimport { releaseParentPath, workspaceActiveWorkPath } from \"../releases/releaseRoutes.js\"\nimport { publishWorkspacePresentation, subscribeWorkspacePresentation } from \"./workspaceSettingsSignals.js\"\nimport type { WorkspacePresentationTransport } from \"./workspaceSettingsTransport.js\"\n\nconst isUnauthorized = Predicate.isTagged(\"UnauthorizedApiError\")\n\n/** Resolve the configured home destination without redirecting deep links. */\nexport const workspaceDefaultLandingPath = (\n workspaceId: WorkspaceId,\n defaultLanding: WorkspacePresentationReadModel[\"presentation\"][\"defaultLanding\"]\n): string =>\n defaultLanding === \"active-work\"\n ? workspaceActiveWorkPath(workspaceId)\n : releaseParentPath(workspaceId)\n\ninterface LoadedLanding {\n readonly path: string\n readonly revision: number\n readonly sessionKey: string\n readonly workspaceId: WorkspaceId\n}\n\nconst lazyBrowserWorkspacePresentationTransport: WorkspacePresentationTransport = {\n load: async (signal) => {\n const { browserWorkspacePresentationTransport } = await import(\n \"./workspaceSettingsTransport.js\"\n )\n return browserWorkspacePresentationTransport.load(signal)\n }\n}\n\n/** Read one workspace's server-owned home destination for brand and root navigation. */\nexport const useWorkspaceDefaultLandingPath = (\n workspaceId: WorkspaceId | null,\n transport: WorkspacePresentationTransport = lazyBrowserWorkspacePresentationTransport\n): string | null => {\n const { invalidateSession, state: browserSession } = useBrowserSession()\n const readableSessionKey = browserReadableSessionKey(browserSession)\n const browserWorkspaceId = browserSession._tag === \"authenticated\" ||\n browserSession._tag === \"storage-unavailable\"\n ? browserSession.session?.workspaceId ?? null\n : null\n const sessionKey = workspaceId !== null && browserWorkspaceId === workspaceId\n ? readableSessionKey\n : null\n const [loaded, setLoaded] = useState<LoadedLanding | null>(null)\n\n useEffect(() =>\n subscribeWorkspacePresentation((settings) => {\n if (\n workspaceId === null ||\n sessionKey === null ||\n settings.workspaceId !== workspaceId\n ) return\n setLoaded((current) => {\n if (\n current?.sessionKey === sessionKey &&\n current.workspaceId === workspaceId &&\n current.revision > settings.revision\n ) return current\n return {\n path: workspaceDefaultLandingPath(\n workspaceId,\n settings.presentation.defaultLanding\n ),\n revision: settings.revision,\n sessionKey,\n workspaceId\n }\n })\n }), [sessionKey, workspaceId])\n\n useEffect(() => {\n if (workspaceId === null || sessionKey === null) {\n setLoaded(null)\n return\n }\n const request = new AbortController()\n transport.load(request.signal).then(\n (settings) => {\n if (request.signal.aborted || settings.workspaceId !== workspaceId) return\n publishWorkspacePresentation(settings)\n setLoaded((current) => {\n if (\n current?.sessionKey === sessionKey &&\n current.workspaceId === workspaceId &&\n current.revision > settings.revision\n ) return current\n return {\n path: workspaceDefaultLandingPath(\n workspaceId,\n settings.presentation.defaultLanding\n ),\n revision: settings.revision,\n sessionKey,\n workspaceId\n }\n })\n },\n (failure) => {\n if (request.signal.aborted) return\n if (isUnauthorized(failure)) invalidateSession(sessionKey)\n setLoaded((current) => {\n if (\n current?.sessionKey === sessionKey &&\n current.workspaceId === workspaceId\n ) return current\n return {\n path: releaseParentPath(workspaceId),\n revision: 0,\n sessionKey,\n workspaceId\n }\n })\n }\n )\n return () => request.abort()\n }, [invalidateSession, sessionKey, transport, workspaceId])\n\n return loaded?.sessionKey === sessionKey && loaded.workspaceId === workspaceId\n ? loaded.path\n : null\n}\n"],"file":"useWorkspaceDefaultLanding-BmaR7aTj.js"}
@@ -0,0 +1,2 @@
1
+ import{r as e}from"./rolldown-runtime-hePW80VL.js";import{t}from"./react-CwJFpaho.js";import{Ti as n,Ya as r,_i as i,ki as a}from"./agent-api-CUWP1qs8.js";import{a as o,t as s}from"./client-D3WRV6yl.js";import{t as c}from"./presentWorkspaceItems-BY8bmqjF.js";var l=e(t(),1),u=r(`UnauthorizedApiError`),d={load:(e,t)=>a(i(function*(){return yield*(yield*s()).deliveryGraph.workspaceEntityProjections({query:{...t.query.length!==0&&{q:t.query},...t.owner!==`all`&&{owner:t.owner},...t.service!==`all`&&{service:t.service},...t.status!==`all`&&{status:t.status},...t.type!==`all`&&{type:t.type}}})}).pipe(n(o)),{signal:e})},f=(e,t,n,r,i,a,o=d)=>{let[s,f]=(0,l.useState)(0),[p,m]=(0,l.useState)({_tag:`idle`}),h=[...t].join(`:`),g=(0,l.useMemo)(()=>({owner:n.owner,query:n.query,service:n.service,status:n.status,type:n.type}),[n.owner,n.query,n.service,n.status,n.type]),_=`${e}|${h}|${r}|${`${g.query}|${g.owner}|${g.service}|${g.status}|${g.type}`}`;(0,l.useEffect)(()=>{if(i===null){m({_tag:`idle`});return}let n=new AbortController;return m(e=>e._tag===`ready`&&e.sessionKey===i?e:{_tag:`loading`,scopeKey:_,sessionKey:i}),o.load(n.signal,g).then(r=>{n.signal.aborted||m({_tag:`ready`,items:c(e,r,t),matchedCount:r.matchedCount,ownerOptions:r.ownerOptions,ownerOptionsTruncated:r.ownerOptionsTruncated,refreshing:!1,scopeKey:_,sessionKey:i,totalCount:r.totalCount,truncated:r.truncated})},e=>{n.signal.aborted||(u(e)&&a(i),m({_tag:`failed`,scopeKey:_,sessionKey:i}))}),()=>n.abort()},[a,g,s,t,_,i,o,e]);let v=i===null?{_tag:`idle`}:p._tag===`idle`||p.sessionKey!==i?{_tag:`loading`,scopeKey:_,sessionKey:i}:p._tag===`ready`&&p.scopeKey!==_?{...p,refreshing:!0}:p._tag!==`ready`&&p.scopeKey!==_?{_tag:`loading`,scopeKey:_,sessionKey:i}:p;return{retry:(0,l.useCallback)(()=>f(e=>e+1),[]),state:v}};export{f as n,d as t};
2
+ //# sourceMappingURL=useWorkspaceItems-6KWfmFtx.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useWorkspaceItems-CHYpfLmL.js","names":[],"sources":["../../../src/client/items/useWorkspaceItems.ts"],"sourcesContent":["import * as Effect from \"effect/Effect\"\nimport * as Predicate from \"effect/Predicate\"\nimport * as FetchHttpClient from \"effect/unstable/http/FetchHttpClient\"\nimport { useCallback, useEffect, useMemo, useState } from \"react\"\n\nimport { makeControlCenterApiClient } from \"../../api/client.js\"\nimport type { WorkspaceEntityProjectionIndex } from \"../../api/deliveryGraph.js\"\nimport type {\n DeliveryEntityKind,\n DeliveryEntityService,\n DeliveryEntityStatusGroup\n} from \"../../domain/deliveryGraph.js\"\nimport type { PersonId, ReleaseId, WorkspaceId } from \"../../domain/identifiers.js\"\nimport { presentWorkspaceEntityIndex, type WorkspaceItemPresentation } from \"./presentWorkspaceItems.js\"\n\nexport type WorkspaceItemsState =\n | { readonly _tag: \"idle\" }\n | { readonly _tag: \"loading\"; readonly scopeKey: string; readonly sessionKey: string }\n | { readonly _tag: \"failed\"; readonly scopeKey: string; readonly sessionKey: string }\n | {\n readonly _tag: \"ready\"\n readonly items: ReadonlyArray<WorkspaceItemPresentation>\n readonly matchedCount: number\n readonly ownerOptions: WorkspaceEntityProjectionIndex[\"ownerOptions\"]\n readonly ownerOptionsTruncated: boolean\n readonly refreshing: boolean\n readonly scopeKey: string\n readonly sessionKey: string\n readonly truncated: boolean\n readonly totalCount: number\n }\n\nexport interface WorkspaceItemsQuery {\n readonly owner: PersonId | \"all\"\n readonly query: string\n readonly service: DeliveryEntityService | \"all\"\n readonly status: DeliveryEntityStatusGroup | \"all\"\n readonly type: DeliveryEntityKind | \"all\"\n}\n\nexport interface WorkspaceItemsTransport {\n readonly load: (signal: AbortSignal, query: WorkspaceItemsQuery) => Promise<WorkspaceEntityProjectionIndex>\n}\n\nconst isUnauthorizedFailure = Predicate.isTagged(\"UnauthorizedApiError\")\n\n/** Generated-client transport for the authenticated workspace entity index. */\nexport const browserWorkspaceItemsTransport: WorkspaceItemsTransport = {\n load: (signal, query) =>\n Effect.runPromise(\n Effect.gen(function*() {\n const client = yield* makeControlCenterApiClient()\n return yield* client.deliveryGraph.workspaceEntityProjections({\n query: {\n ...(!(query.query.length === 0) && { q: query.query }),\n ...(!(query.owner === \"all\") && { owner: query.owner }),\n ...(!(query.service === \"all\") && { service: query.service }),\n ...(!(query.status === \"all\") && { status: query.status }),\n ...(!(query.type === \"all\") && { type: query.type })\n }\n })\n }).pipe(Effect.provide(FetchHttpClient.layer)),\n { signal }\n )\n}\n\n/** Keep one bounded workspace entity index scoped to the exact browser session. */\nexport const useWorkspaceItems = (\n workspaceId: WorkspaceId,\n routableReleaseIds: ReadonlySet<ReleaseId>,\n filters: WorkspaceItemsQuery,\n refreshKey: string,\n sessionKey: string | null,\n onSessionExpired: (sessionKey: string) => void,\n transport: WorkspaceItemsTransport = browserWorkspaceItemsTransport\n) => {\n const [requestRevision, setRequestRevision] = useState(0)\n const [state, setState] = useState<WorkspaceItemsState>({ _tag: \"idle\" })\n const releaseScopeKey = [...routableReleaseIds].join(\":\")\n const query = useMemo<WorkspaceItemsQuery>(() => ({\n owner: filters.owner,\n query: filters.query,\n service: filters.service,\n status: filters.status,\n type: filters.type\n }), [filters.owner, filters.query, filters.service, filters.status, filters.type])\n const filterScopeKey = `${query.query}|${query.owner}|${query.service}|${query.status}|${query.type}`\n const scopeKey = `${workspaceId}|${releaseScopeKey}|${refreshKey}|${filterScopeKey}`\n\n useEffect(() => {\n if (sessionKey === null) {\n setState({ _tag: \"idle\" })\n return\n }\n const abort = new AbortController()\n setState((current) =>\n current._tag === \"ready\" && current.sessionKey === sessionKey\n ? current\n : { _tag: \"loading\", scopeKey, sessionKey }\n )\n transport.load(abort.signal, query).then(\n (index) => {\n if (abort.signal.aborted) return\n setState({\n _tag: \"ready\",\n items: presentWorkspaceEntityIndex(workspaceId, index, routableReleaseIds),\n matchedCount: index.matchedCount,\n ownerOptions: index.ownerOptions,\n ownerOptionsTruncated: index.ownerOptionsTruncated,\n refreshing: false,\n scopeKey,\n sessionKey,\n totalCount: index.totalCount,\n truncated: index.truncated\n })\n },\n (failure) => {\n if (abort.signal.aborted) return\n if (isUnauthorizedFailure(failure)) onSessionExpired(sessionKey)\n setState({ _tag: \"failed\", scopeKey, sessionKey })\n }\n )\n return () => abort.abort()\n }, [onSessionExpired, query, requestRevision, routableReleaseIds, scopeKey, sessionKey, transport, workspaceId])\n\n const currentState: WorkspaceItemsState = sessionKey === null\n ? { _tag: \"idle\" }\n : state._tag === \"idle\" || state.sessionKey !== sessionKey\n ? { _tag: \"loading\", scopeKey, sessionKey }\n : state._tag === \"ready\" && state.scopeKey !== scopeKey\n ? { ...state, refreshing: true }\n : state._tag !== \"ready\" && state.scopeKey !== scopeKey\n ? { _tag: \"loading\", scopeKey, sessionKey }\n : state\n\n return {\n retry: useCallback(() => setRequestRevision((revision) => revision + 1), []),\n state: currentState\n }\n}\n"],"mappings":"6QA4CM,EAAwB,EAAmB,sBAAsB,EAG1D,EAA0D,CACrE,MAAO,EAAQ,IACb,EACE,EAAW,WAAY,CAErB,OAAO,OAAO,MADQ,EAA2B,EAAA,CAC5B,cAAc,2BAA2B,CAC5D,MAAO,CACL,GAAM,EAAM,MAAM,SAAW,GAAM,CAAE,EAAG,EAAM,KAAM,EACpD,GAAM,EAAM,QAAU,OAAU,CAAE,MAAO,EAAM,KAAM,EACrD,GAAM,EAAM,UAAY,OAAU,CAAE,QAAS,EAAM,OAAQ,EAC3D,GAAM,EAAM,SAAW,OAAU,CAAE,OAAQ,EAAM,MAAO,EACxD,GAAM,EAAM,OAAS,OAAU,CAAE,KAAM,EAAM,IAAK,CACpD,CACF,CAAC,CACH,CAAC,CAAC,CAAC,KAAK,EAAe,CAAqB,CAAC,EAC7C,CAAE,QAAO,CACX,CACJ,EAGa,GACX,EACA,EACA,EACA,EACA,EACA,EACA,EAAqC,IAClC,CACH,GAAM,CAAC,EAAiB,IAAA,EAAsB,EAAA,SAAA,CAAS,CAAC,EAClD,CAAC,EAAO,IAAA,EAAY,EAAA,SAAA,CAA8B,CAAE,KAAM,MAAO,CAAC,EAClE,EAAkB,CAAC,GAAG,CAAkB,CAAC,CAAC,KAAK,GAAG,EAClD,GAAA,EAAQ,EAAA,QAAA,MAAoC,CAChD,MAAO,EAAQ,MACf,MAAO,EAAQ,MACf,QAAS,EAAQ,QACjB,OAAQ,EAAQ,OAChB,KAAM,EAAQ,IAChB,GAAI,CAAC,EAAQ,MAAO,EAAQ,MAAO,EAAQ,QAAS,EAAQ,OAAQ,EAAQ,IAAI,CAAC,EAE3E,EAAW,GAAG,EAAY,GAAG,EAAgB,GAAG,EAAW,GAAG,GAD1C,EAAM,MAAM,GAAG,EAAM,MAAM,GAAG,EAAM,QAAQ,GAAG,EAAM,OAAO,GAAG,EAAM,UAG/F,EAAA,EAAA,UAAA,KAAgB,CACd,GAAI,IAAe,KAAM,CACvB,EAAS,CAAE,KAAM,MAAO,CAAC,EACzB,MACF,CACA,IAAM,EAAQ,IAAI,gBA4BlB,OA3BA,EAAU,GACR,EAAQ,OAAS,SAAW,EAAQ,aAAe,EAC/C,EACA,CAAE,KAAM,UAAW,WAAU,YAAW,CAC9C,EACA,EAAU,KAAK,EAAM,OAAQ,CAAK,CAAC,CAAC,KACjC,GAAU,CACL,EAAM,OAAO,SACjB,EAAS,CACP,KAAM,QACN,MAAO,EAA4B,EAAa,EAAO,CAAkB,EACzE,aAAc,EAAM,aACpB,aAAc,EAAM,aACpB,sBAAuB,EAAM,sBAC7B,WAAY,GACZ,WACA,aACA,WAAY,EAAM,WAClB,UAAW,EAAM,SACnB,CAAC,CACH,EACC,GAAY,CACP,EAAM,OAAO,UACb,EAAsB,CAAO,GAAG,EAAiB,CAAU,EAC/D,EAAS,CAAE,KAAM,SAAU,WAAU,YAAW,CAAC,EACnD,CACF,MACa,EAAM,MAAM,CAC3B,EAAG,CAAC,EAAkB,EAAO,EAAiB,EAAoB,EAAU,EAAY,EAAW,CAAW,CAAC,EAE/G,IAAM,EAAoC,IAAe,KACrD,CAAE,KAAM,MAAO,EACf,EAAM,OAAS,QAAU,EAAM,aAAe,EAC9C,CAAE,KAAM,UAAW,WAAU,YAAW,EACxC,EAAM,OAAS,SAAW,EAAM,WAAa,EAC7C,CAAE,GAAG,EAAO,WAAY,EAAK,EAC7B,EAAM,OAAS,SAAW,EAAM,WAAa,EAC7C,CAAE,KAAM,UAAW,WAAU,YAAW,EACxC,EAEJ,MAAO,CACL,OAAA,EAAO,EAAA,YAAA,KAAkB,EAAoB,GAAa,EAAW,CAAC,EAAG,CAAC,CAAC,EAC3E,MAAO,CACT,CACF"}
1
+ {"version":3,"file":"useWorkspaceItems-6KWfmFtx.js","names":[],"sources":["../../../src/client/items/useWorkspaceItems.ts"],"sourcesContent":["import * as Effect from \"effect/Effect\"\nimport * as Predicate from \"effect/Predicate\"\nimport * as FetchHttpClient from \"effect/unstable/http/FetchHttpClient\"\nimport { useCallback, useEffect, useMemo, useState } from \"react\"\n\nimport { makeControlCenterApiClient } from \"../../api/client.js\"\nimport type { WorkspaceEntityProjectionIndex } from \"../../api/deliveryGraph.js\"\nimport type {\n DeliveryEntityKind,\n DeliveryEntityService,\n DeliveryEntityStatusGroup\n} from \"../../domain/deliveryGraph.js\"\nimport type { PersonId, ReleaseId, WorkspaceId } from \"../../domain/identifiers.js\"\nimport { presentWorkspaceEntityIndex, type WorkspaceItemPresentation } from \"./presentWorkspaceItems.js\"\n\nexport type WorkspaceItemsState =\n | { readonly _tag: \"idle\" }\n | { readonly _tag: \"loading\"; readonly scopeKey: string; readonly sessionKey: string }\n | { readonly _tag: \"failed\"; readonly scopeKey: string; readonly sessionKey: string }\n | {\n readonly _tag: \"ready\"\n readonly items: ReadonlyArray<WorkspaceItemPresentation>\n readonly matchedCount: number\n readonly ownerOptions: WorkspaceEntityProjectionIndex[\"ownerOptions\"]\n readonly ownerOptionsTruncated: boolean\n readonly refreshing: boolean\n readonly scopeKey: string\n readonly sessionKey: string\n readonly truncated: boolean\n readonly totalCount: number\n }\n\nexport interface WorkspaceItemsQuery {\n readonly owner: PersonId | \"all\"\n readonly query: string\n readonly service: DeliveryEntityService | \"all\"\n readonly status: DeliveryEntityStatusGroup | \"all\"\n readonly type: DeliveryEntityKind | \"all\"\n}\n\nexport interface WorkspaceItemsTransport {\n readonly load: (signal: AbortSignal, query: WorkspaceItemsQuery) => Promise<WorkspaceEntityProjectionIndex>\n}\n\nconst isUnauthorizedFailure = Predicate.isTagged(\"UnauthorizedApiError\")\n\n/** Generated-client transport for the authenticated workspace entity index. */\nexport const browserWorkspaceItemsTransport: WorkspaceItemsTransport = {\n load: (signal, query) =>\n Effect.runPromise(\n Effect.gen(function*() {\n const client = yield* makeControlCenterApiClient()\n return yield* client.deliveryGraph.workspaceEntityProjections({\n query: {\n ...(!(query.query.length === 0) && { q: query.query }),\n ...(!(query.owner === \"all\") && { owner: query.owner }),\n ...(!(query.service === \"all\") && { service: query.service }),\n ...(!(query.status === \"all\") && { status: query.status }),\n ...(!(query.type === \"all\") && { type: query.type })\n }\n })\n }).pipe(Effect.provide(FetchHttpClient.layer)),\n { signal }\n )\n}\n\n/** Keep one bounded workspace entity index scoped to the exact browser session. */\nexport const useWorkspaceItems = (\n workspaceId: WorkspaceId,\n routableReleaseIds: ReadonlySet<ReleaseId>,\n filters: WorkspaceItemsQuery,\n refreshKey: string,\n sessionKey: string | null,\n onSessionExpired: (sessionKey: string) => void,\n transport: WorkspaceItemsTransport = browserWorkspaceItemsTransport\n) => {\n const [requestRevision, setRequestRevision] = useState(0)\n const [state, setState] = useState<WorkspaceItemsState>({ _tag: \"idle\" })\n const releaseScopeKey = [...routableReleaseIds].join(\":\")\n const query = useMemo<WorkspaceItemsQuery>(() => ({\n owner: filters.owner,\n query: filters.query,\n service: filters.service,\n status: filters.status,\n type: filters.type\n }), [filters.owner, filters.query, filters.service, filters.status, filters.type])\n const filterScopeKey = `${query.query}|${query.owner}|${query.service}|${query.status}|${query.type}`\n const scopeKey = `${workspaceId}|${releaseScopeKey}|${refreshKey}|${filterScopeKey}`\n\n useEffect(() => {\n if (sessionKey === null) {\n setState({ _tag: \"idle\" })\n return\n }\n const abort = new AbortController()\n setState((current) =>\n current._tag === \"ready\" && current.sessionKey === sessionKey\n ? current\n : { _tag: \"loading\", scopeKey, sessionKey }\n )\n transport.load(abort.signal, query).then(\n (index) => {\n if (abort.signal.aborted) return\n setState({\n _tag: \"ready\",\n items: presentWorkspaceEntityIndex(workspaceId, index, routableReleaseIds),\n matchedCount: index.matchedCount,\n ownerOptions: index.ownerOptions,\n ownerOptionsTruncated: index.ownerOptionsTruncated,\n refreshing: false,\n scopeKey,\n sessionKey,\n totalCount: index.totalCount,\n truncated: index.truncated\n })\n },\n (failure) => {\n if (abort.signal.aborted) return\n if (isUnauthorizedFailure(failure)) onSessionExpired(sessionKey)\n setState({ _tag: \"failed\", scopeKey, sessionKey })\n }\n )\n return () => abort.abort()\n }, [onSessionExpired, query, requestRevision, routableReleaseIds, scopeKey, sessionKey, transport, workspaceId])\n\n const currentState: WorkspaceItemsState = sessionKey === null\n ? { _tag: \"idle\" }\n : state._tag === \"idle\" || state.sessionKey !== sessionKey\n ? { _tag: \"loading\", scopeKey, sessionKey }\n : state._tag === \"ready\" && state.scopeKey !== scopeKey\n ? { ...state, refreshing: true }\n : state._tag !== \"ready\" && state.scopeKey !== scopeKey\n ? { _tag: \"loading\", scopeKey, sessionKey }\n : state\n\n return {\n retry: useCallback(() => setRequestRevision((revision) => revision + 1), []),\n state: currentState\n }\n}\n"],"mappings":"kRA4CM,EAAwB,EAAmB,sBAAsB,EAG1D,EAA0D,CACrE,MAAO,EAAQ,IACb,EACE,EAAW,WAAY,CAErB,OAAO,OAAO,MADQ,EAA2B,EAAA,CAC5B,cAAc,2BAA2B,CAC5D,MAAO,CACL,GAAM,EAAM,MAAM,SAAW,GAAM,CAAE,EAAG,EAAM,KAAM,EACpD,GAAM,EAAM,QAAU,OAAU,CAAE,MAAO,EAAM,KAAM,EACrD,GAAM,EAAM,UAAY,OAAU,CAAE,QAAS,EAAM,OAAQ,EAC3D,GAAM,EAAM,SAAW,OAAU,CAAE,OAAQ,EAAM,MAAO,EACxD,GAAM,EAAM,OAAS,OAAU,CAAE,KAAM,EAAM,IAAK,CACpD,CACF,CAAC,CACH,CAAC,CAAC,CAAC,KAAK,EAAe,CAAqB,CAAC,EAC7C,CAAE,QAAO,CACX,CACJ,EAGa,GACX,EACA,EACA,EACA,EACA,EACA,EACA,EAAqC,IAClC,CACH,GAAM,CAAC,EAAiB,IAAA,EAAsB,EAAA,SAAA,CAAS,CAAC,EAClD,CAAC,EAAO,IAAA,EAAY,EAAA,SAAA,CAA8B,CAAE,KAAM,MAAO,CAAC,EAClE,EAAkB,CAAC,GAAG,CAAkB,CAAC,CAAC,KAAK,GAAG,EAClD,GAAA,EAAQ,EAAA,QAAA,MAAoC,CAChD,MAAO,EAAQ,MACf,MAAO,EAAQ,MACf,QAAS,EAAQ,QACjB,OAAQ,EAAQ,OAChB,KAAM,EAAQ,IAChB,GAAI,CAAC,EAAQ,MAAO,EAAQ,MAAO,EAAQ,QAAS,EAAQ,OAAQ,EAAQ,IAAI,CAAC,EAE3E,EAAW,GAAG,EAAY,GAAG,EAAgB,GAAG,EAAW,GAAG,GAD1C,EAAM,MAAM,GAAG,EAAM,MAAM,GAAG,EAAM,QAAQ,GAAG,EAAM,OAAO,GAAG,EAAM,UAG/F,EAAA,EAAA,UAAA,KAAgB,CACd,GAAI,IAAe,KAAM,CACvB,EAAS,CAAE,KAAM,MAAO,CAAC,EACzB,MACF,CACA,IAAM,EAAQ,IAAI,gBA4BlB,OA3BA,EAAU,GACR,EAAQ,OAAS,SAAW,EAAQ,aAAe,EAC/C,EACA,CAAE,KAAM,UAAW,WAAU,YAAW,CAC9C,EACA,EAAU,KAAK,EAAM,OAAQ,CAAK,CAAC,CAAC,KACjC,GAAU,CACL,EAAM,OAAO,SACjB,EAAS,CACP,KAAM,QACN,MAAO,EAA4B,EAAa,EAAO,CAAkB,EACzE,aAAc,EAAM,aACpB,aAAc,EAAM,aACpB,sBAAuB,EAAM,sBAC7B,WAAY,GACZ,WACA,aACA,WAAY,EAAM,WAClB,UAAW,EAAM,SACnB,CAAC,CACH,EACC,GAAY,CACP,EAAM,OAAO,UACb,EAAsB,CAAO,GAAG,EAAiB,CAAU,EAC/D,EAAS,CAAE,KAAM,SAAU,WAAU,YAAW,CAAC,EACnD,CACF,MACa,EAAM,MAAM,CAC3B,EAAG,CAAC,EAAkB,EAAO,EAAiB,EAAoB,EAAU,EAAY,EAAW,CAAW,CAAC,EAE/G,IAAM,EAAoC,IAAe,KACrD,CAAE,KAAM,MAAO,EACf,EAAM,OAAS,QAAU,EAAM,aAAe,EAC9C,CAAE,KAAM,UAAW,WAAU,YAAW,EACxC,EAAM,OAAS,SAAW,EAAM,WAAa,EAC7C,CAAE,GAAG,EAAO,WAAY,EAAK,EAC7B,EAAM,OAAS,SAAW,EAAM,WAAa,EAC7C,CAAE,KAAM,UAAW,WAAU,YAAW,EACxC,EAEJ,MAAO,CACL,OAAA,EAAO,EAAA,YAAA,KAAkB,EAAoB,GAAa,EAAW,CAAC,EAAG,CAAC,CAAC,EAC3E,MAAO,CACT,CACF"}
@@ -1,2 +1,2 @@
1
- import{c as e,s as t}from"./index-BWx9sNOT.js";import{Da as n,Ea as r,In as i,Nn as a,Qt as o,Rn as s,er as c,pn as l,un as u,zn as d}from"./agent-api-CzdQFCcD.js";import{t as f,u as p}from"./releaseRoutes-CSP_eBj6.js";import{t as m}from"./workspaceEntityPaths-xAl2jRFm.js";var h=d({hash:s,pathname:s,search:s,state:i(f)}),g=d({entityOrigin:d({_tag:a(`entity-origin/v2`),entityId:o,origin:h,workspaceId:l})}),_=e=>{if(e.includes(`?`)||e.includes(`#`))return null;let t=e.split(`/`);if(t.length!==5||t[0]!==``||t[1]!==`w`||t[3]!==`items`)return null;let r=c(l)(t[2]),i=c(o)(t[4]);return n(r)&&n(i)?{entityId:i.value,workspaceId:r.value}:null},v=e=>{let t=c(o)(e);return n(t)?t.value:null},y=e=>({hash:``,pathname:m(e),search:``,state:null}),b=e=>e.length<=2048&&(e.length===0||e.startsWith(`?`)),x=e=>e.length<=1024&&(e.length===0||e.startsWith(`#`)),S=(e,t)=>{if(e.length!==5&&e.length!==6||e[0]!==``||e[1]!==`w`||e[2]!==t||e[3]!==`releases`)return null;let n=c(u)(e[4]);return r(n)||e.length===6&&e[5]!==`preview`?null:{releaseId:n.value,workspaceId:t}},C=(e,t)=>{if(e.length>2048)return!1;let n=e.split(`/`);return n[0]!==``||n[1]!==`w`||n[2]!==t?!1:n.length===4?[`overview`,`work`,`items`,`timeline`].includes(n[3]??``):S(n,t)!==null},w=({hash:e,pathname:t,search:r,state:i})=>{let a=c(l)(t.split(`/`)[2]),o=n(a)?S(t.split(`/`),a.value):null;return{hash:e,pathname:t,search:r,state:o===null?null:p(i,o.workspaceId,o.releaseId)}},T=(e,t)=>{if(!C(e.pathname,t)||!b(e.search)||!x(e.hash))return!1;if(e.state===null)return!0;let n=S(e.pathname.split(`/`),t);return n!==null&&p(e.state,t,n.releaseId)!==null},E=(e,t)=>{let n=c(g)(e);if(r(n))return null;let i=n.value.entityOrigin;return i.workspaceId===t&&T(i.origin,t)?i.origin:null},D=(e,t,n,r)=>({entityOrigin:{_tag:`entity-origin/v2`,entityId:n,origin:E(e,t)??(T(r,t)?r:y(t)),workspaceId:t}}),O=(e,t,n)=>{let i=y(t),a=c(g)(e);if(r(a))return{isStored:!1,origin:i};let o=a.value.entityOrigin;return o.workspaceId===t&&o.entityId===n&&T(o.origin,t)?{isStored:!0,origin:o.origin}:{isStored:!1,origin:i}},k=({hash:e,pathname:t,search:n})=>`${t}${n}${e}`,A=(n,r,i,a,o)=>{let s=S(n.pathname.split(`/`),r),c=a.canonicalReleaseId,l=s===null?a.releaseMembershipsTruncated||a.releaseIds.length!==1||a.releaseIds[0]!==c||c===null||!o.has(c)?null:c:!a.releaseMembershipsTruncated&&a.releaseIds.includes(s.releaseId)&&o.has(s.releaseId)?s.releaseId:null;if(l!==null)return e(r,l,i.pathname);let u=_(i.pathname);if(u===null||u.workspaceId!==r)return t(i.pathname,i.search,i.hash);let d=new URLSearchParams(n.pathname===m(r)?n.search:``);return d.set(`object`,u.entityId),t(m(r),`?${d.toString()}`,`#item-details`)};export{A as a,O as i,w as n,k as o,D as r,_ as s,v as t};
2
- //# sourceMappingURL=workspaceEntityRoutes-CFPO-iFw.js.map
1
+ import{l as e,u as t}from"./index-kmYFvwT0.js";import{$t as n,Aa as r,Bn as i,Ln as a,Pn as o,dn as s,ja as c,mn as l,nr as u,zn as d}from"./agent-api-CUWP1qs8.js";import{t as f,u as p}from"./releaseRoutes-h4FVwFvJ.js";import{t as m}from"./workspaceEntityPaths-xAl2jRFm.js";var h=i({hash:d,pathname:d,search:d,state:a(f)}),g=i({entityOrigin:i({_tag:o(`entity-origin/v2`),entityId:n,origin:h,workspaceId:l})}),_=e=>{if(e.includes(`?`)||e.includes(`#`))return null;let t=e.split(`/`);if(t.length!==5||t[0]!==``||t[1]!==`w`||t[3]!==`items`)return null;let r=u(l)(t[2]),i=u(n)(t[4]);return c(r)&&c(i)?{entityId:i.value,workspaceId:r.value}:null},v=e=>{let t=u(n)(e);return c(t)?t.value:null},y=e=>({hash:``,pathname:m(e),search:``,state:null}),b=e=>e.length<=2048&&(e.length===0||e.startsWith(`?`)),x=e=>e.length<=1024&&(e.length===0||e.startsWith(`#`)),S=(e,t)=>{if(e.length!==5&&e.length!==6||e[0]!==``||e[1]!==`w`||e[2]!==t||e[3]!==`releases`)return null;let n=u(s)(e[4]);return r(n)||e.length===6&&e[5]!==`preview`?null:{releaseId:n.value,workspaceId:t}},C=(e,t)=>{if(e.length>2048)return!1;let n=e.split(`/`);return n[0]!==``||n[1]!==`w`||n[2]!==t?!1:n.length===4?[`overview`,`work`,`items`,`timeline`].includes(n[3]??``):S(n,t)!==null},w=({hash:e,pathname:t,search:n,state:r})=>{let i=u(l)(t.split(`/`)[2]),a=c(i)?S(t.split(`/`),i.value):null;return{hash:e,pathname:t,search:n,state:a===null?null:p(r,a.workspaceId,a.releaseId)}},T=(e,t)=>{if(!C(e.pathname,t)||!b(e.search)||!x(e.hash))return!1;if(e.state===null)return!0;let n=S(e.pathname.split(`/`),t);return n!==null&&p(e.state,t,n.releaseId)!==null},E=(e,t)=>{let n=u(g)(e);if(r(n))return null;let i=n.value.entityOrigin;return i.workspaceId===t&&T(i.origin,t)?i.origin:null},D=(e,t,n,r)=>({entityOrigin:{_tag:`entity-origin/v2`,entityId:n,origin:E(e,t)??(T(r,t)?r:y(t)),workspaceId:t}}),O=(e,t,n)=>{let i=y(t),a=u(g)(e);if(r(a))return{isStored:!1,origin:i};let o=a.value.entityOrigin;return o.workspaceId===t&&o.entityId===n&&T(o.origin,t)?{isStored:!0,origin:o.origin}:{isStored:!1,origin:i}},k=({hash:e,pathname:t,search:n})=>`${t}${n}${e}`,A=(n,r,i,a,o)=>{let s=S(n.pathname.split(`/`),r),c=a.canonicalReleaseId,l=s===null?a.releaseMembershipsTruncated||a.releaseIds.length!==1||a.releaseIds[0]!==c||c===null||!o.has(c)?null:c:!a.releaseMembershipsTruncated&&a.releaseIds.includes(s.releaseId)&&o.has(s.releaseId)?s.releaseId:null;if(l!==null)return t(r,l,i.pathname);let u=_(i.pathname);if(u===null||u.workspaceId!==r)return e(i.pathname,i.search,i.hash);let d=new URLSearchParams(n.pathname===m(r)?n.search:``);return d.set(`object`,u.entityId),e(m(r),`?${d.toString()}`,`#item-details`)};export{A as a,O as i,w as n,k as o,D as r,_ as s,v as t};
2
+ //# sourceMappingURL=workspaceEntityRoutes-BHccxrFj.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"workspaceEntityRoutes-CFPO-iFw.js","names":[],"sources":["../../../src/client/items/workspaceEntityRoutes.ts"],"sourcesContent":["import * as Option from \"effect/Option\"\nimport * as Schema from \"effect/Schema\"\n\nimport {\n EntityId,\n type EntityId as EntityIdType,\n ReleaseId,\n type ReleaseId as ReleaseIdType,\n WorkspaceId,\n type WorkspaceId as WorkspaceIdType\n} from \"../../domain/identifiers.js\"\nimport { contextualAgentPath, contextualReleaseAgentPath } from \"../contextualAgentPath.js\"\nimport { releaseAgentPath } from \"../releases/releasePaths.js\"\nimport { type ReleaseRouteState, ReleaseRouteStateSchema, retainReleaseRouteState } from \"../releases/releaseRoutes.js\"\nimport { workspaceEntityParentPath } from \"../workspaceEntityPaths.js\"\n\nexport { workspaceEntityParentPath, workspaceEntityPath } from \"../workspaceEntityPaths.js\"\n\n/** Exact in-application location preserved while a canonical entity route is open. */\nexport interface WorkspaceEntityOrigin {\n readonly hash: string\n readonly pathname: string\n readonly search: string\n readonly state: ReleaseRouteState | null\n}\n\n/** Versioned, bounded router state for one canonical entity activation. */\nexport interface WorkspaceEntityRouteState {\n readonly entityOrigin: {\n readonly _tag: \"entity-origin/v2\"\n readonly entityId: EntityIdType\n readonly origin: WorkspaceEntityOrigin\n readonly workspaceId: WorkspaceIdType\n }\n}\n\n/** Decoded entity origin plus whether it came from trusted matching history state. */\nexport interface ResolvedWorkspaceEntityOrigin {\n readonly isStored: boolean\n readonly origin: WorkspaceEntityOrigin\n}\n\n/** Decoded target of one exact canonical workspace entity href. */\nexport interface WorkspaceEntityTarget {\n readonly entityId: EntityIdType\n readonly workspaceId: WorkspaceIdType\n}\n\n/** Release membership evidence used to select an unambiguous entity-owned agent thread. */\nexport interface WorkspaceEntityReleaseContext {\n readonly canonicalReleaseId: ReleaseIdType | null\n readonly releaseIds: ReadonlyArray<ReleaseIdType>\n readonly releaseMembershipsTruncated: boolean\n}\n\ninterface LocationParts {\n readonly hash: string\n readonly pathname: string\n readonly search: string\n readonly state?: unknown\n}\n\nconst WorkspaceEntityOriginSchema = Schema.Struct({\n hash: Schema.String,\n pathname: Schema.String,\n search: Schema.String,\n state: Schema.NullOr(ReleaseRouteStateSchema)\n})\n\nconst WorkspaceEntityRouteStateSchema = Schema.Struct({\n entityOrigin: Schema.Struct({\n _tag: Schema.Literal(\"entity-origin/v2\"),\n entityId: EntityId,\n origin: WorkspaceEntityOriginSchema,\n workspaceId: WorkspaceId\n })\n})\n\n/** Decode only an exact canonical entity path, rejecting query, hash, and extra path material. */\nexport const workspaceEntityTargetFromHref = (href: string): WorkspaceEntityTarget | null => {\n if (href.includes(\"?\") || href.includes(\"#\")) return null\n const parts = href.split(\"/\")\n if (parts.length !== 5 || parts[0] !== \"\" || parts[1] !== \"w\" || parts[3] !== \"items\") return null\n const workspaceId = Schema.decodeUnknownOption(WorkspaceId)(parts[2])\n const entityId = Schema.decodeUnknownOption(EntityId)(parts[4])\n return Option.isSome(workspaceId) && Option.isSome(entityId)\n ? { entityId: entityId.value, workspaceId: workspaceId.value }\n : null\n}\n\n/** Decode one entity route segment at the browser boundary. */\nexport const decodeEntityRouteId = <UnparsedInput>(value: UnparsedInput): EntityIdType | null => {\n const decoded = Schema.decodeUnknownOption(EntityId)(value)\n return Option.isSome(decoded) ? decoded.value : null\n}\n\nconst fallbackOrigin = (workspaceId: WorkspaceIdType): WorkspaceEntityOrigin => ({\n hash: \"\",\n pathname: workspaceEntityParentPath(workspaceId),\n search: \"\",\n state: null\n})\n\nconst isSearch = (search: string): boolean => search.length <= 2_048 && (search.length === 0 || search.startsWith(\"?\"))\n\nconst isHash = (hash: string): boolean => hash.length <= 1_024 && (hash.length === 0 || hash.startsWith(\"#\"))\n\nconst releaseOriginTarget = (\n parts: ReadonlyArray<string>,\n workspaceId: WorkspaceIdType\n): { readonly releaseId: ReleaseIdType; readonly workspaceId: WorkspaceIdType } | null => {\n if (parts.length !== 5 && parts.length !== 6) return null\n if (parts[0] !== \"\" || parts[1] !== \"w\" || parts[2] !== workspaceId || parts[3] !== \"releases\") return null\n const releaseId = Schema.decodeUnknownOption(ReleaseId)(parts[4])\n if (Option.isNone(releaseId) || (parts.length === 6 && parts[5] !== \"preview\")) return null\n return { releaseId: releaseId.value, workspaceId }\n}\n\nconst isRecognizedOriginPath = (pathname: string, workspaceId: WorkspaceIdType): boolean => {\n if (pathname.length > 2_048) return false\n const parts = pathname.split(\"/\")\n if (parts[0] !== \"\" || parts[1] !== \"w\" || parts[2] !== workspaceId) return false\n if (parts.length === 4) return [\"overview\", \"work\", \"items\", \"timeline\"].includes(parts[3] ?? \"\")\n return releaseOriginTarget(parts, workspaceId) !== null\n}\n\n/** Capture an exact location while retaining only matching, bounded release origin state. */\nexport const entityOriginFromLocation = ({\n hash,\n pathname,\n search,\n state\n}: LocationParts): WorkspaceEntityOrigin => {\n const workspaceId = Schema.decodeUnknownOption(WorkspaceId)(pathname.split(\"/\")[2])\n const target = Option.isSome(workspaceId) ? releaseOriginTarget(pathname.split(\"/\"), workspaceId.value) : null\n return {\n hash,\n pathname,\n search,\n state: target === null ? null : retainReleaseRouteState(state, target.workspaceId, target.releaseId)\n }\n}\n\n/** Confirm an origin is bounded and belongs to a supported page in the exact workspace. */\nexport const isSafeWorkspaceEntityOrigin = (\n origin: WorkspaceEntityOrigin,\n workspaceId: WorkspaceIdType\n): boolean => {\n if (!isRecognizedOriginPath(origin.pathname, workspaceId) || !isSearch(origin.search) || !isHash(origin.hash)) {\n return false\n }\n if (origin.state === null) return true\n const target = releaseOriginTarget(origin.pathname.split(\"/\"), workspaceId)\n return target !== null && retainReleaseRouteState(origin.state, workspaceId, target.releaseId) !== null\n}\n\nconst reusableStoredOrigin = <UnparsedInput>(\n state: UnparsedInput,\n workspaceId: WorkspaceIdType\n): WorkspaceEntityOrigin | null => {\n const decoded = Schema.decodeUnknownOption(WorkspaceEntityRouteStateSchema)(state)\n if (Option.isNone(decoded)) return null\n const marker = decoded.value.entityOrigin\n return marker.workspaceId === workspaceId && isSafeWorkspaceEntityOrigin(marker.origin, workspaceId)\n ? marker.origin\n : null\n}\n\n/**\n * Construct bounded entity route state.\n *\n * A previously validated entity origin is carried through related-entity navigation so the\n * shell's explicit Back action still returns to the root activation surface.\n */\nexport const makeWorkspaceEntityRouteState = <UnparsedInput>(\n state: UnparsedInput,\n workspaceId: WorkspaceIdType,\n entityId: EntityIdType,\n origin: WorkspaceEntityOrigin\n): WorkspaceEntityRouteState => ({\n entityOrigin: {\n _tag: \"entity-origin/v2\",\n entityId,\n origin: reusableStoredOrigin(state, workspaceId) ??\n (isSafeWorkspaceEntityOrigin(origin, workspaceId) ? origin : fallbackOrigin(workspaceId)),\n workspaceId\n }\n})\n\n/** Decode safe history state for the exact workspace/entity pair or use the Items parent. */\nexport const resolveWorkspaceEntityOrigin = <UnparsedInput>(\n state: UnparsedInput,\n workspaceId: WorkspaceIdType,\n entityId: EntityIdType\n): ResolvedWorkspaceEntityOrigin => {\n const fallback = fallbackOrigin(workspaceId)\n const decoded = Schema.decodeUnknownOption(WorkspaceEntityRouteStateSchema)(state)\n if (Option.isNone(decoded)) return { isStored: false, origin: fallback }\n const marker = decoded.value.entityOrigin\n return marker.workspaceId === workspaceId &&\n marker.entityId === entityId &&\n isSafeWorkspaceEntityOrigin(marker.origin, workspaceId)\n ? { isStored: true, origin: marker.origin }\n : { isStored: false, origin: fallback }\n}\n\n/** Serialize an exact validated origin for React Router navigation. */\nexport const workspaceEntityOriginHref = ({\n hash,\n pathname,\n search\n}: WorkspaceEntityOrigin): string => `${pathname}${search}${hash}`\n\n/** Resolve a release-owned agent thread only when the stored origin is an exact release route. */\nexport const workspaceEntityOriginAgentPath = (\n origin: WorkspaceEntityOrigin,\n workspaceId: WorkspaceIdType,\n routableReleaseIds: ReadonlySet<ReleaseIdType>\n): string | null => {\n const target = releaseOriginTarget(origin.pathname.split(\"/\"), workspaceId)\n return target === null || !routableReleaseIds.has(target.releaseId)\n ? null\n : releaseAgentPath(target.workspaceId, target.releaseId)\n}\n\n/** Keep entity actions in a release-owned thread, falling back to the current-page context. */\nexport const workspaceEntityAgentPath = (\n origin: WorkspaceEntityOrigin,\n workspaceId: WorkspaceIdType,\n current: Pick<LocationParts, \"hash\" | \"pathname\" | \"search\">,\n releaseContext: WorkspaceEntityReleaseContext,\n routableReleaseIds: ReadonlySet<ReleaseIdType>\n): string => {\n const originRelease = releaseOriginTarget(origin.pathname.split(\"/\"), workspaceId)\n const canonicalReleaseId = releaseContext.canonicalReleaseId\n const releaseTargetId = originRelease === null\n ? releaseContext.releaseMembershipsTruncated ||\n releaseContext.releaseIds.length !== 1 ||\n releaseContext.releaseIds[0] !== canonicalReleaseId ||\n canonicalReleaseId === null ||\n !routableReleaseIds.has(canonicalReleaseId)\n ? null\n : canonicalReleaseId\n : !releaseContext.releaseMembershipsTruncated &&\n releaseContext.releaseIds.includes(originRelease.releaseId) &&\n routableReleaseIds.has(originRelease.releaseId)\n ? originRelease.releaseId\n : null\n if (releaseTargetId !== null) {\n return contextualReleaseAgentPath(workspaceId, releaseTargetId, current.pathname)\n }\n\n const entity = workspaceEntityTargetFromHref(current.pathname)\n if (entity === null || entity.workspaceId !== workspaceId) {\n return contextualAgentPath(current.pathname, current.search, current.hash)\n }\n const itemSearch = new URLSearchParams(\n origin.pathname === workspaceEntityParentPath(workspaceId) ? origin.search : \"\"\n )\n itemSearch.set(\"object\", entity.entityId)\n return contextualAgentPath(\n workspaceEntityParentPath(workspaceId),\n `?${itemSearch.toString()}`,\n \"#item-details\"\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"workspaceEntityRoutes-BHccxrFj.js","names":[],"sources":["../../../src/client/items/workspaceEntityRoutes.ts"],"sourcesContent":["import * as Option from \"effect/Option\"\nimport * as Schema from \"effect/Schema\"\n\nimport {\n EntityId,\n type EntityId as EntityIdType,\n ReleaseId,\n type ReleaseId as ReleaseIdType,\n WorkspaceId,\n type WorkspaceId as WorkspaceIdType\n} from \"../../domain/identifiers.js\"\nimport { contextualAgentPath, contextualReleaseAgentPath } from \"../contextualAgentPath.js\"\nimport { releaseAgentPath } from \"../releases/releasePaths.js\"\nimport { type ReleaseRouteState, ReleaseRouteStateSchema, retainReleaseRouteState } from \"../releases/releaseRoutes.js\"\nimport { workspaceEntityParentPath } from \"../workspaceEntityPaths.js\"\n\nexport { workspaceEntityParentPath, workspaceEntityPath } from \"../workspaceEntityPaths.js\"\n\n/** Exact in-application location preserved while a canonical entity route is open. */\nexport interface WorkspaceEntityOrigin {\n readonly hash: string\n readonly pathname: string\n readonly search: string\n readonly state: ReleaseRouteState | null\n}\n\n/** Versioned, bounded router state for one canonical entity activation. */\nexport interface WorkspaceEntityRouteState {\n readonly entityOrigin: {\n readonly _tag: \"entity-origin/v2\"\n readonly entityId: EntityIdType\n readonly origin: WorkspaceEntityOrigin\n readonly workspaceId: WorkspaceIdType\n }\n}\n\n/** Decoded entity origin plus whether it came from trusted matching history state. */\nexport interface ResolvedWorkspaceEntityOrigin {\n readonly isStored: boolean\n readonly origin: WorkspaceEntityOrigin\n}\n\n/** Decoded target of one exact canonical workspace entity href. */\nexport interface WorkspaceEntityTarget {\n readonly entityId: EntityIdType\n readonly workspaceId: WorkspaceIdType\n}\n\n/** Release membership evidence used to select an unambiguous entity-owned agent thread. */\nexport interface WorkspaceEntityReleaseContext {\n readonly canonicalReleaseId: ReleaseIdType | null\n readonly releaseIds: ReadonlyArray<ReleaseIdType>\n readonly releaseMembershipsTruncated: boolean\n}\n\ninterface LocationParts {\n readonly hash: string\n readonly pathname: string\n readonly search: string\n readonly state?: unknown\n}\n\nconst WorkspaceEntityOriginSchema = Schema.Struct({\n hash: Schema.String,\n pathname: Schema.String,\n search: Schema.String,\n state: Schema.NullOr(ReleaseRouteStateSchema)\n})\n\nconst WorkspaceEntityRouteStateSchema = Schema.Struct({\n entityOrigin: Schema.Struct({\n _tag: Schema.Literal(\"entity-origin/v2\"),\n entityId: EntityId,\n origin: WorkspaceEntityOriginSchema,\n workspaceId: WorkspaceId\n })\n})\n\n/** Decode only an exact canonical entity path, rejecting query, hash, and extra path material. */\nexport const workspaceEntityTargetFromHref = (href: string): WorkspaceEntityTarget | null => {\n if (href.includes(\"?\") || href.includes(\"#\")) return null\n const parts = href.split(\"/\")\n if (parts.length !== 5 || parts[0] !== \"\" || parts[1] !== \"w\" || parts[3] !== \"items\") return null\n const workspaceId = Schema.decodeUnknownOption(WorkspaceId)(parts[2])\n const entityId = Schema.decodeUnknownOption(EntityId)(parts[4])\n return Option.isSome(workspaceId) && Option.isSome(entityId)\n ? { entityId: entityId.value, workspaceId: workspaceId.value }\n : null\n}\n\n/** Decode one entity route segment at the browser boundary. */\nexport const decodeEntityRouteId = <UnparsedInput>(value: UnparsedInput): EntityIdType | null => {\n const decoded = Schema.decodeUnknownOption(EntityId)(value)\n return Option.isSome(decoded) ? decoded.value : null\n}\n\nconst fallbackOrigin = (workspaceId: WorkspaceIdType): WorkspaceEntityOrigin => ({\n hash: \"\",\n pathname: workspaceEntityParentPath(workspaceId),\n search: \"\",\n state: null\n})\n\nconst isSearch = (search: string): boolean => search.length <= 2_048 && (search.length === 0 || search.startsWith(\"?\"))\n\nconst isHash = (hash: string): boolean => hash.length <= 1_024 && (hash.length === 0 || hash.startsWith(\"#\"))\n\nconst releaseOriginTarget = (\n parts: ReadonlyArray<string>,\n workspaceId: WorkspaceIdType\n): { readonly releaseId: ReleaseIdType; readonly workspaceId: WorkspaceIdType } | null => {\n if (parts.length !== 5 && parts.length !== 6) return null\n if (parts[0] !== \"\" || parts[1] !== \"w\" || parts[2] !== workspaceId || parts[3] !== \"releases\") return null\n const releaseId = Schema.decodeUnknownOption(ReleaseId)(parts[4])\n if (Option.isNone(releaseId) || (parts.length === 6 && parts[5] !== \"preview\")) return null\n return { releaseId: releaseId.value, workspaceId }\n}\n\nconst isRecognizedOriginPath = (pathname: string, workspaceId: WorkspaceIdType): boolean => {\n if (pathname.length > 2_048) return false\n const parts = pathname.split(\"/\")\n if (parts[0] !== \"\" || parts[1] !== \"w\" || parts[2] !== workspaceId) return false\n if (parts.length === 4) return [\"overview\", \"work\", \"items\", \"timeline\"].includes(parts[3] ?? \"\")\n return releaseOriginTarget(parts, workspaceId) !== null\n}\n\n/** Capture an exact location while retaining only matching, bounded release origin state. */\nexport const entityOriginFromLocation = ({\n hash,\n pathname,\n search,\n state\n}: LocationParts): WorkspaceEntityOrigin => {\n const workspaceId = Schema.decodeUnknownOption(WorkspaceId)(pathname.split(\"/\")[2])\n const target = Option.isSome(workspaceId) ? releaseOriginTarget(pathname.split(\"/\"), workspaceId.value) : null\n return {\n hash,\n pathname,\n search,\n state: target === null ? null : retainReleaseRouteState(state, target.workspaceId, target.releaseId)\n }\n}\n\n/** Confirm an origin is bounded and belongs to a supported page in the exact workspace. */\nexport const isSafeWorkspaceEntityOrigin = (\n origin: WorkspaceEntityOrigin,\n workspaceId: WorkspaceIdType\n): boolean => {\n if (!isRecognizedOriginPath(origin.pathname, workspaceId) || !isSearch(origin.search) || !isHash(origin.hash)) {\n return false\n }\n if (origin.state === null) return true\n const target = releaseOriginTarget(origin.pathname.split(\"/\"), workspaceId)\n return target !== null && retainReleaseRouteState(origin.state, workspaceId, target.releaseId) !== null\n}\n\nconst reusableStoredOrigin = <UnparsedInput>(\n state: UnparsedInput,\n workspaceId: WorkspaceIdType\n): WorkspaceEntityOrigin | null => {\n const decoded = Schema.decodeUnknownOption(WorkspaceEntityRouteStateSchema)(state)\n if (Option.isNone(decoded)) return null\n const marker = decoded.value.entityOrigin\n return marker.workspaceId === workspaceId && isSafeWorkspaceEntityOrigin(marker.origin, workspaceId)\n ? marker.origin\n : null\n}\n\n/**\n * Construct bounded entity route state.\n *\n * A previously validated entity origin is carried through related-entity navigation so the\n * shell's explicit Back action still returns to the root activation surface.\n */\nexport const makeWorkspaceEntityRouteState = <UnparsedInput>(\n state: UnparsedInput,\n workspaceId: WorkspaceIdType,\n entityId: EntityIdType,\n origin: WorkspaceEntityOrigin\n): WorkspaceEntityRouteState => ({\n entityOrigin: {\n _tag: \"entity-origin/v2\",\n entityId,\n origin: reusableStoredOrigin(state, workspaceId) ??\n (isSafeWorkspaceEntityOrigin(origin, workspaceId) ? origin : fallbackOrigin(workspaceId)),\n workspaceId\n }\n})\n\n/** Decode safe history state for the exact workspace/entity pair or use the Items parent. */\nexport const resolveWorkspaceEntityOrigin = <UnparsedInput>(\n state: UnparsedInput,\n workspaceId: WorkspaceIdType,\n entityId: EntityIdType\n): ResolvedWorkspaceEntityOrigin => {\n const fallback = fallbackOrigin(workspaceId)\n const decoded = Schema.decodeUnknownOption(WorkspaceEntityRouteStateSchema)(state)\n if (Option.isNone(decoded)) return { isStored: false, origin: fallback }\n const marker = decoded.value.entityOrigin\n return marker.workspaceId === workspaceId &&\n marker.entityId === entityId &&\n isSafeWorkspaceEntityOrigin(marker.origin, workspaceId)\n ? { isStored: true, origin: marker.origin }\n : { isStored: false, origin: fallback }\n}\n\n/** Serialize an exact validated origin for React Router navigation. */\nexport const workspaceEntityOriginHref = ({\n hash,\n pathname,\n search\n}: WorkspaceEntityOrigin): string => `${pathname}${search}${hash}`\n\n/** Resolve a release-owned agent thread only when the stored origin is an exact release route. */\nexport const workspaceEntityOriginAgentPath = (\n origin: WorkspaceEntityOrigin,\n workspaceId: WorkspaceIdType,\n routableReleaseIds: ReadonlySet<ReleaseIdType>\n): string | null => {\n const target = releaseOriginTarget(origin.pathname.split(\"/\"), workspaceId)\n return target === null || !routableReleaseIds.has(target.releaseId)\n ? null\n : releaseAgentPath(target.workspaceId, target.releaseId)\n}\n\n/** Keep entity actions in a release-owned thread, falling back to the current-page context. */\nexport const workspaceEntityAgentPath = (\n origin: WorkspaceEntityOrigin,\n workspaceId: WorkspaceIdType,\n current: Pick<LocationParts, \"hash\" | \"pathname\" | \"search\">,\n releaseContext: WorkspaceEntityReleaseContext,\n routableReleaseIds: ReadonlySet<ReleaseIdType>\n): string => {\n const originRelease = releaseOriginTarget(origin.pathname.split(\"/\"), workspaceId)\n const canonicalReleaseId = releaseContext.canonicalReleaseId\n const releaseTargetId = originRelease === null\n ? releaseContext.releaseMembershipsTruncated ||\n releaseContext.releaseIds.length !== 1 ||\n releaseContext.releaseIds[0] !== canonicalReleaseId ||\n canonicalReleaseId === null ||\n !routableReleaseIds.has(canonicalReleaseId)\n ? null\n : canonicalReleaseId\n : !releaseContext.releaseMembershipsTruncated &&\n releaseContext.releaseIds.includes(originRelease.releaseId) &&\n routableReleaseIds.has(originRelease.releaseId)\n ? originRelease.releaseId\n : null\n if (releaseTargetId !== null) {\n return contextualReleaseAgentPath(workspaceId, releaseTargetId, current.pathname)\n }\n\n const entity = workspaceEntityTargetFromHref(current.pathname)\n if (entity === null || entity.workspaceId !== workspaceId) {\n return contextualAgentPath(current.pathname, current.search, current.hash)\n }\n const itemSearch = new URLSearchParams(\n origin.pathname === workspaceEntityParentPath(workspaceId) ? origin.search : \"\"\n )\n itemSearch.set(\"object\", entity.entityId)\n return contextualAgentPath(\n workspaceEntityParentPath(workspaceId),\n `?${itemSearch.toString()}`,\n \"#item-details\"\n )\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{n as e,r as t,t as n}from"./index-BWx9sNOT.js";var r=32,i=(e,t)=>!e.defaultPrevented&&e.button===0&&!e.altKey&&!e.ctrlKey&&!e.metaKey&&!e.shiftKey&&(t===``||t===`_self`),a=(i,a)=>{let o=t(i);for(let[t,n]of e){if(!n[3]||!n[2].includes(i.pathname))continue;let r=n[2].includes(a)?n[2]:[...n[2],a];e.set(t,[n[0],n[1],r,!0])}e.delete(o);let s=document.querySelector(n),c=[s?.scrollTop??window.scrollY,s!==null,[a],!1];if(!(c[0]<=2)&&(e.set(o,c),!(e.size<=r)))for(let t of e.keys()){e.delete(t);break}};export{i as n,a as t};
2
- //# sourceMappingURL=workspaceScrollCapture-DUj-_YMd.js.map
1
+ import{n as e,r as t,t as n}from"./index-kmYFvwT0.js";var r=32,i=(e,t)=>!e.defaultPrevented&&e.button===0&&!e.altKey&&!e.ctrlKey&&!e.metaKey&&!e.shiftKey&&(t===``||t===`_self`),a=(i,a)=>{let o=t(i);for(let[t,n]of e){if(!n[3]||!n[2].includes(i.pathname))continue;let r=n[2].includes(a)?n[2]:[...n[2],a];e.set(t,[n[0],n[1],r,!0])}e.delete(o);let s=document.querySelector(n),c=[s?.scrollTop??window.scrollY,s!==null,[a],!1];if(!(c[0]<=2)&&(e.set(o,c),!(e.size<=r)))for(let t of e.keys()){e.delete(t);break}};export{i as n,a as t};
2
+ //# sourceMappingURL=workspaceScrollCapture-BzsNJoL7.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"workspaceScrollCapture-DUj-_YMd.js","names":[],"sources":["../../../src/client/workspaceScrollCapture.ts"],"sourcesContent":["import type { Location } from \"react-router\"\n\nimport {\n RELEASE_PREVIEW_SCROLL_SELECTOR,\n type SavedWorkspaceScrollPosition,\n savedWorkspaceScrollPositions,\n SCROLL_POSITION_TOLERANCE,\n workspaceScrollRestorationKey\n} from \"./workspaceScrollRestoration.js\"\n\nconst MAXIMUM_SAVED_WORKSPACE_SCROLL_POSITIONS = 32\n\ninterface WorkspaceNavigationClick {\n readonly altKey: boolean\n readonly button: number\n readonly ctrlKey: boolean\n readonly defaultPrevented: boolean\n readonly metaKey: boolean\n readonly shiftKey: boolean\n}\n\n/** Match the same primary, unmodified, same-tab click contract as React Router. */\nexport const shouldRememberWorkspaceScrollPosition = (event: WorkspaceNavigationClick, linkTarget: string): boolean =>\n !event.defaultPrevented &&\n event.button === 0 &&\n !event.altKey &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.shiftKey &&\n (linkTarget === \"\" || linkTarget === \"_self\")\n\n/** Remember the current viewport before opening a canonical entity route. */\nexport const rememberWorkspaceScrollPosition = (\n location: Pick<Location, \"hash\" | \"pathname\" | \"search\">,\n entityPath: string\n): void => {\n const key = workspaceScrollRestorationKey(location)\n for (const [originKey, saved] of savedWorkspaceScrollPositions) {\n if (!saved[3] || !saved[2].includes(location.pathname)) continue\n const entityPaths = saved[2].includes(entityPath) ? saved[2] : [...saved[2], entityPath]\n savedWorkspaceScrollPositions.set(originKey, [saved[0], saved[1], entityPaths, true])\n }\n savedWorkspaceScrollPositions.delete(key)\n const previewScroller = document.querySelector<HTMLElement>(RELEASE_PREVIEW_SCROLL_SELECTOR)\n const savedPosition = [\n previewScroller?.scrollTop ?? window.scrollY,\n previewScroller !== null,\n [entityPath],\n false\n ] satisfies SavedWorkspaceScrollPosition\n if (savedPosition[0] <= SCROLL_POSITION_TOLERANCE) return\n savedWorkspaceScrollPositions.set(key, savedPosition)\n if (savedWorkspaceScrollPositions.size <= MAXIMUM_SAVED_WORKSPACE_SCROLL_POSITIONS) return\n for (const oldestKey of savedWorkspaceScrollPositions.keys()) {\n savedWorkspaceScrollPositions.delete(oldestKey)\n break\n }\n}\n"],"mappings":"sDAUA,IAAM,EAA2C,GAYpC,GAAyC,EAAiC,IACrF,CAAC,EAAM,kBACP,EAAM,SAAW,GACjB,CAAC,EAAM,QACP,CAAC,EAAM,SACP,CAAC,EAAM,SACP,CAAC,EAAM,WACN,IAAe,IAAM,IAAe,SAG1B,GACX,EACA,IACS,CACT,IAAM,EAAM,EAA8B,CAAQ,EAClD,IAAK,GAAM,CAAC,EAAW,KAAU,EAA+B,CAC9D,GAAI,CAAC,EAAM,IAAM,CAAC,EAAM,EAAE,CAAC,SAAS,EAAS,QAAQ,EAAG,SACxD,IAAM,EAAc,EAAM,EAAE,CAAC,SAAS,CAAU,EAAI,EAAM,GAAK,CAAC,GAAG,EAAM,GAAI,CAAU,EACvF,EAA8B,IAAI,EAAW,CAAC,EAAM,GAAI,EAAM,GAAI,EAAa,EAAI,CAAC,CACtF,CACA,EAA8B,OAAO,CAAG,EACxC,IAAM,EAAkB,SAAS,cAA2B,CAA+B,EACrF,EAAgB,CACpB,GAAiB,WAAa,OAAO,QACrC,IAAoB,KACpB,CAAC,CAAU,EACX,EACF,EACI,OAAc,IAAA,KAClB,EAA8B,IAAI,EAAK,CAAa,EAChD,IAA8B,MAAQ,IAC1C,IAAK,IAAM,KAAa,EAA8B,KAAK,EAAG,CAC5D,EAA8B,OAAO,CAAS,EAC9C,KACF,CACF"}
1
+ {"version":3,"file":"workspaceScrollCapture-BzsNJoL7.js","names":[],"sources":["../../../src/client/workspaceScrollCapture.ts"],"sourcesContent":["import type { Location } from \"react-router\"\n\nimport {\n RELEASE_PREVIEW_SCROLL_SELECTOR,\n type SavedWorkspaceScrollPosition,\n savedWorkspaceScrollPositions,\n SCROLL_POSITION_TOLERANCE,\n workspaceScrollRestorationKey\n} from \"./workspaceScrollRestoration.js\"\n\nconst MAXIMUM_SAVED_WORKSPACE_SCROLL_POSITIONS = 32\n\ninterface WorkspaceNavigationClick {\n readonly altKey: boolean\n readonly button: number\n readonly ctrlKey: boolean\n readonly defaultPrevented: boolean\n readonly metaKey: boolean\n readonly shiftKey: boolean\n}\n\n/** Match the same primary, unmodified, same-tab click contract as React Router. */\nexport const shouldRememberWorkspaceScrollPosition = (event: WorkspaceNavigationClick, linkTarget: string): boolean =>\n !event.defaultPrevented &&\n event.button === 0 &&\n !event.altKey &&\n !event.ctrlKey &&\n !event.metaKey &&\n !event.shiftKey &&\n (linkTarget === \"\" || linkTarget === \"_self\")\n\n/** Remember the current viewport before opening a canonical entity route. */\nexport const rememberWorkspaceScrollPosition = (\n location: Pick<Location, \"hash\" | \"pathname\" | \"search\">,\n entityPath: string\n): void => {\n const key = workspaceScrollRestorationKey(location)\n for (const [originKey, saved] of savedWorkspaceScrollPositions) {\n if (!saved[3] || !saved[2].includes(location.pathname)) continue\n const entityPaths = saved[2].includes(entityPath) ? saved[2] : [...saved[2], entityPath]\n savedWorkspaceScrollPositions.set(originKey, [saved[0], saved[1], entityPaths, true])\n }\n savedWorkspaceScrollPositions.delete(key)\n const previewScroller = document.querySelector<HTMLElement>(RELEASE_PREVIEW_SCROLL_SELECTOR)\n const savedPosition = [\n previewScroller?.scrollTop ?? window.scrollY,\n previewScroller !== null,\n [entityPath],\n false\n ] satisfies SavedWorkspaceScrollPosition\n if (savedPosition[0] <= SCROLL_POSITION_TOLERANCE) return\n savedWorkspaceScrollPositions.set(key, savedPosition)\n if (savedWorkspaceScrollPositions.size <= MAXIMUM_SAVED_WORKSPACE_SCROLL_POSITIONS) return\n for (const oldestKey of savedWorkspaceScrollPositions.keys()) {\n savedWorkspaceScrollPositions.delete(oldestKey)\n break\n }\n}\n"],"mappings":"sDAUA,IAAM,EAA2C,GAYpC,GAAyC,EAAiC,IACrF,CAAC,EAAM,kBACP,EAAM,SAAW,GACjB,CAAC,EAAM,QACP,CAAC,EAAM,SACP,CAAC,EAAM,SACP,CAAC,EAAM,WACN,IAAe,IAAM,IAAe,SAG1B,GACX,EACA,IACS,CACT,IAAM,EAAM,EAA8B,CAAQ,EAClD,IAAK,GAAM,CAAC,EAAW,KAAU,EAA+B,CAC9D,GAAI,CAAC,EAAM,IAAM,CAAC,EAAM,EAAE,CAAC,SAAS,EAAS,QAAQ,EAAG,SACxD,IAAM,EAAc,EAAM,EAAE,CAAC,SAAS,CAAU,EAAI,EAAM,GAAK,CAAC,GAAG,EAAM,GAAI,CAAU,EACvF,EAA8B,IAAI,EAAW,CAAC,EAAM,GAAI,EAAM,GAAI,EAAa,EAAI,CAAC,CACtF,CACA,EAA8B,OAAO,CAAG,EACxC,IAAM,EAAkB,SAAS,cAA2B,CAA+B,EACrF,EAAgB,CACpB,GAAiB,WAAa,OAAO,QACrC,IAAoB,KACpB,CAAC,CAAU,EACX,EACF,EACI,OAAc,IAAA,KAClB,EAA8B,IAAI,EAAK,CAAa,EAChD,IAA8B,MAAQ,IAC1C,IAAK,IAAM,KAAa,EAA8B,KAAK,EAAG,CAC5D,EAA8B,OAAO,CAAS,EAC9C,KACF,CACF"}
@@ -0,0 +1,2 @@
1
+ import{Ti as e,_i as t,hn as n,ki as r,tr as i}from"./agent-api-CUWP1qs8.js";import{a,t as o}from"./client-D3WRV6yl.js";import{n as s,t as c}from"./BrowserCrypto-CoBR2WBd.js";import{t as l}from"./authenticatedMutationClient-Bc_-Jpbo.js";var u={load:n=>r(t(function*(){return yield*(yield*o()).workspaceSettings.readPresentation()}).pipe(e(a)),{signal:n})},d={load:n=>r(t(function*(){return yield*(yield*o()).workspaceSettings.read()}).pipe(e(a)),{signal:n}),makeMutationId:()=>r(t(function*(){let e=yield*s;return yield*i(n)(yield*e.randomUUIDv7)}).pipe(e(c))),update:(n,i)=>r(t(function*(){return yield*(yield*l).workspaceSettings.update({payload:n})}).pipe(e(a)),{signal:i})};export{u as browserWorkspacePresentationTransport,d as browserWorkspaceSettingsTransport};
2
+ //# sourceMappingURL=workspaceSettingsTransport-BwRQteEH.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"workspaceSettingsTransport-Kq7lfPsC.js","names":[],"sources":["../../../src/client/settings/workspaceSettingsTransport.ts"],"sourcesContent":["import * as BrowserCrypto from \"@effect/platform-browser/BrowserCrypto\"\nimport * as Crypto from \"effect/Crypto\"\nimport * as Effect from \"effect/Effect\"\nimport * as Schema from \"effect/Schema\"\nimport * as FetchHttpClient from \"effect/unstable/http/FetchHttpClient\"\n\nimport { makeControlCenterApiClient } from \"../../api/client.js\"\nimport type {\n UpdateWorkspaceSettingsRequest,\n WorkspacePresentationReadModel,\n WorkspaceSettingsReadModel\n} from \"../../api/workspaceSettings.js\"\nimport { WorkspaceSettingsMutationId } from \"../../domain/identifiers.js\"\nimport { makeAuthenticatedMutationClient } from \"../authenticatedMutationClient.js\"\n\n/** Browser boundary for authenticated settings reads and owner-authorized mutations. */\nexport interface WorkspaceSettingsTransport {\n readonly load: (signal: AbortSignal) => Promise<WorkspaceSettingsReadModel>\n readonly makeMutationId: () => Promise<WorkspaceSettingsMutationId>\n readonly update: (\n request: UpdateWorkspaceSettingsRequest,\n signal: AbortSignal\n ) => Promise<WorkspaceSettingsReadModel>\n}\n\n/** Browser boundary for collaborator-safe presentation defaults. */\nexport interface WorkspacePresentationTransport {\n readonly load: (signal: AbortSignal) => Promise<WorkspacePresentationReadModel>\n}\n\n/** Generated API transport exposing only shared presentation settings. */\nexport const browserWorkspacePresentationTransport: WorkspacePresentationTransport = {\n load: (signal) =>\n Effect.runPromise(\n Effect.gen(function*() {\n const client = yield* makeControlCenterApiClient()\n return yield* client.workspaceSettings.readPresentation()\n }).pipe(Effect.provide(FetchHttpClient.layer)),\n { signal }\n )\n}\n\n/** Generated API transport with a retry-stable UUIDv7 mutation identity. */\nexport const browserWorkspaceSettingsTransport: WorkspaceSettingsTransport = {\n load: (signal) =>\n Effect.runPromise(\n Effect.gen(function*() {\n const client = yield* makeControlCenterApiClient()\n return yield* client.workspaceSettings.read()\n }).pipe(Effect.provide(FetchHttpClient.layer)),\n { signal }\n ),\n makeMutationId: () =>\n Effect.runPromise(\n Effect.gen(function*() {\n const cryptoService = yield* Crypto.Crypto\n return yield* Schema.decodeUnknownEffect(\n WorkspaceSettingsMutationId\n )(yield* cryptoService.randomUUIDv7)\n }).pipe(Effect.provide(BrowserCrypto.layer))\n ),\n update: (request, signal) =>\n Effect.runPromise(\n Effect.gen(function*() {\n const client = yield* makeAuthenticatedMutationClient\n return yield* client.workspaceSettings.update({ payload: request })\n }).pipe(Effect.provide(FetchHttpClient.layer)),\n { signal }\n )\n}\n"],"mappings":"kPA+BA,IAAa,EAAwE,CACnF,KAAO,GACL,EACE,EAAW,WAAY,CAErB,OAAO,OAAO,MADQ,EAA2B,EAAA,CAC5B,kBAAkB,iBAAiB,CAC1D,CAAC,CAAC,CAAC,KAAK,EAAe,CAAqB,CAAC,EAC7C,CAAE,QAAO,CACX,CACJ,EAGa,EAAgE,CAC3E,KAAO,GACL,EACE,EAAW,WAAY,CAErB,OAAO,OAAO,MADQ,EAA2B,EAAA,CAC5B,kBAAkB,KAAK,CAC9C,CAAC,CAAC,CAAC,KAAK,EAAe,CAAqB,CAAC,EAC7C,CAAE,QAAO,CACX,EACF,mBACE,EACE,EAAW,WAAY,CACrB,IAAM,EAAgB,MAAO,EAC7B,OAAO,MAAO,EACZ,CACF,CAAC,CAAC,MAAO,EAAc,YAAY,CACrC,CAAC,CAAC,CAAC,KAAK,EAAe,CAAmB,CAAC,CAC7C,EACF,QAAS,EAAS,IAChB,EACE,EAAW,WAAY,CAErB,OAAO,OAAO,MADQ,EAAA,CACD,kBAAkB,OAAO,CAAE,QAAS,CAAQ,CAAC,CACpE,CAAC,CAAC,CAAC,KAAK,EAAe,CAAqB,CAAC,EAC7C,CAAE,QAAO,CACX,CACJ"}
1
+ {"version":3,"file":"workspaceSettingsTransport-BwRQteEH.js","names":[],"sources":["../../../src/client/settings/workspaceSettingsTransport.ts"],"sourcesContent":["import * as BrowserCrypto from \"@effect/platform-browser/BrowserCrypto\"\nimport * as Crypto from \"effect/Crypto\"\nimport * as Effect from \"effect/Effect\"\nimport * as Schema from \"effect/Schema\"\nimport * as FetchHttpClient from \"effect/unstable/http/FetchHttpClient\"\n\nimport { makeControlCenterApiClient } from \"../../api/client.js\"\nimport type {\n UpdateWorkspaceSettingsRequest,\n WorkspacePresentationReadModel,\n WorkspaceSettingsReadModel\n} from \"../../api/workspaceSettings.js\"\nimport { WorkspaceSettingsMutationId } from \"../../domain/identifiers.js\"\nimport { makeAuthenticatedMutationClient } from \"../authenticatedMutationClient.js\"\n\n/** Browser boundary for authenticated settings reads and owner-authorized mutations. */\nexport interface WorkspaceSettingsTransport {\n readonly load: (signal: AbortSignal) => Promise<WorkspaceSettingsReadModel>\n readonly makeMutationId: () => Promise<WorkspaceSettingsMutationId>\n readonly update: (\n request: UpdateWorkspaceSettingsRequest,\n signal: AbortSignal\n ) => Promise<WorkspaceSettingsReadModel>\n}\n\n/** Browser boundary for collaborator-safe presentation defaults. */\nexport interface WorkspacePresentationTransport {\n readonly load: (signal: AbortSignal) => Promise<WorkspacePresentationReadModel>\n}\n\n/** Generated API transport exposing only shared presentation settings. */\nexport const browserWorkspacePresentationTransport: WorkspacePresentationTransport = {\n load: (signal) =>\n Effect.runPromise(\n Effect.gen(function*() {\n const client = yield* makeControlCenterApiClient()\n return yield* client.workspaceSettings.readPresentation()\n }).pipe(Effect.provide(FetchHttpClient.layer)),\n { signal }\n )\n}\n\n/** Generated API transport with a retry-stable UUIDv7 mutation identity. */\nexport const browserWorkspaceSettingsTransport: WorkspaceSettingsTransport = {\n load: (signal) =>\n Effect.runPromise(\n Effect.gen(function*() {\n const client = yield* makeControlCenterApiClient()\n return yield* client.workspaceSettings.read()\n }).pipe(Effect.provide(FetchHttpClient.layer)),\n { signal }\n ),\n makeMutationId: () =>\n Effect.runPromise(\n Effect.gen(function*() {\n const cryptoService = yield* Crypto.Crypto\n return yield* Schema.decodeUnknownEffect(\n WorkspaceSettingsMutationId\n )(yield* cryptoService.randomUUIDv7)\n }).pipe(Effect.provide(BrowserCrypto.layer))\n ),\n update: (request, signal) =>\n Effect.runPromise(\n Effect.gen(function*() {\n const client = yield* makeAuthenticatedMutationClient\n return yield* client.workspaceSettings.update({ payload: request })\n }).pipe(Effect.provide(FetchHttpClient.layer)),\n { signal }\n )\n}\n"],"mappings":"6OA+BA,IAAa,EAAwE,CACnF,KAAO,GACL,EACE,EAAW,WAAY,CAErB,OAAO,OAAO,MADQ,EAA2B,EAAA,CAC5B,kBAAkB,iBAAiB,CAC1D,CAAC,CAAC,CAAC,KAAK,EAAe,CAAqB,CAAC,EAC7C,CAAE,QAAO,CACX,CACJ,EAGa,EAAgE,CAC3E,KAAO,GACL,EACE,EAAW,WAAY,CAErB,OAAO,OAAO,MADQ,EAA2B,EAAA,CAC5B,kBAAkB,KAAK,CAC9C,CAAC,CAAC,CAAC,KAAK,EAAe,CAAqB,CAAC,EAC7C,CAAE,QAAO,CACX,EACF,mBACE,EACE,EAAW,WAAY,CACrB,IAAM,EAAgB,MAAO,EAC7B,OAAO,MAAO,EACZ,CACF,CAAC,CAAC,MAAO,EAAc,YAAY,CACrC,CAAC,CAAC,CAAC,KAAK,EAAe,CAAmB,CAAC,CAC7C,EACF,QAAS,EAAS,IAChB,EACE,EAAW,WAAY,CAErB,OAAO,OAAO,MADQ,EAAA,CACD,kBAAkB,OAAO,CAAE,QAAS,CAAQ,CAAC,CACpE,CAAC,CAAC,CAAC,KAAK,EAAe,CAAqB,CAAC,EAC7C,CAAE,QAAO,CACX,CACJ"}
@@ -316,6 +316,7 @@
316
316
  "npm:react-router/dist/production/index.js",
317
317
  "src/client/BrowserSession.tsx",
318
318
  "src/client/contextualAgentPath.ts",
319
+ "src/client/controlCenterRelayDockShell.tsx",
319
320
  "src/client/settings/workspaceSettingsSignals.ts",
320
321
  "src/client/AppShell.module.css",
321
322
  "src/client/workspaceScrollRestoration.tsx",
@@ -432,6 +433,66 @@
432
433
  ],
433
434
  "isEntry": false
434
435
  },
436
+ {
437
+ "dynamicImports": [],
438
+ "id": "src/client/controlCenterRelayDock.tsx",
439
+ "imports": [
440
+ "workspace:relay-product/dist/conversation.js",
441
+ "workspace:relay-product/dist/index.js",
442
+ "workspace:relay-product/dist/model.js",
443
+ "npm:effect/dist/Result.js",
444
+ "npm:effect/dist/Schema.js"
445
+ ],
446
+ "isEntry": false
447
+ },
448
+ {
449
+ "dynamicImports": [
450
+ "src/client/openPullRequest/openPullRequest.ts"
451
+ ],
452
+ "id": "src/client/controlCenterRelayDockChrome.tsx",
453
+ "imports": [
454
+ "workspace:relay-product/dist/index.js",
455
+ "npm:effect/dist/Effect.js",
456
+ "npm:effect/dist/Schema.js",
457
+ "npm:react/index.js",
458
+ "npm:react-router/dist/production/index.js",
459
+ "workspace:codecommit-core/src/Domain.ts",
460
+ "src/client/BrowserSession.tsx",
461
+ "src/client/controlCenterRelayDock.tsx",
462
+ "src/client/workspaceEntityPaths.ts",
463
+ "npm:react/jsx-runtime.js",
464
+ "\u0000vite/preload-helper.js"
465
+ ],
466
+ "isEntry": false
467
+ },
468
+ {
469
+ "dynamicImports": [
470
+ "src/client/controlCenterRelayDockChrome.tsx"
471
+ ],
472
+ "id": "src/client/controlCenterRelayDockShell.tsx",
473
+ "imports": [
474
+ "workspace:relay-product/dist/registry.js",
475
+ "npm:react/index.js",
476
+ "npm:react/jsx-runtime.js",
477
+ "\u0000vite/preload-helper.js"
478
+ ],
479
+ "isEntry": false
480
+ },
481
+ {
482
+ "dynamicImports": [],
483
+ "id": "src/client/controlCenterRelayThread.tsx",
484
+ "imports": [
485
+ "workspace:relay-product/dist/index.js",
486
+ "npm:effect/dist/Effect.js",
487
+ "npm:effect/dist/Result.js",
488
+ "npm:effect/dist/Schema.js",
489
+ "npm:react/index.js",
490
+ "src/api/agent.ts",
491
+ "src/client/controlCenterRelayDock.tsx",
492
+ "src/client/workspaceEntityPaths.ts"
493
+ ],
494
+ "isEntry": false
495
+ },
435
496
  {
436
497
  "dynamicImports": [],
437
498
  "id": "src/client/entities/DiffLineFocus.tsx",
@@ -639,6 +700,7 @@
639
700
  "id": "src/client/entities/usePullRequestReview.ts",
640
701
  "imports": [
641
702
  "workspace:review/dist/index.js",
703
+ "npm:effect/dist/Data.js",
642
704
  "npm:effect/dist/DateTime.js",
643
705
  "npm:effect/dist/Duration.js",
644
706
  "npm:effect/dist/Effect.js",
@@ -778,6 +840,7 @@
778
840
  "npm:react/index.js",
779
841
  "npm:react-router/dist/production/index.js",
780
842
  "src/client/BrowserSession.tsx",
843
+ "src/client/controlCenterRelayThread.tsx",
781
844
  "src/client/items/workspaceEntityRoutes.ts",
782
845
  "src/client/entities/presentWorkspaceEntity.ts",
783
846
  "src/client/entities/WorkspaceEntityLink.tsx",
@@ -10,7 +10,7 @@
10
10
  />
11
11
  <link rel="icon" href="/favicon.svg" type="image/svg+xml" />
12
12
  <title>Control Center</title>
13
- <script type="module" crossorigin src="/assets/index-BWx9sNOT.js"></script>
13
+ <script type="module" crossorigin src="/assets/index-kmYFvwT0.js"></script>
14
14
  <link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-hePW80VL.js">
15
15
  <link rel="modulepreload" crossorigin href="/assets/react-CwJFpaho.js">
16
16
  <link rel="modulepreload" crossorigin href="/assets/loader-circle-Dem7LJJw.js">
@@ -18,9 +18,9 @@
18
18
  <link rel="modulepreload" crossorigin href="/assets/preload-helper-Czpn1I53.js">
19
19
  <link rel="modulepreload" crossorigin href="/assets/lib-6h955hh9.js">
20
20
  <link rel="modulepreload" crossorigin href="/assets/jsx-runtime-NZYk81nU.js">
21
- <link rel="modulepreload" crossorigin href="/assets/PortalProvider-BpgZwSpw-nEH0TqWT.js">
21
+ <link rel="modulepreload" crossorigin href="/assets/PortalProvider-CN_81Fy3-D_japesx.js">
22
22
  <link rel="modulepreload" crossorigin href="/assets/releasePaths-XoI2BHX3.js">
23
- <link rel="stylesheet" crossorigin href="/assets/index-CIfiz7oF.css">
23
+ <link rel="stylesheet" crossorigin href="/assets/index-tjRpNCt_.css">
24
24
  </head>
25
25
  <body>
26
26
  <div id="root"></div>