@straiffi/archon 1.8.6 → 1.8.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/dist/client/assets/ActivityView-D4Qh96zr.js +1 -0
  2. package/dist/client/assets/GitHubActionsDialog-Bg03OmVv.js +1 -0
  3. package/dist/client/assets/RepositoryGraphDialog-CS_hOqPw.js +1 -0
  4. package/dist/client/assets/VerificationDialog-BYH-Ek8n.js +4 -0
  5. package/dist/client/assets/{arc-D2Nn9xIj.js → arc-C83vRtlz.js} +1 -1
  6. package/dist/client/assets/architecture-7EHR7CIX-Dm8H7N6Z.js +1 -0
  7. package/dist/client/assets/{architectureDiagram-3BPJPVTR-BH5LLK54.js → architectureDiagram-3BPJPVTR-2lxabjSl.js} +1 -1
  8. package/dist/client/assets/{blockDiagram-GPEHLZMM-xOxShPwZ.js → blockDiagram-GPEHLZMM-C80HvJmb.js} +1 -1
  9. package/dist/client/assets/{c4Diagram-AAUBKEIU-BXMrXnKR.js → c4Diagram-AAUBKEIU-BM3k_lKz.js} +1 -1
  10. package/dist/client/assets/channel-HjENOCZ0.js +1 -0
  11. package/dist/client/assets/{chunk-2J33WTMH-BdDEtNMz.js → chunk-2J33WTMH-BTk3lX07.js} +1 -1
  12. package/dist/client/assets/{chunk-3OPIFGDE-PtSkTtIU.js → chunk-3OPIFGDE-DAxdBZ_4.js} +1 -1
  13. package/dist/client/assets/{chunk-4BX2VUAB-CtLS8D71.js → chunk-4BX2VUAB-C5pU9ApX.js} +1 -1
  14. package/dist/client/assets/{chunk-4EGX6M5U-Btnm0QNe.js → chunk-4EGX6M5U-CAjWPjND.js} +1 -1
  15. package/dist/client/assets/{chunk-55IACEB6-74CcJaub.js → chunk-55IACEB6-DhO4-AG4.js} +1 -1
  16. package/dist/client/assets/{chunk-5DO6E6H7-WLZ8L4ko.js → chunk-5DO6E6H7-BDKA-zHS.js} +1 -1
  17. package/dist/client/assets/{chunk-5ZQYHXKU-D5PYP24m.js → chunk-5ZQYHXKU-BYm9s62a.js} +1 -1
  18. package/dist/client/assets/{chunk-727SXJPM-gDX0xZh1.js → chunk-727SXJPM-iVUM8xuV.js} +1 -1
  19. package/dist/client/assets/{chunk-AQP2D5EJ-Bat82lQQ.js → chunk-AQP2D5EJ-DVM7riMJ.js} +1 -1
  20. package/dist/client/assets/{chunk-BR22UD5L-Cou5beGe.js → chunk-BR22UD5L-12D2GWh4.js} +1 -1
  21. package/dist/client/assets/{chunk-BSJP7CBP-DJ57XcV5.js → chunk-BSJP7CBP-DMi77e84.js} +1 -1
  22. package/dist/client/assets/{chunk-CSCIHK7Q-D3sau006.js → chunk-CSCIHK7Q-_D1FzP9B.js} +2 -2
  23. package/dist/client/assets/{chunk-FHYWG6QK-Ba10e2kj.js → chunk-FHYWG6QK-BhSajKiB.js} +1 -1
  24. package/dist/client/assets/{chunk-FMBD7UC4-CEo2wZMx.js → chunk-FMBD7UC4-Drmlc0wM.js} +1 -1
  25. package/dist/client/assets/{chunk-KSCS5N6A-CqEcB7Dr.js → chunk-KSCS5N6A-D3XouAHf.js} +1 -1
  26. package/dist/client/assets/{chunk-L5ZTLDWV-TRTuwXsF.js → chunk-L5ZTLDWV-B7NYWgT4.js} +1 -1
  27. package/dist/client/assets/{chunk-LZXEDZCA-DdpNmv37.js → chunk-LZXEDZCA-Dgkkbb6A.js} +2 -2
  28. package/dist/client/assets/{chunk-MPE355IW-MqEt-J8G.js → chunk-MPE355IW-Cw8YmjTC.js} +1 -1
  29. package/dist/client/assets/{chunk-MZUSXYTE-DdNi9lhx.js → chunk-MZUSXYTE-jvxRCZ7x.js} +1 -1
  30. package/dist/client/assets/{chunk-N66VUXT2-CjemTW4E.js → chunk-N66VUXT2-00i4y0yD.js} +1 -1
  31. package/dist/client/assets/{chunk-ND2GUHAM-BCUL9zWr.js → chunk-ND2GUHAM-CzO1oVCi.js} +1 -1
  32. package/dist/client/assets/{chunk-NZK2D7GU-BAxuwE_2.js → chunk-NZK2D7GU-re0VVZne.js} +1 -1
  33. package/dist/client/assets/{chunk-O5CBEL6O-Cttpc9yf.js → chunk-O5CBEL6O-BwsS59iy.js} +1 -1
  34. package/dist/client/assets/{chunk-PUPMXCY4-ZvwTw0To.js → chunk-PUPMXCY4-DfWourL7.js} +1 -1
  35. package/dist/client/assets/chunk-QZHKN3VN-CtbsU1Bj.js +1 -0
  36. package/dist/client/assets/{chunk-UIBZB4QT-BTY9be9s.js → chunk-UIBZB4QT-v-a5ZfN6.js} +1 -1
  37. package/dist/client/assets/{chunk-WCWK7LTN-Db1n3n3-.js → chunk-WCWK7LTN-CtYzhvvb.js} +1 -1
  38. package/dist/client/assets/chunk-WU5MYG2G-CLyh-xCA.js +1 -0
  39. package/dist/client/assets/{chunk-XPW4576I-DObFPxjB.js → chunk-XPW4576I-CvnAuXH2.js} +1 -1
  40. package/dist/client/assets/classDiagram-4FO5ZUOK-DnhdaVrK.js +1 -0
  41. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-C-BjeSGJ.js +1 -0
  42. package/dist/client/assets/{cose-bilkent-S5V4N54A-MlOPiG6P.js → cose-bilkent-S5V4N54A-fchD-dH2.js} +1 -1
  43. package/dist/client/assets/{dagre-BM42HDAG-BTsZ2dQI.js → dagre-BM42HDAG-x71fYlqQ.js} +1 -1
  44. package/dist/client/assets/{dagre-BWNHuDdf.js → dagre-DSrzm-Gq.js} +1 -1
  45. package/dist/client/assets/{diagram-2AECGRRQ-afPu4kp4.js → diagram-2AECGRRQ-CMdwzuYj.js} +1 -1
  46. package/dist/client/assets/{diagram-5GNKFQAL-SixbJGPN.js → diagram-5GNKFQAL-B3l6I4qJ.js} +1 -1
  47. package/dist/client/assets/{diagram-KO2AKTUF-Dk1670ag.js → diagram-KO2AKTUF-BNhypLBW.js} +1 -1
  48. package/dist/client/assets/{diagram-LMA3HP47-BDNhjRaO.js → diagram-LMA3HP47-CmrhbiDt.js} +1 -1
  49. package/dist/client/assets/{diagram-OG6HWLK6-BLowQCLY.js → diagram-OG6HWLK6-CRobDMLl.js} +1 -1
  50. package/dist/client/assets/{erDiagram-TEJ5UH35-DAg9kUbm.js → erDiagram-TEJ5UH35-CqO7K0TS.js} +1 -1
  51. package/dist/client/assets/eventmodeling-FCH6USID-BWhw0UJ8.js +1 -0
  52. package/dist/client/assets/{flowDiagram-I6XJVG4X-BsaPmiIS.js → flowDiagram-I6XJVG4X-CuLTJZU0.js} +1 -1
  53. package/dist/client/assets/{ganttDiagram-6RSMTGT7-DfF1TT-s.js → ganttDiagram-6RSMTGT7-Bm7v1eRG.js} +1 -1
  54. package/dist/client/assets/gitGraph-WXDBUCRP-BSnxAa1J.js +1 -0
  55. package/dist/client/assets/{gitGraphDiagram-PVQCEYII-CEvTiN6n.js → gitGraphDiagram-PVQCEYII-CNHZr-5i.js} +1 -1
  56. package/dist/client/assets/index-Bs5SQZhz.css +2 -0
  57. package/dist/client/assets/index-LGNsdNYM.js +274 -0
  58. package/dist/client/assets/info-J43DQDTF-DcFwF1-h.js +1 -0
  59. package/dist/client/assets/{infoDiagram-5YYISTIA-CBjYYrzJ.js → infoDiagram-5YYISTIA-z27pUr2X.js} +1 -1
  60. package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-BuCkp1uL.js → ishikawaDiagram-YF4QCWOH-CDocZ0jf.js} +1 -1
  61. package/dist/client/assets/{journeyDiagram-JHISSGLW-DkUPCxT5.js → journeyDiagram-JHISSGLW-CgP31lsU.js} +1 -1
  62. package/dist/client/assets/{kanban-definition-UN3LZRKU-CXwNZ0Fa.js → kanban-definition-UN3LZRKU-DxTm1_fc.js} +1 -1
  63. package/dist/client/assets/{line-CRTZgJXA.js → line-hrZ7m44_.js} +1 -1
  64. package/dist/client/assets/{linear-DT4rSZvy.js → linear-BOwW57yX.js} +1 -1
  65. package/dist/client/assets/{mermaid-parser.core-NTByLn30.js → mermaid-parser.core-BThJAIK-.js} +2 -2
  66. package/dist/client/assets/{mermaid.core-DszsB_Gl.js → mermaid.core-CfVyP_kK.js} +3 -3
  67. package/dist/client/assets/{mindmap-definition-RKZ34NQL-DCrqCcPX.js → mindmap-definition-RKZ34NQL-CuISnLgW.js} +1 -1
  68. package/dist/client/assets/{ordinal-k--hYEme.js → ordinal-CZ33lFpK.js} +1 -1
  69. package/dist/client/assets/packet-YPE3B663-1VZiO_9r.js +1 -0
  70. package/dist/client/assets/pie-LRSECV5Y-BX1-tQCu.js +1 -0
  71. package/dist/client/assets/{pieDiagram-4H26LBE5-CbHeTKto.js → pieDiagram-4H26LBE5-DnWAdd44.js} +1 -1
  72. package/dist/client/assets/{quadrantDiagram-W4KKPZXB-Ptpkh0Dc.js → quadrantDiagram-W4KKPZXB-Cb-RVl5A.js} +1 -1
  73. package/dist/client/assets/radar-GUYGQ44K-B2HRrCR4.js +1 -0
  74. package/dist/client/assets/{requirementDiagram-4Y6WPE33-73PM-Ae5.js → requirementDiagram-4Y6WPE33-DrXg_gCS.js} +1 -1
  75. package/dist/client/assets/{sankeyDiagram-5OEKKPKP-B7RCxzNy.js → sankeyDiagram-5OEKKPKP-DzZjp_ZP.js} +1 -1
  76. package/dist/client/assets/{sequenceDiagram-3UESZ5HK-DGXfHCo0.js → sequenceDiagram-3UESZ5HK-CQJ3PhQD.js} +1 -1
  77. package/dist/client/assets/{stateDiagram-AJRCARHV-Cl0_SVL3.js → stateDiagram-AJRCARHV-B16j9pg1.js} +1 -1
  78. package/dist/client/assets/stateDiagram-v2-BHNVJYJU-vNiFfHwm.js +1 -0
  79. package/dist/client/assets/{timeline-definition-PNZ67QCA-Cufq-wYg.js → timeline-definition-PNZ67QCA-bUG3mZQt.js} +1 -1
  80. package/dist/client/assets/treeView-BLDUP644-CDfUVbUi.js +1 -0
  81. package/dist/client/assets/treemap-LRROVOQU-DUWqu8sK.js +1 -0
  82. package/dist/client/assets/{vennDiagram-CIIHVFJN-ROVZhhP-.js → vennDiagram-CIIHVFJN-DALCJcZD.js} +1 -1
  83. package/dist/client/assets/wardley-L42UT6IY-BEFuPUCy.js +1 -0
  84. package/dist/client/assets/{wardleyDiagram-YWT4CUSO-DlHRfLPH.js → wardleyDiagram-YWT4CUSO-DPQd3l9A.js} +1 -1
  85. package/dist/client/assets/{xychartDiagram-2RQKCTM6-DW-KpRbf.js → xychartDiagram-2RQKCTM6-BIv1FqXG.js} +1 -1
  86. package/dist/client/index.html +2 -2
  87. package/dist/server/db.js +399 -0
  88. package/dist/server/db.js.map +1 -1
  89. package/dist/server/index.js +65 -10
  90. package/dist/server/index.js.map +1 -1
  91. package/dist/server/lib/agent.js +9 -6
  92. package/dist/server/lib/agent.js.map +1 -1
  93. package/dist/server/lib/checkWorkspaceIdentity.js +2 -206
  94. package/dist/server/lib/checkWorkspaceIdentity.js.map +1 -1
  95. package/dist/server/lib/executionReconciliation.js +73 -0
  96. package/dist/server/lib/executionReconciliation.js.map +1 -1
  97. package/dist/server/lib/integrations/github.js +10 -1
  98. package/dist/server/lib/integrations/github.js.map +1 -1
  99. package/dist/server/lib/postBuildChecks.js +20 -12
  100. package/dist/server/lib/postBuildChecks.js.map +1 -1
  101. package/dist/server/lib/repositoryGraphAnalyzer.js +392 -0
  102. package/dist/server/lib/repositoryGraphAnalyzer.js.map +1 -0
  103. package/dist/server/lib/repositoryGraphGitHistory.js +371 -0
  104. package/dist/server/lib/repositoryGraphGitHistory.js.map +1 -0
  105. package/dist/server/lib/repositoryGraphIdentity.js +134 -0
  106. package/dist/server/lib/repositoryGraphIdentity.js.map +1 -0
  107. package/dist/server/lib/repositoryGraphManifest.js +386 -0
  108. package/dist/server/lib/repositoryGraphManifest.js.map +1 -0
  109. package/dist/server/lib/repositoryGraphQueries.js +370 -0
  110. package/dist/server/lib/repositoryGraphQueries.js.map +1 -0
  111. package/dist/server/lib/repositoryGraphRetention.js +104 -0
  112. package/dist/server/lib/repositoryGraphRetention.js.map +1 -0
  113. package/dist/server/lib/repositoryGraphRoutes.js +145 -0
  114. package/dist/server/lib/repositoryGraphRoutes.js.map +1 -0
  115. package/dist/server/lib/repositoryGraphScan.js +370 -0
  116. package/dist/server/lib/repositoryGraphScan.js.map +1 -0
  117. package/dist/server/lib/repositoryGraphStore.js +352 -0
  118. package/dist/server/lib/repositoryGraphStore.js.map +1 -0
  119. package/dist/server/lib/repositoryGraphTargets.js +30 -0
  120. package/dist/server/lib/repositoryGraphTargets.js.map +1 -0
  121. package/dist/server/lib/repositoryGraphTypeScript.js +288 -0
  122. package/dist/server/lib/repositoryGraphTypeScript.js.map +1 -0
  123. package/dist/server/lib/terminal.js +25 -1
  124. package/dist/server/lib/terminal.js.map +1 -1
  125. package/dist/server/lib/types.js +1 -0
  126. package/dist/server/lib/types.js.map +1 -1
  127. package/dist/server/lib/workspaceIdentity.js +433 -0
  128. package/dist/server/lib/workspaceIdentity.js.map +1 -0
  129. package/dist/server/workers/plan.js +9 -7
  130. package/dist/server/workers/plan.js.map +1 -1
  131. package/dist/server/workers/repositoryGraphAnalyzer.js +282 -0
  132. package/dist/server/workers/repositoryGraphAnalyzer.js.map +1 -0
  133. package/package.json +2 -1
  134. package/dist/client/assets/ActivityView-DDeEQgbm.js +0 -1
  135. package/dist/client/assets/GitHubActionsDialog-DH-B_LR3.js +0 -1
  136. package/dist/client/assets/VerificationDialog-x43F7tbo.js +0 -4
  137. package/dist/client/assets/architecture-7EHR7CIX-C-4Cp4ml.js +0 -1
  138. package/dist/client/assets/channel-C0dk5Jiy.js +0 -1
  139. package/dist/client/assets/chunk-QZHKN3VN-LI_RZca2.js +0 -1
  140. package/dist/client/assets/chunk-WU5MYG2G-620NtSlY.js +0 -1
  141. package/dist/client/assets/classDiagram-4FO5ZUOK-C5ptkk7I.js +0 -1
  142. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-BFuXUVOx.js +0 -1
  143. package/dist/client/assets/eventmodeling-FCH6USID-Dqb6QKoI.js +0 -1
  144. package/dist/client/assets/gitGraph-WXDBUCRP-DYEsqh93.js +0 -1
  145. package/dist/client/assets/index-B5TSPCJr.css +0 -2
  146. package/dist/client/assets/index-DV0vl670.js +0 -274
  147. package/dist/client/assets/info-J43DQDTF-CfjXFZai.js +0 -1
  148. package/dist/client/assets/packet-YPE3B663-Dv0HkRHU.js +0 -1
  149. package/dist/client/assets/pie-LRSECV5Y-S5zPzZFN.js +0 -1
  150. package/dist/client/assets/radar-GUYGQ44K-B7psLv22.js +0 -1
  151. package/dist/client/assets/stateDiagram-v2-BHNVJYJU-CqzC1yAT.js +0 -1
  152. package/dist/client/assets/treeView-BLDUP644-B8H0kT67.js +0 -1
  153. package/dist/client/assets/treemap-LRROVOQU-DPLhFHnh.js +0 -1
  154. package/dist/client/assets/wardley-L42UT6IY-B5-Vb08V.js +0 -1
  155. /package/dist/client/assets/{array-BNor45A1.js → array-B2f2amhX.js} +0 -0
  156. /package/dist/client/assets/{chunk-NNHCCRGN-CZB-V-Gv.js → chunk-NNHCCRGN-DgKrp8T-.js} +0 -0
  157. /package/dist/client/assets/{cytoscape.esm-B2lJcMSI.js → cytoscape.esm-BInZCgaJ.js} +0 -0
  158. /package/dist/client/assets/{defaultLocale-DPzUsThw.js → defaultLocale-sPXJ5urm.js} +0 -0
  159. /package/dist/client/assets/{dist-CERhmQhR.js → dist-DfHDMDTt.js} +0 -0
  160. /package/dist/client/assets/{graphlib-BHOW-eWz.js → graphlib-DacNv4Jd.js} +0 -0
  161. /package/dist/client/assets/{init-C0L3woqb.js → init-BVCnG1lj.js} +0 -0
  162. /package/dist/client/assets/{katex-CpjQsUQe.js → katex-BlkrXOwm.js} +0 -0
  163. /package/dist/client/assets/{path-sMK4d_s9.js → path-Bw5AvBNC.js} +0 -0
  164. /package/dist/client/assets/{rough.esm-BoTisKeL.js → rough.esm-DeLgKbOI.js} +0 -0
  165. /package/dist/client/assets/{src-BRjoYtUW.js → src-CFGsdLiG.js} +0 -0
