@knpkv/control-center 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +70 -17
- package/dist/client/.vite/manifest.json +223 -178
- package/dist/client/assets/{ActiveWorkPage-DJQgGZeV.js → ActiveWorkPage-g2-Jyavo.js} +2 -2
- package/dist/client/assets/{ActiveWorkPage-DJQgGZeV.js.map → ActiveWorkPage-g2-Jyavo.js.map} +1 -1
- package/dist/client/assets/AgentPage-B6GQdZAs.css +1 -0
- package/dist/client/assets/AgentPage-DmVsEe13.js +6 -0
- package/dist/client/assets/AgentPage-DmVsEe13.js.map +1 -0
- package/dist/client/assets/AtlassianOAuthCallbackPage-C8u9ItMj.js +2 -0
- package/dist/client/assets/{AtlassianOAuthCallbackPage-D1F1xE_2.js.map → AtlassianOAuthCallbackPage-C8u9ItMj.js.map} +1 -1
- package/dist/client/assets/AuthorizedSharePage-CVBJ1NTm.js +2 -0
- package/dist/client/assets/AuthorizedSharePage-CVBJ1NTm.js.map +1 -0
- package/dist/client/assets/BrowserCrypto-3BoTVFdl.js +2 -0
- package/dist/client/assets/{BrowserCrypto-DVWR7DFd.js.map → BrowserCrypto-3BoTVFdl.js.map} +1 -1
- package/dist/client/assets/BrowserSessionHydrator-CpZnNm4X.js +2 -0
- package/dist/client/assets/BrowserSessionHydrator-CpZnNm4X.js.map +1 -0
- package/dist/client/assets/CommandSearch-DUeRRbV2.js +2 -0
- package/dist/client/assets/{CommandSearch-CP_QCbkm.js.map → CommandSearch-DUeRRbV2.js.map} +1 -1
- package/dist/client/assets/ItemsPage-BF2ZkSzh.js +2 -0
- package/dist/client/assets/{ItemsPage-BGFUkRL2.js.map → ItemsPage-BF2ZkSzh.js.map} +1 -1
- package/dist/client/assets/{PairPage-DIgzx0K2.js → PairPage-CkaZltHd.js} +2 -2
- package/dist/client/assets/{PairPage-DIgzx0K2.js.map → PairPage-CkaZltHd.js.map} +1 -1
- package/dist/client/assets/PortfolioOverview-CEUHJmGC.js +2 -0
- package/dist/client/assets/PortfolioOverview-CEUHJmGC.js.map +1 -0
- package/dist/client/assets/PullRequestReviewPanel-D1IpvHe2.js +6 -0
- package/dist/client/assets/PullRequestReviewPanel-D1IpvHe2.js.map +1 -0
- package/dist/client/assets/ReleaseRoute-BuQybrsg.js +2 -0
- package/dist/client/assets/{ReleaseRoute-DXJ8Jg60.js.map → ReleaseRoute-BuQybrsg.js.map} +1 -1
- package/dist/client/assets/ReleaseWorkset-BclY0Nvj.js +2 -0
- package/dist/client/assets/ReleaseWorkset-BclY0Nvj.js.map +1 -0
- package/dist/client/assets/ServicesPage-hw5Ee69-.js +2 -0
- package/dist/client/assets/ServicesPage-hw5Ee69-.js.map +1 -0
- package/dist/client/assets/TimelinePage-Cj3V98uI.js +2 -0
- package/dist/client/assets/TimelinePage-Cj3V98uI.js.map +1 -0
- package/dist/client/assets/WorkspaceEntityLink-C_rc8lxi.js +2 -0
- package/dist/client/assets/{WorkspaceEntityLink-AdZ_T-Wk.js.map → WorkspaceEntityLink-C_rc8lxi.js.map} +1 -1
- package/dist/client/assets/WorkspaceEntityRoute-DLLT6fY0.css +1 -0
- package/dist/client/assets/WorkspaceEntityRoute-kbnrQ_lY.js +14 -0
- package/dist/client/assets/WorkspaceEntityRoute-kbnrQ_lY.js.map +1 -0
- package/dist/client/assets/WorkspaceHomeLink-DeYYLEsH.js +2 -0
- package/dist/client/assets/{WorkspaceHomeLink-XbKSPths.js.map → WorkspaceHomeLink-DeYYLEsH.js.map} +1 -1
- package/dist/client/assets/{WorkspacePullRequestDetails-BErJ5bk8.js → WorkspacePullRequestDetails-CizqydjN.js} +3 -3
- package/dist/client/assets/WorkspacePullRequestDetails-CizqydjN.js.map +1 -0
- package/dist/client/assets/{WorkspaceReleaseLayout-cfboC5Qh.js → WorkspaceReleaseLayout-CXAQUhkh.js} +2 -2
- package/dist/client/assets/{WorkspaceReleaseLayout-cfboC5Qh.js.map → WorkspaceReleaseLayout-CXAQUhkh.js.map} +1 -1
- package/dist/client/assets/{WorkspaceRichText-D1M637Ff.js → WorkspaceRichText-CCOciILO.js} +2 -2
- package/dist/client/assets/WorkspaceRichText-CCOciILO.js.map +1 -0
- package/dist/client/assets/WorkspaceSettingsPage-GoBfQzBx.css +1 -0
- package/dist/client/assets/WorkspaceSettingsPage-JG-pN_CA.js +2 -0
- package/dist/client/assets/WorkspaceSettingsPage-JG-pN_CA.js.map +1 -0
- package/dist/client/assets/agent-api-Dl9TuGOJ.js +19 -0
- package/dist/client/assets/agent-api-Dl9TuGOJ.js.map +1 -0
- package/dist/client/assets/atlassianOAuthSetupIntentStorage-DE4ySCTb.js +2 -0
- package/dist/client/assets/atlassianOAuthSetupIntentStorage-DE4ySCTb.js.map +1 -0
- package/dist/client/assets/authenticatedMutationClient-DdowMjyo.js +2 -0
- package/dist/client/assets/{authenticatedMutationClient-Ccwguc3i.js.map → authenticatedMutationClient-DdowMjyo.js.map} +1 -1
- package/dist/client/assets/authorizedShareTransport-CnclcYai.js +2 -0
- package/dist/client/assets/{authorizedShareTransport-DZHgFEkh.js.map → authorizedShareTransport-CnclcYai.js.map} +1 -1
- package/dist/client/assets/client-Dq_XQE_l.js +5 -0
- package/dist/client/assets/client-Dq_XQE_l.js.map +1 -0
- package/dist/client/assets/confluenceTasks-DtKq8_eU.js +5 -0
- package/dist/client/assets/confluenceTasks-DtKq8_eU.js.map +1 -0
- package/dist/client/assets/connectionTestTransport-CPK98z7H.js +2 -0
- package/dist/client/assets/connectionTestTransport-CPK98z7H.js.map +1 -0
- package/dist/client/assets/index-zVjlBm9l.js +11 -0
- package/dist/client/assets/index-zVjlBm9l.js.map +1 -0
- package/dist/client/assets/{patterns-5N-j-AD2-BwypFm-e.js → patterns-5N-j-AD2-DLfaGePK.js} +2 -2
- package/dist/client/assets/{patterns-5N-j-AD2-BwypFm-e.js.map → patterns-5N-j-AD2-DLfaGePK.js.map} +1 -1
- package/dist/client/assets/{presentPortfolio-D3ZIcnqt.js → presentPortfolio-DLEq-vEz.js} +2 -2
- package/dist/client/assets/presentPortfolio-DLEq-vEz.js.map +1 -0
- package/dist/client/assets/{presentWorkspaceItems-Bmh4oEbH.js → presentWorkspaceItems-BOY3FbhO.js} +2 -2
- package/dist/client/assets/{presentWorkspaceItems-Bmh4oEbH.js.map → presentWorkspaceItems-BOY3FbhO.js.map} +1 -1
- package/dist/client/assets/{pullRequestReviewFailures-S74M-fOk.js → pullRequestReviewFailures-CyjTVnSX.js} +2 -2
- package/dist/client/assets/{pullRequestReviewFailures-S74M-fOk.js.map → pullRequestReviewFailures-CyjTVnSX.js.map} +1 -1
- package/dist/client/assets/pullRequestReviewThreadReplay-CXHspFTr.js +2 -0
- package/dist/client/assets/pullRequestReviewThreadReplay-CXHspFTr.js.map +1 -0
- package/dist/client/assets/releaseAgentTransport-DaO4svPu.js +2 -0
- package/dist/client/assets/releaseAgentTransport-DaO4svPu.js.map +1 -0
- package/dist/client/assets/releaseRoutes-B4ciNOJj.js +2 -0
- package/dist/client/assets/{releaseRoutes-BCuIdZyA.js.map → releaseRoutes-B4ciNOJj.js.map} +1 -1
- package/dist/client/assets/serviceOnboarding-D0FmodRi.js +2 -0
- package/dist/client/assets/{serviceOnboarding-Jg_0yNjf.js.map → serviceOnboarding-D0FmodRi.js.map} +1 -1
- package/dist/client/assets/{useWorkspaceDefaultLanding-CzlDdEF-.js → useWorkspaceDefaultLanding-BaQdg0sY.js} +3 -3
- package/dist/client/assets/{useWorkspaceDefaultLanding-CzlDdEF-.js.map → useWorkspaceDefaultLanding-BaQdg0sY.js.map} +1 -1
- package/dist/client/assets/{useWorkspaceItems-Cd3MPke2.js → useWorkspaceItems-B-7JHtm0.js} +2 -2
- package/dist/client/assets/{useWorkspaceItems-Cd3MPke2.js.map → useWorkspaceItems-B-7JHtm0.js.map} +1 -1
- package/dist/client/assets/workspaceEntityRoutes-DqqDa0AB.js +2 -0
- package/dist/client/assets/workspaceEntityRoutes-DqqDa0AB.js.map +1 -0
- package/dist/client/assets/workspaceScrollCapture-BYNfR2wo.js +2 -0
- package/dist/client/assets/workspaceScrollCapture-BYNfR2wo.js.map +1 -0
- package/dist/client/assets/workspaceSettingsTransport-Br4lBmvS.js +2 -0
- package/dist/client/assets/{workspaceSettingsTransport-CZWYL5T7.js.map → workspaceSettingsTransport-Br4lBmvS.js.map} +1 -1
- package/dist/client/build-graph.json +115 -0
- package/dist/client/index.html +1 -1
- package/dist/server/api/agent.d.ts +575 -44
- package/dist/server/api/agent.d.ts.map +1 -1
- package/dist/server/api/deliveryGraph.d.ts +474 -454
- package/dist/server/api/deliveryGraph.d.ts.map +1 -1
- package/dist/server/api/index.d.ts +2 -2
- package/dist/server/api/index.d.ts.map +1 -1
- package/dist/server/api/index.js +4 -4
- package/dist/server/api/liveEvents.d.ts +20 -0
- package/dist/server/api/liveEvents.d.ts.map +1 -1
- package/dist/server/api/portfolio.d.ts +23 -0
- package/dist/server/api/portfolio.d.ts.map +1 -1
- package/dist/server/api/session.d.ts +23 -1
- package/dist/server/api/session.d.ts.map +1 -1
- package/dist/server/api/shares.d.ts +4 -2
- package/dist/server/api/shares.d.ts.map +1 -1
- package/dist/server/assets/{BindConfig-DIsf2Rnh.js → BindConfig-DAASchDn.js} +2405 -322
- package/dist/server/assets/BindConfig-DAASchDn.js.map +1 -0
- package/dist/server/assets/{CodePipelineStateDecoder-CVf1A2zG.js → CodePipelineStateDecoder-CNiFRgSi.js} +2 -2
- package/dist/server/assets/{CodePipelineStateDecoder-CVf1A2zG.js.map → CodePipelineStateDecoder-CNiFRgSi.js.map} +1 -1
- package/dist/server/assets/{agent-CyZ40zs1.js → agent-xQhAQXly.js} +181 -11
- package/dist/server/assets/agent-xQhAQXly.js.map +1 -0
- package/dist/server/assets/{controlCenterApi-ZUX3Y-LE.js → controlCenterApi-DNXK7MT1.js} +6 -5
- package/dist/server/assets/controlCenterApi-DNXK7MT1.js.map +1 -0
- package/dist/server/assets/{descriptor-CKtTnhef.js → descriptor-CCvNzSZL.js} +10 -10
- package/dist/server/assets/{descriptor-CKtTnhef.js.map → descriptor-CCvNzSZL.js.map} +1 -1
- package/dist/server/assets/{failures-mgYDkUZy.js → failures-CesHLYbN.js} +2 -2
- package/dist/server/assets/{failures-mgYDkUZy.js.map → failures-CesHLYbN.js.map} +1 -1
- package/dist/server/assets/{firstPartyServices-D7b8BOek.js → firstPartyServices-Cdzjcs2H.js} +2 -2
- package/dist/server/assets/{firstPartyServices-D7b8BOek.js.map → firstPartyServices-Cdzjcs2H.js.map} +1 -1
- package/dist/server/assets/{manualPluginSynchronization-DFlhKvav.js → manualPluginSynchronization-DFIeUHP9.js} +6 -5
- package/dist/server/assets/manualPluginSynchronization-DFIeUHP9.js.map +1 -0
- package/dist/server/assets/{plugins-D__oMDpI.js → plugins-DiPrfzV8.js} +2 -2
- package/dist/server/assets/{plugins-D__oMDpI.js.map → plugins-DiPrfzV8.js.map} +1 -1
- package/dist/server/assets/{readiness-BhA-Nr9c.js → readiness-31Mqc-9H.js} +3 -3
- package/dist/server/assets/{readiness-BhA-Nr9c.js.map → readiness-31Mqc-9H.js.map} +1 -1
- package/dist/server/assets/{relationshipInferenceMaterialization-DYBcaWhQ.js → relationshipInferenceMaterialization-Dyix96px.js} +1158 -169
- package/dist/server/assets/relationshipInferenceMaterialization-Dyix96px.js.map +1 -0
- package/dist/server/assets/{workspaceSettings-BE713Oe8.js → workspaceSettings-sv8h_h2P.js} +2787 -2700
- package/dist/server/assets/workspaceSettings-sv8h_h2P.js.map +1 -0
- package/dist/server/build-graph.json +144 -4
- package/dist/server/domain/actors.d.ts +12 -12
- package/dist/server/domain/confluenceTasks.d.ts +27 -0
- package/dist/server/domain/confluenceTasks.d.ts.map +1 -0
- package/dist/server/domain/deliveryGraph.d.ts +51 -49
- package/dist/server/domain/deliveryGraph.d.ts.map +1 -1
- package/dist/server/domain/governedAction/bindings.d.ts +26 -12
- package/dist/server/domain/governedAction/bindings.d.ts.map +1 -1
- package/dist/server/domain/governedAction/lifecycle.d.ts +8 -8
- package/dist/server/domain/governedAction/model.d.ts +45 -18
- package/dist/server/domain/governedAction/model.d.ts.map +1 -1
- package/dist/server/domain/governedAction/stateMachine.d.ts +34 -34
- package/dist/server/domain/index.js +6 -6
- package/dist/server/domain/normalizedIssue.d.ts +1 -1
- package/dist/server/domain/normalizedPage.d.ts +1 -0
- package/dist/server/domain/normalizedPage.d.ts.map +1 -1
- package/dist/server/domain/prReview.d.ts +38 -0
- package/dist/server/domain/prReview.d.ts.map +1 -1
- package/dist/server/domain/prReviewReconciliation.d.ts +56 -0
- package/dist/server/domain/prReviewReconciliation.d.ts.map +1 -0
- package/dist/server/domain/prReviewRevision.d.ts +1 -0
- package/dist/server/domain/prReviewRevision.d.ts.map +1 -1
- package/dist/server/domain/readiness/model.d.ts +3 -3
- package/dist/server/domain/release.d.ts +3 -3
- package/dist/server/domain/releasePipelineApproval.d.ts +31 -0
- package/dist/server/domain/releasePipelineApproval.d.ts.map +1 -0
- package/dist/server/domain/releasePublication.d.ts +4 -0
- package/dist/server/domain/releasePublication.d.ts.map +1 -0
- package/dist/server/index.js +8 -8
- package/dist/server/server/agent/AgentJobWorker.d.ts +10 -1
- package/dist/server/server/agent/AgentJobWorker.d.ts.map +1 -1
- package/dist/server/server/agent/ReleaseAgentPrompt.d.ts.map +1 -1
- package/dist/server/server/agent/internal/AgentJobTaskExecutor.d.ts +4 -3
- package/dist/server/server/agent/internal/AgentJobTaskExecutor.d.ts.map +1 -1
- package/dist/server/server/agent/internal/PrReviewSandboxSession.d.ts +17 -1
- package/dist/server/server/agent/internal/PrReviewSandboxSession.d.ts.map +1 -1
- package/dist/server/server/agent/internal/PrReviewTaskExecutor.d.ts +76 -2
- package/dist/server/server/agent/internal/PrReviewTaskExecutor.d.ts.map +1 -1
- package/dist/server/server/agent/internal/PrReviewTelemetry.d.ts +27 -0
- package/dist/server/server/agent/internal/PrReviewTelemetry.d.ts.map +1 -0
- package/dist/server/server/api/ApplicationServices.d.ts +39 -5
- package/dist/server/server/api/ApplicationServices.d.ts.map +1 -1
- package/dist/server/server/api/Handlers.d.ts +1 -1
- package/dist/server/server/api/Handlers.d.ts.map +1 -1
- package/dist/server/server/api/RequestBoundary.d.ts.map +1 -1
- package/dist/server/server/application/GovernedReviewSuggestionPublicationGateway.d.ts.map +1 -1
- package/dist/server/server/application/ReviewSuggestionPublicationGateway.d.ts +4 -0
- package/dist/server/server/application/ReviewSuggestionPublicationGateway.d.ts.map +1 -1
- package/dist/server/server/application/deliveryGraphInspection.d.ts.map +1 -1
- package/dist/server/server/application/index.d.ts +1 -0
- package/dist/server/server/application/index.d.ts.map +1 -1
- package/dist/server/server/application/liveEvents.d.ts.map +1 -1
- package/dist/server/server/application/normalizedPluginPageMaterialization.d.ts.map +1 -1
- package/dist/server/server/application/pipelineExecutionProjection.d.ts +7 -6
- package/dist/server/server/application/pipelineExecutionProjection.d.ts.map +1 -1
- package/dist/server/server/application/portfolioSnapshots.d.ts +2018 -4
- package/dist/server/server/application/portfolioSnapshots.d.ts.map +1 -1
- package/dist/server/server/application/pullRequestReviews.d.ts.map +1 -1
- package/dist/server/server/application/releaseAgent.d.ts +11 -3
- package/dist/server/server/application/releaseAgent.d.ts.map +1 -1
- package/dist/server/server/application/releasePublicationIntent.d.ts +7 -0
- package/dist/server/server/application/releasePublicationIntent.d.ts.map +1 -0
- package/dist/server/server/application/releasePublicationMetadata.d.ts +61 -0
- package/dist/server/server/application/releasePublicationMetadata.d.ts.map +1 -0
- package/dist/server/server/application/releasePublicationSubmissions.d.ts +3730 -0
- package/dist/server/server/application/releasePublicationSubmissions.d.ts.map +1 -0
- package/dist/server/server/application/releaseRunbookHydration.d.ts +2310 -0
- package/dist/server/server/application/releaseRunbookHydration.d.ts.map +1 -0
- package/dist/server/server/application/releaseSynchronization.d.ts.map +1 -1
- package/dist/server/server/cli.js +8 -8
- package/dist/server/server/cli.js.map +1 -1
- package/dist/server/server/governance/governedActionDigests.d.ts +236 -218
- package/dist/server/server/governance/governedActionDigests.d.ts.map +1 -1
- package/dist/server/server/governance/internal/GovernedActionExecutionEngine.d.ts +3 -4
- package/dist/server/server/governance/internal/GovernedActionExecutionEngine.d.ts.map +1 -1
- package/dist/server/server/governance/internal/execution-store/begin.d.ts.map +1 -1
- package/dist/server/server/governance/internal/execution-store/dispatch-inbox.d.ts +1 -1
- package/dist/server/server/governance/internal/execution-store/dispatch-outcome.d.ts +8 -8
- package/dist/server/server/governance/internal/execution-store/provider-outcome-fold.d.ts +2 -2
- package/dist/server/server/governance/internal/execution-store/reconciliation-inbox.d.ts +1 -1
- package/dist/server/server/governance/internal/execution-store/recovery-claim.d.ts +37 -30
- package/dist/server/server/governance/internal/execution-store/recovery-claim.d.ts.map +1 -1
- package/dist/server/server/index.js +5 -5
- package/dist/server/server/internal/codepipeline-state-probe.js +1 -1
- package/dist/server/server/persistence/Database.d.ts +1 -1
- package/dist/server/server/persistence/Database.d.ts.map +1 -1
- package/dist/server/server/persistence/Persistence.d.ts +1549 -577
- package/dist/server/server/persistence/Persistence.d.ts.map +1 -1
- package/dist/server/server/persistence/backup/BackupArchive.d.ts.map +1 -1
- package/dist/server/server/persistence/object-store/BlobPublisher.d.ts.map +1 -1
- package/dist/server/server/persistence/object-store/PinnedDirectory.d.ts +2 -2
- package/dist/server/server/persistence/object-store/PinnedDirectory.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/agentJobModels.d.ts +345 -8
- package/dist/server/server/persistence/repositories/agentJobModels.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/agentJobRepository.d.ts +654 -192
- package/dist/server/server/persistence/repositories/agentJobRepository.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/delivery-graph/contract.d.ts +148 -138
- package/dist/server/server/persistence/repositories/delivery-graph/contract.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/delivery-graph/decode.d.ts +27 -25
- package/dist/server/server/persistence/repositories/delivery-graph/decode.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/delivery-graph/read.d.ts +117 -111
- package/dist/server/server/persistence/repositories/delivery-graph/read.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/delivery-graph/rows.d.ts +28 -27
- package/dist/server/server/persistence/repositories/delivery-graph/rows.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/delivery-graph/write.d.ts +50 -48
- package/dist/server/server/persistence/repositories/delivery-graph/write.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/deliveryGraphRepository.d.ts +117 -111
- package/dist/server/server/persistence/repositories/deliveryGraphRepository.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/governed-action/codec.d.ts +259 -234
- package/dist/server/server/persistence/repositories/governed-action/codec.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/governed-action/contract.d.ts +68 -46
- package/dist/server/server/persistence/repositories/governed-action/contract.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/governed-action/read.d.ts +668 -190
- package/dist/server/server/persistence/repositories/governed-action/read.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/governed-action/transaction.d.ts +680 -206
- package/dist/server/server/persistence/repositories/governed-action/transaction.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/governed-action/write-preparation.d.ts +38 -31
- package/dist/server/server/persistence/repositories/governed-action/write-preparation.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/governed-action/write-replay.d.ts +46 -32
- package/dist/server/server/persistence/repositories/governed-action/write-replay.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/governed-action/write.d.ts +46 -32
- package/dist/server/server/persistence/repositories/governed-action/write.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/governedActionRepository.d.ts +678 -205
- package/dist/server/server/persistence/repositories/governedActionRepository.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/internal/reviewSuggestionRevisions.d.ts +85 -4
- package/dist/server/server/persistence/repositories/internal/reviewSuggestionRevisions.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/models.d.ts +9 -9
- package/dist/server/server/persistence/repositories/peopleRepository.d.ts +36 -36
- package/dist/server/server/persistence/repositories/providerAccountRepository.d.ts +1 -1
- package/dist/server/server/persistence/repositories/readiness/assessments.d.ts +6 -6
- package/dist/server/server/persistence/repositories/readiness/contract.d.ts +450 -450
- package/dist/server/server/persistence/repositories/readiness/queue.d.ts +14 -14
- package/dist/server/server/persistence/repositories/readinessRepository.d.ts +7 -7
- package/dist/server/server/persistence/repositories/releaseRepository.d.ts +18 -18
- package/dist/server/server/persistence/repositories/retentionRepository.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/timelineRepository.d.ts +4 -4
- package/dist/server/server/plugins/atlassian/AtlassianOAuthGrants.d.ts.map +1 -1
- package/dist/server/server/plugins/atlassian/AtlassianOAuthScopes.d.ts +9 -0
- package/dist/server/server/plugins/atlassian/AtlassianOAuthScopes.d.ts.map +1 -0
- package/dist/server/server/plugins/atlassian/AtlassianProfiles.d.ts.map +1 -1
- package/dist/server/server/plugins/codecommit/CodeCommitPluginDefinition.d.ts.map +1 -1
- package/dist/server/server/plugins/jira/JiraReadPlugin.d.ts +2 -2
- package/dist/server/server/plugins/jira/JiraReadPlugin.d.ts.map +1 -1
- package/dist/server/server/plugins/jira/JiraReadProvider.d.ts.map +1 -1
- package/dist/server/server/plugins/jira/JiraReleaseVersionLimits.d.ts +8 -0
- package/dist/server/server/plugins/jira/JiraReleaseVersionLimits.d.ts.map +1 -0
- package/dist/server/server/plugins/jira/index.d.ts +1 -1
- package/dist/server/server/plugins/jira/index.d.ts.map +1 -1
- package/dist/server/server/runtime/Bootstrap.d.ts +1 -1
- package/dist/server/server/runtime/Bootstrap.d.ts.map +1 -1
- package/dist/server/server/runtime/ControlCenterServer.d.ts +3 -3
- package/dist/server/server/runtime/ControlCenterServer.d.ts.map +1 -1
- package/dist/server/server/runtime/PrReviewWorkerStartup.d.ts +11 -1
- package/dist/server/server/runtime/PrReviewWorkerStartup.d.ts.map +1 -1
- package/dist/server/server/runtime/RetentionStartup.d.ts.map +1 -1
- package/dist/server/server/runtime/ServerLifecycle.d.ts.map +1 -1
- package/dist/server/server/secrets/SecretStore.d.ts.map +1 -1
- package/package.json +10 -9
- package/dist/client/assets/AgentPage-DGL93TJU.js +0 -3
- package/dist/client/assets/AgentPage-DGL93TJU.js.map +0 -1
- package/dist/client/assets/AgentPage-DVSgQgJa.css +0 -1
- package/dist/client/assets/AtlassianOAuthCallbackPage-D1F1xE_2.js +0 -2
- package/dist/client/assets/AuthorizedSharePage-DCQUFY2I.js +0 -2
- package/dist/client/assets/AuthorizedSharePage-DCQUFY2I.js.map +0 -1
- package/dist/client/assets/BrowserCrypto-DVWR7DFd.js +0 -2
- package/dist/client/assets/BrowserSessionHydrator-DE46feEX.js +0 -2
- package/dist/client/assets/BrowserSessionHydrator-DE46feEX.js.map +0 -1
- package/dist/client/assets/CommandSearch-CP_QCbkm.js +0 -2
- package/dist/client/assets/ItemsPage-BGFUkRL2.js +0 -2
- package/dist/client/assets/PortfolioOverview-D45rk8Hl.js +0 -2
- package/dist/client/assets/PortfolioOverview-D45rk8Hl.js.map +0 -1
- package/dist/client/assets/PullRequestReviewPanel-CqPtjhVW.js +0 -6
- package/dist/client/assets/PullRequestReviewPanel-CqPtjhVW.js.map +0 -1
- package/dist/client/assets/ReleaseRoute-DXJ8Jg60.js +0 -2
- package/dist/client/assets/ReleaseWorkset-Dtzalmji.js +0 -2
- package/dist/client/assets/ReleaseWorkset-Dtzalmji.js.map +0 -1
- package/dist/client/assets/ServicesPage-DGcUjd2H.js +0 -2
- package/dist/client/assets/ServicesPage-DGcUjd2H.js.map +0 -1
- package/dist/client/assets/TimelinePage-Bq1RTQlP.js +0 -2
- package/dist/client/assets/TimelinePage-Bq1RTQlP.js.map +0 -1
- package/dist/client/assets/WorkspaceEntityLink-AdZ_T-Wk.js +0 -2
- package/dist/client/assets/WorkspaceEntityRoute-9iMOV64J.css +0 -1
- package/dist/client/assets/WorkspaceEntityRoute-Bxxnc8us.js +0 -3
- package/dist/client/assets/WorkspaceEntityRoute-Bxxnc8us.js.map +0 -1
- package/dist/client/assets/WorkspaceHomeLink-XbKSPths.js +0 -2
- package/dist/client/assets/WorkspacePullRequestDetails-BErJ5bk8.js.map +0 -1
- package/dist/client/assets/WorkspaceRichText-D1M637Ff.js.map +0 -1
- package/dist/client/assets/WorkspaceSettingsPage-Fy7Wx8Y2.js +0 -2
- package/dist/client/assets/WorkspaceSettingsPage-Fy7Wx8Y2.js.map +0 -1
- package/dist/client/assets/WorkspaceSettingsPage-P6yfac0b.css +0 -1
- package/dist/client/assets/agent-api-QVqt4a0O.js +0 -19
- package/dist/client/assets/agent-api-QVqt4a0O.js.map +0 -1
- package/dist/client/assets/authenticatedMutationClient-Ccwguc3i.js +0 -2
- package/dist/client/assets/authorizedShareTransport-DZHgFEkh.js +0 -2
- package/dist/client/assets/client-D27unen8.js +0 -5
- package/dist/client/assets/client-D27unen8.js.map +0 -1
- package/dist/client/assets/connectionTestTransport-BQ55d6Me.js +0 -2
- package/dist/client/assets/connectionTestTransport-BQ55d6Me.js.map +0 -1
- package/dist/client/assets/index-j5ze816l.js +0 -11
- package/dist/client/assets/index-j5ze816l.js.map +0 -1
- package/dist/client/assets/presentPortfolio-D3ZIcnqt.js.map +0 -1
- package/dist/client/assets/pullRequestReviewThreadReplay-oljKM7Xz.js +0 -2
- package/dist/client/assets/pullRequestReviewThreadReplay-oljKM7Xz.js.map +0 -1
- package/dist/client/assets/releaseRoutes-BCuIdZyA.js +0 -2
- package/dist/client/assets/serviceOnboarding-Jg_0yNjf.js +0 -2
- package/dist/client/assets/workspaceScrollCapture-CJ4QUptr.js +0 -2
- package/dist/client/assets/workspaceScrollCapture-CJ4QUptr.js.map +0 -1
- package/dist/client/assets/workspaceSettingsTransport-CZWYL5T7.js +0 -2
- package/dist/server/assets/BindConfig-DIsf2Rnh.js.map +0 -1
- package/dist/server/assets/agent-CyZ40zs1.js.map +0 -1
- package/dist/server/assets/controlCenterApi-ZUX3Y-LE.js.map +0 -1
- package/dist/server/assets/manualPluginSynchronization-DFlhKvav.js.map +0 -1
- package/dist/server/assets/relationshipInferenceMaterialization-DYBcaWhQ.js.map +0 -1
- package/dist/server/assets/workspaceSettings-BE713Oe8.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"mappings":"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","names":[],"ignoreList":[],"sources":["../../../src/client/entities/presentWorkspaceClockifyTimeEntry.ts","../../../src/client/entities/presentWorkspaceConfluencePage.ts","../../../src/client/entities/presentWorkspaceIssue.ts","../../../src/client/entities/presentWorkspacePipelineExecution.ts","../../../src/client/entities/presentWorkspacePullRequest.ts","../../../src/client/entities/presentWorkspaceEntity.ts","../../../src/client/entities/WorkspaceClockifyTimeEntryDetails.tsx","../../../src/client/entities/useClockifyActionSubmission.ts","../../../src/client/entities/WorkspaceConfluencePageDetails.tsx","../../../src/client/entities/WorkspaceIssueDetails.tsx","../../../src/client/entities/WorkspacePipelineExecutionDetails.tsx","../../../src/client/entities/usePullRequestReview.ts","../../../src/client/entities/useWorkspaceEntity.ts","../../../src/client/entities/WorkspaceEntityRoute.tsx"],"sourcesContent":["import * as DateTime from \"effect/DateTime\"\n\nimport type { WorkspaceEntityInspection } from \"../../api/deliveryGraph.js\"\nimport type { DeliveryEntityDetails, DeliveryRelationship } from \"../../domain/deliveryGraph.js\"\nimport type { EntityId, WorkspaceId } from \"../../domain/identifiers.js\"\nimport type { Revision } from \"../../domain/sourceRevision.js\"\nimport { workspaceEntityPath } from \"../workspaceEntityPaths.js\"\n\ntype TimeEntryDetails = Extract<DeliveryEntityDetails, { readonly _tag: \"time-entry\" }>\n\nexport interface WorkspaceClockifyJiraAssociation {\n readonly evidenceLabel: string\n readonly href: string\n readonly key: string\n readonly state: \"inferred\" | \"linked\"\n readonly title: string\n}\n\nexport interface WorkspaceClockifyTimeEntryPresentation {\n readonly approvalDecidedAt: {\n readonly dateTime: string\n readonly label: string\n } | null\n readonly approvalDetail: string\n readonly approvalLabel: string\n readonly approvers: ReadonlyArray<string>\n readonly associationDetail: string\n readonly associationLabel: string\n readonly billableLabel: string\n readonly contributorLabel: string\n readonly description: string\n readonly durationLabel: string\n readonly endedAt: string\n readonly jiraAssociations: ReadonlyArray<WorkspaceClockifyJiraAssociation>\n readonly lockLabel: string\n readonly projectLabel: string\n readonly rollupLabel: string\n readonly sourceRevision: Revision\n readonly startedAt: string\n readonly timerLabel: string\n readonly totalMinutes: number\n}\n\nconst timestampFormatter = new Intl.DateTimeFormat(\"en-GB\", {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n timeZone: \"UTC\"\n})\n\nconst titleCase = (value: string): string =>\n value\n .split(/[_\\-\\s]+/u)\n .filter(Boolean)\n .map((part) => `${part.charAt(0).toLocaleUpperCase(\"en-US\")}${part.slice(1).toLocaleLowerCase(\"en-US\")}`)\n .join(\" \")\n\nconst durationLabel = (minutes: number): string => {\n const hours = Math.floor(minutes / 60)\n const remainder = minutes % 60\n if (hours === 0) return `${String(remainder)}m`\n return remainder === 0 ? `${String(hours)}h` : `${String(hours)}h ${String(remainder)}m`\n}\n\nconst timestampLabel = (value: DateTime.DateTime | null | undefined): string =>\n value === null || value === undefined ? \"Not synchronized\" : timestampFormatter.format(DateTime.toDateUtc(value))\n\nconst timestampPresentation = (value: DateTime.DateTime | null | undefined) =>\n value === null || value === undefined\n ? null\n : {\n dateTime: DateTime.formatIso(value),\n label: timestampFormatter.format(DateTime.toDateUtc(value))\n }\n\nconst acceptedRelationship = (relationship: DeliveryRelationship): boolean =>\n relationship.lifecycle._tag !== \"missing\" &&\n relationship.lifecycle._tag !== \"rejected\" &&\n relationship.lifecycle._tag !== \"superseded\"\n\nconst jiraAssociationsFor = (\n workspaceId: WorkspaceId,\n inspection: WorkspaceEntityInspection\n): ReadonlyArray<WorkspaceClockifyJiraAssociation> => {\n const subjectNodeIds = new Set(\n inspection.graph.nodes.flatMap(({ nodeId, resolution }) =>\n resolution._tag === \"resolved\" &&\n resolution.target._tag === \"entity\" &&\n resolution.target.entityId === inspection.entity.projection.entityId\n ? [nodeId]\n : []\n )\n )\n const issueIdByNode = new Map<string, EntityId>()\n for (const { nodeId, resolution } of inspection.graph.nodes) {\n if (\n resolution._tag === \"resolved\" &&\n resolution.target._tag === \"entity\" &&\n resolution.target.entityKind === \"issue\"\n ) issueIdByNode.set(nodeId, resolution.target.entityId)\n }\n const issues = new Map<EntityId, WorkspaceEntityInspection[\"entity\"][\"projection\"]>()\n for (const { projection } of inspection.graph.relatedEntityProjections) {\n if (projection.entityState === \"present\" && projection.entityType === \"issue\") {\n issues.set(projection.entityId, projection)\n }\n }\n\n const associations = new Map<EntityId, {\n readonly evidenceClaimIds: Set<string>\n readonly issue: WorkspaceEntityInspection[\"entity\"][\"projection\"]\n state: \"inferred\" | \"linked\"\n }>()\n for (const relationship of inspection.graph.relationships) {\n if (\n relationship.kind !== \"tracks-time-for\" ||\n !subjectNodeIds.has(relationship.sourceNodeId) ||\n !acceptedRelationship(relationship)\n ) continue\n const issueId = issueIdByNode.get(relationship.targetNodeId)\n const issue = issueId === undefined ? undefined : issues.get(issueId)\n if (issueId === undefined || issue === undefined) continue\n const inferred = relationship.lifecycle._tag === \"inferred\" || relationship.confidence._tag === \"inferred\"\n const current = associations.get(issueId)\n if (current === undefined) {\n associations.set(issueId, {\n evidenceClaimIds: new Set(relationship.evidenceClaimIds),\n issue,\n state: inferred ? \"inferred\" : \"linked\"\n })\n continue\n }\n for (const evidenceClaimId of relationship.evidenceClaimIds) current.evidenceClaimIds.add(evidenceClaimId)\n if (!inferred) current.state = \"linked\"\n }\n\n return [...associations.entries()].map(([issueId, { evidenceClaimIds, issue, state }]) => ({\n evidenceLabel: `${String(evidenceClaimIds.size)} evidence claim${evidenceClaimIds.size === 1 ? \"\" : \"s\"}`,\n href: workspaceEntityPath(workspaceId, issueId),\n key: issue.displayKey,\n state,\n title: issue.title\n }))\n}\n\n/** Present one immutable Clockify entry with its current Control Center approval. */\nexport const presentWorkspaceClockifyTimeEntry = (\n workspaceId: WorkspaceId,\n details: TimeEntryDetails,\n inspection: WorkspaceEntityInspection\n): WorkspaceClockifyTimeEntryPresentation => {\n const jiraAssociations = jiraAssociationsFor(workspaceId, inspection)\n const inferredCount = jiraAssociations.filter(({ state }) => state === \"inferred\").length\n const approvers = inspection.entity.owners\n .filter(({ roles }) => roles.some((role) => role.includes(\"approver\")))\n .map(({ displayName }) => displayName)\n const contributor = details.userId === undefined\n ? undefined\n : inspection.entity.owners.find(({ sourceIdentities }) =>\n sourceIdentities?.some(\n ({ providerId, vendorPersonId }) => providerId === \"clockify\" && vendorPersonId === details.userId\n ) ?? false\n )\n return {\n approvalDecidedAt: timestampPresentation(inspection.clockifyApproval?.decidedAt),\n approvalDetail: inspection.clockifyApproval === null\n ? \"No Control Center decision is recorded for this exact Clockify revision.\"\n : inspection.clockifyApproval.rationale,\n approvalLabel: inspection.clockifyApproval === null\n ? \"Pending\"\n : titleCase(inspection.clockifyApproval.decision),\n approvers,\n associationDetail: jiraAssociations.length === 0\n ? \"No current Jira relationship explains where this time belongs. The entry remains visible.\"\n : inferredCount === 0\n ? `${String(jiraAssociations.length)} current Jira link${jiraAssociations.length === 1 ? \"\" : \"s\"}`\n : `${String(inferredCount)} inferred Jira link${inferredCount === 1 ? \"\" : \"s\"} — verify before reporting`,\n associationLabel: jiraAssociations.length === 0 ? \"Unattributed\" : \"Attributed\",\n billableLabel: details.billable ? \"Billable\" : \"Non-billable\",\n contributorLabel: contributor?.displayName ?? details.userId ?? \"Contributor not synchronized\",\n description: details.description ?? inspection.entity.projection.title,\n durationLabel: durationLabel(details.durationMinutes),\n endedAt: timestampLabel(details.endedAt),\n jiraAssociations,\n lockLabel: details.locked === undefined\n ? \"Lock state not synchronized\"\n : details.locked\n ? \"Locked\"\n : \"Unlocked\",\n projectLabel: details.projectId ?? \"No Clockify project\",\n rollupLabel: `1 visible entry · ${String(details.durationMinutes)} exact minute${\n details.durationMinutes === 1 ? \"\" : \"s\"\n }`,\n sourceRevision: inspection.source.revision,\n startedAt: timestampLabel(details.startedAt),\n timerLabel: details.startedAt === undefined || details.endedAt === undefined\n ? \"Timer state not synchronized\"\n : details.endedAt === null\n ? \"Timer running\"\n : \"Completed\",\n totalMinutes: details.durationMinutes\n }\n}\n","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 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 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 type { RlyPerson } from \"@knpkv/rly/patterns\"\nimport * as DateTime from \"effect/DateTime\"\nimport * as Option from \"effect/Option\"\n\nimport type { DeliveryEntityDetails } from \"../../domain/deliveryGraph.js\"\nimport type { SourceRevision } from \"../../domain/sourceRevision.js\"\n\ntype IssueDetails = Extract<DeliveryEntityDetails, { readonly _tag: \"issue\" }>\n\nexport interface WorkspaceIssueMetadata {\n readonly label: string\n readonly value: string\n}\n\nexport interface WorkspaceIssueCommentPresentation {\n readonly author: RlyPerson\n readonly body: string | null\n readonly id: string\n readonly time: string | null\n}\n\nexport interface WorkspaceIssueHistoryPresentation {\n readonly actor: RlyPerson\n readonly changes: ReadonlyArray<{ readonly field: string; readonly transition: string }>\n readonly id: string\n readonly time: string | null\n}\n\nexport interface WorkspaceIssueRelatedPresentation {\n readonly href: string | null\n readonly key: string\n readonly status: string\n readonly summary: string\n}\n\nexport interface WorkspaceIssuePresentation {\n readonly acceptanceCriteria: string | null\n readonly collaborators: ReadonlyArray<RlyPerson>\n readonly commentCount: number\n readonly comments: ReadonlyArray<WorkspaceIssueCommentPresentation>\n readonly commentBodiesTruncated: boolean\n readonly commentsTruncated: boolean\n readonly description: string | null\n readonly environment: string | null\n readonly history: ReadonlyArray<WorkspaceIssueHistoryPresentation>\n readonly historyCount: number\n readonly historyTruncated: boolean\n readonly metadata: ReadonlyArray<WorkspaceIssueMetadata>\n readonly parent: WorkspaceIssueRelatedPresentation | null\n readonly subtasks: ReadonlyArray<WorkspaceIssueRelatedPresentation>\n readonly truncationMessage: string | null\n}\n\nconst timestampFormatter = new Intl.DateTimeFormat(\"en-GB\", {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n timeZone: \"UTC\"\n})\n\nconst titleCase = (value: string): string =>\n value.split(\"-\").map((part) => `${part.charAt(0).toLocaleUpperCase(\"en-US\")}${part.slice(1)}`).join(\" \")\n\nconst readableTimestamp = (value: string | null): string | null => {\n if (value === null) return null\n return Option.match(DateTime.make(value), {\n onNone: () => value,\n onSome: (timestamp) => timestampFormatter.format(DateTime.toDateUtc(timestamp))\n })\n}\n\nconst valueName = (value: { readonly name: string | null; readonly sourceId: string | null }): string =>\n value.name ?? value.sourceId ?? \"Not set\"\n\nconst listValue = (values: ReadonlyArray<string> | undefined): string =>\n values === undefined || values.length === 0 ? \"Not set\" : values.join(\" · \")\n\nconst personFallback = (sourcePersonId: string): RlyPerson => ({\n id: sourcePersonId,\n name: \"Unknown collaborator\",\n role: \"Jira collaborator\"\n})\n\nconst peopleFor = (details: IssueDetails): ReadonlyMap<string, RlyPerson> =>\n new Map(\n (details.collaborators ?? []).map((collaborator) => {\n const roles = collaborator.roles.map(titleCase)\n return [\n collaborator.sourcePersonId,\n {\n id: collaborator.sourcePersonId,\n name: collaborator.displayName,\n role: roles.length === 0 ? \"Jira collaborator\" : roles.join(\" · \"),\n ...(collaborator.avatarUrl === null ? {} : { avatarSrc: collaborator.avatarUrl })\n }\n ]\n })\n )\n\nconst relatedIssue = (\n value: NonNullable<IssueDetails[\"parent\"]>,\n sourceUrl: SourceRevision[\"sourceUrl\"]\n): WorkspaceIssueRelatedPresentation => ({\n href: (() => {\n if (sourceUrl === null || value.key === null) return null\n const browsePath = /^(.*\\/browse\\/)[^/]+$/u.exec(sourceUrl.pathname)?.[1]\n return browsePath === undefined ? null : `${sourceUrl.origin}${browsePath}${encodeURIComponent(value.key)}`\n })(),\n key: value.key ?? value.sourceId ?? \"Unknown issue\",\n status: value.status === null ? \"Status unknown\" : valueName(value.status),\n summary: value.summary ?? \"Summary unavailable\"\n})\n\nconst metadataFor = (details: IssueDetails): ReadonlyArray<WorkspaceIssueMetadata> => {\n const project = details.project\n const fixVersions = (details.fixVersions ?? []).map(valueName)\n const components = (details.components ?? []).map(valueName)\n return [\n {\n label: \"Type\",\n value: details.issueType === null || details.issueType === undefined ? \"Not set\" : valueName(details.issueType)\n },\n {\n label: \"Project\",\n value: project === null || project === undefined\n ? \"Not set\"\n : [project.key, project.name].filter((value): value is string => value !== null).join(\" · \") || \"Not set\"\n },\n {\n label: \"Resolution\",\n value: details.resolution === null || details.resolution === undefined\n ? \"Unresolved\"\n : valueName(details.resolution)\n },\n { label: \"Labels\", value: listValue(details.labels) },\n { label: \"Components\", value: listValue(components) },\n { label: \"Fix versions\", value: listValue(fixVersions) },\n { label: \"Created\", value: readableTimestamp(details.createdAt ?? null) ?? \"Not available\" },\n { label: \"Updated\", value: readableTimestamp(details.updatedAt ?? null) ?? \"Not available\" },\n { label: \"Due\", value: readableTimestamp(details.dueDate ?? null) ?? \"Not set\" }\n ]\n}\n\nconst transition = (from: string | null, to: string | null): string => `${from ?? \"Empty\"} → ${to ?? \"Empty\"}`\n\n/** Present provider-neutral synchronized issue detail for the canonical entity document. */\nexport const presentWorkspaceIssue = (\n details: IssueDetails,\n sourceUrl: SourceRevision[\"sourceUrl\"]\n): WorkspaceIssuePresentation => {\n const people = peopleFor(details)\n const person = (sourcePersonId: string | null): RlyPerson =>\n sourcePersonId === null\n ? personFallback(\"unknown-person\")\n : (people.get(sourcePersonId) ?? personFallback(sourcePersonId))\n const truncatedFields = new Set(details.truncatedFields ?? [])\n const comments = (details.comments ?? []).map((comment) => ({\n author: person(comment.authorSourcePersonId),\n body: comment.body,\n id: comment.sourceId,\n time: readableTimestamp(comment.updatedAt ?? comment.createdAt)\n }))\n const history = (details.history ?? []).map((entry) => ({\n actor: person(entry.authorSourcePersonId),\n changes: entry.changes.map((change) => ({ field: change.field, transition: transition(change.from, change.to) })),\n id: entry.sourceId,\n time: readableTimestamp(entry.createdAt)\n }))\n const commentCount = details.commentTotal ?? comments.length\n const historyCount = details.historyTotal ?? history.length\n const commentsTruncated = (details.commentsTruncated ?? false) || commentCount > comments.length\n const historyTruncated = (details.historyTruncated ?? false) || historyCount > history.length\n const reducedFields = [...truncatedFields].filter(\n (field) => field !== \"comments\" && (field !== \"history\" || !historyTruncated)\n )\n return {\n acceptanceCriteria: details.acceptanceCriteria ?? null,\n collaborators: [...people.values()],\n commentCount,\n comments,\n commentBodiesTruncated: details.commentBodiesTruncated ?? (truncatedFields.has(\"comments\") && !commentsTruncated),\n commentsTruncated,\n description: details.description ?? null,\n environment: details.environment ?? null,\n history,\n historyCount,\n historyTruncated,\n metadata: metadataFor(details),\n parent: details.parent === null || details.parent === undefined ? null : relatedIssue(details.parent, sourceUrl),\n subtasks: (details.subtasks ?? []).map((subtask) => relatedIssue(subtask, sourceUrl)),\n truncationMessage: reducedFields.length === 0\n ? null\n : `Jira shortened ${reducedFields.map(titleCase).join(\", \")} to keep this synchronized view bounded.`\n }\n}\n","import type { RlyStage, RlyVerdictTone } 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 PipelineDetails = Extract<DeliveryEntityDetails, { readonly _tag: \"pipeline-execution\" }>\ntype PipelineStatus = PipelineDetails[\"status\"]\n\nexport interface WorkspacePipelineTimestamp {\n readonly dateTime: string\n readonly label: string\n}\n\nexport interface WorkspacePipelineActionPresentation {\n readonly actor: string | null\n readonly artifacts: ReadonlyArray<{\n readonly accessLabel: string\n readonly direction: \"input\" | \"output\"\n readonly name: string\n }>\n readonly duration: string\n readonly error: string | null\n readonly id: string\n readonly name: string\n readonly provider: string\n readonly region: string | null\n readonly stageName: string\n readonly status: string\n readonly summary: string | null\n readonly tone: RlyVerdictTone\n}\n\nexport interface WorkspacePipelineExecutionPresentation {\n readonly actionCountLabel: string\n readonly actions: ReadonlyArray<WorkspacePipelineActionPresentation>\n readonly actionsTruncated: boolean\n readonly approvers: ReadonlyArray<string>\n readonly duration: string\n readonly executionId: string\n readonly executionMode: string\n readonly operators: ReadonlyArray<string>\n readonly pagesRead: number\n readonly pipelineName: string\n readonly pipelineVersion: string\n readonly pullRequestCountLabel: string\n readonly releaseCountLabel: string\n readonly runbookCountLabel: string\n readonly sourceArtifacts: ReadonlyArray<{\n readonly accessLabel: string\n readonly createdAt: WorkspacePipelineTimestamp | null\n readonly name: string\n readonly revision: string\n readonly summary: string | null\n }>\n readonly stages: ReadonlyArray<RlyStage>\n readonly startedAt: WorkspacePipelineTimestamp | null\n readonly status: string\n readonly statusSummary: string | null\n readonly targetEnvironment: string\n readonly triggerDetail: string\n readonly triggerRevision: string\n readonly triggerType: string\n readonly updatedAt: WorkspacePipelineTimestamp | null\n}\n\nconst timestampFormatter = new Intl.DateTimeFormat(\"en-GB\", {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n timeZone: \"UTC\"\n})\n\nconst titleCase = (value: string): string =>\n value\n .replace(/([a-z])([A-Z])/gu, \"$1 $2\")\n .split(/[._\\-\\s]+/u)\n .filter((part) => part.length > 0)\n .map((part) => `${part.charAt(0).toLocaleUpperCase(\"en-US\")}${part.slice(1)}`)\n .join(\" \")\n\nconst timestampFor = (value: DateTime.DateTime | null | undefined): WorkspacePipelineTimestamp | null =>\n value === null || value === undefined\n ? null\n : {\n dateTime: DateTime.formatIso(value),\n label: timestampFormatter.format(DateTime.toDateUtc(value))\n }\n\nconst durationBetween = (\n startedAt: DateTime.DateTime | null | undefined,\n updatedAt: DateTime.DateTime | null | undefined,\n running = false\n): string => {\n if (startedAt === null || startedAt === undefined || updatedAt === null || updatedAt === undefined) {\n return running ? \"In progress\" : \"Not available\"\n }\n const seconds = Math.max(\n 0,\n Math.round((DateTime.toEpochMillis(updatedAt) - DateTime.toEpochMillis(startedAt)) / 1_000)\n )\n if (seconds < 60) return `${String(seconds)}s`\n const minutes = Math.floor(seconds / 60)\n const remainder = seconds % 60\n return remainder === 0 ? `${String(minutes)}m` : `${String(minutes)}m ${String(remainder)}s`\n}\n\nconst toneFor = (status: PipelineStatus): RlyVerdictTone => {\n switch (status) {\n case \"succeeded\":\n return \"positive\"\n case \"failed\":\n return \"critical\"\n case \"running\":\n return \"progress\"\n case \"stopped\":\n return \"caution\"\n case \"queued\":\n return \"neutral\"\n }\n}\n\nconst stageFor = (stage: NonNullable<PipelineDetails[\"stages\"]>[number]): RlyStage => ({\n id: stage.name,\n name: stage.name,\n reason: `${String(stage.actionCount)} action${stage.actionCount === 1 ? \"\" : \"s\"}${\n stage.actionsTruncated ? \" · detail is partial\" : \"\"\n }`,\n state: titleCase(stage.status),\n tone: toneFor(stage.status)\n})\n\nconst identityLabel = (identity: string): string => {\n const leaf = identity.split(\"/\").filter((part) => part.length > 0).at(-1) ?? identity\n return leaf.includes(\"@\") ? leaf : titleCase(leaf) || identity\n}\n\nconst currentlyRelatedEntityIds = (inspection: WorkspaceEntityInspection): ReadonlySet<string> => {\n const entityIdByNode = new Map(\n inspection.graph.nodes.flatMap(({ nodeId, resolution }): ReadonlyArray<readonly [string, string]> =>\n resolution._tag === \"resolved\" && resolution.target._tag === \"entity\"\n ? [[nodeId, resolution.target.entityId]]\n : []\n )\n )\n const subjectNodeIds = new Set(\n inspection.graph.nodes.flatMap(({ nodeId, resolution }) =>\n resolution._tag === \"resolved\" && resolution.target._tag === \"entity\" &&\n resolution.target.entityId === inspection.entity.projection.entityId\n ? [nodeId]\n : []\n )\n )\n return new Set(inspection.graph.relationships.flatMap((relationship) => {\n if (\n relationship.lifecycle._tag === \"missing\" ||\n relationship.lifecycle._tag === \"rejected\" ||\n relationship.lifecycle._tag === \"superseded\"\n ) return []\n if (subjectNodeIds.has(relationship.sourceNodeId)) {\n const entityId = entityIdByNode.get(relationship.targetNodeId)\n return entityId === undefined ? [] : [entityId]\n }\n if (subjectNodeIds.has(relationship.targetNodeId)) {\n const entityId = entityIdByNode.get(relationship.sourceNodeId)\n return entityId === undefined ? [] : [entityId]\n }\n return []\n }))\n}\n\nconst targetEnvironment = (details: PipelineDetails): string => {\n const deploymentAction = details.actions?.find(({ category }) => category?.toLocaleLowerCase(\"en-US\") === \"deploy\")\n return deploymentAction === undefined\n ? \"Not linked\"\n : `${deploymentAction.stageName} · ${deploymentAction.region ?? \"region unknown\"}`\n}\n\n/** Present one immutable CodePipeline execution as a compact operator flight recorder. */\nexport const presentWorkspacePipelineExecution = (\n details: PipelineDetails,\n inspection: WorkspaceEntityInspection\n): WorkspacePipelineExecutionPresentation => {\n const related = currentlyRelatedEntityIds(inspection)\n const relatedCount = (kind: \"page\" | \"pull-request\"): number =>\n inspection.graph.relatedEntityProjections.filter(({ projection }) =>\n projection.entityState === \"present\" && projection.entityType === kind && related.has(projection.entityId)\n ).length\n const lowerBound = (count: number, truncated: boolean): string => `${String(count)}${truncated ? \"+\" : \"\"}`\n const actions = details.actions ?? []\n const actors = [...new Set(actions.flatMap(({ updatedBy }) => updatedBy === null ? [] : [identityLabel(updatedBy)]))]\n const approvers = [\n ...new Set(\n actions.flatMap(({ category, updatedBy }) =>\n category?.toLocaleLowerCase(\"en-US\") === \"approval\" && updatedBy !== null ? [identityLabel(updatedBy)] : []\n )\n )\n ]\n return {\n actionCountLabel: lowerBound(details.actionCount ?? actions.length, details.actionsTruncated ?? false),\n actions: actions.map((action) => ({\n actor: action.updatedBy === null ? null : identityLabel(action.updatedBy),\n artifacts: action.artifacts.map((artifact) => ({\n accessLabel: \"Proxy required\",\n direction: artifact.direction,\n name: artifact.name\n })),\n duration: durationBetween(action.startedAt, action.updatedAt, action.status === \"running\"),\n error: action.errorMessage ?? action.errorCode,\n id: action.actionExecutionId,\n name: action.actionName,\n provider: [action.owner, action.provider, action.version].filter((value) => value !== null).join(\" · \") ||\n \"Provider unavailable\",\n region: action.region,\n stageName: action.stageName,\n status: titleCase(action.status),\n summary: action.externalExecutionSummary,\n tone: toneFor(action.status)\n })),\n actionsTruncated: details.actionsTruncated ?? false,\n approvers,\n duration: durationBetween(details.startedAt, details.updatedAt, details.status === \"running\"),\n executionId: details.executionId,\n executionMode:\n [details.executionMode, details.executionType].filter((value) => value !== null && value !== undefined).join(\n \" · \"\n ) || \"Not synchronized\",\n operators: actors.filter((actor) => !approvers.includes(actor)),\n pagesRead: details.actionPagesRead ?? 0,\n pipelineName: details.pipelineName,\n pipelineVersion: details.pipelineVersion === null || details.pipelineVersion === undefined\n ? \"Unknown\"\n : `v${String(details.pipelineVersion)}`,\n pullRequestCountLabel: lowerBound(relatedCount(\"pull-request\"), inspection.graph.truncated),\n releaseCountLabel: lowerBound(inspection.entity.releaseIds.length, inspection.entity.releaseMembershipsTruncated),\n runbookCountLabel: lowerBound(relatedCount(\"page\"), inspection.graph.truncated),\n sourceArtifacts: (details.sourceArtifacts ?? []).map((artifact) => ({\n accessLabel: \"Proxy required\",\n createdAt: timestampFor(artifact.createdAt),\n name: artifact.name,\n revision: artifact.revisionId ?? \"Revision unavailable\",\n summary: artifact.revisionSummary\n })),\n stages: (details.stages ?? []).map(stageFor),\n startedAt: timestampFor(details.startedAt),\n status: titleCase(details.status),\n statusSummary: details.statusSummary ?? null,\n targetEnvironment: targetEnvironment(details),\n triggerDetail: details.triggerDetail === null || details.triggerDetail === undefined\n ? \"Trigger identity unavailable\"\n : identityLabel(details.triggerDetail),\n triggerRevision: details.triggerRevision,\n triggerType: details.triggerType === null || details.triggerType === undefined\n ? \"Unknown trigger\"\n : titleCase(details.triggerType),\n updatedAt: timestampFor(details.updatedAt)\n }\n}\n","import type { RlyPerson } from \"@knpkv/rly/patterns\"\nimport * as DateTime from \"effect/DateTime\"\nimport * as Option from \"effect/Option\"\n\nimport type { WorkspaceEntityInspection } from \"../../api/deliveryGraph.js\"\nimport type { DeliveryEntityDetails } from \"../../domain/deliveryGraph.js\"\nimport type { SourceRevision } from \"../../domain/sourceRevision.js\"\nimport type { WorkspacePullRequestDiffScope } from \"./WorkspacePullRequestDiff.js\"\n\ntype PullRequestDetails = Extract<DeliveryEntityDetails, { readonly _tag: \"pull-request\" }>\n\nexport interface WorkspacePullRequestTimestamp {\n readonly dateTime: string\n readonly label: string\n}\n\nexport interface WorkspacePullRequestPresentation {\n readonly author: RlyPerson | null\n readonly baseRevision: string | null\n readonly createdAt: WorkspacePullRequestTimestamp | null\n readonly description: string | null\n readonly diffScope: WorkspacePullRequestDiffScope\n readonly filesHref: string | null\n readonly headRevision: string\n readonly issueCount: number\n readonly issueCountLabel: string\n readonly mergeBaseRevision: string | null\n readonly pipelineCount: number\n readonly pipelineCountLabel: string\n readonly releaseCount: number\n readonly releaseCountLabel: string\n readonly reviewLabel: string\n readonly sourceBranch: string\n readonly targetBranch: string\n readonly updatedAt: WorkspacePullRequestTimestamp | null\n}\n\nconst timestampFormatter = new Intl.DateTimeFormat(\"en-GB\", {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n timeZone: \"UTC\"\n})\n\nconst titleCase = (value: string): string =>\n value\n .split(/[._\\-\\s]+/u)\n .filter((part) => part.length > 0)\n .map((part) => `${part.charAt(0).toLocaleUpperCase(\"en-US\")}${part.slice(1)}`)\n .join(\" \")\n\nconst authorName = (reference: string): string => {\n const leaf = reference.split(\"/\").filter((part) => part.length > 0).at(-1) ?? reference\n return titleCase(leaf) || \"AWS identity\"\n}\n\nconst authorFor = (reference: string | null | undefined): RlyPerson | null =>\n reference === null || reference === undefined\n ? null\n : {\n id: reference,\n name: authorName(reference),\n role: \"Pull request author\"\n }\n\nconst timestampFor = (value: PullRequestDetails[\"createdAt\"]): WorkspacePullRequestTimestamp | null => {\n if (value === null || value === undefined) return null\n return Option.match(DateTime.make(value), {\n onNone: () => null,\n onSome: (timestamp) => ({\n dateTime: DateTime.formatIso(timestamp),\n label: timestampFormatter.format(DateTime.toDateUtc(timestamp))\n })\n })\n}\n\nconst reviewLabel = (reviewState: PullRequestDetails[\"reviewState\"]): string => {\n switch (reviewState) {\n case \"approved\":\n return \"Approved by people\"\n case \"changes-requested\":\n return \"Changes requested\"\n case \"merged\":\n return \"Merged\"\n case \"requested\":\n return \"Human review requested\"\n case \"not-requested\":\n return \"No human approval synchronized\"\n }\n}\n\nconst connectedEntityIds = (inspection: WorkspaceEntityInspection): ReadonlySet<string> => {\n const entityIdByNode = new Map(\n inspection.graph.nodes.flatMap(({ nodeId, resolution }): ReadonlyArray<readonly [string, string]> =>\n resolution._tag === \"resolved\" && resolution.target._tag === \"entity\"\n ? [[nodeId, resolution.target.entityId]]\n : []\n )\n )\n const subjectNodeIds = new Set(\n inspection.graph.nodes.flatMap(({ nodeId, resolution }) =>\n resolution._tag === \"resolved\" &&\n resolution.target._tag === \"entity\" &&\n resolution.target.entityId === inspection.entity.projection.entityId\n ? [nodeId]\n : []\n )\n )\n return new Set(inspection.graph.relationships.flatMap((relationship) => {\n if (\n relationship.lifecycle._tag === \"missing\" ||\n relationship.lifecycle._tag === \"rejected\" ||\n relationship.lifecycle._tag === \"superseded\"\n ) return []\n const relatedNodeId = subjectNodeIds.has(relationship.sourceNodeId)\n ? relationship.targetNodeId\n : subjectNodeIds.has(relationship.targetNodeId)\n ? relationship.sourceNodeId\n : null\n const relatedEntityId = relatedNodeId === null ? null : entityIdByNode.get(relatedNodeId)\n return relatedEntityId === undefined || relatedEntityId === null ? [] : [relatedEntityId]\n }))\n}\n\n/** Present one immutable pull-request revision without conflating agent and human review. */\nexport const presentWorkspacePullRequest = (\n details: PullRequestDetails,\n source: SourceRevision,\n inspection: WorkspaceEntityInspection\n): WorkspacePullRequestPresentation => {\n const connected = connectedEntityIds(inspection)\n const relatedCount = (entityType: \"issue\" | \"pipeline-execution\"): number =>\n inspection.graph.relatedEntityProjections.filter(\n ({ projection }) =>\n projection.entityState === \"present\" &&\n projection.entityType === entityType &&\n connected.has(projection.entityId)\n ).length\n const releaseCount = inspection.entity.releaseIds.length\n const issueCount = relatedCount(\"issue\")\n const pipelineCount = relatedCount(\"pipeline-execution\")\n const evidenceCountLabel = (count: number): string => `${String(count)}${inspection.graph.truncated ? \"+\" : \"\"}`\n return {\n author: authorFor(details.authorReference),\n baseRevision: details.baseRevision ?? null,\n createdAt: timestampFor(details.createdAt),\n description: details.description?.trim() || null,\n diffScope: {\n pluginConnectionId: source.pluginConnectionId,\n vendorImmutableId: source.vendorImmutableId,\n revision: source.revision\n },\n filesHref: source.sourceUrl?.href ?? null,\n headRevision: details.headRevision,\n issueCount,\n issueCountLabel: evidenceCountLabel(issueCount),\n mergeBaseRevision: details.mergeBaseRevision ?? null,\n pipelineCount,\n pipelineCountLabel: evidenceCountLabel(pipelineCount),\n releaseCount,\n releaseCountLabel: `${String(releaseCount)}${inspection.entity.releaseMembershipsTruncated ? \"+\" : \"\"}`,\n reviewLabel: reviewLabel(details.reviewState),\n sourceBranch: details.sourceBranch,\n targetBranch: details.targetBranch,\n updatedAt: timestampFor(details.updatedAt)\n }\n}\n","import type {\n RlyCollaboratorCategory,\n RlyFreshnessState,\n RlyPerson,\n RlyRelationship,\n RlyService,\n RlyTimelineEvent,\n RlyVerdictTone\n} from \"@knpkv/rly/patterns\"\nimport * as DateTime from \"effect/DateTime\"\n\nimport type { WorkspaceEntityInspection, WorkspaceEntityOwner } from \"../../api/deliveryGraph.js\"\nimport type { Role } from \"../../domain/actors.js\"\nimport type {\n DeliveryEntityDetails,\n DeliveryEntityKind,\n DeliveryNode,\n DeliveryRelationship\n} from \"../../domain/deliveryGraph.js\"\nimport type { EntityId, GraphNodeId, ReleaseId, WorkspaceId } from \"../../domain/identifiers.js\"\nimport type { SourceRevision } from \"../../domain/sourceRevision.js\"\nimport { serviceFor, statusFor, statusPresentation } from \"../items/presentWorkspaceItems.js\"\nimport { workspaceEntityPath } from \"../workspaceEntityPaths.js\"\nimport {\n presentWorkspaceClockifyTimeEntry,\n type WorkspaceClockifyTimeEntryPresentation\n} from \"./presentWorkspaceClockifyTimeEntry.js\"\nimport {\n presentWorkspaceConfluencePage,\n type WorkspaceConfluencePagePresentation\n} from \"./presentWorkspaceConfluencePage.js\"\nimport { presentWorkspaceIssue, type WorkspaceIssuePresentation } from \"./presentWorkspaceIssue.js\"\nimport {\n presentWorkspacePipelineExecution,\n type WorkspacePipelineExecutionPresentation\n} from \"./presentWorkspacePipelineExecution.js\"\nimport { presentWorkspacePullRequest } from \"./presentWorkspacePullRequest.js\"\nimport type { WorkspacePullRequestPresentation } from \"./presentWorkspacePullRequest.js\"\n\nexport interface WorkspaceEntityFact {\n readonly label: string\n readonly value: string\n}\n\nexport interface WorkspaceEntityActionPresentation {\n readonly external: boolean\n readonly href: string | null\n readonly label: string\n}\n\nexport interface WorkspaceEntityCollaboratorsPresentation {\n readonly approvers: ReadonlyArray<RlyPerson>\n readonly authors: ReadonlyArray<RlyPerson>\n readonly emptyLabel: string\n readonly expandedCategories: ReadonlyArray<RlyCollaboratorCategory>\n readonly operators: ReadonlyArray<RlyPerson>\n readonly owners: ReadonlyArray<RlyPerson>\n readonly reviewers: ReadonlyArray<RlyPerson>\n}\n\nexport interface WorkspaceEntityEvidencePresentation {\n readonly claimCount: number\n readonly freshness: RlyFreshnessState\n readonly freshnessDateTime: string\n readonly freshnessTime: string\n readonly itemCount: number\n readonly reference: string\n}\n\nexport interface WorkspaceEntityReleasePresentation {\n readonly href: string\n readonly id: ReleaseId\n readonly label: string\n}\n\nexport interface WorkspaceEntityPresentation {\n readonly activity: ReadonlyArray<RlyTimelineEvent>\n readonly activityEmptyLabel: string\n readonly agentContext: string\n readonly collaborators: WorkspaceEntityCollaboratorsPresentation\n readonly clockifyTimeEntry: WorkspaceClockifyTimeEntryPresentation | null\n readonly confluencePage: WorkspaceConfluencePagePresentation | null\n readonly contentSummary: string\n readonly displayKey: string\n readonly evidence: WorkspaceEntityEvidencePresentation\n readonly facts: ReadonlyArray<WorkspaceEntityFact>\n readonly freshness: RlyFreshnessState\n readonly freshnessDateTime: string\n readonly freshnessTime: string\n readonly kindLabel: string\n readonly issue: WorkspaceIssuePresentation | null\n readonly pipelineExecution: WorkspacePipelineExecutionPresentation | null\n readonly pullRequest: WorkspacePullRequestPresentation | null\n readonly partialMessages: ReadonlyArray<string>\n readonly primaryAction: WorkspaceEntityActionPresentation\n readonly relationships: ReadonlyArray<RlyRelationship>\n readonly relationshipEmptyLabel: string\n readonly releases: ReadonlyArray<WorkspaceEntityReleasePresentation>\n readonly service: RlyService\n readonly serviceName: string\n readonly title: string\n readonly tone: RlyVerdictTone\n readonly verdict: string\n}\n\nconst timestampFormatter = new Intl.DateTimeFormat(\"en-GB\", {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n timeZone: \"UTC\"\n})\n\nconst titleCase = (value: string): string =>\n value.split(\"-\").map((part) => `${part.charAt(0).toLocaleUpperCase(\"en-US\")}${part.slice(1)}`).join(\" \")\n\nconst serviceNames = {\n clockify: \"Clockify\",\n codecommit: \"CodeCommit\",\n codepipeline: \"CodePipeline\",\n confluence: \"Confluence\",\n jira: \"Jira\"\n} satisfies Readonly<Record<RlyService, string>>\n\nconst kindNames = {\n deployment: \"Deployment\",\n issue: \"Issue\",\n page: \"Page\",\n \"pipeline-execution\": \"Pipeline execution\",\n \"pull-request\": \"Pull request\",\n \"time-entry\": \"Time entry\"\n} satisfies Readonly<Record<DeliveryEntityKind, string>>\n\nconst readableTimestamp = (timestamp: DateTime.DateTime): string =>\n timestampFormatter.format(DateTime.toDateUtc(timestamp))\n\nconst sourceHref = (source: SourceRevision): string | null => source.sourceUrl === null ? null : source.sourceUrl.href\n\nconst releaseHref = (workspaceId: WorkspaceId, releaseId: ReleaseId): string =>\n `/w/${encodeURIComponent(workspaceId)}/releases/${encodeURIComponent(releaseId)}`\n\nconst shortIdentity = (identity: string): string => identity.slice(-8)\n\nconst factsFor = (details: DeliveryEntityDetails): ReadonlyArray<WorkspaceEntityFact> => {\n switch (details._tag) {\n case \"issue\":\n return [\n { label: \"Priority\", value: details.priority ?? \"Not set\" },\n {\n label: \"Estimate\",\n value: details.estimatePoints === null ? \"Not estimated\" : `${details.estimatePoints} points`\n }\n ]\n case \"pull-request\":\n return [\n { label: \"Repository\", value: details.repository },\n ...(details.lifecycle === null || details.lifecycle === undefined\n ? []\n : [{ label: \"State\", value: titleCase(details.lifecycle) }]),\n { label: \"Branches\", value: `${details.sourceBranch} → ${details.targetBranch}` },\n { label: \"Head revision\", value: details.headRevision }\n ]\n case \"page\":\n return [\n { label: \"Space\", value: details.spaceKey },\n { label: \"Revision\", value: details.revision }\n ]\n case \"pipeline-execution\":\n return [\n { label: \"Pipeline\", value: details.pipelineName },\n { label: \"Execution\", value: details.executionId },\n { label: \"Trigger revision\", value: details.triggerRevision }\n ]\n case \"deployment\":\n return [\n { label: \"Environment\", value: shortIdentity(details.environmentId) },\n { label: \"Revision\", value: details.revision }\n ]\n case \"time-entry\":\n return [\n { label: \"Duration\", value: `${details.durationMinutes} min` },\n { label: \"Billable\", value: details.billable ? \"Yes\" : \"No\" }\n ]\n }\n}\n\nconst roleLabel = (role: Role): string => titleCase(role)\n\nconst personFor = (owner: WorkspaceEntityOwner): RlyPerson => ({\n avatarFallback: owner.avatarFallback,\n id: owner.personId,\n name: owner.displayName,\n role: [...new Set(owner.roles.map(roleLabel))].join(\" · \")\n})\n\nconst collaboratorCategory = (roles: ReadonlyArray<Role>): RlyCollaboratorCategory => {\n if (roles.some((role) => role.includes(\"approver\"))) return \"approvers\"\n if (roles.some((role) => role === \"reviewer\" || role === \"watcher\")) return \"reviewers\"\n if (roles.includes(\"operator\")) return \"operators\"\n if (roles.some((role) => role === \"author\" || role === \"contributor\")) return \"authors\"\n return \"owners\"\n}\n\nconst collaboratorsFor = (\n owners: ReadonlyArray<WorkspaceEntityOwner>\n): WorkspaceEntityCollaboratorsPresentation => {\n const categoryOrder: ReadonlyArray<RlyCollaboratorCategory> = [\n \"authors\",\n \"owners\",\n \"reviewers\",\n \"operators\",\n \"approvers\"\n ]\n const categories: Record<RlyCollaboratorCategory, Array<RlyPerson>> = {\n approvers: [],\n authors: [],\n operators: [],\n owners: [],\n reviewers: []\n }\n for (const owner of owners) categories[collaboratorCategory(owner.roles)].push(personFor(owner))\n const expandedCategories = categoryOrder.filter((category) => categories[category].length > 0)\n return {\n ...categories,\n emptyLabel: \"No collaborator is assigned to this object.\",\n expandedCategories\n }\n}\n\nconst collaboratorsWithIssue = (\n collaborators: WorkspaceEntityCollaboratorsPresentation,\n issue: WorkspaceIssuePresentation | null\n): WorkspaceEntityCollaboratorsPresentation => {\n if (issue === null) return collaborators\n const owners = [...collaborators.owners]\n const authors = [...collaborators.authors]\n const canonicalNames = new Set(\n [\n ...collaborators.approvers,\n ...collaborators.authors,\n ...collaborators.operators,\n ...collaborators.owners,\n ...collaborators.reviewers\n ].map((person) => person.name.toLocaleLowerCase(\"en-US\"))\n )\n const issuePersonIds = new Set<string>()\n for (const person of issue.collaborators) {\n if (issuePersonIds.has(person.id)) continue\n issuePersonIds.add(person.id)\n const normalizedName = person.name.toLocaleLowerCase(\"en-US\")\n if (canonicalNames.has(normalizedName)) continue\n if (person.role.includes(\"Assignee\")) owners.push(person)\n else authors.push(person)\n }\n const expandedCategories: Array<RlyCollaboratorCategory> = []\n if (authors.length > 0) expandedCategories.push(\"authors\")\n if (owners.length > 0) expandedCategories.push(\"owners\")\n for (const category of collaborators.expandedCategories) expandedCategories.push(category)\n return {\n ...collaborators,\n authors,\n emptyLabel: \"No collaborator was synchronized or assigned to this object.\",\n expandedCategories: [...new Set(expandedCategories)],\n owners\n }\n}\n\nconst collaboratorsWithPage = (\n collaborators: WorkspaceEntityCollaboratorsPresentation,\n page: WorkspaceConfluencePagePresentation | null,\n owners: ReadonlyArray<WorkspaceEntityOwner>\n): WorkspaceEntityCollaboratorsPresentation => {\n if (page === null) return collaborators\n const next = {\n approvers: [...collaborators.approvers],\n authors: [...collaborators.authors],\n operators: [...collaborators.operators],\n owners: [...collaborators.owners],\n reviewers: [...collaborators.reviewers]\n }\n const knownIds = new Set(Object.values(next).flat().map(({ id }) => id))\n const knownConfluenceSourceIds = new Set<string>(\n owners.flatMap((owner) =>\n (owner.sourceIdentities ?? [])\n .filter(({ providerId }) => providerId === \"confluence\")\n .map(({ vendorPersonId }) => vendorPersonId)\n )\n )\n for (const person of page.contributors) {\n if (knownIds.has(person.id) || knownConfluenceSourceIds.has(person.id)) continue\n knownIds.add(person.id)\n if (person.role.includes(\"Owner\")) next.owners.push(person)\n else if (person.role.includes(\"Watcher\")) next.reviewers.push(person)\n else next.authors.push(person)\n }\n const categoryOrder: ReadonlyArray<RlyCollaboratorCategory> = [\n \"authors\",\n \"owners\",\n \"reviewers\",\n \"operators\",\n \"approvers\"\n ]\n return {\n ...next,\n emptyLabel: \"No collaborator was synchronized or assigned to this document.\",\n expandedCategories: categoryOrder.filter(\n (category) => next[category].length > 0\n )\n }\n}\n\nconst freshnessFor = (inspection: WorkspaceEntityInspection): RlyFreshnessState => {\n const freshness = inspection.freshness\n if (freshness === null) return inspection.isSourceCurrent ? \"current\" : \"cached\"\n if (freshness._tag === \"current\") {\n return inspection.isSourceCurrent && freshness.provenance._tag === \"provider\" ? \"current\" : \"cached\"\n }\n return freshness._tag\n}\n\nconst freshnessTimestamp = (inspection: WorkspaceEntityInspection): DateTime.DateTime => {\n const freshness = inspection.freshness\n if (freshness === null) return inspection.entity.recordedAt\n return freshness.sourceObservedAt ?? freshness.synchronizedAt ?? freshness.pluginHealth.checkedAt\n}\n\nconst endpointFor = (\n node: DeliveryNode | undefined,\n entityById: ReadonlyMap<EntityId, WorkspaceEntityInspection[\"entity\"][\"projection\"]>,\n service: RlyService,\n workspaceId: WorkspaceId\n): RlyRelationship[\"source\"] => {\n if (node === undefined) {\n return { state: \"missing\", label: \"Unknown graph endpoint\", reason: \"The endpoint is outside this graph response.\" }\n }\n if (node.resolution._tag === \"missing\") {\n return {\n state: \"missing\",\n label: node.resolution.missingKey,\n reason: `${titleCase(node.endpointKind)} is not connected.`\n }\n }\n const target = node.resolution.target\n if (target._tag === \"entity\") {\n const projection = entityById.get(target.entityId)\n if (projection === undefined) {\n return {\n state: \"missing\",\n label: `${kindNames[target.entityKind]} ${shortIdentity(target.entityId)}`,\n reason: \"The related object is outside this bounded response.\",\n service: serviceFor(target.entityKind)\n }\n }\n if (projection.entityState === \"deleted\") {\n return {\n state: \"missing\",\n label: `${projection.title} · Deleted`,\n reason: \"The related object was deleted.\",\n service: serviceFor(projection.entityType)\n }\n }\n return {\n state: \"present\",\n href: workspaceEntityPath(workspaceId, projection.entityId),\n id: projection.entityId,\n reference: projection.displayKey,\n service: serviceFor(projection.entityType),\n title: projection.title\n }\n }\n if (target._tag === \"release\") {\n return {\n state: \"present\",\n href: releaseHref(workspaceId, target.releaseId),\n id: target.releaseId,\n reference: `Control Center release · ${shortIdentity(target.releaseId)}`,\n service,\n title: \"Delivery release\"\n }\n }\n return {\n state: \"present\",\n id: target.environmentId,\n reference: `Control Center environment · ${shortIdentity(target.environmentId)}`,\n service,\n title: \"Delivery environment\"\n }\n}\n\nconst relationshipEvidence = (relationship: DeliveryRelationship): string => {\n const evidence = relationship.evidenceClaimIds.length\n const confidence = relationship.confidence._tag === \"inferred\"\n ? `${Math.round(relationship.confidence.score * 100)}% inferred`\n : titleCase(relationship.confidence._tag)\n return `${evidence} evidence claim${evidence === 1 ? \"\" : \"s\"} · ${confidence}`\n}\n\nconst relationshipsFor = (\n inspection: WorkspaceEntityInspection,\n workspaceId: WorkspaceId,\n service: RlyService\n): ReadonlyArray<RlyRelationship> => {\n const nodeById = new Map<GraphNodeId, DeliveryNode>(inspection.graph.nodes.map((node) => [node.nodeId, node]))\n const projections = [inspection.entity, ...inspection.graph.relatedEntityProjections]\n .map(({ projection }) => projection)\n const entityById = new Map<EntityId, WorkspaceEntityInspection[\"entity\"][\"projection\"]>(\n projections.map((projection) => [projection.entityId, projection])\n )\n const ownerById = new Map(inspection.entity.owners.map((owner) => [owner.personId, owner]))\n return inspection.graph.relationships.map((relationship) => {\n const actorOwner = relationship.recordedBy._tag === \"human\"\n ? ownerById.get(relationship.recordedBy.personId)\n : undefined\n return {\n ...(actorOwner === undefined ? {} : { actor: personFor(actorOwner) }),\n direction: \"forward\",\n evidence: relationshipEvidence(relationship),\n id: relationship.relationshipId,\n kind: titleCase(relationship.kind),\n lifecycle: relationship.lifecycle._tag,\n source: endpointFor(nodeById.get(relationship.sourceNodeId), entityById, service, workspaceId),\n target: endpointFor(nodeById.get(relationship.targetNodeId), entityById, service, workspaceId)\n }\n })\n}\n\nconst activityFor = (inspection: WorkspaceEntityInspection): ReadonlyArray<RlyTimelineEvent> =>\n inspection.activity.events.map((event) => ({\n actor: event.actor.label,\n actorKind: event.actor.kind,\n dateTime: DateTime.formatIso(event.occurredAt),\n detail: titleCase(event.sourceKind),\n ...(event.href === null ? {} : { href: event.href }),\n id: event.eventKey,\n ...(event.service === null ? {} : { service: event.service }),\n time: readableTimestamp(event.occurredAt),\n title: event.title\n }))\n\nconst primaryActionFor = (\n inspection: WorkspaceEntityInspection,\n workspaceId: WorkspaceId,\n serviceName: string\n): WorkspaceEntityActionPresentation => {\n const href = sourceHref(inspection.source)\n if (href !== null) return { external: true, href, label: `Open in ${serviceName}` }\n const releaseId = inspection.entity.canonicalReleaseId\n return releaseId === null\n ? { external: false, href: null, label: \"Source link unavailable\" }\n : { external: false, href: releaseHref(workspaceId, releaseId), label: \"Open delivery release\" }\n}\n\nconst partialMessagesFor = (inspection: WorkspaceEntityInspection): ReadonlyArray<string> => [\n ...(inspection.entity.ownersTruncated ? [\"More collaborators exist than this bounded view can show.\"] : []),\n ...(inspection.entity.releaseMembershipsTruncated\n ? [\"More release memberships exist than this bounded delivery path can show.\"]\n : []),\n ...(inspection.graph.truncated ? [\"The relationship graph is partial; additional delivery links exist.\"] : []),\n ...(inspection.activity.truncated ? [\"The activity list is partial; older events are not shown.\"] : [])\n]\n\ninterface AgentContextInput {\n readonly displayKey: string\n readonly issue: WorkspaceIssuePresentation | null\n readonly releaseCount: number\n readonly serviceName: string\n readonly title: string\n}\n\nconst agentContextFor = ({\n displayKey,\n issue,\n releaseCount,\n serviceName,\n title\n}: AgentContextInput): string =>\n issue === null\n ? `${displayKey} · ${title} · ${serviceName}`\n : `${displayKey} · ${title} · ${serviceName} issue · ${String(releaseCount)} release${\n releaseCount === 1 ? \"\" : \"s\"\n } · ${String(issue.commentCount)} synchronized comment${issue.commentCount === 1 ? \"\" : \"s\"}`\n\n/** Turn one provider-neutral canonical read into explicit application-owned Rly inputs. */\nexport const presentWorkspaceEntity = (\n workspaceId: WorkspaceId,\n inspection: WorkspaceEntityInspection\n): WorkspaceEntityPresentation => {\n const projection = inspection.entity.projection\n const service = serviceFor(projection.entityType)\n const serviceName = serviceNames[service]\n const verdict = statusFor(projection.details)\n const issue = projection.details._tag === \"issue\"\n ? presentWorkspaceIssue(projection.details, inspection.source.sourceUrl)\n : null\n const pullRequest = projection.details._tag === \"pull-request\"\n ? presentWorkspacePullRequest(projection.details, inspection.source, inspection)\n : null\n const pipelineExecution = projection.details._tag === \"pipeline-execution\"\n ? presentWorkspacePipelineExecution(projection.details, inspection)\n : null\n const confluencePage = projection.details._tag === \"page\"\n ? presentWorkspaceConfluencePage(projection.details, inspection)\n : null\n const clockifyTimeEntry = projection.details._tag === \"time-entry\"\n ? presentWorkspaceClockifyTimeEntry(workspaceId, projection.details, inspection)\n : null\n const freshnessTimestampValue = freshnessTimestamp(inspection)\n const releaseCount = inspection.entity.releaseIds.length\n return {\n activity: activityFor(inspection),\n activityEmptyLabel: \"No attributable activity has been recorded for this object.\",\n agentContext: agentContextFor({\n displayKey: projection.displayKey,\n issue,\n releaseCount,\n serviceName,\n title: projection.title\n }),\n collaborators: collaboratorsWithPage(\n collaboratorsWithIssue(collaboratorsFor(inspection.entity.owners), issue),\n confluencePage,\n inspection.entity.owners\n ),\n clockifyTimeEntry,\n confluencePage,\n contentSummary: `${kindNames[projection.entityType]} ${projection.displayKey} is tracked in ${serviceName}. ${\n releaseCount === 0\n ? \"It is not linked to a release yet.\"\n : `It belongs to ${releaseCount}${inspection.entity.releaseMembershipsTruncated ? \"+\" : \"\"} release${\n releaseCount === 1 ? \"\" : \"s\"\n }.`\n }`,\n displayKey: projection.displayKey,\n evidence: {\n claimCount: inspection.graph.evidenceClaims.length,\n freshness: freshnessFor(inspection),\n freshnessDateTime: DateTime.formatIso(freshnessTimestampValue),\n freshnessTime: readableTimestamp(freshnessTimestampValue),\n itemCount: inspection.graph.evidenceItems.length,\n reference: `${projection.displayKey} · source revision ${inspection.source.revision}`\n },\n facts: [\n { label: \"Object\", value: kindNames[projection.entityType] },\n { label: \"Service\", value: serviceName },\n ...factsFor(projection.details)\n ],\n freshness: freshnessFor(inspection),\n freshnessDateTime: DateTime.formatIso(freshnessTimestampValue),\n freshnessTime: readableTimestamp(freshnessTimestampValue),\n kindLabel: kindNames[projection.entityType],\n issue,\n pipelineExecution,\n pullRequest,\n partialMessages: partialMessagesFor(inspection),\n primaryAction: primaryActionFor(inspection, workspaceId, serviceName),\n relationships: relationshipsFor(inspection, workspaceId, service),\n relationshipEmptyLabel: \"No delivery relationships have been recorded for this object.\",\n releases: inspection.entity.releaseIds.map((releaseId) => ({\n href: releaseHref(workspaceId, releaseId),\n id: releaseId,\n label: `Release ${shortIdentity(releaseId)}`\n })),\n service,\n serviceName,\n title: projection.title,\n tone: statusPresentation(projection.entityType, verdict).tone,\n verdict\n }\n}\n","import { StateLabel, Text } from \"@knpkv/rly/primitives\"\nimport { useRef, useState, type FormEvent, type ReactElement, type ReactNode } from \"react\"\nimport { Link } from \"react-router\"\n\nimport type { SubmitClockifyActionRequest } from \"../../api/deliveryGraph.js\"\nimport type { WorkspaceClockifyTimeEntryPresentation } from \"./presentWorkspaceClockifyTimeEntry.js\"\nimport type { ClockifyActionSubmissionState } from \"./useClockifyActionSubmission.js\"\nimport styles from \"./WorkspaceClockifyTimeEntryDetails.module.css\"\n\nconst Section = ({\n children,\n heading,\n meta\n}: {\n readonly children: ReactNode\n readonly heading: string\n readonly meta: string\n}): ReactElement => (\n <section className={styles.section}>\n <header className={styles.sectionHeading}>\n <Text as=\"h2\" variant=\"section-title\">\n {heading}\n </Text>\n <Text tone=\"secondary\" variant=\"meta\">\n {meta}\n </Text>\n </header>\n {children}\n </section>\n)\n\n/** Render one immutable Clockify entry and its Control Center-owned approval. */\nexport const WorkspaceClockifyTimeEntryDetails = ({\n canApprove = false,\n canCorrect = false,\n onSubmit,\n submission = { _tag: \"idle\" },\n timeEntry\n}: {\n readonly canApprove?: boolean\n readonly canCorrect?: boolean\n readonly onSubmit?: (request: SubmitClockifyActionRequest) => void\n readonly submission?: ClockifyActionSubmissionState\n readonly timeEntry: WorkspaceClockifyTimeEntryPresentation\n}): ReactElement => {\n const [jiraIssueKey, setJiraIssueKey] = useState(\"\")\n const [rationale, setRationale] = useState(\"\")\n const approvalDecision = useRef<\"approved\" | \"rejected\">(\"approved\")\n const correctionDisabled = !canCorrect || onSubmit === undefined || submission._tag === \"submitting\"\n const approvalDisabled = !canApprove || onSubmit === undefined || submission._tag === \"submitting\"\n const submitCorrection = (event: FormEvent): void => {\n event.preventDefault()\n if (!correctionDisabled)\n onSubmit({\n _tag: \"correct-association\",\n expectedRevision: timeEntry.sourceRevision,\n jiraIssueKey\n })\n }\n const submitApproval = (event: FormEvent): void => {\n event.preventDefault()\n if (!approvalDisabled && rationale.trim().length > 0) {\n onSubmit({\n _tag: \"record-approval\",\n expectedRevision: timeEntry.sourceRevision,\n decision: approvalDecision.current,\n rationale: rationale.trim()\n })\n approvalDecision.current = \"approved\"\n }\n }\n return (\n <article className={styles.document} data-workspace-clockify-time-entry-detail>\n <section aria-label=\"Clockify time ledger\" className={styles.ledger}>\n <div className={styles.total}>\n <span>Total tracked</span>\n <strong>{timeEntry.durationLabel}</strong>\n <small>{timeEntry.rollupLabel}</small>\n </div>\n <div className={styles.ledgerBody}>\n <header>\n <span>Time ledger</span>\n <StateLabel\n label={timeEntry.associationLabel}\n tone={timeEntry.jiraAssociations.length === 0 ? \"caution\" : \"positive\"}\n />\n </header>\n <p>{timeEntry.description}</p>\n <dl className={styles.primaryFacts}>\n <div>\n <dt>Project</dt>\n <dd>{timeEntry.projectLabel}</dd>\n </div>\n <div>\n <dt>Billing</dt>\n <dd>{timeEntry.billableLabel}</dd>\n </div>\n <div>\n <dt>Contributor</dt>\n <dd>{timeEntry.contributorLabel}</dd>\n </div>\n </dl>\n </div>\n </section>\n\n <Section heading=\"Entry\" meta=\"The exact source record included in the total\">\n <div className={styles.entry}>\n <strong>{timeEntry.durationLabel}</strong>\n <dl>\n <div>\n <dt>Started</dt>\n <dd>{timeEntry.startedAt}</dd>\n </div>\n <div>\n <dt>Ended</dt>\n <dd>{timeEntry.endedAt}</dd>\n </div>\n <div>\n <dt>State</dt>\n <dd>{timeEntry.timerLabel}</dd>\n </div>\n <div>\n <dt>Provider lock</dt>\n <dd>{timeEntry.lockLabel}</dd>\n </div>\n </dl>\n </div>\n </Section>\n\n <Section heading=\"Jira attribution\" meta=\"Current delivery-ledger relationships\">\n <div className={styles.attribution} data-state={timeEntry.jiraAssociations.length === 0 ? \"missing\" : \"linked\"}>\n <div>\n <strong>{timeEntry.associationLabel}</strong>\n <p>{timeEntry.associationDetail}</p>\n </div>\n {timeEntry.jiraAssociations.length === 0 ? null : (\n <ul>\n {timeEntry.jiraAssociations.map((association) => (\n <li key={association.href}>\n <Link to={association.href}>\n <span>{association.key}</span>\n <strong>{association.title}</strong>\n <small>\n {association.state === \"inferred\" ? \"Inferred\" : \"Linked\"} · {association.evidenceLabel}\n </small>\n </Link>\n </li>\n ))}\n </ul>\n )}\n </div>\n </Section>\n\n <Section heading=\"People\" meta=\"Provider contributor and assigned approvers\">\n <dl className={styles.people}>\n <div>\n <dt>Contributor</dt>\n <dd>{timeEntry.contributorLabel}</dd>\n </div>\n <div>\n <dt>Approvers</dt>\n <dd>{timeEntry.approvers.join(\" · \") || \"No approval recorded\"}</dd>\n </div>\n </dl>\n </Section>\n\n <aside className={styles.readOnly} data-clockify-approval>\n <strong>Control Center approval: {timeEntry.approvalLabel}</strong>\n <span>{timeEntry.approvalDetail}</span>\n {timeEntry.approvalDecidedAt === null ? null : (\n <time dateTime={timeEntry.approvalDecidedAt.dateTime}>Recorded {timeEntry.approvalDecidedAt.label}</time>\n )}\n </aside>\n <section aria-label=\"Governed Clockify actions\" data-clockify-governed-actions>\n <form onSubmit={submitCorrection}>\n <label>\n Jira issue key\n <input\n disabled={correctionDisabled}\n maxLength={100}\n onChange={(event) => setJiraIssueKey(event.currentTarget.value)}\n pattern=\"[A-Z][A-Z0-9]*-[1-9][0-9]*\"\n required\n value={jiraIssueKey}\n />\n </label>\n <button disabled={correctionDisabled} type=\"submit\">\n Correct association\n </button>\n </form>\n <form onSubmit={submitApproval}>\n <label>\n Approval rationale\n <input\n disabled={approvalDisabled}\n maxLength={1_000}\n onChange={(event) => setRationale(event.currentTarget.value)}\n required\n value={rationale}\n />\n </label>\n <button\n disabled={approvalDisabled || rationale.trim().length === 0}\n onClick={() => {\n approvalDecision.current = \"approved\"\n }}\n type=\"submit\"\n >\n Approve revision\n </button>\n <button\n disabled={approvalDisabled || rationale.trim().length === 0}\n onClick={() => {\n approvalDecision.current = \"rejected\"\n }}\n type=\"submit\"\n >\n Reject revision\n </button>\n </form>\n {submission._tag === \"failed\" ? <p role=\"alert\">The governed action could not be submitted.</p> : null}\n {submission._tag === \"succeeded\" ? <p>Action recorded: {submission.result.state}</p> : null}\n </section>\n </article>\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, useRef, useState } from \"react\"\n\nimport type { SubmitClockifyActionRequest, SubmitClockifyActionResponse } from \"../../api/deliveryGraph.js\"\nimport type { EntityId } from \"../../domain/identifiers.js\"\nimport { makeAuthenticatedMutationClient } from \"../authenticatedMutationClient.js\"\n\nexport type ClockifyActionSubmissionState =\n | { readonly _tag: \"idle\" }\n | { readonly _tag: \"submitting\" }\n | { readonly _tag: \"succeeded\"; readonly result: SubmitClockifyActionResponse }\n | { readonly _tag: \"failed\" }\n\nexport interface ClockifyActionSubmissionTransport {\n readonly submit: (\n entityId: EntityId,\n request: SubmitClockifyActionRequest,\n signal: AbortSignal\n ) => Promise<SubmitClockifyActionResponse>\n}\n\n/** Generated-client transport carrying the authenticated mutation proof. */\nexport const browserClockifyActionSubmissionTransport: ClockifyActionSubmissionTransport = {\n submit: (entityId, request, signal) =>\n Effect.runPromise(\n Effect.gen(function*() {\n const client = yield* makeAuthenticatedMutationClient\n return yield* request._tag === \"correct-association\"\n ? client.deliveryGraph.submitClockifyAction({\n params: { entityId },\n payload: request\n })\n : client.deliveryGraph.submitClockifyAction({\n params: { entityId },\n payload: request\n })\n }).pipe(Effect.provide(FetchHttpClient.layer)),\n { signal }\n )\n}\n\n/** Submit one human-confirmed Clockify action and retain its durable result. */\nexport const useClockifyActionSubmission = (\n entityId: EntityId,\n sessionKey: string | null,\n onSessionExpired: (sessionKey: string) => void,\n onSucceeded: () => void,\n transport: ClockifyActionSubmissionTransport = browserClockifyActionSubmissionTransport\n): {\n readonly state: ClockifyActionSubmissionState\n readonly submit: (request: SubmitClockifyActionRequest) => void\n} => {\n const [state, setState] = useState<ClockifyActionSubmissionState>({ _tag: \"idle\" })\n const active = useRef<AbortController | null>(null)\n useEffect(() => {\n active.current?.abort()\n active.current = null\n setState({ _tag: \"idle\" })\n return () => {\n active.current?.abort()\n active.current = null\n }\n }, [entityId, sessionKey])\n return {\n state,\n submit: useCallback((request) => {\n if (sessionKey === null || active.current !== null) return\n const abort = new AbortController()\n active.current = abort\n setState({ _tag: \"submitting\" })\n transport.submit(entityId, request, abort.signal).then(\n (result) => {\n if (active.current !== abort) return\n active.current = null\n setState({ _tag: \"succeeded\", result })\n onSucceeded()\n },\n (error) => {\n if (active.current !== abort) return\n active.current = null\n if (Predicate.isTagged(\"UnauthorizedApiError\")(error)) onSessionExpired(sessionKey)\n if (!abort.signal.aborted) setState({ _tag: \"failed\" })\n }\n )\n }, [entityId, onSessionExpired, onSucceeded, sessionKey, transport])\n }\n}\n","import { PeopleStrip } from \"@knpkv/rly/patterns\"\nimport { StateLabel, Text } from \"@knpkv/rly/primitives\"\nimport { type ReactElement, type ReactNode, useState } from \"react\"\n\nimport type { WorkspaceConfluencePagePresentation } from \"./presentWorkspaceConfluencePage.js\"\nimport { WorkspaceRichText } from \"./WorkspaceRichText.js\"\nimport styles from \"./WorkspaceConfluencePageDetails.module.css\"\n\nconst Section = ({\n children,\n heading,\n meta\n}: {\n readonly children: ReactNode\n readonly heading: string\n readonly meta: string\n}): ReactElement => (\n <section className={styles.section}>\n <header className={styles.sectionHeading}>\n <Text as=\"h2\" variant=\"section-title\">\n {heading}\n </Text>\n <Text tone=\"secondary\" variant=\"meta\">\n {meta}\n </Text>\n </header>\n {children}\n </section>\n)\n\n/** Render one canonical Confluence page without exposing provider media or write controls. */\nexport const WorkspaceConfluencePageDetails = ({\n page\n}: {\n readonly page: WorkspaceConfluencePagePresentation\n}): ReactElement => {\n const [peopleExpanded, setPeopleExpanded] = useState(false)\n return (\n <article className={styles.document} data-workspace-confluence-page-detail>\n <section aria-label=\"Document identity\" className={styles.folio}>\n <div className={styles.revision}>\n <span>Revision</span>\n <strong>{page.revision}</strong>\n </div>\n <div className={styles.folioMeta}>\n <StateLabel\n label={page.status}\n tone={page.status === \"Superseded\" ? \"caution\" : page.status === \"Current\" ? \"positive\" : \"neutral\"}\n />\n <dl>\n <div>\n <dt>Space</dt>\n <dd>{page.sourceSpaceId}</dd>\n </div>\n <div>\n <dt>Updated</dt>\n <dd>\n {page.updatedAt === null ? (\n \"Not synchronized\"\n ) : (\n <time dateTime={page.updatedAt.dateTime}>{page.updatedAt.label}</time>\n )}\n </dd>\n </div>\n <div>\n <dt>Created</dt>\n <dd>\n {page.createdAt === null ? (\n \"Not synchronized\"\n ) : (\n <time dateTime={page.createdAt.dateTime}>{page.createdAt.label}</time>\n )}\n </dd>\n </div>\n </dl>\n </div>\n </section>\n\n <Section heading=\"Document\" meta=\"Safely converted text; raw provider markup and media stay outside this view\">\n {page.contentState === \"loaded\" && page.content !== null ? (\n <WorkspaceRichText className={styles.richText} value={page.content} />\n ) : (\n <div className={styles.contentState} data-content-state={page.contentState}>\n <strong>\n {page.contentState === \"lazy\" ? \"Content has not been loaded\" : \"No readable body was returned\"}\n </strong>\n <Text tone=\"secondary\">\n {page.contentState === \"lazy\"\n ? \"The page is synchronized lazily. Open the authenticated Confluence source to read it now.\"\n : \"Revision metadata remains available in this read-only view.\"}\n </Text>\n </div>\n )}\n </Section>\n\n <Section heading=\"People\" meta={page.watcherInventoryLabel}>\n {page.contributors.length === 0 ? (\n <Text tone=\"secondary\">No owner, contributor, or watcher identity was synchronized.</Text>\n ) : (\n <PeopleStrip\n aria-label=\"Page collaborators\"\n expanded={peopleExpanded}\n limit={4}\n onExpandedChange={setPeopleExpanded}\n people={page.contributors}\n />\n )}\n </Section>\n\n <div className={styles.collections}>\n <Section heading=\"Revision history\" meta={page.historyInventoryLabel}>\n {page.versions.length === 0 ? (\n <Text tone=\"secondary\">No revision history was synchronized.</Text>\n ) : (\n <ol className={styles.versions}>\n {page.versions.map((version) => (\n <li key={`${String(version.number)}-${version.createdAt.dateTime}`}>\n <strong>v{version.number}</strong>\n <span>{version.message}</span>\n <small>\n {version.author} · <time dateTime={version.createdAt.dateTime}>{version.createdAt.label}</time>\n {version.minorEdit ? \" · Minor edit\" : \"\"}\n </small>\n </li>\n ))}\n </ol>\n )}\n </Section>\n\n <Section heading=\"Attachments\" meta={page.attachmentInventoryLabel}>\n {page.attachments.length === 0 ? (\n <Text tone=\"secondary\">No attachment metadata was synchronized.</Text>\n ) : (\n <ul className={styles.attachments}>\n {page.attachments.map((attachment) => (\n <li key={attachment.id}>\n <strong>{attachment.title}</strong>\n <span>\n {attachment.mediaType} · {attachment.fileSize} · {attachment.version}\n </span>\n <small>Metadata only · authenticated proxy required</small>\n </li>\n ))}\n </ul>\n )}\n </Section>\n </div>\n\n <Section heading=\"Runbook evidence\" meta=\"Immutable delivery evidence around this page\">\n <div className={styles.evidenceCount}>\n <strong>{page.runbookEvidenceCount}</strong>\n <span>evidence item{page.runbookEvidenceCount === 1 ? \"\" : \"s\"} in the current bounded graph</span>\n </div>\n </Section>\n </article>\n )\n}\n","import { Person } from \"@knpkv/rly/patterns\"\nimport { Text } from \"@knpkv/rly/primitives\"\nimport type { ReactElement, ReactNode } from \"react\"\n\nimport type { WorkspaceIssuePresentation } from \"./presentWorkspaceIssue.js\"\nimport styles from \"./WorkspaceIssueDetails.module.css\"\nimport { WorkspaceRichText } from \"./WorkspaceRichText.js\"\n\nconst Section = ({\n children,\n heading,\n meta\n}: {\n readonly children: ReactNode\n readonly heading: string\n readonly meta?: string\n}): ReactElement => (\n <section className={styles.section}>\n <header className={styles.sectionHeading}>\n <Text as=\"h2\" variant=\"section-title\">\n {heading}\n </Text>\n {meta === undefined ? null : (\n <Text tone=\"secondary\" variant=\"meta\">\n {meta}\n </Text>\n )}\n </header>\n {children}\n </section>\n)\n\nconst RichText = ({ empty, value }: { readonly empty: string; readonly value: string | null }): ReactElement =>\n value === null ? (\n <Text tone=\"secondary\">{empty}</Text>\n ) : (\n <WorkspaceRichText className={styles.richText} value={value} />\n )\n\n/** Render a complete, read-only synchronized issue as a quiet working document. */\nexport const WorkspaceIssueDetails = ({ issue }: { readonly issue: WorkspaceIssuePresentation }): ReactElement => (\n <article className={styles.document} data-workspace-issue-detail>\n {issue.truncationMessage === null ? null : (\n <Text className={styles.boundaryNotice} tone=\"secondary\">\n {issue.truncationMessage}\n </Text>\n )}\n\n <Section heading=\"Description\" meta=\"What changes and why\">\n <RichText empty=\"No description was synchronized from Jira.\" value={issue.description} />\n </Section>\n\n <Section heading=\"Acceptance criteria\" meta=\"The finish line\">\n <div className={styles.criteria}>\n <RichText empty=\"No acceptance criteria were synchronized.\" value={issue.acceptanceCriteria} />\n </div>\n </Section>\n\n {issue.environment === null ? null : (\n <Section heading=\"Environment\" meta=\"Where this applies\">\n <RichText empty=\"No environment was synchronized.\" value={issue.environment} />\n </Section>\n )}\n\n <Section heading=\"People\" meta={`${String(issue.collaborators.length)} collaborators`}>\n {issue.collaborators.length === 0 ? (\n <Text tone=\"secondary\">No Jira collaborator was synchronized for this issue.</Text>\n ) : (\n <ul className={styles.people}>\n {issue.collaborators.map((person) => (\n <li key={person.id}>\n <Person person={person} />\n </li>\n ))}\n </ul>\n )}\n </Section>\n\n <Section heading=\"Issue details\" meta=\"Synchronized fields\">\n <dl className={styles.metadata}>\n {issue.metadata.map((field) => (\n <div key={field.label}>\n <dt>{field.label}</dt>\n <dd>{field.value}</dd>\n </div>\n ))}\n </dl>\n </Section>\n\n {issue.parent === null && issue.subtasks.length === 0 ? null : (\n <Section heading=\"Related Jira work\" meta=\"Source hierarchy\">\n <div className={styles.related}>\n {issue.parent === null ? null : (\n <div>\n <Text tone=\"secondary\" variant=\"meta\">\n Parent\n </Text>\n {issue.parent.href === null ? (\n <strong>{issue.parent.key}</strong>\n ) : (\n <a href={issue.parent.href} rel=\"noreferrer\" target=\"_blank\">\n {issue.parent.key}\n </a>\n )}\n <span>{issue.parent.summary}</span>\n <small>{issue.parent.status}</small>\n </div>\n )}\n {issue.subtasks.map((subtask) => (\n <div key={subtask.key}>\n <Text tone=\"secondary\" variant=\"meta\">\n Subtask\n </Text>\n {subtask.href === null ? (\n <strong>{subtask.key}</strong>\n ) : (\n <a href={subtask.href} rel=\"noreferrer\" target=\"_blank\">\n {subtask.key}\n </a>\n )}\n <span>{subtask.summary}</span>\n <small>{subtask.status}</small>\n </div>\n ))}\n </div>\n </Section>\n )}\n\n <Section heading=\"Comments\" meta={`${String(issue.commentCount)} comments`}>\n {issue.commentBodiesTruncated ? (\n <Text className={styles.collectionNotice} tone=\"secondary\">\n Jira shortened comment bodies to keep this synchronized view bounded.\n </Text>\n ) : null}\n {issue.commentsTruncated ? (\n <Text className={styles.collectionNotice} tone=\"secondary\">\n Only the newest synchronized comments are shown.\n </Text>\n ) : null}\n {issue.comments.length === 0 ? (\n <Text tone=\"secondary\">No comment was synchronized for this issue.</Text>\n ) : (\n <ol className={styles.conversation}>\n {issue.comments.map((comment) => (\n <li key={comment.id}>\n <div className={styles.attribution}>\n <Person person={comment.author} size=\"compact\" />\n {comment.time === null ? null : <time>{comment.time}</time>}\n </div>\n <WorkspaceRichText className={styles.commentBody} value={comment.body ?? \"Comment body unavailable.\"} />\n </li>\n ))}\n </ol>\n )}\n </Section>\n\n <Section heading=\"History\" meta={`${String(issue.historyCount)} changes`}>\n {issue.historyTruncated ? (\n <Text className={styles.collectionNotice} tone=\"secondary\">\n Only the newest synchronized history is shown.\n </Text>\n ) : null}\n {issue.history.length === 0 ? (\n <Text tone=\"secondary\">No field history was synchronized for this issue.</Text>\n ) : (\n <ol className={styles.history}>\n {issue.history.map((entry) => (\n <li key={entry.id}>\n <div className={styles.attribution}>\n <Person person={entry.actor} size=\"compact\" />\n {entry.time === null ? null : <time>{entry.time}</time>}\n </div>\n <dl>\n {entry.changes.map((change, index) => (\n <div key={`${change.field}:${String(index)}`}>\n <dt>{change.field}</dt>\n <dd>{change.transition}</dd>\n </div>\n ))}\n </dl>\n </li>\n ))}\n </ol>\n )}\n </Section>\n </article>\n)\n","import { StageRail } from \"@knpkv/rly/patterns\"\nimport { StateLabel, Text } from \"@knpkv/rly/primitives\"\nimport type { ReactElement, ReactNode } from \"react\"\n\nimport type { WorkspacePipelineExecutionPresentation } from \"./presentWorkspacePipelineExecution.js\"\nimport styles from \"./WorkspacePipelineExecutionDetails.module.css\"\n\nconst Section = ({\n children,\n heading,\n meta\n}: {\n readonly children: ReactNode\n readonly heading: string\n readonly meta: string\n}): ReactElement => (\n <section className={styles.section}>\n <header className={styles.sectionHeading}>\n <Text as=\"h2\" variant=\"section-title\">\n {heading}\n </Text>\n <Text tone=\"secondary\" variant=\"meta\">\n {meta}\n </Text>\n </header>\n {children}\n </section>\n)\n\nconst Timestamp = ({ value }: { readonly value: WorkspacePipelineExecutionPresentation[\"startedAt\"] }): ReactElement =>\n value === null ? <>Not synchronized</> : <time dateTime={value.dateTime}>{value.label}</time>\n\n/** Render one immutable CodePipeline execution as an operator-readable flight recorder. */\nexport const WorkspacePipelineExecutionDetails = ({\n pipeline\n}: {\n readonly pipeline: WorkspacePipelineExecutionPresentation\n}): ReactElement => (\n <article className={styles.document} data-workspace-pipeline-execution-detail>\n <section aria-label=\"Execution identity\" className={styles.hero}>\n <div className={styles.heroHeading}>\n <span>Execution</span>\n <strong>{pipeline.executionId}</strong>\n <StateLabel\n label={pipeline.status}\n tone={\n pipeline.status === \"Succeeded\"\n ? \"positive\"\n : pipeline.status === \"Failed\"\n ? \"critical\"\n : pipeline.status === \"Running\"\n ? \"progress\"\n : pipeline.status === \"Stopped\"\n ? \"caution\"\n : \"neutral\"\n }\n />\n </div>\n {pipeline.statusSummary === null ? null : <p className={styles.summary}>{pipeline.statusSummary}</p>}\n <dl className={styles.heroFacts}>\n <div>\n <dt>Why</dt>\n <dd>\n {pipeline.triggerType}\n <small>{pipeline.triggerDetail}</small>\n </dd>\n </div>\n <div>\n <dt>Revision</dt>\n <dd>\n <code>{pipeline.triggerRevision}</code>\n </dd>\n </div>\n <div>\n <dt>Where</dt>\n <dd>{pipeline.targetEnvironment}</dd>\n </div>\n <div>\n <dt>Duration</dt>\n <dd>{pipeline.duration}</dd>\n </div>\n </dl>\n <dl className={styles.executionMeta}>\n <div>\n <dt>Pipeline</dt>\n <dd>\n {pipeline.pipelineName} · {pipeline.pipelineVersion}\n </dd>\n </div>\n <div>\n <dt>Started</dt>\n <dd>\n <Timestamp value={pipeline.startedAt} />\n </dd>\n </div>\n <div>\n <dt>Updated</dt>\n <dd>\n <Timestamp value={pipeline.updatedAt} />\n </dd>\n </div>\n <div>\n <dt>Mode</dt>\n <dd>{pipeline.executionMode}</dd>\n </div>\n </dl>\n </section>\n\n <StageRail\n className={styles.stageRail}\n emptyLabel=\"No stage detail was synchronized for this execution.\"\n heading=\"Execution path\"\n stages={pipeline.stages}\n />\n\n <Section heading=\"People\" meta=\"Provider identities that operated or approved this run\">\n <div className={styles.peopleLanes}>\n <div>\n <small>Operators</small>\n <strong>{pipeline.operators.join(\" · \") || \"Not synchronized\"}</strong>\n </div>\n <div>\n <small>Approvers</small>\n <strong>{pipeline.approvers.join(\" · \") || \"No approval recorded\"}</strong>\n </div>\n </div>\n </Section>\n\n <Section\n heading=\"Actions\"\n meta={`${pipeline.actionCountLabel} actions · ${String(pipeline.pagesRead)} bounded pages read`}\n >\n {pipeline.actionsTruncated ? (\n <p className={styles.partial}>This is a bounded view. Additional action detail exists in CodePipeline.</p>\n ) : null}\n {pipeline.actions.length === 0 ? (\n <Text tone=\"secondary\">No action detail was synchronized for this execution.</Text>\n ) : (\n <ol className={styles.actions}>\n {pipeline.actions.map((action) => (\n <li data-tone={action.tone} key={action.id}>\n <header>\n <span>\n <small>{action.stageName}</small>\n <strong>{action.name}</strong>\n </span>\n <StateLabel label={action.status} tone={action.tone} />\n </header>\n <dl>\n <div>\n <dt>Provider</dt>\n <dd>{action.provider}</dd>\n </div>\n <div>\n <dt>Duration</dt>\n <dd>{action.duration}</dd>\n </div>\n <div>\n <dt>Actor</dt>\n <dd>{action.actor ?? \"Not synchronized\"}</dd>\n </div>\n <div>\n <dt>Region</dt>\n <dd>{action.region ?? \"Not synchronized\"}</dd>\n </div>\n </dl>\n {action.summary === null ? null : <p>{action.summary}</p>}\n {action.error === null ? null : <p className={styles.error}>{action.error}</p>}\n {action.artifacts.length === 0 ? null : (\n <ul className={styles.artifacts}>\n {action.artifacts.map((artifact, index) => (\n <li key={`${artifact.direction}-${artifact.name}-${String(index)}`}>\n <span>{artifact.direction}</span>\n <strong>{artifact.name}</strong>\n <small>{artifact.accessLabel}</small>\n </li>\n ))}\n </ul>\n )}\n </li>\n ))}\n </ol>\n )}\n </Section>\n\n <Section heading=\"Source artifacts\" meta=\"Metadata only; content stays behind the authenticated proxy\">\n {pipeline.sourceArtifacts.length === 0 ? (\n <Text tone=\"secondary\">No source artifact metadata was synchronized.</Text>\n ) : (\n <ul className={styles.sourceArtifacts}>\n {pipeline.sourceArtifacts.map((artifact) => (\n <li key={`${artifact.name}-${artifact.revision}`}>\n <span>\n <strong>{artifact.name}</strong>\n <code>{artifact.revision}</code>\n </span>\n <span>\n {artifact.summary ?? \"No summary\"}\n <small>{artifact.accessLabel}</small>\n </span>\n </li>\n ))}\n </ul>\n )}\n </Section>\n\n <Section heading=\"Delivery evidence\" meta=\"Current accepted relationships around this exact run\">\n <dl className={styles.deliveryCounts}>\n <div>\n <dt>Releases</dt>\n <dd>{pipeline.releaseCountLabel}</dd>\n </div>\n <div>\n <dt>Pull requests</dt>\n <dd>{pipeline.pullRequestCountLabel}</dd>\n </div>\n <div>\n <dt>Runbooks</dt>\n <dd>{pipeline.runbookCountLabel}</dd>\n </div>\n </dl>\n <Text tone=\"secondary\">\n Use the delivery relationships below to open each connected object and inspect its evidence.\n </Text>\n </Section>\n </article>\n)\n","import * as DateTime from \"effect/DateTime\"\nimport * as Duration from \"effect/Duration\"\nimport * as Effect from \"effect/Effect\"\nimport * as Predicate from \"effect/Predicate\"\nimport { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\"\n\nimport type {\n AgentProviderCatalog,\n AgentProviderCatalogEntry,\n DurableAgentPrompt,\n PublishedReviewComment,\n PullRequestReviewState,\n PullRequestReviewThreadPage,\n ReleaseAgentThreadCursor,\n ReviewSuggestionPublicationContent,\n ReviewSuggestionPublicationPreview,\n ReviewSuggestionPublicationSelection\n} from \"../../api/agent.js\"\nimport type { RateLimitedApiError } from \"../../api/errors.js\"\nimport type { EntityId } from \"../../domain/identifiers.js\"\nimport {\n isRecoverablePullRequestReviewFailure,\n isUnauthorizedPullRequestReviewFailure\n} from \"./pullRequestReviewFailures.js\"\nimport type { PullRequestReviewThread } from \"./pullRequestReviewThreadReplay.js\"\n\nconst pullRequestReviewBrowser = import(\"./pullRequestReviewThreadReplay.js\")\nconst generatedClientTransport = pullRequestReviewBrowser.then(\n ({ generatedClientPullRequestReviewTransport }) => generatedClientPullRequestReviewTransport\n)\n\nconst isRateLimitedReviewFailure = (failure: unknown): failure is RateLimitedApiError =>\n Predicate.isTagged(failure, \"RateLimitedApiError\")\n\nconst waitBeforeAutomaticReviewRetry = (failure?: unknown): Effect.Effect<void> => {\n if (!isRateLimitedReviewFailure(failure)) return Effect.sleep(Duration.seconds(1))\n const retryAt = failure.retryAt\n if (retryAt === null) return Effect.sleep(Duration.seconds(2))\n return Effect.flatMap(DateTime.now, (now) =>\n Effect.sleep(\n Duration.millis(\n Math.max(0, DateTime.toEpochMillis(retryAt) - DateTime.toEpochMillis(now))\n )\n ))\n}\n\ninterface ReviewProviderSelection {\n readonly displayName?: NonNullable<AgentProviderCatalogEntry[\"displayName\"]>\n readonly model: AgentProviderCatalogEntry[\"models\"][number]\n readonly providerId: AgentProviderCatalogEntry[\"providerId\"]\n readonly reviewProfile: NonNullable<AgentProviderCatalogEntry[\"reviewProfile\"]>\n}\n\nexport interface PullRequestReviewScope {\n readonly baseRevision: string | null\n readonly entityId: EntityId\n readonly headRevision: string\n readonly sessionKey: string\n}\n\n/** Browser selection resolved to an exact revision before publication preview. */\nexport type ReviewSuggestionPublicationTarget = Pick<\n ReviewSuggestionPublicationSelection,\n \"jobId\" | \"revisionId\" | \"suggestionId\"\n>\n\nexport type PullRequestReviewControllerState =\n | { readonly _tag: \"idle\" }\n | ({ readonly _tag: \"loading\" } & PullRequestReviewScope)\n | ({ readonly _tag: \"failed\" } & PullRequestReviewScope)\n | ({\n readonly _tag: \"ready\"\n readonly action: \"idle\" | \"starting\" | \"failed\"\n readonly historyAction: \"idle\" | \"loading\" | \"failed\"\n readonly provider: ReviewProviderSelection | null\n /** Ordered launch presets; `provider` remains the default for older callers. */\n readonly providerPresets?: ReadonlyArray<ReviewProviderSelection>\n readonly review: PullRequestReviewState\n readonly thread?: PullRequestReviewThread\n } & PullRequestReviewScope)\n\nexport type PullRequestReviewPublicationState =\n | { readonly _tag: \"idle\" }\n | {\n readonly _tag: \"previewing\"\n readonly selection: ReviewSuggestionPublicationTarget\n }\n | {\n readonly _tag: \"preview\"\n readonly preview: ReviewSuggestionPublicationPreview\n }\n | {\n readonly _tag: \"publishing\"\n readonly preview: ReviewSuggestionPublicationPreview\n }\n | {\n readonly _tag: \"published\"\n readonly headSuperseded: boolean\n readonly preview: ReviewSuggestionPublicationPreview\n readonly publication: PublishedReviewComment\n }\n | {\n readonly _tag: \"receipt-conflict\"\n readonly preview: ReviewSuggestionPublicationPreview\n readonly publication: PublishedReviewComment\n }\n | {\n readonly _tag: \"failed\"\n readonly preview: ReviewSuggestionPublicationPreview | null\n readonly selection: ReviewSuggestionPublicationTarget\n }\n\n/** Browser boundary for immutable pull-request review reads and mutations. */\nexport interface PullRequestReviewTransport {\n readonly enqueue: (\n entityId: EntityId,\n provider: ReviewProviderSelection,\n prompt: DurableAgentPrompt | undefined,\n signal: AbortSignal\n ) => Promise<PullRequestReviewState>\n readonly load: (entityId: EntityId, signal: AbortSignal) => Promise<PullRequestReviewState>\n readonly loadThread: (\n entityId: EntityId,\n cursor: ReleaseAgentThreadCursor | null,\n signal: AbortSignal,\n direction?: \"after\" | \"before\"\n ) => Promise<PullRequestReviewThreadPage>\n readonly previewPublication: (\n entityId: EntityId,\n selection: ReviewSuggestionPublicationTarget,\n signal: AbortSignal\n ) => Promise<ReviewSuggestionPublicationPreview>\n readonly providers: (signal: AbortSignal) => Promise<AgentProviderCatalog>\n readonly publishSuggestion: (\n entityId: EntityId,\n selection: ReviewSuggestionPublicationSelection,\n finalContent: ReviewSuggestionPublicationContent,\n authorityBinding: ReviewSuggestionPublicationPreview[\"authorityBinding\"],\n signal: AbortSignal\n ) => Promise<PublishedReviewComment>\n}\n\nconst eligibleProviders = (catalog: AgentProviderCatalog): ReadonlyArray<ReviewProviderSelection> => {\n const eligible = new Array<ReviewProviderSelection>()\n for (const provider of catalog.providers) {\n const model = provider.models[0]\n if (\n provider.health === \"available\" &&\n provider.capabilities.includes(\"pr-review\") &&\n provider.reviewProfile !== undefined &&\n model\n ) {\n eligible.push({\n providerId: provider.providerId,\n model,\n reviewProfile: provider.reviewProfile,\n ...(provider.displayName === undefined ? {} : { displayName: provider.displayName })\n })\n }\n }\n return eligible\n}\n\n/** Generated-client transport for the authenticated immutable-review contract. */\nexport const browserPullRequestReviewTransport: PullRequestReviewTransport = {\n enqueue: (...args) => generatedClientTransport.then((transport) => transport.enqueue(...args)),\n load: (...args) => generatedClientTransport.then((transport) => transport.load(...args)),\n loadThread: (...args) => generatedClientTransport.then((transport) => transport.loadThread(...args)),\n previewPublication: (...args) => generatedClientTransport.then((transport) => transport.previewPublication(...args)),\n providers: (...args) => generatedClientTransport.then((transport) => transport.providers(...args)),\n publishSuggestion: (...args) => generatedClientTransport.then((transport) => transport.publishSuggestion(...args))\n}\n\nconst sameReviewScope = (\n left: PullRequestReviewScope,\n right: PullRequestReviewScope\n): boolean =>\n left.baseRevision === right.baseRevision &&\n left.entityId === right.entityId &&\n left.headRevision === right.headRevision &&\n left.sessionKey === right.sessionKey\n\n/** Observe the lazy history boundary so a missing browser chunk remains retryable. */\nexport const observePullRequestReviewHistoryLoad = (\n task: Promise<void>,\n signal: AbortSignal,\n current: PullRequestReviewControllerState & PullRequestReviewScope,\n latestScope: { readonly current: PullRequestReviewScope | null },\n setState: (\n update: (state: PullRequestReviewControllerState) => PullRequestReviewControllerState\n ) => void\n): void => {\n task.catch((failure: unknown) => {\n if (\n signal.aborted ||\n latestScope.current === null ||\n !sameReviewScope(latestScope.current, current)\n ) return\n Effect.runFork(Effect.logError(\"Pull-request review history boundary failed\", failure))\n setState((latest) =>\n latest._tag === \"ready\" && sameReviewScope(latest, current)\n ? { ...latest, historyAction: \"failed\" }\n : latest\n )\n })\n}\n\n/** Publish the shared merged replay, not an older async caller snapshot. */\nexport const publishNewestPullRequestReviewThread = (\n candidate: PullRequestReviewThread,\n signal: AbortSignal,\n current: PullRequestReviewScope,\n latestScope: { readonly current: PullRequestReviewScope | null },\n latestThread: { readonly current: PullRequestReviewThread | null },\n setState: (\n update: (state: PullRequestReviewControllerState) => PullRequestReviewControllerState\n ) => void\n): void => {\n if (\n signal.aborted ||\n latestScope.current === null ||\n !sameReviewScope(latestScope.current, current)\n ) return\n setState((latest) =>\n latest._tag === \"ready\" && sameReviewScope(latest, current)\n ? { ...latest, thread: latestThread.current ?? candidate }\n : latest\n )\n}\n\nconst matchesScope = (\n review: PullRequestReviewState,\n scope: PullRequestReviewScope\n): boolean =>\n review._tag === \"unavailable\" ||\n (\n review.subject.baseRevision === scope.baseRevision &&\n review.subject.headRevision === scope.headRevision\n )\n\n/** Keep review state scoped to the exact entity and authenticated browser session. */\nexport const usePullRequestReview = (\n entityId: EntityId,\n baseRevision: string | null,\n headRevision: string | null,\n sessionKey: string | null,\n canEnqueue: boolean,\n onSessionExpired: (sessionKey: string) => void,\n transport: PullRequestReviewTransport = browserPullRequestReviewTransport\n): {\n readonly cancelPublication: () => void\n readonly loadEarlier: () => void\n readonly previewPublication: (selection: ReviewSuggestionPublicationTarget) => void\n readonly publication: PullRequestReviewPublicationState\n readonly publishSuggestion: (finalContent: ReviewSuggestionPublicationContent) => void\n readonly retry: () => void\n readonly start: (\n prompt?: DurableAgentPrompt,\n providerId?: ReviewProviderSelection[\"providerId\"]\n ) => void\n readonly state: PullRequestReviewControllerState\n} => {\n const [requestRevision, setRequestRevision] = useState(0)\n const [state, setState] = useState<PullRequestReviewControllerState>({ _tag: \"idle\" })\n const [publication, setPublication] = useState<PullRequestReviewPublicationState>({ _tag: \"idle\" })\n const historyAbort = useRef<AbortController | null>(null)\n const mutationAbort = useRef<AbortController | null>(null)\n const publicationAbort = useRef<AbortController | null>(null)\n const automaticRetryScope = useRef<PullRequestReviewScope | null>(null)\n const latestScope = useRef<PullRequestReviewScope | null>(null)\n const latestThread = useRef<PullRequestReviewThread | null>(null)\n const scope = useMemo(\n () =>\n sessionKey === null || headRevision === null\n ? null\n : { baseRevision, entityId, headRevision, sessionKey },\n [baseRevision, entityId, headRevision, sessionKey]\n )\n useLayoutEffect(() => {\n latestScope.current = scope\n }, [scope])\n useLayoutEffect(() => {\n latestThread.current = null\n }, [entityId, sessionKey])\n\n useEffect(() => {\n if (sessionKey === null || headRevision === null) {\n setState({ _tag: \"idle\" })\n return\n }\n const scope = { baseRevision, entityId, headRevision, sessionKey } satisfies PullRequestReviewScope\n const previousThread = latestThread.current ?? undefined\n const abort = new AbortController()\n const scheduleAutomaticRetry = (message: string, failure?: unknown): boolean => {\n if (\n automaticRetryScope.current !== null &&\n sameReviewScope(automaticRetryScope.current, scope)\n ) return false\n automaticRetryScope.current = scope\n Effect.runFork(Effect.logWarning(message, failure))\n Effect.runPromise(waitBeforeAutomaticReviewRetry(failure), { signal: abort.signal }).then(\n () => {\n if (!abort.signal.aborted) setRequestRevision((revision) => revision + 1)\n },\n (_retryFailure: unknown) => {\n if (!abort.signal.aborted) setState({ _tag: \"failed\", ...scope })\n }\n )\n return true\n }\n setState((current) =>\n current._tag === \"ready\" && sameReviewScope(current, scope)\n ? current\n : { _tag: \"loading\", ...scope }\n )\n pullRequestReviewBrowser.then(\n ({ loadPullRequestReviewSnapshot }) =>\n loadPullRequestReviewSnapshot(\n transport,\n entityId,\n canEnqueue,\n abort.signal,\n previousThread,\n latestThread\n )\n ).then(\n ({ catalog, catalogNeedsRetry, review, thread }) => {\n if (!abort.signal.aborted) {\n if (!catalogNeedsRetry) automaticRetryScope.current = null\n const providerPresets = eligibleProviders(catalog)\n setState(\n matchesScope(review, scope)\n ? {\n _tag: \"ready\",\n ...scope,\n action: \"idle\",\n historyAction: \"idle\",\n provider: providerPresets[0] ?? null,\n providerPresets,\n review,\n thread\n }\n : { _tag: \"failed\", ...scope }\n )\n if (catalogNeedsRetry) {\n scheduleAutomaticRetry(\"Pull-request review provider catalog unavailable; retrying once\")\n }\n }\n },\n (failure) => {\n if (abort.signal.aborted) return\n if (isUnauthorizedPullRequestReviewFailure(failure)) {\n onSessionExpired(sessionKey)\n setState({ _tag: \"failed\", ...scope })\n return\n }\n if (\n isRecoverablePullRequestReviewFailure(failure) &&\n scheduleAutomaticRetry(\n \"Pull-request review snapshot load failed; retrying once\",\n failure\n )\n ) {\n return\n }\n setState({ _tag: \"failed\", ...scope })\n }\n )\n return () => abort.abort()\n }, [\n baseRevision,\n canEnqueue,\n entityId,\n headRevision,\n onSessionExpired,\n requestRevision,\n sessionKey,\n transport\n ])\n\n useEffect(() => {\n if (state._tag !== \"ready\" || state.review._tag !== \"pending\") return\n const abort = new AbortController()\n Effect.runPromise(Effect.sleep(\"2 seconds\"), { signal: abort.signal }).then(\n () => {\n if (!abort.signal.aborted) setRequestRevision((revision) => revision + 1)\n },\n (_failure: unknown) => {\n if (!abort.signal.aborted) {\n setState({\n _tag: \"failed\",\n baseRevision: state.baseRevision,\n entityId: state.entityId,\n headRevision: state.headRevision,\n sessionKey: state.sessionKey\n })\n }\n }\n )\n return () => abort.abort()\n }, [state])\n\n useEffect(\n () => () => {\n historyAbort.current?.abort()\n mutationAbort.current?.abort()\n publicationAbort.current?.abort()\n },\n []\n )\n useEffect(() => {\n historyAbort.current?.abort()\n historyAbort.current = null\n mutationAbort.current?.abort()\n mutationAbort.current = null\n publicationAbort.current?.abort()\n publicationAbort.current = null\n setPublication({ _tag: \"idle\" })\n }, [entityId, sessionKey])\n useLayoutEffect(() => {\n mutationAbort.current?.abort()\n mutationAbort.current = null\n setPublication((current) => current._tag === \"publishing\" ? current : { _tag: \"idle\" })\n }, [baseRevision, headRevision])\n\n const refreshThread = useCallback((\n refreshScope: PullRequestReviewScope,\n signal: AbortSignal\n ): void => {\n const previous = latestThread.current ?? undefined\n pullRequestReviewBrowser.then(\n ({ refreshPullRequestReviewThread }) =>\n refreshPullRequestReviewThread(\n transport,\n refreshScope.entityId,\n signal,\n previous,\n latestThread\n )\n ).then(\n (thread) => {\n publishNewestPullRequestReviewThread(\n thread,\n signal,\n refreshScope,\n latestScope,\n latestThread,\n setState\n )\n },\n () => undefined\n )\n }, [transport])\n\n const loadEarlier = useCallback(() => {\n if (\n state._tag !== \"ready\" ||\n state.historyAction === \"loading\" ||\n state.thread === undefined ||\n !state.thread.hasEarlier\n ) return\n const current = state\n const currentThread = state.thread\n historyAbort.current?.abort()\n const abort = new AbortController()\n historyAbort.current = abort\n setState({ ...current, historyAction: \"loading\" })\n observePullRequestReviewHistoryLoad(\n pullRequestReviewBrowser.then(\n ({ loadEarlierPullRequestReviewThreadIntoState }) =>\n loadEarlierPullRequestReviewThreadIntoState(\n transport,\n current,\n currentThread,\n abort.signal,\n latestScope,\n latestThread,\n onSessionExpired,\n setState\n )\n ),\n abort.signal,\n current,\n latestScope,\n setState\n )\n }, [onSessionExpired, state, transport])\n\n const start = useCallback((\n prompt?: DurableAgentPrompt,\n providerId?: ReviewProviderSelection[\"providerId\"]\n ) => {\n if (state._tag !== \"ready\" || state.review._tag === \"unavailable\") return\n const provider = providerId === undefined\n ? state.provider\n : state.providerPresets?.find((candidate) => candidate.providerId === providerId) ?? null\n if (provider === null) return\n const current = state\n mutationAbort.current?.abort()\n const abort = new AbortController()\n mutationAbort.current = abort\n setState({ ...current, action: \"starting\" })\n transport.enqueue(entityId, provider, prompt, abort.signal).then(\n (review) => {\n if (abort.signal.aborted) return\n setState((latest) =>\n latest._tag === \"ready\" &&\n sameReviewScope(latest, current) &&\n matchesScope(review, current)\n ? { ...latest, action: \"idle\", review }\n : latest._tag === \"ready\" && sameReviewScope(latest, current)\n ? {\n _tag: \"failed\",\n baseRevision: current.baseRevision,\n entityId: current.entityId,\n headRevision: current.headRevision,\n sessionKey: current.sessionKey\n }\n : latest\n )\n },\n (failure) => {\n if (abort.signal.aborted) return\n if (isUnauthorizedPullRequestReviewFailure(failure)) onSessionExpired(current.sessionKey)\n setState((latest) =>\n latest._tag === \"ready\" && sameReviewScope(latest, current)\n ? { ...latest, action: \"failed\" }\n : latest\n )\n }\n )\n }, [entityId, onSessionExpired, state, transport])\n\n const previewPublication = useCallback((selection: ReviewSuggestionPublicationTarget) => {\n if (\n state._tag !== \"ready\" ||\n state.review._tag !== \"completed\" ||\n state.review.jobId !== selection.jobId ||\n !state.review.report.suggestions.some(\n ({ suggestionId }) => suggestionId === selection.suggestionId\n )\n ) return\n const current = state\n mutationAbort.current?.abort()\n const abort = new AbortController()\n mutationAbort.current = abort\n setPublication({ _tag: \"previewing\", selection })\n transport.previewPublication(entityId, selection, abort.signal).then(\n (preview) => {\n if (abort.signal.aborted) return\n setPublication(\n preview.subject.headRevision === current.headRevision\n ? { _tag: \"preview\", preview }\n : { _tag: \"failed\", preview: null, selection }\n )\n },\n (failure) => {\n if (abort.signal.aborted) return\n if (isUnauthorizedPullRequestReviewFailure(failure)) onSessionExpired(current.sessionKey)\n setPublication({ _tag: \"failed\", preview: null, selection })\n }\n )\n }, [entityId, onSessionExpired, state, transport])\n\n const publishSuggestion = useCallback((finalContent: ReviewSuggestionPublicationContent) => {\n if (state._tag !== \"ready\") return\n const preview = publication._tag === \"preview\"\n ? publication.preview\n : publication._tag === \"failed\"\n ? publication.preview\n : null\n if (preview === null) return\n const current = state\n const selection = {\n jobId: preview.jobId,\n suggestionId: preview.suggestionId,\n revisionId: preview.revisionId\n }\n publicationAbort.current?.abort()\n const abort = new AbortController()\n publicationAbort.current = abort\n setPublication({ _tag: \"publishing\", preview })\n transport.publishSuggestion(\n entityId,\n selection,\n finalContent,\n preview.authorityBinding,\n abort.signal\n ).then(\n (published) => {\n if (abort.signal.aborted) return\n const receiptMatches = published.suggestionRevision.reviewedHead ===\n preview.suggestionRevision.reviewedHead\n if (receiptMatches) {\n setState((latest) =>\n latest._tag === \"ready\" && latest.review._tag === \"completed\" &&\n latest.review.jobId === published.jobId\n ? {\n ...latest,\n review: {\n ...latest.review,\n report: {\n ...latest.review.report,\n suggestions: latest.review.report.suggestions.map((suggestion) => {\n if (suggestion.suggestionId !== published.suggestionId) return suggestion\n const transitioned: typeof suggestion = { ...suggestion, state: \"published\" }\n return transitioned\n })\n }\n }\n }\n : latest\n )\n }\n setPublication(\n receiptMatches\n ? {\n _tag: \"published\",\n headSuperseded: latestScope.current === null ||\n published.subject.baseRevision !== latestScope.current.baseRevision ||\n published.subject.headRevision !== latestScope.current.headRevision,\n preview,\n publication: published\n }\n : { _tag: \"receipt-conflict\", preview, publication: published }\n )\n const activeScope = latestScope.current\n if (\n activeScope !== null &&\n activeScope.entityId === current.entityId &&\n activeScope.sessionKey === current.sessionKey\n ) refreshThread(activeScope, abort.signal)\n },\n (failure) => {\n if (abort.signal.aborted) return\n if (isUnauthorizedPullRequestReviewFailure(failure)) onSessionExpired(current.sessionKey)\n setPublication({ _tag: \"failed\", preview, selection })\n }\n )\n }, [entityId, onSessionExpired, publication, refreshThread, state, transport])\n\n const currentState: PullRequestReviewControllerState = scope === null\n ? { _tag: \"idle\" }\n : state._tag !== \"idle\" && sameReviewScope(state, scope)\n ? state\n : { _tag: \"loading\", ...scope }\n\n return {\n cancelPublication: useCallback(() => {\n mutationAbort.current?.abort()\n mutationAbort.current = null\n publicationAbort.current?.abort()\n publicationAbort.current = null\n setPublication({ _tag: \"idle\" })\n }, []),\n loadEarlier,\n previewPublication,\n publication,\n publishSuggestion,\n retry: useCallback(() => {\n automaticRetryScope.current = null\n setRequestRevision((revision) => revision + 1)\n }, []),\n start,\n state: currentState\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): { readonly retry: () => void; readonly state: WorkspaceEntityState } => {\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 { LinkProvider } from \"@knpkv/rly/foundations\"\nimport {\n AgentContextButton,\n CollaboratorGroup,\n EntityShell,\n EvidenceStamp,\n RelationshipChain,\n RelationshipTable,\n ServiceMark,\n TimelineRow,\n type RlyCollaboratorCategory\n} from \"@knpkv/rly/patterns\"\nimport { Button, Skeleton, StatePanel, Text } from \"@knpkv/rly/primitives\"\nimport { type ReactElement, lazy, Suspense, useEffect, useRef, useState } from \"react\"\nimport { Link, useLocation, useNavigate, useOutletContext, useParams } from \"react-router\"\n\nimport type { DurableAgentPrompt } from \"../../api/agent.js\"\nimport type { SubmitClockifyActionRequest } from \"../../api/deliveryGraph.js\"\nimport type { EntityId as EntityIdType, WorkspaceId as WorkspaceIdType } from \"../../domain/identifiers.js\"\nimport { browserReadableSessionKey, useBrowserSession } from \"../BrowserSession.js\"\nimport {\n decodeEntityRouteId,\n resolveWorkspaceEntityOrigin,\n type WorkspaceEntityOrigin,\n workspaceEntityAgentPath,\n workspaceEntityOriginHref,\n workspaceEntityParentPath\n} from \"../items/workspaceEntityRoutes.js\"\nimport type { WorkspaceReleaseOutletContext } from \"../releases/WorkspaceReleaseLayout.js\"\nimport { presentWorkspaceEntity, type WorkspaceEntityPresentation } from \"./presentWorkspaceEntity.js\"\nimport { WorkspaceEntityLink } from \"./WorkspaceEntityLink.js\"\nimport styles from \"./WorkspaceEntityRoute.module.css\"\nimport { WorkspaceClockifyTimeEntryDetails } from \"./WorkspaceClockifyTimeEntryDetails.js\"\nimport { type ClockifyActionSubmissionState, useClockifyActionSubmission } from \"./useClockifyActionSubmission.js\"\nimport { WorkspaceConfluencePageDetails } from \"./WorkspaceConfluencePageDetails.js\"\nimport { WorkspaceIssueDetails } from \"./WorkspaceIssueDetails.js\"\nimport { WorkspacePipelineExecutionDetails } from \"./WorkspacePipelineExecutionDetails.js\"\nimport {\n usePullRequestReview,\n type PullRequestReviewControllerState,\n type PullRequestReviewPublicationState,\n type ReviewSuggestionPublicationTarget\n} from \"./usePullRequestReview.js\"\nimport type { ReviewSuggestionRevisionTransport } from \"./useReviewSuggestionRevisions.js\"\nimport { useWorkspaceEntity, type WorkspaceEntityState } from \"./useWorkspaceEntity.js\"\n\nconst WorkspacePullRequestDetails = lazy(() =>\n import(\"./WorkspacePullRequestDetails.js\").then((module) => ({\n default: module.WorkspacePullRequestDetails\n }))\n)\n\nconst originLabel = (href: string, workspaceId: WorkspaceIdType): string => {\n const pathname = href.split(/[?#]/u, 1)[0] ?? \"\"\n if (pathname === workspaceEntityParentPath(workspaceId)) return \"Back to items\"\n if (pathname.includes(\"/releases/\")) return \"Back to release\"\n if (pathname.endsWith(\"/work\")) return \"Back to active work\"\n if (pathname.endsWith(\"/timeline\")) return \"Back to timeline\"\n return \"Back to workspace\"\n}\n\nconst RouteState = ({\n action,\n description,\n title,\n tone = \"neutral\"\n}: {\n readonly action?: ReactElement\n readonly description: string\n readonly title: string\n readonly tone?: \"critical\" | \"neutral\" | \"progress\"\n}): ReactElement => {\n const ref = useRef<HTMLElement>(null)\n useEffect(() => ref.current?.focus(), [])\n return (\n <section className={styles.state} data-workspace-entity-state={tone} ref={ref} tabIndex={-1}>\n <StatePanel action={action} description={description} title={title} tone={tone} />\n </section>\n )\n}\n\nconst LoadingEntity = (): ReactElement => (\n <section aria-label=\"Loading canonical entity\" className={styles.loading}>\n <Skeleton decorative={false} height=\"12rem\" label=\"Loading canonical entity\" variant=\"block\" />\n <div className={styles.loadingColumns}>\n <Skeleton height=\"20rem\" variant=\"block\" />\n <Skeleton height=\"20rem\" variant=\"block\" />\n </div>\n </section>\n)\n\nconst PrincipalAction = ({\n action\n}: {\n readonly action: WorkspaceEntityPresentation[\"primaryAction\"]\n}): ReactElement => {\n if (action.href === null) {\n return (\n <Button disabled size=\"principal\" stretch variant=\"primary\">\n {action.label}\n </Button>\n )\n }\n return action.external ? (\n <a className={styles.principalAction} href={action.href} rel=\"noreferrer\" target=\"_blank\">\n {action.label}\n </a>\n ) : (\n <Link className={styles.principalAction} to={action.href}>\n {action.label}\n </Link>\n )\n}\n\nconst DeliveryPath = ({ presentation }: { readonly presentation: WorkspaceEntityPresentation }): ReactElement => (\n <section aria-labelledby=\"workspace-entity-path\" className={styles.deliveryPath}>\n <div className={styles.sectionHeading}>\n <Text as=\"h2\" id=\"workspace-entity-path\" variant=\"section-title\">\n Delivery path\n </Text>\n <Text tone=\"secondary\" variant=\"meta\">\n Where this work lives\n </Text>\n </div>\n <div className={styles.pathRail}>\n <div className={styles.pathNode}>\n <ServiceMark service={presentation.service} size=\"compact\" />\n <span>\n <strong>{presentation.serviceName}</strong>\n <code>{presentation.displayKey}</code>\n </span>\n </div>\n {presentation.releases.length === 0 ? (\n <div className={styles.pathEmpty}>No release membership yet</div>\n ) : (\n <ol className={styles.releasePath}>\n {presentation.releases.map((release) => (\n <li key={release.id}>\n <Link to={release.href}>{release.label}</Link>\n </li>\n ))}\n </ol>\n )}\n </div>\n <Text tone=\"secondary\">{presentation.contentSummary}</Text>\n </section>\n)\n\nconst EntityFacts = ({ presentation }: { readonly presentation: WorkspaceEntityPresentation }): ReactElement => (\n <section aria-labelledby=\"workspace-entity-facts\" className={styles.facts}>\n <Text as=\"h2\" id=\"workspace-entity-facts\" variant=\"card-title\">\n At a glance\n </Text>\n <dl>\n {presentation.facts.map((fact) => (\n <div key={fact.label}>\n <dt>{fact.label}</dt>\n <dd>{fact.value}</dd>\n </div>\n ))}\n </dl>\n </section>\n)\n\nconst EntityEvidence = ({ presentation }: { readonly presentation: WorkspaceEntityPresentation }): ReactElement => (\n <section aria-labelledby=\"workspace-entity-evidence\" className={styles.evidence}>\n <Text as=\"h2\" id=\"workspace-entity-evidence\" variant=\"card-title\">\n Provenance\n </Text>\n <EvidenceStamp\n freshness={presentation.evidence.freshness}\n freshnessDateTime={presentation.evidence.freshnessDateTime}\n freshnessTime={presentation.evidence.freshnessTime}\n reference={presentation.evidence.reference}\n service={presentation.service}\n />\n <Text tone=\"secondary\" variant=\"meta\">\n {presentation.evidence.itemCount} evidence item{presentation.evidence.itemCount === 1 ? \"\" : \"s\"} ·{\" \"}\n {presentation.evidence.claimCount} claim{presentation.evidence.claimCount === 1 ? \"\" : \"s\"}\n </Text>\n </section>\n)\n\nconst EntityCollaborators = ({\n presentation\n}: {\n readonly presentation: WorkspaceEntityPresentation\n}): ReactElement => {\n const [expanded, setExpanded] = useState<ReadonlyArray<RlyCollaboratorCategory>>(\n presentation.collaborators.expandedCategories\n )\n return (\n <div className={styles.workingCircle}>\n <CollaboratorGroup\n approvers={presentation.collaborators.approvers}\n authors={presentation.collaborators.authors}\n emptyLabel={presentation.collaborators.emptyLabel}\n expandedCategories={expanded}\n heading=\"Working circle\"\n limit={3}\n onCategoryExpandedChange={(category, nextExpanded) => {\n setExpanded((current) =>\n nextExpanded ? [...new Set([...current, category])] : current.filter((candidate) => candidate !== category)\n )\n }}\n operators={presentation.collaborators.operators}\n owners={presentation.collaborators.owners}\n reviewers={presentation.collaborators.reviewers}\n size=\"compact\"\n />\n </div>\n )\n}\n\nconst EntityRelationships = ({ presentation }: { readonly presentation: WorkspaceEntityPresentation }): ReactElement =>\n presentation.relationships.length <= 4 ? (\n <RelationshipChain\n emptyLabel={presentation.relationshipEmptyLabel}\n heading=\"Delivery relationships\"\n relationships={presentation.relationships}\n />\n ) : (\n <RelationshipTable\n emptyLabel={presentation.relationshipEmptyLabel}\n heading=\"Delivery relationships\"\n relationships={presentation.relationships}\n />\n )\n\nconst EntityActivity = ({ presentation }: { readonly presentation: WorkspaceEntityPresentation }): ReactElement => (\n <section aria-labelledby=\"workspace-entity-activity\" className={styles.activity}>\n <div className={styles.sectionHeading}>\n <Text as=\"h2\" id=\"workspace-entity-activity\" variant=\"section-title\">\n Activity\n </Text>\n <Text tone=\"secondary\" variant=\"meta\">\n Quiet, attributable history\n </Text>\n </div>\n {presentation.activity.length === 0 ? (\n <Text tone=\"secondary\">{presentation.activityEmptyLabel}</Text>\n ) : (\n <ol className={styles.timeline}>\n {presentation.activity.map((event, index) => (\n <TimelineRow continued={index < presentation.activity.length - 1} event={event} key={event.id} />\n ))}\n </ol>\n )}\n </section>\n)\n\nconst staleMessage = (state: Extract<WorkspaceEntityState, { readonly _tag: \"stale\" }>): string => {\n switch (state.reason) {\n case \"refreshing\":\n return \"Refreshing from the connected service. The last complete inspection remains visible.\"\n case \"refresh-failed\":\n return \"The latest refresh failed. The last complete inspection remains visible and may be out of date.\"\n case \"source-stale\":\n return \"The connected service reported stale source data. Confirm current state before acting.\"\n }\n}\n\nconst EntityContent = ({\n clockifyActionCanApprove,\n clockifyActionCanCorrect,\n clockifyActionState,\n clockifyActionSubmit,\n onSessionExpired,\n presentation,\n retry,\n reviewCanEnqueue,\n reviewLoadEarlier,\n reviewPublication,\n reviewPublicationCancel,\n reviewPublicationPreview,\n reviewRetry,\n reviewStart,\n reviewState,\n reviewSuggestionPublish,\n reviewSuggestionRevisionTransport,\n sessionKey,\n stale\n}: {\n readonly clockifyActionCanApprove: boolean\n readonly clockifyActionCanCorrect: boolean\n readonly clockifyActionState: ClockifyActionSubmissionState\n readonly clockifyActionSubmit: (request: SubmitClockifyActionRequest) => void\n readonly onSessionExpired: (sessionKey: string) => void\n readonly presentation: WorkspaceEntityPresentation\n readonly reviewCanEnqueue: boolean\n readonly reviewPublication: PullRequestReviewPublicationState\n readonly reviewPublicationCancel: () => void\n readonly reviewLoadEarlier: () => void\n readonly reviewPublicationPreview: (selection: ReviewSuggestionPublicationTarget) => void\n readonly reviewRetry: () => void\n readonly reviewSuggestionRevisionTransport?: ReviewSuggestionRevisionTransport\n readonly reviewSuggestionPublish: (finalContent: string) => void\n readonly reviewStart: (prompt?: DurableAgentPrompt) => void\n readonly reviewState: PullRequestReviewControllerState\n readonly retry: () => void\n readonly sessionKey: string | null\n readonly stale: Extract<WorkspaceEntityState, { readonly _tag: \"stale\" }> | null\n}): ReactElement => (\n <div className={styles.content}>\n {stale === null ? null : (\n <StatePanel\n action={stale.reason === \"refreshing\" ? undefined : <Button onClick={retry}>Retry refresh</Button>}\n announce={stale.reason === \"refresh-failed\" ? \"polite\" : \"off\"}\n description={staleMessage(stale)}\n title={stale.reason === \"refreshing\" ? \"Refreshing source\" : \"Showing retained source data\"}\n tone=\"caution\"\n />\n )}\n {presentation.partialMessages.map((message) => (\n <StatePanel description={message} key={message} title=\"Partial canonical view\" tone=\"caution\" />\n ))}\n {presentation.clockifyTimeEntry === null ? null : (\n <WorkspaceClockifyTimeEntryDetails\n canApprove={clockifyActionCanApprove}\n canCorrect={clockifyActionCanCorrect}\n onSubmit={clockifyActionSubmit}\n submission={clockifyActionState}\n timeEntry={presentation.clockifyTimeEntry}\n />\n )}\n {presentation.issue === null ? null : <WorkspaceIssueDetails issue={presentation.issue} />}\n {presentation.confluencePage === null ? null : (\n <WorkspaceConfluencePageDetails page={presentation.confluencePage} />\n )}\n {presentation.pipelineExecution === null ? null : (\n <WorkspacePipelineExecutionDetails pipeline={presentation.pipelineExecution} />\n )}\n {presentation.pullRequest === null ? null : (\n <Suspense fallback={<Skeleton decorative={false} height=\"20rem\" label=\"Loading pull request\" variant=\"block\" />}>\n <WorkspacePullRequestDetails\n approvers={presentation.collaborators.approvers}\n onSessionExpired={onSessionExpired}\n onReviewLoadEarlier={reviewLoadEarlier}\n onReviewPublicationCancel={reviewPublicationCancel}\n onReviewPublicationPreview={reviewPublicationPreview}\n onReviewRetry={reviewRetry}\n onReviewSuggestionPublish={reviewSuggestionPublish}\n onReviewStart={reviewStart}\n pullRequest={presentation.pullRequest}\n reviewCanEnqueue={reviewCanEnqueue}\n reviewPublication={reviewPublication}\n {...(reviewSuggestionRevisionTransport === undefined ? {} : { reviewSuggestionRevisionTransport })}\n reviewState={reviewState}\n reviewers={presentation.collaborators.reviewers}\n sessionKey={sessionKey}\n />\n </Suspense>\n )}\n <DeliveryPath presentation={presentation} />\n </div>\n)\n\ninterface WorkspaceEntityViewProps {\n readonly clockifyActionCanApprove?: boolean\n readonly clockifyActionCanCorrect?: boolean\n readonly clockifyActionState?: ClockifyActionSubmissionState\n readonly clockifyActionSubmit?: (request: SubmitClockifyActionRequest) => void\n readonly onAskAgent: () => void\n readonly onSessionExpired?: (sessionKey: string) => void\n readonly originHref: string\n readonly originLabel: string\n readonly originState: WorkspaceEntityOrigin[\"state\"]\n readonly retry: () => void\n readonly reviewCanEnqueue?: boolean\n readonly reviewLoadEarlier?: () => void\n readonly reviewPublication?: PullRequestReviewPublicationState\n readonly reviewPublicationCancel?: () => void\n readonly reviewPublicationPreview?: (selection: ReviewSuggestionPublicationTarget) => void\n readonly reviewRetry?: () => void\n readonly reviewSuggestionRevisionTransport?: ReviewSuggestionRevisionTransport\n readonly reviewSuggestionPublish?: (finalContent: string) => void\n readonly reviewStart?: (prompt?: DurableAgentPrompt) => void\n readonly reviewState?: PullRequestReviewControllerState\n readonly state: WorkspaceEntityState\n readonly sessionKey?: string | null\n readonly workspaceId: WorkspaceIdType\n}\n\nconst ignoreSessionExpiration = (_sessionKey: string): void => undefined\nconst ignoreAction = (): void => undefined\n\n/** Pure state renderer for the canonical entity route. */\nexport const WorkspaceEntityView = ({\n clockifyActionCanApprove = false,\n clockifyActionCanCorrect = false,\n clockifyActionState = { _tag: \"idle\" },\n clockifyActionSubmit = ignoreAction,\n onAskAgent,\n onSessionExpired = ignoreSessionExpiration,\n originHref,\n originLabel: backLabel,\n originState,\n retry,\n reviewCanEnqueue = false,\n reviewLoadEarlier = ignoreAction,\n reviewPublication = { _tag: \"idle\" },\n reviewPublicationCancel = ignoreAction,\n reviewPublicationPreview = ignoreAction,\n reviewRetry = ignoreAction,\n reviewStart = ignoreAction,\n reviewState = { _tag: \"idle\" },\n reviewSuggestionPublish = ignoreAction,\n reviewSuggestionRevisionTransport,\n sessionKey = null,\n state,\n workspaceId\n}: WorkspaceEntityViewProps): ReactElement => {\n const focusRef = useRef<HTMLElement>(null)\n const visibleEntityId =\n state._tag === \"ready\" || state._tag === \"stale\" ? state.inspection.entity.projection.entityId : state._tag\n useEffect(() => focusRef.current?.focus(), [visibleEntityId])\n\n if (state._tag === \"idle\") {\n return (\n <RouteState\n action={\n <Link state={originState} to={originHref}>\n {backLabel}\n </Link>\n }\n description=\"A readable workspace session is required before this object can be loaded.\"\n title=\"Entity unavailable\"\n />\n )\n }\n if (state._tag === \"loading\") return <LoadingEntity />\n if (state._tag === \"not-found\") {\n return (\n <RouteState\n action={\n <Link state={originState} to={originHref}>\n {backLabel}\n </Link>\n }\n description=\"This object is not in this workspace. It may have been deleted, disconnected, or the address may be wrong.\"\n title=\"Object not found\"\n />\n )\n }\n if (state._tag === \"failed\") {\n return (\n <RouteState\n action={<Button onClick={retry}>Retry entity</Button>}\n description=\"The canonical object could not be loaded. Your current workspace location is preserved.\"\n title=\"Could not load object\"\n tone=\"critical\"\n />\n )\n }\n\n const presentation = presentWorkspaceEntity(workspaceId, state.inspection)\n const clockifyActionsCurrent =\n state._tag === \"ready\" && state.inspection.isSourceCurrent && state.inspection.sourceActionsAvailable\n return (\n <LinkProvider component={WorkspaceEntityLink}>\n <EntityShell\n actions={<PrincipalAction action={presentation.primaryAction} />}\n activity={<EntityActivity presentation={presentation} />}\n agentEntry={\n <AgentContextButton\n actionLabel=\"Ask about this object\"\n agentName=\"Relay\"\n context={presentation.agentContext}\n onClick={onAskAgent}\n />\n }\n collaborators={\n <EntityCollaborators key={state.inspection.entity.projection.entityId} presentation={presentation} />\n }\n className={styles.shell}\n content={\n <EntityContent\n clockifyActionCanApprove={clockifyActionsCurrent && clockifyActionCanApprove}\n clockifyActionCanCorrect={clockifyActionsCurrent && clockifyActionCanCorrect}\n clockifyActionState={clockifyActionState}\n clockifyActionSubmit={clockifyActionSubmit}\n onSessionExpired={onSessionExpired}\n presentation={presentation}\n reviewCanEnqueue={reviewCanEnqueue}\n reviewPublication={reviewPublication}\n reviewPublicationCancel={reviewPublicationCancel}\n reviewLoadEarlier={reviewLoadEarlier}\n reviewPublicationPreview={reviewPublicationPreview}\n reviewRetry={reviewRetry}\n {...(reviewSuggestionRevisionTransport === undefined ? {} : { reviewSuggestionRevisionTransport })}\n reviewSuggestionPublish={reviewSuggestionPublish}\n reviewStart={reviewStart}\n reviewState={reviewState}\n retry={retry}\n sessionKey={sessionKey}\n stale={state._tag === \"stale\" ? state : null}\n />\n }\n data-service={presentation.service}\n data-workspace-entity-id={state.inspection.entity.projection.entityId}\n evidence={<EntityEvidence presentation={presentation} />}\n facts={<EntityFacts presentation={presentation} />}\n freshness={presentation.freshness}\n freshnessDateTime={presentation.freshnessDateTime}\n freshnessTime={presentation.freshnessTime}\n navigation={\n <Link className={styles.back} state={originState} to={originHref}>\n {backLabel}\n </Link>\n }\n reason={`${presentation.displayKey} is ${presentation.verdict.toLocaleLowerCase(\"en-US\")} in ${presentation.serviceName}.`}\n ref={focusRef}\n relationships={<EntityRelationships presentation={presentation} />}\n service={presentation.service}\n tabIndex={-1}\n title={presentation.title}\n tone={presentation.tone}\n verdict={presentation.verdict}\n />\n </LinkProvider>\n )\n}\n\nconst ConnectedWorkspaceEntity = ({\n entityId,\n workspaceId\n}: {\n readonly entityId: EntityIdType\n readonly workspaceId: WorkspaceIdType\n}): ReactElement => {\n const context = useOutletContext<WorkspaceReleaseOutletContext>()\n const browserSession = useBrowserSession()\n const location = useLocation()\n const navigate = useNavigate()\n const refreshKey =\n context.controller.state._tag === \"ready\" ? context.controller.state.portfolio.generatedAt : \"pending\"\n const sessionKey = browserReadableSessionKey(browserSession.state)\n const controller = useWorkspaceEntity(workspaceId, entityId, refreshKey, sessionKey, browserSession.invalidateSession)\n const clockifyActions = useClockifyActionSubmission(\n entityId,\n sessionKey,\n browserSession.invalidateSession,\n controller.retry\n )\n const reviewCanEnqueue =\n browserSession.state._tag === \"authenticated\" && browserSession.state.session.permission === \"workspace-owner\"\n const reviewSubject =\n (controller.state._tag === \"ready\" || controller.state._tag === \"stale\") &&\n controller.state.inspection.entity.projection.details._tag === \"pull-request\"\n ? {\n baseRevision: controller.state.inspection.entity.projection.details.baseRevision ?? null,\n headRevision: controller.state.inspection.entity.projection.details.headRevision\n }\n : null\n const reviewController = usePullRequestReview(\n entityId,\n reviewSubject?.baseRevision ?? null,\n reviewSubject?.headRevision ?? null,\n sessionKey,\n reviewCanEnqueue,\n browserSession.invalidateSession\n )\n const resolvedOrigin = resolveWorkspaceEntityOrigin(location.state, workspaceId, entityId)\n const resolvedOriginHref = workspaceEntityOriginHref(resolvedOrigin.origin)\n const releaseContext =\n controller.state._tag === \"ready\" || controller.state._tag === \"stale\"\n ? controller.state.inspection.entity\n : { canonicalReleaseId: null, releaseIds: [], releaseMembershipsTruncated: false }\n const routableReleaseIds = new Set(\n context.controller.state._tag === \"ready\" ? context.controller.state.portfolio.releases.map(({ id }) => id) : []\n )\n const agentPath = workspaceEntityAgentPath(\n resolvedOrigin.origin,\n workspaceId,\n location,\n releaseContext,\n routableReleaseIds\n )\n return (\n <WorkspaceEntityView\n clockifyActionCanApprove={\n browserSession.state._tag === \"authenticated\" &&\n (browserSession.state.session.permission === \"workspace-owner\" ||\n browserSession.state.session.permission === \"workspace-approver\")\n }\n clockifyActionCanCorrect={\n browserSession.state._tag === \"authenticated\" && browserSession.state.session.permission === \"workspace-owner\"\n }\n clockifyActionState={clockifyActions.state}\n clockifyActionSubmit={clockifyActions.submit}\n onAskAgent={() => navigate(agentPath, { state: location.state })}\n onSessionExpired={browserSession.invalidateSession}\n originHref={resolvedOriginHref}\n originLabel={originLabel(resolvedOriginHref, workspaceId)}\n originState={resolvedOrigin.origin.state}\n retry={controller.retry}\n reviewCanEnqueue={reviewCanEnqueue}\n reviewPublication={reviewController.publication}\n reviewPublicationCancel={reviewController.cancelPublication}\n reviewLoadEarlier={reviewController.loadEarlier}\n reviewPublicationPreview={reviewController.previewPublication}\n reviewRetry={reviewController.retry}\n reviewSuggestionPublish={reviewController.publishSuggestion}\n reviewStart={reviewController.start}\n reviewState={reviewController.state}\n state={controller.state}\n sessionKey={sessionKey}\n workspaceId={workspaceId}\n />\n )\n}\n\n/** Load and render one exact normalized object at its canonical full-page route. */\nexport const WorkspaceEntityRoute = (): ReactElement => {\n const context = useOutletContext<WorkspaceReleaseOutletContext>()\n const params = useParams()\n const entityId = decodeEntityRouteId(params.entityId)\n return entityId === null ? (\n <RouteState\n action={<Link to={workspaceEntityParentPath(context.workspaceId)}>Back to items</Link>}\n description=\"The object address is not a canonical entity identifier.\"\n title=\"Object not found\"\n />\n ) : (\n <ConnectedWorkspaceEntity entityId={entityId} workspaceId={context.workspaceId} />\n )\n}\n"],"file":"WorkspaceEntityRoute-Bxxnc8us.js"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{n as e}from"./lib-BzlsKFNV.js";import{t}from"./jsx-runtime-By8HlURe.js";import{t as n}from"./useWorkspaceDefaultLanding-CzlDdEF-.js";var r=t(),i=({children:t,className:i,fallbackPath:a,workspaceId:o})=>(0,r.jsx)(e,{className:i,to:n(o)??a,children:t});export{i as WorkspaceHomeLink};
|
|
2
|
-
//# sourceMappingURL=WorkspaceHomeLink-XbKSPths.js.map
|