@covro/covro 0.3.1-dev.1 → 0.3.1-dev.3

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 (130) hide show
  1. package/README.md +16 -10
  2. package/README.zh-CN.md +16 -10
  3. package/dist/drizzle/0006_project_order.sql +8 -0
  4. package/dist/drizzle/meta/0006_snapshot.json +488 -0
  5. package/dist/drizzle/meta/_journal.json +7 -0
  6. package/dist/server/config-store.js +10 -2
  7. package/dist/server/config-store.js.map +2 -2
  8. package/dist/server/config.js +4 -0
  9. package/dist/server/config.js.map +2 -2
  10. package/dist/server/db/schema.js +1 -0
  11. package/dist/server/db/schema.js.map +2 -2
  12. package/dist/server/http.js +43 -5
  13. package/dist/server/http.js.map +2 -2
  14. package/dist/server/local-files.js.map +1 -1
  15. package/dist/server/project-clones.js +2 -2
  16. package/dist/server/project-clones.js.map +2 -2
  17. package/dist/server/project-paths.js +39 -0
  18. package/dist/server/project-paths.js.map +7 -0
  19. package/dist/server/projects.js +48 -5
  20. package/dist/server/projects.js.map +2 -2
  21. package/dist/server/service.js +15 -3
  22. package/dist/server/service.js.map +2 -2
  23. package/dist/server/text-files.js +32 -0
  24. package/dist/server/text-files.js.map +7 -0
  25. package/dist/shared/file-preview.js +22 -0
  26. package/dist/shared/file-preview.js.map +7 -0
  27. package/dist/shared/project-path.js +8 -0
  28. package/dist/shared/project-path.js.map +7 -0
  29. package/dist/shared/release-notes.js +9 -0
  30. package/dist/shared/release-notes.js.map +7 -0
  31. package/dist/shared/updates.js.map +2 -2
  32. package/dist/shared/validation.js +2 -0
  33. package/dist/shared/validation.js.map +2 -2
  34. package/dist/update-worker.cjs +8 -3
  35. package/dist/updates/manager.js +7 -4
  36. package/dist/updates/manager.js.map +2 -2
  37. package/dist/updates/registry.js +21 -9
  38. package/dist/updates/registry.js.map +3 -3
  39. package/dist/updates/release-notes.js +73 -0
  40. package/dist/updates/release-notes.js.map +7 -0
  41. package/dist/updates/worker.js +3 -3
  42. package/dist/updates/worker.js.map +2 -2
  43. package/dist/web/assets/{abnfDiagram-WEYOIA3C-DLvlob5t.js → abnfDiagram-WEYOIA3C-CgSmgOr1.js} +1 -1
  44. package/dist/web/assets/{arc-DgauwgFe.js → arc-DHf4CdSk.js} +1 -1
  45. package/dist/web/assets/{architecture-WOLXFQ4H-DvjLv0QN.js → architecture-WOLXFQ4H-DMTD1pHe.js} +1 -1
  46. package/dist/web/assets/{architectureDiagram-ZHVYKT53-BAyZGlzu.js → architectureDiagram-ZHVYKT53-DTR8wiWo.js} +1 -1
  47. package/dist/web/assets/{blockDiagram-RJAE7QA3-BVfkmjlt.js → blockDiagram-RJAE7QA3-DcNiTPKZ.js} +1 -1
  48. package/dist/web/assets/{c4Diagram-XDPPPE54-rTsfyMoB.js → c4Diagram-XDPPPE54-BDxJVXjQ.js} +1 -1
  49. package/dist/web/assets/channel-B6d61z43.js +1 -0
  50. package/dist/web/assets/{chunk-2E7WHVMD-CQ_N_vLS.js → chunk-2E7WHVMD-D5oKHRGT.js} +1 -1
  51. package/dist/web/assets/{chunk-4EMNKR2T-wBy_gyo6.js → chunk-4EMNKR2T-CtrbVCM-.js} +1 -1
  52. package/dist/web/assets/{chunk-55XCU76K-DYiwIhmI.js → chunk-55XCU76K-Dhl7DEL7.js} +1 -1
  53. package/dist/web/assets/{chunk-7S6XSTFO-CRGtfVHg.js → chunk-7S6XSTFO-C8EwegP-.js} +1 -1
  54. package/dist/web/assets/{chunk-AQDTSKZB-1G2Za6bm.js → chunk-AQDTSKZB-lFiNKr7B.js} +1 -1
  55. package/dist/web/assets/{chunk-DSNLSHJZ-B1LLoYuG.js → chunk-DSNLSHJZ-B8GftONA.js} +1 -1
  56. package/dist/web/assets/{chunk-HAGFOTED-78h1RpHh.js → chunk-HAGFOTED-Cnc2mh7_.js} +1 -1
  57. package/dist/web/assets/{chunk-HNE4Q36P-DmR5B27Q.js → chunk-HNE4Q36P-BKl6ZgI0.js} +1 -1
  58. package/dist/web/assets/{chunk-NQOKRVIF-D7WSEPzg.js → chunk-NQOKRVIF-qKlxSw3D.js} +1 -1
  59. package/dist/web/assets/{chunk-UHW7PFBP-gl7a5V-l.js → chunk-UHW7PFBP-C_zh3mNe.js} +1 -1
  60. package/dist/web/assets/{chunk-VQ5W62QI-KaBXxBre.js → chunk-VQ5W62QI-BXoyXK0q.js} +1 -1
  61. package/dist/web/assets/{chunk-WQQL4CDK-DDczFoOr.js → chunk-WQQL4CDK-BBeqcU1J.js} +1 -1
  62. package/dist/web/assets/{chunk-XXDRQBXY-3ug4Qhxg.js → chunk-XXDRQBXY-DzssZtz_.js} +1 -1
  63. package/dist/web/assets/{chunk-YZO67HFG-BpWOuCXP.js → chunk-YZO67HFG-BbNSwLjS.js} +1 -1
  64. package/dist/web/assets/{chunk-ZAUX2LTX-1ojPb1if.js → chunk-ZAUX2LTX-CjURwZfv.js} +1 -1
  65. package/dist/web/assets/{chunk-ZCHMQSOR-D2kK2cPj.js → chunk-ZCHMQSOR-u39dymjE.js} +1 -1
  66. package/dist/web/assets/{classDiagram-v2-4MYWR3UA-B7eMvxAO.js → classDiagram-v2-4MYWR3UA-BEXx5gKT.js} +1 -1
  67. package/dist/web/assets/{cose-bilkent-JH36ORCC-BtB8mbt8.js → cose-bilkent-JH36ORCC-BxDEucP_.js} +1 -1
  68. package/dist/web/assets/{cynefin-EF2NZ3EQ-CIctqxlE.js → cynefin-EF2NZ3EQ-BhkCsT6-.js} +1 -1
  69. package/dist/web/assets/{cynefinDiagram-WF24UDRP-qat2GD9P.js → cynefinDiagram-WF24UDRP-Wpu-yNke.js} +1 -1
  70. package/dist/web/assets/{dagre-NK4GIZVX-OJamzzID.js → dagre-NK4GIZVX-LNSSIN4l.js} +1 -1
  71. package/dist/web/assets/{diagram-CBK3MWTC-C7cX2tqO.js → diagram-CBK3MWTC-BVDr5Vx9.js} +1 -1
  72. package/dist/web/assets/{diagram-I5XIIV2D-DsMfKVN7.js → diagram-I5XIIV2D-MnLzR1Rv.js} +1 -1
  73. package/dist/web/assets/{diagram-ODIL2UCW-Cz66FxdJ.js → diagram-ODIL2UCW-CZ4igbo_.js} +1 -1
  74. package/dist/web/assets/{diagram-PFBEJUXE-CwhPuwKj.js → diagram-PFBEJUXE-4hCnyMdK.js} +1 -1
  75. package/dist/web/assets/{diagram-RJA3I4VV-C52IGiFJ.js → diagram-RJA3I4VV-DTo42rGA.js} +1 -1
  76. package/dist/web/assets/{diagram-TYUNFSNR-C2LZVLKY.js → diagram-TYUNFSNR-BC12iCUZ.js} +1 -1
  77. package/dist/web/assets/{dist-Bxu8YbZb.js → dist-Dg_ysSxT.js} +1 -1
  78. package/dist/web/assets/{ebnfDiagram-V4P3TTPT-eQKKlMli.js → ebnfDiagram-V4P3TTPT-Du8LCQ31.js} +1 -1
  79. package/dist/web/assets/{elk-QONTBCTQ-C5kIOZTA.js → elk-QONTBCTQ-BzTAR-T1.js} +1 -1
  80. package/dist/web/assets/{erDiagram-KYQIGQAA-CMTowz5P.js → erDiagram-KYQIGQAA-SXYIjNOP.js} +1 -1
  81. package/dist/web/assets/{eventmodeling-K75KTNOO-C5v-UF8X.js → eventmodeling-K75KTNOO-Sbno3ZxQ.js} +1 -1
  82. package/dist/web/assets/flowDiagram-IUGLLWBU-Ae1H3vSR.js +1 -0
  83. package/dist/web/assets/{ganttDiagram-R7GPNTJY-B0viiC-b.js → ganttDiagram-R7GPNTJY-DBeX1qmu.js} +1 -1
  84. package/dist/web/assets/{gitGraph-VSP46ZUC-tEjFmPhN.js → gitGraph-VSP46ZUC-CKWihueS.js} +1 -1
  85. package/dist/web/assets/{gitGraphDiagram-PDYL7XHY-CsOwt7jz.js → gitGraphDiagram-PDYL7XHY-Cj1E3jqN.js} +1 -1
  86. package/dist/web/assets/index-CtTuHkNv.js +147 -0
  87. package/dist/web/assets/index-DwnjYADO.css +1 -0
  88. package/dist/web/assets/{info-OHQRW6UA-DnFGu4Ew.js → info-OHQRW6UA-D0w3nR0p.js} +1 -1
  89. package/dist/web/assets/{infoDiagram-MVDRKAX5-B6WiNaDF.js → infoDiagram-MVDRKAX5-F0jTCG-G.js} +1 -1
  90. package/dist/web/assets/{ishikawaDiagram-HPEHV2GE-Dn70fI1r.js → ishikawaDiagram-HPEHV2GE-CwQGP9AT.js} +1 -1
  91. package/dist/web/assets/{journeyDiagram-BOSHW7O7-BUjYzV2f.js → journeyDiagram-BOSHW7O7-CPY5GqD2.js} +1 -1
  92. package/dist/web/assets/{kanban-definition-FNSA4HC5-BDMfWbtB.js → kanban-definition-FNSA4HC5-BCL38eXh.js} +1 -1
  93. package/dist/web/assets/{line-DNSRZHBK.js → line-DoUzbVJS.js} +1 -1
  94. package/dist/web/assets/{linear-CrS49q6J.js → linear-LoqU-SEO.js} +1 -1
  95. package/dist/web/assets/{mermaid-parser.core-DXuyO8Px.js → mermaid-parser.core-CvO-MTG1.js} +3 -3
  96. package/dist/web/assets/{mermaid.core-DUTnbQkq.js → mermaid.core-DcCEGt0V.js} +4 -4
  97. package/dist/web/assets/{mindmap-definition-6OY57UG3-CqZTtItJ.js → mindmap-definition-6OY57UG3-yZvSibNz.js} +1 -1
  98. package/dist/web/assets/{packet-JDAUHWVQ-DXEZgY0a.js → packet-JDAUHWVQ-9ZiCegsV.js} +1 -1
  99. package/dist/web/assets/{pegDiagram-ECIUJNBX-D6CCPNem.js → pegDiagram-ECIUJNBX-BkGwBoEk.js} +1 -1
  100. package/dist/web/assets/{pie-XZMESJXO-AXRFjZ4G.js → pie-XZMESJXO-kAXIwFnU.js} +1 -1
  101. package/dist/web/assets/{pieDiagram-GNMPY74T-B9Ss8_5s.js → pieDiagram-GNMPY74T-jiwTgtdb.js} +1 -1
  102. package/dist/web/assets/{quadrantDiagram-D57K4MC3-JrlylCtz.js → quadrantDiagram-D57K4MC3-u9HdbUwr.js} +1 -1
  103. package/dist/web/assets/{radar-ABXABTNO-ChFm4hZg.js → radar-ABXABTNO-BQ911CvQ.js} +1 -1
  104. package/dist/web/assets/{railroad-I3PHUGI6-DaXXzqhZ.js → railroad-I3PHUGI6-Bvm7MWf9.js} +1 -1
  105. package/dist/web/assets/{railroad-abnf-LNEFI6M7-DGE67q11.js → railroad-abnf-LNEFI6M7-BfFmWnzu.js} +1 -1
  106. package/dist/web/assets/{railroad-ebnf-DWYD2UWJ-Cq9S3q72.js → railroad-ebnf-DWYD2UWJ-B8Ekz4aD.js} +1 -1
  107. package/dist/web/assets/{railroad-peg-JR7BVNR7-D2Gth3eY.js → railroad-peg-JR7BVNR7-B5ANjRbC.js} +1 -1
  108. package/dist/web/assets/{railroadDiagram-Y72NRBL7-BpkXX59H.js → railroadDiagram-Y72NRBL7-iu8Hmuma.js} +1 -1
  109. package/dist/web/assets/{requirementDiagram-EQYSW5RA-oNp3DMM4.js → requirementDiagram-EQYSW5RA-DgiEaaYZ.js} +1 -1
  110. package/dist/web/assets/{sankeyDiagram-SY24JHO5-bHfheSKO.js → sankeyDiagram-SY24JHO5-KzDvhd8J.js} +1 -1
  111. package/dist/web/assets/{sequenceDiagram-BLEHNHQU-CEM2XfNF.js → sequenceDiagram-BLEHNHQU-DJMSHuO_.js} +1 -1
  112. package/dist/web/assets/{src-KjMctvzy.js → src-C5WkvxTS.js} +1 -1
  113. package/dist/web/assets/{stateDiagram-v2-A6IESKWZ-D_TaR_ix.js → stateDiagram-v2-A6IESKWZ-CyfHfUyU.js} +1 -1
  114. package/dist/web/assets/{swimlanes-B3ENRKFQ-BUYl2fsg.js → swimlanes-B3ENRKFQ-YPSzHf2U.js} +1 -1
  115. package/dist/web/assets/swimlanesDiagram-AYQRV4AK-D2_NQS-o.js +8 -0
  116. package/dist/web/assets/{timeline-definition-JXYKGLGB-CpKsGN6d.js → timeline-definition-JXYKGLGB-BwvPIiSj.js} +1 -1
  117. package/dist/web/assets/{treeView-D4JQ5SDB-Dioaagqt.js → treeView-D4JQ5SDB-DsUhEw24.js} +1 -1
  118. package/dist/web/assets/{treemap-SAJKECNS-B8NLQ14o.js → treemap-SAJKECNS-D5NThB4V.js} +1 -1
  119. package/dist/web/assets/{usecaseDiagram-WPOLBNNX-CfwdxcsG.js → usecaseDiagram-WPOLBNNX-fLWGvuS0.js} +1 -1
  120. package/dist/web/assets/{vennDiagram-Q3Y3IDCW-DQoKGtXo.js → vennDiagram-Q3Y3IDCW-DFzlk_u2.js} +1 -1
  121. package/dist/web/assets/{wardley-7MLQ67FV-DQHLHmeZ.js → wardley-7MLQ67FV-0uG-noJX.js} +1 -1
  122. package/dist/web/assets/{wardleyDiagram-IVAIDKWA-DV-lq7zb.js → wardleyDiagram-IVAIDKWA-DfEQPTLg.js} +1 -1
  123. package/dist/web/assets/{xychartDiagram-4URNHDU4-wV4ueoGC.js → xychartDiagram-4URNHDU4-BXVsWbL0.js} +1 -1
  124. package/dist/web/index.html +2 -2
  125. package/package.json +4 -4
  126. package/dist/web/assets/channel-GGfPocHk.js +0 -1
  127. package/dist/web/assets/flowDiagram-IUGLLWBU-C-jE8afx.js +0 -1
  128. package/dist/web/assets/index-COSho7m2.css +0 -1
  129. package/dist/web/assets/index-D7GZPtTj.js +0 -147
  130. package/dist/web/assets/swimlanesDiagram-AYQRV4AK-DDLmyR4x.js +0 -8
