@straiffi/archon 1.8.15 → 1.8.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/assets/ActivityView-XT8l-IRo.js +1 -0
- package/dist/client/assets/GitHubActionsDialog-C1nmgELc.js +1 -0
- package/dist/client/assets/VerificationDialog-Cg5XNaPd.js +4 -0
- package/dist/client/assets/{arc-C83vRtlz.js → arc-D2Nn9xIj.js} +1 -1
- package/dist/client/assets/architecture-7EHR7CIX-C-4Cp4ml.js +1 -0
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-Dx7MJofM.js → architectureDiagram-3BPJPVTR-YDD_HNbm.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-CSSJR8F_.js → blockDiagram-GPEHLZMM-BCgBIlJR.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-C4F9969r.js → c4Diagram-AAUBKEIU-BLfk5bKl.js} +1 -1
- package/dist/client/assets/channel-3_WpUZue.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-23HW6i-y.js → chunk-2J33WTMH-DvwqUfn2.js} +1 -1
- package/dist/client/assets/{chunk-3OPIFGDE-C3ZmRDMb.js → chunk-3OPIFGDE-D9R3JLGz.js} +1 -1
- package/dist/client/assets/{chunk-4BX2VUAB-C5pU9ApX.js → chunk-4BX2VUAB-CtLS8D71.js} +1 -1
- package/dist/client/assets/{chunk-4EGX6M5U-CAjWPjND.js → chunk-4EGX6M5U-Btnm0QNe.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-DhO4-AG4.js → chunk-55IACEB6-74CcJaub.js} +1 -1
- package/dist/client/assets/{chunk-5DO6E6H7-BDKA-zHS.js → chunk-5DO6E6H7-WLZ8L4ko.js} +1 -1
- package/dist/client/assets/{chunk-5ZQYHXKU-B_-UQvCg.js → chunk-5ZQYHXKU-CZeWOab2.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-5Dua6u1B.js → chunk-727SXJPM-YdTt6zCi.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-DcpcaFRO.js → chunk-AQP2D5EJ-BFHbP_eb.js} +1 -1
- package/dist/client/assets/{chunk-BR22UD5L-12D2GWh4.js → chunk-BR22UD5L-Cou5beGe.js} +1 -1
- package/dist/client/assets/{chunk-BSJP7CBP-DMi77e84.js → chunk-BSJP7CBP-DJ57XcV5.js} +1 -1
- package/dist/client/assets/{chunk-CSCIHK7Q-CLCpOw52.js → chunk-CSCIHK7Q-C0BPXL2C.js} +2 -2
- package/dist/client/assets/{chunk-FHYWG6QK-BhSajKiB.js → chunk-FHYWG6QK-Ba10e2kj.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-Drmlc0wM.js → chunk-FMBD7UC4-CEo2wZMx.js} +1 -1
- package/dist/client/assets/{chunk-KSCS5N6A-uOZFe2JI.js → chunk-KSCS5N6A-DqC4tO6g.js} +1 -1
- package/dist/client/assets/{chunk-L5ZTLDWV-DNnzSNoX.js → chunk-L5ZTLDWV-BERUWsJ6.js} +1 -1
- package/dist/client/assets/{chunk-LZXEDZCA-CSA3Xnoh.js → chunk-LZXEDZCA-BUHwhuWm.js} +2 -2
- package/dist/client/assets/{chunk-MPE355IW-Cw8YmjTC.js → chunk-MPE355IW-MqEt-J8G.js} +1 -1
- package/dist/client/assets/{chunk-MZUSXYTE-jvxRCZ7x.js → chunk-MZUSXYTE-DdNi9lhx.js} +1 -1
- package/dist/client/assets/{chunk-N66VUXT2-00i4y0yD.js → chunk-N66VUXT2-CjemTW4E.js} +1 -1
- package/dist/client/assets/{chunk-ND2GUHAM-BQR5rD7w.js → chunk-ND2GUHAM-DCfmNJ41.js} +1 -1
- package/dist/client/assets/{chunk-NZK2D7GU-DyIwcQYQ.js → chunk-NZK2D7GU-CHOkPepJ.js} +1 -1
- package/dist/client/assets/{chunk-O5CBEL6O-DfW60w5V.js → chunk-O5CBEL6O-ByMuL2EO.js} +1 -1
- package/dist/client/assets/{chunk-PUPMXCY4-DfWourL7.js → chunk-PUPMXCY4-ZvwTw0To.js} +1 -1
- package/dist/client/assets/chunk-QZHKN3VN-LI_RZca2.js +1 -0
- package/dist/client/assets/{chunk-UIBZB4QT-v-a5ZfN6.js → chunk-UIBZB4QT-BTY9be9s.js} +1 -1
- package/dist/client/assets/{chunk-WCWK7LTN-CtYzhvvb.js → chunk-WCWK7LTN-Db1n3n3-.js} +1 -1
- package/dist/client/assets/chunk-WU5MYG2G-BGsB3vTj.js +1 -0
- package/dist/client/assets/{chunk-XPW4576I-CvnAuXH2.js → chunk-XPW4576I-DObFPxjB.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK--L8rxPgF.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-uW5z5Qib.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-fchD-dH2.js → cose-bilkent-S5V4N54A-MlOPiG6P.js} +1 -1
- package/dist/client/assets/{dagre-BM42HDAG-Ba7Pz-ZI.js → dagre-BM42HDAG-CtmlVYvf.js} +1 -1
- package/dist/client/assets/{dagre-DSrzm-Gq.js → dagre-BWNHuDdf.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-BxYfgpZ6.js → diagram-2AECGRRQ-DmQ2-tFR.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-Bc4-O-UJ.js → diagram-5GNKFQAL-l49VXoBJ.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-Ds1Lmrzm.js → diagram-KO2AKTUF-0-U37RyJ.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-VFQabxKS.js → diagram-LMA3HP47-DupuMWgW.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-Baff59Zc.js → diagram-OG6HWLK6-D5DoIHW2.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-Da5zHjOK.js → erDiagram-TEJ5UH35-DO-3-WYF.js} +1 -1
- package/dist/client/assets/eventmodeling-FCH6USID-Dqb6QKoI.js +1 -0
- package/dist/client/assets/{flowDiagram-I6XJVG4X-pdGMAuog.js → flowDiagram-I6XJVG4X-CG1viGSO.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-DjJGX0nm.js → ganttDiagram-6RSMTGT7-CV-6ALMZ.js} +1 -1
- package/dist/client/assets/gitGraph-WXDBUCRP-DYEsqh93.js +1 -0
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-kErlwtcT.js → gitGraphDiagram-PVQCEYII-CHnyP-d3.js} +1 -1
- package/dist/client/assets/index-CsZfTdMO.css +2 -0
- package/dist/client/assets/index-DQ7z6ZWk.js +275 -0
- package/dist/client/assets/info-J43DQDTF-CfjXFZai.js +1 -0
- package/dist/client/assets/{infoDiagram-5YYISTIA-Bx78HhDi.js → infoDiagram-5YYISTIA-iKC-l4xs.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-BP0YQCMl.js → ishikawaDiagram-YF4QCWOH-zi-y6jRI.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-DUgrCOuD.js → journeyDiagram-JHISSGLW-Da4wMeC4.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-K0Zc5_M8.js → kanban-definition-UN3LZRKU-CZQ1yL5y.js} +1 -1
- package/dist/client/assets/{line-Dtg-krjk.js → line-B-FS1zIN.js} +1 -1
- package/dist/client/assets/{linear-BOwW57yX.js → linear-DT4rSZvy.js} +1 -1
- package/dist/client/assets/{mermaid-parser.core-Dw5BI77W.js → mermaid-parser.core-DPXl3axs.js} +2 -2
- package/dist/client/assets/{mermaid.core-BE-qlWNj.js → mermaid.core-DjqrtE_A.js} +3 -3
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-1Piz4H9I.js → mindmap-definition-RKZ34NQL-Day2-dLJ.js} +1 -1
- package/dist/client/assets/{ordinal-CZ33lFpK.js → ordinal-k--hYEme.js} +1 -1
- package/dist/client/assets/packet-YPE3B663-Dv0HkRHU.js +1 -0
- package/dist/client/assets/pie-LRSECV5Y-S5zPzZFN.js +1 -0
- package/dist/client/assets/{pieDiagram-4H26LBE5-zlWdJ7lL.js → pieDiagram-4H26LBE5-BmZiJzvi.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-DRQY8Adp.js → quadrantDiagram-W4KKPZXB-DJgAcycV.js} +1 -1
- package/dist/client/assets/radar-GUYGQ44K-B7psLv22.js +1 -0
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-B8_GJFxl.js → requirementDiagram-4Y6WPE33-y94ek5ya.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-BaI0Njo8.js → sankeyDiagram-5OEKKPKP-ChuulS6b.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-DjqAXbRF.js → sequenceDiagram-3UESZ5HK-C7eiUu5p.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-Ovr_3LeO.js → stateDiagram-AJRCARHV-Dy4QkKUV.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-HdcReOP7.js +1 -0
- package/dist/client/assets/{timeline-definition-PNZ67QCA-DkczYKeZ.js → timeline-definition-PNZ67QCA-CTtZLJWJ.js} +1 -1
- package/dist/client/assets/treeView-BLDUP644-B8H0kT67.js +1 -0
- package/dist/client/assets/treemap-LRROVOQU-DPLhFHnh.js +1 -0
- package/dist/client/assets/{vennDiagram-CIIHVFJN-BZyo4ESi.js → vennDiagram-CIIHVFJN-C5matxMS.js} +1 -1
- package/dist/client/assets/wardley-L42UT6IY-B5-Vb08V.js +1 -0
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-BEISrECX.js → wardleyDiagram-YWT4CUSO-m_iOvfzY.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-CyNzGK7f.js → xychartDiagram-2RQKCTM6-BmOxTt9K.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/server/db.js +235 -0
- package/dist/server/db.js.map +1 -1
- package/dist/server/index.js +200 -45
- package/dist/server/index.js.map +1 -1
- package/dist/server/lib/agent.js +139 -90
- package/dist/server/lib/agent.js.map +1 -1
- package/dist/server/lib/agentProvider.js +1 -6
- package/dist/server/lib/agentProvider.js.map +1 -1
- package/dist/server/lib/buildExecutionEnvironment.js +535 -0
- package/dist/server/lib/buildExecutionEnvironment.js.map +1 -0
- package/dist/server/lib/buildOpenQuestionOperations.js +9 -3
- package/dist/server/lib/buildOpenQuestionOperations.js.map +1 -1
- package/dist/server/lib/checkAutoFix.js +1 -0
- package/dist/server/lib/checkAutoFix.js.map +1 -1
- package/dist/server/lib/checkRepairDispatch.js +3 -1
- package/dist/server/lib/checkRepairDispatch.js.map +1 -1
- package/dist/server/lib/dockerSandboxCredentials.js +62 -0
- package/dist/server/lib/dockerSandboxCredentials.js.map +1 -0
- package/dist/server/lib/dockerSandboxEnvironmentOperations.js +54 -0
- package/dist/server/lib/dockerSandboxEnvironmentOperations.js.map +1 -0
- package/dist/server/lib/dockerSandboxExecutionEnvironment.js +725 -0
- package/dist/server/lib/dockerSandboxExecutionEnvironment.js.map +1 -0
- package/dist/server/lib/dockerSandboxExecutionProvider.js +196 -0
- package/dist/server/lib/dockerSandboxExecutionProvider.js.map +1 -0
- package/dist/server/lib/dockerSandboxOpencodeSessionOperations.js +29 -0
- package/dist/server/lib/dockerSandboxOpencodeSessionOperations.js.map +1 -0
- package/dist/server/lib/dockerSandboxRuntimeController.js +187 -0
- package/dist/server/lib/dockerSandboxRuntimeController.js.map +1 -0
- package/dist/server/lib/executionEnvironment.js +22 -0
- package/dist/server/lib/executionEnvironment.js.map +1 -1
- package/dist/server/lib/executionEnvironmentContexts.js +144 -0
- package/dist/server/lib/executionEnvironmentContexts.js.map +1 -0
- package/dist/server/lib/executionEnvironmentLifecycle.js +63 -0
- package/dist/server/lib/executionEnvironmentLifecycle.js.map +1 -0
- package/dist/server/lib/executionEnvironmentReconciliation.js +782 -0
- package/dist/server/lib/executionEnvironmentReconciliation.js.map +1 -0
- package/dist/server/lib/executionEnvironmentRoutes.js +375 -0
- package/dist/server/lib/executionEnvironmentRoutes.js.map +1 -0
- package/dist/server/lib/executionEnvironmentValidation.js +540 -0
- package/dist/server/lib/executionEnvironmentValidation.js.map +1 -0
- package/dist/server/lib/executionEnvironmentValidationOperations.js +636 -0
- package/dist/server/lib/executionEnvironmentValidationOperations.js.map +1 -0
- package/dist/server/lib/executionEnvironments.js +726 -0
- package/dist/server/lib/executionEnvironments.js.map +1 -0
- package/dist/server/lib/executionReconciliation.js +77 -0
- package/dist/server/lib/executionReconciliation.js.map +1 -1
- package/dist/server/lib/executionRetry.js +3 -0
- package/dist/server/lib/executionRetry.js.map +1 -1
- package/dist/server/lib/executionRuns.js +1 -0
- package/dist/server/lib/executionRuns.js.map +1 -1
- package/dist/server/lib/executionTargets.js +107 -0
- package/dist/server/lib/executionTargets.js.map +1 -0
- package/dist/server/lib/executionTimeline.js +3 -0
- package/dist/server/lib/executionTimeline.js.map +1 -1
- package/dist/server/lib/hostExecutionEnvironment.js +47 -1
- package/dist/server/lib/hostExecutionEnvironment.js.map +1 -1
- package/dist/server/lib/mobileAccess.js +2 -2
- package/dist/server/lib/mobileAccess.js.map +1 -1
- package/dist/server/lib/models.js +11 -0
- package/dist/server/lib/models.js.map +1 -1
- package/dist/server/lib/opencodeErrors.js +31 -3
- package/dist/server/lib/opencodeErrors.js.map +1 -1
- package/dist/server/lib/opencodeSessionOperations.js +189 -9
- package/dist/server/lib/opencodeSessionOperations.js.map +1 -1
- package/dist/server/lib/opencodeTaskSessions.js +7 -12
- package/dist/server/lib/opencodeTaskSessions.js.map +1 -1
- package/dist/server/lib/postBuildChecks.js +2 -1
- package/dist/server/lib/postBuildChecks.js.map +1 -1
- package/dist/server/lib/projects.js +10 -0
- package/dist/server/lib/projects.js.map +1 -1
- package/dist/server/lib/specArtifact.js +1 -1
- package/dist/server/lib/specArtifact.js.map +1 -1
- package/dist/server/lib/specDraft.js +1 -5
- package/dist/server/lib/specDraft.js.map +1 -1
- package/dist/server/lib/specExport.js +1 -6
- package/dist/server/lib/specExport.js.map +1 -1
- package/dist/server/lib/specGraphFeature.js +3 -0
- package/dist/server/lib/specGraphFeature.js.map +1 -0
- package/dist/server/lib/specRepositoryEvidenceFormatting.js +2 -1
- package/dist/server/lib/specRepositoryEvidenceFormatting.js.map +1 -1
- package/dist/server/lib/specRepositoryImpact.js +4 -0
- package/dist/server/lib/specRepositoryImpact.js.map +1 -1
- package/dist/server/lib/specReviewContext.js +6 -20
- package/dist/server/lib/specReviewContext.js.map +1 -1
- package/dist/server/lib/specSnapshotEvidence.js +4 -0
- package/dist/server/lib/specSnapshotEvidence.js.map +1 -1
- package/dist/server/lib/specTicketMaterialization.js +4 -1
- package/dist/server/lib/specTicketMaterialization.js.map +1 -1
- package/dist/server/lib/ticketFollowUpOperations.js +8 -1
- package/dist/server/lib/ticketFollowUpOperations.js.map +1 -1
- package/dist/server/lib/ticketRunOperations.js +0 -3
- package/dist/server/lib/ticketRunOperations.js.map +1 -1
- package/dist/server/lib/types.js +1 -0
- package/dist/server/lib/types.js.map +1 -1
- package/dist/server/lib/workspaceIdentity.js +3 -0
- package/dist/server/lib/workspaceIdentity.js.map +1 -1
- package/dist/server/workers/build.js +115 -8
- package/dist/server/workers/build.js.map +1 -1
- package/dist/server/workers/followUp.js +119 -3
- package/dist/server/workers/followUp.js.map +1 -1
- package/dist/server/workers/plan.js +34 -22
- package/dist/server/workers/plan.js.map +1 -1
- package/dist/server/workers/review.js +14 -13
- package/dist/server/workers/review.js.map +1 -1
- package/dist/server/workers/specReview.js +0 -1
- package/dist/server/workers/specReview.js.map +1 -1
- package/dist/server/workers/specSession.js +46 -122
- package/dist/server/workers/specSession.js.map +1 -1
- package/package.json +1 -1
- package/dist/client/assets/ActivityView-DpY9GZez.js +0 -1
- package/dist/client/assets/GitHubActionsDialog-BCr-hjvp.js +0 -1
- package/dist/client/assets/RepositoryGraphDialog-_hm-x1Dx.js +0 -1
- package/dist/client/assets/VerificationDialog-CsjDzpE1.js +0 -4
- package/dist/client/assets/architecture-7EHR7CIX-Dm8H7N6Z.js +0 -1
- package/dist/client/assets/channel-DVkhJzgx.js +0 -1
- package/dist/client/assets/chunk-QZHKN3VN-CtbsU1Bj.js +0 -1
- package/dist/client/assets/chunk-WU5MYG2G-CzMMPYdi.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-6oZ93s5p.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-DYO_YnkU.js +0 -1
- package/dist/client/assets/eventmodeling-FCH6USID-BWhw0UJ8.js +0 -1
- package/dist/client/assets/gitGraph-WXDBUCRP-BSnxAa1J.js +0 -1
- package/dist/client/assets/index-CS4TzG41.css +0 -2
- package/dist/client/assets/index-D5TEfELZ.js +0 -275
- package/dist/client/assets/info-J43DQDTF-DcFwF1-h.js +0 -1
- package/dist/client/assets/packet-YPE3B663-1VZiO_9r.js +0 -1
- package/dist/client/assets/pie-LRSECV5Y-BX1-tQCu.js +0 -1
- package/dist/client/assets/radar-GUYGQ44K-B2HRrCR4.js +0 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-9pmeAorV.js +0 -1
- package/dist/client/assets/treeView-BLDUP644-CDfUVbUi.js +0 -1
- package/dist/client/assets/treemap-LRROVOQU-DUWqu8sK.js +0 -1
- package/dist/client/assets/wardley-L42UT6IY-BEFuPUCy.js +0 -1
- /package/dist/client/assets/{array-B2f2amhX.js → array-BNor45A1.js} +0 -0
- /package/dist/client/assets/{chunk-NNHCCRGN-DgKrp8T-.js → chunk-NNHCCRGN-CZB-V-Gv.js} +0 -0
- /package/dist/client/assets/{cytoscape.esm-BInZCgaJ.js → cytoscape.esm-B2lJcMSI.js} +0 -0
- /package/dist/client/assets/{defaultLocale-sPXJ5urm.js → defaultLocale-DPzUsThw.js} +0 -0
- /package/dist/client/assets/{dist-DfHDMDTt.js → dist-CERhmQhR.js} +0 -0
- /package/dist/client/assets/{graphlib-DacNv4Jd.js → graphlib-BHOW-eWz.js} +0 -0
- /package/dist/client/assets/{init-BVCnG1lj.js → init-C0L3woqb.js} +0 -0
- /package/dist/client/assets/{katex-BlkrXOwm.js → katex-CpjQsUQe.js} +0 -0
- /package/dist/client/assets/{path-Bw5AvBNC.js → path-sMK4d_s9.js} +0 -0
- /package/dist/client/assets/{rough.esm-DeLgKbOI.js → rough.esm-BoTisKeL.js} +0 -0
- /package/dist/client/assets/{src-CFGsdLiG.js → src-BRjoYtUW.js} +0 -0
package/dist/server/index.js
CHANGED
|
@@ -10,6 +10,8 @@ import { adjectives, animals, uniqueNamesGenerator } from 'unique-names-generato
|
|
|
10
10
|
import db from './db.js';
|
|
11
11
|
import { pruneAllRepositoryGraphScans } from './lib/repositoryGraphRetention.js';
|
|
12
12
|
import { registerRepositoryGraphRoutes } from './lib/repositoryGraphRoutes.js';
|
|
13
|
+
import { registerExecutionEnvironmentRoutes } from './lib/executionEnvironmentRoutes.js';
|
|
14
|
+
import { dockerSandboxAdapter, dockerSandboxRunner, dockerSandboxRuntimeController, } from './lib/dockerSandboxEnvironmentOperations.js';
|
|
13
15
|
import { deleteChatSession, getChatSession, listChatSessions } from './lib/chats.js';
|
|
14
16
|
import { deleteSpecSession, getCreatedTicketIdsForSnapshot, getSpecSession, getSpecSnapshot, listSpecSessions } from './lib/specs.js';
|
|
15
17
|
import { getSpecSnapshotRepositoryEvidenceFreshness } from './lib/specSnapshotEvidence.js';
|
|
@@ -82,6 +84,9 @@ import { buildImportedIssueSessionTitle, importProviderHostedIssueImages } from
|
|
|
82
84
|
import { dispatchGitHubWorkflow, getGitHubWorkflowDispatchConfig, getGitHubWorkflowRun, getGitHubWorkflowRunJobs, listGitHubWorkflows, listGitHubWorkflowRuns, } from './lib/integrations/githubActions.js';
|
|
83
85
|
import { clearAllGitHubActionsSessions, getActiveTrackedRunCount, getTrackedGitHubActionsRuns, startGitHubActionsPolling, trackGitHubActionsRun, } from './lib/integrations/githubActionsSessions.js';
|
|
84
86
|
import { reconcileStartupExecutions } from './lib/executionReconciliation.js';
|
|
87
|
+
import { cleanupProjectExecutionEnvironments, cleanupExecutionEnvironmentsForTarget, ExecutionEnvironmentCleanupError, reconcileOrphanedExecutionEnvironments, reconcileExecutionEnvironments, reconcileProductionExecutionEnvironmentBindings, } from './lib/executionEnvironmentReconciliation.js';
|
|
88
|
+
import { createExecutionTargetKey } from './lib/executionTargets.js';
|
|
89
|
+
import { getExecutionEnvironmentContextForRun } from './lib/executionEnvironmentContexts.js';
|
|
85
90
|
import { PlanningReferenceError, resolveExternalPlanningDescription } from './lib/integrations/planning.js';
|
|
86
91
|
import { refreshIfNeeded as refreshAssignedIssues, clearCachedAssignedIssues } from './lib/integrations/assignedIssuesCache.js';
|
|
87
92
|
import { buildCommitMessagePrompt, normalizeGeneratedCommitMessage } from './lib/commitMessage.js';
|
|
@@ -453,6 +458,7 @@ const buildExecutionRunDetailResponse = async (project, run) => {
|
|
|
453
458
|
details,
|
|
454
459
|
agent_runs: listAgentRunsForExecutionRun(run.id),
|
|
455
460
|
...artifacts,
|
|
461
|
+
environment_context: getExecutionEnvironmentContextForRun(project.id, run.id),
|
|
456
462
|
};
|
|
457
463
|
};
|
|
458
464
|
const formatWorktreeDeleteError = (target, branch, error) => {
|
|
@@ -506,6 +512,25 @@ const getBundlePlanBlockerError = () => {
|
|
|
506
512
|
const hasActiveBundleCheckWork = (projectId, bundleId) => Boolean(getActiveBundleRepairBlocker(bundleId)
|
|
507
513
|
|| findActiveCheckBatchForTarget(projectId, 'bundle', bundleId)
|
|
508
514
|
|| findActiveCheckAutoFixForTarget(projectId, 'bundle', bundleId));
|
|
515
|
+
const cleanupWorktreeExecutionTarget = async ({ project, targetKind, targetKey, targetLabel, worktreeTarget, branch, }) => {
|
|
516
|
+
try {
|
|
517
|
+
await cleanupExecutionEnvironmentsForTarget({
|
|
518
|
+
projectId: project.id,
|
|
519
|
+
targetKind,
|
|
520
|
+
targetKey,
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
catch (error) {
|
|
524
|
+
const message = error instanceof Error ? error.message : 'Docker Sandbox cleanup could not be verified.';
|
|
525
|
+
throw new HttpError(409, `Cannot delete ${targetLabel} until its Docker Sandbox cleanup completes: ${message}`);
|
|
526
|
+
}
|
|
527
|
+
try {
|
|
528
|
+
deleteWorktree(branch, project);
|
|
529
|
+
}
|
|
530
|
+
catch (error) {
|
|
531
|
+
throw new HttpError(500, formatWorktreeDeleteError(worktreeTarget, branch, error));
|
|
532
|
+
}
|
|
533
|
+
};
|
|
509
534
|
const deleteTicketRecord = async (ticket) => {
|
|
510
535
|
if (ticket.project_id
|
|
511
536
|
&& ticket.worktree_bundle_id
|
|
@@ -524,19 +549,54 @@ const deleteTicketRecord = async (ticket) => {
|
|
|
524
549
|
const project = getEffectiveProject(ticket);
|
|
525
550
|
if (project) {
|
|
526
551
|
try {
|
|
527
|
-
|
|
552
|
+
await cleanupWorktreeExecutionTarget({
|
|
553
|
+
project,
|
|
554
|
+
targetKind: 'branch-worktree',
|
|
555
|
+
targetKey: createExecutionTargetKey(project.id, { kind: 'branch-worktree', bundleId: null, branch }),
|
|
556
|
+
targetLabel: 'ticket worktree',
|
|
557
|
+
worktreeTarget: 'ticket',
|
|
558
|
+
branch,
|
|
559
|
+
});
|
|
528
560
|
}
|
|
529
561
|
catch (error) {
|
|
530
562
|
return {
|
|
531
563
|
ok: false,
|
|
532
|
-
status: 500,
|
|
533
|
-
error:
|
|
564
|
+
status: error instanceof HttpError ? error.status : 500,
|
|
565
|
+
error: error instanceof Error ? error.message : 'Unable to delete the ticket worktree',
|
|
534
566
|
};
|
|
535
567
|
}
|
|
536
568
|
}
|
|
537
569
|
}
|
|
538
570
|
const bundledProject = isBundledTicket(ticket) ? getEffectiveProject(ticket) : null;
|
|
539
571
|
const deletedBundleId = ticket.worktree_bundle_id;
|
|
572
|
+
const deletedBundle = bundledProject && deletedBundleId ? getBundle(deletedBundleId, bundledProject.id) : null;
|
|
573
|
+
const bundleResourcesWereCleaned = Boolean(bundledProject
|
|
574
|
+
&& deletedBundle
|
|
575
|
+
&& !isProjectRootBundle(deletedBundle)
|
|
576
|
+
&& countBundleTickets(deletedBundle.id, bundledProject.id) === 1);
|
|
577
|
+
if (bundleResourcesWereCleaned && bundledProject && deletedBundle) {
|
|
578
|
+
try {
|
|
579
|
+
await cleanupWorktreeExecutionTarget({
|
|
580
|
+
project: bundledProject,
|
|
581
|
+
targetKind: 'bundle-worktree',
|
|
582
|
+
targetKey: createExecutionTargetKey(bundledProject.id, {
|
|
583
|
+
kind: 'bundle-worktree',
|
|
584
|
+
bundleId: deletedBundle.id,
|
|
585
|
+
branch: deletedBundle.branch,
|
|
586
|
+
}),
|
|
587
|
+
targetLabel: 'bundle worktree',
|
|
588
|
+
worktreeTarget: 'bundle',
|
|
589
|
+
branch: deletedBundle.branch,
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
catch (error) {
|
|
593
|
+
return {
|
|
594
|
+
ok: false,
|
|
595
|
+
status: error instanceof HttpError ? error.status : 500,
|
|
596
|
+
error: error instanceof Error ? error.message : 'Unable to delete the bundle worktree',
|
|
597
|
+
};
|
|
598
|
+
}
|
|
599
|
+
}
|
|
540
600
|
let nextBuildTicketId = null;
|
|
541
601
|
let nextBuildSequenceId = null;
|
|
542
602
|
let affectedTicketIds = [];
|
|
@@ -557,7 +617,7 @@ const deleteTicketRecord = async (ticket) => {
|
|
|
557
617
|
}
|
|
558
618
|
if (bundledProject && deletedBundleId) {
|
|
559
619
|
try {
|
|
560
|
-
cleanupBundleIfEmpty(deletedBundleId, bundledProject);
|
|
620
|
+
await cleanupBundleIfEmpty(deletedBundleId, bundledProject, { resourcesAlreadyCleaned: bundleResourcesWereCleaned });
|
|
561
621
|
}
|
|
562
622
|
catch (error) {
|
|
563
623
|
return {
|
|
@@ -870,7 +930,7 @@ const createAutoBundleForName = (name, projectId, baseBranch = null) => {
|
|
|
870
930
|
}
|
|
871
931
|
return bundle;
|
|
872
932
|
};
|
|
873
|
-
const cleanupBundleIfEmpty = (bundleId, project) => {
|
|
933
|
+
const cleanupBundleIfEmpty = async (bundleId, project, options = {}) => {
|
|
874
934
|
if (!bundleId) {
|
|
875
935
|
return;
|
|
876
936
|
}
|
|
@@ -884,11 +944,19 @@ const cleanupBundleIfEmpty = (bundleId, project) => {
|
|
|
884
944
|
if (hasActiveBundleCheckWork(project.id, bundle.id)) {
|
|
885
945
|
throw new HttpError(409, 'Cannot delete a bundle while check work is active');
|
|
886
946
|
}
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
947
|
+
if (!options.resourcesAlreadyCleaned) {
|
|
948
|
+
await cleanupWorktreeExecutionTarget({
|
|
949
|
+
project,
|
|
950
|
+
targetKind: 'bundle-worktree',
|
|
951
|
+
targetKey: createExecutionTargetKey(project.id, {
|
|
952
|
+
kind: 'bundle-worktree',
|
|
953
|
+
bundleId: bundle.id,
|
|
954
|
+
branch: bundle.branch,
|
|
955
|
+
}),
|
|
956
|
+
targetLabel: 'bundle worktree',
|
|
957
|
+
worktreeTarget: 'bundle',
|
|
958
|
+
branch: bundle.branch,
|
|
959
|
+
});
|
|
892
960
|
}
|
|
893
961
|
deleteBundle(bundle.id, project.id);
|
|
894
962
|
};
|
|
@@ -1358,6 +1426,8 @@ const listDetailedBundleTickets = (projectId, bundleId) => {
|
|
|
1358
1426
|
const representative = getBundleRepresentativeTicketContext(projectId, bundleId);
|
|
1359
1427
|
return representative ? sortBundleTicketsByExecutionOrder(listTicketsInRunContext(representative)) : [];
|
|
1360
1428
|
};
|
|
1429
|
+
const listBoardBundleTickets = (projectId, bundleId) => listTickets(projectId, { detail: 'board' })
|
|
1430
|
+
.filter(ticket => ticket.worktree_bundle_id === bundleId);
|
|
1361
1431
|
const listBundleConversationTickets = (projectId, bundleId) => {
|
|
1362
1432
|
const representative = getBundleRepresentativeTicketContext(projectId, bundleId);
|
|
1363
1433
|
return representative
|
|
@@ -2480,6 +2550,12 @@ const emitRunStateForContext = (ticket, isRunningValue) => {
|
|
|
2480
2550
|
};
|
|
2481
2551
|
app.use(express.json({ limit: '5mb' }));
|
|
2482
2552
|
registerRepositoryGraphRoutes(app, { emitter: io });
|
|
2553
|
+
registerExecutionEnvironmentRoutes(app, {
|
|
2554
|
+
emitter: io,
|
|
2555
|
+
runner: dockerSandboxRunner,
|
|
2556
|
+
adapter: dockerSandboxAdapter,
|
|
2557
|
+
runtimeController: dockerSandboxRuntimeController,
|
|
2558
|
+
});
|
|
2483
2559
|
const requireDesktopMobileAccessRequest = (req, res) => {
|
|
2484
2560
|
const rejectionReason = validateDesktopMobileAccessRequest(req);
|
|
2485
2561
|
if (!rejectionReason) {
|
|
@@ -2598,7 +2674,7 @@ app.post('/projects/:id/chat-sessions', (req, res) => {
|
|
|
2598
2674
|
}
|
|
2599
2675
|
return res.status(result.status).json(result.value);
|
|
2600
2676
|
});
|
|
2601
|
-
app.get('/projects/:id/chat-sessions/:sessionId', (req, res) => {
|
|
2677
|
+
app.get('/projects/:id/chat-sessions/:sessionId', async (req, res) => {
|
|
2602
2678
|
const project = getProjectById(req.params.id);
|
|
2603
2679
|
if (!project) {
|
|
2604
2680
|
return res.status(404).json({ error: 'Not found' });
|
|
@@ -2607,7 +2683,7 @@ app.get('/projects/:id/chat-sessions/:sessionId', (req, res) => {
|
|
|
2607
2683
|
if (!chatSession) {
|
|
2608
2684
|
return res.status(404).json({ error: 'Not found' });
|
|
2609
2685
|
}
|
|
2610
|
-
const refreshedChatSession = refreshChatSessionUsageSnapshot(chatSession.id, { includeMessages: true });
|
|
2686
|
+
const refreshedChatSession = await refreshChatSessionUsageSnapshot(chatSession.id, { includeMessages: true });
|
|
2611
2687
|
if (!refreshedChatSession || refreshedChatSession.project_id !== project.id) {
|
|
2612
2688
|
return res.json(chatSession);
|
|
2613
2689
|
}
|
|
@@ -2908,7 +2984,7 @@ app.post('/projects/:id/spec-sessions', (req, res) => {
|
|
|
2908
2984
|
}
|
|
2909
2985
|
return res.status(result.status).json(result.value);
|
|
2910
2986
|
});
|
|
2911
|
-
app.get('/projects/:id/spec-sessions/:sessionId', (req, res) => {
|
|
2987
|
+
app.get('/projects/:id/spec-sessions/:sessionId', async (req, res) => {
|
|
2912
2988
|
const project = getProjectById(req.params.id);
|
|
2913
2989
|
if (!project) {
|
|
2914
2990
|
return res.status(404).json({ error: 'Not found' });
|
|
@@ -2917,7 +2993,7 @@ app.get('/projects/:id/spec-sessions/:sessionId', (req, res) => {
|
|
|
2917
2993
|
if (!specSession) {
|
|
2918
2994
|
return res.status(404).json({ error: 'Not found' });
|
|
2919
2995
|
}
|
|
2920
|
-
const refreshedSpecSession = refreshSpecSessionUsageSnapshot(specSession.id, { includeMessages: true });
|
|
2996
|
+
const refreshedSpecSession = await refreshSpecSessionUsageSnapshot(specSession.id, { includeMessages: true });
|
|
2921
2997
|
if (!refreshedSpecSession || refreshedSpecSession.project_id !== project.id) {
|
|
2922
2998
|
return res.json(specSession);
|
|
2923
2999
|
}
|
|
@@ -3848,7 +3924,7 @@ app.post('/bundles', async (req, res) => {
|
|
|
3848
3924
|
}
|
|
3849
3925
|
res.status(201).json(serializeBundleRow(result.project.id, bundle, [], result.project));
|
|
3850
3926
|
});
|
|
3851
|
-
app.delete('/bundles/:id', (req, res) => {
|
|
3927
|
+
app.delete('/bundles/:id', async (req, res) => {
|
|
3852
3928
|
const result = getRequiredProject(req);
|
|
3853
3929
|
if ('error' in result) {
|
|
3854
3930
|
return res.status(400).json({ error: result.error });
|
|
@@ -3882,11 +3958,22 @@ app.delete('/bundles/:id', (req, res) => {
|
|
|
3882
3958
|
.filter(specSession => specSession.target_bundle_id === bundle.id)
|
|
3883
3959
|
.map(specSession => specSession.id);
|
|
3884
3960
|
try {
|
|
3885
|
-
|
|
3961
|
+
await cleanupWorktreeExecutionTarget({
|
|
3962
|
+
project: result.project,
|
|
3963
|
+
targetKind: 'bundle-worktree',
|
|
3964
|
+
targetKey: createExecutionTargetKey(result.project.id, {
|
|
3965
|
+
kind: 'bundle-worktree',
|
|
3966
|
+
bundleId: bundle.id,
|
|
3967
|
+
branch: bundle.branch,
|
|
3968
|
+
}),
|
|
3969
|
+
targetLabel: 'bundle worktree',
|
|
3970
|
+
worktreeTarget: 'bundle',
|
|
3971
|
+
branch: bundle.branch,
|
|
3972
|
+
});
|
|
3886
3973
|
}
|
|
3887
3974
|
catch (error) {
|
|
3888
|
-
return res.status(500).json({
|
|
3889
|
-
error:
|
|
3975
|
+
return res.status(error instanceof HttpError ? error.status : 500).json({
|
|
3976
|
+
error: error instanceof Error ? error.message : 'Unable to delete the bundle worktree',
|
|
3890
3977
|
});
|
|
3891
3978
|
}
|
|
3892
3979
|
deleteBundle(bundle.id, result.project.id);
|
|
@@ -4171,12 +4258,16 @@ app.post('/bundles/:id/build-open-questions/resolve', async (req, res) => {
|
|
|
4171
4258
|
progressionRunId: accepted.progressionRunId,
|
|
4172
4259
|
broadcaster: io,
|
|
4173
4260
|
});
|
|
4174
|
-
for (const ticket of
|
|
4261
|
+
for (const ticket of listBoardBundleTickets(result.project.id, bundle.id)) {
|
|
4175
4262
|
io.emit('ticket:updated', ticket);
|
|
4176
4263
|
}
|
|
4177
|
-
return res.json(
|
|
4264
|
+
return res.json({
|
|
4265
|
+
kind: accepted.kind,
|
|
4266
|
+
batch_id: accepted.batchId,
|
|
4267
|
+
target_ticket_id: null,
|
|
4268
|
+
});
|
|
4178
4269
|
}
|
|
4179
|
-
const ticketsBeforeReview =
|
|
4270
|
+
const ticketsBeforeReview = listBoardBundleTickets(result.project.id, bundle.id);
|
|
4180
4271
|
if (!areBundleTicketsReadyForAutomaticReview(ticketsBeforeReview, bundle.id)) {
|
|
4181
4272
|
completeAutomationProgression({
|
|
4182
4273
|
projectId: result.project.id,
|
|
@@ -4187,7 +4278,11 @@ app.post('/bundles/:id/build-open-questions/resolve', async (req, res) => {
|
|
|
4187
4278
|
for (const ticket of ticketsBeforeReview) {
|
|
4188
4279
|
io.emit('ticket:updated', ticket);
|
|
4189
4280
|
}
|
|
4190
|
-
return res.json(
|
|
4281
|
+
return res.json({
|
|
4282
|
+
kind: accepted.kind,
|
|
4283
|
+
batch_id: accepted.batchId,
|
|
4284
|
+
target_ticket_id: null,
|
|
4285
|
+
});
|
|
4191
4286
|
}
|
|
4192
4287
|
let reviewStartFailureStatus = null;
|
|
4193
4288
|
let reviewStartFailureError = null;
|
|
@@ -4218,24 +4313,27 @@ app.post('/bundles/:id/build-open-questions/resolve', async (req, res) => {
|
|
|
4218
4313
|
});
|
|
4219
4314
|
return res.status(reviewStartFailureStatus).json({ error: reviewStartFailureError });
|
|
4220
4315
|
}
|
|
4221
|
-
const updatedTickets =
|
|
4316
|
+
const updatedTickets = listBoardBundleTickets(result.project.id, bundle.id);
|
|
4222
4317
|
for (const ticket of updatedTickets) {
|
|
4223
4318
|
io.emit('ticket:updated', ticket);
|
|
4224
4319
|
}
|
|
4225
4320
|
const reviewOwner = reviewStarted
|
|
4226
4321
|
? updatedTickets.find(ticket => ticket.state === 'review' && ticket.parked_at === null)
|
|
4227
4322
|
: null;
|
|
4228
|
-
return res.json(
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4323
|
+
return res.json({
|
|
4324
|
+
kind: accepted.kind,
|
|
4325
|
+
batch_id: accepted.batchId,
|
|
4326
|
+
target_ticket_id: reviewOwner?.id ?? null,
|
|
4327
|
+
});
|
|
4232
4328
|
}
|
|
4233
|
-
for (const ticket of
|
|
4329
|
+
for (const ticket of listBoardBundleTickets(result.project.id, bundle.id)) {
|
|
4234
4330
|
io.emit('ticket:updated', ticket);
|
|
4235
4331
|
}
|
|
4236
|
-
return res.status(accepted.status).json(
|
|
4332
|
+
return res.status(accepted.status).json({
|
|
4333
|
+
kind: accepted.kind,
|
|
4334
|
+
batch_id: accepted.batchId,
|
|
4237
4335
|
target_ticket_id: accepted.targetTicket.id,
|
|
4238
|
-
})
|
|
4336
|
+
});
|
|
4239
4337
|
});
|
|
4240
4338
|
app.post('/bundles/:id/undo-review', (req, res) => {
|
|
4241
4339
|
const result = getRequiredProject(req);
|
|
@@ -6002,7 +6100,7 @@ app.post('/projects', (req, res) => {
|
|
|
6002
6100
|
return res.status(400).json({ error: validation.error });
|
|
6003
6101
|
}
|
|
6004
6102
|
const projectCount = Number(db.prepare('SELECT COUNT(*) AS count FROM projects').get()?.count ?? 0);
|
|
6005
|
-
const { name, repo_path, linked_project_ids, run_setup, run_services, check_definitions, required_check_definition_ids, pre_review_check_definition_ids, post_build_check_definition_ids, auto_fix_check_definition_ids, test_commands, run_ide, preview_service_name, preview_path, preview_capability_mode, helper_model, helper_variant, reviewer_model, reviewer_variant, commit_message_rules, commit_after_each_ticket, auto_park_stale_tickets, memory_enabled, scan_include_globs_json, scan_exclude_globs_json, worktree_sync, spec_aware_code_review_enabled, automation_depth, automation_review_fix_enabled, automation_pause_on_open_questions, automation_review_severity, automation_review_max_iterations, } = validation.values;
|
|
6103
|
+
const { name, repo_path, build_execution_provider, linked_project_ids, run_setup, run_services, check_definitions, required_check_definition_ids, pre_review_check_definition_ids, post_build_check_definition_ids, auto_fix_check_definition_ids, test_commands, run_ide, preview_service_name, preview_path, preview_capability_mode, helper_model, helper_variant, reviewer_model, reviewer_variant, commit_message_rules, commit_after_each_ticket, auto_park_stale_tickets, memory_enabled, scan_include_globs_json, scan_exclude_globs_json, worktree_sync, spec_aware_code_review_enabled, automation_depth, automation_review_fix_enabled, automation_pause_on_open_questions, automation_review_severity, automation_review_max_iterations, } = validation.values;
|
|
6006
6104
|
if (!repo_path) {
|
|
6007
6105
|
return res.status(400).json({ error: 'repo_path must be a non-empty string' });
|
|
6008
6106
|
}
|
|
@@ -6020,6 +6118,7 @@ app.post('/projects', (req, res) => {
|
|
|
6020
6118
|
id,
|
|
6021
6119
|
name,
|
|
6022
6120
|
repo_path,
|
|
6121
|
+
build_execution_provider,
|
|
6023
6122
|
run_setup,
|
|
6024
6123
|
run_services,
|
|
6025
6124
|
check_definitions,
|
|
@@ -6050,8 +6149,8 @@ app.post('/projects', (req, res) => {
|
|
|
6050
6149
|
automation_review_severity,
|
|
6051
6150
|
automation_review_max_iterations
|
|
6052
6151
|
)
|
|
6053
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
6054
|
-
`).run(id, name, normalizedRepoPath, run_setup, run_services, check_definitions, required_check_definition_ids ?? '[]', pre_review_check_definition_ids ?? '[]', post_build_check_definition_ids ?? '[]', auto_fix_check_definition_ids ?? '[]', test_commands, run_ide ?? null, preview_service_name ?? null, preview_path ?? null, preview_capability_mode ?? null, helper_model ?? null, helper_variant ?? null, reviewer_model ?? null, reviewer_model ? reviewer_variant ?? null : null, commit_message_rules ?? null, commit_after_each_ticket ?? 0, auto_park_stale_tickets ?? 0, memory_enabled ?? 0, scan_include_globs_json ?? null, scan_exclude_globs_json ?? null, worktree_sync ?? null, spec_aware_code_review_enabled ?? 0, automation_depth ?? 'manual', automation_review_fix_enabled ?? 0, automation_pause_on_open_questions ?? 0, automation_review_severity ?? 'medium', automation_review_max_iterations ?? 3);
|
|
6152
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
6153
|
+
`).run(id, name, normalizedRepoPath, build_execution_provider ?? 'host', run_setup, run_services, check_definitions, required_check_definition_ids ?? '[]', pre_review_check_definition_ids ?? '[]', post_build_check_definition_ids ?? '[]', auto_fix_check_definition_ids ?? '[]', test_commands, run_ide ?? null, preview_service_name ?? null, preview_path ?? null, preview_capability_mode ?? null, helper_model ?? null, helper_variant ?? null, reviewer_model ?? null, reviewer_model ? reviewer_variant ?? null : null, commit_message_rules ?? null, commit_after_each_ticket ?? 0, auto_park_stale_tickets ?? 0, memory_enabled ?? 0, scan_include_globs_json ?? null, scan_exclude_globs_json ?? null, worktree_sync ?? null, spec_aware_code_review_enabled ?? 0, automation_depth ?? 'manual', automation_review_fix_enabled ?? 0, automation_pause_on_open_questions ?? 0, automation_review_severity ?? 'medium', automation_review_max_iterations ?? 3);
|
|
6055
6154
|
replaceProjectLinks(id, linked_project_ids ?? []);
|
|
6056
6155
|
ensureProjectRootBundle(id);
|
|
6057
6156
|
if (projectCount === 0) {
|
|
@@ -7258,11 +7357,12 @@ app.patch('/projects/:id', (req, res) => {
|
|
|
7258
7357
|
});
|
|
7259
7358
|
}
|
|
7260
7359
|
}
|
|
7261
|
-
const { name, repo_path, linked_project_ids, run_setup, run_services, check_definitions, required_check_definition_ids, pre_review_check_definition_ids, post_build_check_definition_ids, auto_fix_check_definition_ids, test_commands, run_ide, preview_service_name, preview_path, preview_capability_mode, helper_model, helper_variant, reviewer_model, reviewer_variant, commit_message_rules, commit_after_each_ticket, auto_park_stale_tickets, memory_enabled, scan_include_globs_json, scan_exclude_globs_json, worktree_sync, spec_aware_code_review_enabled, automation_depth, automation_review_fix_enabled, automation_pause_on_open_questions, automation_review_severity, automation_review_max_iterations, } = validation.values;
|
|
7360
|
+
const { name, repo_path, build_execution_provider, linked_project_ids, run_setup, run_services, check_definitions, required_check_definition_ids, pre_review_check_definition_ids, post_build_check_definition_ids, auto_fix_check_definition_ids, test_commands, run_ide, preview_service_name, preview_path, preview_capability_mode, helper_model, helper_variant, reviewer_model, reviewer_variant, commit_message_rules, commit_after_each_ticket, auto_park_stale_tickets, memory_enabled, scan_include_globs_json, scan_exclude_globs_json, worktree_sync, spec_aware_code_review_enabled, automation_depth, automation_review_fix_enabled, automation_pause_on_open_questions, automation_review_severity, automation_review_max_iterations, } = validation.values;
|
|
7262
7361
|
const updateProject = db.prepare(`
|
|
7263
7362
|
UPDATE projects SET
|
|
7264
7363
|
name = ?,
|
|
7265
7364
|
repo_path = ?,
|
|
7365
|
+
build_execution_provider = ?,
|
|
7266
7366
|
run_setup = ?,
|
|
7267
7367
|
run_services = ?,
|
|
7268
7368
|
check_definitions = ?,
|
|
@@ -7324,7 +7424,7 @@ app.patch('/projects/:id', (req, res) => {
|
|
|
7324
7424
|
if ('error' in policyReferences) {
|
|
7325
7425
|
return policyReferences;
|
|
7326
7426
|
}
|
|
7327
|
-
updateProject.run(name ?? project.name, repo_path ?? project.repo_path, hasOwn(validation.values, 'run_setup') ? run_setup : project.run_setup, hasOwn(validation.values, 'run_services') ? run_services : project.run_services, nextCheckDefinitions, nextRequiredCheckDefinitionIds, nextPreReviewCheckDefinitionIds, nextPostBuildCheckDefinitionIds, nextAutoFixCheckDefinitionIds, hasOwn(validation.values, 'test_commands') ? test_commands : project.test_commands, hasOwn(validation.values, 'run_ide') ? run_ide : project.run_ide, hasOwn(validation.values, 'preview_service_name') ? preview_service_name : project.preview_service_name, hasOwn(validation.values, 'preview_path') ? preview_path : project.preview_path, hasOwn(validation.values, 'preview_capability_mode') ? preview_capability_mode : project.preview_capability_mode, hasOwn(validation.values, 'helper_model') ? helper_model : project.helper_model, hasOwn(validation.values, 'helper_variant') ? helper_variant : project.helper_variant, nextReviewerModel, nextReviewerVariant, hasOwn(validation.values, 'commit_message_rules') ? commit_message_rules : project.commit_message_rules, hasOwn(validation.values, 'commit_after_each_ticket') ? commit_after_each_ticket : project.commit_after_each_ticket, hasOwn(validation.values, 'auto_park_stale_tickets') ? auto_park_stale_tickets : project.auto_park_stale_tickets, hasOwn(validation.values, 'memory_enabled') ? memory_enabled : project.memory_enabled, hasOwn(validation.values, 'scan_include_globs_json') ? scan_include_globs_json : project.scan_include_globs_json, hasOwn(validation.values, 'scan_exclude_globs_json') ? scan_exclude_globs_json : project.scan_exclude_globs_json, hasOwn(validation.values, 'worktree_sync') ? worktree_sync : project.worktree_sync, hasOwn(validation.values, 'spec_aware_code_review_enabled') ? spec_aware_code_review_enabled : project.spec_aware_code_review_enabled, hasOwn(validation.values, 'automation_depth') ? automation_depth : project.automation_depth, hasOwn(validation.values, 'automation_review_fix_enabled') ? automation_review_fix_enabled : project.automation_review_fix_enabled, hasOwn(validation.values, 'automation_pause_on_open_questions') ? automation_pause_on_open_questions : project.automation_pause_on_open_questions, hasOwn(validation.values, 'automation_review_severity') ? automation_review_severity : project.automation_review_severity, hasOwn(validation.values, 'automation_review_max_iterations') ? automation_review_max_iterations : project.automation_review_max_iterations, req.params.id);
|
|
7427
|
+
updateProject.run(name ?? project.name, repo_path ?? project.repo_path, hasOwn(validation.values, 'build_execution_provider') ? build_execution_provider : project.build_execution_provider, hasOwn(validation.values, 'run_setup') ? run_setup : project.run_setup, hasOwn(validation.values, 'run_services') ? run_services : project.run_services, nextCheckDefinitions, nextRequiredCheckDefinitionIds, nextPreReviewCheckDefinitionIds, nextPostBuildCheckDefinitionIds, nextAutoFixCheckDefinitionIds, hasOwn(validation.values, 'test_commands') ? test_commands : project.test_commands, hasOwn(validation.values, 'run_ide') ? run_ide : project.run_ide, hasOwn(validation.values, 'preview_service_name') ? preview_service_name : project.preview_service_name, hasOwn(validation.values, 'preview_path') ? preview_path : project.preview_path, hasOwn(validation.values, 'preview_capability_mode') ? preview_capability_mode : project.preview_capability_mode, hasOwn(validation.values, 'helper_model') ? helper_model : project.helper_model, hasOwn(validation.values, 'helper_variant') ? helper_variant : project.helper_variant, nextReviewerModel, nextReviewerVariant, hasOwn(validation.values, 'commit_message_rules') ? commit_message_rules : project.commit_message_rules, hasOwn(validation.values, 'commit_after_each_ticket') ? commit_after_each_ticket : project.commit_after_each_ticket, hasOwn(validation.values, 'auto_park_stale_tickets') ? auto_park_stale_tickets : project.auto_park_stale_tickets, hasOwn(validation.values, 'memory_enabled') ? memory_enabled : project.memory_enabled, hasOwn(validation.values, 'scan_include_globs_json') ? scan_include_globs_json : project.scan_include_globs_json, hasOwn(validation.values, 'scan_exclude_globs_json') ? scan_exclude_globs_json : project.scan_exclude_globs_json, hasOwn(validation.values, 'worktree_sync') ? worktree_sync : project.worktree_sync, hasOwn(validation.values, 'spec_aware_code_review_enabled') ? spec_aware_code_review_enabled : project.spec_aware_code_review_enabled, hasOwn(validation.values, 'automation_depth') ? automation_depth : project.automation_depth, hasOwn(validation.values, 'automation_review_fix_enabled') ? automation_review_fix_enabled : project.automation_review_fix_enabled, hasOwn(validation.values, 'automation_pause_on_open_questions') ? automation_pause_on_open_questions : project.automation_pause_on_open_questions, hasOwn(validation.values, 'automation_review_severity') ? automation_review_severity : project.automation_review_severity, hasOwn(validation.values, 'automation_review_max_iterations') ? automation_review_max_iterations : project.automation_review_max_iterations, req.params.id);
|
|
7328
7428
|
if (hasOwn(validation.values, 'linked_project_ids')) {
|
|
7329
7429
|
replaceProjectLinks(project.id, linked_project_ids ?? []);
|
|
7330
7430
|
}
|
|
@@ -7373,15 +7473,23 @@ const assertProjectDeletionEligible = (projectId, claimId) => {
|
|
|
7373
7473
|
}
|
|
7374
7474
|
};
|
|
7375
7475
|
const completeClaimedProjectDeletion = async (projectId, claimId) => {
|
|
7476
|
+
const marked = db.prepare(`
|
|
7477
|
+
UPDATE projects
|
|
7478
|
+
SET deletion_cleanup_started_at = COALESCE(deletion_cleanup_started_at, CURRENT_TIMESTAMP)
|
|
7479
|
+
WHERE id = ? AND deletion_claim_id = ?
|
|
7480
|
+
`).run(projectId, claimId);
|
|
7481
|
+
if (marked.changes !== 1) {
|
|
7482
|
+
throw new ProjectDeletionError(409, 'Project deletion ownership was lost');
|
|
7483
|
+
}
|
|
7484
|
+
await cleanupProjectExecutionEnvironments(projectId, claimId);
|
|
7376
7485
|
await runExclusiveExecutionArtifactMaintenance(() => reconcileProjectExecutionArtifacts(projectId, {
|
|
7377
7486
|
emitter: io,
|
|
7378
7487
|
beginCleanup: () => {
|
|
7379
|
-
const
|
|
7380
|
-
|
|
7381
|
-
|
|
7382
|
-
|
|
7383
|
-
|
|
7384
|
-
if (marked.changes !== 1) {
|
|
7488
|
+
const owned = db.prepare(`
|
|
7489
|
+
SELECT 1 FROM projects
|
|
7490
|
+
WHERE id = ? AND deletion_claim_id = ? AND deletion_cleanup_started_at IS NOT NULL
|
|
7491
|
+
`).get(projectId, claimId);
|
|
7492
|
+
if (!owned) {
|
|
7385
7493
|
throw new ProjectDeletionError(409, 'Project deletion ownership was lost');
|
|
7386
7494
|
}
|
|
7387
7495
|
},
|
|
@@ -7426,6 +7534,7 @@ const completeClaimedProjectDeletion = async (projectId, claimId) => {
|
|
|
7426
7534
|
SET parent_run_id = NULL, retry_of_run_id = NULL
|
|
7427
7535
|
WHERE project_id = ?
|
|
7428
7536
|
`).run(projectId);
|
|
7537
|
+
db.prepare("DELETE FROM execution_environments WHERE project_id = ? AND lifecycle_state = 'retired'").run(projectId);
|
|
7429
7538
|
const deleted = db.prepare('DELETE FROM projects WHERE id = ? AND deletion_claim_id = ?').run(projectId, claimId);
|
|
7430
7539
|
if (deleted.changes !== 1) {
|
|
7431
7540
|
throw new ProjectDeletionError(409, 'Project deletion ownership was lost');
|
|
@@ -7477,6 +7586,9 @@ app.delete('/projects/:id', async (req, res) => {
|
|
|
7477
7586
|
if (error instanceof ExecutionArtifactCleanupError) {
|
|
7478
7587
|
return res.status(409).json({ error: error.message });
|
|
7479
7588
|
}
|
|
7589
|
+
if (error instanceof ExecutionEnvironmentCleanupError) {
|
|
7590
|
+
return res.status(409).json({ error: error.message });
|
|
7591
|
+
}
|
|
7480
7592
|
if (error instanceof ProjectDeletionError) {
|
|
7481
7593
|
return res.status(error.status).json({ error: error.message });
|
|
7482
7594
|
}
|
|
@@ -7543,7 +7655,7 @@ app.post('/tickets', (req, res) => {
|
|
|
7543
7655
|
return res.status(500).json({ error: getErrorMessage(error) || 'Unable to create ticket' });
|
|
7544
7656
|
}
|
|
7545
7657
|
});
|
|
7546
|
-
app.patch('/tickets/:id', (req, res) => {
|
|
7658
|
+
app.patch('/tickets/:id', async (req, res) => {
|
|
7547
7659
|
const ticket = getTicket(req.params.id);
|
|
7548
7660
|
if (!ticket) {
|
|
7549
7661
|
return res.status(404).json({ error: 'Not found' });
|
|
@@ -7670,16 +7782,46 @@ app.patch('/tickets/:id', (req, res) => {
|
|
|
7670
7782
|
return res.status(404).json({ error: 'Bundle not found' });
|
|
7671
7783
|
}
|
|
7672
7784
|
}
|
|
7785
|
+
const bundleChanged = previousBundleId !== resolvedBundleId || ticket.project_id !== nextProjectId;
|
|
7786
|
+
let previousBundleResourcesCleaned = false;
|
|
7787
|
+
if (bundleChanged && previousBundleId && previousProject) {
|
|
7788
|
+
const previousBundle = getBundle(previousBundleId, previousProject.id);
|
|
7789
|
+
if (previousBundle
|
|
7790
|
+
&& !isProjectRootBundle(previousBundle)
|
|
7791
|
+
&& countBundleTickets(previousBundle.id, previousProject.id) === 1) {
|
|
7792
|
+
try {
|
|
7793
|
+
await cleanupWorktreeExecutionTarget({
|
|
7794
|
+
project: previousProject,
|
|
7795
|
+
targetKind: 'bundle-worktree',
|
|
7796
|
+
targetKey: createExecutionTargetKey(previousProject.id, {
|
|
7797
|
+
kind: 'bundle-worktree',
|
|
7798
|
+
bundleId: previousBundle.id,
|
|
7799
|
+
branch: previousBundle.branch,
|
|
7800
|
+
}),
|
|
7801
|
+
targetLabel: 'bundle worktree',
|
|
7802
|
+
worktreeTarget: 'bundle',
|
|
7803
|
+
branch: previousBundle.branch,
|
|
7804
|
+
});
|
|
7805
|
+
previousBundleResourcesCleaned = true;
|
|
7806
|
+
}
|
|
7807
|
+
catch (error) {
|
|
7808
|
+
return res.status(error instanceof HttpError ? error.status : 500).json({
|
|
7809
|
+
error: error instanceof Error ? error.message : 'Unable to clean up the empty bundle',
|
|
7810
|
+
});
|
|
7811
|
+
}
|
|
7812
|
+
}
|
|
7813
|
+
}
|
|
7673
7814
|
if (isProjectChanging) {
|
|
7674
7815
|
deleteTicketDependenciesForTicket(ticket.id);
|
|
7675
7816
|
}
|
|
7676
7817
|
db.prepare('UPDATE tickets SET title = ?, description = ?, model = ?, variant = ?, skills_json = ?, worktree_bundle_id = ?, project_id = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?').run(title?.trim() ?? ticket.title, description ?? ticket.description, resolvedModel, resolvedVariant, JSON.stringify(resolvedSkills), resolvedBundleId, nextProjectId, req.params.id);
|
|
7677
7818
|
upsertTicketDescriptionMessage(req.params.id, description ?? ticket.description);
|
|
7678
7819
|
const updated = getTicket(req.params.id);
|
|
7679
|
-
const bundleChanged = previousBundleId !== resolvedBundleId || ticket.project_id !== nextProjectId;
|
|
7680
7820
|
if (bundleChanged && previousBundleId && previousProject) {
|
|
7681
7821
|
try {
|
|
7682
|
-
cleanupBundleIfEmpty(previousBundleId, previousProject
|
|
7822
|
+
await cleanupBundleIfEmpty(previousBundleId, previousProject, {
|
|
7823
|
+
resourcesAlreadyCleaned: previousBundleResourcesCleaned,
|
|
7824
|
+
});
|
|
7683
7825
|
}
|
|
7684
7826
|
catch (error) {
|
|
7685
7827
|
return res.status(error instanceof HttpError ? error.status : 500).json({
|
|
@@ -7911,6 +8053,10 @@ app.post('/tickets/:id/retry', (req, res) => {
|
|
|
7911
8053
|
if (!acceptance.sequenceId) {
|
|
7912
8054
|
throw new Error('Build sequence no longer exists');
|
|
7913
8055
|
}
|
|
8056
|
+
const project = getEffectiveProject(acceptance.ticket);
|
|
8057
|
+
if (!project) {
|
|
8058
|
+
throw new Error('Build project no longer exists');
|
|
8059
|
+
}
|
|
7914
8060
|
transaction.createExecutionRun({
|
|
7915
8061
|
projectId: ticket.project_id,
|
|
7916
8062
|
kind: 'build',
|
|
@@ -7920,6 +8066,9 @@ app.post('/tickets/:id/retry', (req, res) => {
|
|
|
7920
8066
|
{ entityType: 'bundle', entityId: ticket.worktree_bundle_id, relationship: 'context' },
|
|
7921
8067
|
{ entityType: 'build_sequence', entityId: acceptance.sequenceId, relationship: 'context' },
|
|
7922
8068
|
],
|
|
8069
|
+
metadata: {
|
|
8070
|
+
build_execution_provider: project.build_execution_provider ?? 'host',
|
|
8071
|
+
},
|
|
7923
8072
|
initiatedBy: 'user',
|
|
7924
8073
|
retryOfRunId: retrySource?.id ?? null,
|
|
7925
8074
|
eventType: 'build_created',
|
|
@@ -9261,6 +9410,10 @@ export const runExecutionArtifactCleanup = (mode) => {
|
|
|
9261
9410
|
if (mode === 'periodic') {
|
|
9262
9411
|
await resumeInterruptedProjectDeletions();
|
|
9263
9412
|
}
|
|
9413
|
+
const orphanedEnvironments = await reconcileOrphanedExecutionEnvironments();
|
|
9414
|
+
if (orphanedEnvironments.scanned > 0) {
|
|
9415
|
+
console.log(`Reconciled ${orphanedEnvironments.cleaned} orphaned execution environment(s); ${orphanedEnvironments.failed} cleanup(s) retained for retry`);
|
|
9416
|
+
}
|
|
9264
9417
|
await runExclusiveExecutionArtifactMaintenance(async () => {
|
|
9265
9418
|
const intents = await reconcileExecutionArtifactRegistrationIntents({ mode });
|
|
9266
9419
|
const artifacts = await reconcileFinalizedExecutionArtifacts({ emitter: io });
|
|
@@ -9316,8 +9469,10 @@ export const startServer = ({ port = DEFAULT_PORT, host } = {}) => {
|
|
|
9316
9469
|
}
|
|
9317
9470
|
startServerPromise = (async () => {
|
|
9318
9471
|
releaseInterruptedProjectDeletionClaims();
|
|
9319
|
-
await
|
|
9472
|
+
await reconcileProductionExecutionEnvironmentBindings();
|
|
9473
|
+
await reconcileExecutionEnvironments();
|
|
9320
9474
|
await reconcileStartupExecutions({ getGitHubConfig: getGitHubConnectionConfig });
|
|
9475
|
+
await resumeInterruptedProjectDeletions();
|
|
9321
9476
|
const repositoryGraphSchemaExists = db.prepare(`
|
|
9322
9477
|
SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'repository_graph_scans'
|
|
9323
9478
|
`).get();
|