@covro/covro 0.2.1-dev.5 → 0.2.1-dev.6

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 (93) hide show
  1. package/README.md +5 -4
  2. package/README.zh-CN.md +2 -1
  3. package/dist/codex/auto-review.js +55 -0
  4. package/dist/codex/auto-review.js.map +2 -2
  5. package/dist/server/project-clones.js +53 -17
  6. package/dist/server/project-clones.js.map +2 -2
  7. package/dist/web/assets/{abnfDiagram-WEYOIA3C-CwLX554E.js → abnfDiagram-WEYOIA3C-BkC1EVBk.js} +1 -1
  8. package/dist/web/assets/{arc-DAaDyyqc.js → arc-CYGT9huc.js} +1 -1
  9. package/dist/web/assets/{architecture-WOLXFQ4H-y6MnEqN0.js → architecture-WOLXFQ4H-DCsF3gVg.js} +1 -1
  10. package/dist/web/assets/{architectureDiagram-ZHVYKT53-_B_4k-Pp.js → architectureDiagram-ZHVYKT53-Cn6kovuz.js} +1 -1
  11. package/dist/web/assets/{blockDiagram-RJAE7QA3-C9jZ7FHy.js → blockDiagram-RJAE7QA3-CNk2zXm9.js} +1 -1
  12. package/dist/web/assets/{c4Diagram-XDPPPE54-DQAtMvqN.js → c4Diagram-XDPPPE54-CTuI_1XJ.js} +1 -1
  13. package/dist/web/assets/channel-BDxsxdm-.js +1 -0
  14. package/dist/web/assets/{chunk-2E7WHVMD-Bu427yab.js → chunk-2E7WHVMD-TrYs0qV3.js} +1 -1
  15. package/dist/web/assets/{chunk-4EMNKR2T-BrGrBG7B.js → chunk-4EMNKR2T-QL4-PZ4r.js} +1 -1
  16. package/dist/web/assets/{chunk-55XCU76K-l4f0OZWA.js → chunk-55XCU76K-yynn-EEr.js} +1 -1
  17. package/dist/web/assets/{chunk-7S6XSTFO-D7ixF313.js → chunk-7S6XSTFO-dzrEn-_W.js} +1 -1
  18. package/dist/web/assets/{chunk-AQDTSKZB-Cesd-BF2.js → chunk-AQDTSKZB-DaNZMEGO.js} +1 -1
  19. package/dist/web/assets/{chunk-DSNLSHJZ-B7dim5uT.js → chunk-DSNLSHJZ-BnMtx8Ho.js} +1 -1
  20. package/dist/web/assets/{chunk-HAGFOTED-B-f2I7TA.js → chunk-HAGFOTED-fg-JyiA5.js} +1 -1
  21. package/dist/web/assets/{chunk-HNE4Q36P-CoIvaeX6.js → chunk-HNE4Q36P-CCsfPbcn.js} +1 -1
  22. package/dist/web/assets/{chunk-NQOKRVIF-BybRxR7n.js → chunk-NQOKRVIF-DLlOpcWZ.js} +1 -1
  23. package/dist/web/assets/{chunk-UHW7PFBP-CV5WG4tq.js → chunk-UHW7PFBP-B-sPKpeS.js} +1 -1
  24. package/dist/web/assets/{chunk-VQ5W62QI-BO4AjXi1.js → chunk-VQ5W62QI-BVqGMzey.js} +1 -1
  25. package/dist/web/assets/{chunk-WQQL4CDK-CADNDGXO.js → chunk-WQQL4CDK-DcwJXNuh.js} +1 -1
  26. package/dist/web/assets/{chunk-XXDRQBXY-C6QZT7KW.js → chunk-XXDRQBXY-DRwLkqyU.js} +1 -1
  27. package/dist/web/assets/{chunk-YZO67HFG-Cm6eGReX.js → chunk-YZO67HFG-BrrgBnrQ.js} +1 -1
  28. package/dist/web/assets/{chunk-ZAUX2LTX-CUBoGbKg.js → chunk-ZAUX2LTX-C7qvwkRr.js} +1 -1
  29. package/dist/web/assets/{chunk-ZCHMQSOR-B0ImOOtq.js → chunk-ZCHMQSOR-DdBd3Cvs.js} +1 -1
  30. package/dist/web/assets/{classDiagram-v2-4MYWR3UA-D5NWZ9vm.js → classDiagram-v2-4MYWR3UA-Dn2RZb3v.js} +1 -1
  31. package/dist/web/assets/{cose-bilkent-JH36ORCC-BzckEyjA.js → cose-bilkent-JH36ORCC-BlXvtfgE.js} +1 -1
  32. package/dist/web/assets/{cynefin-EF2NZ3EQ-Da_J6-Jb.js → cynefin-EF2NZ3EQ-odDgTxc-.js} +1 -1
  33. package/dist/web/assets/{cynefinDiagram-WF24UDRP-b4g_B1A-.js → cynefinDiagram-WF24UDRP-BySEoCW8.js} +1 -1
  34. package/dist/web/assets/{dagre-NK4GIZVX-89H2mfs9.js → dagre-NK4GIZVX-ihxmhB4X.js} +1 -1
  35. package/dist/web/assets/{diagram-CBK3MWTC-CW4f_P0l.js → diagram-CBK3MWTC-Ckr5P3IM.js} +1 -1
  36. package/dist/web/assets/{diagram-I5XIIV2D-Cv5Qndgc.js → diagram-I5XIIV2D-D5BZIval.js} +1 -1
  37. package/dist/web/assets/{diagram-ODIL2UCW-LrXxeoCt.js → diagram-ODIL2UCW-BC5jjqqY.js} +1 -1
  38. package/dist/web/assets/{diagram-PFBEJUXE-uJV2PooB.js → diagram-PFBEJUXE-D_IdYKqC.js} +1 -1
  39. package/dist/web/assets/{diagram-RJA3I4VV-DlY0PGRs.js → diagram-RJA3I4VV-DlPNsPqP.js} +1 -1
  40. package/dist/web/assets/{diagram-TYUNFSNR-B1KoXBEE.js → diagram-TYUNFSNR-Ca2ANhGM.js} +1 -1
  41. package/dist/web/assets/{dist-B4eX4BCP.js → dist-BSWkYZRr.js} +1 -1
  42. package/dist/web/assets/{ebnfDiagram-V4P3TTPT-xCvQVbdj.js → ebnfDiagram-V4P3TTPT-BrqvmeiB.js} +1 -1
  43. package/dist/web/assets/{elk-QONTBCTQ-Cl8Hu-Uy.js → elk-QONTBCTQ-BfXeOE2E.js} +1 -1
  44. package/dist/web/assets/{erDiagram-KYQIGQAA-Xp-AvSwE.js → erDiagram-KYQIGQAA-CMuYoCVJ.js} +1 -1
  45. package/dist/web/assets/{eventmodeling-K75KTNOO-C0truZGU.js → eventmodeling-K75KTNOO-9s4vQqv1.js} +1 -1
  46. package/dist/web/assets/flowDiagram-IUGLLWBU-BHwP7Ha7.js +1 -0
  47. package/dist/web/assets/{ganttDiagram-R7GPNTJY-rPaYp-D7.js → ganttDiagram-R7GPNTJY-B-Xmfmm2.js} +1 -1
  48. package/dist/web/assets/{gitGraph-VSP46ZUC-Bgfpho41.js → gitGraph-VSP46ZUC-ZSbSQ7jf.js} +1 -1
  49. package/dist/web/assets/{gitGraphDiagram-PDYL7XHY-kDcmuv6k.js → gitGraphDiagram-PDYL7XHY-BhxijLaZ.js} +1 -1
  50. package/dist/web/assets/index-BrvtlTwN.js +147 -0
  51. package/dist/web/assets/{index-B7tnf28H.css → index-mkDvqMQ3.css} +1 -1
  52. package/dist/web/assets/{info-OHQRW6UA-CAWg5k9R.js → info-OHQRW6UA-CTSCkjt3.js} +1 -1
  53. package/dist/web/assets/{infoDiagram-MVDRKAX5-Cd08ebhn.js → infoDiagram-MVDRKAX5-D46MTesD.js} +1 -1
  54. package/dist/web/assets/{ishikawaDiagram-HPEHV2GE-tAXBLt9k.js → ishikawaDiagram-HPEHV2GE-Bafu9NOk.js} +1 -1
  55. package/dist/web/assets/{journeyDiagram-BOSHW7O7-ZgnWqXkg.js → journeyDiagram-BOSHW7O7-CRsIi1Ry.js} +1 -1
  56. package/dist/web/assets/{kanban-definition-FNSA4HC5-BUjtjd-h.js → kanban-definition-FNSA4HC5-DjIT_uLs.js} +1 -1
  57. package/dist/web/assets/{line-DG48HRVK.js → line-B5MDdgVs.js} +1 -1
  58. package/dist/web/assets/{linear-CqnXVCVw.js → linear-wm7JWxlT.js} +1 -1
  59. package/dist/web/assets/{mermaid-parser.core-gIvgB9WK.js → mermaid-parser.core-C7jTW4sZ.js} +3 -3
  60. package/dist/web/assets/{mermaid.core-C_R7Y1XB.js → mermaid.core-DcWRGjP5.js} +4 -4
  61. package/dist/web/assets/{mindmap-definition-6OY57UG3-CwUEEl_y.js → mindmap-definition-6OY57UG3-qY6vV0UI.js} +1 -1
  62. package/dist/web/assets/{packet-JDAUHWVQ-BrXmpRQ3.js → packet-JDAUHWVQ-9B7vLYK0.js} +1 -1
  63. package/dist/web/assets/{pegDiagram-ECIUJNBX-lLApO85Q.js → pegDiagram-ECIUJNBX-B7gLZ_Fs.js} +1 -1
  64. package/dist/web/assets/{pie-XZMESJXO-C_8kR5WX.js → pie-XZMESJXO-MfazZSiE.js} +1 -1
  65. package/dist/web/assets/{pieDiagram-GNMPY74T-CawGmJZn.js → pieDiagram-GNMPY74T-1ahagzzC.js} +1 -1
  66. package/dist/web/assets/{quadrantDiagram-D57K4MC3-Dg6Yq3s_.js → quadrantDiagram-D57K4MC3-C-GkwjOp.js} +1 -1
  67. package/dist/web/assets/{radar-ABXABTNO-Bs1xY09D.js → radar-ABXABTNO-CgutvWTi.js} +1 -1
  68. package/dist/web/assets/{railroad-I3PHUGI6-Bw_qS6e3.js → railroad-I3PHUGI6-Bl9LJINm.js} +1 -1
  69. package/dist/web/assets/{railroad-abnf-LNEFI6M7-CQr33CuI.js → railroad-abnf-LNEFI6M7-CGRpAnuU.js} +1 -1
  70. package/dist/web/assets/{railroad-ebnf-DWYD2UWJ-BY9nk5pg.js → railroad-ebnf-DWYD2UWJ-D6A47xZS.js} +1 -1
  71. package/dist/web/assets/{railroad-peg-JR7BVNR7-CcFsAEI4.js → railroad-peg-JR7BVNR7-DxGphrFO.js} +1 -1
  72. package/dist/web/assets/{railroadDiagram-Y72NRBL7-rkZbchmc.js → railroadDiagram-Y72NRBL7-D8P17OV4.js} +1 -1
  73. package/dist/web/assets/{requirementDiagram-EQYSW5RA-CSOcijj5.js → requirementDiagram-EQYSW5RA-c93_xAaQ.js} +1 -1
  74. package/dist/web/assets/{sankeyDiagram-SY24JHO5-E0uo0rRp.js → sankeyDiagram-SY24JHO5-FankqwcZ.js} +1 -1
  75. package/dist/web/assets/{sequenceDiagram-BLEHNHQU-BKWAAcRu.js → sequenceDiagram-BLEHNHQU-CWH5SeL1.js} +1 -1
  76. package/dist/web/assets/{src-F6L8HcEC.js → src-BXQOmVZv.js} +1 -1
  77. package/dist/web/assets/{stateDiagram-v2-A6IESKWZ-BBk2tpPh.js → stateDiagram-v2-A6IESKWZ-DLfcw0e7.js} +1 -1
  78. package/dist/web/assets/{swimlanes-B3ENRKFQ-CAUrhGwF.js → swimlanes-B3ENRKFQ-DZ-yBiap.js} +1 -1
  79. package/dist/web/assets/swimlanesDiagram-AYQRV4AK-BlmdUBbW.js +8 -0
  80. package/dist/web/assets/{timeline-definition-JXYKGLGB-D0FWj9fa.js → timeline-definition-JXYKGLGB-B7XvxDHY.js} +1 -1
  81. package/dist/web/assets/{treeView-D4JQ5SDB-CkJOmf93.js → treeView-D4JQ5SDB-DrB6wXJ0.js} +1 -1
  82. package/dist/web/assets/{treemap-SAJKECNS-BSFsardB.js → treemap-SAJKECNS-BynFjsvx.js} +1 -1
  83. package/dist/web/assets/{usecaseDiagram-WPOLBNNX-B2U-2o4g.js → usecaseDiagram-WPOLBNNX-BISzHOHN.js} +1 -1
  84. package/dist/web/assets/{vennDiagram-Q3Y3IDCW-BijTH0fT.js → vennDiagram-Q3Y3IDCW-BZwjTIST.js} +1 -1
  85. package/dist/web/assets/{wardley-7MLQ67FV-DDOa5RzL.js → wardley-7MLQ67FV-2bM0pMhO.js} +1 -1
  86. package/dist/web/assets/{wardleyDiagram-IVAIDKWA-mbb5GvW5.js → wardleyDiagram-IVAIDKWA-CflkU8us.js} +1 -1
  87. package/dist/web/assets/{xychartDiagram-4URNHDU4-DHd60D_Y.js → xychartDiagram-4URNHDU4-DRspOlD3.js} +1 -1
  88. package/dist/web/index.html +4 -4
  89. package/package.json +5 -3
  90. package/dist/web/assets/channel-ByzMCsOB.js +0 -1
  91. package/dist/web/assets/flowDiagram-IUGLLWBU-T67jQ-T_.js +0 -1
  92. package/dist/web/assets/index-3DUP8YCe.js +0 -142
  93. package/dist/web/assets/swimlanesDiagram-AYQRV4AK-BCnJymLL.js +0 -8