@@ -0,0 +1,32 @@
1
+ import { AppError } from "../shared/errors.js";
2
+ import { filePreviewFormat, PLAIN_TEXT_EXTENSIONS } from "../shared/file-preview.js";
3
+ import { readLocalFile } from "./local-files.js";
4
+ const MAX_TEXT_BYTES = 2 * 1024 * 1024;
5
+ async function readLocalText(path, scope) {
6
+ const file = await readLocalFile(path, scope, {
7
+ code: "TEXT",
8
+ label: "\u6587\u672C",
9
+ maxBytes: MAX_TEXT_BYTES,
10
+ sizeError: "\u6587\u672C\u6587\u4EF6\u8D85\u8FC7 2 MiB \u9884\u89C8\u9650\u5236",
11
+ validatePath(candidate) {
12
+ if (filePreviewFormat(candidate) !== "text")
13
+ throw new AppError(
14
+ "UNSUPPORTED_TEXT_TYPE",
15
+ `\u4EC5\u652F\u6301 ${PLAIN_TEXT_EXTENSIONS.map((extension) => `.${extension}`).join("\u3001")} \u6587\u4EF6`,
16
+ 415
17
+ );
18
+ }
19
+ });
20
+ try {
21
+ const content = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(file.bytes);
22
+ if (content.includes("\0")) throw new Error("Binary content");
23
+ return { path: file.path, content };
24
+ } catch {
25
+ throw new AppError("INVALID_TEXT_CONTENT", "\u6587\u4EF6\u4E0D\u662F\u6709\u6548\u7684 UTF-8 \u7EAF\u6587\u672C", 415);
26
+ }
27
+ }
28
+ export {
29
+ MAX_TEXT_BYTES,
30
+ readLocalText
31
+ };
32
+ //# sourceMappingURL=text-files.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/server/text-files.ts"],
4
+ "sourcesContent": ["import { AppError } from '../shared/errors.js';\nimport { filePreviewFormat, PLAIN_TEXT_EXTENSIONS } from '../shared/file-preview.js';\nimport type { TextFile } from '../shared/types.js';\nimport { readLocalFile, type FileScope } from './local-files.js';\n\nexport const MAX_TEXT_BYTES = 2 * 1024 * 1024;\n\nexport async function readLocalText(path: string | undefined, scope: FileScope): Promise<TextFile> {\n const file = await readLocalFile(path, scope, {\n code: 'TEXT',\n label: '\u6587\u672C',\n maxBytes: MAX_TEXT_BYTES,\n sizeError: '\u6587\u672C\u6587\u4EF6\u8D85\u8FC7 2 MiB \u9884\u89C8\u9650\u5236',\n validatePath(candidate) {\n if (filePreviewFormat(candidate) !== 'text')\n throw new AppError(\n 'UNSUPPORTED_TEXT_TYPE',\n `\u4EC5\u652F\u6301 ${PLAIN_TEXT_EXTENSIONS.map((extension) => `.${extension}`).join('\u3001')} \u6587\u4EF6`,\n 415,\n );\n },\n });\n try {\n const content = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(file.bytes);\n if (content.includes('\\0')) throw new Error('Binary content');\n return { path: file.path, content };\n } catch {\n throw new AppError('INVALID_TEXT_CONTENT', '\u6587\u4EF6\u4E0D\u662F\u6709\u6548\u7684 UTF-8 \u7EAF\u6587\u672C', 415);\n }\n}\n"],
5
+ "mappings": "AAAA,SAAS,gBAAgB;AACzB,SAAS,mBAAmB,6BAA6B;AAEzD,SAAS,qBAAqC;AAEvC,MAAM,iBAAiB,IAAI,OAAO;AAEzC,eAAsB,cAAc,MAA0B,OAAqC;AACjG,QAAM,OAAO,MAAM,cAAc,MAAM,OAAO;AAAA,IAC5C,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,WAAW;AAAA,IACX,aAAa,WAAW;AACtB,UAAI,kBAAkB,SAAS,MAAM;AACnC,cAAM,IAAI;AAAA,UACR;AAAA,UACA,sBAAO,sBAAsB,IAAI,CAAC,cAAc,IAAI,SAAS,EAAE,EAAE,KAAK,QAAG,CAAC;AAAA,UAC1E;AAAA,QACF;AAAA,IACJ;AAAA,EACF,CAAC;AACD,MAAI;AACF,UAAM,UAAU,IAAI,YAAY,SAAS,EAAE,OAAO,MAAM,WAAW,KAAK,CAAC,EAAE,OAAO,KAAK,KAAK;AAC5F,QAAI,QAAQ,SAAS,IAAI,EAAG,OAAM,IAAI,MAAM,gBAAgB;AAC5D,WAAO,EAAE,MAAM,KAAK,MAAM,QAAQ;AAAA,EACpC,QAAQ;AACN,UAAM,IAAI,SAAS,wBAAwB,uEAAqB,GAAG;AAAA,EACrE;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,22 @@
1
+ const PLAIN_TEXT_EXTENSIONS = [
2
+ "txt",
3
+ "csv",
4
+ "tsv",
5
+ "toml",
6
+ "yaml",
7
+ "yml",
8
+ "jsonl",
9
+ "log",
10
+ "ini"
11
+ ];
12
+ function filePreviewFormat(path) {
13
+ if (/\.(md|markdown)$/i.test(path)) return "markdown";
14
+ if (/\.json$/i.test(path)) return "json";
15
+ const extension = /\.([^./\\]+)$/.exec(path)?.[1]?.toLowerCase();
16
+ return PLAIN_TEXT_EXTENSIONS.some((value) => value === extension) ? "text" : void 0;
17
+ }
18
+ export {
19
+ PLAIN_TEXT_EXTENSIONS,
20
+ filePreviewFormat
21
+ };
22
+ //# sourceMappingURL=file-preview.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/shared/file-preview.ts"],
4
+ "sourcesContent": ["/** Formats rendered literally, without parsing, executing or rewriting their contents. */\nexport const PLAIN_TEXT_EXTENSIONS = [\n 'txt',\n 'csv',\n 'tsv',\n 'toml',\n 'yaml',\n 'yml',\n 'jsonl',\n 'log',\n 'ini',\n] as const;\n\nexport function filePreviewFormat(path: string): 'markdown' | 'json' | 'text' | undefined {\n if (/\\.(md|markdown)$/i.test(path)) return 'markdown';\n if (/\\.json$/i.test(path)) return 'json';\n const extension = /\\.([^./\\\\]+)$/.exec(path)?.[1]?.toLowerCase();\n return PLAIN_TEXT_EXTENSIONS.some((value) => value === extension) ? 'text' : undefined;\n}\n"],
5
+ "mappings": "AACO,MAAM,wBAAwB;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,SAAS,kBAAkB,MAAwD;AACxF,MAAI,oBAAoB,KAAK,IAAI,EAAG,QAAO;AAC3C,MAAI,WAAW,KAAK,IAAI,EAAG,QAAO;AAClC,QAAM,YAAY,gBAAgB,KAAK,IAAI,IAAI,CAAC,GAAG,YAAY;AAC/D,SAAO,sBAAsB,KAAK,CAAC,UAAU,UAAU,SAAS,IAAI,SAAS;AAC/E;",
6
+ "names": []
7
+ }
@@ -0,0 +1,8 @@
1
+ function repositoryDirectory(repository) {
2
+ const name = repository.trim().replace(/\/+$/, "").split(/[/:]/).pop()?.replace(/\.git$/, "") ?? "";
3
+ return name && name !== "." && name !== ".." && !/[\\\s?#\0]/.test(name) ? name : "";
4
+ }
5
+ export {
6
+ repositoryDirectory
7
+ };
8
+ //# sourceMappingURL=project-path.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/shared/project-path.ts"],
4
+ "sourcesContent": ["/** A suggestion only; repository validation still runs before starting Git. */\nexport function repositoryDirectory(repository: string): string {\n const name =\n repository\n .trim()\n .replace(/\\/+$/, '')\n .split(/[/:]/)\n .pop()\n ?.replace(/\\.git$/, '') ?? '';\n return name && name !== '.' && name !== '..' && !/[\\\\\\s?#\\0]/.test(name) ? name : '';\n}\n"],
5
+ "mappings": "AACO,SAAS,oBAAoB,YAA4B;AAC9D,QAAM,OACJ,WACG,KAAK,EACL,QAAQ,QAAQ,EAAE,EAClB,MAAM,MAAM,EACZ,IAAI,GACH,QAAQ,UAAU,EAAE,KAAK;AAC/B,SAAO,QAAQ,SAAS,OAAO,SAAS,QAAQ,CAAC,aAAa,KAAK,IAAI,IAAI,OAAO;AACpF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,9 @@
1
+ const releasesUrl = "https://github.com/yuzheng14/covro/releases";
2
+ function releaseNotesUrl(version) {
3
+ return `${releasesUrl}/tag/${encodeURIComponent(`v${version}`)}`;
4
+ }
5
+ export {
6
+ releaseNotesUrl,
7
+ releasesUrl
8
+ };
9
+ //# sourceMappingURL=release-notes.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/shared/release-notes.ts"],
4
+ "sourcesContent": ["export const releasesUrl = 'https://github.com/yuzheng14/covro/releases';\n\nexport function releaseNotesUrl(version: string) {\n return `${releasesUrl}/tag/${encodeURIComponent(`v${version}`)}`;\n}\n\nexport type ReleaseNotes = { version: string; url: string } & (\n | { state: 'available'; body: string }\n | { state: 'empty' }\n | { state: 'missing' }\n | { state: 'error'; reason: 'unavailable' | 'rateLimited' }\n);\n"],
5
+ "mappings": "AAAO,MAAM,cAAc;AAEpB,SAAS,gBAAgB,SAAiB;AAC/C,SAAO,GAAG,WAAW,QAAQ,mBAAmB,IAAI,OAAO,EAAE,CAAC;AAChE;",
6
+ "names": []
7
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/shared/updates.ts"],
4
- "sourcesContent": ["import type {\n CodexCompatibility,\n CodexCompatibilityManifest,\n CodexUpdateConfirmation,\n} from './codex-compatibility.js';\nexport const releaseChannels = ['stable', 'beta', 'dev'] as const;\nexport type ReleaseChannel = (typeof releaseChannels)[number];\nexport interface UpdateSettings {\n channel: ReleaseChannel;\n automatic: boolean;\n}\nexport type UpdatePhase =\n 'installing' | 'waiting' | 'stopping' | 'verifying' | 'succeeded' | 'rolledBack' | 'failed';\nexport interface UpdateRun {\n id: string;\n from: string;\n target: string;\n channel: ReleaseChannel;\n phase: UpdatePhase;\n message: string;\n startedAt: number;\n updatedAt: number;\n committed?: boolean;\n codex?: { version: string; manifest: CodexCompatibilityManifest; confirmedUnverified: boolean };\n}\nexport interface UpdateStatus {\n version: string;\n commit?: string;\n source: 'npm';\n codex: CodexCompatibility;\n settings: UpdateSettings;\n available?: {\n version: string;\n channel: ReleaseChannel;\n commit?: string;\n downgrade: boolean;\n codex: CodexCompatibility;\n };\n checkedAt?: number;\n checkError?: string;\n supported: boolean;\n unsupportedReason?: string;\n run?: UpdateRun;\n}\nexport const updateActive = (run?: UpdateRun) =>\n Boolean(run && ['installing', 'waiting', 'stopping', 'verifying'].includes(run.phase));\nexport interface UpdateController {\n status(): Promise<UpdateStatus>;\n check(channel?: ReleaseChannel): Promise<UpdateStatus>;\n configure(settings: UpdateSettings): Promise<UpdateStatus>;\n start(input: {\n clientOperationId: string;\n channel?: ReleaseChannel;\n allowDowngrade?: boolean;\n codexConfirmation?: CodexUpdateConfirmation;\n }): Promise<UpdateStatus>;\n close(): void;\n}\n"],
5
- "mappings": "AAKO,MAAM,kBAAkB,CAAC,UAAU,QAAQ,KAAK;AAuChD,MAAM,eAAe,CAAC,QAC3B,QAAQ,OAAO,CAAC,cAAc,WAAW,YAAY,WAAW,EAAE,SAAS,IAAI,KAAK,CAAC;",
4
+ "sourcesContent": ["import type {\n CodexCompatibility,\n CodexCompatibilityManifest,\n CodexUpdateConfirmation,\n} from './codex-compatibility.js';\nexport const releaseChannels = ['stable', 'beta', 'dev'] as const;\nexport type ReleaseChannel = (typeof releaseChannels)[number];\nexport interface UpdateSettings {\n channel: ReleaseChannel;\n automatic: boolean;\n}\nexport type UpdatePhase =\n 'installing' | 'waiting' | 'stopping' | 'verifying' | 'succeeded' | 'rolledBack' | 'failed';\nexport interface UpdateRun {\n id: string;\n from: string;\n target: string;\n /** Subscribed channel after activation, independent of the candidate's source. */\n channel: ReleaseChannel;\n /** Optional for update records created by older versions. */\n sourceChannel?: ReleaseChannel;\n commit?: string;\n phase: UpdatePhase;\n message: string;\n startedAt: number;\n updatedAt: number;\n committed?: boolean;\n codex?: { version: string; manifest: CodexCompatibilityManifest; confirmedUnverified: boolean };\n}\nexport interface UpdateStatus {\n version: string;\n commit?: string;\n source: 'npm';\n codex: CodexCompatibility;\n settings: UpdateSettings;\n available?: {\n version: string;\n requestedChannel: ReleaseChannel;\n /** Actual npm source of the selected version. */\n channel: ReleaseChannel;\n commit?: string;\n downgrade: boolean;\n codex: CodexCompatibility;\n };\n checkedAt?: number;\n checkError?: string;\n supported: boolean;\n unsupportedReason?: string;\n run?: UpdateRun;\n}\nexport const updateActive = (run?: UpdateRun) =>\n Boolean(run && ['installing', 'waiting', 'stopping', 'verifying'].includes(run.phase));\nexport interface UpdateController {\n status(): Promise<UpdateStatus>;\n check(channel?: ReleaseChannel): Promise<UpdateStatus>;\n configure(settings: UpdateSettings): Promise<UpdateStatus>;\n start(input: {\n clientOperationId: string;\n channel?: ReleaseChannel;\n allowDowngrade?: boolean;\n codexConfirmation?: CodexUpdateConfirmation;\n }): Promise<UpdateStatus>;\n close(): void;\n}\n"],
5
+ "mappings": "AAKO,MAAM,kBAAkB,CAAC,UAAU,QAAQ,KAAK;AA6ChD,MAAM,eAAe,CAAC,QAC3B,QAAQ,OAAO,CAAC,cAAc,WAAW,YAAY,WAAW,EAAE,SAAS,IAAI,KAAK,CAAC;",
6
6
  "names": []
7
7
  }
