@covro/covro 0.2.1-dev.5 → 0.2.1-dev.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 (133) hide show
  1. package/README.md +12 -4
  2. package/README.zh-CN.md +9 -1
  3. package/dist/backups/factory.js +22 -0
  4. package/dist/backups/factory.js.map +7 -0
  5. package/dist/backups/lock.js +22 -0
  6. package/dist/backups/lock.js.map +7 -0
  7. package/dist/backups/manager.js +170 -0
  8. package/dist/backups/manager.js.map +7 -0
  9. package/dist/backups/restore.js +188 -0
  10. package/dist/backups/restore.js.map +7 -0
  11. package/dist/backups/store.js +274 -0
  12. package/dist/backups/store.js.map +7 -0
  13. package/dist/cli/backup.js +84 -0
  14. package/dist/cli/backup.js.map +7 -0
  15. package/dist/cli/daemon.js +7 -0
  16. package/dist/cli/daemon.js.map +2 -2
  17. package/dist/cli/main.js +35 -5
  18. package/dist/cli/main.js.map +2 -2
  19. package/dist/cli/paths.js.map +2 -2
  20. package/dist/codex/auto-review.js +55 -0
  21. package/dist/codex/auto-review.js.map +2 -2
  22. package/dist/server/db/history.js +60 -0
  23. package/dist/server/db/history.js.map +7 -0
  24. package/dist/server/db/index.js +11 -1
  25. package/dist/server/db/index.js.map +2 -2
  26. package/dist/server/db/migrate.js +8 -18
  27. package/dist/server/db/migrate.js.map +2 -2
  28. package/dist/server/http.js +21 -3
  29. package/dist/server/http.js.map +2 -2
  30. package/dist/server/main.js +14 -3
  31. package/dist/server/main.js.map +2 -2
  32. package/dist/server/project-clones.js +53 -17
  33. package/dist/server/project-clones.js.map +2 -2
  34. package/dist/server/service.js +9 -5
  35. package/dist/server/service.js.map +2 -2
  36. package/dist/shared/backups.js +55 -0
  37. package/dist/shared/backups.js.map +7 -0
  38. package/dist/shared/database.js +15 -0
  39. package/dist/shared/database.js.map +7 -0
  40. package/dist/update-worker.cjs +934 -388
  41. package/dist/updates/files.js +2 -1
  42. package/dist/updates/files.js.map +2 -2
  43. package/dist/updates/transaction.js +3 -24
  44. package/dist/updates/transaction.js.map +2 -2
  45. package/dist/updates/worker.js +69 -19
  46. package/dist/updates/worker.js.map +2 -2
  47. package/dist/web/assets/{abnfDiagram-WEYOIA3C-CwLX554E.js → abnfDiagram-WEYOIA3C-Baw8Q2RL.js} +1 -1
  48. package/dist/web/assets/{arc-DAaDyyqc.js → arc-BvZHXzPr.js} +1 -1
  49. package/dist/web/assets/{architecture-WOLXFQ4H-y6MnEqN0.js → architecture-WOLXFQ4H-DrQ2OxuY.js} +1 -1
  50. package/dist/web/assets/{architectureDiagram-ZHVYKT53-_B_4k-Pp.js → architectureDiagram-ZHVYKT53-D96hX75H.js} +1 -1
  51. package/dist/web/assets/{blockDiagram-RJAE7QA3-C9jZ7FHy.js → blockDiagram-RJAE7QA3-Csce-aWb.js} +1 -1
  52. package/dist/web/assets/{c4Diagram-XDPPPE54-DQAtMvqN.js → c4Diagram-XDPPPE54-Dfu8ZQ6Y.js} +1 -1
  53. package/dist/web/assets/channel-DQhtAfM4.js +1 -0
  54. package/dist/web/assets/{chunk-2E7WHVMD-Bu427yab.js → chunk-2E7WHVMD-Vb63e-lu.js} +1 -1
  55. package/dist/web/assets/{chunk-4EMNKR2T-BrGrBG7B.js → chunk-4EMNKR2T-DrY1P7q3.js} +1 -1
  56. package/dist/web/assets/{chunk-55XCU76K-l4f0OZWA.js → chunk-55XCU76K-D70bjQ9E.js} +1 -1
  57. package/dist/web/assets/{chunk-7S6XSTFO-D7ixF313.js → chunk-7S6XSTFO-CfW90MUC.js} +1 -1
  58. package/dist/web/assets/{chunk-AQDTSKZB-Cesd-BF2.js → chunk-AQDTSKZB-u4KDDGBt.js} +1 -1
  59. package/dist/web/assets/{chunk-DSNLSHJZ-B7dim5uT.js → chunk-DSNLSHJZ-Cax3giJD.js} +1 -1
  60. package/dist/web/assets/{chunk-HAGFOTED-B-f2I7TA.js → chunk-HAGFOTED-BG9UMwzK.js} +1 -1
  61. package/dist/web/assets/{chunk-HNE4Q36P-CoIvaeX6.js → chunk-HNE4Q36P-BNxIfOgZ.js} +1 -1
  62. package/dist/web/assets/{chunk-NQOKRVIF-BybRxR7n.js → chunk-NQOKRVIF-DJ60e0Al.js} +1 -1
  63. package/dist/web/assets/{chunk-UHW7PFBP-CV5WG4tq.js → chunk-UHW7PFBP-C9gHYcjJ.js} +1 -1
  64. package/dist/web/assets/{chunk-VQ5W62QI-BO4AjXi1.js → chunk-VQ5W62QI-TyHPGVfQ.js} +1 -1
  65. package/dist/web/assets/{chunk-WQQL4CDK-CADNDGXO.js → chunk-WQQL4CDK-DeAauheh.js} +1 -1
  66. package/dist/web/assets/{chunk-XXDRQBXY-C6QZT7KW.js → chunk-XXDRQBXY-V-L20Tbi.js} +1 -1
  67. package/dist/web/assets/{chunk-YZO67HFG-Cm6eGReX.js → chunk-YZO67HFG-LV5QVBiU.js} +1 -1
  68. package/dist/web/assets/{chunk-ZAUX2LTX-CUBoGbKg.js → chunk-ZAUX2LTX-CBsBBk7L.js} +1 -1
  69. package/dist/web/assets/{chunk-ZCHMQSOR-B0ImOOtq.js → chunk-ZCHMQSOR-a2_9JHHn.js} +1 -1
  70. package/dist/web/assets/{classDiagram-v2-4MYWR3UA-D5NWZ9vm.js → classDiagram-v2-4MYWR3UA-77eiBCO3.js} +1 -1
  71. package/dist/web/assets/{cose-bilkent-JH36ORCC-BzckEyjA.js → cose-bilkent-JH36ORCC-DDP73pnY.js} +1 -1
  72. package/dist/web/assets/{cynefin-EF2NZ3EQ-Da_J6-Jb.js → cynefin-EF2NZ3EQ-onpnpyxc.js} +1 -1
  73. package/dist/web/assets/{cynefinDiagram-WF24UDRP-b4g_B1A-.js → cynefinDiagram-WF24UDRP-BmLplbnH.js} +1 -1
  74. package/dist/web/assets/{dagre-NK4GIZVX-89H2mfs9.js → dagre-NK4GIZVX-BhaMf_Gx.js} +1 -1
  75. package/dist/web/assets/{diagram-CBK3MWTC-CW4f_P0l.js → diagram-CBK3MWTC-BaalTqFt.js} +1 -1
  76. package/dist/web/assets/{diagram-I5XIIV2D-Cv5Qndgc.js → diagram-I5XIIV2D-4Tdshcyt.js} +1 -1
  77. package/dist/web/assets/{diagram-ODIL2UCW-LrXxeoCt.js → diagram-ODIL2UCW-SlEcZgod.js} +1 -1
  78. package/dist/web/assets/{diagram-PFBEJUXE-uJV2PooB.js → diagram-PFBEJUXE-CosCAXbh.js} +1 -1
  79. package/dist/web/assets/{diagram-RJA3I4VV-DlY0PGRs.js → diagram-RJA3I4VV-HQElVL4B.js} +1 -1
  80. package/dist/web/assets/{diagram-TYUNFSNR-B1KoXBEE.js → diagram-TYUNFSNR-BT2WDc21.js} +1 -1
  81. package/dist/web/assets/{dist-B4eX4BCP.js → dist-CrpGQKqw.js} +1 -1
  82. package/dist/web/assets/{ebnfDiagram-V4P3TTPT-xCvQVbdj.js → ebnfDiagram-V4P3TTPT-BhK6AM0_.js} +1 -1
  83. package/dist/web/assets/{elk-QONTBCTQ-Cl8Hu-Uy.js → elk-QONTBCTQ-CS7DfCnD.js} +1 -1
  84. package/dist/web/assets/{erDiagram-KYQIGQAA-Xp-AvSwE.js → erDiagram-KYQIGQAA-DxVnuqFK.js} +1 -1
  85. package/dist/web/assets/{eventmodeling-K75KTNOO-C0truZGU.js → eventmodeling-K75KTNOO-oC_YeomD.js} +1 -1
  86. package/dist/web/assets/flowDiagram-IUGLLWBU-Bspg0rQz.js +1 -0
  87. package/dist/web/assets/{ganttDiagram-R7GPNTJY-rPaYp-D7.js → ganttDiagram-R7GPNTJY-CquUpiE1.js} +1 -1
  88. package/dist/web/assets/{gitGraph-VSP46ZUC-Bgfpho41.js → gitGraph-VSP46ZUC-BTtGQYsh.js} +1 -1
  89. package/dist/web/assets/{gitGraphDiagram-PDYL7XHY-kDcmuv6k.js → gitGraphDiagram-PDYL7XHY-BsokGXYo.js} +1 -1
  90. package/dist/web/assets/index-B8tsymVC.js +147 -0
  91. package/dist/web/assets/{index-B7tnf28H.css → index-COSho7m2.css} +1 -1
  92. package/dist/web/assets/{info-OHQRW6UA-CAWg5k9R.js → info-OHQRW6UA-CvGN4gWh.js} +1 -1
  93. package/dist/web/assets/{infoDiagram-MVDRKAX5-Cd08ebhn.js → infoDiagram-MVDRKAX5-BF9Rp3BT.js} +1 -1
  94. package/dist/web/assets/{ishikawaDiagram-HPEHV2GE-tAXBLt9k.js → ishikawaDiagram-HPEHV2GE-DtD20ngU.js} +1 -1
  95. package/dist/web/assets/{journeyDiagram-BOSHW7O7-ZgnWqXkg.js → journeyDiagram-BOSHW7O7-gB16trHV.js} +1 -1
  96. package/dist/web/assets/{kanban-definition-FNSA4HC5-BUjtjd-h.js → kanban-definition-FNSA4HC5-D0aKOsE2.js} +1 -1
  97. package/dist/web/assets/{line-DG48HRVK.js → line-BR5dqPmF.js} +1 -1
  98. package/dist/web/assets/{linear-CqnXVCVw.js → linear-OsiQaPpK.js} +1 -1
  99. package/dist/web/assets/{mermaid-parser.core-gIvgB9WK.js → mermaid-parser.core-MEuwYVot.js} +3 -3
  100. package/dist/web/assets/{mermaid.core-C_R7Y1XB.js → mermaid.core-CVKnnz65.js} +4 -4
  101. package/dist/web/assets/{mindmap-definition-6OY57UG3-CwUEEl_y.js → mindmap-definition-6OY57UG3-5aHA-kPJ.js} +1 -1
  102. package/dist/web/assets/{packet-JDAUHWVQ-BrXmpRQ3.js → packet-JDAUHWVQ-uj48AF5r.js} +1 -1
  103. package/dist/web/assets/{pegDiagram-ECIUJNBX-lLApO85Q.js → pegDiagram-ECIUJNBX-BkVIHLBX.js} +1 -1
  104. package/dist/web/assets/{pie-XZMESJXO-C_8kR5WX.js → pie-XZMESJXO-D3hy3nD7.js} +1 -1
  105. package/dist/web/assets/{pieDiagram-GNMPY74T-CawGmJZn.js → pieDiagram-GNMPY74T-CBAqGMEo.js} +1 -1
  106. package/dist/web/assets/{quadrantDiagram-D57K4MC3-Dg6Yq3s_.js → quadrantDiagram-D57K4MC3-C35kvNRB.js} +1 -1
  107. package/dist/web/assets/{radar-ABXABTNO-Bs1xY09D.js → radar-ABXABTNO-3LWE6J2Y.js} +1 -1
  108. package/dist/web/assets/{railroad-I3PHUGI6-Bw_qS6e3.js → railroad-I3PHUGI6-B6Mc9Djl.js} +1 -1
  109. package/dist/web/assets/{railroad-abnf-LNEFI6M7-CQr33CuI.js → railroad-abnf-LNEFI6M7-DJnbwbpn.js} +1 -1
  110. package/dist/web/assets/{railroad-ebnf-DWYD2UWJ-BY9nk5pg.js → railroad-ebnf-DWYD2UWJ-BFXAvY4k.js} +1 -1
  111. package/dist/web/assets/{railroad-peg-JR7BVNR7-CcFsAEI4.js → railroad-peg-JR7BVNR7-JYGb2Oq5.js} +1 -1
  112. package/dist/web/assets/{railroadDiagram-Y72NRBL7-rkZbchmc.js → railroadDiagram-Y72NRBL7-uBIggR0w.js} +1 -1
  113. package/dist/web/assets/{requirementDiagram-EQYSW5RA-CSOcijj5.js → requirementDiagram-EQYSW5RA-CDWglrxJ.js} +1 -1
  114. package/dist/web/assets/{sankeyDiagram-SY24JHO5-E0uo0rRp.js → sankeyDiagram-SY24JHO5-BT16hnTl.js} +1 -1
  115. package/dist/web/assets/{sequenceDiagram-BLEHNHQU-BKWAAcRu.js → sequenceDiagram-BLEHNHQU-eFJ27rVk.js} +1 -1
  116. package/dist/web/assets/{src-F6L8HcEC.js → src-BlOCBHYS.js} +1 -1
  117. package/dist/web/assets/{stateDiagram-v2-A6IESKWZ-BBk2tpPh.js → stateDiagram-v2-A6IESKWZ-CK_s-2Qv.js} +1 -1
  118. package/dist/web/assets/{swimlanes-B3ENRKFQ-CAUrhGwF.js → swimlanes-B3ENRKFQ-WLMrk9Lm.js} +1 -1
  119. package/dist/web/assets/swimlanesDiagram-AYQRV4AK-DmjebfnI.js +8 -0
  120. package/dist/web/assets/{timeline-definition-JXYKGLGB-D0FWj9fa.js → timeline-definition-JXYKGLGB-D0-xZS_V.js} +1 -1
  121. package/dist/web/assets/{treeView-D4JQ5SDB-CkJOmf93.js → treeView-D4JQ5SDB-TTivyB8T.js} +1 -1
  122. package/dist/web/assets/{treemap-SAJKECNS-BSFsardB.js → treemap-SAJKECNS-DtU16wOO.js} +1 -1
  123. package/dist/web/assets/{usecaseDiagram-WPOLBNNX-B2U-2o4g.js → usecaseDiagram-WPOLBNNX-DLFybW0F.js} +1 -1
  124. package/dist/web/assets/{vennDiagram-Q3Y3IDCW-BijTH0fT.js → vennDiagram-Q3Y3IDCW-DRDuYw70.js} +1 -1
  125. package/dist/web/assets/{wardley-7MLQ67FV-DDOa5RzL.js → wardley-7MLQ67FV-tZ-5qrqv.js} +1 -1
  126. package/dist/web/assets/{wardleyDiagram-IVAIDKWA-mbb5GvW5.js → wardleyDiagram-IVAIDKWA-wRKeGCMl.js} +1 -1
  127. package/dist/web/assets/{xychartDiagram-4URNHDU4-DHd60D_Y.js → xychartDiagram-4URNHDU4-B5-k-DHF.js} +1 -1
  128. package/dist/web/index.html +4 -4
  129. package/package.json +10 -3
  130. package/dist/web/assets/channel-ByzMCsOB.js +0 -1
  131. package/dist/web/assets/flowDiagram-IUGLLWBU-T67jQ-T_.js +0 -1
  132. package/dist/web/assets/index-3DUP8YCe.js +0 -142
  133. package/dist/web/assets/swimlanesDiagram-AYQRV4AK-BCnJymLL.js +0 -8