package/README.md CHANGED
@@ -30,7 +30,8 @@
30
30
  ## ✨ What you can do
31
31
 
32
32
  - 📱 **Step away from your desk. Stay with the task.** Follow tool activity, inspect file changes, handle permission requests, and answer Codex's questions from your computer or phone. Closing the page doesn't cancel the task.
33
- - 💬 **Start without a project.** Use **新建会话** (New conversation) to start in an automatically assigned directory. Conversations and files stay available after refresh, restart, or archive.
33
+ - 💬 **Start without a project.** Use **New session** to start in an automatically assigned directory. Conversations and files stay available after refresh, restart, or archive.
34
+ - 🌐 **Choose your interface language.** Switch between 简体中文, English, 日本語 and 한국어 without leaving your session. Prompts, replies, tool output and paths remain unchanged. [Localization details](docs/i18n.md).
34
35
  - 🗂️ **See every project in one place.** Run independent tasks in parallel and spot which conversations are working, waiting for approval, or ready to read.
35
36
  - 💬 **Pick up your Codex CLI conversations.** Browse saved history, resume existing work, or fork a new direction. Rename conversations to find them later and archive them when you're done. View and copy the full Thread ID in conversation details or diagnostics.
36
37
  - ⚡ **Open long conversations sooner.** Recent messages appear first; scrolling preloads older history. On this device, cached conversation lists and history pages appear while the server checks for updates. [Loading and cache behavior](docs/session-history.md).
@@ -51,7 +52,7 @@ Mermaid diagrams render locally after their code fence closes, with automatic li
51
52
 
52
53
  ## 🚀 Get started
53
54
 
54
- You need **Node.js 24.19 or later in the 24.x line** and an installed, signed-in **Codex CLI**. The interface currently uses Simplified Chinese.
55
+ You need **Node.js 24.19 or later in the 24.x line** and an installed, signed-in **Codex CLI**. The interface supports Simplified Chinese, English, Japanese and Korean. Choose **Language** in the sidebar; the first visit follows your browser preferences, and manual choices are saved on this device.
55
56
 
56
57
  <!-- codex-compatibility:start -->
57
58
 
@@ -105,9 +106,9 @@ pnpm build
105
106
  pnpm start -- --config ./config.local.json
106
107
  ```
107
108
 
108
- Open **<http://127.0.0.1:8787>** and click **+** beside **未关联项目** (Unassigned) in the sidebar to send a task without choosing a project.
109
+ Open **<http://127.0.0.1:8787>** and click **+** beside **Unassigned** in the sidebar to send a task without choosing a project.
109
110
 
110
- To work in a project directory, click **添加项目** (Add project), then choose an existing host directory or **克隆 Git 仓库** (Clone Git repository). For cloning, enter an HTTPS/SSH repository address, an absolute destination on the host, and an optional project name. Git must be available to the service and uses the host’s existing credentials. Follow progress or cancel in the dialog; once imported, open the project and send your first task. [Clone requirements and recovery](docs/project-clone.md).
111
+ To work in a project directory, click **Add project**, then choose an existing host directory or **Clone Git repository**. For cloning, enter an HTTPS/SSH repository address, an absolute destination on the host, and an optional project name. Git must be available to the service and uses the host’s existing credentials. Follow progress or cancel in the dialog; once imported, open the project and send your first task. [Clone requirements and recovery](docs/project-clone.md).
111
112
 
112
113
  Unassigned conversations use separate directories under `<dataDir>/workspaces/`, allocated on the first send. Their files are retained until you explicitly remove them; archiving does not delete files. See [conversation workspaces](docs/workspaces.md) for directory, recovery, and backup details.
113
114
 
package/README.zh-CN.md CHANGED
@@ -31,6 +31,7 @@
31
31
 
32
32
  - 📱 **离开电脑,也能跟进任务。** 在电脑或手机上查看工具活动与文件变更、处理权限审批、回答 Codex 的问题。关闭页面,任务仍会继续。
33
33
  - 💬 **无需项目,也能直接开始。** 点击 **新建会话**,应用自动分配独立目录;刷新、重启或归档后,会话和文件仍保留。
34
+ - 🌐 **选择界面语言。** 支持简体中文、English、日本語和 한국어,会话内即可切换;输入、回复、工具原文和路径保持不变。[多语言说明](docs/i18n.md)。
34
35
  - 🗂️ **多个项目,一眼掌握进展。** 让独立任务并行执行,随时看到哪些会话正在工作、等待审批,哪些已有结果可读。
35
36
  - 💬 **接着你的 Codex CLI 会话。** 浏览已有历史、恢复工作,或 Fork 一个新方向;为会话命名以便查找,完成后归档。在会话详情或状态诊断中查看、复制完整 Thread ID。
36
37
  - ⚡ **更快打开长会话。** 优先显示最近消息,向上滚动时提前加载历史;本机会话列表和历史分片可先显示缓存,再由服务端核对更新。[加载与缓存说明](docs/session-history.md)。
@@ -51,7 +52,7 @@ Mermaid 图表在代码块闭合后于本地渲染,自动适配浅色/深色
51
52
 
52
53
  ## 🚀 开始使用
53
54
 
54
- 需要 **Node.js 24.x,版本不低于 24.19**,以及已经安装、登录的 **Codex CLI**。界面目前使用简体中文。
55
+ 需要 **Node.js 24.x,版本不低于 24.19**,以及已经安装、登录的 **Codex CLI**。界面支持简体中文、英语、日语和韩语。在侧栏选择「语言」;首次访问按浏览器偏好匹配,手动选择会保存在当前设备。
55
56
 
56
57
  <!-- codex-compatibility:start -->
57
58
 
@@ -82,6 +82,60 @@ ${action.target}`
82
82
  return { actionLabel: "\u64CD\u4F5C\u5BA1\u6838", actionSummary: "\u672A\u63D0\u4F9B\u53EF\u8BC6\u522B\u7684\u64CD\u4F5C\u8BE6\u60C5" };
83
83
  }
84
84
  }