@@ -8,6 +8,8 @@ import { createHash, randomUUID } from 'crypto';
8
8
  import cors from 'cors';
9
9
  import { adjectives, animals, uniqueNamesGenerator } from 'unique-names-generator';
10
10
  import db from './db.js';
11
+ import { pruneAllRepositoryGraphScans } from './lib/repositoryGraphRetention.js';
12
+ import { registerRepositoryGraphRoutes } from './lib/repositoryGraphRoutes.js';
11
13
  import { deleteChatSession, getChatSession, listChatSessions } from './lib/chats.js';
12
14
  import { deleteSpecSession, getCreatedTicketIdsForSnapshot, getSpecSession, getSpecSnapshot, listSpecSessions } from './lib/specs.js';
13
15
  import { createChatAttachment, createSpecAttachment, getAttachmentById, deleteChatAttachment, deleteProjectAttachments, deleteSpecSessionAttachment, getChatAttachmentForSession, getChatAttachmentLinkedMessageId, getSpecAttachmentForSession, getSpecAttachmentLinkedMessageId, MAX_CHAT_ATTACHMENTS_PER_TURN, MAX_CHAT_ATTACHMENT_SIZE_BYTES, MAX_SPEC_ATTACHMENTS_PER_TURN, MAX_SPEC_ATTACHMENT_SIZE_BYTES, readChatAttachmentContent, readSpecAttachmentContent, validateImageAttachment, } from './lib/attachments.js';