@@ -49,6 +49,7 @@ async function copyDurable(source, target) {
49
49
  export {
50
50
  copyDurable,
51
51
  readJson,
52
- saveJson
52
+ saveJson,
53
+ syncDirectory
53
54
  };
54
55
  //# sourceMappingURL=files.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/updates/files.ts"],
4
- "sourcesContent": ["import { randomUUID } from 'node:crypto';\nimport { dirname } from 'node:path';\nimport { cp, mkdir, open, readFile, rename, rm } from 'node:fs/promises';\nexport async function readJson<T>(filename: string): Promise<T | undefined> {\n try {\n return JSON.parse(await readFile(filename, 'utf8')) as T;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return undefined;\n throw error;\n }\n}\nexport async function saveJson(filename: string, value: unknown) {\n await mkdir(dirname(filename), { recursive: true, mode: 0o700 });\n const temporary = `${filename}.${randomUUID()}.tmp`;\n try {\n const file = await open(temporary, 'wx', 0o600);\n try {\n await file.writeFile(`${JSON.stringify(value, null, 2)}\\n`);\n await file.sync();\n } finally {\n await file.close();\n }\n await rename(temporary, filename);\n await syncDirectory(dirname(filename));\n } finally {\n await rm(temporary, { force: true });\n }\n}\n\nasync function syncDirectory(directory: string) {\n if (process.platform === 'win32') return;\n const handle = await open(directory, 'r');\n try {\n await handle.sync();\n } finally {\n await handle.close();\n }\n}\n\nexport async function copyDurable(source: string, target: string) {\n await cp(source, target);\n const file = await open(target, 'r');\n try {\n await file.sync();\n } finally {\n await file.close();\n }\n await syncDirectory(dirname(target));\n}\n"],
5
- "mappings": "AAAA,SAAS,kBAAkB;AAC3B,SAAS,eAAe;AACxB,SAAS,IAAI,OAAO,MAAM,UAAU,QAAQ,UAAU;AACtD,eAAsB,SAAY,UAA0C;AAC1E,MAAI;AACF,WAAO,KAAK,MAAM,MAAM,SAAS,UAAU,MAAM,CAAC;AAAA,EACpD,SAAS,OAAO;AACd,QAAK,MAAgC,SAAS,SAAU,QAAO;AAC/D,UAAM;AAAA,EACR;AACF;AACA,eAAsB,SAAS,UAAkB,OAAgB;AAC/D,QAAM,MAAM,QAAQ,QAAQ,GAAG,EAAE,WAAW,MAAM,MAAM,IAAM,CAAC;AAC/D,QAAM,YAAY,GAAG,QAAQ,IAAI,WAAW,CAAC;AAC7C,MAAI;AACF,UAAM,OAAO,MAAM,KAAK,WAAW,MAAM,GAAK;AAC9C,QAAI;AACF,YAAM,KAAK,UAAU,GAAG,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AAAA,CAAI;AAC1D,YAAM,KAAK,KAAK;AAAA,IAClB,UAAE;AACA,YAAM,KAAK,MAAM;AAAA,IACnB;AACA,UAAM,OAAO,WAAW,QAAQ;AAChC,UAAM,cAAc,QAAQ,QAAQ,CAAC;AAAA,EACvC,UAAE;AACA,UAAM,GAAG,WAAW,EAAE,OAAO,KAAK,CAAC;AAAA,EACrC;AACF;AAEA,eAAe,cAAc,WAAmB;AAC9C,MAAI,QAAQ,aAAa,QAAS;AAClC,QAAM,SAAS,MAAM,KAAK,WAAW,GAAG;AACxC,MAAI;AACF,UAAM,OAAO,KAAK;AAAA,EACpB,UAAE;AACA,UAAM,OAAO,MAAM;AAAA,EACrB;AACF;AAEA,eAAsB,YAAY,QAAgB,QAAgB;AAChE,QAAM,GAAG,QAAQ,MAAM;AACvB,QAAM,OAAO,MAAM,KAAK,QAAQ,GAAG;AACnC,MAAI;AACF,UAAM,KAAK,KAAK;AAAA,EAClB,UAAE;AACA,UAAM,KAAK,MAAM;AAAA,EACnB;AACA,QAAM,cAAc,QAAQ,MAAM,CAAC;AACrC;",
4
+ "sourcesContent": ["import { randomUUID } from 'node:crypto';\nimport { dirname } from 'node:path';\nimport { cp, mkdir, open, readFile, rename, rm } from 'node:fs/promises';\nexport async function readJson<T>(filename: string): Promise<T | undefined> {\n try {\n return JSON.parse(await readFile(filename, 'utf8')) as T;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return undefined;\n throw error;\n }\n}\nexport async function saveJson(filename: string, value: unknown) {\n await mkdir(dirname(filename), { recursive: true, mode: 0o700 });\n const temporary = `${filename}.${randomUUID()}.tmp`;\n try {\n const file = await open(temporary, 'wx', 0o600);\n try {\n await file.writeFile(`${JSON.stringify(value, null, 2)}\\n`);\n await file.sync();\n } finally {\n await file.close();\n }\n await rename(temporary, filename);\n await syncDirectory(dirname(filename));\n } finally {\n await rm(temporary, { force: true });\n }\n}\n\nexport async function syncDirectory(directory: string) {\n if (process.platform === 'win32') return;\n const handle = await open(directory, 'r');\n try {\n await handle.sync();\n } finally {\n await handle.close();\n }\n}\n\nexport async function copyDurable(source: string, target: string) {\n await cp(source, target);\n const file = await open(target, 'r');\n try {\n await file.sync();\n } finally {\n await file.close();\n }\n await syncDirectory(dirname(target));\n}\n"],
5
+ "mappings": "AAAA,SAAS,kBAAkB;AAC3B,SAAS,eAAe;AACxB,SAAS,IAAI,OAAO,MAAM,UAAU,QAAQ,UAAU;AACtD,eAAsB,SAAY,UAA0C;AAC1E,MAAI;AACF,WAAO,KAAK,MAAM,MAAM,SAAS,UAAU,MAAM,CAAC;AAAA,EACpD,SAAS,OAAO;AACd,QAAK,MAAgC,SAAS,SAAU,QAAO;AAC/D,UAAM;AAAA,EACR;AACF;AACA,eAAsB,SAAS,UAAkB,OAAgB;AAC/D,QAAM,MAAM,QAAQ,QAAQ,GAAG,EAAE,WAAW,MAAM,MAAM,IAAM,CAAC;AAC/D,QAAM,YAAY,GAAG,QAAQ,IAAI,WAAW,CAAC;AAC7C,MAAI;AACF,UAAM,OAAO,MAAM,KAAK,WAAW,MAAM,GAAK;AAC9C,QAAI;AACF,YAAM,KAAK,UAAU,GAAG,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AAAA,CAAI;AAC1D,YAAM,KAAK,KAAK;AAAA,IAClB,UAAE;AACA,YAAM,KAAK,MAAM;AAAA,IACnB;AACA,UAAM,OAAO,WAAW,QAAQ;AAChC,UAAM,cAAc,QAAQ,QAAQ,CAAC;AAAA,EACvC,UAAE;AACA,UAAM,GAAG,WAAW,EAAE,OAAO,KAAK,CAAC;AAAA,EACrC;AACF;AAEA,eAAsB,cAAc,WAAmB;AACrD,MAAI,QAAQ,aAAa,QAAS;AAClC,QAAM,SAAS,MAAM,KAAK,WAAW,GAAG;AACxC,MAAI;AACF,UAAM,OAAO,KAAK;AAAA,EACpB,UAAE;AACA,UAAM,OAAO,MAAM;AAAA,EACrB;AACF;AAEA,eAAsB,YAAY,QAAgB,QAAgB;AAChE,QAAM,GAAG,QAAQ,MAAM;AACvB,QAAM,OAAO,MAAM,KAAK,QAAQ,GAAG;AACnC,MAAI;AACF,UAAM,KAAK,KAAK;AAAA,EAClB,UAAE;AACA,UAAM,KAAK,MAAM;AAAA,EACnB;AACA,QAAM,cAAc,QAAQ,MAAM,CAAC;AACrC;",
6
6
  "names": []
7
7
  }
@@ -1,14 +1,6 @@
1
1
  import { npmPackageName } from "../shared/package.js";
2
- import { mkdir, rename, rm, stat } from "node:fs/promises";
2
+ import { rename, rm } from "node:fs/promises";
3
3
  import { dirname, join } from "node:path";