@@ -11,6 +11,7 @@ const cloneProjectSchema = createProjectSchema.extend({
11
11
  repository: z.string().trim().min(1).max(4096)
12
12
  });
13
13
  const removeProjectSchema = z.object({}).strict();
14
+ const reorderProjectsSchema = z.object({ projectIds: z.array(idSchema).refine((ids) => new Set(ids).size === ids.length) }).strict();
14
15
  const settingsSchema = z.object({
15
16
  model: z.string().min(1).max(200).optional(),
16
17
  reasoningEffort: z.string().min(1).max(40).optional(),
@@ -108,6 +109,7 @@ export {
108
109
  removeProjectSchema,
109
110
  renameProjectSchema,
110
111
  renameThreadSchema,
112
+ reorderProjectsSchema,
111
113
  resolveActionSchema,
112
114
  resumeThreadSchema,
113
115
  saveModelDefaultsSchema,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/shared/validation.ts"],
4
- "sourcesContent": ["import { z } from 'zod';\nimport { imageDataBytes, MAX_IMAGE_BYTES, MAX_IMAGES } from './images.js';\nimport type { TaskMessage } from './types.js';\nimport { threadNameError } from './thread-name.js';\nexport const cursorSchema = z.string().min(1).max(4096);\nexport const idSchema = z.string().min(1).max(256);\nconst projectNameSchema = z.string().trim().min(1).max(100);\nexport const createProjectSchema = z\n .object({ path: z.string().trim().min(1).max(4096), name: projectNameSchema.optional() })\n .strict();\nexport const renameProjectSchema = z.object({ name: projectNameSchema }).strict();\nexport const cloneProjectSchema = createProjectSchema.extend({\n clientOperationId: z.string().uuid(),\n repository: z.string().trim().min(1).max(4096),\n});\nexport const removeProjectSchema = z.object({}).strict();\nexport const settingsSchema = z\n .object({\n model: z.string().min(1).max(200).optional(),\n reasoningEffort: z.string().min(1).max(40).optional(),\n serviceTier: z.literal('fast').nullable().optional(),\n permissionMode: z.enum(['ask', 'auto-review', 'full-access', 'read-only']).optional(),\n approvalPolicy: z.enum(['untrusted', 'on-request', 'never']).optional(),\n approvalReviewer: z.enum(['user', 'auto_review']).optional(),\n sandbox: z.enum(['read-only', 'workspace-write', 'danger-full-access']).optional(),\n })\n .strict()\n .refine(\n (settings) =>\n settings.permissionMode === undefined ||\n (settings.sandbox === undefined &&\n settings.approvalPolicy === undefined &&\n settings.approvalReviewer === undefined),\n '\u6743\u9650\u6A21\u5F0F\u4E0D\u80FD\u4E0E\u72EC\u7ACB\u7684\u6743\u9650\u3001\u5BA1\u6279\u7B56\u7565\u6216\u5BA1\u6838\u65B9\u540C\u65F6\u8BBE\u7F6E',\n );\nexport const operationSchema = z.object({ clientOperationId: z.string().uuid() }).strict();\nexport const saveModelDefaultsSchema = operationSchema.extend({\n settings: z\n .object({\n model: z.string().min(1).max(200),\n reasoningEffort: z.string().min(1).max(40).nullable(),\n })\n .strict(),\n});\nexport const startReviewSchema = operationSchema;\nexport const confirmCompatibilitySchema = operationSchema.extend({\n codexEpoch: idSchema,\n codexVersion: z.string().min(1).max(200),\n verifiedVersion: z.string().min(1).max(200),\n confirm: z.literal(true),\n});\nexport const createThreadSchema = operationSchema.extend({ settings: settingsSchema.optional() });\nexport const forkThreadSchema = createThreadSchema;\nexport const renameThreadSchema = operationSchema.extend({\n name: z\n .string()\n .superRefine((name, context) => {\n const message = threadNameError(name);\n if (message) context.addIssue({ code: 'custom', message });\n })\n .transform((name) => name.trim()),\n});\nexport const resumeThreadSchema = createThreadSchema.extend({\n confirmExternalStopped: z.boolean().optional(),\n});\nconst taskFields = {\n text: z.string().max(100_000),\n images: z\n .array(z.string().refine((value) => imageDataBytes(value) !== undefined, 'Invalid image'))\n .max(MAX_IMAGES)\n .refine(\n (images) =>\n images.reduce((sum, image) => sum + (imageDataBytes(image) ?? Infinity), 0) <=\n MAX_IMAGE_BYTES,\n 'Images exceed size limit',\n )\n .optional(),\n};\nconst hasContent = (input: TaskMessage) => Boolean(input.text.trim() || input.images?.length);\nexport const startTurnSchema = createThreadSchema\n .extend({\n ...taskFields,\n })\n .refine(hasContent, 'Text or an image is required');\nexport const steerSchema = operationSchema\n .extend({\n expectedTurnId: idSchema,\n ...taskFields,\n })\n .refine(hasContent, 'Text or an image is required');\nexport const interruptSchema = operationSchema.extend({ expectedTurnId: idSchema });\nconst elicitationValueSchema = z.union([\n z.string().max(10_000),\n z.number().finite(),\n z.boolean(),\n z.array(z.string().max(10_000)).max(500),\n]);\nexport const resolveActionSchema = operationSchema.extend({\n resolution: z.union([\n z\n .object({\n decision: z.string().min(1).max(200),\n content: z.record(z.string().max(1000), elicitationValueSchema).optional(),\n persist: z.literal('session').optional(),\n })\n .strict(),\n z.object({ answers: z.record(z.string(), z.array(z.string().max(10_000)).max(50)) }).strict(),\n ]),\n});\nexport const reconcileSchema = operationSchema.extend({ confirmEnded: z.literal(true) });\nexport const subscribeSchema = z\n .object({\n type: z.literal('subscribe'),\n threadId: idSchema,\n after: z\n .object({ serverEpoch: idSchema, seq: z.number().int().nonnegative() })\n .strict()\n .optional(),\n })\n .strict();\nexport const socketMessageSchema = z.discriminatedUnion('type', [\n subscribeSchema,\n z.object({ type: z.literal('unsubscribe') }).strict(),\n]);\n\nexport const archiveThreadSchema = operationSchema.extend({ archived: z.boolean() });\nexport const archivedQuerySchema = z\n .enum(['true', 'false'])\n .optional()\n .transform((value) => value === 'true');\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { z } from 'zod';\nimport { imageDataBytes, MAX_IMAGE_BYTES, MAX_IMAGES } from './images.js';\nimport type { TaskMessage } from './types.js';\nimport { threadNameError } from './thread-name.js';\nexport const cursorSchema = z.string().min(1).max(4096);\nexport const idSchema = z.string().min(1).max(256);\nconst projectNameSchema = z.string().trim().min(1).max(100);\nexport const createProjectSchema = z\n .object({ path: z.string().trim().min(1).max(4096), name: projectNameSchema.optional() })\n .strict();\nexport const renameProjectSchema = z.object({ name: projectNameSchema }).strict();\nexport const cloneProjectSchema = createProjectSchema.extend({\n clientOperationId: z.string().uuid(),\n repository: z.string().trim().min(1).max(4096),\n});\nexport const removeProjectSchema = z.object({}).strict();\nexport const reorderProjectsSchema = z\n .object({ projectIds: z.array(idSchema).refine((ids) => new Set(ids).size === ids.length) })\n .strict();\nexport const settingsSchema = z\n .object({\n model: z.string().min(1).max(200).optional(),\n reasoningEffort: z.string().min(1).max(40).optional(),\n serviceTier: z.literal('fast').nullable().optional(),\n permissionMode: z.enum(['ask', 'auto-review', 'full-access', 'read-only']).optional(),\n approvalPolicy: z.enum(['untrusted', 'on-request', 'never']).optional(),\n approvalReviewer: z.enum(['user', 'auto_review']).optional(),\n sandbox: z.enum(['read-only', 'workspace-write', 'danger-full-access']).optional(),\n })\n .strict()\n .refine(\n (settings) =>\n settings.permissionMode === undefined ||\n (settings.sandbox === undefined &&\n settings.approvalPolicy === undefined &&\n settings.approvalReviewer === undefined),\n '\u6743\u9650\u6A21\u5F0F\u4E0D\u80FD\u4E0E\u72EC\u7ACB\u7684\u6743\u9650\u3001\u5BA1\u6279\u7B56\u7565\u6216\u5BA1\u6838\u65B9\u540C\u65F6\u8BBE\u7F6E',\n );\nexport const operationSchema = z.object({ clientOperationId: z.string().uuid() }).strict();\nexport const saveModelDefaultsSchema = operationSchema.extend({\n settings: z\n .object({\n model: z.string().min(1).max(200),\n reasoningEffort: z.string().min(1).max(40).nullable(),\n })\n .strict(),\n});\nexport const startReviewSchema = operationSchema;\nexport const confirmCompatibilitySchema = operationSchema.extend({\n codexEpoch: idSchema,\n codexVersion: z.string().min(1).max(200),\n verifiedVersion: z.string().min(1).max(200),\n confirm: z.literal(true),\n});\nexport const createThreadSchema = operationSchema.extend({ settings: settingsSchema.optional() });\nexport const forkThreadSchema = createThreadSchema;\nexport const renameThreadSchema = operationSchema.extend({\n name: z\n .string()\n .superRefine((name, context) => {\n const message = threadNameError(name);\n if (message) context.addIssue({ code: 'custom', message });\n })\n .transform((name) => name.trim()),\n});\nexport const resumeThreadSchema = createThreadSchema.extend({\n confirmExternalStopped: z.boolean().optional(),\n});\nconst taskFields = {\n text: z.string().max(100_000),\n images: z\n .array(z.string().refine((value) => imageDataBytes(value) !== undefined, 'Invalid image'))\n .max(MAX_IMAGES)\n .refine(\n (images) =>\n images.reduce((sum, image) => sum + (imageDataBytes(image) ?? Infinity), 0) <=\n MAX_IMAGE_BYTES,\n 'Images exceed size limit',\n )\n .optional(),\n};\nconst hasContent = (input: TaskMessage) => Boolean(input.text.trim() || input.images?.length);\nexport const startTurnSchema = createThreadSchema\n .extend({\n ...taskFields,\n })\n .refine(hasContent, 'Text or an image is required');\nexport const steerSchema = operationSchema\n .extend({\n expectedTurnId: idSchema,\n ...taskFields,\n })\n .refine(hasContent, 'Text or an image is required');\nexport const interruptSchema = operationSchema.extend({ expectedTurnId: idSchema });\nconst elicitationValueSchema = z.union([\n z.string().max(10_000),\n z.number().finite(),\n z.boolean(),\n z.array(z.string().max(10_000)).max(500),\n]);\nexport const resolveActionSchema = operationSchema.extend({\n resolution: z.union([\n z\n .object({\n decision: z.string().min(1).max(200),\n content: z.record(z.string().max(1000), elicitationValueSchema).optional(),\n persist: z.literal('session').optional(),\n })\n .strict(),\n z.object({ answers: z.record(z.string(), z.array(z.string().max(10_000)).max(50)) }).strict(),\n ]),\n});\nexport const reconcileSchema = operationSchema.extend({ confirmEnded: z.literal(true) });\nexport const subscribeSchema = z\n .object({\n type: z.literal('subscribe'),\n threadId: idSchema,\n after: z\n .object({ serverEpoch: idSchema, seq: z.number().int().nonnegative() })\n .strict()\n .optional(),\n })\n .strict();\nexport const socketMessageSchema = z.discriminatedUnion('type', [\n subscribeSchema,\n z.object({ type: z.literal('unsubscribe') }).strict(),\n]);\n\nexport const archiveThreadSchema = operationSchema.extend({ archived: z.boolean() });\nexport const archivedQuerySchema = z\n .enum(['true', 'false'])\n .optional()\n .transform((value) => value === 'true');\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -21478,6 +21478,10 @@ var configSchema = external_exports.object({
21478
21478
  publicOrigin: external_exports.array(origin).min(1).default(["http://127.0.0.1:8787"]).transform((values) => [...new Set(values)]),
21479
21479
  developmentOrigins: external_exports.array(origin).default([]),
21480
21480
  dataDir: external_exports.string().min(1).default("./.local/codex-web"),
21481
+ workDir: external_exports.string().trim().max(4096).refine(
21482
+ (path) => (0, import_node_path2.isAbsolute)(path) && !path.includes("\0"),
21483
+ "workDir \u5FC5\u987B\u662F\u670D\u52A1\u4E3B\u673A\u4E0A\u7684\u7EDD\u5BF9\u76EE\u5F55\u8DEF\u5F84"
21484
+ ).optional(),
21481
21485
  codex: external_exports.object({
21482
21486
  binary: external_exports.string().min(1).default("codex"),
21483
21487
  home: external_exports.string().refine(import_node_path2.isAbsolute).optional(),
@@ -22421,6 +22425,7 @@ var releaseSchema = external_exports.object({
22421
22425
  name: external_exports.literal(npmPackageName),
22422
22426
  version: external_exports.string().refine(validVersion),
22423
22427
  gitHead: external_exports.string().optional(),
22428
+ covroCommit: external_exports.string().optional(),
22424
22429
  covroCodex: external_exports.unknown().optional()
22425
22430
  });
22426
22431
  async function inspectInstallation(root) {
@@ -22648,11 +22653,11 @@ async function worker(directory) {
22648
22653
  ],
22649
22654
  { timeout: 10 * 6e4, maxBuffer: 2 * 1024 * 1024 }
22650
22655
  );
22651
- const candidate = await readJson(
22652
- (0, import_node_path11.join)(paths.candidate, "package.json")
22653
- );
22656
+ const candidate = await readJson((0, import_node_path11.join)(paths.candidate, "package.json"));
22654
22657
  if (candidate?.name !== npmPackageName || candidate.version !== record2.target)
22655
22658
  throw new Error("\u5019\u9009\u5305\u8EAB\u4EFD\u6216\u7248\u672C\u4E0D\u5339\u914D");
22659
+ if (record2.commit && (candidate.covroCommit ?? candidate.gitHead) !== record2.commit)
22660
+ throw new Error("\u5019\u9009\u5305\u6E90\u7801\u63D0\u4EA4\u4E0E\u68C0\u67E5\u65F6\u4E0D\u4E00\u81F4\uFF0C\u62D2\u7EDD\u5207\u6362");
22656
22661
  if (!record2.codex) throw new Error("\u7F3A\u5C11 Codex \u5347\u7EA7\u6821\u9A8C\u8BB0\u5F55\uFF0C\u8BF7\u91CD\u65B0\u68C0\u67E5\u66F4\u65B0");
22657
22662
  const manifest = codexCompatibilitySchema.parse(candidate.covroCodex);
22658
22663
  if (JSON.stringify(manifest) !== JSON.stringify(record2.codex.manifest))
@@ -87,8 +87,9 @@ class UpdateManager {
87
87
  const release = await lookupRelease(channel, this.network.signal);
88
88
  this.available = {
89
89
  version: release.version,
90
- channel,
91
- commit: release.gitHead,
90
+ requestedChannel: channel,
91
+ channel: release.channel,
92
+ commit: release.covroCommit ?? release.gitHead,
92
93
  downgrade: compareVersions(release.version, packageInfo.version) < 0,
93
94
  codex: assessCodexCompatibility(release.covroCodex, this.codexVersion())
94
95
  };
@@ -183,7 +184,7 @@ class UpdateManager {
183
184
  "\u76EE\u6807\u7248\u672C\u8F83\u65E7\uFF0C\u9700\u8981\u660E\u786E\u5141\u8BB8\u964D\u7EA7\uFF1B\u4ECD\u5C06\u68C0\u67E5\u6570\u636E\u5E93\u517C\u5BB9\u6027\u3002",
184
185
  409
185
186
  );
186
- if (checked.available.version === packageInfo.version) {
187
+ if (compareVersions(checked.available.version, packageInfo.version) === 0) {
187
188
  return this.configure({ ...this.settings, channel });
188
189
  }
189
190
  const confirmation = request.codexConfirmation;
@@ -207,6 +208,8 @@ class UpdateManager {
207
208
  from: packageInfo.version,
208
209
  target: checked.available.version,
209
210
  channel,
211
+ sourceChannel: checked.available.channel,
212
+ commit: checked.available.commit,
210
213
  codex: { version: codex.version, manifest: codex.manifest, confirmedUnverified },
211
214
  phase: "installing",
212
215
  message: "\u6B63\u5728\u5B89\u88C5\u5019\u9009 npm \u5305",
@@ -292,7 +295,7 @@ class UpdateManager {
292
295
  if (!this.context || this.reason || this.checking) return;
293
296
  this.checking = (async () => {
294
297
  const result = await this.check();
295
- if (this.settings.automatic && result.available && result.available.codex.status === "verified" && !result.available.downgrade && result.available.version !== packageInfo.version && result.run?.target !== result.available.version && !updateActive(result.run))
298
+ if (this.settings.automatic && result.available && result.available.codex.status === "verified" && !result.available.downgrade && compareVersions(result.available.version, packageInfo.version) > 0 && result.run?.target !== result.available.version && !updateActive(result.run))
296
299
  return this.start({ clientOperationId: crypto.randomUUID() });
297
300
  return result;
298
301
  })();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/updates/manager.ts"],
4
- "sourcesContent": ["import { CODEX_COMPATIBILITY } from '../codex/compatibility.js';\nimport {\n assessCodexCompatibility,\n requireCodexCompatibility,\n} from '../shared/codex-compatibility.js';\nimport { createHash } from 'node:crypto';\nimport { spawn } from 'node:child_process';\nimport { copyFile, mkdir, open } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport lockfile from 'proper-lockfile';\nimport { z } from 'zod';\nimport { AppError } from '../shared/errors.js';\nimport {\n releaseChannels,\n updateActive,\n type UpdateController,\n type UpdateSettings,\n type UpdateRun,\n type UpdateStatus,\n type ReleaseChannel,\n} from '../shared/updates.js';\nimport { packageInfo, packageRoot, type CovroPaths } from '../cli/paths.js';\nimport { readJson, saveJson } from './files.js';\nimport { compareVersions, inspectInstallation, lookupRelease } from './registry.js';\n\nexport const settingsSchema = z\n .object({ channel: z.enum(releaseChannels), automatic: z.boolean() })\n .strict();\nexport const updateRequestSchema = z\n .object({\n clientOperationId: z.uuid(),\n channel: z.enum(releaseChannels).optional(),\n allowDowngrade: z.boolean().optional(),\n codexConfirmation: z\n .object({ version: z.string().max(128), target: z.string().max(128) })\n .strict()\n .optional(),\n })\n .strict();\nexport interface UpdateContext {\n location: CovroPaths;\n dataDir: string;\n root: string;\n directory: string;\n}\nexport class UpdateManager implements UpdateController {\n private settings: UpdateSettings = {\n channel:\n packageInfo.covroChannel ??\n (packageInfo.version?.includes('-dev.')\n ? 'dev'\n : packageInfo.version?.includes('-beta.')\n ? 'beta'\n : 'stable'),\n automatic: false,\n };\n private available?: UpdateStatus['available'];\n private checkedAt?: number;\n private checkError?: string;\n private reason = '\u5F53\u524D\u670D\u52A1\u672A\u901A\u8FC7 covro \u542F\u52A8\uFF0C\u7F51\u9875\u4EC5\u652F\u6301\u7248\u672C\u68C0\u6D4B\uFF1B\u5347\u7EA7\u8BF7\u4F7F\u7528\u539F\u90E8\u7F72\u65B9\u5F0F\u3002';\n private timer?: ReturnType<typeof setInterval>;\n private checking?: Promise<UpdateStatus>;\n private readonly network = new AbortController();\n readonly context?: UpdateContext;\n constructor(\n location?: CovroPaths,\n dataDir?: string,\n private readonly codexVersion: () => string | null = () => null,\n ) {\n if (location && dataDir)\n this.context = {\n location,\n dataDir,\n root: packageRoot,\n directory: join(\n location.home,\n 'updates',\n createHash('sha256').update(packageRoot).digest('hex').slice(0, 16),\n ),\n };\n }\n async initialize() {\n if (!this.context) return;\n const saved = await readJson<unknown>(join(this.context.directory, 'settings.json'));\n if (saved !== undefined) this.settings = settingsSchema.parse(saved);\n this.reason =\n process.platform === 'win32'\n ? 'Windows \u6682\u4E0D\u652F\u6301\u53D7\u7BA1\u81EA\u52A8\u5347\u7EA7\uFF0C\u8BF7\u4F7F\u7528 npm \u66F4\u65B0\u5E76\u91CD\u542F\u3002'\n : ((await inspectInstallation(this.context.root)) ?? '');\n this.timer = setInterval(() => void this.automatic().catch(() => {}), 30 * 60_000);\n this.timer.unref();\n // No network request in the startup critical path.\n void this.automatic().catch(() => {});\n }\n async status(): Promise<UpdateStatus> {\n const run = this.context\n ? await readJson<UpdateRun>(join(this.context.directory, 'run.json'))\n : undefined;\n return {\n version: packageInfo.version ?? 'unknown',\n commit: packageInfo.covroCommit,\n source: 'npm',\n codex: assessCodexCompatibility(CODEX_COMPATIBILITY, this.codexVersion()),\n settings: this.settings,\n supported: !this.reason,\n unsupportedReason: this.reason || undefined,\n available: this.available\n ? {\n ...this.available,\n codex: assessCodexCompatibility(this.available.codex.manifest, this.codexVersion()),\n }\n : undefined,\n checkedAt: this.checkedAt,\n checkError: this.checkError,\n run,\n };\n }\n async check(channel: ReleaseChannel = this.settings.channel) {\n try {\n const release = await lookupRelease(channel, this.network.signal);\n this.available = {\n version: release.version,\n channel,\n commit: release.gitHead,\n downgrade: compareVersions(release.version, packageInfo.version) < 0,\n codex: assessCodexCompatibility(release.covroCodex, this.codexVersion()),\n };\n this.checkError = undefined;\n } catch (error) {\n this.available = undefined;\n this.checkError = error instanceof Error ? error.message : '\u65E0\u6CD5\u68C0\u67E5\u66F4\u65B0';\n }\n this.checkedAt = Date.now();\n return this.status();\n }\n async configure(input: UpdateSettings) {\n if (!this.context || this.reason) throw new AppError('UPDATE_UNSUPPORTED', this.reason, 409);\n this.settings = settingsSchema.parse(input);\n await saveJson(join(this.context.directory, 'settings.json'), this.settings);\n return this.status();\n }\n async activationPending() {\n const run = (await this.status()).run;\n if (run && !run.committed && run.phase === 'failed' && run.from !== packageInfo.version)\n throw new Error(\n '\u4E0A\u6B21\u5347\u7EA7\u5C1A\u672A\u5B8C\u6210\u6062\u590D\uFF1B\u8BF7\u8FD0\u884C covro update repair \u540E\u518D\u542F\u52A8\uFF0C\u907F\u514D\u5199\u5165\u672A\u6FC0\u6D3B\u7248\u672C\u3002',\n );\n if (run && !run.committed && run.phase === 'stopping')\n throw new Error('\u5347\u7EA7\u6B63\u5728\u5207\u6362\u5B89\u88C5\uFF0C\u8BF7\u7B49\u5F85\u5347\u7EA7\u5B8C\u6210\uFF1B\u4E0D\u8981\u5E76\u884C\u542F\u52A8\u670D\u52A1\u3002');\n if (run && !run.committed && run.phase === 'verifying') {\n if (run.target !== packageInfo.version)\n throw new Error('\u5347\u7EA7\u5019\u9009\u8EAB\u4EFD\u4E0D\u5339\u914D\uFF0C\u8BF7\u8FD0\u884C covro update repair');\n return true;\n }\n return false;\n }\n async commitActivation(id: string) {\n if (!this.context) throw new Error('\u5F53\u524D\u4E0D\u662F\u53D7\u7BA1\u5B89\u88C5');\n const run = (await this.status()).run;\n if (!run || run.id !== id || run.phase !== 'verifying' || run.target !== packageInfo.version)\n throw new Error('\u5347\u7EA7\u8BB0\u5F55\u3001\u7248\u672C\u6216\u8FD0\u884C\u72B6\u6001\u4E0D\u5339\u914D');\n if (!run.codex || run.codex.version !== this.codexVersion())\n throw new Error('Codex \u7248\u672C\u5728\u5347\u7EA7\u671F\u95F4\u53D1\u751F\u53D8\u5316\u6216\u7F3A\u5C11\u6821\u9A8C\u8BB0\u5F55\uFF0C\u62D2\u7EDD\u6FC0\u6D3B');\n requireCodexCompatibility(\n CODEX_COMPATIBILITY,\n this.codexVersion(),\n run.codex.confirmedUnverified,\n );\n this.settings = { ...this.settings, channel: run.channel };\n await saveJson(join(this.context.directory, 'settings.json'), this.settings);\n await saveJson(join(this.context.directory, 'run.json'), {\n ...run,\n committed: true,\n phase: 'succeeded',\n message: '\u5347\u7EA7\u6210\u529F\uFF0C\u670D\u52A1\u5DF2\u6062\u590D',\n updatedAt: Date.now(),\n });\n }\n async start(input: z.infer<typeof updateRequestSchema>) {\n const request = updateRequestSchema.parse(input);\n if (!this.context || this.reason) throw new AppError('UPDATE_UNSUPPORTED', this.reason, 409);\n await mkdir(this.context.directory, { recursive: true, mode: 0o700 });\n let releaseLock: () => Promise<void>;\n try {\n releaseLock = await lockfile.lock(this.context.directory, {\n retries: 0,\n stale: 10_000,\n update: 2_000,\n });\n } catch {\n return this.status();\n }\n try {\n const before = await this.status();\n if (\n await readJson(\n join(this.context.directory, 'requests', `${request.clientOperationId}.json`),\n )\n )\n return before;\n if (before.run?.id === request.clientOperationId) return before;\n if (updateActive(before.run)) {\n if (Date.now() - before.run!.updatedAt > 120_000)\n throw new AppError(\n 'UPDATE_INTERRUPTED',\n '\u4E0A\u6B21\u5347\u7EA7\u8FDB\u7A0B\u5DF2\u5931\u8054\u3002\u8BF7\u4F7F\u7528 covro update repair \u6062\u590D\uFF0C\u4FDD\u7559\u5F53\u524D\u5B89\u88C5\u548C\u5907\u4EFD\u3002',\n 409,\n );\n return before;\n }\n const channel = request.channel ?? this.settings.channel;\n const checked = await this.check(channel);\n if (!checked.available)\n throw new AppError('UPDATE_CHECK_FAILED', checked.checkError ?? '\u672A\u627E\u5230\u53EF\u7528\u7248\u672C', 502);\n if (checked.available.downgrade && !request.allowDowngrade)\n throw new AppError(\n 'UPDATE_DOWNGRADE',\n '\u76EE\u6807\u7248\u672C\u8F83\u65E7\uFF0C\u9700\u8981\u660E\u786E\u5141\u8BB8\u964D\u7EA7\uFF1B\u4ECD\u5C06\u68C0\u67E5\u6570\u636E\u5E93\u517C\u5BB9\u6027\u3002',\n 409,\n );\n if (checked.available.version === packageInfo.version) {\n return this.configure({ ...this.settings, channel });\n }\n const confirmation = request.codexConfirmation;\n const codex = checked.available.codex;\n const confirmedUnverified = Boolean(\n confirmation &&\n confirmation.target === checked.available.version &&\n confirmation.version === codex.version,\n );\n if (confirmation && !confirmedUnverified)\n throw new AppError(\n 'UPDATE_CODEX_CHANGED',\n '\u76EE\u6807\u7248\u672C\u6216 Codex \u5DF2\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u68C0\u67E5\u5E76\u786E\u8BA4\u3002',\n 409,\n );\n try {\n requireCodexCompatibility(codex.manifest, codex.version, confirmedUnverified);\n } catch (error) {\n throw new AppError('UPDATE_CODEX_INCOMPATIBLE', (error as Error).message, 409);\n }\n const run: UpdateRun = {\n id: request.clientOperationId,\n from: packageInfo.version,\n target: checked.available.version,\n channel,\n codex: { version: codex.version!, manifest: codex.manifest!, confirmedUnverified },\n phase: 'installing',\n message: '\u6B63\u5728\u5B89\u88C5\u5019\u9009 npm \u5305',\n startedAt: Date.now(),\n updatedAt: Date.now(),\n };\n await saveJson(join(this.context.directory, 'context.json'), this.context);\n const worker = join(this.context.directory, 'worker.cjs');\n await copyFile(join(packageRoot, 'dist/update-worker.cjs'), worker);\n const log = await open(join(this.context.directory, 'update.log'), 'a', 0o600);\n try {\n await saveJson(join(this.context.directory, 'run.json'), run);\n await saveJson(\n join(this.context.directory, 'requests', `${request.clientOperationId}.json`),\n { target: run.target, channel: run.channel },\n );\n const child = spawn(process.execPath, [worker, this.context.directory], {\n detached: true,\n stdio: ['ignore', log.fd, log.fd],\n windowsHide: true,\n });\n await new Promise<void>((done, reject) => {\n child.once('spawn', done);\n child.once('error', reject);\n });\n child.unref();\n } catch (error) {\n await saveJson(join(this.context.directory, 'run.json'), {\n ...run,\n phase: 'failed',\n message: String(error),\n updatedAt: Date.now(),\n });\n throw error;\n } finally {\n await log.close();\n }\n return this.status();\n } finally {\n await releaseLock();\n }\n }\n async repair() {\n if (!this.context) throw new Error('\u6CA1\u6709\u53EF\u6062\u590D\u7684\u53D7\u7BA1\u5B89\u88C5');\n const directory = this.context.directory;\n let releaseLock: () => Promise<void>;\n try {\n releaseLock = await lockfile.lock(directory, { retries: 0, stale: 10_000, update: 2_000 });\n } catch {\n throw new Error('\u5347\u7EA7\u8FDB\u7A0B\u4ECD\u6301\u6709\u9501\uFF0C\u8BF7\u7B49\u5F85\u5B8C\u6210\u540E\u518D\u6062\u590D');\n }\n try {\n const run = (await this.status()).run;\n if (!run) throw new Error('\u6CA1\u6709\u53EF\u6062\u590D\u7684\u5347\u7EA7\u8BB0\u5F55');\n if (run.committed || run.phase === 'succeeded') return this.status();\n if (updateActive(run) && Date.now() - run.updatedAt < 30_000)\n throw new Error('\u5347\u7EA7\u521A\u5F00\u59CB\uFF0C\u8BF7\u7B49\u5F85\u81F3\u5C11 30 \u79D2\u540E\u518D\u6062\u590D\u5931\u8054\u8FDB\u7A0B');\n const log = await open(join(directory, 'update.log'), 'a', 0o600);\n try {\n const child = spawn(\n process.execPath,\n [join(directory, 'worker.cjs'), directory, '--repair'],\n {\n detached: true,\n stdio: ['ignore', log.fd, log.fd],\n windowsHide: true,\n },\n );\n await new Promise<void>((done, reject) => {\n child.once('spawn', done);\n child.once('error', reject);\n });\n child.unref();\n } finally {\n await log.close();\n }\n return this.status();\n } finally {\n await releaseLock();\n }\n }\n private async automatic() {\n if (!this.context || this.reason || this.checking) return;\n this.checking = (async () => {\n const result = await this.check();\n if (\n this.settings.automatic &&\n result.available &&\n result.available.codex.status === 'verified' &&\n !result.available.downgrade &&\n result.available.version !== packageInfo.version &&\n result.run?.target !== result.available.version &&\n !updateActive(result.run)\n )\n return this.start({ clientOperationId: crypto.randomUUID() });\n return result;\n })();\n try {\n await this.checking;\n } finally {\n this.checking = undefined;\n }\n }\n close() {\n this.network.abort();\n clearInterval(this.timer);\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { CODEX_COMPATIBILITY } from '../codex/compatibility.js';\nimport {\n assessCodexCompatibility,\n requireCodexCompatibility,\n} from '../shared/codex-compatibility.js';\nimport { createHash } from 'node:crypto';\nimport { spawn } from 'node:child_process';\nimport { copyFile, mkdir, open } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport lockfile from 'proper-lockfile';\nimport { z } from 'zod';\nimport { AppError } from '../shared/errors.js';\nimport {\n releaseChannels,\n updateActive,\n type UpdateController,\n type UpdateSettings,\n type UpdateRun,\n type UpdateStatus,\n type ReleaseChannel,\n} from '../shared/updates.js';\nimport { packageInfo, packageRoot, type CovroPaths } from '../cli/paths.js';\nimport { readJson, saveJson } from './files.js';\nimport { compareVersions, inspectInstallation, lookupRelease } from './registry.js';\n\nexport const settingsSchema = z\n .object({ channel: z.enum(releaseChannels), automatic: z.boolean() })\n .strict();\nexport const updateRequestSchema = z\n .object({\n clientOperationId: z.uuid(),\n channel: z.enum(releaseChannels).optional(),\n allowDowngrade: z.boolean().optional(),\n codexConfirmation: z\n .object({ version: z.string().max(128), target: z.string().max(128) })\n .strict()\n .optional(),\n })\n .strict();\nexport interface UpdateContext {\n location: CovroPaths;\n dataDir: string;\n root: string;\n directory: string;\n}\nexport class UpdateManager implements UpdateController {\n private settings: UpdateSettings = {\n channel:\n packageInfo.covroChannel ??\n (packageInfo.version?.includes('-dev.')\n ? 'dev'\n : packageInfo.version?.includes('-beta.')\n ? 'beta'\n : 'stable'),\n automatic: false,\n };\n private available?: UpdateStatus['available'];\n private checkedAt?: number;\n private checkError?: string;\n private reason = '\u5F53\u524D\u670D\u52A1\u672A\u901A\u8FC7 covro \u542F\u52A8\uFF0C\u7F51\u9875\u4EC5\u652F\u6301\u7248\u672C\u68C0\u6D4B\uFF1B\u5347\u7EA7\u8BF7\u4F7F\u7528\u539F\u90E8\u7F72\u65B9\u5F0F\u3002';\n private timer?: ReturnType<typeof setInterval>;\n private checking?: Promise<UpdateStatus>;\n private readonly network = new AbortController();\n readonly context?: UpdateContext;\n constructor(\n location?: CovroPaths,\n dataDir?: string,\n private readonly codexVersion: () => string | null = () => null,\n ) {\n if (location && dataDir)\n this.context = {\n location,\n dataDir,\n root: packageRoot,\n directory: join(\n location.home,\n 'updates',\n createHash('sha256').update(packageRoot).digest('hex').slice(0, 16),\n ),\n };\n }\n async initialize() {\n if (!this.context) return;\n const saved = await readJson<unknown>(join(this.context.directory, 'settings.json'));\n if (saved !== undefined) this.settings = settingsSchema.parse(saved);\n this.reason =\n process.platform === 'win32'\n ? 'Windows \u6682\u4E0D\u652F\u6301\u53D7\u7BA1\u81EA\u52A8\u5347\u7EA7\uFF0C\u8BF7\u4F7F\u7528 npm \u66F4\u65B0\u5E76\u91CD\u542F\u3002'\n : ((await inspectInstallation(this.context.root)) ?? '');\n this.timer = setInterval(() => void this.automatic().catch(() => {}), 30 * 60_000);\n this.timer.unref();\n // No network request in the startup critical path.\n void this.automatic().catch(() => {});\n }\n async status(): Promise<UpdateStatus> {\n const run = this.context\n ? await readJson<UpdateRun>(join(this.context.directory, 'run.json'))\n : undefined;\n return {\n version: packageInfo.version ?? 'unknown',\n commit: packageInfo.covroCommit,\n source: 'npm',\n codex: assessCodexCompatibility(CODEX_COMPATIBILITY, this.codexVersion()),\n settings: this.settings,\n supported: !this.reason,\n unsupportedReason: this.reason || undefined,\n available: this.available\n ? {\n ...this.available,\n codex: assessCodexCompatibility(this.available.codex.manifest, this.codexVersion()),\n }\n : undefined,\n checkedAt: this.checkedAt,\n checkError: this.checkError,\n run,\n };\n }\n async check(channel: ReleaseChannel = this.settings.channel) {\n try {\n const release = await lookupRelease(channel, this.network.signal);\n this.available = {\n version: release.version,\n requestedChannel: channel,\n channel: release.channel,\n commit: release.covroCommit ?? release.gitHead,\n downgrade: compareVersions(release.version, packageInfo.version) < 0,\n codex: assessCodexCompatibility(release.covroCodex, this.codexVersion()),\n };\n this.checkError = undefined;\n } catch (error) {\n this.available = undefined;\n this.checkError = error instanceof Error ? error.message : '\u65E0\u6CD5\u68C0\u67E5\u66F4\u65B0';\n }\n this.checkedAt = Date.now();\n return this.status();\n }\n async configure(input: UpdateSettings) {\n if (!this.context || this.reason) throw new AppError('UPDATE_UNSUPPORTED', this.reason, 409);\n this.settings = settingsSchema.parse(input);\n await saveJson(join(this.context.directory, 'settings.json'), this.settings);\n return this.status();\n }\n async activationPending() {\n const run = (await this.status()).run;\n if (run && !run.committed && run.phase === 'failed' && run.from !== packageInfo.version)\n throw new Error(\n '\u4E0A\u6B21\u5347\u7EA7\u5C1A\u672A\u5B8C\u6210\u6062\u590D\uFF1B\u8BF7\u8FD0\u884C covro update repair \u540E\u518D\u542F\u52A8\uFF0C\u907F\u514D\u5199\u5165\u672A\u6FC0\u6D3B\u7248\u672C\u3002',\n );\n if (run && !run.committed && run.phase === 'stopping')\n throw new Error('\u5347\u7EA7\u6B63\u5728\u5207\u6362\u5B89\u88C5\uFF0C\u8BF7\u7B49\u5F85\u5347\u7EA7\u5B8C\u6210\uFF1B\u4E0D\u8981\u5E76\u884C\u542F\u52A8\u670D\u52A1\u3002');\n if (run && !run.committed && run.phase === 'verifying') {\n if (run.target !== packageInfo.version)\n throw new Error('\u5347\u7EA7\u5019\u9009\u8EAB\u4EFD\u4E0D\u5339\u914D\uFF0C\u8BF7\u8FD0\u884C covro update repair');\n return true;\n }\n return false;\n }\n async commitActivation(id: string) {\n if (!this.context) throw new Error('\u5F53\u524D\u4E0D\u662F\u53D7\u7BA1\u5B89\u88C5');\n const run = (await this.status()).run;\n if (!run || run.id !== id || run.phase !== 'verifying' || run.target !== packageInfo.version)\n throw new Error('\u5347\u7EA7\u8BB0\u5F55\u3001\u7248\u672C\u6216\u8FD0\u884C\u72B6\u6001\u4E0D\u5339\u914D');\n if (!run.codex || run.codex.version !== this.codexVersion())\n throw new Error('Codex \u7248\u672C\u5728\u5347\u7EA7\u671F\u95F4\u53D1\u751F\u53D8\u5316\u6216\u7F3A\u5C11\u6821\u9A8C\u8BB0\u5F55\uFF0C\u62D2\u7EDD\u6FC0\u6D3B');\n requireCodexCompatibility(\n CODEX_COMPATIBILITY,\n this.codexVersion(),\n run.codex.confirmedUnverified,\n );\n this.settings = { ...this.settings, channel: run.channel };\n await saveJson(join(this.context.directory, 'settings.json'), this.settings);\n await saveJson(join(this.context.directory, 'run.json'), {\n ...run,\n committed: true,\n phase: 'succeeded',\n message: '\u5347\u7EA7\u6210\u529F\uFF0C\u670D\u52A1\u5DF2\u6062\u590D',\n updatedAt: Date.now(),\n });\n }\n async start(input: z.infer<typeof updateRequestSchema>) {\n const request = updateRequestSchema.parse(input);\n if (!this.context || this.reason) throw new AppError('UPDATE_UNSUPPORTED', this.reason, 409);\n await mkdir(this.context.directory, { recursive: true, mode: 0o700 });\n let releaseLock: () => Promise<void>;\n try {\n releaseLock = await lockfile.lock(this.context.directory, {\n retries: 0,\n stale: 10_000,\n update: 2_000,\n });\n } catch {\n return this.status();\n }\n try {\n const before = await this.status();\n if (\n await readJson(\n join(this.context.directory, 'requests', `${request.clientOperationId}.json`),\n )\n )\n return before;\n if (before.run?.id === request.clientOperationId) return before;\n if (updateActive(before.run)) {\n if (Date.now() - before.run!.updatedAt > 120_000)\n throw new AppError(\n 'UPDATE_INTERRUPTED',\n '\u4E0A\u6B21\u5347\u7EA7\u8FDB\u7A0B\u5DF2\u5931\u8054\u3002\u8BF7\u4F7F\u7528 covro update repair \u6062\u590D\uFF0C\u4FDD\u7559\u5F53\u524D\u5B89\u88C5\u548C\u5907\u4EFD\u3002',\n 409,\n );\n return before;\n }\n const channel = request.channel ?? this.settings.channel;\n const checked = await this.check(channel);\n if (!checked.available)\n throw new AppError('UPDATE_CHECK_FAILED', checked.checkError ?? '\u672A\u627E\u5230\u53EF\u7528\u7248\u672C', 502);\n if (checked.available.downgrade && !request.allowDowngrade)\n throw new AppError(\n 'UPDATE_DOWNGRADE',\n '\u76EE\u6807\u7248\u672C\u8F83\u65E7\uFF0C\u9700\u8981\u660E\u786E\u5141\u8BB8\u964D\u7EA7\uFF1B\u4ECD\u5C06\u68C0\u67E5\u6570\u636E\u5E93\u517C\u5BB9\u6027\u3002',\n 409,\n );\n if (compareVersions(checked.available.version, packageInfo.version) === 0) {\n return this.configure({ ...this.settings, channel });\n }\n const confirmation = request.codexConfirmation;\n const codex = checked.available.codex;\n const confirmedUnverified = Boolean(\n confirmation &&\n confirmation.target === checked.available.version &&\n confirmation.version === codex.version,\n );\n if (confirmation && !confirmedUnverified)\n throw new AppError(\n 'UPDATE_CODEX_CHANGED',\n '\u76EE\u6807\u7248\u672C\u6216 Codex \u5DF2\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u68C0\u67E5\u5E76\u786E\u8BA4\u3002',\n 409,\n );\n try {\n requireCodexCompatibility(codex.manifest, codex.version, confirmedUnverified);\n } catch (error) {\n throw new AppError('UPDATE_CODEX_INCOMPATIBLE', (error as Error).message, 409);\n }\n const run: UpdateRun = {\n id: request.clientOperationId,\n from: packageInfo.version,\n target: checked.available.version,\n channel,\n sourceChannel: checked.available.channel,\n commit: checked.available.commit,\n codex: { version: codex.version!, manifest: codex.manifest!, confirmedUnverified },\n phase: 'installing',\n message: '\u6B63\u5728\u5B89\u88C5\u5019\u9009 npm \u5305',\n startedAt: Date.now(),\n updatedAt: Date.now(),\n };\n await saveJson(join(this.context.directory, 'context.json'), this.context);\n const worker = join(this.context.directory, 'worker.cjs');\n await copyFile(join(packageRoot, 'dist/update-worker.cjs'), worker);\n const log = await open(join(this.context.directory, 'update.log'), 'a', 0o600);\n try {\n await saveJson(join(this.context.directory, 'run.json'), run);\n await saveJson(\n join(this.context.directory, 'requests', `${request.clientOperationId}.json`),\n { target: run.target, channel: run.channel },\n );\n const child = spawn(process.execPath, [worker, this.context.directory], {\n detached: true,\n stdio: ['ignore', log.fd, log.fd],\n windowsHide: true,\n });\n await new Promise<void>((done, reject) => {\n child.once('spawn', done);\n child.once('error', reject);\n });\n child.unref();\n } catch (error) {\n await saveJson(join(this.context.directory, 'run.json'), {\n ...run,\n phase: 'failed',\n message: String(error),\n updatedAt: Date.now(),\n });\n throw error;\n } finally {\n await log.close();\n }\n return this.status();\n } finally {\n await releaseLock();\n }\n }\n async repair() {\n if (!this.context) throw new Error('\u6CA1\u6709\u53EF\u6062\u590D\u7684\u53D7\u7BA1\u5B89\u88C5');\n const directory = this.context.directory;\n let releaseLock: () => Promise<void>;\n try {\n releaseLock = await lockfile.lock(directory, { retries: 0, stale: 10_000, update: 2_000 });\n } catch {\n throw new Error('\u5347\u7EA7\u8FDB\u7A0B\u4ECD\u6301\u6709\u9501\uFF0C\u8BF7\u7B49\u5F85\u5B8C\u6210\u540E\u518D\u6062\u590D');\n }\n try {\n const run = (await this.status()).run;\n if (!run) throw new Error('\u6CA1\u6709\u53EF\u6062\u590D\u7684\u5347\u7EA7\u8BB0\u5F55');\n if (run.committed || run.phase === 'succeeded') return this.status();\n if (updateActive(run) && Date.now() - run.updatedAt < 30_000)\n throw new Error('\u5347\u7EA7\u521A\u5F00\u59CB\uFF0C\u8BF7\u7B49\u5F85\u81F3\u5C11 30 \u79D2\u540E\u518D\u6062\u590D\u5931\u8054\u8FDB\u7A0B');\n const log = await open(join(directory, 'update.log'), 'a', 0o600);\n try {\n const child = spawn(\n process.execPath,\n [join(directory, 'worker.cjs'), directory, '--repair'],\n {\n detached: true,\n stdio: ['ignore', log.fd, log.fd],\n windowsHide: true,\n },\n );\n await new Promise<void>((done, reject) => {\n child.once('spawn', done);\n child.once('error', reject);\n });\n child.unref();\n } finally {\n await log.close();\n }\n return this.status();\n } finally {\n await releaseLock();\n }\n }\n private async automatic() {\n if (!this.context || this.reason || this.checking) return;\n this.checking = (async () => {\n const result = await this.check();\n if (\n this.settings.automatic &&\n result.available &&\n result.available.codex.status === 'verified' &&\n !result.available.downgrade &&\n compareVersions(result.available.version, packageInfo.version) > 0 &&\n result.run?.target !== result.available.version &&\n !updateActive(result.run)\n )\n return this.start({ clientOperationId: crypto.randomUUID() });\n return result;\n })();\n try {\n await this.checking;\n } finally {\n this.checking = undefined;\n }\n }\n close() {\n this.network.abort();\n clearInterval(this.timer);\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,6 @@
1
1
  import { npmPackageName } from "../shared/package.js";
2
- import { validVersion } from "../shared/versions.js";
3
- import { validVersion as validVersion2, compareVersions } from "../shared/versions.js";
2
+ import { validVersion, compareVersions } from "../shared/versions.js";
3
+ import { validVersion as validVersion2, compareVersions as compareVersions2 } from "../shared/versions.js";
4
4
  import { execFile } from "node:child_process";
5
5
  import { promisify } from "node:util";
6
6
  import { realpath, access, lstat } from "node:fs/promises";
@@ -18,24 +18,36 @@ const releaseSchema = z.object({
18
18
  name: z.literal(npmPackageName),
19
19
  version: z.string().refine(validVersion),
20
20
  gitHead: z.string().optional(),
21
+ covroCommit: z.string().optional(),
21
22
  covroCodex: z.unknown().optional()
22
23
  });
23
24
  function packageMetadataUrl(selector) {
24
25
  const url = `${registry}/${encodeURIComponent(npmPackageName)}`;
25
26
  return selector === void 0 ? url : `${url}/${encodeURIComponent(selector)}`;
26
27
  }
27
- async function lookupRelease(channel, signal) {
28
+ async function lookupTag(channel, signal) {
28
29
  const response = await fetch(packageMetadataUrl(npmTags[channel]), {
29
30
  signal: signal ? AbortSignal.any([signal, AbortSignal.timeout(15e3)]) : AbortSignal.timeout(15e3),
30
31
  headers: { accept: "application/json" }
31
32
  });
32
- if (!response.ok)
33
- throw new Error(
34
- response.status === 404 ? `npm \u5C1A\u672A\u53D1\u5E03 Covro \u7684 ${channel} \u6E20\u9053` : `npm \u67E5\u8BE2\u5931\u8D25\uFF08${response.status}\uFF09`
35
- );
33
+ if (response.status === 404) return void 0;
34
+ if (!response.ok) throw new Error(`npm ${npmTags[channel]} \u67E5\u8BE2\u5931\u8D25\uFF08${response.status}\uFF09`);
36
35
  const body = await response.text();
37
36
  if (body.length > 2 * 1024 * 1024) throw new Error("npm \u5143\u6570\u636E\u8FC7\u5927");
38
- return releaseSchema.parse(JSON.parse(body));
37
+ return { ...releaseSchema.parse(JSON.parse(body)), channel };
38
+ }
39
+ async function lookupRelease(channel, signal) {
40
+ const sources = channel === "stable" ? ["stable"] : ["stable", channel];
41
+ const releases = await Promise.all(sources.map((source) => lookupTag(source, signal)));
42
+ let selected;
43
+ for (const release of releases)
44
+ if (release && (!selected || compareVersions(release.version, selected.version) > 0))
45
+ selected = release;
46
+ if (!selected)
47
+ throw new Error(
48
+ `npm \u5C1A\u672A\u53D1\u5E03 Covro \u7684\u53EF\u7528\u7248\u672C\uFF08${sources.map((source) => npmTags[source]).join("\u3001")}\uFF09`
49
+ );
50
+ return selected;
39
51
  }
40
52
  async function inspectInstallation(root) {
41
53
  try {
@@ -59,7 +71,7 @@ async function inspectPackageDirectory(root, globalRoot) {
59
71
  return void 0;
60
72
  }
61
73
  export {
62
- compareVersions,
74
+ compareVersions2 as compareVersions,
63
75
  inspectInstallation,
64
76
  inspectPackageDirectory,
65
77
  lookupRelease,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/updates/registry.ts"],
4
- "sourcesContent": ["import { npmPackageName } from '../shared/package.js';\nimport { validVersion } from '../shared/versions.js';\nexport { validVersion, compareVersions } from '../shared/versions.js';\nimport { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { realpath, access, lstat } from 'node:fs/promises';\nimport { constants } from 'node:fs';\nimport { join } from 'node:path';\nimport { z } from 'zod';\nimport type { ReleaseChannel } from '../shared/updates.js';\n\nconst run = promisify(execFile);\nexport const registry = 'https://registry.npmjs.org';\nexport const npmTags: Record<ReleaseChannel, string> = {\n stable: 'latest',\n beta: 'beta',\n dev: 'dev',\n};\nexport const releaseSchema = z.object({\n name: z.literal(npmPackageName),\n version: z.string().refine(validVersion),\n gitHead: z.string().optional(),\n covroCodex: z.unknown().optional(),\n});\nexport function packageMetadataUrl(selector?: string) {\n const url = `${registry}/${encodeURIComponent(npmPackageName)}`;\n return selector === undefined ? url : `${url}/${encodeURIComponent(selector)}`;\n}\nexport async function lookupRelease(channel: ReleaseChannel, signal?: AbortSignal) {\n // Resolve a channel exactly once. Install the resulting immutable version, never the moving tag.\n const response = await fetch(packageMetadataUrl(npmTags[channel]), {\n signal: signal\n ? AbortSignal.any([signal, AbortSignal.timeout(15_000)])\n : AbortSignal.timeout(15_000),\n headers: { accept: 'application/json' },\n });\n if (!response.ok)\n throw new Error(\n response.status === 404\n ? `npm \u5C1A\u672A\u53D1\u5E03 Covro \u7684 ${channel} \u6E20\u9053`\n : `npm \u67E5\u8BE2\u5931\u8D25\uFF08${response.status}\uFF09`,\n );\n const body = await response.text();\n if (body.length > 2 * 1024 * 1024) throw new Error('npm \u5143\u6570\u636E\u8FC7\u5927');\n return releaseSchema.parse(JSON.parse(body));\n}\nexport async function inspectInstallation(root: string): Promise<string | undefined> {\n try {\n const { stdout } = await run('npm', ['root', '--global'], { timeout: 15_000 });\n return await inspectPackageDirectory(root, stdout.trim());\n } catch {\n return '\u65E0\u6CD5\u786E\u8BA4\u53EF\u5199\u7684 npm \u5168\u5C40\u5B89\u88C5\uFF1B\u8BF7\u68C0\u67E5 npm\u3001\u5B89\u88C5\u76EE\u5F55\u6743\u9650\u53CA\u540E\u53F0 PATH\u3002';\n }\n}\n\nexport async function inspectPackageDirectory(root: string, globalRoot: string) {\n const expected = join(await realpath(globalRoot), npmPackageName);\n // npm link and pnpm global point outside the package directory. Following\n // that link would let the worker rename a developer's source checkout.\n if ((await lstat(expected)).isSymbolicLink() || (await realpath(root)) !== expected)\n return '\u5F53\u524D\u4E3A\u6E90\u7801\u3001\u94FE\u63A5\u6216\u975E npm \u5168\u5C40\u5B89\u88C5\uFF1B\u8BF7\u4F7F\u7528\u539F\u90E8\u7F72\u65B9\u5F0F\u66F4\u65B0\u3002';\n try {\n await lstat(join(expected, '.git'));\n return '\u5F53\u524D\u5B89\u88C5\u5305\u542B Git \u5DE5\u4F5C\u533A\uFF1B\u8BF7\u4F7F\u7528\u539F\u90E8\u7F72\u65B9\u5F0F\u66F4\u65B0\u3002';\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n }\n await access(root, constants.W_OK);\n return undefined;\n}\n"],
5
- "mappings": "AAAA,SAAS,sBAAsB;AAC/B,SAAS,oBAAoB;AAC7B,SAAS,gBAAAA,eAAc,uBAAuB;AAC9C,SAAS,gBAAgB;AACzB,SAAS,iBAAiB;AAC1B,SAAS,UAAU,QAAQ,aAAa;AACxC,SAAS,iBAAiB;AAC1B,SAAS,YAAY;AACrB,SAAS,SAAS;AAGlB,MAAM,MAAM,UAAU,QAAQ;AACvB,MAAM,WAAW;AACjB,MAAM,UAA0C;AAAA,EACrD,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,KAAK;AACP;AACO,MAAM,gBAAgB,EAAE,OAAO;AAAA,EACpC,MAAM,EAAE,QAAQ,cAAc;AAAA,EAC9B,SAAS,EAAE,OAAO,EAAE,OAAO,YAAY;AAAA,EACvC,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,YAAY,EAAE,QAAQ,EAAE,SAAS;AACnC,CAAC;AACM,SAAS,mBAAmB,UAAmB;AACpD,QAAM,MAAM,GAAG,QAAQ,IAAI,mBAAmB,cAAc,CAAC;AAC7D,SAAO,aAAa,SAAY,MAAM,GAAG,GAAG,IAAI,mBAAmB,QAAQ,CAAC;AAC9E;AACA,eAAsB,cAAc,SAAyB,QAAsB;AAEjF,QAAM,WAAW,MAAM,MAAM,mBAAmB,QAAQ,OAAO,CAAC,GAAG;AAAA,IACjE,QAAQ,SACJ,YAAY,IAAI,CAAC,QAAQ,YAAY,QAAQ,IAAM,CAAC,CAAC,IACrD,YAAY,QAAQ,IAAM;AAAA,IAC9B,SAAS,EAAE,QAAQ,mBAAmB;AAAA,EACxC,CAAC;AACD,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR,SAAS,WAAW,MAChB,6CAAoB,OAAO,kBAC3B,qCAAY,SAAS,MAAM;AAAA,IACjC;AACF,QAAM,OAAO,MAAM,SAAS,KAAK;AACjC,MAAI,KAAK,SAAS,IAAI,OAAO,KAAM,OAAM,IAAI,MAAM,oCAAW;AAC9D,SAAO,cAAc,MAAM,KAAK,MAAM,IAAI,CAAC;AAC7C;AACA,eAAsB,oBAAoB,MAA2C;AACnF,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAM,IAAI,OAAO,CAAC,QAAQ,UAAU,GAAG,EAAE,SAAS,KAAO,CAAC;AAC7E,WAAO,MAAM,wBAAwB,MAAM,OAAO,KAAK,CAAC;AAAA,EAC1D,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,wBAAwB,MAAc,YAAoB;AAC9E,QAAM,WAAW,KAAK,MAAM,SAAS,UAAU,GAAG,cAAc;AAGhE,OAAK,MAAM,MAAM,QAAQ,GAAG,eAAe,KAAM,MAAM,SAAS,IAAI,MAAO;AACzE,WAAO;AACT,MAAI;AACF,UAAM,MAAM,KAAK,UAAU,MAAM,CAAC;AAClC,WAAO;AAAA,EACT,SAAS,OAAO;AACd,QAAK,MAAgC,SAAS,SAAU,OAAM;AAAA,EAChE;AACA,QAAM,OAAO,MAAM,UAAU,IAAI;AACjC,SAAO;AACT;",
6
- "names": ["validVersion"]
4
+ "sourcesContent": ["import { npmPackageName } from '../shared/package.js';\nimport { validVersion, compareVersions } from '../shared/versions.js';\nexport { validVersion, compareVersions } from '../shared/versions.js';\nimport { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { realpath, access, lstat } from 'node:fs/promises';\nimport { constants } from 'node:fs';\nimport { join } from 'node:path';\nimport { z } from 'zod';\nimport type { ReleaseChannel } from '../shared/updates.js';\n\nconst run = promisify(execFile);\nexport const registry = 'https://registry.npmjs.org';\nexport const npmTags: Record<ReleaseChannel, string> = {\n stable: 'latest',\n beta: 'beta',\n dev: 'dev',\n};\nexport const releaseSchema = z.object({\n name: z.literal(npmPackageName),\n version: z.string().refine(validVersion),\n gitHead: z.string().optional(),\n covroCommit: z.string().optional(),\n covroCodex: z.unknown().optional(),\n});\nexport function packageMetadataUrl(selector?: string) {\n const url = `${registry}/${encodeURIComponent(npmPackageName)}`;\n return selector === undefined ? url : `${url}/${encodeURIComponent(selector)}`;\n}\nasync function lookupTag(channel: ReleaseChannel, signal?: AbortSignal) {\n const response = await fetch(packageMetadataUrl(npmTags[channel]), {\n signal: signal\n ? AbortSignal.any([signal, AbortSignal.timeout(15_000)])\n : AbortSignal.timeout(15_000),\n headers: { accept: 'application/json' },\n });\n if (response.status === 404) return undefined;\n if (!response.ok) throw new Error(`npm ${npmTags[channel]} \u67E5\u8BE2\u5931\u8D25\uFF08${response.status}\uFF09`);\n const body = await response.text();\n if (body.length > 2 * 1024 * 1024) throw new Error('npm \u5143\u6570\u636E\u8FC7\u5927');\n return { ...releaseSchema.parse(JSON.parse(body)), channel };\n}\nexport async function lookupRelease(channel: ReleaseChannel, signal?: AbortSignal) {\n // Resolve every allowed source once, then bind the chosen version and its metadata.\n // Stable wins equal precedence; a newer prerelease still wins over an older stable.\n const sources: ReleaseChannel[] = channel === 'stable' ? ['stable'] : ['stable', channel];\n const releases = await Promise.all(sources.map((source) => lookupTag(source, signal)));\n let selected: Awaited<ReturnType<typeof lookupTag>>;\n for (const release of releases)\n if (release && (!selected || compareVersions(release.version, selected.version) > 0))\n selected = release;\n if (!selected)\n throw new Error(\n `npm \u5C1A\u672A\u53D1\u5E03 Covro \u7684\u53EF\u7528\u7248\u672C\uFF08${sources.map((source) => npmTags[source]).join('\u3001')}\uFF09`,\n );\n return selected;\n}\nexport async function inspectInstallation(root: string): Promise<string | undefined> {\n try {\n const { stdout } = await run('npm', ['root', '--global'], { timeout: 15_000 });\n return await inspectPackageDirectory(root, stdout.trim());\n } catch {\n return '\u65E0\u6CD5\u786E\u8BA4\u53EF\u5199\u7684 npm \u5168\u5C40\u5B89\u88C5\uFF1B\u8BF7\u68C0\u67E5 npm\u3001\u5B89\u88C5\u76EE\u5F55\u6743\u9650\u53CA\u540E\u53F0 PATH\u3002';\n }\n}\n\nexport async function inspectPackageDirectory(root: string, globalRoot: string) {\n const expected = join(await realpath(globalRoot), npmPackageName);\n // npm link and pnpm global point outside the package directory. Following\n // that link would let the worker rename a developer's source checkout.\n if ((await lstat(expected)).isSymbolicLink() || (await realpath(root)) !== expected)\n return '\u5F53\u524D\u4E3A\u6E90\u7801\u3001\u94FE\u63A5\u6216\u975E npm \u5168\u5C40\u5B89\u88C5\uFF1B\u8BF7\u4F7F\u7528\u539F\u90E8\u7F72\u65B9\u5F0F\u66F4\u65B0\u3002';\n try {\n await lstat(join(expected, '.git'));\n return '\u5F53\u524D\u5B89\u88C5\u5305\u542B Git \u5DE5\u4F5C\u533A\uFF1B\u8BF7\u4F7F\u7528\u539F\u90E8\u7F72\u65B9\u5F0F\u66F4\u65B0\u3002';\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n }\n await access(root, constants.W_OK);\n return undefined;\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["validVersion", "compareVersions"]
7
7
  }
@@ -0,0 +1,73 @@
1
+ import { z } from "zod";
2
+ import { releaseNotesUrl } from "../shared/release-notes.js";
3
+ import { validVersion } from "../shared/versions.js";
4
+ const releaseNotesQuery = z.object({
5
+ version: z.string().max(128).refine((value) => value === value.trim() && validVersion(value)),
6
+ refresh: z.literal("1").optional()
7
+ });
8
+ const releaseSchema = z.object({
9
+ tag_name: z.string(),
10
+ html_url: z.string().url(),
11
+ body: z.string().nullable().optional(),
12
+ draft: z.boolean()
13
+ });
14
+ function createReleaseNotesLookup() {
15
+ const cache = /* @__PURE__ */ new Map();
16
+ const pending = /* @__PURE__ */ new Map();
17
+ async function load(version) {
18
+ const target = { version, url: releaseNotesUrl(version) };
19
+ try {
20
+ const response = await fetch(
21
+ `https://api.github.com/repos/yuzheng14/covro/releases/tags/${encodeURIComponent(`v${version}`)}`,
22
+ {
23
+ headers: { accept: "application/vnd.github+json" },
24
+ signal: AbortSignal.timeout(1e4),
25
+ redirect: "error"
26
+ }
27
+ );
28
+ if (response.status === 404) return { ...target, state: "missing" };
29
+ if (response.status === 429 || response.status === 403)
30
+ return { ...target, state: "error", reason: "rateLimited" };
31
+ if (!response.ok) throw new Error("Release request failed");
32
+ const text = await response.text();
33
+ if (text.length > 1024 * 1024) throw new Error("Release response too large");
34
+ const release = releaseSchema.parse(JSON.parse(text));
35
+ if (release.tag_name !== `v${version}`) throw new Error("Release tag mismatch");
36
+ if (release.draft) return { ...target, state: "missing" };
37
+ if (decodeURIComponent(release.html_url) !== decodeURIComponent(target.url))
38
+ throw new Error("Release URL mismatch");
39
+ return release.body?.trim() ? { ...target, url: release.html_url, state: "available", body: release.body } : { ...target, url: release.html_url, state: "empty" };
40
+ } catch {
41
+ return { ...target, state: "error", reason: "unavailable" };
42
+ }
43
+ }
44
+ return async (version, refresh = false) => {
45
+ releaseNotesQuery.parse({ version });
46
+ const cached = cache.get(version);
47
+ if (!refresh && cached && cached.expires > Date.now()) return cached.notes;
48
+ const existing = pending.get(version);
49
+ if (existing) return existing;
50
+ const request = load(version).then((notes) => {
51
+ if (notes.state !== "error") {
52
+ cache.delete(version);
53
+ if (cache.size >= 32) cache.delete(cache.keys().next().value);
54
+ cache.set(version, {
55
+ notes,
56
+ expires: Date.now() + (notes.state === "available" ? 5 * 6e4 : 6e4)
57
+ });
58
+ }
59
+ return notes;
60
+ });
61
+ pending.set(version, request);
62
+ try {
63
+ return await request;
64
+ } finally {
65
+ pending.delete(version);
66
+ }
67
+ };
68
+ }
69
+ export {
70
+ createReleaseNotesLookup,
71
+ releaseNotesQuery
72
+ };
73
+ //# sourceMappingURL=release-notes.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/updates/release-notes.ts"],
4
+ "sourcesContent": ["import { z } from 'zod';\nimport { releaseNotesUrl, type ReleaseNotes } from '../shared/release-notes.js';\nimport { validVersion } from '../shared/versions.js';\n\nexport const releaseNotesQuery = z.object({\n version: z\n .string()\n .max(128)\n .refine((value) => value === value.trim() && validVersion(value)),\n refresh: z.literal('1').optional(),\n});\nconst releaseSchema = z.object({\n tag_name: z.string(),\n html_url: z.string().url(),\n body: z.string().nullable().optional(),\n draft: z.boolean(),\n});\n\n/** Per gateway, shared across tabs; never mix a moving npm channel with a release tag. */\nexport function createReleaseNotesLookup() {\n const cache = new Map<string, { notes: ReleaseNotes; expires: number }>();\n const pending = new Map<string, Promise<ReleaseNotes>>();\n async function load(version: string): Promise<ReleaseNotes> {\n const target = { version, url: releaseNotesUrl(version) };\n try {\n const response = await fetch(\n `https://api.github.com/repos/yuzheng14/covro/releases/tags/${encodeURIComponent(`v${version}`)}`,\n {\n headers: { accept: 'application/vnd.github+json' },\n signal: AbortSignal.timeout(10_000),\n redirect: 'error',\n },\n );\n if (response.status === 404) return { ...target, state: 'missing' };\n if (response.status === 429 || response.status === 403)\n return { ...target, state: 'error', reason: 'rateLimited' };\n if (!response.ok) throw new Error('Release request failed');\n const text = await response.text();\n if (text.length > 1024 * 1024) throw new Error('Release response too large');\n const release = releaseSchema.parse(JSON.parse(text));\n if (release.tag_name !== `v${version}`) throw new Error('Release tag mismatch');\n if (release.draft) return { ...target, state: 'missing' };\n // Only link to this repository and exact tag, even if upstream data is malformed.\n if (decodeURIComponent(release.html_url) !== decodeURIComponent(target.url))\n throw new Error('Release URL mismatch');\n return release.body?.trim()\n ? { ...target, url: release.html_url, state: 'available', body: release.body }\n : { ...target, url: release.html_url, state: 'empty' };\n } catch {\n return { ...target, state: 'error', reason: 'unavailable' };\n }\n }\n return async (version: string, refresh = false): Promise<ReleaseNotes> => {\n // Validate here as well so non-HTTP callers cannot construct arbitrary selectors.\n releaseNotesQuery.parse({ version });\n const cached = cache.get(version);\n if (!refresh && cached && cached.expires > Date.now()) return cached.notes;\n const existing = pending.get(version);\n if (existing) return existing;\n const request = load(version).then((notes) => {\n if (notes.state !== 'error') {\n cache.delete(version);\n if (cache.size >= 32) cache.delete(cache.keys().next().value!);\n cache.set(version, {\n notes,\n expires: Date.now() + (notes.state === 'available' ? 5 * 60_000 : 60_000),\n });\n }\n return notes;\n });\n pending.set(version, request);\n try {\n return await request;\n } finally {\n pending.delete(version);\n }\n };\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -223,11 +223,11 @@ async function worker(directory) {
223
223
  ],
224
224
  { timeout: 10 * 6e4, maxBuffer: 2 * 1024 * 1024 }
225
225
  );
226
- const candidate = await readJson(
227
- join(paths.candidate, "package.json")
228
- );
226
+ const candidate = await readJson(join(paths.candidate, "package.json"));
229
227
  if (candidate?.name !== npmPackageName || candidate.version !== record.target)
230
228
  throw new Error("\u5019\u9009\u5305\u8EAB\u4EFD\u6216\u7248\u672C\u4E0D\u5339\u914D");
229
+ if (record.commit && (candidate.covroCommit ?? candidate.gitHead) !== record.commit)
230
+ throw new Error("\u5019\u9009\u5305\u6E90\u7801\u63D0\u4EA4\u4E0E\u68C0\u67E5\u65F6\u4E0D\u4E00\u81F4\uFF0C\u62D2\u7EDD\u5207\u6362");
231
231
  if (!record.codex) throw new Error("\u7F3A\u5C11 Codex \u5347\u7EA7\u6821\u9A8C\u8BB0\u5F55\uFF0C\u8BF7\u91CD\u65B0\u68C0\u67E5\u66F4\u65B0");
232
232
  const manifest = codexCompatibilitySchema.parse(candidate.covroCodex);
233
233
  if (JSON.stringify(manifest) !== JSON.stringify(record.codex.manifest))