@@ -70,7 +72,7 @@ import { ExecutionArtifactCleanupError, reconcileExecutionArtifactRegistrationIn
70
72
  import { closeHttpServer, shutdownRealtimeServer } from './lib/shutdown.js';
71
73
  import { resolveClientBuildPaths, shouldServeClientApp, STATIC_CLIENT_DIRECTORY_OPTIONS, STATIC_CLIENT_INDEX_OPTIONS, } from './lib/staticClient.js';
72
74
  import { deleteIntegrationConnection, getGitHubConnectionConfig, getJiraConnectionConfig, listIntegrationConnections, upsertIntegrationConnection, } from './lib/integrations/index.js';
73
- import { createGitHubPullRequest, createOrFindGitHubPullRequest, findOpenGitHubPullRequest, findOpenGitHubPullRequestByHeadBranch, getGitHubPullRequestComments, getGitHubPullRequestReviews, getGitHubPullRequest, GitHubApiError, hasGitHubRemoteBranch, resolveGitHubRepository, validateGitHubConnection, } from './lib/integrations/github.js';
75
+ import { createGitHubPullRequest, createOrFindGitHubPullRequest, findOpenGitHubPullRequest, findOpenGitHubPullRequestByHeadBranch, getGitHubPullRequestComments, getGitHubPullRequestReviews, getGitHubPullRequest, GitHubApiError, hasGitHubRemoteBranch, hasGitHubRemoteBranchAsync, resolveGitHubRepository, validateGitHubConnection, } from './lib/integrations/github.js';
74
76
  import { importJiraIssue, JiraApiError, prepareJiraIssueImport, validateJiraConnection } from './lib/integrations/jira.js';
75
77
  import { importGitHubIssue, prepareGitHubIssueImport } from './lib/integrations/github-issues.js';
76
78
  import { buildImportedIssueSessionTitle, importProviderHostedIssueImages } from './lib/integrations/importedIssueImages.js';
@@ -91,6 +93,7 @@ import { getCheckAttemptDiagnosticResponse, getCheckBatchDiagnosticResponse } fr
91
93
  import { getCheckDefinitionFingerprint } from './lib/checkDefinitions.js';
92
94
  import { getCheckGateEvaluation, hydrateCheckGatePresentApplicability } from './lib/checkGateEvaluations.js';
93
95
  import { captureCheckWorkspaceIdentity } from './lib/checkWorkspaceIdentity.js';
96
+ import { hasActiveBundleRepositoryGraphScan, hasActiveProjectRepositoryGraphScan } from './lib/repositoryGraphStore.js';
94
97
  import { resolveEffectiveRequiredCheckPolicyMembership, resolveRequiredCheckPolicy } from './lib/requiredCheckPolicy.js';
95
98
  import { getBundleBuildBlockerResponse, shouldStartBundleBuildNow, transitionTicketState, } from './lib/ticketWorkflowOperations.js';
96
99
  import { submitPlanTicketFollowUp, submitTicketFollowUp, } from './lib/ticketFollowUpOperations.js';
@@ -1475,9 +1478,6 @@ const shouldDiscoverBundlePullRequestOnOpen = (project, bundle) => {
1475
1478
  if (tickets.some(ticket => ticket.agent_status === 'running')) {
1476
1479
  return false;
1477
1480
  }
1478
- if (!hasGitHubRemoteBranch(project.repo_path, bundle.branch)) {
1479
- return false;
1480
- }
1481
1481
  const key = getBundlePullRequestDiscoveryKey(project.id, bundle.id);
1482
1482
  if (bundlePullRequestDiscoveryInFlight.has(key)) {
1483
1483
  return false;
@@ -1491,6 +1491,9 @@ const startBundlePullRequestDiscoveryIfNeeded = (project, bundle) => {
1491
1491
  const key = getBundlePullRequestDiscoveryKey(project.id, bundle.id);
1492
1492
  const task = (async () => {
1493
1493
  try {
1494
+ if (!await hasGitHubRemoteBranchAsync(project.repo_path, bundle.branch)) {
1495
+ return;
1496
+ }
1494
1497
  const discoveredPullRequest = await discoverOpenBundlePullRequest(project, bundle);
1495
1498
  if (!discoveredPullRequest) {
1496
1499
  bundlePullRequestDiscoveryMissTimestamps.set(key, Date.now());
@@ -1498,7 +1501,7 @@ const startBundlePullRequestDiscoveryIfNeeded = (project, bundle) => {
1498
1501
  }
1499
1502
  bundlePullRequestDiscoveryMissTimestamps.delete(key);
1500
1503
  bundlePullRequestDiscoveryErrorTimestamps.delete(key);
1501
- reconcileBundleTicketsAfterPullRequestSync(project.id, bundle.id);
1504
+ emitBundlePullRequestUpdated(project.id, bundle.id);
1502
1505
  }
1503
1506
  catch (error) {
1504
1507
  bundlePullRequestDiscoveryErrorTimestamps.set(key, Date.now());
@@ -1587,9 +1590,10 @@ const startTrackedBundlePullRequestSyncIfNeeded = (project, bundle, options = {}
1587
1590
  const key = getBundlePullRequestDiscoveryKey(project.id, bundle.id);
1588
1591
  const task = (async () => {
1589
1592
  try {
1590
- await syncTrackedBundlePullRequestIfNeeded(project, bundle, { ...options, rethrow: true });
1593
+ const nextPullRequest = await syncTrackedBundlePullRequestIfNeeded(project, bundle, { ...options, rethrow: true });
1591
1594
  bundlePullRequestSyncErrorTimestamps.delete(key);
1592
- reconcileBundleTicketsAfterPullRequestSync(project.id, bundle.id);
1595
+ emitBundlePullRequestUpdated(project.id, bundle.id);
1596
+ scheduleBundleTicketReconciliationIfTerminal(project.id, bundle.id, nextPullRequest?.state ?? null);
1593
1597
  }
1594
1598
  catch (error) {
1595
1599
  bundlePullRequestSyncErrorTimestamps.set(key, Date.now());
@@ -1666,6 +1670,26 @@ const reconcileBundleTicketsAfterPullRequestSync = (projectId, bundleId) => {
1666
1670
  }
1667
1671
  }
1668
1672
  };
1673
+ const emitBundlePullRequestUpdated = (projectId, bundleId) => {
1674
+ io.emit('bundle-pull-request:updated', {
1675
+ project_id: projectId,
1676
+ bundle_id: bundleId,
1677
+ pull_request: serializeBundlePullRequest(getBundlePullRequestRecord(bundleId, projectId)),
1678
+ });
1679
+ };
1680
+ const scheduleBundleTicketReconciliationIfTerminal = (projectId, bundleId, nextState) => {
1681
+ if (nextState !== 'merged' && nextState !== 'closed') {
1682
+ return;
1683
+ }
1684
+ setImmediate(() => {
1685
+ try {
1686
+ reconcileBundleTicketsAfterPullRequestSync(projectId, bundleId);
1687
+ }
1688
+ catch (error) {
1689
+ console.warn(`[integrations] github pr ticket reconciliation failed project=${projectId} bundle=${bundleId}`, error);
1690
+ }
1691
+ });
1692
+ };
1669
1693
  const syncProjectBundlePullRequestsIfNeeded = async (project, bundles, options = {}) => {
1670
1694
  let startedCount = 0;
1671
1695
  for (const bundle of bundles) {
@@ -2426,6 +2450,7 @@ const emitRunStateForContext = (ticket, isRunningValue) => {
2426
2450
  }
2427
2451
  };
2428
2452
  app.use(express.json({ limit: '5mb' }));
2453
+ registerRepositoryGraphRoutes(app, { emitter: io });
2429
2454
  const requireDesktopMobileAccessRequest = (req, res) => {
2430
2455
  const rejectionReason = validateDesktopMobileAccessRequest(req);
2431
2456
  if (!rejectionReason) {
@@ -3641,6 +3666,7 @@ app.post('/bundles/:id/pull-request', async (req, res) => {
3641
3666
  headBranch: bundle.branch,
3642
3667
  });
3643
3668
  upsertBundlePullRequestFromGitHub(result.project.id, bundle.id, githubConfig, nextPullRequest);
3669
+ emitBundlePullRequestUpdated(result.project.id, bundle.id);
3644
3670
  return res.json(serializeBundleDetails(result.project, bundle));
3645
3671
  }
3646
3672
  catch (error) {
@@ -3668,7 +3694,7 @@ app.post('/bundles/:id/pull-request/sync', async (req, res) => {
3668
3694
  if (!trackedPullRequest) {
3669
3695
  try {
3670
3696
  trackedPullRequest = await discoverOpenBundlePullRequest(result.project, bundle);
3671
- reconcileBundleTicketsAfterPullRequestSync(result.project.id, bundle.id);
3697
+ emitBundlePullRequestUpdated(result.project.id, bundle.id);
3672
3698
  return res.json(serializeBundleDetails(result.project, bundle));
3673
3699
  }
3674
3700
  catch (error) {
@@ -3681,8 +3707,9 @@ app.post('/bundles/:id/pull-request/sync', async (req, res) => {
3681
3707
  }
3682
3708
  try {
3683
3709
  const nextPullRequest = await getGitHubPullRequest(githubConfig, trackedPullRequest.number);
3684
- upsertBundlePullRequestFromGitHub(result.project.id, bundle.id, githubConfig, nextPullRequest);
3685
- reconcileBundleTicketsAfterPullRequestSync(result.project.id, bundle.id);
3710
+ const nextRecord = upsertBundlePullRequestFromGitHub(result.project.id, bundle.id, githubConfig, nextPullRequest);
3711
+ emitBundlePullRequestUpdated(result.project.id, bundle.id);
3712
+ scheduleBundleTicketReconciliationIfTerminal(result.project.id, bundle.id, nextRecord?.state ?? null);
3686
3713
  console.info(`[integrations] github pr sync completed project=${result.project.id} bundle=${bundle.id} pr=${trackedPullRequest.number}`);
3687
3714
  return res.json(serializeBundleDetails(result.project, bundle));
3688
3715
  }
@@ -3825,6 +3852,9 @@ app.delete('/bundles/:id', (req, res) => {
3825
3852
  if (hasActiveBundleSpecWork(result.project.id, bundle.id)) {
3826
3853
  return res.status(409).json({ error: 'Cannot delete a bundle while Spec work is active' });
3827
3854
  }
3855
+ if (hasActiveBundleRepositoryGraphScan(result.project.id, bundle.id)) {
3856
+ return res.status(409).json({ error: 'Cannot delete a bundle while a repository graph scan is active' });
3857
+ }
3828
3858
  if (countBundleTickets(bundle.id, result.project.id) > 0) {
3829
3859
  return res.status(409).json({ error: 'Cannot delete a bundle that is still used by tickets' });
3830
3860
  }
@@ -7248,6 +7278,9 @@ const assertProjectDeletionEligible = (projectId, claimId) => {
7248
7278
  if (hasActiveProjectCheckBatch(projectId)) {
7249
7279
  throw new ProjectDeletionError(409, 'Cannot delete a project while checks are active');
7250
7280
  }
7281
+ if (!claimId && hasActiveProjectRepositoryGraphScan(projectId)) {
7282
+ throw new ProjectDeletionError(409, 'Cannot delete a project while a repository graph scan is active');
7283
+ }
7251
7284
  };
7252
7285
  const completeClaimedProjectDeletion = async (projectId, claimId) => {
7253
7286
  await runExclusiveExecutionArtifactMaintenance(() => reconcileProjectExecutionArtifacts(projectId, {
@@ -9082,6 +9115,15 @@ const runExecutionEvidenceCleanup = () => {
9082
9115
  catch (error) {
9083
9116
  console.error('Failed to clean up expired execution evidence', error);
9084
9117
  }
9118
+ try {
9119
+ const result = pruneAllRepositoryGraphScans();
9120
+ if (result.total > 0) {
9121
+ console.log(`Pruned ${result.total} repository graph scan(s): ${result.completed} completed, ${result.non_completed} non-completed`);
9122
+ }
9123
+ }
9124
+ catch (error) {
9125
+ console.error('Failed to prune repository graph scans', error);
9126
+ }
9085
9127
  };
9086
9128
  const startExecutionEvidenceCleanupTimer = () => {
9087
9129
  if (executionEvidenceCleanupTimer) {
@@ -9155,6 +9197,13 @@ export const startServer = ({ port = DEFAULT_PORT, host } = {}) => {
9155
9197
  releaseInterruptedProjectDeletionClaims();
9156
9198
  await resumeInterruptedProjectDeletions();
9157
9199
  await reconcileStartupExecutions({ getGitHubConfig: getGitHubConnectionConfig });
9200
+ const repositoryGraphSchemaExists = db.prepare(`
9201
+ SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'repository_graph_scans'
9202
+ `).get();
9203
+ if (repositoryGraphSchemaExists) {
9204
+ const graphScans = await import('./lib/repositoryGraphScan.js');
9205
+ graphScans.openRepositoryGraphScanAdmissions();
9206
+ }
9158
9207
  throwIfShutdownRequested();
9159
9208
  await runExecutionArtifactCleanup('startup');
9160
9209
  throwIfShutdownRequested();
@@ -9215,6 +9264,12 @@ export const shutdownServer = async (signal) => {
9215
9264
  }
9216
9265
  await executionArtifactCleanupPromise;
9217
9266
  await stopMobileAccess();
9267
+ const repositoryGraphSchemaExists = db.prepare(`
9268
+ SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'repository_graph_scans'
9269
+ `).get();
9270
+ if (repositoryGraphSchemaExists) {
9271
+ await (await import('./lib/repositoryGraphScan.js')).shutdownRepositoryGraphScans();
9272
+ }
9218
9273
  await shutdownCheckRunner();
9219
9274
  await clearAllTestSessions(io);
9220
9275
  await clearAllGitHubActionsSessions();