4
- import { copyDurable, saveJson } from "./files.js";
5
- const exists = async (path) => stat(path).then(
6
- () => true,
7
- (error) => {
8
- if (error.code === "ENOENT") return false;
9
- throw error;
10
- }
11
- );
12
4
  async function activateUpdate(paths, effects) {
13
5
  let stopped = false;
14
6
  let moved = false;
@@ -20,13 +12,7 @@ async function activateUpdate(paths, effects) {
20
12
  await effects.phase("stopping", "\u5DF2\u5173\u95ED\u65B0\u4EFB\u52A1\u5165\u53E3\uFF0C\u6B63\u5728\u505C\u6B62\u65E7\u670D\u52A1\u5E76\u5907\u4EFD\u6570\u636E");
21
13
  stopped = true;
22
14
  await effects.stop();
23
- await mkdir(paths.backup, { recursive: true, mode: 448 });
24
- for (const name of ["app.sqlite", "app.sqlite-wal", "app.sqlite-shm"]) {
25
- if (await exists(join(paths.dataDir, name)))
26
- await copyDurable(join(paths.dataDir, name), join(paths.backup, name));
27
- }
28
- await copyDurable(paths.config, join(paths.backup, "config.json"));
29
- await saveJson(join(paths.backup, "snapshot.json"), { complete: true });
15
+ await effects.backup();
30
16
  backedUp = true;
31
17
  await rename(paths.root, paths.previous);
32
18
  moved = true;
@@ -50,14 +36,7 @@ async function activateUpdate(paths, effects) {
50
36
  await rm(paths.root, { recursive: true, force: true });
51
37
  await rename(paths.previous, paths.root);
52
38
  }
53
- if (backedUp) {
54
- for (const name of ["app.sqlite", "app.sqlite-wal", "app.sqlite-shm"]) {
55
- await rm(join(paths.dataDir, name), { force: true });
56
- if (await exists(join(paths.backup, name)))
57
- await copyDurable(join(paths.backup, name), join(paths.dataDir, name));
58
- }
59
- await copyDurable(join(paths.backup, "config.json"), paths.config);
60
- }
39
+ if (backedUp) await effects.restore();
61
40
  await effects.phase(
62
41
  "rolledBack",
63
42
  `\u65B0\u7248\u542F\u52A8\u5931\u8D25\uFF0C\u5DF2\u6062\u590D\u65E7\u7248\uFF1A${error instanceof Error ? error.message : String(error)}`
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/updates/transaction.ts"],
4
- "sourcesContent": ["import { npmPackageName } from '../shared/package.js';\nimport { mkdir, rename, rm, stat } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport type { UpdateRun } from '../shared/updates.js';\nimport { copyDurable, saveJson } from './files.js';\n\nexport interface TransactionPaths {\n root: string;\n prefix: string;\n candidate: string;\n previous: string;\n backup: string;\n dataDir: string;\n config: string;\n}\nexport interface UpdateEffects {\n waitForIdle(): Promise<void>;\n stop(): Promise<void>;\n start(candidate: boolean): Promise<void>;\n verify(): Promise<void>;\n commit(): Promise<void>;\n hasCommitted?(): Promise<boolean>;\n resume?(): Promise<void>;\n phase(phase: UpdateRun['phase'], message: string): Promise<void>;\n}\nconst exists = async (path: string) =>\n stat(path).then(\n () => true,\n (error: NodeJS.ErrnoException) => {\n if (error.code === 'ENOENT') return false;\n throw error;\n },\n );\n\n/** Rollback is confined to admission: no new business writes are accepted before commit. */\nexport async function activateUpdate(paths: TransactionPaths, effects: UpdateEffects) {\n let stopped = false;\n let moved = false;\n let backedUp = false;\n let committed = false;\n try {\n await effects.phase('waiting', '\u5019\u9009\u5305\u5DF2\u51C6\u5907\u597D\uFF0C\u7B49\u5F85\u6240\u6709\u4EFB\u52A1\u3001\u5BA1\u6279\u4E0E\u5F85\u6838\u5BF9\u64CD\u4F5C\u7ED3\u675F');\n await effects.waitForIdle();\n await effects.phase('stopping', '\u5DF2\u5173\u95ED\u65B0\u4EFB\u52A1\u5165\u53E3\uFF0C\u6B63\u5728\u505C\u6B62\u65E7\u670D\u52A1\u5E76\u5907\u4EFD\u6570\u636E');\n // stop may fail after the process has already exited; recovery must restart the old service.\n stopped = true;\n await effects.stop();\n await mkdir(paths.backup, { recursive: true, mode: 0o700 });\n for (const name of ['app.sqlite', 'app.sqlite-wal', 'app.sqlite-shm']) {\n if (await exists(join(paths.dataDir, name)))\n await copyDurable(join(paths.dataDir, name), join(paths.backup, name));\n }\n await copyDurable(paths.config, join(paths.backup, 'config.json'));\n await saveJson(join(paths.backup, 'snapshot.json'), { complete: true });\n backedUp = true;\n await rename(paths.root, paths.previous);\n moved = true;\n await rename(paths.candidate, paths.root);\n await effects.phase('verifying', '\u6B63\u5728\u542F\u52A8\u65B0\u7248\u3001\u8FC1\u79FB\u6570\u636E\u5E93\u5E76\u9A8C\u8BC1\uFF1B\u4E1A\u52A1\u5199\u5165\u4FDD\u6301\u6682\u505C');\n await effects.start(true);\n await effects.verify();\n await effects.commit();\n committed = true;\n // The new gateway persists the commit before admitting requests. Never restore its data later.\n return;\n } catch (error) {\n if (committed || (await effects.hasCommitted?.())) return;\n if (!stopped) {\n await effects.resume?.();\n await effects.phase('failed', error instanceof Error ? error.message : String(error));\n throw error;\n }\n try {\n await effects.stop();\n if (moved) {\n await rm(paths.root, { recursive: true, force: true });\n await rename(paths.previous, paths.root);\n }\n if (backedUp) {\n for (const name of ['app.sqlite', 'app.sqlite-wal', 'app.sqlite-shm']) {\n await rm(join(paths.dataDir, name), { force: true });\n if (await exists(join(paths.backup, name)))\n await copyDurable(join(paths.backup, name), join(paths.dataDir, name));\n }\n await copyDurable(join(paths.backup, 'config.json'), paths.config);\n }\n await effects.phase(\n 'rolledBack',\n `\u65B0\u7248\u542F\u52A8\u5931\u8D25\uFF0C\u5DF2\u6062\u590D\u65E7\u7248\uFF1A${error instanceof Error ? error.message : String(error)}`,\n );\n await effects.start(false);\n } catch (recovery) {\n await effects.phase(\n 'failed',\n `\u5347\u7EA7\u5931\u8D25\u4E14\u6062\u590D\u5C1A\u672A\u5B8C\u6210\uFF1B\u4FDD\u7559\u5907\u4EFD ${paths.backup}\u3002${String(error)}\uFF1B\u6062\u590D\uFF1A${String(recovery)}`,\n );\n throw recovery;\n }\n throw error;\n }\n}\n\nexport function transactionPaths(\n root: string,\n id: string,\n dataDir: string,\n config: string,\n backup: string,\n): TransactionPaths {\n const prefix = join(dirname(root), `.covro-stage-${id}`);\n return {\n root,\n prefix,\n candidate: join(\n prefix,\n process.platform === 'win32' ? 'node_modules' : 'lib/node_modules',\n npmPackageName,\n ),\n previous: join(dirname(root), `.covro-previous-${id}`),\n backup,\n dataDir,\n config,\n };\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { npmPackageName } from '../shared/package.js';\nimport { rename, rm } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport type { UpdateRun } from '../shared/updates.js';\n\nexport interface TransactionPaths {\n root: string;\n prefix: string;\n candidate: string;\n previous: string;\n backup: string;\n dataDir: string;\n config: string;\n}\nexport interface UpdateEffects {\n waitForIdle(): Promise<void>;\n backup(): Promise<void>;\n restore(): Promise<void>;\n stop(): Promise<void>;\n start(candidate: boolean): Promise<void>;\n verify(): Promise<void>;\n commit(): Promise<void>;\n hasCommitted?(): Promise<boolean>;\n resume?(): Promise<void>;\n phase(phase: UpdateRun['phase'], message: string): Promise<void>;\n}\n/** Rollback is confined to admission: no new business writes are accepted before commit. */\nexport async function activateUpdate(paths: TransactionPaths, effects: UpdateEffects) {\n let stopped = false;\n let moved = false;\n let backedUp = false;\n let committed = false;\n try {\n await effects.phase('waiting', '\u5019\u9009\u5305\u5DF2\u51C6\u5907\u597D\uFF0C\u7B49\u5F85\u6240\u6709\u4EFB\u52A1\u3001\u5BA1\u6279\u4E0E\u5F85\u6838\u5BF9\u64CD\u4F5C\u7ED3\u675F');\n await effects.waitForIdle();\n await effects.phase('stopping', '\u5DF2\u5173\u95ED\u65B0\u4EFB\u52A1\u5165\u53E3\uFF0C\u6B63\u5728\u505C\u6B62\u65E7\u670D\u52A1\u5E76\u5907\u4EFD\u6570\u636E');\n // stop may fail after the process has already exited; recovery must restart the old service.\n stopped = true;\n await effects.stop();\n await effects.backup();\n backedUp = true;\n await rename(paths.root, paths.previous);\n moved = true;\n await rename(paths.candidate, paths.root);\n await effects.phase('verifying', '\u6B63\u5728\u542F\u52A8\u65B0\u7248\u3001\u8FC1\u79FB\u6570\u636E\u5E93\u5E76\u9A8C\u8BC1\uFF1B\u4E1A\u52A1\u5199\u5165\u4FDD\u6301\u6682\u505C');\n await effects.start(true);\n await effects.verify();\n await effects.commit();\n committed = true;\n // The new gateway persists the commit before admitting requests. Never restore its data later.\n return;\n } catch (error) {\n if (committed || (await effects.hasCommitted?.())) return;\n if (!stopped) {\n await effects.resume?.();\n await effects.phase('failed', error instanceof Error ? error.message : String(error));\n throw error;\n }\n try {\n await effects.stop();\n if (moved) {\n await rm(paths.root, { recursive: true, force: true });\n await rename(paths.previous, paths.root);\n }\n if (backedUp) await effects.restore();\n await effects.phase(\n 'rolledBack',\n `\u65B0\u7248\u542F\u52A8\u5931\u8D25\uFF0C\u5DF2\u6062\u590D\u65E7\u7248\uFF1A${error instanceof Error ? error.message : String(error)}`,\n );\n await effects.start(false);\n } catch (recovery) {\n await effects.phase(\n 'failed',\n `\u5347\u7EA7\u5931\u8D25\u4E14\u6062\u590D\u5C1A\u672A\u5B8C\u6210\uFF1B\u4FDD\u7559\u5907\u4EFD ${paths.backup}\u3002${String(error)}\uFF1B\u6062\u590D\uFF1A${String(recovery)}`,\n );\n throw recovery;\n }\n throw error;\n }\n}\n\nexport function transactionPaths(\n root: string,\n id: string,\n dataDir: string,\n config: string,\n backup: string,\n): TransactionPaths {\n const prefix = join(dirname(root), `.covro-stage-${id}`);\n return {\n root,\n prefix,\n candidate: join(\n prefix,\n process.platform === 'win32' ? 'node_modules' : 'lib/node_modules',\n npmPackageName,\n ),\n previous: join(dirname(root), `.covro-previous-${id}`),\n backup,\n dataDir,\n config,\n };\n}\n"],
5
+ "mappings": "AAAA,SAAS,sBAAsB;AAC/B,SAAS,QAAQ,UAAU;AAC3B,SAAS,SAAS,YAAY;AAyB9B,eAAsB,eAAe,OAAyB,SAAwB;AACpF,MAAI,UAAU;AACd,MAAI,QAAQ;AACZ,MAAI,WAAW;AACf,MAAI,YAAY;AAChB,MAAI;AACF,UAAM,QAAQ,MAAM,WAAW,wJAA2B;AAC1D,UAAM,QAAQ,YAAY;AAC1B,UAAM,QAAQ,MAAM,YAAY,gIAAuB;AAEvD,cAAU;AACV,UAAM,QAAQ,KAAK;AACnB,UAAM,QAAQ,OAAO;AACrB,eAAW;AACX,UAAM,OAAO,MAAM,MAAM,MAAM,QAAQ;AACvC,YAAQ;AACR,UAAM,OAAO,MAAM,WAAW,MAAM,IAAI;AACxC,UAAM,QAAQ,MAAM,aAAa,kJAA0B;AAC3D,UAAM,QAAQ,MAAM,IAAI;AACxB,UAAM,QAAQ,OAAO;AACrB,UAAM,QAAQ,OAAO;AACrB,gBAAY;AAEZ;AAAA,EACF,SAAS,OAAO;AACd,QAAI,aAAc,MAAM,QAAQ,eAAe,EAAI;AACnD,QAAI,CAAC,SAAS;AACZ,YAAM,QAAQ,SAAS;AACvB,YAAM,QAAQ,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AACpF,YAAM;AAAA,IACR;AACA,QAAI;AACF,YAAM,QAAQ,KAAK;AACnB,UAAI,OAAO;AACT,cAAM,GAAG,MAAM,MAAM,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AACrD,cAAM,OAAO,MAAM,UAAU,MAAM,IAAI;AAAA,MACzC;AACA,UAAI,SAAU,OAAM,QAAQ,QAAQ;AACpC,YAAM,QAAQ;AAAA,QACZ;AAAA,QACA,iFAAgB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACxE;AACA,YAAM,QAAQ,MAAM,KAAK;AAAA,IAC3B,SAAS,UAAU;AACjB,YAAM,QAAQ;AAAA,QACZ;AAAA,QACA,oGAAoB,MAAM,MAAM,SAAI,OAAO,KAAK,CAAC,2BAAO,OAAO,QAAQ,CAAC;AAAA,MAC1E;AACA,YAAM;AAAA,IACR;AACA,UAAM;AAAA,EACR;AACF;AAEO,SAAS,iBACd,MACA,IACA,SACA,QACA,QACkB;AAClB,QAAM,SAAS,KAAK,QAAQ,IAAI,GAAG,gBAAgB,EAAE,EAAE;AACvD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,WAAW;AAAA,MACT;AAAA,MACA,QAAQ,aAAa,UAAU,iBAAiB;AAAA,MAChD;AAAA,IACF;AAAA,IACA,UAAU,KAAK,QAAQ,IAAI,GAAG,mBAAmB,EAAE,EAAE;AAAA,IACrD;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
@@ -1,3 +1,8 @@
1
+ import { BackupStore, backupDirectory, verifyLegacySnapshot } from "../backups/store.js";
2
+ import { acquireMaintenanceLock } from "../backups/lock.js";
3
+ import { acquireInstanceLock } from "../server/instance-lock.js";
4
+ import { inspectDatabase, readMigrations } from "../server/db/history.js";
5
+ import { databaseCompatibilitySchema } from "../shared/database.js";
1
6
  import { npmPackageName } from "../shared/package.js";
2
7
  import {
3
8
  codexCompatibilitySchema,
@@ -6,8 +11,7 @@ import {
6
11
  import { execFile } from "node:child_process";
7
12
  import { promisify } from "node:util";
8
13
  import { createRequire } from "node:module";
9
- import { createHash } from "node:crypto";
10
- import { access, readFile, mkdir, readdir, rm, rename } from "node:fs/promises";
14
+ import { access, mkdir, readdir, rm, rename } from "node:fs/promises";
11
15
  import { constants } from "node:fs";
12
16
  import { dirname, join } from "node:path";
13
17
  import { setTimeout } from "node:timers/promises";
@@ -50,20 +54,14 @@ async function verifyMigrations(context, candidate) {
50
54
  }
51
55
  const db = new Sqlite(filename, { readonly: true, fileMustExist: true });
52
56
  try {
53
- const table = db.prepare("SELECT name FROM sqlite_master WHERE name = '__drizzle_migrations'").get();
54
- if (!table) return;
55
- const applied = db.prepare("SELECT hash FROM __drizzle_migrations ORDER BY created_at").all();
56
- const journal = JSON.parse(
57
- await readFile(join(candidate, "dist/drizzle/meta/_journal.json"), "utf8")
58
- );
59
- const hashes = await Promise.all(
60
- journal.entries.map(async (entry) => {
61
- if (!/^[a-zA-Z0-9_-]+$/.test(entry.tag)) throw new Error("\u5019\u9009\u5305\u5305\u542B\u65E0\u6548\u8FC1\u79FB\u8DEF\u5F84");
62
- return createHash("sha256").update(await readFile(join(candidate, "dist/drizzle", `${entry.tag}.sql`))).digest("hex");
63
- })
64
- );
65
- if (applied.some((entry, i) => entry.hash !== hashes[i]))
66
- throw new Error("\u76EE\u6807\u7248\u672C\u4E0D\u517C\u5BB9\u5F53\u524D\u6570\u636E\u5E93\u8FC1\u79FB\u5386\u53F2\u3002\u8BF7\u7B49\u5F85\u517C\u5BB9\u7248\u672C\uFF0C\u6216\u4F7F\u7528\u72EC\u7ACB\u6D4B\u8BD5\u6570\u636E\u76EE\u5F55\u3002");
57
+ const migrations = readMigrations(join(candidate, "dist/drizzle"));
58
+ const metadata = await readJson(join(candidate, "package.json"));
59
+ if (metadata?.covroDatabase) {
60
+ const contract = databaseCompatibilitySchema.parse(metadata.covroDatabase);
61
+ if (contract.schemaVersion !== migrations.length)
62
+ throw new Error("\u76EE\u6807\u7248\u672C\u7684 Schema \u58F0\u660E\u4E0E\u8FC1\u79FB\u4E0D\u4E00\u81F4");
63
+ }
64
+ inspectDatabase(db, migrations);
67
65
  } finally {
68
66
  db.close();
69
67
  }
@@ -90,10 +88,40 @@ async function worker(directory) {
90
88
  record.id,
91
89
  context.dataDir,
92
90
  context.location.config,
93
- join(directory, `backup-${record.id}`)
91
+ join(backupDirectory(context.location.home, context.dataDir), record.id)
92
+ );
93
+ let releaseMaintenance;
94
+ let releaseData;
95
+ const previousMetadata = await readJson(
96
+ join(paths.previous, "package.json")
97
+ );
98
+ const originalRoot = previousMetadata?.version === record.from ? paths.previous : context.root;
99
+ const originalMetadata = await readJson(join(originalRoot, "package.json"));
100
+ const Sqlite = createRequire(join(originalRoot, "package.json"))(
101
+ "better-sqlite3"
94
102
  );
103
+ const migrations = readMigrations(join(originalRoot, "dist/drizzle"));
104
+ const backups = new BackupStore({
105
+ directory: backupDirectory(context.location.home, context.dataDir),
106
+ config: paths.config,
107
+ dataDir: paths.dataDir,
108
+ appVersion: record.from,
109
+ commit: originalMetadata?.covroCommit,
110
+ contract: databaseCompatibilitySchema.parse(
111
+ originalMetadata?.covroDatabase ?? {
112
+ schemaVersion: migrations.length,
113
+ minRestorableSchemaVersion: 1,
114
+ backupFormatVersion: 1
115
+ }
116
+ ),
117
+ Sqlite,
118
+ migrations
119
+ });
95
120
  try {
96
121
  if (process.argv[3] === "--repair") {
122
+ releaseMaintenance = await acquireMaintenanceLock(context.dataDir);
123
+ if (!await readJson(join(paths.backup, "snapshot.json")))
124
+ paths.backup = join(directory, `backup-${record.id}`);
97
125
  const active = await control(context.location, "status").catch(
98
126
  (error) => {
99
127
  if (isNotRunning(error)) return void 0;
@@ -111,8 +139,14 @@ async function worker(directory) {
111
139
  throw new Error("\u65E7\u670D\u52A1\u5DF2\u6062\u590D\u4E1A\u52A1\u5199\u5165\uFF1B\u62D2\u7EDD\u7528\u5347\u7EA7\u524D\u5FEB\u7167\u8986\u76D6\u73B0\u6709\u6570\u636E\uFF0C\u8BF7\u4FDD\u7559\u73B0\u573A\u68C0\u67E5\u3002");
112
140
  if (previous.name !== npmPackageName || previous.version !== record.from)
113
141
  throw new Error("\u65E7\u7248\u5907\u4EFD\u8EAB\u4EFD\u4E0D\u5339\u914D");
114
- const snapshot = await readJson(join(paths.backup, "snapshot.json"));
115
- if (!snapshot?.complete) throw new Error("\u6570\u636E\u5E93\u5907\u4EFD\u4E0D\u5B8C\u6574\uFF0C\u4FDD\u7559\u5168\u90E8\u73B0\u573A\u4F9B\u68C0\u67E5");
142
+ const snapshot = await readJson(
143
+ join(paths.backup, "snapshot.json")
144
+ );
145
+ if (snapshot?.formatVersion === 1) {
146
+ const verified = await backups.verify(record.id);
147
+ if (verified.appVersion !== record.from || verified.protectedBy !== record.id || verified.configPath !== paths.config || verified.dataDir !== paths.dataDir)
148
+ throw new Error("\u5907\u4EFD\u8EAB\u4EFD\u4E0D\u5339\u914D");
149
+ } else await verifyLegacySnapshot(paths.backup, Sqlite, join(originalRoot, "dist/drizzle"));
116
150
  } else {
117
151
  const original = await readJson(
118
152
  join(paths.root, "package.json")
@@ -125,6 +159,7 @@ async function worker(directory) {
125
159
  if (!admission.ready) throw new Error("\u4ECD\u6709\u4EFB\u52A1\u3001\u5BA1\u6279\u6216\u5F85\u6838\u5BF9\u64CD\u4F5C\uFF0C\u4E0D\u80FD\u6062\u590D\u65E7\u5B89\u88C5");
126
160
  }
127
161
  await stopService(context);
162
+ releaseData = await acquireInstanceLock(context.dataDir);
128
163
  if (previous) {
129
164
  await rm(paths.root, { recursive: true, force: true });
130
165
  await rename(paths.previous, paths.root);
@@ -145,6 +180,8 @@ async function worker(directory) {
145
180
  throw new Error("\u672A\u627E\u5230\u5B8C\u6574\u7684\u4E0A\u4E00\u7248\u672C\u5B89\u88C5");
146
181
  await update("rolledBack", "\u5DF2\u6062\u590D\u4E0A\u6B21\u672A\u5B8C\u6210\u7684\u5347\u7EA7\uFF0C\u6B63\u5728\u542F\u52A8\u4E0A\u4E00\u7248\u672C");
147
182
  try {
183
+ await releaseData?.();
184
+ releaseData = void 0;
148
185
  await startService(context);
149
186
  await verifyRestoredService(context, record.from);
150
187
  await update("rolledBack", "\u5DF2\u6062\u590D\u4E0A\u6B21\u672A\u5B8C\u6210\u7684\u5347\u7EA7\uFF0C\u4E0A\u4E00\u7248\u672C\u5DF2\u5C31\u7EEA");
@@ -216,7 +253,16 @@ async function worker(directory) {
216
253
  { timeout: 3e4 }
217
254
  );
218
255
  await verifyMigrations(context, paths.candidate);
256
+ releaseMaintenance = await acquireMaintenanceLock(context.dataDir);
219
257
  await activateUpdate(paths, {
258
+ backup: async () => {
259
+ releaseData = await acquireInstanceLock(context.dataDir);
260
+ await backups.create({ id: record.id, trigger: "preUpgrade", protectedBy: record.id });
261
+ },
262
+ restore: async () => {
263
+ releaseData ??= await acquireInstanceLock(context.dataDir);
264
+ await backups.restoreFiles(record.id);
265
+ },
220
266
  phase: update,
221
267
  waitForIdle: async () => {
222
268
  for (; ; ) {
@@ -235,6 +281,8 @@ async function worker(directory) {
235
281
  },
236
282
  stop: () => stopService(context),
237
283
  start: async (candidate2) => {
284
+ await releaseData?.();
285
+ releaseData = void 0;
238
286
  await startService(context);
239
287
  if (!candidate2) await verifyRestoredService(context, record.from);
240
288
  },
@@ -277,6 +325,8 @@ async function worker(directory) {
277
325
  console.error(message(error));
278
326
  process.exitCode = record.committed || record.phase === "rolledBack" ? 0 : 1;
279
327
  } finally {
328
+ await releaseData?.();
329
+ await releaseMaintenance?.();
280
330
  await release();
281
331
  if (record.phase === "succeeded" || record.phase === "rolledBack") {
282
332
  await rm(paths.prefix, { recursive: true, force: true });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/updates/worker.ts"],
4
- "sourcesContent": ["import { npmPackageName } from '../shared/package.js';\nimport {\n codexCompatibilitySchema,\n requireCodexCompatibility,\n} from '../shared/codex-compatibility.js';\n// Bundled with its pure JavaScript dependencies and copied outside the installation before launch.\nimport { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { createRequire } from 'node:module';\nimport { createHash } from 'node:crypto';\nimport { access, readFile, mkdir, readdir, rm, rename } from 'node:fs/promises';\nimport { constants } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { setTimeout } from 'node:timers/promises';\nimport lockfile from 'proper-lockfile';\nimport type Database from 'better-sqlite3';\nimport type { UpdateRun } from '../shared/updates.js';\nimport type { UpdateContext } from './manager.js';\nimport { control, isNotRunning } from '../cli/control.js';\nimport { startBackground, stopBackground } from '../cli/background.js';\nimport { copyDurable, readJson, saveJson } from './files.js';\nimport { activateUpdate, transactionPaths } from './transaction.js';\nimport { inspectInstallation, registry } from './registry.js';\n\nconst exec = promisify(execFile);\nconst message = (error: unknown) => (error instanceof Error ? error.message : String(error));\ntype DaemonStatus = {\n version: string;\n pid: number;\n maintenance?: boolean;\n codexVersion?: string | null;\n codexReady?: boolean;\n};\n\nasync function startService(context: UpdateContext) {\n // Shared with `covro start`: never inherit a Background security session on macOS.\n // Activation is checked from the durable update record by the daemon.\n await startBackground(context.location, join(context.root, 'bin/covro.mjs'));\n}\nasync function stopService(context: UpdateContext) {\n await stopBackground(context.location);\n}\n\nasync function verifyRestoredService(context: UpdateContext, version: string) {\n for (let attempt = 0; attempt < 240; attempt++) {\n try {\n const restored = await control<DaemonStatus>(context.location, 'status');\n if (restored.version !== version || restored.maintenance)\n throw new Error('\u65E7\u7248\u6062\u590D\u8EAB\u4EFD\u4E0D\u5339\u914D');\n return;\n } catch (error) {\n if (attempt === 239) throw error;\n }\n await setTimeout(250);\n }\n}\n\nasync function verifyMigrations(context: UpdateContext, candidate: string) {\n // Loading the existing native addon happens before any package path is replaced.\n const require = createRequire(join(context.root, 'package.json'));\n const Sqlite = require('better-sqlite3') as typeof Database;\n const filename = join(context.dataDir, 'app.sqlite');\n try {\n await access(filename);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return;\n throw error;\n }\n const db = new Sqlite(filename, { readonly: true, fileMustExist: true });\n try {\n const table = db\n .prepare(\"SELECT name FROM sqlite_master WHERE name = '__drizzle_migrations'\")\n .get();\n if (!table) return;\n const applied = db\n .prepare('SELECT hash FROM __drizzle_migrations ORDER BY created_at')\n .all() as { hash: string }[];\n const journal = JSON.parse(\n await readFile(join(candidate, 'dist/drizzle/meta/_journal.json'), 'utf8'),\n ) as { entries: { tag: string }[] };\n const hashes = await Promise.all(\n journal.entries.map(async (entry) => {\n if (!/^[a-zA-Z0-9_-]+$/.test(entry.tag)) throw new Error('\u5019\u9009\u5305\u5305\u542B\u65E0\u6548\u8FC1\u79FB\u8DEF\u5F84');\n return createHash('sha256')\n .update(await readFile(join(candidate, 'dist/drizzle', `${entry.tag}.sql`)))\n .digest('hex');\n }),\n );\n if (applied.some((entry, i) => entry.hash !== hashes[i]))\n throw new Error('\u76EE\u6807\u7248\u672C\u4E0D\u517C\u5BB9\u5F53\u524D\u6570\u636E\u5E93\u8FC1\u79FB\u5386\u53F2\u3002\u8BF7\u7B49\u5F85\u517C\u5BB9\u7248\u672C\uFF0C\u6216\u4F7F\u7528\u72EC\u7ACB\u6D4B\u8BD5\u6570\u636E\u76EE\u5F55\u3002');\n } finally {\n db.close();\n }\n}\n\nasync function worker(directory: string) {\n await mkdir(directory, { recursive: true, mode: 0o700 });\n const release = await lockfile.lock(directory, {\n stale: 10_000,\n update: 2_000,\n retries: { retries: 30, minTimeout: 100, maxTimeout: 500 },\n });\n let record = await readJson<UpdateRun>(join(directory, 'run.json'));\n const context = await readJson<UpdateContext>(join(directory, 'context.json'));\n if (!record || !context) {\n await release();\n throw new Error('\u7F3A\u5C11\u5347\u7EA7\u8BB0\u5F55');\n }\n const update = async (phase: UpdateRun['phase'], detail: string) => {\n record = { ...record!, phase, message: detail, updatedAt: Date.now() };\n await saveJson(join(directory, 'run.json'), record);\n };\n const paths = transactionPaths(\n context.root,\n record.id,\n context.dataDir,\n context.location.config,\n join(directory, `backup-${record.id}`),\n );\n try {\n if (process.argv[3] === '--repair') {\n const active = await control<DaemonStatus>(context.location, 'status').catch(\n (error: unknown) => {\n if (isNotRunning(error)) return undefined;\n throw error;\n },\n );\n if (record.committed) return;\n if (active && !active.maintenance && active.version !== record.from)\n throw new Error('\u5F53\u524D\u670D\u52A1\u53EF\u80FD\u5DF2\u63A5\u53D7\u65B0\u7248\u4E1A\u52A1\u6570\u636E\uFF1B\u62D2\u7EDD\u6062\u590D\u65E7\u5FEB\u7167\uFF0C\u8BF7\u4F7F\u7528\u517C\u5BB9\u7248\u672C\u68C0\u67E5\u3002');\n const previous = await readJson<{ version: string; name: string }>(\n join(paths.previous, 'package.json'),\n );\n if (previous) {\n if (active && !active.maintenance)\n throw new Error('\u65E7\u670D\u52A1\u5DF2\u6062\u590D\u4E1A\u52A1\u5199\u5165\uFF1B\u62D2\u7EDD\u7528\u5347\u7EA7\u524D\u5FEB\u7167\u8986\u76D6\u73B0\u6709\u6570\u636E\uFF0C\u8BF7\u4FDD\u7559\u73B0\u573A\u68C0\u67E5\u3002');\n if (previous.name !== npmPackageName || previous.version !== record.from)\n throw new Error('\u65E7\u7248\u5907\u4EFD\u8EAB\u4EFD\u4E0D\u5339\u914D');\n const snapshot = await readJson<{ complete: boolean }>(join(paths.backup, 'snapshot.json'));\n if (!snapshot?.complete) throw new Error('\u6570\u636E\u5E93\u5907\u4EFD\u4E0D\u5B8C\u6574\uFF0C\u4FDD\u7559\u5168\u90E8\u73B0\u573A\u4F9B\u68C0\u67E5');\n } else {\n const original = await readJson<{ name: string; version: string }>(\n join(paths.root, 'package.json'),\n );\n if (original?.name !== npmPackageName || original.version !== record.from)\n throw new Error('\u672A\u627E\u5230\u5B8C\u6574\u7684\u4E0A\u4E00\u7248\u672C\u5B89\u88C5');\n }\n if (active && !active.maintenance) {\n const admission = await control<{ ready: boolean }>(context.location, 'prepare-update');\n if (!admission.ready) throw new Error('\u4ECD\u6709\u4EFB\u52A1\u3001\u5BA1\u6279\u6216\u5F85\u6838\u5BF9\u64CD\u4F5C\uFF0C\u4E0D\u80FD\u6062\u590D\u65E7\u5B89\u88C5');\n }\n await stopService(context);\n if (previous) {\n await rm(paths.root, { recursive: true, force: true });\n await rename(paths.previous, paths.root);\n for (const name of ['app.sqlite', 'app.sqlite-wal', 'app.sqlite-shm']) {\n await rm(join(paths.dataDir, name), { force: true });\n try {\n await copyDurable(join(paths.backup, name), join(paths.dataDir, name));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n }\n }\n await copyDurable(join(paths.backup, 'config.json'), paths.config);\n }\n const restored = await readJson<{ name: string; version: string }>(\n join(paths.root, 'package.json'),\n );\n if (restored?.name !== npmPackageName || restored.version !== record.from)\n throw new Error('\u672A\u627E\u5230\u5B8C\u6574\u7684\u4E0A\u4E00\u7248\u672C\u5B89\u88C5');\n await update('rolledBack', '\u5DF2\u6062\u590D\u4E0A\u6B21\u672A\u5B8C\u6210\u7684\u5347\u7EA7\uFF0C\u6B63\u5728\u542F\u52A8\u4E0A\u4E00\u7248\u672C');\n try {\n await startService(context);\n await verifyRestoredService(context, record.from);\n await update('rolledBack', '\u5DF2\u6062\u590D\u4E0A\u6B21\u672A\u5B8C\u6210\u7684\u5347\u7EA7\uFF0C\u4E0A\u4E00\u7248\u672C\u5DF2\u5C31\u7EEA');\n } catch (error) {\n await update('failed', `\u65E7\u7248\u6062\u590D\u542F\u52A8\u5931\u8D25\uFF0C\u4FDD\u7559\u5907\u4EFD\uFF1A${message(error)}`);\n throw error;\n }\n return;\n }\n const reason = await inspectInstallation(context.root);\n if (reason) throw new Error(reason);\n // A second managed configuration must be stopped before replacing their shared npm package.\n for (const key of await readdir(join(context.location.home, 'instances'))) {\n if (key === context.location.key) continue;\n const instance = await readJson<{ root: string; config: string; socket: string }>(\n join(context.location.home, 'instances', key, 'instance.json'),\n );\n if (instance?.root !== context.root) continue;\n try {\n await control({ ...context.location, socket: instance.socket }, 'status');\n throw new Error('\u540C\u4E00 npm \u5B89\u88C5\u8FD8\u6709\u5176\u4ED6 Covro \u5B9E\u4F8B\uFF0C\u8BF7\u5148\u505C\u6B62\u5176\u4ED6\u5B9E\u4F8B\u518D\u5347\u7EA7\u3002');\n } catch (error) {\n if (!isNotRunning(error)) throw error;\n }\n }\n await access(dirname(context.root), constants.W_OK);\n // npm global layout keeps production dependencies nested in the package being swapped.\n await exec(\n 'npm',\n [\n 'install',\n '--global',\n '--prefix',\n paths.prefix,\n '--omit=dev',\n '--no-audit',\n '--no-fund',\n `--registry=${registry}`,\n '--allow-scripts=better-sqlite3',\n `${npmPackageName}@${record.target}`,\n ],\n { timeout: 10 * 60_000, maxBuffer: 2 * 1024 * 1024 },\n );\n const candidate = await readJson<{ name: string; version: string; covroCodex?: unknown }>(\n join(paths.candidate, 'package.json'),\n );\n if (candidate?.name !== npmPackageName || candidate.version !== record.target)\n throw new Error('\u5019\u9009\u5305\u8EAB\u4EFD\u6216\u7248\u672C\u4E0D\u5339\u914D');\n if (!record.codex) throw new Error('\u7F3A\u5C11 Codex \u5347\u7EA7\u6821\u9A8C\u8BB0\u5F55\uFF0C\u8BF7\u91CD\u65B0\u68C0\u67E5\u66F4\u65B0');\n const manifest = codexCompatibilitySchema.parse(candidate.covroCodex);\n if (JSON.stringify(manifest) !== JSON.stringify(record.codex.manifest))\n throw new Error('\u5019\u9009\u5305\u7684 Codex \u517C\u5BB9\u58F0\u660E\u4E0E\u68C0\u67E5\u65F6\u4E0D\u4E00\u81F4\uFF0C\u62D2\u7EDD\u5207\u6362');\n const checkCodex = async (current?: DaemonStatus) => {\n const state = current ?? (await control<DaemonStatus>(context.location, 'status'));\n if (state.codexVersion !== record!.codex!.version)\n throw new Error('Codex \u7248\u672C\u5728\u7B49\u5F85\u5347\u7EA7\u671F\u95F4\u53D1\u751F\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u68C0\u67E5\u66F4\u65B0');\n requireCodexCompatibility(\n manifest,\n state.codexVersion ?? null,\n record!.codex!.confirmedUnverified,\n );\n };\n await checkCodex();\n await exec(process.execPath, [join(paths.candidate, 'bin/covro.mjs'), '--version'], {\n timeout: 30_000,\n });\n const nativeProbe =\n 'const {createRequire}=await import(\"node:module\"); const r=createRequire(process.argv[1]); const DB=r(\"better-sqlite3\"); const db=new DB(\":memory:\"); db.close();';\n await exec(\n process.execPath,\n ['--input-type=module', '-e', nativeProbe, join(paths.candidate, 'package.json')],\n { timeout: 30_000 },\n );\n await verifyMigrations(context, paths.candidate);\n await activateUpdate(paths, {\n phase: update,\n waitForIdle: async () => {\n // Queue without blocking normal work; admission closes atomically only after all blockers clear.\n for (;;) {\n await checkCodex();\n const result = await control<{ ready: boolean; reason?: string }>(\n context.location,\n 'prepare-update',\n );\n if (result.ready) {\n await checkCodex();\n return;\n }\n await update('waiting', result.reason ?? '\u7B49\u5F85\u6240\u6709\u4EFB\u52A1\u7ED3\u675F');\n await setTimeout(2_000);\n }\n },\n stop: () => stopService(context),\n start: async (candidate) => {\n await startService(context);\n if (!candidate) await verifyRestoredService(context, record!.from);\n },\n verify: async () => {\n for (let attempt = 0; attempt < 240; attempt++) {\n const current = await control<DaemonStatus>(context.location, 'status').catch(\n () => undefined,\n );\n if (current) {\n if (current.version !== record!.target || !current.maintenance)\n throw new Error('\u65B0\u7248\u670D\u52A1\u8EAB\u4EFD\u6216\u7EF4\u62A4\u72B6\u6001\u4E0D\u5339\u914D');\n await checkCodex(current);\n if (current.codexReady) return;\n }\n await setTimeout(250);\n }\n throw new Error('\u65B0\u7248\u670D\u52A1\u6216 Codex \u8FDE\u63A5\u672A\u5C31\u7EEA\uFF0C\u62D2\u7EDD\u6FC0\u6D3B');\n },\n commit: async () => {\n // Gateway commits the durable result before reopening task admission.\n await control(context.location, 'activate-update', {\n id: record!.id,\n channel: record!.channel,\n });\n const final = await readJson<UpdateRun>(join(directory, 'run.json'));\n if (!final?.committed) throw new Error('\u65B0\u7248\u5C1A\u672A\u786E\u8BA4\u5347\u7EA7\u63D0\u4EA4');\n record = final;\n },\n hasCommitted: async () =>\n Boolean((await readJson<UpdateRun>(join(directory, 'run.json')))?.committed),\n resume: async () => {\n await control(context.location, 'cancel-update').catch(() => {});\n },\n });\n } catch (error) {\n const latest = await readJson<UpdateRun>(join(directory, 'run.json'));\n if (latest?.committed) {\n // A lost commit response cannot authorize restoring older data.\n record = latest;\n } else if (!['rolledBack', 'failed'].includes(record.phase))\n await update('failed', message(error));\n console.error(message(error));\n process.exitCode = record.committed || record.phase === 'rolledBack' ? 0 : 1;\n } finally {\n await release();\n // Keep the last good installation and database backup for explicit recovery.\n if (record.phase === 'succeeded' || record.phase === 'rolledBack') {\n await rm(paths.prefix, { recursive: true, force: true });\n }\n }\n}\n\nif (process.argv[2])\n void worker(process.argv[2]).catch((error: unknown) => {\n console.error(message(error));\n process.exitCode = 1;\n });\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { BackupStore, backupDirectory, verifyLegacySnapshot } from '../backups/store.js';\nimport { acquireMaintenanceLock } from '../backups/lock.js';\nimport { acquireInstanceLock } from '../server/instance-lock.js';\nimport { inspectDatabase, readMigrations } from '../server/db/history.js';\nimport { databaseCompatibilitySchema } from '../shared/database.js';\nimport { npmPackageName } from '../shared/package.js';\nimport {\n codexCompatibilitySchema,\n requireCodexCompatibility,\n} from '../shared/codex-compatibility.js';\n// Bundled with its pure JavaScript dependencies and copied outside the installation before launch.\nimport { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { createRequire } from 'node:module';\nimport { access, mkdir, readdir, rm, rename } from 'node:fs/promises';\nimport { constants } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { setTimeout } from 'node:timers/promises';\nimport lockfile from 'proper-lockfile';\nimport type Database from 'better-sqlite3';\nimport type { UpdateRun } from '../shared/updates.js';\nimport type { UpdateContext } from './manager.js';\nimport { control, isNotRunning } from '../cli/control.js';\nimport { startBackground, stopBackground } from '../cli/background.js';\nimport { copyDurable, readJson, saveJson } from './files.js';\nimport { activateUpdate, transactionPaths } from './transaction.js';\nimport { inspectInstallation, registry } from './registry.js';\n\nconst exec = promisify(execFile);\nconst message = (error: unknown) => (error instanceof Error ? error.message : String(error));\ntype DaemonStatus = {\n version: string;\n pid: number;\n maintenance?: boolean;\n codexVersion?: string | null;\n codexReady?: boolean;\n};\n\nasync function startService(context: UpdateContext) {\n // Shared with `covro start`: never inherit a Background security session on macOS.\n // Activation is checked from the durable update record by the daemon.\n await startBackground(context.location, join(context.root, 'bin/covro.mjs'));\n}\nasync function stopService(context: UpdateContext) {\n await stopBackground(context.location);\n}\n\nasync function verifyRestoredService(context: UpdateContext, version: string) {\n for (let attempt = 0; attempt < 240; attempt++) {\n try {\n const restored = await control<DaemonStatus>(context.location, 'status');\n if (restored.version !== version || restored.maintenance)\n throw new Error('\u65E7\u7248\u6062\u590D\u8EAB\u4EFD\u4E0D\u5339\u914D');\n return;\n } catch (error) {\n if (attempt === 239) throw error;\n }\n await setTimeout(250);\n }\n}\n\nasync function verifyMigrations(context: UpdateContext, candidate: string) {\n // Loading the existing native addon happens before any package path is replaced.\n const require = createRequire(join(context.root, 'package.json'));\n const Sqlite = require('better-sqlite3') as typeof Database;\n const filename = join(context.dataDir, 'app.sqlite');\n try {\n await access(filename);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return;\n throw error;\n }\n const db = new Sqlite(filename, { readonly: true, fileMustExist: true });\n try {\n const migrations = readMigrations(join(candidate, 'dist/drizzle'));\n const metadata = await readJson<{ covroDatabase?: unknown }>(join(candidate, 'package.json'));\n if (metadata?.covroDatabase) {\n const contract = databaseCompatibilitySchema.parse(metadata.covroDatabase);\n if (contract.schemaVersion !== migrations.length)\n throw new Error('\u76EE\u6807\u7248\u672C\u7684 Schema \u58F0\u660E\u4E0E\u8FC1\u79FB\u4E0D\u4E00\u81F4');\n }\n inspectDatabase(db, migrations);\n } finally {\n db.close();\n }\n}\n\nasync function worker(directory: string) {\n await mkdir(directory, { recursive: true, mode: 0o700 });\n const release = await lockfile.lock(directory, {\n stale: 10_000,\n update: 2_000,\n retries: { retries: 30, minTimeout: 100, maxTimeout: 500 },\n });\n let record = await readJson<UpdateRun>(join(directory, 'run.json'));\n const context = await readJson<UpdateContext>(join(directory, 'context.json'));\n if (!record || !context) {\n await release();\n throw new Error('\u7F3A\u5C11\u5347\u7EA7\u8BB0\u5F55');\n }\n const update = async (phase: UpdateRun['phase'], detail: string) => {\n record = { ...record!, phase, message: detail, updatedAt: Date.now() };\n await saveJson(join(directory, 'run.json'), record);\n };\n const paths = transactionPaths(\n context.root,\n record.id,\n context.dataDir,\n context.location.config,\n join(backupDirectory(context.location.home, context.dataDir), record.id),\n );\n let releaseMaintenance: (() => Promise<void>) | undefined;\n let releaseData: (() => Promise<void>) | undefined;\n const previousMetadata = await readJson<{ version: string }>(\n join(paths.previous, 'package.json'),\n );\n const originalRoot = previousMetadata?.version === record.from ? paths.previous : context.root;\n const originalMetadata = await readJson<{\n version: string;\n covroCommit?: string;\n covroDatabase?: unknown;\n }>(join(originalRoot, 'package.json'));\n const Sqlite = createRequire(join(originalRoot, 'package.json'))(\n 'better-sqlite3',\n ) as typeof Database;\n const migrations = readMigrations(join(originalRoot, 'dist/drizzle'));\n const backups = new BackupStore({\n directory: backupDirectory(context.location.home, context.dataDir),\n config: paths.config,\n dataDir: paths.dataDir,\n appVersion: record.from,\n commit: originalMetadata?.covroCommit,\n contract: databaseCompatibilitySchema.parse(\n originalMetadata?.covroDatabase ?? {\n schemaVersion: migrations.length,\n minRestorableSchemaVersion: 1,\n backupFormatVersion: 1,\n },\n ),\n Sqlite,\n migrations,\n });\n try {\n if (process.argv[3] === '--repair') {\n releaseMaintenance = await acquireMaintenanceLock(context.dataDir);\n if (!(await readJson(join(paths.backup, 'snapshot.json'))))\n paths.backup = join(directory, `backup-${record.id}`);\n const active = await control<DaemonStatus>(context.location, 'status').catch(\n (error: unknown) => {\n if (isNotRunning(error)) return undefined;\n throw error;\n },\n );\n if (record.committed) return;\n if (active && !active.maintenance && active.version !== record.from)\n throw new Error('\u5F53\u524D\u670D\u52A1\u53EF\u80FD\u5DF2\u63A5\u53D7\u65B0\u7248\u4E1A\u52A1\u6570\u636E\uFF1B\u62D2\u7EDD\u6062\u590D\u65E7\u5FEB\u7167\uFF0C\u8BF7\u4F7F\u7528\u517C\u5BB9\u7248\u672C\u68C0\u67E5\u3002');\n const previous = await readJson<{ version: string; name: string }>(\n join(paths.previous, 'package.json'),\n );\n if (previous) {\n if (active && !active.maintenance)\n throw new Error('\u65E7\u670D\u52A1\u5DF2\u6062\u590D\u4E1A\u52A1\u5199\u5165\uFF1B\u62D2\u7EDD\u7528\u5347\u7EA7\u524D\u5FEB\u7167\u8986\u76D6\u73B0\u6709\u6570\u636E\uFF0C\u8BF7\u4FDD\u7559\u73B0\u573A\u68C0\u67E5\u3002');\n if (previous.name !== npmPackageName || previous.version !== record.from)\n throw new Error('\u65E7\u7248\u5907\u4EFD\u8EAB\u4EFD\u4E0D\u5339\u914D');\n const snapshot = await readJson<{ complete: boolean; formatVersion?: number }>(\n join(paths.backup, 'snapshot.json'),\n );\n if (snapshot?.formatVersion === 1) {\n const verified = await backups.verify(record.id);\n if (\n verified.appVersion !== record.from ||\n verified.protectedBy !== record.id ||\n verified.configPath !== paths.config ||\n verified.dataDir !== paths.dataDir\n )\n throw new Error('\u5907\u4EFD\u8EAB\u4EFD\u4E0D\u5339\u914D');\n } else await verifyLegacySnapshot(paths.backup, Sqlite, join(originalRoot, 'dist/drizzle'));\n } else {\n const original = await readJson<{ name: string; version: string }>(\n join(paths.root, 'package.json'),\n );\n if (original?.name !== npmPackageName || original.version !== record.from)\n throw new Error('\u672A\u627E\u5230\u5B8C\u6574\u7684\u4E0A\u4E00\u7248\u672C\u5B89\u88C5');\n }\n if (active && !active.maintenance) {\n const admission = await control<{ ready: boolean }>(context.location, 'prepare-update');\n if (!admission.ready) throw new Error('\u4ECD\u6709\u4EFB\u52A1\u3001\u5BA1\u6279\u6216\u5F85\u6838\u5BF9\u64CD\u4F5C\uFF0C\u4E0D\u80FD\u6062\u590D\u65E7\u5B89\u88C5');\n }\n await stopService(context);\n releaseData = await acquireInstanceLock(context.dataDir);\n if (previous) {\n await rm(paths.root, { recursive: true, force: true });\n await rename(paths.previous, paths.root);\n for (const name of ['app.sqlite', 'app.sqlite-wal', 'app.sqlite-shm']) {\n await rm(join(paths.dataDir, name), { force: true });\n try {\n await copyDurable(join(paths.backup, name), join(paths.dataDir, name));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n }\n }\n await copyDurable(join(paths.backup, 'config.json'), paths.config);\n }\n const restored = await readJson<{ name: string; version: string }>(\n join(paths.root, 'package.json'),\n );\n if (restored?.name !== npmPackageName || restored.version !== record.from)\n throw new Error('\u672A\u627E\u5230\u5B8C\u6574\u7684\u4E0A\u4E00\u7248\u672C\u5B89\u88C5');\n await update('rolledBack', '\u5DF2\u6062\u590D\u4E0A\u6B21\u672A\u5B8C\u6210\u7684\u5347\u7EA7\uFF0C\u6B63\u5728\u542F\u52A8\u4E0A\u4E00\u7248\u672C');\n try {\n await releaseData?.();\n releaseData = undefined;\n await startService(context);\n await verifyRestoredService(context, record.from);\n await update('rolledBack', '\u5DF2\u6062\u590D\u4E0A\u6B21\u672A\u5B8C\u6210\u7684\u5347\u7EA7\uFF0C\u4E0A\u4E00\u7248\u672C\u5DF2\u5C31\u7EEA');\n } catch (error) {\n await update('failed', `\u65E7\u7248\u6062\u590D\u542F\u52A8\u5931\u8D25\uFF0C\u4FDD\u7559\u5907\u4EFD\uFF1A${message(error)}`);\n throw error;\n }\n return;\n }\n const reason = await inspectInstallation(context.root);\n if (reason) throw new Error(reason);\n // A second managed configuration must be stopped before replacing their shared npm package.\n for (const key of await readdir(join(context.location.home, 'instances'))) {\n if (key === context.location.key) continue;\n const instance = await readJson<{ root: string; config: string; socket: string }>(\n join(context.location.home, 'instances', key, 'instance.json'),\n );\n if (instance?.root !== context.root) continue;\n try {\n await control({ ...context.location, socket: instance.socket }, 'status');\n throw new Error('\u540C\u4E00 npm \u5B89\u88C5\u8FD8\u6709\u5176\u4ED6 Covro \u5B9E\u4F8B\uFF0C\u8BF7\u5148\u505C\u6B62\u5176\u4ED6\u5B9E\u4F8B\u518D\u5347\u7EA7\u3002');\n } catch (error) {\n if (!isNotRunning(error)) throw error;\n }\n }\n await access(dirname(context.root), constants.W_OK);\n // npm global layout keeps production dependencies nested in the package being swapped.\n await exec(\n 'npm',\n [\n 'install',\n '--global',\n '--prefix',\n paths.prefix,\n '--omit=dev',\n '--no-audit',\n '--no-fund',\n `--registry=${registry}`,\n '--allow-scripts=better-sqlite3',\n `${npmPackageName}@${record.target}`,\n ],\n { timeout: 10 * 60_000, maxBuffer: 2 * 1024 * 1024 },\n );\n const candidate = await readJson<{ name: string; version: string; covroCodex?: unknown }>(\n join(paths.candidate, 'package.json'),\n );\n if (candidate?.name !== npmPackageName || candidate.version !== record.target)\n throw new Error('\u5019\u9009\u5305\u8EAB\u4EFD\u6216\u7248\u672C\u4E0D\u5339\u914D');\n if (!record.codex) throw new Error('\u7F3A\u5C11 Codex \u5347\u7EA7\u6821\u9A8C\u8BB0\u5F55\uFF0C\u8BF7\u91CD\u65B0\u68C0\u67E5\u66F4\u65B0');\n const manifest = codexCompatibilitySchema.parse(candidate.covroCodex);\n if (JSON.stringify(manifest) !== JSON.stringify(record.codex.manifest))\n throw new Error('\u5019\u9009\u5305\u7684 Codex \u517C\u5BB9\u58F0\u660E\u4E0E\u68C0\u67E5\u65F6\u4E0D\u4E00\u81F4\uFF0C\u62D2\u7EDD\u5207\u6362');\n const checkCodex = async (current?: DaemonStatus) => {\n const state = current ?? (await control<DaemonStatus>(context.location, 'status'));\n if (state.codexVersion !== record!.codex!.version)\n throw new Error('Codex \u7248\u672C\u5728\u7B49\u5F85\u5347\u7EA7\u671F\u95F4\u53D1\u751F\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u68C0\u67E5\u66F4\u65B0');\n requireCodexCompatibility(\n manifest,\n state.codexVersion ?? null,\n record!.codex!.confirmedUnverified,\n );\n };\n await checkCodex();\n await exec(process.execPath, [join(paths.candidate, 'bin/covro.mjs'), '--version'], {\n timeout: 30_000,\n });\n const nativeProbe =\n 'const {createRequire}=await import(\"node:module\"); const r=createRequire(process.argv[1]); const DB=r(\"better-sqlite3\"); const db=new DB(\":memory:\"); db.close();';\n await exec(\n process.execPath,\n ['--input-type=module', '-e', nativeProbe, join(paths.candidate, 'package.json')],\n { timeout: 30_000 },\n );\n await verifyMigrations(context, paths.candidate);\n releaseMaintenance = await acquireMaintenanceLock(context.dataDir);\n await activateUpdate(paths, {\n backup: async () => {\n releaseData = await acquireInstanceLock(context.dataDir);\n await backups.create({ id: record!.id, trigger: 'preUpgrade', protectedBy: record!.id });\n },\n restore: async () => {\n releaseData ??= await acquireInstanceLock(context.dataDir);\n await backups.restoreFiles(record!.id);\n },\n phase: update,\n waitForIdle: async () => {\n // Queue without blocking normal work; admission closes atomically only after all blockers clear.\n for (;;) {\n await checkCodex();\n const result = await control<{ ready: boolean; reason?: string }>(\n context.location,\n 'prepare-update',\n );\n if (result.ready) {\n await checkCodex();\n return;\n }\n await update('waiting', result.reason ?? '\u7B49\u5F85\u6240\u6709\u4EFB\u52A1\u7ED3\u675F');\n await setTimeout(2_000);\n }\n },\n stop: () => stopService(context),\n start: async (candidate) => {\n await releaseData?.();\n releaseData = undefined;\n await startService(context);\n if (!candidate) await verifyRestoredService(context, record!.from);\n },\n verify: async () => {\n for (let attempt = 0; attempt < 240; attempt++) {\n const current = await control<DaemonStatus>(context.location, 'status').catch(\n () => undefined,\n );\n if (current) {\n if (current.version !== record!.target || !current.maintenance)\n throw new Error('\u65B0\u7248\u670D\u52A1\u8EAB\u4EFD\u6216\u7EF4\u62A4\u72B6\u6001\u4E0D\u5339\u914D');\n await checkCodex(current);\n if (current.codexReady) return;\n }\n await setTimeout(250);\n }\n throw new Error('\u65B0\u7248\u670D\u52A1\u6216 Codex \u8FDE\u63A5\u672A\u5C31\u7EEA\uFF0C\u62D2\u7EDD\u6FC0\u6D3B');\n },\n commit: async () => {\n // Gateway commits the durable result before reopening task admission.\n await control(context.location, 'activate-update', {\n id: record!.id,\n channel: record!.channel,\n });\n const final = await readJson<UpdateRun>(join(directory, 'run.json'));\n if (!final?.committed) throw new Error('\u65B0\u7248\u5C1A\u672A\u786E\u8BA4\u5347\u7EA7\u63D0\u4EA4');\n record = final;\n },\n hasCommitted: async () =>\n Boolean((await readJson<UpdateRun>(join(directory, 'run.json')))?.committed),\n resume: async () => {\n await control(context.location, 'cancel-update').catch(() => {});\n },\n });\n } catch (error) {\n const latest = await readJson<UpdateRun>(join(directory, 'run.json'));\n if (latest?.committed) {\n // A lost commit response cannot authorize restoring older data.\n record = latest;\n } else if (!['rolledBack', 'failed'].includes(record.phase))\n await update('failed', message(error));\n console.error(message(error));\n process.exitCode = record.committed || record.phase === 'rolledBack' ? 0 : 1;\n } finally {\n await releaseData?.();\n await releaseMaintenance?.();\n await release();\n // Keep the last good installation and database backup for explicit recovery.\n if (record.phase === 'succeeded' || record.phase === 'rolledBack') {\n await rm(paths.prefix, { recursive: true, force: true });\n }\n }\n}\n\nif (process.argv[2])\n void worker(process.argv[2]).catch((error: unknown) => {\n console.error(message(error));\n process.exitCode = 1;\n });\n"],
5
+ "mappings": "AAAA,SAAS,aAAa,iBAAiB,4BAA4B;AACnE,SAAS,8BAA8B;AACvC,SAAS,2BAA2B;AACpC,SAAS,iBAAiB,sBAAsB;AAChD,SAAS,mCAAmC;AAC5C,SAAS,sBAAsB;AAC/B;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAEP,SAAS,gBAAgB;AACzB,SAAS,iBAAiB;AAC1B,SAAS,qBAAqB;AAC9B,SAAS,QAAQ,OAAO,SAAS,IAAI,cAAc;AACnD,SAAS,iBAAiB;AAC1B,SAAS,SAAS,YAAY;AAC9B,SAAS,kBAAkB;AAC3B,OAAO,cAAc;AAIrB,SAAS,SAAS,oBAAoB;AACtC,SAAS,iBAAiB,sBAAsB;AAChD,SAAS,aAAa,UAAU,gBAAgB;AAChD,SAAS,gBAAgB,wBAAwB;AACjD,SAAS,qBAAqB,gBAAgB;AAE9C,MAAM,OAAO,UAAU,QAAQ;AAC/B,MAAM,UAAU,CAAC,UAAoB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAS1F,eAAe,aAAa,SAAwB;AAGlD,QAAM,gBAAgB,QAAQ,UAAU,KAAK,QAAQ,MAAM,eAAe,CAAC;AAC7E;AACA,eAAe,YAAY,SAAwB;AACjD,QAAM,eAAe,QAAQ,QAAQ;AACvC;AAEA,eAAe,sBAAsB,SAAwB,SAAiB;AAC5E,WAAS,UAAU,GAAG,UAAU,KAAK,WAAW;AAC9C,QAAI;AACF,YAAM,WAAW,MAAM,QAAsB,QAAQ,UAAU,QAAQ;AACvE,UAAI,SAAS,YAAY,WAAW,SAAS;AAC3C,cAAM,IAAI,MAAM,wDAAW;AAC7B;AAAA,IACF,SAAS,OAAO;AACd,UAAI,YAAY,IAAK,OAAM;AAAA,IAC7B;AACA,UAAM,WAAW,GAAG;AAAA,EACtB;AACF;AAEA,eAAe,iBAAiB,SAAwB,WAAmB;AAEzE,QAAMA,WAAU,cAAc,KAAK,QAAQ,MAAM,cAAc,CAAC;AAChE,QAAM,SAASA,SAAQ,gBAAgB;AACvC,QAAM,WAAW,KAAK,QAAQ,SAAS,YAAY;AACnD,MAAI;AACF,UAAM,OAAO,QAAQ;AAAA,EACvB,SAAS,OAAO;AACd,QAAK,MAAgC,SAAS,SAAU;AACxD,UAAM;AAAA,EACR;AACA,QAAM,KAAK,IAAI,OAAO,UAAU,EAAE,UAAU,MAAM,eAAe,KAAK,CAAC;AACvE,MAAI;AACF,UAAM,aAAa,eAAe,KAAK,WAAW,cAAc,CAAC;AACjE,UAAM,WAAW,MAAM,SAAsC,KAAK,WAAW,cAAc,CAAC;AAC5F,QAAI,UAAU,eAAe;AAC3B,YAAM,WAAW,4BAA4B,MAAM,SAAS,aAAa;AACzE,UAAI,SAAS,kBAAkB,WAAW;AACxC,cAAM,IAAI,MAAM,wFAAuB;AAAA,IAC3C;AACA,oBAAgB,IAAI,UAAU;AAAA,EAChC,UAAE;AACA,OAAG,MAAM;AAAA,EACX;AACF;AAEA,eAAe,OAAO,WAAmB;AACvC,QAAM,MAAM,WAAW,EAAE,WAAW,MAAM,MAAM,IAAM,CAAC;AACvD,QAAM,UAAU,MAAM,SAAS,KAAK,WAAW;AAAA,IAC7C,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,SAAS,EAAE,SAAS,IAAI,YAAY,KAAK,YAAY,IAAI;AAAA,EAC3D,CAAC;AACD,MAAI,SAAS,MAAM,SAAoB,KAAK,WAAW,UAAU,CAAC;AAClE,QAAM,UAAU,MAAM,SAAwB,KAAK,WAAW,cAAc,CAAC;AAC7E,MAAI,CAAC,UAAU,CAAC,SAAS;AACvB,UAAM,QAAQ;AACd,UAAM,IAAI,MAAM,sCAAQ;AAAA,EAC1B;AACA,QAAM,SAAS,OAAO,OAA2B,WAAmB;AAClE,aAAS,EAAE,GAAG,QAAS,OAAO,SAAS,QAAQ,WAAW,KAAK,IAAI,EAAE;AACrE,UAAM,SAAS,KAAK,WAAW,UAAU,GAAG,MAAM;AAAA,EACpD;AACA,QAAM,QAAQ;AAAA,IACZ,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,QAAQ,SAAS;AAAA,IACjB,KAAK,gBAAgB,QAAQ,SAAS,MAAM,QAAQ,OAAO,GAAG,OAAO,EAAE;AAAA,EACzE;AACA,MAAI;AACJ,MAAI;AACJ,QAAM,mBAAmB,MAAM;AAAA,IAC7B,KAAK,MAAM,UAAU,cAAc;AAAA,EACrC;AACA,QAAM,eAAe,kBAAkB,YAAY,OAAO,OAAO,MAAM,WAAW,QAAQ;AAC1F,QAAM,mBAAmB,MAAM,SAI5B,KAAK,cAAc,cAAc,CAAC;AACrC,QAAM,SAAS,cAAc,KAAK,cAAc,cAAc,CAAC;AAAA,IAC7D;AAAA,EACF;AACA,QAAM,aAAa,eAAe,KAAK,cAAc,cAAc,CAAC;AACpE,QAAM,UAAU,IAAI,YAAY;AAAA,IAC9B,WAAW,gBAAgB,QAAQ,SAAS,MAAM,QAAQ,OAAO;AAAA,IACjE,QAAQ,MAAM;AAAA,IACd,SAAS,MAAM;AAAA,IACf,YAAY,OAAO;AAAA,IACnB,QAAQ,kBAAkB;AAAA,IAC1B,UAAU,4BAA4B;AAAA,MACpC,kBAAkB,iBAAiB;AAAA,QACjC,eAAe,WAAW;AAAA,QAC1B,4BAA4B;AAAA,QAC5B,qBAAqB;AAAA,MACvB;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,MAAI;AACF,QAAI,QAAQ,KAAK,CAAC,MAAM,YAAY;AAClC,2BAAqB,MAAM,uBAAuB,QAAQ,OAAO;AACjE,UAAI,CAAE,MAAM,SAAS,KAAK,MAAM,QAAQ,eAAe,CAAC;AACtD,cAAM,SAAS,KAAK,WAAW,UAAU,OAAO,EAAE,EAAE;AACtD,YAAM,SAAS,MAAM,QAAsB,QAAQ,UAAU,QAAQ,EAAE;AAAA,QACrE,CAAC,UAAmB;AAClB,cAAI,aAAa,KAAK,EAAG,QAAO;AAChC,gBAAM;AAAA,QACR;AAAA,MACF;AACA,UAAI,OAAO,UAAW;AACtB,UAAI,UAAU,CAAC,OAAO,eAAe,OAAO,YAAY,OAAO;AAC7D,cAAM,IAAI,MAAM,8MAAoC;AACtD,YAAM,WAAW,MAAM;AAAA,QACrB,KAAK,MAAM,UAAU,cAAc;AAAA,MACrC;AACA,UAAI,UAAU;AACZ,YAAI,UAAU,CAAC,OAAO;AACpB,gBAAM,IAAI,MAAM,8MAAoC;AACtD,YAAI,SAAS,SAAS,kBAAkB,SAAS,YAAY,OAAO;AAClE,gBAAM,IAAI,MAAM,wDAAW;AAC7B,cAAM,WAAW,MAAM;AAAA,UACrB,KAAK,MAAM,QAAQ,eAAe;AAAA,QACpC;AACA,YAAI,UAAU,kBAAkB,GAAG;AACjC,gBAAM,WAAW,MAAM,QAAQ,OAAO,OAAO,EAAE;AAC/C,cACE,SAAS,eAAe,OAAO,QAC/B,SAAS,gBAAgB,OAAO,MAChC,SAAS,eAAe,MAAM,UAC9B,SAAS,YAAY,MAAM;AAE3B,kBAAM,IAAI,MAAM,4CAAS;AAAA,QAC7B,MAAO,OAAM,qBAAqB,MAAM,QAAQ,QAAQ,KAAK,cAAc,cAAc,CAAC;AAAA,MAC5F,OAAO;AACL,cAAM,WAAW,MAAM;AAAA,UACrB,KAAK,MAAM,MAAM,cAAc;AAAA,QACjC;AACA,YAAI,UAAU,SAAS,kBAAkB,SAAS,YAAY,OAAO;AACnE,gBAAM,IAAI,MAAM,0EAAc;AAAA,MAClC;AACA,UAAI,UAAU,CAAC,OAAO,aAAa;AACjC,cAAM,YAAY,MAAM,QAA4B,QAAQ,UAAU,gBAAgB;AACtF,YAAI,CAAC,UAAU,MAAO,OAAM,IAAI,MAAM,gIAAuB;AAAA,MAC/D;AACA,YAAM,YAAY,OAAO;AACzB,oBAAc,MAAM,oBAAoB,QAAQ,OAAO;AACvD,UAAI,UAAU;AACZ,cAAM,GAAG,MAAM,MAAM,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AACrD,cAAM,OAAO,MAAM,UAAU,MAAM,IAAI;AACvC,mBAAW,QAAQ,CAAC,cAAc,kBAAkB,gBAAgB,GAAG;AACrE,gBAAM,GAAG,KAAK,MAAM,SAAS,IAAI,GAAG,EAAE,OAAO,KAAK,CAAC;AACnD,cAAI;AACF,kBAAM,YAAY,KAAK,MAAM,QAAQ,IAAI,GAAG,KAAK,MAAM,SAAS,IAAI,CAAC;AAAA,UACvE,SAAS,OAAO;AACd,gBAAK,MAAgC,SAAS,SAAU,OAAM;AAAA,UAChE;AAAA,QACF;AACA,cAAM,YAAY,KAAK,MAAM,QAAQ,aAAa,GAAG,MAAM,MAAM;AAAA,MACnE;AACA,YAAM,WAAW,MAAM;AAAA,QACrB,KAAK,MAAM,MAAM,cAAc;AAAA,MACjC;AACA,UAAI,UAAU,SAAS,kBAAkB,SAAS,YAAY,OAAO;AACnE,cAAM,IAAI,MAAM,0EAAc;AAChC,YAAM,OAAO,cAAc,0HAAsB;AACjD,UAAI;AACF,cAAM,cAAc;AACpB,sBAAc;AACd,cAAM,aAAa,OAAO;AAC1B,cAAM,sBAAsB,SAAS,OAAO,IAAI;AAChD,cAAM,OAAO,cAAc,oHAAqB;AAAA,MAClD,SAAS,OAAO;AACd,cAAM,OAAO,UAAU,uFAAiB,QAAQ,KAAK,CAAC,EAAE;AACxD,cAAM;AAAA,MACR;AACA;AAAA,IACF;AACA,UAAM,SAAS,MAAM,oBAAoB,QAAQ,IAAI;AACrD,QAAI,OAAQ,OAAM,IAAI,MAAM,MAAM;AAElC,eAAW,OAAO,MAAM,QAAQ,KAAK,QAAQ,SAAS,MAAM,WAAW,CAAC,GAAG;AACzE,UAAI,QAAQ,QAAQ,SAAS,IAAK;AAClC,YAAM,WAAW,MAAM;AAAA,QACrB,KAAK,QAAQ,SAAS,MAAM,aAAa,KAAK,eAAe;AAAA,MAC/D;AACA,UAAI,UAAU,SAAS,QAAQ,KAAM;AACrC,UAAI;AACF,cAAM,QAAQ,EAAE,GAAG,QAAQ,UAAU,QAAQ,SAAS,OAAO,GAAG,QAAQ;AACxE,cAAM,IAAI,MAAM,wJAAqC;AAAA,MACvD,SAAS,OAAO;AACd,YAAI,CAAC,aAAa,KAAK,EAAG,OAAM;AAAA,MAClC;AAAA,IACF;AACA,UAAM,OAAO,QAAQ,QAAQ,IAAI,GAAG,UAAU,IAAI;AAElD,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc,QAAQ;AAAA,QACtB;AAAA,QACA,GAAG,cAAc,IAAI,OAAO,MAAM;AAAA,MACpC;AAAA,MACA,EAAE,SAAS,KAAK,KAAQ,WAAW,IAAI,OAAO,KAAK;AAAA,IACrD;AACA,UAAM,YAAY,MAAM;AAAA,MACtB,KAAK,MAAM,WAAW,cAAc;AAAA,IACtC;AACA,QAAI,WAAW,SAAS,kBAAkB,UAAU,YAAY,OAAO;AACrE,YAAM,IAAI,MAAM,oEAAa;AAC/B,QAAI,CAAC,OAAO,MAAO,OAAM,IAAI,MAAM,yGAAyB;AAC5D,UAAM,WAAW,yBAAyB,MAAM,UAAU,UAAU;AACpE,QAAI,KAAK,UAAU,QAAQ,MAAM,KAAK,UAAU,OAAO,MAAM,QAAQ;AACnE,YAAM,IAAI,MAAM,iIAA6B;AAC/C,UAAM,aAAa,OAAO,YAA2B;AACnD,YAAM,QAAQ,WAAY,MAAM,QAAsB,QAAQ,UAAU,QAAQ;AAChF,UAAI,MAAM,iBAAiB,OAAQ,MAAO;AACxC,cAAM,IAAI,MAAM,sIAA6B;AAC/C;AAAA,QACE;AAAA,QACA,MAAM,gBAAgB;AAAA,QACtB,OAAQ,MAAO;AAAA,MACjB;AAAA,IACF;AACA,UAAM,WAAW;AACjB,UAAM,KAAK,QAAQ,UAAU,CAAC,KAAK,MAAM,WAAW,eAAe,GAAG,WAAW,GAAG;AAAA,MAClF,SAAS;AAAA,IACX,CAAC;AACD,UAAM,cACJ;AACF,UAAM;AAAA,MACJ,QAAQ;AAAA,MACR,CAAC,uBAAuB,MAAM,aAAa,KAAK,MAAM,WAAW,cAAc,CAAC;AAAA,MAChF,EAAE,SAAS,IAAO;AAAA,IACpB;AACA,UAAM,iBAAiB,SAAS,MAAM,SAAS;AAC/C,yBAAqB,MAAM,uBAAuB,QAAQ,OAAO;AACjE,UAAM,eAAe,OAAO;AAAA,MAC1B,QAAQ,YAAY;AAClB,sBAAc,MAAM,oBAAoB,QAAQ,OAAO;AACvD,cAAM,QAAQ,OAAO,EAAE,IAAI,OAAQ,IAAI,SAAS,cAAc,aAAa,OAAQ,GAAG,CAAC;AAAA,MACzF;AAAA,MACA,SAAS,YAAY;AACnB,wBAAgB,MAAM,oBAAoB,QAAQ,OAAO;AACzD,cAAM,QAAQ,aAAa,OAAQ,EAAE;AAAA,MACvC;AAAA,MACA,OAAO;AAAA,MACP,aAAa,YAAY;AAEvB,mBAAS;AACP,gBAAM,WAAW;AACjB,gBAAM,SAAS,MAAM;AAAA,YACnB,QAAQ;AAAA,YACR;AAAA,UACF;AACA,cAAI,OAAO,OAAO;AAChB,kBAAM,WAAW;AACjB;AAAA,UACF;AACA,gBAAM,OAAO,WAAW,OAAO,UAAU,kDAAU;AACnD,gBAAM,WAAW,GAAK;AAAA,QACxB;AAAA,MACF;AAAA,MACA,MAAM,MAAM,YAAY,OAAO;AAAA,MAC/B,OAAO,OAAOC,eAAc;AAC1B,cAAM,cAAc;AACpB,sBAAc;AACd,cAAM,aAAa,OAAO;AAC1B,YAAI,CAACA,WAAW,OAAM,sBAAsB,SAAS,OAAQ,IAAI;AAAA,MACnE;AAAA,MACA,QAAQ,YAAY;AAClB,iBAAS,UAAU,GAAG,UAAU,KAAK,WAAW;AAC9C,gBAAM,UAAU,MAAM,QAAsB,QAAQ,UAAU,QAAQ,EAAE;AAAA,YACtE,MAAM;AAAA,UACR;AACA,cAAI,SAAS;AACX,gBAAI,QAAQ,YAAY,OAAQ,UAAU,CAAC,QAAQ;AACjD,oBAAM,IAAI,MAAM,sFAAgB;AAClC,kBAAM,WAAW,OAAO;AACxB,gBAAI,QAAQ,WAAY;AAAA,UAC1B;AACA,gBAAM,WAAW,GAAG;AAAA,QACtB;AACA,cAAM,IAAI,MAAM,mGAAwB;AAAA,MAC1C;AAAA,MACA,QAAQ,YAAY;AAElB,cAAM,QAAQ,QAAQ,UAAU,mBAAmB;AAAA,UACjD,IAAI,OAAQ;AAAA,UACZ,SAAS,OAAQ;AAAA,QACnB,CAAC;AACD,cAAM,QAAQ,MAAM,SAAoB,KAAK,WAAW,UAAU,CAAC;AACnE,YAAI,CAAC,OAAO,UAAW,OAAM,IAAI,MAAM,8DAAY;AACnD,iBAAS;AAAA,MACX;AAAA,MACA,cAAc,YACZ,SAAS,MAAM,SAAoB,KAAK,WAAW,UAAU,CAAC,IAAI,SAAS;AAAA,MAC7E,QAAQ,YAAY;AAClB,cAAM,QAAQ,QAAQ,UAAU,eAAe,EAAE,MAAM,MAAM;AAAA,QAAC,CAAC;AAAA,MACjE;AAAA,IACF,CAAC;AAAA,EACH,SAAS,OAAO;AACd,UAAM,SAAS,MAAM,SAAoB,KAAK,WAAW,UAAU,CAAC;AACpE,QAAI,QAAQ,WAAW;AAErB,eAAS;AAAA,IACX,WAAW,CAAC,CAAC,cAAc,QAAQ,EAAE,SAAS,OAAO,KAAK;AACxD,YAAM,OAAO,UAAU,QAAQ,KAAK,CAAC;AACvC,YAAQ,MAAM,QAAQ,KAAK,CAAC;AAC5B,YAAQ,WAAW,OAAO,aAAa,OAAO,UAAU,eAAe,IAAI;AAAA,EAC7E,UAAE;AACA,UAAM,cAAc;AACpB,UAAM,qBAAqB;AAC3B,UAAM,QAAQ;AAEd,QAAI,OAAO,UAAU,eAAe,OAAO,UAAU,cAAc;AACjE,YAAM,GAAG,MAAM,QAAQ,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,IACzD;AAAA,EACF;AACF;AAEA,IAAI,QAAQ,KAAK,CAAC;AAChB,OAAK,OAAO,QAAQ,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,UAAmB;AACrD,YAAQ,MAAM,QAAQ,KAAK,CAAC;AAC5B,YAAQ,WAAW;AAAA,EACrB,CAAC;",
6
6
  "names": ["require", "candidate"]
7
7
  }
@@ -1 +1 @@
1
- import{m as e,t}from"./mermaid-parser.core-gIvgB9WK.js";import{n}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import{m as r}from"./src-F6L8HcEC.js";import"./chunk-DSNLSHJZ-B7dim5uT.js";import{n as i,r as a,t as o}from"./chunk-2E7WHVMD-Bu427yab.js";import{t as s}from"./chunk-JWPE2WC7-DVXcaiue.js";import"./mermaid.core-C_R7Y1XB.js";var c=e().RailroadAbnf.parser.LangiumParser,l=n(e=>{let t=e.alternatives.map(u);return t.length===1?t[0]:{type:`choice`,alternatives:t}},`transformAlternation`),u=n(e=>{let t=e.elements.map(f);return t.length===1?t[0]:{type:`sequence`,elements:t}},`transformConcatenation`),d=n(e=>{if(e.includes(`*`)){let[t,n]=e.split(`*`);return{min:t?parseInt(t,10):0,max:n?parseInt(n,10):1/0}}let t=parseInt(e,10);return{min:t,max:t}},`parseRepeat`),f=n(e=>{let t=p(e.primary);if(!e.repeat)return t;let{min:n,max:r}=d(e.repeat);return n===0&&r===1?{type:`optional`,element:t}:{type:`repetition`,element:t,min:n,max:r}},`transformElement`),p=n(e=>{switch(e.$type){case`AbnfStringLiteral`:return{type:`terminal`,value:e.value};case`AbnfNumVal`:return{type:`terminal`,value:e.value};case`AbnfRuleName`:return{type:`nonterminal`,name:e.name};case`AbnfGroup`:return l(e.element);case`AbnfOptionalGroup`:return{type:`optional`,element:l(e.element)};default:throw Error(`Unsupported ABNF primary node: ${e.$type}`)}},`transformPrimary`),m=n(e=>({name:e.name,definition:l(e.definition)}),`transformRule`),h=n(e=>{s(e,o),e.title&&o.setTitle(e.title),e.rules.map(e=>o.addRule(m(e)))},`populateDb`),g={parser:{parse:n(e=>{o.clear(),r.debug(`[ABNF Parser] Starting Langium parse`);let n=c.parse(e);if(n.lexerErrors.length>0||n.parserErrors.length>0)throw new t(n);let i=n.value;r.debug(`[ABNF Parser] Parsed rules:`,i.rules.length),h(i),r.debug(`[ABNF Parser] Parse complete`)},`parse`),parser:{yy:o}},db:o,renderer:a,styles:i};export{g as diagram};
1
+ import{m as e,t}from"./mermaid-parser.core-MEuwYVot.js";import{n}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import{m as r}from"./src-BlOCBHYS.js";import"./chunk-DSNLSHJZ-Cax3giJD.js";import{n as i,r as a,t as o}from"./chunk-2E7WHVMD-Vb63e-lu.js";import{t as s}from"./chunk-JWPE2WC7-DVXcaiue.js";import"./mermaid.core-CVKnnz65.js";var c=e().RailroadAbnf.parser.LangiumParser,l=n(e=>{let t=e.alternatives.map(u);return t.length===1?t[0]:{type:`choice`,alternatives:t}},`transformAlternation`),u=n(e=>{let t=e.elements.map(f);return t.length===1?t[0]:{type:`sequence`,elements:t}},`transformConcatenation`),d=n(e=>{if(e.includes(`*`)){let[t,n]=e.split(`*`);return{min:t?parseInt(t,10):0,max:n?parseInt(n,10):1/0}}let t=parseInt(e,10);return{min:t,max:t}},`parseRepeat`),f=n(e=>{let t=p(e.primary);if(!e.repeat)return t;let{min:n,max:r}=d(e.repeat);return n===0&&r===1?{type:`optional`,element:t}:{type:`repetition`,element:t,min:n,max:r}},`transformElement`),p=n(e=>{switch(e.$type){case`AbnfStringLiteral`:return{type:`terminal`,value:e.value};case`AbnfNumVal`:return{type:`terminal`,value:e.value};case`AbnfRuleName`:return{type:`nonterminal`,name:e.name};case`AbnfGroup`:return l(e.element);case`AbnfOptionalGroup`:return{type:`optional`,element:l(e.element)};default:throw Error(`Unsupported ABNF primary node: ${e.$type}`)}},`transformPrimary`),m=n(e=>({name:e.name,definition:l(e.definition)}),`transformRule`),h=n(e=>{s(e,o),e.title&&o.setTitle(e.title),e.rules.map(e=>o.addRule(m(e)))},`populateDb`),g={parser:{parse:n(e=>{o.clear(),r.debug(`[ABNF Parser] Starting Langium parse`);let n=c.parse(e);if(n.lexerErrors.length>0||n.parserErrors.length>0)throw new t(n);let i=n.value;r.debug(`[ABNF Parser] Parsed rules:`,i.rules.length),h(i),r.debug(`[ABNF Parser] Parse complete`)},`parse`),parser:{yy:o}},db:o,renderer:a,styles:i};export{g as diagram};
@@ -1 +1 @@
1
- import{n as e,t}from"./path-fybaL0A-.js";import{a as n,c as r,d as i,f as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,u as p}from"./dist-B4eX4BCP.js";function m(e){return e.innerRadius}function h(e){return e.outerRadius}function g(e){return e.startAngle}function _(e){return e.endAngle}function v(e){return e&&e.padAngle}function y(e,t,n,r,i,a,o,s){var c=n-e,l=r-t,u=o-i,d=s-a,f=d*c-u*l;if(!(f*f<1e-12))return f=(u*(t-a)-d*(e-i))/f,[e+f*c,t+f*l]}function b(e,t,n,r,i,a,o){var c=e-n,l=t-r,u=(o?a:-a)/d(c*c+l*l),f=u*l,p=-u*c,m=e+f,h=t+p,g=n+f,_=r+p,v=(m+g)/2,y=(h+_)/2,b=g-m,x=_-h,S=b*b+x*x,C=i-a,w=m*_-g*h,T=(x<0?-1:1)*d(s(0,C*C*S-w*w)),E=(w*x-b*T)/S,D=(-w*b-x*T)/S,O=(w*x+b*T)/S,k=(-w*b+x*T)/S,A=E-v,j=D-y,M=O-v,N=k-y;return A*A+j*j>M*M+N*N&&(E=O,D=k),{cx:E,cy:D,x01:-f,y01:-p,x11:E*(i/C-1),y11:D*(i/C-1)}}function x(){var s=m,x=h,S=e(0),C=null,w=g,T=_,E=v,D=null,O=t(k);function k(){var e,t,m=+s.apply(this,arguments),h=+x.apply(this,arguments),g=w.apply(this,arguments)-r,_=T.apply(this,arguments)-r,v=l(_-g),k=_>g;if(D||=e=O(),h<m&&(t=h,h=m,m=t),!(h>1e-12))D.moveTo(0,0);else if(v>c-1e-12)D.moveTo(h*u(g),h*a(g)),D.arc(0,0,h,g,_,!k),m>1e-12&&(D.moveTo(m*u(_),m*a(_)),D.arc(0,0,m,_,g,k));else{var A=g,j=_,M=g,N=_,P=v,F=v,I=E.apply(this,arguments)/2,L=I>1e-12&&(C?+C.apply(this,arguments):d(m*m+h*h)),R=p(l(h-m)/2,+S.apply(this,arguments)),z=R,B=R,V,H;if(L>1e-12){var U=o(L/m*a(I)),W=o(L/h*a(I));(P-=U*2)>1e-12?(U*=k?1:-1,M+=U,N-=U):(P=0,M=N=(g+_)/2),(F-=W*2)>1e-12?(W*=k?1:-1,A+=W,j-=W):(F=0,A=j=(g+_)/2)}var G=h*u(A),K=h*a(A),q=m*u(N),J=m*a(N);if(R>1e-12){var Y=h*u(j),X=h*a(j),Z=m*u(M),Q=m*a(M),$;if(v<i){if($=y(G,K,Z,Q,Y,X,q,J)){var ee=G-$[0],te=K-$[1],ne=Y-$[0],re=X-$[1],ie=1/a(f((ee*ne+te*re)/(d(ee*ee+te*te)*d(ne*ne+re*re)))/2),ae=d($[0]*$[0]+$[1]*$[1]);z=p(R,(m-ae)/(ie-1)),B=p(R,(h-ae)/(ie+1))}else z=B=0}}F>1e-12?B>1e-12?(V=b(Z,Q,G,K,h,B,k),H=b(Y,X,q,J,h,B,k),D.moveTo(V.cx+V.x01,V.cy+V.y01),B<R?D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,h,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),!k),D.arc(H.cx,H.cy,B,n(H.y11,H.x11),n(H.y01,H.x01),!k))):(D.moveTo(G,K),D.arc(0,0,h,A,j,!k)):D.moveTo(G,K),!(m>1e-12)||!(P>1e-12)?D.lineTo(q,J):z>1e-12?(V=b(q,J,Y,X,m,-z,k),H=b(G,K,Z,Q,m,-z,k),D.lineTo(V.cx+V.x01,V.cy+V.y01),z<R?D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,m,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),k),D.arc(H.cx,H.cy,z,n(H.y11,H.x11),n(H.y01,H.x01),!k))):D.arc(0,0,m,N,M,k)}if(D.closePath(),e)return D=null,e+``||null}return k.centroid=function(){var e=(+s.apply(this,arguments)+ +x.apply(this,arguments))/2,t=(+w.apply(this,arguments)+ +T.apply(this,arguments))/2-i/2;return[u(t)*e,a(t)*e]},k.innerRadius=function(t){return arguments.length?(s=typeof t==`function`?t:e(+t),k):s},k.outerRadius=function(t){return arguments.length?(x=typeof t==`function`?t:e(+t),k):x},k.cornerRadius=function(t){return arguments.length?(S=typeof t==`function`?t:e(+t),k):S},k.padRadius=function(t){return arguments.length?(C=t==null?null:typeof t==`function`?t:e(+t),k):C},k.startAngle=function(t){return arguments.length?(w=typeof t==`function`?t:e(+t),k):w},k.endAngle=function(t){return arguments.length?(T=typeof t==`function`?t:e(+t),k):T},k.padAngle=function(t){return arguments.length?(E=typeof t==`function`?t:e(+t),k):E},k.context=function(e){return arguments.length?(D=e??null,k):D},k}export{x as t};
1
+ import{n as e,t}from"./path-fybaL0A-.js";import{a as n,c as r,d as i,f as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,u as p}from"./dist-CrpGQKqw.js";function m(e){return e.innerRadius}function h(e){return e.outerRadius}function g(e){return e.startAngle}function _(e){return e.endAngle}function v(e){return e&&e.padAngle}function y(e,t,n,r,i,a,o,s){var c=n-e,l=r-t,u=o-i,d=s-a,f=d*c-u*l;if(!(f*f<1e-12))return f=(u*(t-a)-d*(e-i))/f,[e+f*c,t+f*l]}function b(e,t,n,r,i,a,o){var c=e-n,l=t-r,u=(o?a:-a)/d(c*c+l*l),f=u*l,p=-u*c,m=e+f,h=t+p,g=n+f,_=r+p,v=(m+g)/2,y=(h+_)/2,b=g-m,x=_-h,S=b*b+x*x,C=i-a,w=m*_-g*h,T=(x<0?-1:1)*d(s(0,C*C*S-w*w)),E=(w*x-b*T)/S,D=(-w*b-x*T)/S,O=(w*x+b*T)/S,k=(-w*b+x*T)/S,A=E-v,j=D-y,M=O-v,N=k-y;return A*A+j*j>M*M+N*N&&(E=O,D=k),{cx:E,cy:D,x01:-f,y01:-p,x11:E*(i/C-1),y11:D*(i/C-1)}}function x(){var s=m,x=h,S=e(0),C=null,w=g,T=_,E=v,D=null,O=t(k);function k(){var e,t,m=+s.apply(this,arguments),h=+x.apply(this,arguments),g=w.apply(this,arguments)-r,_=T.apply(this,arguments)-r,v=l(_-g),k=_>g;if(D||=e=O(),h<m&&(t=h,h=m,m=t),!(h>1e-12))D.moveTo(0,0);else if(v>c-1e-12)D.moveTo(h*u(g),h*a(g)),D.arc(0,0,h,g,_,!k),m>1e-12&&(D.moveTo(m*u(_),m*a(_)),D.arc(0,0,m,_,g,k));else{var A=g,j=_,M=g,N=_,P=v,F=v,I=E.apply(this,arguments)/2,L=I>1e-12&&(C?+C.apply(this,arguments):d(m*m+h*h)),R=p(l(h-m)/2,+S.apply(this,arguments)),z=R,B=R,V,H;if(L>1e-12){var U=o(L/m*a(I)),W=o(L/h*a(I));(P-=U*2)>1e-12?(U*=k?1:-1,M+=U,N-=U):(P=0,M=N=(g+_)/2),(F-=W*2)>1e-12?(W*=k?1:-1,A+=W,j-=W):(F=0,A=j=(g+_)/2)}var G=h*u(A),K=h*a(A),q=m*u(N),J=m*a(N);if(R>1e-12){var Y=h*u(j),X=h*a(j),Z=m*u(M),Q=m*a(M),$;if(v<i){if($=y(G,K,Z,Q,Y,X,q,J)){var ee=G-$[0],te=K-$[1],ne=Y-$[0],re=X-$[1],ie=1/a(f((ee*ne+te*re)/(d(ee*ee+te*te)*d(ne*ne+re*re)))/2),ae=d($[0]*$[0]+$[1]*$[1]);z=p(R,(m-ae)/(ie-1)),B=p(R,(h-ae)/(ie+1))}else z=B=0}}F>1e-12?B>1e-12?(V=b(Z,Q,G,K,h,B,k),H=b(Y,X,q,J,h,B,k),D.moveTo(V.cx+V.x01,V.cy+V.y01),B<R?D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,h,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),!k),D.arc(H.cx,H.cy,B,n(H.y11,H.x11),n(H.y01,H.x01),!k))):(D.moveTo(G,K),D.arc(0,0,h,A,j,!k)):D.moveTo(G,K),!(m>1e-12)||!(P>1e-12)?D.lineTo(q,J):z>1e-12?(V=b(q,J,Y,X,m,-z,k),H=b(G,K,Z,Q,m,-z,k),D.lineTo(V.cx+V.x01,V.cy+V.y01),z<R?D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,m,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),k),D.arc(H.cx,H.cy,z,n(H.y11,H.x11),n(H.y01,H.x01),!k))):D.arc(0,0,m,N,M,k)}if(D.closePath(),e)return D=null,e+``||null}return k.centroid=function(){var e=(+s.apply(this,arguments)+ +x.apply(this,arguments))/2,t=(+w.apply(this,arguments)+ +T.apply(this,arguments))/2-i/2;return[u(t)*e,a(t)*e]},k.innerRadius=function(t){return arguments.length?(s=typeof t==`function`?t:e(+t),k):s},k.outerRadius=function(t){return arguments.length?(x=typeof t==`function`?t:e(+t),k):x},k.cornerRadius=function(t){return arguments.length?(S=typeof t==`function`?t:e(+t),k):S},k.padRadius=function(t){return arguments.length?(C=t==null?null:typeof t==`function`?t:e(+t),k):C},k.startAngle=function(t){return arguments.length?(w=typeof t==`function`?t:e(+t),k):w},k.endAngle=function(t){return arguments.length?(T=typeof t==`function`?t:e(+t),k):T},k.padAngle=function(t){return arguments.length?(E=typeof t==`function`?t:e(+t),k):E},k.context=function(e){return arguments.length?(D=e??null,k):D},k}export{x as t};
@@ -1 +1 @@
1
- import"./chunk-NGNAAXSQ-C2Wy9Xmz.js";export{M as createArchitectureServices}from"./mermaid-parser.core-gIvgB9WK.js";
1
+ import"./chunk-NGNAAXSQ-C2Wy9Xmz.js";export{M as createArchitectureServices}from"./mermaid-parser.core-MEuwYVot.js";