85
+ function actionPresentation(action) {
86
+ const raw = (value) => ({ label: "raw", value });
87
+ switch (action.type) {
88
+ case "command":
89
+ return { kind: action.type, parts: [raw(action.command)] };
90
+ case "execve":
91
+ return {
92
+ kind: action.type,
93
+ parts: [
94
+ { label: "program", value: action.program },
95
+ { label: "arguments", value: action.argv.map((arg) => JSON.stringify(arg)).join(" ") }
96
+ ]
97
+ };
98
+ case "writeStdin":
99
+ return {
100
+ kind: action.type,
101
+ parts: [{ label: "process", value: action.processId }, raw(action.stdin)]
102
+ };
103
+ case "applyPatch":
104
+ return { kind: action.type, parts: action.files.map(raw) };
105
+ case "networkAccess":
106
+ return {
107
+ kind: action.type,
108
+ parts: [raw(`${action.protocol}://${action.host}:${action.port}`), raw(action.target)]
109
+ };
110
+ case "mcpToolCall":
111
+ return {
112
+ kind: action.type,
113
+ parts: [
114
+ raw(
115
+ [action.connectorName, `${action.server}/${action.toolName}`, action.toolTitle].filter(Boolean).join(" \xB7 ")
116
+ )
117
+ ]
118
+ };
119
+ case "requestPermissions": {
120
+ const parts = [];
121
+ if (action.reason) parts.push(raw(action.reason));
122
+ const network = action.permissions.network?.enabled;
123
+ if (network != null)
124
+ parts.push({ label: network ? "networkAllowed" : "networkRestricted", value: "" });
125
+ const files = action.permissions.fileSystem;
126
+ for (const path of files?.read ?? []) parts.push({ label: "read", value: path });
127
+ for (const path of files?.write ?? []) parts.push({ label: "write", value: path });
128
+ for (const entry of files?.entries ?? [])
129
+ parts.push({
130
+ label: entry.access,
131
+ value: entry.path.type === "path" ? entry.path.path : JSON.stringify(entry.path)
132
+ });
133
+ if (files?.globScanMaxDepth !== void 0)
134
+ parts.push({ label: "depth", value: String(files.globScanMaxDepth) });
135
+ return { kind: action.type, parts };
136
+ }
137
+ }
138
+ }
85
139
  function mapAutoReview(params) {
86
140
  const review = params.review;
87
141
  return {
@@ -89,6 +143,7 @@ function mapAutoReview(params) {
89
143
  ...params.targetItemId === null ? {} : { targetItemId: params.targetItemId },
90
144
  status: ["inProgress", "approved", "denied", "timedOut", "aborted"].includes(review.status) ? review.status : "unknown",
91
145
  ...describeAction(params.action),
146
+ presentation: actionPresentation(params.action),
92
147
  ...review.rationale === null ? {} : { rationale: review.rationale },
93
148
  ...review.riskLevel === null ? {} : { riskLevel: review.riskLevel },
94
149
  ...review.userAuthorization === null ? {} : { userAuthorization: review.userAuthorization },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/codex/auto-review.ts"],
4
- "sourcesContent": ["import type { AutoReviewView } from '../shared/types.js';\nimport type { GuardianApprovalReviewAction } from './generated/v2/GuardianApprovalReviewAction.js';\nimport type { FileSystemPath } from './generated/v2/FileSystemPath.js';\nimport type { ItemGuardianApprovalReviewStartedNotification } from './generated/v2/ItemGuardianApprovalReviewStartedNotification.js';\nimport type { ItemGuardianApprovalReviewCompletedNotification } from './generated/v2/ItemGuardianApprovalReviewCompletedNotification.js';\n\ntype Notification =\n ItemGuardianApprovalReviewStartedNotification | ItemGuardianApprovalReviewCompletedNotification;\n\nfunction pathLabel(path: FileSystemPath): string {\n if (path.type === 'path') return path.path;\n if (path.type === 'glob_pattern') return `\u5339\u914D\uFF1A${path.pattern}`;\n const special = path.value;\n const subpath =\n 'subpath' in special && special.subpath !== null ? `\uFF08\u5B50\u8DEF\u5F84\uFF1A${special.subpath}\uFF09` : '';\n switch (special.kind) {\n case 'root':\n return '\u6574\u4E2A\u6587\u4EF6\u7CFB\u7EDF\uFF08/\uFF09';\n case 'minimal':\n return '\u7CFB\u7EDF\u57FA\u7840\u8FD0\u884C\u76EE\u5F55';\n case 'project_roots':\n return `\u9879\u76EE\u6839\u76EE\u5F55${subpath}`;\n case 'tmpdir':\n return '\u7CFB\u7EDF\u4E34\u65F6\u76EE\u5F55\uFF08TMPDIR\uFF09';\n case 'slash_tmp':\n return '/tmp';\n case 'unknown':\n return `\u7279\u6B8A\u8DEF\u5F84\uFF1A${special.path}${subpath}`;\n }\n}\n\nfunction describeAction(\n action: GuardianApprovalReviewAction,\n): Pick<AutoReviewView, 'actionLabel' | 'actionSummary' | 'cwd'> {\n switch (action.type) {\n case 'command':\n return { actionLabel: '\u547D\u4EE4\u6267\u884C', actionSummary: action.command, cwd: action.cwd };\n case 'execve':\n return {\n actionLabel: '\u7A0B\u5E8F\u6267\u884C',\n actionSummary: `\u7A0B\u5E8F\uFF1A${action.program}\\n\u53C2\u6570\uFF1A${action.argv.map((arg) => JSON.stringify(arg)).join(' ')}`,\n cwd: action.cwd,\n };\n case 'writeStdin':\n return {\n actionLabel: '\u7EC8\u7AEF\u8F93\u5165',\n actionSummary: `\u8FDB\u7A0B ${action.processId}\\n${action.stdin}`,\n cwd: action.cwd,\n };\n case 'applyPatch':\n return {\n actionLabel: '\u6587\u4EF6\u53D8\u66F4',\n actionSummary: action.files.join('\\n') || '\u672A\u63D0\u4F9B\u6587\u4EF6\u8DEF\u5F84',\n cwd: action.cwd,\n };\n case 'networkAccess':\n return {\n actionLabel: '\u7F51\u7EDC\u8BBF\u95EE',\n actionSummary: `${action.protocol}://${action.host}:${action.port}\\n${action.target}`,\n };\n case 'mcpToolCall':\n return {\n actionLabel: '\u5DE5\u5177\u8C03\u7528',\n actionSummary: [\n action.connectorName,\n `${action.server}/${action.toolName}`,\n action.toolTitle,\n ]\n .filter(Boolean)\n .join(' \u00B7 '),\n };\n case 'requestPermissions': {\n const lines: string[] = [];\n if (action.reason) lines.push(action.reason);\n if (\n action.permissions.network?.enabled !== null &&\n action.permissions.network?.enabled !== undefined\n )\n lines.push(`\u7F51\u7EDC\u8BBF\u95EE\uFF1A${action.permissions.network.enabled ? '\u5141\u8BB8' : '\u4E0D\u5F00\u653E\u989D\u5916\u6743\u9650'}`);\n const files = action.permissions.fileSystem;\n if (files) {\n for (const path of files.read ?? []) lines.push(`\u8BFB\u53D6\uFF1A${path}`);\n for (const path of files.write ?? []) lines.push(`\u5199\u5165\uFF1A${path}`);\n for (const entry of files.entries ?? [])\n lines.push(\n `${{ read: '\u8BFB\u53D6', write: '\u5199\u5165', deny: '\u7981\u6B62\u8BBF\u95EE' }[entry.access]}\uFF1A${pathLabel(entry.path)}`,\n );\n if (files.globScanMaxDepth !== undefined)\n lines.push(`\u76EE\u5F55\u5339\u914D\u641C\u7D22\u6DF1\u5EA6\uFF1A${files.globScanMaxDepth}`);\n }\n return {\n actionLabel: '\u6743\u9650\u53D8\u66F4',\n actionSummary: lines.join('\\n') || '\u672A\u8BF7\u6C42\u989D\u5916\u7F51\u7EDC\u6216\u6587\u4EF6\u8BBF\u95EE\u6743\u9650',\n };\n }\n default:\n return { actionLabel: '\u64CD\u4F5C\u5BA1\u6838', actionSummary: '\u672A\u63D0\u4F9B\u53EF\u8BC6\u522B\u7684\u64CD\u4F5C\u8BE6\u60C5' };\n }\n}\n\n/** Display-only data. Notifications never become a PendingAction or a permission response. */\nexport function mapAutoReview(params: Notification): AutoReviewView {\n const review = params.review;\n return {\n reviewId: params.reviewId,\n ...(params.targetItemId === null ? {} : { targetItemId: params.targetItemId }),\n status: ['inProgress', 'approved', 'denied', 'timedOut', 'aborted'].includes(review.status)\n ? review.status\n : 'unknown',\n ...describeAction(params.action),\n ...(review.rationale === null ? {} : { rationale: review.rationale }),\n ...(review.riskLevel === null ? {} : { riskLevel: review.riskLevel }),\n ...(review.userAuthorization === null ? {} : { userAuthorization: review.userAuthorization }),\n startedAtMs: params.startedAtMs,\n ...('completedAtMs' in params ? { completedAtMs: params.completedAtMs } : {}),\n };\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { AutoReviewView } from '../shared/types.js';\nimport type { GuardianApprovalReviewAction } from './generated/v2/GuardianApprovalReviewAction.js';\nimport type { FileSystemPath } from './generated/v2/FileSystemPath.js';\nimport type { ItemGuardianApprovalReviewStartedNotification } from './generated/v2/ItemGuardianApprovalReviewStartedNotification.js';\nimport type { ItemGuardianApprovalReviewCompletedNotification } from './generated/v2/ItemGuardianApprovalReviewCompletedNotification.js';\n\ntype Notification =\n ItemGuardianApprovalReviewStartedNotification | ItemGuardianApprovalReviewCompletedNotification;\n\nfunction pathLabel(path: FileSystemPath): string {\n if (path.type === 'path') return path.path;\n if (path.type === 'glob_pattern') return `\u5339\u914D\uFF1A${path.pattern}`;\n const special = path.value;\n const subpath =\n 'subpath' in special && special.subpath !== null ? `\uFF08\u5B50\u8DEF\u5F84\uFF1A${special.subpath}\uFF09` : '';\n switch (special.kind) {\n case 'root':\n return '\u6574\u4E2A\u6587\u4EF6\u7CFB\u7EDF\uFF08/\uFF09';\n case 'minimal':\n return '\u7CFB\u7EDF\u57FA\u7840\u8FD0\u884C\u76EE\u5F55';\n case 'project_roots':\n return `\u9879\u76EE\u6839\u76EE\u5F55${subpath}`;\n case 'tmpdir':\n return '\u7CFB\u7EDF\u4E34\u65F6\u76EE\u5F55\uFF08TMPDIR\uFF09';\n case 'slash_tmp':\n return '/tmp';\n case 'unknown':\n return `\u7279\u6B8A\u8DEF\u5F84\uFF1A${special.path}${subpath}`;\n }\n}\n\nfunction describeAction(\n action: GuardianApprovalReviewAction,\n): Pick<AutoReviewView, 'actionLabel' | 'actionSummary' | 'cwd'> {\n switch (action.type) {\n case 'command':\n return { actionLabel: '\u547D\u4EE4\u6267\u884C', actionSummary: action.command, cwd: action.cwd };\n case 'execve':\n return {\n actionLabel: '\u7A0B\u5E8F\u6267\u884C',\n actionSummary: `\u7A0B\u5E8F\uFF1A${action.program}\\n\u53C2\u6570\uFF1A${action.argv.map((arg) => JSON.stringify(arg)).join(' ')}`,\n cwd: action.cwd,\n };\n case 'writeStdin':\n return {\n actionLabel: '\u7EC8\u7AEF\u8F93\u5165',\n actionSummary: `\u8FDB\u7A0B ${action.processId}\\n${action.stdin}`,\n cwd: action.cwd,\n };\n case 'applyPatch':\n return {\n actionLabel: '\u6587\u4EF6\u53D8\u66F4',\n actionSummary: action.files.join('\\n') || '\u672A\u63D0\u4F9B\u6587\u4EF6\u8DEF\u5F84',\n cwd: action.cwd,\n };\n case 'networkAccess':\n return {\n actionLabel: '\u7F51\u7EDC\u8BBF\u95EE',\n actionSummary: `${action.protocol}://${action.host}:${action.port}\\n${action.target}`,\n };\n case 'mcpToolCall':\n return {\n actionLabel: '\u5DE5\u5177\u8C03\u7528',\n actionSummary: [\n action.connectorName,\n `${action.server}/${action.toolName}`,\n action.toolTitle,\n ]\n .filter(Boolean)\n .join(' \u00B7 '),\n };\n case 'requestPermissions': {\n const lines: string[] = [];\n if (action.reason) lines.push(action.reason);\n if (\n action.permissions.network?.enabled !== null &&\n action.permissions.network?.enabled !== undefined\n )\n lines.push(`\u7F51\u7EDC\u8BBF\u95EE\uFF1A${action.permissions.network.enabled ? '\u5141\u8BB8' : '\u4E0D\u5F00\u653E\u989D\u5916\u6743\u9650'}`);\n const files = action.permissions.fileSystem;\n if (files) {\n for (const path of files.read ?? []) lines.push(`\u8BFB\u53D6\uFF1A${path}`);\n for (const path of files.write ?? []) lines.push(`\u5199\u5165\uFF1A${path}`);\n for (const entry of files.entries ?? [])\n lines.push(\n `${{ read: '\u8BFB\u53D6', write: '\u5199\u5165', deny: '\u7981\u6B62\u8BBF\u95EE' }[entry.access]}\uFF1A${pathLabel(entry.path)}`,\n );\n if (files.globScanMaxDepth !== undefined)\n lines.push(`\u76EE\u5F55\u5339\u914D\u641C\u7D22\u6DF1\u5EA6\uFF1A${files.globScanMaxDepth}`);\n }\n return {\n actionLabel: '\u6743\u9650\u53D8\u66F4',\n actionSummary: lines.join('\\n') || '\u672A\u8BF7\u6C42\u989D\u5916\u7F51\u7EDC\u6216\u6587\u4EF6\u8BBF\u95EE\u6743\u9650',\n };\n }\n default:\n return { actionLabel: '\u64CD\u4F5C\u5BA1\u6838', actionSummary: '\u672A\u63D0\u4F9B\u53EF\u8BC6\u522B\u7684\u64CD\u4F5C\u8BE6\u60C5' };\n }\n}\n\nfunction actionPresentation(\n action: GuardianApprovalReviewAction,\n): NonNullable<AutoReviewView['presentation']> {\n const raw = (value: string) => ({ label: 'raw', value });\n switch (action.type) {\n case 'command':\n return { kind: action.type, parts: [raw(action.command)] };\n case 'execve':\n return {\n kind: action.type,\n parts: [\n { label: 'program', value: action.program },\n { label: 'arguments', value: action.argv.map((arg) => JSON.stringify(arg)).join(' ') },\n ],\n };\n case 'writeStdin':\n return {\n kind: action.type,\n parts: [{ label: 'process', value: action.processId }, raw(action.stdin)],\n };\n case 'applyPatch':\n return { kind: action.type, parts: action.files.map(raw) };\n case 'networkAccess':\n return {\n kind: action.type,\n parts: [raw(`${action.protocol}://${action.host}:${action.port}`), raw(action.target)],\n };\n case 'mcpToolCall':\n return {\n kind: action.type,\n parts: [\n raw(\n [action.connectorName, `${action.server}/${action.toolName}`, action.toolTitle]\n .filter(Boolean)\n .join(' \u00B7 '),\n ),\n ],\n };\n case 'requestPermissions': {\n const parts: { label: string; value: string }[] = [];\n if (action.reason) parts.push(raw(action.reason));\n const network = action.permissions.network?.enabled;\n if (network != null)\n parts.push({ label: network ? 'networkAllowed' : 'networkRestricted', value: '' });\n const files = action.permissions.fileSystem;\n for (const path of files?.read ?? []) parts.push({ label: 'read', value: path });\n for (const path of files?.write ?? []) parts.push({ label: 'write', value: path });\n for (const entry of files?.entries ?? [])\n parts.push({\n label: entry.access,\n value: entry.path.type === 'path' ? entry.path.path : JSON.stringify(entry.path),\n });\n if (files?.globScanMaxDepth !== undefined)\n parts.push({ label: 'depth', value: String(files.globScanMaxDepth) });\n return { kind: action.type, parts };\n }\n }\n}\n\n/** Display-only data. Notifications never become a PendingAction or a permission response. */\nexport function mapAutoReview(params: Notification): AutoReviewView {\n const review = params.review;\n return {\n reviewId: params.reviewId,\n ...(params.targetItemId === null ? {} : { targetItemId: params.targetItemId }),\n status: ['inProgress', 'approved', 'denied', 'timedOut', 'aborted'].includes(review.status)\n ? review.status\n : 'unknown',\n ...describeAction(params.action),\n presentation: actionPresentation(params.action),\n ...(review.rationale === null ? {} : { rationale: review.rationale }),\n ...(review.riskLevel === null ? {} : { riskLevel: review.riskLevel }),\n ...(review.userAuthorization === null ? {} : { userAuthorization: review.userAuthorization }),\n startedAtMs: params.startedAtMs,\n ...('completedAtMs' in params ? { completedAtMs: params.completedAtMs } : {}),\n };\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -64,26 +64,51 @@ function checkEmpty(path) {
64
64
  }
65
65
  }
66
66
  function failure(output, missingGit) {
67
- if (missingGit) return "\u670D\u52A1\u5668\u672A\u5B89\u88C5 Git\uFF0C\u6216\u670D\u52A1\u7684 PATH \u4E2D\u627E\u4E0D\u5230 Git\u3002\u5B89\u88C5\u5E76\u914D\u7F6E\u540E\u91CD\u8BD5\u3002";
67
+ if (missingGit)
68
+ return {
69
+ code: "CLONE_GIT_MISSING",
70
+ message: "\u670D\u52A1\u5668\u672A\u5B89\u88C5 Git\uFF0C\u6216\u670D\u52A1\u7684 PATH \u4E2D\u627E\u4E0D\u5230 Git\u3002\u5B89\u88C5\u5E76\u914D\u7F6E\u540E\u91CD\u8BD5\u3002"
71
+ };
68
72
  if (/authentication failed|could not read username|permission denied|publickey|terminal prompts disabled|credential|access denied|401|403/i.test(
69
73
  output
70
74
  ))
71
- return "Git \u8BA4\u8BC1\u5931\u8D25\u6216\u6CA1\u6709\u4ED3\u5E93\u8BBF\u95EE\u6743\u9650\u3002\u8BF7\u5728\u8FD0\u884C\u670D\u52A1\u7684\u4E3B\u673A\u4E0A\u914D\u7F6E Git \u51ED\u636E\u6216 SSH \u5BC6\u94A5\u540E\u91CD\u8BD5\u3002";
75
+ return {
76
+ code: "CLONE_AUTH_FAILED",
77
+ message: "Git \u8BA4\u8BC1\u5931\u8D25\u6216\u6CA1\u6709\u4ED3\u5E93\u8BBF\u95EE\u6743\u9650\u3002\u8BF7\u5728\u8FD0\u884C\u670D\u52A1\u7684\u4E3B\u673A\u4E0A\u914D\u7F6E Git \u51ED\u636E\u6216 SSH \u5BC6\u94A5\u540E\u91CD\u8BD5\u3002"
78
+ };
72
79
  if (/host key verification failed/i.test(output))
73
- return "SSH \u4E3B\u673A\u9A8C\u8BC1\u5931\u8D25\u3002\u8BF7\u5728\u8FD0\u884C\u670D\u52A1\u7684\u4E3B\u673A\u4E0A\u786E\u8BA4\u5E76\u914D\u7F6E\u4ED3\u5E93\u4E3B\u673A\u7684 SSH \u4FE1\u4EFB\u540E\u91CD\u8BD5\u3002";
80
+ return {
81
+ code: "CLONE_HOST_KEY_FAILED",
82
+ message: "SSH \u4E3B\u673A\u9A8C\u8BC1\u5931\u8D25\u3002\u8BF7\u5728\u8FD0\u884C\u670D\u52A1\u7684\u4E3B\u673A\u4E0A\u786E\u8BA4\u5E76\u914D\u7F6E\u4ED3\u5E93\u4E3B\u673A\u7684 SSH \u4FE1\u4EFB\u540E\u91CD\u8BD5\u3002"
83
+ };
74
84
  if (/repository .*not found|does not appear to be a git repository|not a repository|404/i.test(
75
85
  output
76
86
  ))
77
- return "\u4ED3\u5E93\u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BBF\u95EE\u3002\u8BF7\u68C0\u67E5\u4ED3\u5E93\u5730\u5740\u548C\u4E3B\u673A\u4E0A\u7684 Git \u8BBF\u95EE\u6743\u9650\u3002";
87
+ return {
88
+ code: "CLONE_REPOSITORY_UNAVAILABLE",
89
+ message: "\u4ED3\u5E93\u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BBF\u95EE\u3002\u8BF7\u68C0\u67E5\u4ED3\u5E93\u5730\u5740\u548C\u4E3B\u673A\u4E0A\u7684 Git \u8BBF\u95EE\u6743\u9650\u3002"
90
+ };
78
91
  if (/could not resolve|failed to connect|unable to access|connection|timed out|certificate/i.test(
79
92
  output
80
93
  ))
81
- return "\u65E0\u6CD5\u8FDE\u63A5 Git \u4ED3\u5E93\u3002\u8BF7\u68C0\u67E5\u670D\u52A1\u5668\u7F51\u7EDC\u3001\u4EE3\u7406\u548C\u8BC1\u4E66\u914D\u7F6E\u540E\u91CD\u8BD5\u3002";
94
+ return {
95
+ code: "CLONE_NETWORK_FAILED",
96
+ message: "\u65E0\u6CD5\u8FDE\u63A5 Git \u4ED3\u5E93\u3002\u8BF7\u68C0\u67E5\u670D\u52A1\u5668\u7F51\u7EDC\u3001\u4EE3\u7406\u548C\u8BC1\u4E66\u914D\u7F6E\u540E\u91CD\u8BD5\u3002"
97
+ };
82
98
  if (/already exists and is not an empty directory/i.test(output))
83
- return "\u76EE\u6807\u76EE\u5F55\u5DF2\u5305\u542B\u6587\u4EF6\uFF0CGit \u5DF2\u505C\u6B62\u514B\u9686\uFF1B\u4E0D\u4F1A\u8986\u76D6\u6216\u5220\u9664\u5DF2\u6709\u6587\u4EF6\u3002";
99
+ return {
100
+ code: "CLONE_TARGET_NOT_EMPTY",
101
+ message: "\u76EE\u6807\u76EE\u5F55\u5DF2\u5305\u542B\u6587\u4EF6\uFF0CGit \u5DF2\u505C\u6B62\u514B\u9686\uFF1B\u4E0D\u4F1A\u8986\u76D6\u6216\u5220\u9664\u5DF2\u6709\u6587\u4EF6\u3002"
102
+ };
84
103
  if (/no space left|disk quota/i.test(output))
85
- return "\u670D\u52A1\u5668\u78C1\u76D8\u7A7A\u95F4\u4E0D\u8DB3\uFF0C\u8BF7\u91CA\u653E\u7A7A\u95F4\u540E\u4F7F\u7528\u65B0\u7684\u7A7A\u76EE\u5F55\u91CD\u8BD5\u3002";
86
- return "Git \u514B\u9686\u5931\u8D25\u3002\u8BF7\u68C0\u67E5\u4ED3\u5E93\u5730\u5740\u3001\u4E3B\u673A\u4E0A\u7684 Git \u8BA4\u8BC1\u3001\u76EE\u5F55\u6743\u9650\u548C\u78C1\u76D8\u7A7A\u95F4\u540E\u91CD\u8BD5\u3002";
104
+ return {
105
+ code: "CLONE_DISK_FULL",
106
+ message: "\u670D\u52A1\u5668\u78C1\u76D8\u7A7A\u95F4\u4E0D\u8DB3\uFF0C\u8BF7\u91CA\u653E\u7A7A\u95F4\u540E\u4F7F\u7528\u65B0\u7684\u7A7A\u76EE\u5F55\u91CD\u8BD5\u3002"
107
+ };
108
+ return {
109
+ code: "CLONE_FAILED",
110
+ message: "Git \u514B\u9686\u5931\u8D25\u3002\u8BF7\u68C0\u67E5\u4ED3\u5E93\u5730\u5740\u3001\u4E3B\u673A\u4E0A\u7684 Git \u8BA4\u8BC1\u3001\u76EE\u5F55\u6743\u9650\u548C\u78C1\u76D8\u7A7A\u95F4\u540E\u91CD\u8BD5\u3002"
111
+ };
87
112
  }
88
113
  class ProjectClones {
89
114
  constructor(register, registered) {
@@ -141,7 +166,8 @@ class ProjectClones {
141
166
  path,
142
167
  name: parsed.name,
143
168
  status: "cloning",
144
- progress: "\u6B63\u5728\u8FDE\u63A5\u4ED3\u5E93\u2026"
169
+ progress: "\u6B63\u5728\u8FDE\u63A5\u4ED3\u5E93\u2026",
170
+ progressStage: "connecting"
145
171
  },
146
172
  fingerprint,
147
173
  done: Promise.resolve()
@@ -166,6 +192,7 @@ class ProjectClones {
166
192
  if (job && active(job) && job.view.status !== "cancelling") {
167
193
  job.view.status = "cancelling";
168
194
  job.view.progress = "\u6B63\u5728\u53D6\u6D88\uFF0C\u7B49\u5F85 Git \u9000\u51FA\u2026";
195
+ job.view.progressStage = "cancelling";
169
196
  this.signal(job, "SIGTERM");
170
197
  }
171
198
  return this.get(id);
@@ -181,10 +208,14 @@ class ProjectClones {
181
208
  job.view.project = this.register({ path: job.view.path, name: job.view.name });
182
209
  job.view.status = "completed";
183
210
  job.view.progress = "\u514B\u9686\u5B8C\u6210\uFF0C\u9879\u76EE\u5DF2\u6DFB\u52A0";
211
+ job.view.progressStage = "completed";
212
+ delete job.view.errorCode;
184
213
  delete job.view.error;
185
214
  } catch {
186
215
  job.view.status = "registration-failed";
187
216
  job.view.progress = "\u514B\u9686\u5DF2\u5B8C\u6210\uFF0C\u9879\u76EE\u5C1A\u672A\u6DFB\u52A0";
217
+ job.view.progressStage = "registration_failed";
218
+ job.view.errorCode = "CLONE_REGISTRATION_FAILED";
188
219
  job.view.error = "\u9879\u76EE\u6CE8\u518C\u5931\u8D25\u3002\u5DF2\u514B\u9686\u7684\u6587\u4EF6\u4FDD\u7559\u5728\u76EE\u6807\u76EE\u5F55\uFF1B\u53EF\u91CD\u8BD5\u6DFB\u52A0\u9879\u76EE\uFF0C\u65E0\u9700\u518D\u6B21\u514B\u9686\uFF0C\u4E5F\u53EF\u901A\u8FC7\u201C\u5DF2\u6709\u76EE\u5F55\u201D\u6DFB\u52A0\u3002";
189
220
  }
190
221
  }
@@ -241,14 +272,14 @@ class ProjectClones {
241
272
  );
242
273
  if (!match || job.view.status !== "cloning") continue;
243
274
  const labels = {
244
- "Receiving objects": "\u6B63\u5728\u63A5\u6536\u5BF9\u8C61",
245
- "Resolving deltas": "\u6B63\u5728\u89E3\u6790\u5DEE\u5F02",
246
- "Updating files": "\u6B63\u5728\u68C0\u51FA\u6587\u4EF6",
247
- "Checking out files": "\u6B63\u5728\u68C0\u51FA\u6587\u4EF6",
248
- "Counting objects": "\u6B63\u5728\u7EDF\u8BA1\u5BF9\u8C61",
249
- "Compressing objects": "\u6B63\u5728\u538B\u7F29\u5BF9\u8C61"
275
+ "Receiving objects": ["receiving", "\u6B63\u5728\u63A5\u6536\u5BF9\u8C61"],
276
+ "Resolving deltas": ["resolving", "\u6B63\u5728\u89E3\u6790\u5DEE\u5F02"],
277
+ "Updating files": ["checking_out", "\u6B63\u5728\u68C0\u51FA\u6587\u4EF6"],
278
+ "Checking out files": ["checking_out", "\u6B63\u5728\u68C0\u51FA\u6587\u4EF6"],
279
+ "Counting objects": ["counting", "\u6B63\u5728\u7EDF\u8BA1\u5BF9\u8C61"],
280
+ "Compressing objects": ["compressing", "\u6B63\u5728\u538B\u7F29\u5BF9\u8C61"]
250
281
  };
251
- job.view.progress = labels[match[1]];
282
+ [job.view.progressStage, job.view.progress] = labels[match[1]];
252
283
  job.view.percent = Math.min(100, Number(match[2]));
253
284
  }
254
285
  };
@@ -276,11 +307,16 @@ class ProjectClones {
276
307
  if (job.view.status === "cancelling") {
277
308
  job.view.status = timedOut ? "failed" : "cancelled";
278
309
  job.view.progress = timedOut ? "\u514B\u9686\u8D85\u65F6\uFF0C\u5DF2\u505C\u6B62" : "\u5DF2\u53D6\u6D88\u514B\u9686";
310
+ job.view.progressStage = timedOut ? "timed_out" : "cancelled";
311
+ job.view.errorCode = timedOut ? "CLONE_TIMED_OUT" : "CLONE_CANCELLED";
279
312
  job.view.error = `${timedOut ? "\u514B\u9686\u8D85\u8FC7 30 \u5206\u949F\uFF0C\u5DF2\u505C\u6B62\u3002" : ""}\u672A\u6DFB\u52A0\u9879\u76EE\uFF0C\u4E5F\u672A\u5220\u9664\u4EFB\u4F55\u6587\u4EF6\u3002\u76EE\u6807\u76EE\u5F55\u53EF\u80FD\u6B8B\u7559\u6587\u4EF6\uFF0C\u8BF7\u68C0\u67E5\u540E\u4F7F\u7528\u65B0\u7684\u7A7A\u76EE\u5F55\u91CD\u8BD5\u3002`;
280
313
  } else if (code !== 0) {
281
314
  job.view.status = "failed";
282
315
  job.view.progress = "\u514B\u9686\u5931\u8D25";
283
- job.view.error = `${failure(output, missingGit)} \u672A\u6DFB\u52A0\u9879\u76EE\uFF1B\u76EE\u6807\u76EE\u5F55\u53EF\u80FD\u6B8B\u7559\u6587\u4EF6\uFF0C\u8BF7\u68C0\u67E5\u540E\u4F7F\u7528\u65B0\u7684\u7A7A\u76EE\u5F55\u91CD\u8BD5\u3002`;
316
+ job.view.progressStage = "failed";
317
+ const problem = failure(output, missingGit);
318
+ job.view.errorCode = problem.code;
319
+ job.view.error = `${problem.message} \u672A\u6DFB\u52A0\u9879\u76EE\uFF1B\u76EE\u6807\u76EE\u5F55\u53EF\u80FD\u6B8B\u7559\u6587\u4EF6\uFF0C\u8BF7\u68C0\u67E5\u540E\u4F7F\u7528\u65B0\u7684\u7A7A\u76EE\u5F55\u91CD\u8BD5\u3002`;
284
320
  } else this.finishRegistration(job);
285
321
  }
286
322
  async close() {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/server/project-clones.ts"],
4
- "sourcesContent": ["import { spawn, type ChildProcess } from 'node:child_process';\nimport { createHash } from 'node:crypto';\nimport { accessSync, constants, lstatSync, readdirSync, realpathSync } from 'node:fs';\nimport { basename, dirname, isAbsolute, join, resolve } from 'node:path';\nimport { AppError } from '../shared/errors.js';\nimport type {\n CloneProjectInput,\n CreateProjectInput,\n Project,\n ProjectClone,\n} from '../shared/types.js';\nimport { cloneProjectSchema } from '../shared/validation.js';\nimport { containsPath } from './projects.js';\n\ninterface Job {\n view: ProjectClone;\n fingerprint: string;\n child?: ChildProcess;\n done: Promise<void>;\n}\nconst active = (job: Job) => ['cloning', 'cancelling'].includes(job.view.status);\nconst hasControl = (value: string) =>\n [...value].some((character) => character.charCodeAt(0) < 32 || character.charCodeAt(0) === 127);\n\n/** Only remote Git transports; never pass a local path, option, or remote helper to Git. */\nexport function validateRepository(repository: string): void {\n let valid = false;\n if (!hasControl(repository) && !/[\\s\\\\]/.test(repository)) {\n if (/^(https|ssh):\\/\\//.test(repository)) {\n try {\n const url = new URL(repository);\n valid = Boolean(\n url.hostname &&\n !url.hostname.startsWith('-') &&\n url.pathname.length > 1 &&\n !url.password &&\n !url.search &&\n !url.hash &&\n (url.protocol === 'ssh:'\n ? /^(?:[a-zA-Z0-9_][\\w.-]*)?$/.test(url.username)\n : !url.username),\n );\n } catch {\n /* Report a fixed message, never the supplied URL. */\n }\n } else {\n valid = /^(?:[a-zA-Z0-9_][\\w.-]*@)?[a-zA-Z0-9][\\w.-]*:[^/:\\s][^\\s]*$/.test(repository);\n }\n }\n if (!valid)\n throw new AppError(\n 'INVALID_REPOSITORY',\n '\u8BF7\u8F93\u5165 HTTPS \u6216 SSH Git \u4ED3\u5E93\u5730\u5740\uFF1B\u8BF7\u4F7F\u7528\u4E3B\u673A\u5DF2\u6709\u7684\u8BA4\u8BC1\uFF0C\u4E0D\u8981\u5728\u5730\u5740\u4E2D\u586B\u5199\u5BC6\u7801\u3001\u4EE4\u724C\u6216\u67E5\u8BE2\u53C2\u6570',\n 400,\n );\n}\n\nfunction targetPath(path: string): string {\n if (!isAbsolute(path) || hasControl(path) || resolve(path) === dirname(resolve(path)))\n throw new AppError('INVALID_PROJECT_PATH', '\u8BF7\u586B\u5199\u670D\u52A1\u5668\u4E0A\u7684\u7EDD\u5BF9\u76EE\u6807\u76EE\u5F55', 400);\n try {\n const target = join(realpathSync(dirname(resolve(path))), basename(resolve(path)));\n accessSync(dirname(target), constants.W_OK | constants.X_OK);\n return target;\n } catch {\n throw new AppError(\n 'CLONE_PARENT_UNAVAILABLE',\n '\u76EE\u6807\u76EE\u5F55\u7684\u7236\u76EE\u5F55\u5FC5\u987B\u5DF2\u5B58\u5728\uFF0C\u4E14\u670D\u52A1\u9700\u8981\u5199\u5165\u548C\u8FDB\u5165\u6743\u9650',\n 409,\n );\n }\n}\n\nfunction checkEmpty(path: string): void {\n try {\n const stat = lstatSync(path);\n if (!stat.isDirectory() || stat.isSymbolicLink() || readdirSync(path).length)\n throw new AppError(\n 'CLONE_TARGET_EXISTS',\n '\u76EE\u6807\u76EE\u5F55\u5DF2\u5B58\u5728\u4E14\u975E\u7A7A\uFF0C\u6216\u4E0D\u662F\u666E\u901A\u76EE\u5F55\uFF1B\u8BF7\u9009\u62E9\u65B0\u7684\u7A7A\u76EE\u5F55\uFF0C\u4E0D\u4F1A\u8986\u76D6\u5DF2\u6709\u6587\u4EF6',\n 409,\n );\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return;\n if (error instanceof AppError) throw error;\n throw new AppError(\n 'CLONE_TARGET_UNAVAILABLE',\n '\u65E0\u6CD5\u68C0\u67E5\u76EE\u6807\u76EE\u5F55\uFF0C\u8BF7\u68C0\u67E5\u670D\u52A1\u5668\u8DEF\u5F84\u548C\u8BBF\u95EE\u6743\u9650',\n 409,\n );\n }\n}\n\nfunction failure(output: string, missingGit: boolean): string {\n if (missingGit) return '\u670D\u52A1\u5668\u672A\u5B89\u88C5 Git\uFF0C\u6216\u670D\u52A1\u7684 PATH \u4E2D\u627E\u4E0D\u5230 Git\u3002\u5B89\u88C5\u5E76\u914D\u7F6E\u540E\u91CD\u8BD5\u3002';\n if (\n /authentication failed|could not read username|permission denied|publickey|terminal prompts disabled|credential|access denied|401|403/i.test(\n output,\n )\n )\n return 'Git \u8BA4\u8BC1\u5931\u8D25\u6216\u6CA1\u6709\u4ED3\u5E93\u8BBF\u95EE\u6743\u9650\u3002\u8BF7\u5728\u8FD0\u884C\u670D\u52A1\u7684\u4E3B\u673A\u4E0A\u914D\u7F6E Git \u51ED\u636E\u6216 SSH \u5BC6\u94A5\u540E\u91CD\u8BD5\u3002';\n if (/host key verification failed/i.test(output))\n return 'SSH \u4E3B\u673A\u9A8C\u8BC1\u5931\u8D25\u3002\u8BF7\u5728\u8FD0\u884C\u670D\u52A1\u7684\u4E3B\u673A\u4E0A\u786E\u8BA4\u5E76\u914D\u7F6E\u4ED3\u5E93\u4E3B\u673A\u7684 SSH \u4FE1\u4EFB\u540E\u91CD\u8BD5\u3002';\n if (\n /repository .*not found|does not appear to be a git repository|not a repository|404/i.test(\n output,\n )\n )\n return '\u4ED3\u5E93\u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BBF\u95EE\u3002\u8BF7\u68C0\u67E5\u4ED3\u5E93\u5730\u5740\u548C\u4E3B\u673A\u4E0A\u7684 Git \u8BBF\u95EE\u6743\u9650\u3002';\n if (\n /could not resolve|failed to connect|unable to access|connection|timed out|certificate/i.test(\n output,\n )\n )\n return '\u65E0\u6CD5\u8FDE\u63A5 Git \u4ED3\u5E93\u3002\u8BF7\u68C0\u67E5\u670D\u52A1\u5668\u7F51\u7EDC\u3001\u4EE3\u7406\u548C\u8BC1\u4E66\u914D\u7F6E\u540E\u91CD\u8BD5\u3002';\n if (/already exists and is not an empty directory/i.test(output))\n return '\u76EE\u6807\u76EE\u5F55\u5DF2\u5305\u542B\u6587\u4EF6\uFF0CGit \u5DF2\u505C\u6B62\u514B\u9686\uFF1B\u4E0D\u4F1A\u8986\u76D6\u6216\u5220\u9664\u5DF2\u6709\u6587\u4EF6\u3002';\n if (/no space left|disk quota/i.test(output))\n return '\u670D\u52A1\u5668\u78C1\u76D8\u7A7A\u95F4\u4E0D\u8DB3\uFF0C\u8BF7\u91CA\u653E\u7A7A\u95F4\u540E\u4F7F\u7528\u65B0\u7684\u7A7A\u76EE\u5F55\u91CD\u8BD5\u3002';\n return 'Git \u514B\u9686\u5931\u8D25\u3002\u8BF7\u68C0\u67E5\u4ED3\u5E93\u5730\u5740\u3001\u4E3B\u673A\u4E0A\u7684 Git \u8BA4\u8BC1\u3001\u76EE\u5F55\u6743\u9650\u548C\u78C1\u76D8\u7A7A\u95F4\u540E\u91CD\u8BD5\u3002';\n}\n\n/** Transient jobs never persist repository URLs, credentials, or raw Git output. */\nexport class ProjectClones {\n private readonly jobs = new Map<string, Job>();\n private closing = false;\n constructor(\n private readonly register: (input: CreateProjectInput) => Project,\n private readonly registered: (path: string) => boolean,\n ) {}\n\n get hasActive(): boolean {\n return [...this.jobs.values()].some(active);\n }\n\n assertIdlePath(path: string): void {\n if (!this.hasActive) return;\n let canonical = resolve(path);\n try {\n canonical = realpathSync(path);\n } catch {\n try {\n canonical = join(realpathSync(dirname(canonical)), basename(canonical));\n } catch {\n /* Normal registration validation reports unavailable paths. */\n }\n }\n if (\n [...this.jobs.values()].some(\n (job) =>\n active(job) &&\n (containsPath(job.view.path, canonical) || containsPath(canonical, job.view.path)),\n )\n )\n throw new AppError('CLONE_IN_PROGRESS', '\u8BE5\u76EE\u5F55\u6B63\u5728\u514B\u9686\uFF0C\u8BF7\u7B49\u5F85\u5B8C\u6210\u6216\u53D6\u6D88\u540E\u518D\u64CD\u4F5C', 409);\n }\n\n start(input: CloneProjectInput): ProjectClone {\n const parsed = cloneProjectSchema.parse(input);\n validateRepository(parsed.repository);\n const fingerprint = createHash('sha256').update(JSON.stringify(parsed)).digest('hex');\n const previous = this.jobs.get(parsed.clientOperationId);\n if (previous) {\n if (previous.fingerprint !== fingerprint)\n throw new AppError('CLONE_ID_CONFLICT', '\u8BE5\u64CD\u4F5C ID \u5DF2\u7528\u4E8E\u5176\u4ED6\u514B\u9686\u8BF7\u6C42', 409);\n return this.get(previous.view.id);\n }\n if (this.closing) throw new AppError('GATEWAY_STOPPING', '\u670D\u52A1\u6B63\u5728\u505C\u6B62\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5', 503);\n const path = targetPath(parsed.path);\n this.assertIdlePath(path);\n if (this.registered(path))\n throw new AppError('PROJECT_EXISTS', '\u8BE5\u76EE\u5F55\u5DF2\u6DFB\u52A0\u4E3A\u9879\u76EE\uFF0C\u8BF7\u4F7F\u7528\u5DF2\u6709\u9879\u76EE\u6216\u9009\u62E9\u5176\u4ED6\u76EE\u5F55', 409);\n checkEmpty(path);\n if ([...this.jobs.values()].filter(active).length >= 4)\n throw new AppError('CLONE_LIMIT', '\u5DF2\u6709\u591A\u4E2A\u4ED3\u5E93\u6B63\u5728\u514B\u9686\uFF0C\u8BF7\u7B49\u5F85\u5B8C\u6210\u540E\u91CD\u8BD5', 409);\n // Bound transient history without evicting a running process.\n if (this.jobs.size >= 100) {\n const oldest = [...this.jobs].find(([, job]) => !active(job));\n if (oldest) this.jobs.delete(oldest[0]);\n }\n const job: Job = {\n view: {\n id: parsed.clientOperationId,\n path,\n name: parsed.name,\n status: 'cloning',\n progress: '\u6B63\u5728\u8FDE\u63A5\u4ED3\u5E93\u2026',\n },\n fingerprint,\n done: Promise.resolve(),\n };\n this.jobs.set(job.view.id, job);\n job.done = this.run(job, parsed.repository);\n return this.get(job.view.id);\n }\n\n get(id: string): ProjectClone {\n const job = this.jobs.get(id);\n if (!job)\n throw new AppError(\n 'CLONE_NOT_FOUND',\n '\u672A\u627E\u5230\u514B\u9686\u8BB0\u5F55\uFF1B\u670D\u52A1\u91CD\u542F\u540E\u8BF7\u68C0\u67E5\u76EE\u6807\u76EE\u5F55\uFF0C\u518D\u6DFB\u52A0\u5DF2\u6709\u76EE\u5F55\u6216\u4F7F\u7528\u65B0\u7684\u7A7A\u76EE\u5F55\u91CD\u8BD5',\n 404,\n );\n return structuredClone(job.view);\n }\n\n cancel(id: string): ProjectClone {\n const job = this.jobs.get(id);\n this.get(id);\n if (job && active(job) && job.view.status !== 'cancelling') {\n job.view.status = 'cancelling';\n job.view.progress = '\u6B63\u5728\u53D6\u6D88\uFF0C\u7B49\u5F85 Git \u9000\u51FA\u2026';\n this.signal(job, 'SIGTERM');\n }\n return this.get(id);\n }\n\n retryRegistration(id: string): ProjectClone {\n const job = this.jobs.get(id);\n this.get(id);\n if (job?.view.status === 'registration-failed') this.finishRegistration(job);\n return this.get(id);\n }\n\n private finishRegistration(job: Job): void {\n try {\n job.view.project = this.register({ path: job.view.path, name: job.view.name });\n job.view.status = 'completed';\n job.view.progress = '\u514B\u9686\u5B8C\u6210\uFF0C\u9879\u76EE\u5DF2\u6DFB\u52A0';\n delete job.view.error;\n } catch {\n job.view.status = 'registration-failed';\n job.view.progress = '\u514B\u9686\u5DF2\u5B8C\u6210\uFF0C\u9879\u76EE\u5C1A\u672A\u6DFB\u52A0';\n job.view.error =\n '\u9879\u76EE\u6CE8\u518C\u5931\u8D25\u3002\u5DF2\u514B\u9686\u7684\u6587\u4EF6\u4FDD\u7559\u5728\u76EE\u6807\u76EE\u5F55\uFF1B\u53EF\u91CD\u8BD5\u6DFB\u52A0\u9879\u76EE\uFF0C\u65E0\u9700\u518D\u6B21\u514B\u9686\uFF0C\u4E5F\u53EF\u901A\u8FC7\u201C\u5DF2\u6709\u76EE\u5F55\u201D\u6DFB\u52A0\u3002';\n }\n }\n\n private signal(job: Job, signal: NodeJS.Signals): void {\n if (!job.child?.pid) return;\n try {\n if (process.platform === 'win32') job.child.kill(signal);\n else process.kill(-job.child.pid, signal);\n } catch {\n /* Process may have already exited. */\n }\n }\n\n private async run(job: Job, repository: string): Promise<void> {\n let output = '';\n let pending = '';\n let missingGit = false;\n let timedOut = false;\n const sshCommand =\n process.env.GIT_SSH_COMMAND ??\n (process.env.GIT_SSH ? `'${process.env.GIT_SSH.replaceAll(\"'\", \"'\\\\''\")}'` : 'ssh');\n const child = spawn(\n 'git',\n [\n '-c',\n 'protocol.allow=never',\n '-c',\n 'protocol.https.allow=always',\n '-c',\n 'protocol.ssh.allow=always',\n 'clone',\n '--progress',\n '--',\n repository,\n job.view.path,\n ],\n {\n detached: process.platform !== 'win32',\n stdio: ['ignore', 'pipe', 'pipe'],\n env: {\n ...process.env,\n GIT_TERMINAL_PROMPT: '0',\n GCM_INTERACTIVE: 'never',\n GIT_SSH_COMMAND: `${sshCommand} -oBatchMode=yes -oStrictHostKeyChecking=yes`,\n LC_ALL: 'C',\n },\n },\n );\n job.child = child;\n const read = (chunk: Buffer) => {\n output = (output + chunk.toString()).slice(-16_384);\n pending = (pending + chunk.toString()).slice(-4096);\n const lines = pending.split(/[\\r\\n]/);\n pending = lines.pop() ?? '';\n for (const line of lines) {\n const match =\n /^(?:remote: )?(Receiving objects|Resolving deltas|Updating files|Checking out files|Counting objects|Compressing objects):\\s+(\\d{1,3})%/.exec(\n line,\n );\n if (!match || job.view.status !== 'cloning') continue;\n const labels: Record<string, string> = {\n 'Receiving objects': '\u6B63\u5728\u63A5\u6536\u5BF9\u8C61',\n 'Resolving deltas': '\u6B63\u5728\u89E3\u6790\u5DEE\u5F02',\n 'Updating files': '\u6B63\u5728\u68C0\u51FA\u6587\u4EF6',\n 'Checking out files': '\u6B63\u5728\u68C0\u51FA\u6587\u4EF6',\n 'Counting objects': '\u6B63\u5728\u7EDF\u8BA1\u5BF9\u8C61',\n 'Compressing objects': '\u6B63\u5728\u538B\u7F29\u5BF9\u8C61',\n };\n job.view.progress = labels[match[1]!]!;\n job.view.percent = Math.min(100, Number(match[2]));\n }\n };\n child.stdout?.on('data', read);\n child.stderr?.on('data', read);\n const timeout = setTimeout(() => {\n timedOut = true;\n this.cancel(job.view.id);\n }, 30 * 60_000);\n timeout.unref();\n const escalation = setInterval(() => {\n if (job.view.status === 'cancelling') this.signal(job, 'SIGKILL');\n }, 3000);\n escalation.unref();\n const code = await new Promise<number | null>((done) => {\n child.once('error', (error: NodeJS.ErrnoException) => {\n missingGit = error.code === 'ENOENT';\n });\n child.once('close', done);\n });\n clearTimeout(timeout);\n clearInterval(escalation);\n job.child = undefined;\n delete job.view.percent;\n if (job.view.status === 'cancelling') {\n job.view.status = timedOut ? 'failed' : 'cancelled';\n job.view.progress = timedOut ? '\u514B\u9686\u8D85\u65F6\uFF0C\u5DF2\u505C\u6B62' : '\u5DF2\u53D6\u6D88\u514B\u9686';\n job.view.error = `${timedOut ? '\u514B\u9686\u8D85\u8FC7 30 \u5206\u949F\uFF0C\u5DF2\u505C\u6B62\u3002' : ''}\u672A\u6DFB\u52A0\u9879\u76EE\uFF0C\u4E5F\u672A\u5220\u9664\u4EFB\u4F55\u6587\u4EF6\u3002\u76EE\u6807\u76EE\u5F55\u53EF\u80FD\u6B8B\u7559\u6587\u4EF6\uFF0C\u8BF7\u68C0\u67E5\u540E\u4F7F\u7528\u65B0\u7684\u7A7A\u76EE\u5F55\u91CD\u8BD5\u3002`;\n } else if (code !== 0) {\n job.view.status = 'failed';\n job.view.progress = '\u514B\u9686\u5931\u8D25';\n job.view.error = `${failure(output, missingGit)} \u672A\u6DFB\u52A0\u9879\u76EE\uFF1B\u76EE\u6807\u76EE\u5F55\u53EF\u80FD\u6B8B\u7559\u6587\u4EF6\uFF0C\u8BF7\u68C0\u67E5\u540E\u4F7F\u7528\u65B0\u7684\u7A7A\u76EE\u5F55\u91CD\u8BD5\u3002`;\n } else this.finishRegistration(job);\n }\n\n async close(): Promise<void> {\n this.closing = true;\n for (const job of this.jobs.values()) if (active(job)) this.cancel(job.view.id);\n await Promise.all([...this.jobs.values()].map((job) => job.done));\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { spawn, type ChildProcess } from 'node:child_process';\nimport { createHash } from 'node:crypto';\nimport { accessSync, constants, lstatSync, readdirSync, realpathSync } from 'node:fs';\nimport { basename, dirname, isAbsolute, join, resolve } from 'node:path';\nimport { AppError } from '../shared/errors.js';\nimport type {\n CloneProjectInput,\n CreateProjectInput,\n Project,\n ProjectClone,\n} from '../shared/types.js';\nimport { cloneProjectSchema } from '../shared/validation.js';\nimport { containsPath } from './projects.js';\n\ninterface Job {\n view: ProjectClone;\n fingerprint: string;\n child?: ChildProcess;\n done: Promise<void>;\n}\nconst active = (job: Job) => ['cloning', 'cancelling'].includes(job.view.status);\nconst hasControl = (value: string) =>\n [...value].some((character) => character.charCodeAt(0) < 32 || character.charCodeAt(0) === 127);\n\n/** Only remote Git transports; never pass a local path, option, or remote helper to Git. */\nexport function validateRepository(repository: string): void {\n let valid = false;\n if (!hasControl(repository) && !/[\\s\\\\]/.test(repository)) {\n if (/^(https|ssh):\\/\\//.test(repository)) {\n try {\n const url = new URL(repository);\n valid = Boolean(\n url.hostname &&\n !url.hostname.startsWith('-') &&\n url.pathname.length > 1 &&\n !url.password &&\n !url.search &&\n !url.hash &&\n (url.protocol === 'ssh:'\n ? /^(?:[a-zA-Z0-9_][\\w.-]*)?$/.test(url.username)\n : !url.username),\n );\n } catch {\n /* Report a fixed message, never the supplied URL. */\n }\n } else {\n valid = /^(?:[a-zA-Z0-9_][\\w.-]*@)?[a-zA-Z0-9][\\w.-]*:[^/:\\s][^\\s]*$/.test(repository);\n }\n }\n if (!valid)\n throw new AppError(\n 'INVALID_REPOSITORY',\n '\u8BF7\u8F93\u5165 HTTPS \u6216 SSH Git \u4ED3\u5E93\u5730\u5740\uFF1B\u8BF7\u4F7F\u7528\u4E3B\u673A\u5DF2\u6709\u7684\u8BA4\u8BC1\uFF0C\u4E0D\u8981\u5728\u5730\u5740\u4E2D\u586B\u5199\u5BC6\u7801\u3001\u4EE4\u724C\u6216\u67E5\u8BE2\u53C2\u6570',\n 400,\n );\n}\n\nfunction targetPath(path: string): string {\n if (!isAbsolute(path) || hasControl(path) || resolve(path) === dirname(resolve(path)))\n throw new AppError('INVALID_PROJECT_PATH', '\u8BF7\u586B\u5199\u670D\u52A1\u5668\u4E0A\u7684\u7EDD\u5BF9\u76EE\u6807\u76EE\u5F55', 400);\n try {\n const target = join(realpathSync(dirname(resolve(path))), basename(resolve(path)));\n accessSync(dirname(target), constants.W_OK | constants.X_OK);\n return target;\n } catch {\n throw new AppError(\n 'CLONE_PARENT_UNAVAILABLE',\n '\u76EE\u6807\u76EE\u5F55\u7684\u7236\u76EE\u5F55\u5FC5\u987B\u5DF2\u5B58\u5728\uFF0C\u4E14\u670D\u52A1\u9700\u8981\u5199\u5165\u548C\u8FDB\u5165\u6743\u9650',\n 409,\n );\n }\n}\n\nfunction checkEmpty(path: string): void {\n try {\n const stat = lstatSync(path);\n if (!stat.isDirectory() || stat.isSymbolicLink() || readdirSync(path).length)\n throw new AppError(\n 'CLONE_TARGET_EXISTS',\n '\u76EE\u6807\u76EE\u5F55\u5DF2\u5B58\u5728\u4E14\u975E\u7A7A\uFF0C\u6216\u4E0D\u662F\u666E\u901A\u76EE\u5F55\uFF1B\u8BF7\u9009\u62E9\u65B0\u7684\u7A7A\u76EE\u5F55\uFF0C\u4E0D\u4F1A\u8986\u76D6\u5DF2\u6709\u6587\u4EF6',\n 409,\n );\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return;\n if (error instanceof AppError) throw error;\n throw new AppError(\n 'CLONE_TARGET_UNAVAILABLE',\n '\u65E0\u6CD5\u68C0\u67E5\u76EE\u6807\u76EE\u5F55\uFF0C\u8BF7\u68C0\u67E5\u670D\u52A1\u5668\u8DEF\u5F84\u548C\u8BBF\u95EE\u6743\u9650',\n 409,\n );\n }\n}\n\nfunction failure(\n output: string,\n missingGit: boolean,\n): { code: NonNullable<ProjectClone['errorCode']>; message: string } {\n if (missingGit)\n return {\n code: 'CLONE_GIT_MISSING',\n message: '\u670D\u52A1\u5668\u672A\u5B89\u88C5 Git\uFF0C\u6216\u670D\u52A1\u7684 PATH \u4E2D\u627E\u4E0D\u5230 Git\u3002\u5B89\u88C5\u5E76\u914D\u7F6E\u540E\u91CD\u8BD5\u3002',\n };\n if (\n /authentication failed|could not read username|permission denied|publickey|terminal prompts disabled|credential|access denied|401|403/i.test(\n output,\n )\n )\n return {\n code: 'CLONE_AUTH_FAILED',\n message:\n 'Git \u8BA4\u8BC1\u5931\u8D25\u6216\u6CA1\u6709\u4ED3\u5E93\u8BBF\u95EE\u6743\u9650\u3002\u8BF7\u5728\u8FD0\u884C\u670D\u52A1\u7684\u4E3B\u673A\u4E0A\u914D\u7F6E Git \u51ED\u636E\u6216 SSH \u5BC6\u94A5\u540E\u91CD\u8BD5\u3002',\n };\n if (/host key verification failed/i.test(output))\n return {\n code: 'CLONE_HOST_KEY_FAILED',\n message: 'SSH \u4E3B\u673A\u9A8C\u8BC1\u5931\u8D25\u3002\u8BF7\u5728\u8FD0\u884C\u670D\u52A1\u7684\u4E3B\u673A\u4E0A\u786E\u8BA4\u5E76\u914D\u7F6E\u4ED3\u5E93\u4E3B\u673A\u7684 SSH \u4FE1\u4EFB\u540E\u91CD\u8BD5\u3002',\n };\n if (\n /repository .*not found|does not appear to be a git repository|not a repository|404/i.test(\n output,\n )\n )\n return {\n code: 'CLONE_REPOSITORY_UNAVAILABLE',\n message: '\u4ED3\u5E93\u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BBF\u95EE\u3002\u8BF7\u68C0\u67E5\u4ED3\u5E93\u5730\u5740\u548C\u4E3B\u673A\u4E0A\u7684 Git \u8BBF\u95EE\u6743\u9650\u3002',\n };\n if (\n /could not resolve|failed to connect|unable to access|connection|timed out|certificate/i.test(\n output,\n )\n )\n return {\n code: 'CLONE_NETWORK_FAILED',\n message: '\u65E0\u6CD5\u8FDE\u63A5 Git \u4ED3\u5E93\u3002\u8BF7\u68C0\u67E5\u670D\u52A1\u5668\u7F51\u7EDC\u3001\u4EE3\u7406\u548C\u8BC1\u4E66\u914D\u7F6E\u540E\u91CD\u8BD5\u3002',\n };\n if (/already exists and is not an empty directory/i.test(output))\n return {\n code: 'CLONE_TARGET_NOT_EMPTY',\n message: '\u76EE\u6807\u76EE\u5F55\u5DF2\u5305\u542B\u6587\u4EF6\uFF0CGit \u5DF2\u505C\u6B62\u514B\u9686\uFF1B\u4E0D\u4F1A\u8986\u76D6\u6216\u5220\u9664\u5DF2\u6709\u6587\u4EF6\u3002',\n };\n if (/no space left|disk quota/i.test(output))\n return {\n code: 'CLONE_DISK_FULL',\n message: '\u670D\u52A1\u5668\u78C1\u76D8\u7A7A\u95F4\u4E0D\u8DB3\uFF0C\u8BF7\u91CA\u653E\u7A7A\u95F4\u540E\u4F7F\u7528\u65B0\u7684\u7A7A\u76EE\u5F55\u91CD\u8BD5\u3002',\n };\n return {\n code: 'CLONE_FAILED',\n message: 'Git \u514B\u9686\u5931\u8D25\u3002\u8BF7\u68C0\u67E5\u4ED3\u5E93\u5730\u5740\u3001\u4E3B\u673A\u4E0A\u7684 Git \u8BA4\u8BC1\u3001\u76EE\u5F55\u6743\u9650\u548C\u78C1\u76D8\u7A7A\u95F4\u540E\u91CD\u8BD5\u3002',\n };\n}\n\n/** Transient jobs never persist repository URLs, credentials, or raw Git output. */\nexport class ProjectClones {\n private readonly jobs = new Map<string, Job>();\n private closing = false;\n constructor(\n private readonly register: (input: CreateProjectInput) => Project,\n private readonly registered: (path: string) => boolean,\n ) {}\n\n get hasActive(): boolean {\n return [...this.jobs.values()].some(active);\n }\n\n assertIdlePath(path: string): void {\n if (!this.hasActive) return;\n let canonical = resolve(path);\n try {\n canonical = realpathSync(path);\n } catch {\n try {\n canonical = join(realpathSync(dirname(canonical)), basename(canonical));\n } catch {\n /* Normal registration validation reports unavailable paths. */\n }\n }\n if (\n [...this.jobs.values()].some(\n (job) =>\n active(job) &&\n (containsPath(job.view.path, canonical) || containsPath(canonical, job.view.path)),\n )\n )\n throw new AppError('CLONE_IN_PROGRESS', '\u8BE5\u76EE\u5F55\u6B63\u5728\u514B\u9686\uFF0C\u8BF7\u7B49\u5F85\u5B8C\u6210\u6216\u53D6\u6D88\u540E\u518D\u64CD\u4F5C', 409);\n }\n\n start(input: CloneProjectInput): ProjectClone {\n const parsed = cloneProjectSchema.parse(input);\n validateRepository(parsed.repository);\n const fingerprint = createHash('sha256').update(JSON.stringify(parsed)).digest('hex');\n const previous = this.jobs.get(parsed.clientOperationId);\n if (previous) {\n if (previous.fingerprint !== fingerprint)\n throw new AppError('CLONE_ID_CONFLICT', '\u8BE5\u64CD\u4F5C ID \u5DF2\u7528\u4E8E\u5176\u4ED6\u514B\u9686\u8BF7\u6C42', 409);\n return this.get(previous.view.id);\n }\n if (this.closing) throw new AppError('GATEWAY_STOPPING', '\u670D\u52A1\u6B63\u5728\u505C\u6B62\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5', 503);\n const path = targetPath(parsed.path);\n this.assertIdlePath(path);\n if (this.registered(path))\n throw new AppError('PROJECT_EXISTS', '\u8BE5\u76EE\u5F55\u5DF2\u6DFB\u52A0\u4E3A\u9879\u76EE\uFF0C\u8BF7\u4F7F\u7528\u5DF2\u6709\u9879\u76EE\u6216\u9009\u62E9\u5176\u4ED6\u76EE\u5F55', 409);\n checkEmpty(path);\n if ([...this.jobs.values()].filter(active).length >= 4)\n throw new AppError('CLONE_LIMIT', '\u5DF2\u6709\u591A\u4E2A\u4ED3\u5E93\u6B63\u5728\u514B\u9686\uFF0C\u8BF7\u7B49\u5F85\u5B8C\u6210\u540E\u91CD\u8BD5', 409);\n // Bound transient history without evicting a running process.\n if (this.jobs.size >= 100) {\n const oldest = [...this.jobs].find(([, job]) => !active(job));\n if (oldest) this.jobs.delete(oldest[0]);\n }\n const job: Job = {\n view: {\n id: parsed.clientOperationId,\n path,\n name: parsed.name,\n status: 'cloning',\n progress: '\u6B63\u5728\u8FDE\u63A5\u4ED3\u5E93\u2026',\n progressStage: 'connecting',\n },\n fingerprint,\n done: Promise.resolve(),\n };\n this.jobs.set(job.view.id, job);\n job.done = this.run(job, parsed.repository);\n return this.get(job.view.id);\n }\n\n get(id: string): ProjectClone {\n const job = this.jobs.get(id);\n if (!job)\n throw new AppError(\n 'CLONE_NOT_FOUND',\n '\u672A\u627E\u5230\u514B\u9686\u8BB0\u5F55\uFF1B\u670D\u52A1\u91CD\u542F\u540E\u8BF7\u68C0\u67E5\u76EE\u6807\u76EE\u5F55\uFF0C\u518D\u6DFB\u52A0\u5DF2\u6709\u76EE\u5F55\u6216\u4F7F\u7528\u65B0\u7684\u7A7A\u76EE\u5F55\u91CD\u8BD5',\n 404,\n );\n return structuredClone(job.view);\n }\n\n cancel(id: string): ProjectClone {\n const job = this.jobs.get(id);\n this.get(id);\n if (job && active(job) && job.view.status !== 'cancelling') {\n job.view.status = 'cancelling';\n job.view.progress = '\u6B63\u5728\u53D6\u6D88\uFF0C\u7B49\u5F85 Git \u9000\u51FA\u2026';\n job.view.progressStage = 'cancelling';\n this.signal(job, 'SIGTERM');\n }\n return this.get(id);\n }\n\n retryRegistration(id: string): ProjectClone {\n const job = this.jobs.get(id);\n this.get(id);\n if (job?.view.status === 'registration-failed') this.finishRegistration(job);\n return this.get(id);\n }\n\n private finishRegistration(job: Job): void {\n try {\n job.view.project = this.register({ path: job.view.path, name: job.view.name });\n job.view.status = 'completed';\n job.view.progress = '\u514B\u9686\u5B8C\u6210\uFF0C\u9879\u76EE\u5DF2\u6DFB\u52A0';\n job.view.progressStage = 'completed';\n delete job.view.errorCode;\n delete job.view.error;\n } catch {\n job.view.status = 'registration-failed';\n job.view.progress = '\u514B\u9686\u5DF2\u5B8C\u6210\uFF0C\u9879\u76EE\u5C1A\u672A\u6DFB\u52A0';\n job.view.progressStage = 'registration_failed';\n job.view.errorCode = 'CLONE_REGISTRATION_FAILED';\n job.view.error =\n '\u9879\u76EE\u6CE8\u518C\u5931\u8D25\u3002\u5DF2\u514B\u9686\u7684\u6587\u4EF6\u4FDD\u7559\u5728\u76EE\u6807\u76EE\u5F55\uFF1B\u53EF\u91CD\u8BD5\u6DFB\u52A0\u9879\u76EE\uFF0C\u65E0\u9700\u518D\u6B21\u514B\u9686\uFF0C\u4E5F\u53EF\u901A\u8FC7\u201C\u5DF2\u6709\u76EE\u5F55\u201D\u6DFB\u52A0\u3002';\n }\n }\n\n private signal(job: Job, signal: NodeJS.Signals): void {\n if (!job.child?.pid) return;\n try {\n if (process.platform === 'win32') job.child.kill(signal);\n else process.kill(-job.child.pid, signal);\n } catch {\n /* Process may have already exited. */\n }\n }\n\n private async run(job: Job, repository: string): Promise<void> {\n let output = '';\n let pending = '';\n let missingGit = false;\n let timedOut = false;\n const sshCommand =\n process.env.GIT_SSH_COMMAND ??\n (process.env.GIT_SSH ? `'${process.env.GIT_SSH.replaceAll(\"'\", \"'\\\\''\")}'` : 'ssh');\n const child = spawn(\n 'git',\n [\n '-c',\n 'protocol.allow=never',\n '-c',\n 'protocol.https.allow=always',\n '-c',\n 'protocol.ssh.allow=always',\n 'clone',\n '--progress',\n '--',\n repository,\n job.view.path,\n ],\n {\n detached: process.platform !== 'win32',\n stdio: ['ignore', 'pipe', 'pipe'],\n env: {\n ...process.env,\n GIT_TERMINAL_PROMPT: '0',\n GCM_INTERACTIVE: 'never',\n GIT_SSH_COMMAND: `${sshCommand} -oBatchMode=yes -oStrictHostKeyChecking=yes`,\n LC_ALL: 'C',\n },\n },\n );\n job.child = child;\n const read = (chunk: Buffer) => {\n output = (output + chunk.toString()).slice(-16_384);\n pending = (pending + chunk.toString()).slice(-4096);\n const lines = pending.split(/[\\r\\n]/);\n pending = lines.pop() ?? '';\n for (const line of lines) {\n const match =\n /^(?:remote: )?(Receiving objects|Resolving deltas|Updating files|Checking out files|Counting objects|Compressing objects):\\s+(\\d{1,3})%/.exec(\n line,\n );\n if (!match || job.view.status !== 'cloning') continue;\n const labels: Record<string, [NonNullable<ProjectClone['progressStage']>, string]> = {\n 'Receiving objects': ['receiving', '\u6B63\u5728\u63A5\u6536\u5BF9\u8C61'],\n 'Resolving deltas': ['resolving', '\u6B63\u5728\u89E3\u6790\u5DEE\u5F02'],\n 'Updating files': ['checking_out', '\u6B63\u5728\u68C0\u51FA\u6587\u4EF6'],\n 'Checking out files': ['checking_out', '\u6B63\u5728\u68C0\u51FA\u6587\u4EF6'],\n 'Counting objects': ['counting', '\u6B63\u5728\u7EDF\u8BA1\u5BF9\u8C61'],\n 'Compressing objects': ['compressing', '\u6B63\u5728\u538B\u7F29\u5BF9\u8C61'],\n };\n [job.view.progressStage, job.view.progress] = labels[match[1]!]!;\n job.view.percent = Math.min(100, Number(match[2]));\n }\n };\n child.stdout?.on('data', read);\n child.stderr?.on('data', read);\n const timeout = setTimeout(() => {\n timedOut = true;\n this.cancel(job.view.id);\n }, 30 * 60_000);\n timeout.unref();\n const escalation = setInterval(() => {\n if (job.view.status === 'cancelling') this.signal(job, 'SIGKILL');\n }, 3000);\n escalation.unref();\n const code = await new Promise<number | null>((done) => {\n child.once('error', (error: NodeJS.ErrnoException) => {\n missingGit = error.code === 'ENOENT';\n });\n child.once('close', done);\n });\n clearTimeout(timeout);\n clearInterval(escalation);\n job.child = undefined;\n delete job.view.percent;\n if (job.view.status === 'cancelling') {\n job.view.status = timedOut ? 'failed' : 'cancelled';\n job.view.progress = timedOut ? '\u514B\u9686\u8D85\u65F6\uFF0C\u5DF2\u505C\u6B62' : '\u5DF2\u53D6\u6D88\u514B\u9686';\n job.view.progressStage = timedOut ? 'timed_out' : 'cancelled';\n job.view.errorCode = timedOut ? 'CLONE_TIMED_OUT' : 'CLONE_CANCELLED';\n job.view.error = `${timedOut ? '\u514B\u9686\u8D85\u8FC7 30 \u5206\u949F\uFF0C\u5DF2\u505C\u6B62\u3002' : ''}\u672A\u6DFB\u52A0\u9879\u76EE\uFF0C\u4E5F\u672A\u5220\u9664\u4EFB\u4F55\u6587\u4EF6\u3002\u76EE\u6807\u76EE\u5F55\u53EF\u80FD\u6B8B\u7559\u6587\u4EF6\uFF0C\u8BF7\u68C0\u67E5\u540E\u4F7F\u7528\u65B0\u7684\u7A7A\u76EE\u5F55\u91CD\u8BD5\u3002`;\n } else if (code !== 0) {\n job.view.status = 'failed';\n job.view.progress = '\u514B\u9686\u5931\u8D25';\n job.view.progressStage = 'failed';\n const problem = failure(output, missingGit);\n job.view.errorCode = problem.code;\n job.view.error = `${problem.message} \u672A\u6DFB\u52A0\u9879\u76EE\uFF1B\u76EE\u6807\u76EE\u5F55\u53EF\u80FD\u6B8B\u7559\u6587\u4EF6\uFF0C\u8BF7\u68C0\u67E5\u540E\u4F7F\u7528\u65B0\u7684\u7A7A\u76EE\u5F55\u91CD\u8BD5\u3002`;\n } else this.finishRegistration(job);\n }\n\n async close(): Promise<void> {\n this.closing = true;\n for (const job of this.jobs.values()) if (active(job)) this.cancel(job.view.id);\n await Promise.all([...this.jobs.values()].map((job) => job.done));\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["job"]
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-C7jTW4sZ.js";import{n}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import{m as r}from"./src-BXQOmVZv.js";import"./chunk-DSNLSHJZ-BnMtx8Ho.js";import{n as i,r as a,t as o}from"./chunk-2E7WHVMD-TrYs0qV3.js";import{t as s}from"./chunk-JWPE2WC7-DVXcaiue.js";import"./mermaid.core-DcWRGjP5.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-BSWkYZRr.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-C7jTW4sZ.js";