@covro/covro 0.5.1-dev.1 → 0.5.1-dev.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/README.zh-CN.md +3 -1
- package/dist/server/github-repository.js +61 -0
- package/dist/server/github-repository.js.map +7 -0
- package/dist/server/http.js +8 -0
- package/dist/server/http.js.map +2 -2
- package/dist/server/service.js +18 -0
- package/dist/server/service.js.map +2 -2
- package/dist/web/assets/{abnfDiagram-WEYOIA3C-B7ZgLRcz.js → abnfDiagram-WEYOIA3C-DK1b1m5g.js} +1 -1
- package/dist/web/assets/{arc-l2Y0qpaA.js → arc-0hKPa6cH.js} +1 -1
- package/dist/web/assets/{architecture-WOLXFQ4H-CPMJhOrI.js → architecture-WOLXFQ4H-DUa2ELbW.js} +1 -1
- package/dist/web/assets/{architectureDiagram-ZHVYKT53-BGyNOKZB.js → architectureDiagram-ZHVYKT53-DfpAMcHI.js} +1 -1
- package/dist/web/assets/{blockDiagram-RJAE7QA3-CFTsFM2C.js → blockDiagram-RJAE7QA3-CD8LlPAk.js} +1 -1
- package/dist/web/assets/{c4Diagram-XDPPPE54-DePVq6hL.js → c4Diagram-XDPPPE54-KVKGUBPP.js} +1 -1
- package/dist/web/assets/channel-CpEW0zog.js +1 -0
- package/dist/web/assets/{chunk-2E7WHVMD-BjwXDHKa.js → chunk-2E7WHVMD-CPcfaznm.js} +1 -1
- package/dist/web/assets/{chunk-4EMNKR2T-DfazpkKZ.js → chunk-4EMNKR2T-Ba4ZkZos.js} +1 -1
- package/dist/web/assets/{chunk-55XCU76K-C8SPf4XM.js → chunk-55XCU76K-COU6aQoV.js} +1 -1
- package/dist/web/assets/{chunk-7S6XSTFO-4drJ38MC.js → chunk-7S6XSTFO-mof6va94.js} +1 -1
- package/dist/web/assets/{chunk-AQDTSKZB-CT94xwkm.js → chunk-AQDTSKZB-B9S7XD0k.js} +1 -1
- package/dist/web/assets/{chunk-DSNLSHJZ-Do8zQFMz.js → chunk-DSNLSHJZ-DiTTjo21.js} +1 -1
- package/dist/web/assets/{chunk-HAGFOTED-5XuJjFhz.js → chunk-HAGFOTED-bBaCv2Gr.js} +1 -1
- package/dist/web/assets/{chunk-HNE4Q36P-DlG6wQNV.js → chunk-HNE4Q36P-COubV5SQ.js} +1 -1
- package/dist/web/assets/{chunk-NQOKRVIF-D-7GGebB.js → chunk-NQOKRVIF-D7mCDLmx.js} +1 -1
- package/dist/web/assets/{chunk-UHW7PFBP-BTJa6uY3.js → chunk-UHW7PFBP-7E_Y7QMq.js} +1 -1
- package/dist/web/assets/{chunk-VQ5W62QI-DtWEqWoe.js → chunk-VQ5W62QI-DIe2sxBO.js} +1 -1
- package/dist/web/assets/{chunk-WQQL4CDK-qNZoyGqM.js → chunk-WQQL4CDK-sGc70NW0.js} +1 -1
- package/dist/web/assets/{chunk-XXDRQBXY-DGCXD5QG.js → chunk-XXDRQBXY-CnTJfCp_.js} +1 -1
- package/dist/web/assets/{chunk-YZO67HFG-DwHNq7O3.js → chunk-YZO67HFG-D1uBxw_D.js} +1 -1
- package/dist/web/assets/{chunk-ZAUX2LTX-1lvpL_7X.js → chunk-ZAUX2LTX-quytYPeh.js} +1 -1
- package/dist/web/assets/{chunk-ZCHMQSOR-Dt3EEGC_.js → chunk-ZCHMQSOR-CebhdtBu.js} +1 -1
- package/dist/web/assets/{classDiagram-v2-4MYWR3UA-DiM_A5E4.js → classDiagram-v2-4MYWR3UA-_NujQwSa.js} +1 -1
- package/dist/web/assets/{cose-bilkent-JH36ORCC-B5yeBESI.js → cose-bilkent-JH36ORCC-DltmODTL.js} +1 -1
- package/dist/web/assets/{cynefin-EF2NZ3EQ-DepIuM8k.js → cynefin-EF2NZ3EQ-CyNUtvfu.js} +1 -1
- package/dist/web/assets/{cynefinDiagram-WF24UDRP-9NThILAR.js → cynefinDiagram-WF24UDRP-DH1m77PD.js} +1 -1
- package/dist/web/assets/{dagre-NK4GIZVX-C3KdtDhG.js → dagre-NK4GIZVX-DiCwjat3.js} +1 -1
- package/dist/web/assets/{diagram-CBK3MWTC-v3bh0eI-.js → diagram-CBK3MWTC-DnoBkry8.js} +1 -1
- package/dist/web/assets/{diagram-I5XIIV2D-B-ICpu9I.js → diagram-I5XIIV2D-CIeRHNwj.js} +1 -1
- package/dist/web/assets/{diagram-ODIL2UCW-DpmbfYP-.js → diagram-ODIL2UCW-BiyJagHP.js} +1 -1
- package/dist/web/assets/{diagram-PFBEJUXE-DjCVTHlN.js → diagram-PFBEJUXE-B6xGLENr.js} +1 -1
- package/dist/web/assets/{diagram-RJA3I4VV-BgwHDpSh.js → diagram-RJA3I4VV-DCbGrXsR.js} +1 -1
- package/dist/web/assets/{diagram-TYUNFSNR-BSQV5_eI.js → diagram-TYUNFSNR-BjYXlBMa.js} +1 -1
- package/dist/web/assets/{dist-DnjG1c62.js → dist-C9Qd1YEe.js} +1 -1
- package/dist/web/assets/{ebnfDiagram-V4P3TTPT-CpfF488c.js → ebnfDiagram-V4P3TTPT-CpRXdAa6.js} +1 -1
- package/dist/web/assets/{elk-QONTBCTQ-DpD_nrIC.js → elk-QONTBCTQ-BZa9Vnbc.js} +1 -1
- package/dist/web/assets/{erDiagram-KYQIGQAA-17q4UWrx.js → erDiagram-KYQIGQAA-7AaYG_a9.js} +1 -1
- package/dist/web/assets/{eventmodeling-K75KTNOO-CuFiu_4h.js → eventmodeling-K75KTNOO-BzIg1KNf.js} +1 -1
- package/dist/web/assets/flowDiagram-IUGLLWBU-FDG_7_Jf.js +1 -0
- package/dist/web/assets/{ganttDiagram-R7GPNTJY-9ZLwR83Q.js → ganttDiagram-R7GPNTJY-DeNg-7K2.js} +1 -1
- package/dist/web/assets/{gitGraph-VSP46ZUC-DjHWMo_n.js → gitGraph-VSP46ZUC-BR-A7hdM.js} +1 -1
- package/dist/web/assets/{gitGraphDiagram-PDYL7XHY-qoPQTUpT.js → gitGraphDiagram-PDYL7XHY-LMyLpeqK.js} +1 -1
- package/dist/web/assets/index-CEM8pkOB.css +1 -0
- package/dist/web/assets/index-D2dQZgkr.js +147 -0
- package/dist/web/assets/{info-OHQRW6UA-B0YOBALB.js → info-OHQRW6UA-CRbCGNnm.js} +1 -1
- package/dist/web/assets/{infoDiagram-MVDRKAX5-DWLetMhi.js → infoDiagram-MVDRKAX5-DTUWae1O.js} +1 -1
- package/dist/web/assets/{ishikawaDiagram-HPEHV2GE-D7fHGOrW.js → ishikawaDiagram-HPEHV2GE-CE4r0jTM.js} +1 -1
- package/dist/web/assets/{journeyDiagram-BOSHW7O7-DJJ-UZbG.js → journeyDiagram-BOSHW7O7-KcSuVnTV.js} +1 -1
- package/dist/web/assets/{kanban-definition-FNSA4HC5-zWaq8RKK.js → kanban-definition-FNSA4HC5-I0QF1Ftr.js} +1 -1
- package/dist/web/assets/{line-BggZ3vsX.js → line-DLSy1-se.js} +1 -1
- package/dist/web/assets/{linear-Cz_-flHq.js → linear-XWNSUdmR.js} +1 -1
- package/dist/web/assets/{mermaid-parser.core-C7Kpq-Lh.js → mermaid-parser.core-BcMfaJSH.js} +3 -3
- package/dist/web/assets/{mermaid.core-B-AKvFuX.js → mermaid.core-CPl3cZ55.js} +4 -4
- package/dist/web/assets/{mindmap-definition-6OY57UG3-JGOdyl4n.js → mindmap-definition-6OY57UG3-BIB4ahHf.js} +1 -1
- package/dist/web/assets/{packet-JDAUHWVQ-DKCNvhvF.js → packet-JDAUHWVQ-UZicf9-F.js} +1 -1
- package/dist/web/assets/{pegDiagram-ECIUJNBX-BKKUVsiJ.js → pegDiagram-ECIUJNBX-ckOqIfTt.js} +1 -1
- package/dist/web/assets/{pie-XZMESJXO-Cj1U8HAg.js → pie-XZMESJXO-DErhKWJX.js} +1 -1
- package/dist/web/assets/{pieDiagram-GNMPY74T-B4gWYmj5.js → pieDiagram-GNMPY74T-CrnS_2qe.js} +1 -1
- package/dist/web/assets/{quadrantDiagram-D57K4MC3-CzKFFFWA.js → quadrantDiagram-D57K4MC3-UK4DsDJz.js} +1 -1
- package/dist/web/assets/{radar-ABXABTNO-BvW6txnl.js → radar-ABXABTNO-BYgJm4I9.js} +1 -1
- package/dist/web/assets/{railroad-I3PHUGI6-CQFUQhrP.js → railroad-I3PHUGI6-2n6yUb7T.js} +1 -1
- package/dist/web/assets/{railroad-abnf-LNEFI6M7-Dp31IQhK.js → railroad-abnf-LNEFI6M7-CGAFqTzs.js} +1 -1
- package/dist/web/assets/{railroad-ebnf-DWYD2UWJ-DDYlK9R4.js → railroad-ebnf-DWYD2UWJ-gJx_FXYW.js} +1 -1
- package/dist/web/assets/{railroad-peg-JR7BVNR7-C8-c26bu.js → railroad-peg-JR7BVNR7-Dm0kEaxK.js} +1 -1
- package/dist/web/assets/{railroadDiagram-Y72NRBL7-6FaSHHCa.js → railroadDiagram-Y72NRBL7-CqzySn4U.js} +1 -1
- package/dist/web/assets/{requirementDiagram-EQYSW5RA-C6Ry03Cr.js → requirementDiagram-EQYSW5RA-B33Hrc0L.js} +1 -1
- package/dist/web/assets/{sankeyDiagram-SY24JHO5-Cwnb3Qeu.js → sankeyDiagram-SY24JHO5-BA9Smc0j.js} +1 -1
- package/dist/web/assets/{sequenceDiagram-BLEHNHQU-CRvwFUCU.js → sequenceDiagram-BLEHNHQU-CUA-rKot.js} +1 -1
- package/dist/web/assets/{src-DVW4doAe.js → src-htchAh5W.js} +1 -1
- package/dist/web/assets/{stateDiagram-v2-A6IESKWZ-wwkCw23o.js → stateDiagram-v2-A6IESKWZ-kIYMkX3_.js} +1 -1
- package/dist/web/assets/{swimlanes-B3ENRKFQ-ChNg0Cbk.js → swimlanes-B3ENRKFQ-C8Lzsqig.js} +1 -1
- package/dist/web/assets/swimlanesDiagram-AYQRV4AK-CWrPdxiH.js +8 -0
- package/dist/web/assets/{timeline-definition-JXYKGLGB-BVfl26_t.js → timeline-definition-JXYKGLGB-C3uOHb1e.js} +1 -1
- package/dist/web/assets/{treeView-D4JQ5SDB-DJFvd6yo.js → treeView-D4JQ5SDB-Dq-ug1SE.js} +1 -1
- package/dist/web/assets/{treemap-SAJKECNS-BDiJSu2k.js → treemap-SAJKECNS-mX01fnXB.js} +1 -1
- package/dist/web/assets/{usecaseDiagram-WPOLBNNX-Bq_3KTOD.js → usecaseDiagram-WPOLBNNX-DMBep2-D.js} +1 -1
- package/dist/web/assets/{vennDiagram-Q3Y3IDCW-6YGgOzny.js → vennDiagram-Q3Y3IDCW-CUardqBP.js} +1 -1
- package/dist/web/assets/{wardley-7MLQ67FV-4cm0j7qc.js → wardley-7MLQ67FV-CIOqSz29.js} +1 -1
- package/dist/web/assets/{wardleyDiagram-IVAIDKWA-BMqtyCjx.js → wardleyDiagram-IVAIDKWA-DtfU2fzi.js} +1 -1
- package/dist/web/assets/{xychartDiagram-4URNHDU4-CFsu67vz.js → xychartDiagram-4URNHDU4-Cb3se94q.js} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +3 -3
- package/dist/web/assets/channel-DiiJLG5R.js +0 -1
- package/dist/web/assets/flowDiagram-IUGLLWBU-D63MFFYq.js +0 -1
- package/dist/web/assets/index-CGAKLE5y.js +0 -147
- package/dist/web/assets/index-QZirxrGa.css +0 -1
- package/dist/web/assets/swimlanesDiagram-AYQRV4AK-Dww2HRCa.js +0 -8
package/README.md
CHANGED
|
@@ -34,9 +34,11 @@
|
|
|
34
34
|
- 📖 **Read results while you chat.** Preview documents, diagrams, and code changes beside the conversation on desktop, or full-screen on mobile.
|
|
35
35
|
- 🔔 **Know when your attention is needed.** Enable browser notifications for completed work, questions, and approvals; keep the page open in a supported desktop browser.
|
|
36
36
|
|
|
37
|
+
Use **+** in the message box to attach images from your phone or computer. Open the combined model control to choose the model, reasoning effort, and Fast mode.
|
|
38
|
+
|
|
37
39
|
See the [usage guide · 中文](docs/usage.zh-CN.md) for workflow details and controls.
|
|
38
40
|
|
|
39
|
-
Start a new conversation in the current workspace with **⌘ + Option + N** on macOS or **Ctrl + Alt + N** on Windows/Linux. The message box receives focus and existing drafts stay available.
|
|
41
|
+
Start a new conversation in the current workspace with **⌘ + Option + N** on macOS or **Ctrl + Alt + N** on Windows/Linux. The message box receives focus and existing drafts stay available. When the workspace has a recognized GitHub remote, the GitHub icon in the header opens its repository in a new tab. See [workspace details](docs/workspaces.md#open-the-github-repository) for remote selection rules.
|
|
40
42
|
|
|
41
43
|
<details>
|
|
42
44
|
<summary><strong>📱 A workspace that fits your phone</strong></summary>
|
package/README.zh-CN.md
CHANGED
|
@@ -34,9 +34,11 @@
|
|
|
34
34
|
- 📖 **一边看产出,一边讨论。** 电脑上将文档、图表和代码变更与会话并排阅读,手机上使用全屏阅读器。
|
|
35
35
|
- 🔔 **及时收到待办提醒。** 开启浏览器通知,在工作结束、需要回答或审批时收到提醒;需在支持通知的桌面浏览器中保持页面运行。
|
|
36
36
|
|
|
37
|
+
点击输入框中的 **+**,可从手机或电脑选择图片附件。模型、推理强度和 Fast 模式统一收进模型设置入口。
|
|
38
|
+
|
|
37
39
|
操作方式与使用细节见[使用指南](docs/usage.zh-CN.md)。
|
|
38
40
|
|
|
39
|
-
在当前工作区新建会话:macOS 按 **⌘ + Option + N**,Windows/Linux 按 **Ctrl + Alt + N
|
|
41
|
+
在当前工作区新建会话:macOS 按 **⌘ + Option + N**,Windows/Linux 按 **Ctrl + Alt + N**。输入框会自动获得焦点,已有草稿继续保留。工作区有可识别的 GitHub remote 时,点击顶部 GitHub 图标即可在新标签页打开仓库;remote 选择规则见[工作区说明](docs/workspaces.md#快捷打开-github-仓库)。
|
|
40
42
|
|
|
41
43
|
<details>
|
|
42
44
|
<summary><strong>📱 手机上也能舒服地使用</strong></summary>
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
const exec = promisify(execFile);
|
|
4
|
+
function githubRepositoryUrl(remote) {
|
|
5
|
+
let path;
|
|
6
|
+
const scp = /^(?:[^\s/@:]+@)?github\.com:([^\s]+)$/i.exec(remote);
|
|
7
|
+
if (scp) path = scp[1];
|
|
8
|
+
else {
|
|
9
|
+
try {
|
|
10
|
+
const url = new URL(remote);
|
|
11
|
+
if (!["https:", "http:", "ssh:", "git:"].includes(url.protocol) || url.hostname.toLowerCase() !== "github.com" || url.port && !(url.protocol === "ssh:" && url.port === "22"))
|
|
12
|
+
return null;
|
|
13
|
+
path = url.pathname.slice(1);
|
|
14
|
+
} catch {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
const match = /^([a-z\d](?:[a-z\d-]*[a-z\d])?)\/([a-z\d_.-]+?)\/?$/i.exec(path);
|
|
19
|
+
if (!match) return null;
|
|
20
|
+
const repository = match[2].replace(/\.git$/i, "");
|
|
21
|
+
if (!repository || repository === "." || repository === "..") return null;
|
|
22
|
+
return `https://github.com/${match[1]}/${repository}`;
|
|
23
|
+
}
|
|
24
|
+
function selectGithubRepository(remotes) {
|
|
25
|
+
const origin = remotes.filter((remote) => remote.name === "origin");
|
|
26
|
+
const candidates = origin.length ? origin : remotes;
|
|
27
|
+
if (!candidates.length) return null;
|
|
28
|
+
const urls = candidates.map((remote) => githubRepositoryUrl(remote.url));
|
|
29
|
+
const first = urls[0];
|
|
30
|
+
return first && urls.every((url) => url?.toLowerCase() === first.toLowerCase()) ? first : null;
|
|
31
|
+
}
|
|
32
|
+
async function readGithubRepository(cwd) {
|
|
33
|
+
const options = { encoding: "utf8", timeout: 3e3, maxBuffer: 64 * 1024 };
|
|
34
|
+
try {
|
|
35
|
+
const { stdout: inside } = await exec(
|
|
36
|
+
"git",
|
|
37
|
+
["-C", cwd, "rev-parse", "--is-inside-work-tree"],
|
|
38
|
+
options
|
|
39
|
+
);
|
|
40
|
+
if (inside.trim() !== "true") return null;
|
|
41
|
+
const { stdout } = await exec(
|
|
42
|
+
"git",
|
|
43
|
+
["-C", cwd, "config", "--null", "--get-regexp", "^remote\\..*\\.url$"],
|
|
44
|
+
options
|
|
45
|
+
);
|
|
46
|
+
const remotes = stdout.split("\0").flatMap((entry) => {
|
|
47
|
+
const separator = entry.indexOf("\n");
|
|
48
|
+
const key = entry.slice(0, separator);
|
|
49
|
+
return separator >= 0 && key.startsWith("remote.") && key.endsWith(".url") ? [{ name: key.slice(7, -4), url: entry.slice(separator + 1) }] : [];
|
|
50
|
+
});
|
|
51
|
+
return selectGithubRepository(remotes);
|
|
52
|
+
} catch {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export {
|
|
57
|
+
githubRepositoryUrl,
|
|
58
|
+
readGithubRepository,
|
|
59
|
+
selectGithubRepository
|
|
60
|
+
};
|
|
61
|
+
//# sourceMappingURL=github-repository.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/server/github-repository.ts"],
|
|
4
|
+
"sourcesContent": ["import { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\n\nconst exec = promisify(execFile);\n\n/** Return only a canonical public GitHub web URL; never forward remote credentials. */\nexport function githubRepositoryUrl(remote: string): string | null {\n let path: string;\n const scp = /^(?:[^\\s/@:]+@)?github\\.com:([^\\s]+)$/i.exec(remote);\n if (scp) path = scp[1]!;\n else {\n try {\n const url = new URL(remote);\n if (\n !['https:', 'http:', 'ssh:', 'git:'].includes(url.protocol) ||\n url.hostname.toLowerCase() !== 'github.com' ||\n (url.port && !(url.protocol === 'ssh:' && url.port === '22'))\n )\n return null;\n path = url.pathname.slice(1);\n } catch {\n return null;\n }\n }\n // Exact owner/repository paths prevent links to arbitrary GitHub pages or encoded paths.\n const match = /^([a-z\\d](?:[a-z\\d-]*[a-z\\d])?)\\/([a-z\\d_.-]+?)\\/?$/i.exec(path);\n if (!match) return null;\n const repository = match[2]!.replace(/\\.git$/i, '');\n if (!repository || repository === '.' || repository === '..') return null;\n return `https://github.com/${match[1]}/${repository}`;\n}\n\nexport function selectGithubRepository(remotes: { name: string; url: string }[]): string | null {\n const origin = remotes.filter((remote) => remote.name === 'origin');\n const candidates = origin.length ? origin : remotes;\n if (!candidates.length) return null;\n const urls = candidates.map((remote) => githubRepositoryUrl(remote.url));\n const first = urls[0];\n // Without origin, every remote must identify the same repository. Ambiguity hides the link.\n return first && urls.every((url) => url?.toLowerCase() === first.toLowerCase()) ? first : null;\n}\n\nexport async function readGithubRepository(cwd: string): Promise<string | null> {\n const options = { encoding: 'utf8' as const, timeout: 3000, maxBuffer: 64 * 1024 };\n try {\n const { stdout: inside } = await exec(\n 'git',\n ['-C', cwd, 'rev-parse', '--is-inside-work-tree'],\n options,\n );\n if (inside.trim() !== 'true') return null;\n // Git resolves parent checkouts and worktree config; no network or remote commands run.\n const { stdout } = await exec(\n 'git',\n ['-C', cwd, 'config', '--null', '--get-regexp', '^remote\\\\..*\\\\.url$'],\n options,\n );\n const remotes = stdout.split('\\0').flatMap((entry) => {\n const separator = entry.indexOf('\\n');\n const key = entry.slice(0, separator);\n return separator >= 0 && key.startsWith('remote.') && key.endsWith('.url')\n ? [{ name: key.slice(7, -4), url: entry.slice(separator + 1) }]\n : [];\n });\n return selectGithubRepository(remotes);\n } catch {\n // Missing Git, unreadable config, timeouts and non-repositories leave other actions available.\n return null;\n }\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,gBAAgB;AACzB,SAAS,iBAAiB;AAE1B,MAAM,OAAO,UAAU,QAAQ;AAGxB,SAAS,oBAAoB,QAA+B;AACjE,MAAI;AACJ,QAAM,MAAM,yCAAyC,KAAK,MAAM;AAChE,MAAI,IAAK,QAAO,IAAI,CAAC;AAAA,OAChB;AACH,QAAI;AACF,YAAM,MAAM,IAAI,IAAI,MAAM;AAC1B,UACE,CAAC,CAAC,UAAU,SAAS,QAAQ,MAAM,EAAE,SAAS,IAAI,QAAQ,KAC1D,IAAI,SAAS,YAAY,MAAM,gBAC9B,IAAI,QAAQ,EAAE,IAAI,aAAa,UAAU,IAAI,SAAS;AAEvD,eAAO;AACT,aAAO,IAAI,SAAS,MAAM,CAAC;AAAA,IAC7B,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,QAAQ,uDAAuD,KAAK,IAAI;AAC9E,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,aAAa,MAAM,CAAC,EAAG,QAAQ,WAAW,EAAE;AAClD,MAAI,CAAC,cAAc,eAAe,OAAO,eAAe,KAAM,QAAO;AACrE,SAAO,sBAAsB,MAAM,CAAC,CAAC,IAAI,UAAU;AACrD;AAEO,SAAS,uBAAuB,SAAyD;AAC9F,QAAM,SAAS,QAAQ,OAAO,CAAC,WAAW,OAAO,SAAS,QAAQ;AAClE,QAAM,aAAa,OAAO,SAAS,SAAS;AAC5C,MAAI,CAAC,WAAW,OAAQ,QAAO;AAC/B,QAAM,OAAO,WAAW,IAAI,CAAC,WAAW,oBAAoB,OAAO,GAAG,CAAC;AACvE,QAAM,QAAQ,KAAK,CAAC;AAEpB,SAAO,SAAS,KAAK,MAAM,CAAC,QAAQ,KAAK,YAAY,MAAM,MAAM,YAAY,CAAC,IAAI,QAAQ;AAC5F;AAEA,eAAsB,qBAAqB,KAAqC;AAC9E,QAAM,UAAU,EAAE,UAAU,QAAiB,SAAS,KAAM,WAAW,KAAK,KAAK;AACjF,MAAI;AACF,UAAM,EAAE,QAAQ,OAAO,IAAI,MAAM;AAAA,MAC/B;AAAA,MACA,CAAC,MAAM,KAAK,aAAa,uBAAuB;AAAA,MAChD;AAAA,IACF;AACA,QAAI,OAAO,KAAK,MAAM,OAAQ,QAAO;AAErC,UAAM,EAAE,OAAO,IAAI,MAAM;AAAA,MACvB;AAAA,MACA,CAAC,MAAM,KAAK,UAAU,UAAU,gBAAgB,qBAAqB;AAAA,MACrE;AAAA,IACF;AACA,UAAM,UAAU,OAAO,MAAM,IAAI,EAAE,QAAQ,CAAC,UAAU;AACpD,YAAM,YAAY,MAAM,QAAQ,IAAI;AACpC,YAAM,MAAM,MAAM,MAAM,GAAG,SAAS;AACpC,aAAO,aAAa,KAAK,IAAI,WAAW,SAAS,KAAK,IAAI,SAAS,MAAM,IACrE,CAAC,EAAE,MAAM,IAAI,MAAM,GAAG,EAAE,GAAG,KAAK,MAAM,MAAM,YAAY,CAAC,EAAE,CAAC,IAC5D,CAAC;AAAA,IACP,CAAC;AACD,WAAO,uBAAuB,OAAO;AAAA,EACvC,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/server/http.js
CHANGED
|
@@ -163,6 +163,14 @@ function createApp({
|
|
|
163
163
|
return c.json(op, status(op));
|
|
164
164
|
});
|
|
165
165
|
app.get("/api/projects", async (c) => c.json({ data: await service.listProjects() }));
|
|
166
|
+
app.get(
|
|
167
|
+
"/api/projects/:projectId/github-repository",
|
|
168
|
+
async (c) => c.json(await service.getProjectGithubRepository(id(c.req.param("projectId"))))
|
|
169
|
+
);
|
|
170
|
+
app.get(
|
|
171
|
+
"/api/threads/:threadId/github-repository",
|
|
172
|
+
async (c) => c.json(await service.getThreadGithubRepository(id(c.req.param("threadId"))))
|
|
173
|
+
);
|
|
166
174
|
app.get(
|
|
167
175
|
"/api/unassigned/runtime-settings",
|
|
168
176
|
async (c) => c.json(await service.readRuntimeSettings(null))
|
package/dist/server/http.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/server/http.ts"],
|
|
4
|
-
"sourcesContent": ["import type { BackupController } from '../shared/backups.js';\nimport { backupIdSchema } from '../shared/backups.js';\nimport { backupRequestSchema } from '../backups/manager.js';\nimport { createHash } from 'node:crypto';\nimport { Hono } from 'hono';\nimport { bodyLimit } from 'hono/body-limit';\nimport { serveStatic } from '@hono/node-server/serve-static';\nimport { upgradeWebSocket, type HttpBindings } from '@hono/node-server';\nimport type { ZodType } from 'zod';\nimport { ZodError } from 'zod';\nimport { AppError } from '../shared/errors.js';\nimport { IMAGE_REQUEST_BYTES } from '../shared/images.js';\nimport * as schemas from '../shared/validation.js';\nimport type { Operation } from '../shared/types.js';\nimport type { AppConfig } from './config.js';\nimport { ConfigStore } from './config-store.js';\nimport { projectPathPreview, resolveProjectPath } from './project-paths.js';\nimport { createAuthenticator, type Authenticator, type Identity } from './auth.js';\nimport type { GatewayService } from './service.js';\nimport { socketHandlers } from './websocket.js';\nimport { z } from 'zod';\nimport { releaseChannels, type UpdateController } from '../shared/updates.js';\nimport { settingsSchema, updateRequestSchema } from '../updates/manager.js';\nimport { createReleaseNotesLookup, releaseNotesQuery } from '../updates/release-notes.js';\nimport { startShellSchema } from '../shared/shell.js';\nexport interface HttpDependencies {\n config: AppConfig;\n service: GatewayService;\n staticDir: string;\n authenticate?: Authenticator;\n updates?: UpdateController;\n backups?: BackupController;\n}\nexport function createApp({\n config,\n service,\n staticDir,\n authenticate = createAuthenticator(config),\n updates,\n backups,\n}: HttpDependencies) {\n const app = new Hono<{\n Bindings: HttpBindings;\n Variables: { identity: Identity; operationId?: string };\n }>();\n app.onError((error, c) => {\n const failure =\n error instanceof AppError\n ? error\n : error instanceof ZodError || error instanceof SyntaxError\n ? new AppError('VALIDATION_FAILED', 'Invalid request data', 400)\n : new AppError('INTERNAL_ERROR', 'An internal error occurred', 500);\n return c.json({ error: failure.toJSON(c.get('operationId')) }, failure.status as 400);\n });\n app.get('/api/health', (c) => c.json({ ok: true }));\n app.use('*', async (c, next) => {\n c.set('identity', await authenticate(c.req.raw, c.req.path === '/ws'));\n await next();\n });\n app.use('/api/*', (c, next) =>\n bodyLimit({\n maxSize: /^\\/api\\/threads\\/[^/]+\\/(turns|steer)$/.test(c.req.path)\n ? IMAGE_REQUEST_BYTES\n : 512 * 1024,\n onError: () => {\n throw new AppError('BODY_TOO_LARGE', 'Request body exceeds limit', 413);\n },\n })(c, next),\n );\n app.use('/api/*', async (c, next) => {\n c.header('Cache-Control', 'no-store');\n if (\n service.isInMaintenance() &&\n !['GET', 'HEAD', 'OPTIONS'].includes(c.req.method) &&\n !c.req.path.startsWith('/api/updates') &&\n !c.req.path.startsWith('/api/backups')\n )\n throw service.maintenanceError();\n await next();\n });\n if (backups) {\n app.get('/api/backups', async (c) => c.json(await backups.status()));\n app.post('/api/backups', async (c) =>\n c.json(await backups.start(backupRequestSchema.parse(await c.req.json())), 202),\n );\n app.post('/api/backups/:id/cancel', async (c) =>\n c.json(await backups.cancel(backupIdSchema.parse(c.req.param('id')))),\n );\n app.post('/api/backups/:id/verify', async (c) =>\n c.json(await backups.verify(backupIdSchema.parse(c.req.param('id')))),\n );\n }\n if (updates) {\n const releaseNotes = createReleaseNotesLookup();\n app.get('/api/updates/release-notes', async (c) => {\n const { version, refresh } = releaseNotesQuery.parse(c.req.query());\n return c.json(await releaseNotes(version, refresh === '1'));\n });\n app.get('/api/updates', async (c) => c.json(await updates.status()));\n app.post('/api/updates/check', async (c) => {\n const input = z\n .object({ channel: z.enum(releaseChannels).optional() })\n .strict()\n .parse(await c.req.json());\n return c.json(await updates.check(input.channel));\n });\n app.post('/api/updates/settings', async (c) =>\n c.json(await updates.configure(settingsSchema.parse(await c.req.json()))),\n );\n app.post('/api/updates/run', async (c) =>\n c.json(await updates.start(updateRequestSchema.parse(await c.req.json())), 202),\n );\n }\n const id = (value: string) => schemas.idSchema.parse(value);\n const parse = async <T>(\n c: { req: { json: () => Promise<unknown> }; set: (key: 'operationId', value: string) => void },\n schema: ZodType<T>,\n ): Promise<T> => {\n const value: unknown = await c.req.json();\n if (\n value &&\n typeof value === 'object' &&\n 'clientOperationId' in value &&\n typeof value.clientOperationId === 'string'\n )\n c.set('operationId', value.clientOperationId);\n return schema.parse(value);\n };\n const status = (op: Operation) =>\n op.status === 'dispatching' || op.status === 'accepted' ? (202 as const) : (200 as const);\n const configuration = new ConfigStore(config);\n app.get('/api/project-path', (c) => {\n const input = z\n .object({\n path: z.string().max(4096).default(''),\n directory: z\n .string()\n .max(255)\n .refine((value) => !/[\\\\/\\0]/.test(value) && value !== '.' && value !== '..')\n .optional(),\n })\n .parse({ path: c.req.query('path'), directory: c.req.query('directory') });\n return c.json(projectPathPreview(input.path.trim(), configuration.workDir, input.directory));\n });\n app.use('/api/config*', async (c, next) => {\n c.header('Cache-Control', 'no-store');\n await next();\n });\n app.get('/api/config', async (c) => c.json(await configuration.snapshot()));\n app.post('/api/config', async (c) => c.json(await configuration.save(await c.req.json())));\n app.post('/api/config/import', async (c) =>\n c.json(await configuration.previewImport(await c.req.json())),\n );\n app.get('/api/config/export', async (c) => {\n c.header('Content-Disposition', 'attachment; filename=\"codex-web-config.json\"');\n return c.json(await configuration.export());\n });\n app.get('/api/history-cache-context', async (c) => {\n const identity = c.get('identity');\n if (config.auth.mode !== 'local' && !identity.subject)\n throw new AppError('UNAUTHENTICATED', '\u65E0\u6CD5\u786E\u8BA4\u7F13\u5B58\u6240\u5C5E\u7528\u6237', 401);\n const projects = await service.listProjects();\n // A restart, user change or project/permission change creates a new namespace.\n // The subject is hashed on the server and is never exposed to browser storage.\n const scope = createHash('sha256')\n .update(\n JSON.stringify([\n service.events.serverEpoch,\n service.getSystem().codexEpoch,\n config.auth.mode,\n identity.subject ?? 'local',\n projects.map((project) => [project.id, project.rootPath, project.available]),\n ]),\n )\n .digest('hex');\n return c.json({ scope });\n });\n app.get('/api/system', (c) => c.json(service.getSystem()));\n app.get('/api/shell', (c) =>\n c.json(\n service.shell.snapshot(\n c.req.query('epoch'),\n z.coerce\n .number()\n .int()\n .min(0)\n .max(Number.MAX_SAFE_INTEGER)\n .default(0)\n .parse(c.req.query('after')),\n ),\n ),\n );\n app.post('/api/projects/:projectId/shell', async (c) => {\n const op = await service.startShell(\n id(c.req.param('projectId')),\n await parse(c, startShellSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/shell/:commandId/interrupt', async (c) => {\n const op = await service.interruptShell(\n id(c.req.param('commandId')),\n await parse(c, schemas.operationSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/system/compatibility/confirm', async (c) => {\n const op = await service.confirmCompatibility(\n await parse(c, schemas.confirmCompatibilitySchema),\n );\n return c.json(op, status(op));\n });\n app.get('/api/projects', async (c) => c.json({ data: await service.listProjects() }));\n app.get('/api/unassigned/runtime-settings', async (c) =>\n c.json(await service.readRuntimeSettings(null)),\n );\n app.post('/api/unassigned/model-defaults', async (c) => {\n const op = await service.saveModelDefaults(\n null,\n await parse(c, schemas.saveModelDefaultsSchema),\n );\n return c.json(op, status(op));\n });\n app.get('/api/unassigned/threads', async (c) =>\n c.json(\n await service.listThreadSummaries(\n null,\n c.req.query('cursor') === undefined\n ? undefined\n : schemas.cursorSchema.parse(c.req.query('cursor')),\n schemas.archivedQuerySchema.parse(c.req.query('archived')),\n ),\n ),\n );\n app.post('/api/unassigned/threads', async (c) => {\n const op = await service.createThread(null, await parse(c, schemas.createThreadSchema));\n return c.json(op, status(op));\n });\n app.post('/api/project-clones', async (c) =>\n c.json(\n service.cloneProject(await parse(c, schemas.cloneProjectSchema), (path) =>\n resolveProjectPath(path, configuration.workDir),\n ),\n 202,\n ),\n );\n app.get('/api/project-clones/:cloneId', (c) =>\n c.json(service.projectClones.get(id(c.req.param('cloneId')))),\n );\n app.post('/api/project-clones/:cloneId/cancel', async (c) => {\n await parse(c, schemas.removeProjectSchema);\n return c.json(service.projectClones.cancel(id(c.req.param('cloneId'))));\n });\n app.post('/api/project-clones/:cloneId/register', async (c) => {\n await parse(c, schemas.removeProjectSchema);\n return c.json(service.projectClones.retryRegistration(id(c.req.param('cloneId'))));\n });\n app.post('/api/projects/reorder', async (c) =>\n c.json(service.reorderProjects(await parse(c, schemas.reorderProjectsSchema))),\n );\n app.get('/api/projects/:projectId/runtime-settings', async (c) =>\n c.json(await service.readRuntimeSettings(id(c.req.param('projectId')))),\n );\n app.post('/api/projects/:projectId/model-defaults', async (c) => {\n const op = await service.saveModelDefaults(\n id(c.req.param('projectId')),\n await parse(c, schemas.saveModelDefaultsSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/projects', async (c) => {\n const input = await parse(c, schemas.createProjectSchema);\n return c.json(\n service.addProject({ ...input, path: resolveProjectPath(input.path, configuration.workDir) }),\n );\n });\n app.post('/api/projects/:projectId/rename', async (c) =>\n c.json(\n service.renameProject(\n id(c.req.param('projectId')),\n await parse(c, schemas.renameProjectSchema),\n ),\n ),\n );\n app.post('/api/projects/:projectId/remove', async (c) => {\n await parse(c, schemas.removeProjectSchema);\n return c.json(service.removeProject(id(c.req.param('projectId'))));\n });\n app.get('/api/projects/:projectId/threads', async (c) =>\n c.json(\n await service.listThreadSummaries(\n id(c.req.param('projectId')),\n c.req.query('cursor') === undefined\n ? undefined\n : schemas.cursorSchema.parse(c.req.query('cursor')),\n schemas.archivedQuerySchema.parse(c.req.query('archived')),\n ),\n ),\n );\n app.get('/api/threads', async (c) =>\n c.json(\n await service.listThreads(\n id(c.req.query('projectId') ?? ''),\n c.req.query('cursor') === undefined\n ? undefined\n : schemas.cursorSchema.parse(c.req.query('cursor')),\n schemas.archivedQuerySchema.parse(c.req.query('archived')),\n ),\n ),\n );\n app.post('/api/threads/:threadId/archive', async (c) => {\n return c.json(\n await service.setThreadArchived(\n id(c.req.param('threadId')),\n await parse(c, schemas.archiveThreadSchema),\n ),\n );\n });\n app.get('/api/threads/:threadId', async (c) =>\n c.json(await service.getThread(id(c.req.param('threadId')))),\n );\n app.get('/api/threads/:threadId/history', async (c) =>\n c.json(await service.getThreadHistory(id(c.req.param('threadId')), c.req.query('cursor'))),\n );\n app.get('/api/threads/:threadId/attention', (c) =>\n c.json(service.getThreadAttention(id(c.req.param('threadId')))),\n );\n app.get('/api/threads/:threadId/metadata', async (c) =>\n c.json(await service.getThreadMetadata(id(c.req.param('threadId')))),\n );\n app.get('/api/threads/:threadId/export', async (c) => {\n const exported = await service.exportThread(id(c.req.param('threadId')));\n c.header('Content-Type', 'text/markdown; charset=utf-8');\n c.header('Content-Disposition', `attachment; filename=\"${exported.filename}\"`);\n c.header('Cache-Control', 'no-store');\n c.header('X-Content-Type-Options', 'nosniff');\n c.header('X-Export-Completeness', exported.partial ? 'partial' : 'saved-history');\n return c.body(exported.markdown);\n });\n app.get('/api/threads/:threadId/images', async (c) => {\n c.header('Cache-Control', 'private, no-store');\n c.header('X-Content-Type-Options', 'nosniff');\n c.header('Cross-Origin-Resource-Policy', 'same-origin');\n c.header('Content-Security-Policy', \"default-src 'none'; sandbox\");\n const image = await service.getThreadImage(id(c.req.param('threadId')), c.req.query('path'));\n // Hash the validated bytes so same-size overwrites with preserved mtimes also invalidate.\n const etag = `\"${createHash('sha256').update(image.bytes).digest('hex')}\"`;\n c.header('Cache-Control', 'private, no-cache');\n c.header('ETag', etag);\n const ifNoneMatch = c.req.header('If-None-Match');\n if (\n ifNoneMatch === '*' ||\n ifNoneMatch?.split(',').some((tag) => tag.trim().replace(/^W\\//, '') === etag)\n )\n return c.body(null, 304);\n return c.body(image.bytes, 200, {\n 'Content-Type': image.contentType,\n 'Content-Length': String(image.bytes.length),\n });\n });\n app.get('/api/threads/:threadId/markdown', async (c) => {\n c.header('Cache-Control', 'private, no-store');\n c.header('X-Content-Type-Options', 'nosniff');\n c.header('Cross-Origin-Resource-Policy', 'same-origin');\n return c.json(\n await service.getThreadMarkdown(id(c.req.param('threadId')), c.req.query('path')),\n );\n });\n app.get('/api/threads/:threadId/text', async (c) => {\n c.header('Cache-Control', 'private, no-store');\n c.header('X-Content-Type-Options', 'nosniff');\n c.header('Cross-Origin-Resource-Policy', 'same-origin');\n return c.json(await service.getThreadText(id(c.req.param('threadId')), c.req.query('path')));\n });\n app.get('/api/threads/:threadId/json', async (c) => {\n c.header('Cache-Control', 'private, no-store');\n c.header('X-Content-Type-Options', 'nosniff');\n c.header('Cross-Origin-Resource-Policy', 'same-origin');\n return c.json(await service.getThreadJson(id(c.req.param('threadId')), c.req.query('path')));\n });\n app.get('/api/operations/:operationId', (c) =>\n c.json(service.getOperation(id(c.req.param('operationId')))),\n );\n app.post('/api/projects/:projectId/threads', async (c) => {\n const op = await service.createThread(\n id(c.req.param('projectId')),\n await parse(c, schemas.createThreadSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/resume', async (c) => {\n const op = await service.resumeThread(\n id(c.req.param('threadId')),\n await parse(c, schemas.resumeThreadSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/fork', async (c) => {\n const op = await service.forkThread(\n id(c.req.param('threadId')),\n await parse(c, schemas.forkThreadSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/rename', async (c) => {\n const op = await service.renameThread(\n id(c.req.param('threadId')),\n await parse(c, schemas.renameThreadSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/turns', async (c) => {\n const op = await service.startTurn(\n id(c.req.param('threadId')),\n await parse(c, schemas.startTurnSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/review', async (c) => {\n const op = await service.startReview(\n id(c.req.param('threadId')),\n await parse(c, schemas.startReviewSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/steer', async (c) => {\n const op = await service.steer(\n id(c.req.param('threadId')),\n await parse(c, schemas.steerSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/compact', async (c) => {\n const op = await service.compactThread(\n id(c.req.param('threadId')),\n await parse(c, schemas.operationSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/interrupt', async (c) => {\n const op = await service.interrupt(\n id(c.req.param('threadId')),\n await parse(c, schemas.interruptSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/actions/:actionId/resolve', async (c) => {\n const op = await service.resolveAction(\n id(c.req.param('actionId')),\n await parse(c, schemas.resolveActionSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/operations/:operationId/reconcile', async (c) => {\n const op = await service.reconcileOperation(\n id(c.req.param('operationId')),\n await parse(c, schemas.reconcileSchema),\n );\n return c.json(op, status(op));\n });\n app.get(\n '/ws',\n upgradeWebSocket((c) =>\n socketHandlers(service, config, c.get('identity'), c.req.query('overview') === '1'),\n ),\n );\n app.all('/api/*', () => {\n throw new AppError('NOT_FOUND', 'API route not found', 404);\n });\n app.all('/api', () => {\n throw new AppError('NOT_FOUND', 'API route not found', 404);\n });\n app.all('/ws/*', () => {\n throw new AppError('NOT_FOUND', 'WebSocket route not found', 404);\n });\n app.use('*', async (c, next) => {\n if (!c.req.path.startsWith('/assets/')) c.header('Cache-Control', 'no-store');\n c.header('X-Content-Type-Options', 'nosniff');\n c.header('Referrer-Policy', 'same-origin');\n c.header(\n 'Content-Security-Policy',\n // Remote Markdown images load directly in the browser, including HTTPS redirects.\n // Keep scripts, connections and all other resource policies restricted as before.\n \"default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https:; connect-src 'self'; frame-ancestors 'none'; base-uri 'none'\",\n );\n await next();\n });\n app.get('*', serveStatic({ root: staticDir }));\n app.get('*', async (c, next) => {\n if (!c.req.header('accept')?.includes('text/html') || /\\.[^/]+$/.test(c.req.path))\n return c.json({ error: { code: 'NOT_FOUND', message: 'Resource not found' } }, 404);\n return serveStatic({ path: `${staticDir}/index.html` })(c, next);\n });\n app.notFound((c) => c.json({ error: { code: 'NOT_FOUND', message: 'Resource not found' } }, 404));\n return app;\n}\n"],
|
|
5
|
-
"mappings": "AACA,SAAS,sBAAsB;AAC/B,SAAS,2BAA2B;AACpC,SAAS,kBAAkB;AAC3B,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAC1B,SAAS,mBAAmB;AAC5B,SAAS,wBAA2C;AAEpD,SAAS,gBAAgB;AACzB,SAAS,gBAAgB;AACzB,SAAS,2BAA2B;AACpC,YAAY,aAAa;AAGzB,SAAS,mBAAmB;AAC5B,SAAS,oBAAoB,0BAA0B;AACvD,SAAS,2BAA8D;AAEvE,SAAS,sBAAsB;AAC/B,SAAS,SAAS;AAClB,SAAS,uBAA8C;AACvD,SAAS,gBAAgB,2BAA2B;AACpD,SAAS,0BAA0B,yBAAyB;AAC5D,SAAS,wBAAwB;AAS1B,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe,oBAAoB,MAAM;AAAA,EACzC;AAAA,EACA;AACF,GAAqB;AACnB,QAAM,MAAM,IAAI,KAGb;AACH,MAAI,QAAQ,CAAC,OAAO,MAAM;AACxB,UAAM,UACJ,iBAAiB,WACb,QACA,iBAAiB,YAAY,iBAAiB,cAC5C,IAAI,SAAS,qBAAqB,wBAAwB,GAAG,IAC7D,IAAI,SAAS,kBAAkB,8BAA8B,GAAG;AACxE,WAAO,EAAE,KAAK,EAAE,OAAO,QAAQ,OAAO,EAAE,IAAI,aAAa,CAAC,EAAE,GAAG,QAAQ,MAAa;AAAA,EACtF,CAAC;AACD,MAAI,IAAI,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,KAAK,CAAC,CAAC;AAClD,MAAI,IAAI,KAAK,OAAO,GAAG,SAAS;AAC9B,MAAE,IAAI,YAAY,MAAM,aAAa,EAAE,IAAI,KAAK,EAAE,IAAI,SAAS,KAAK,CAAC;AACrE,UAAM,KAAK;AAAA,EACb,CAAC;AACD,MAAI;AAAA,IAAI;AAAA,IAAU,CAAC,GAAG,SACpB,UAAU;AAAA,MACR,SAAS,yCAAyC,KAAK,EAAE,IAAI,IAAI,IAC7D,sBACA,MAAM;AAAA,MACV,SAAS,MAAM;AACb,cAAM,IAAI,SAAS,kBAAkB,8BAA8B,GAAG;AAAA,MACxE;AAAA,IACF,CAAC,EAAE,GAAG,IAAI;AAAA,EACZ;AACA,MAAI,IAAI,UAAU,OAAO,GAAG,SAAS;AACnC,MAAE,OAAO,iBAAiB,UAAU;AACpC,QACE,QAAQ,gBAAgB,KACxB,CAAC,CAAC,OAAO,QAAQ,SAAS,EAAE,SAAS,EAAE,IAAI,MAAM,KACjD,CAAC,EAAE,IAAI,KAAK,WAAW,cAAc,KACrC,CAAC,EAAE,IAAI,KAAK,WAAW,cAAc;AAErC,YAAM,QAAQ,iBAAiB;AACjC,UAAM,KAAK;AAAA,EACb,CAAC;AACD,MAAI,SAAS;AACX,QAAI,IAAI,gBAAgB,OAAO,MAAM,EAAE,KAAK,MAAM,QAAQ,OAAO,CAAC,CAAC;AACnE,QAAI;AAAA,MAAK;AAAA,MAAgB,OAAO,MAC9B,EAAE,KAAK,MAAM,QAAQ,MAAM,oBAAoB,MAAM,MAAM,EAAE,IAAI,KAAK,CAAC,CAAC,GAAG,GAAG;AAAA,IAChF;AACA,QAAI;AAAA,MAAK;AAAA,MAA2B,OAAO,MACzC,EAAE,KAAK,MAAM,QAAQ,OAAO,eAAe,MAAM,EAAE,IAAI,MAAM,IAAI,CAAC,CAAC,CAAC;AAAA,IACtE;AACA,QAAI;AAAA,MAAK;AAAA,MAA2B,OAAO,MACzC,EAAE,KAAK,MAAM,QAAQ,OAAO,eAAe,MAAM,EAAE,IAAI,MAAM,IAAI,CAAC,CAAC,CAAC;AAAA,IACtE;AAAA,EACF;AACA,MAAI,SAAS;AACX,UAAM,eAAe,yBAAyB;AAC9C,QAAI,IAAI,8BAA8B,OAAO,MAAM;AACjD,YAAM,EAAE,SAAS,QAAQ,IAAI,kBAAkB,MAAM,EAAE,IAAI,MAAM,CAAC;AAClE,aAAO,EAAE,KAAK,MAAM,aAAa,SAAS,YAAY,GAAG,CAAC;AAAA,IAC5D,CAAC;AACD,QAAI,IAAI,gBAAgB,OAAO,MAAM,EAAE,KAAK,MAAM,QAAQ,OAAO,CAAC,CAAC;AACnE,QAAI,KAAK,sBAAsB,OAAO,MAAM;AAC1C,YAAM,QAAQ,EACX,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,SAAS,EAAE,CAAC,EACtD,OAAO,EACP,MAAM,MAAM,EAAE,IAAI,KAAK,CAAC;AAC3B,aAAO,EAAE,KAAK,MAAM,QAAQ,MAAM,MAAM,OAAO,CAAC;AAAA,IAClD,CAAC;AACD,QAAI;AAAA,MAAK;AAAA,MAAyB,OAAO,MACvC,EAAE,KAAK,MAAM,QAAQ,UAAU,eAAe,MAAM,MAAM,EAAE,IAAI,KAAK,CAAC,CAAC,CAAC;AAAA,IAC1E;AACA,QAAI;AAAA,MAAK;AAAA,MAAoB,OAAO,MAClC,EAAE,KAAK,MAAM,QAAQ,MAAM,oBAAoB,MAAM,MAAM,EAAE,IAAI,KAAK,CAAC,CAAC,GAAG,GAAG;AAAA,IAChF;AAAA,EACF;AACA,QAAM,KAAK,CAAC,UAAkB,QAAQ,SAAS,MAAM,KAAK;AAC1D,QAAM,QAAQ,OACZ,GACA,WACe;AACf,UAAM,QAAiB,MAAM,EAAE,IAAI,KAAK;AACxC,QACE,SACA,OAAO,UAAU,YACjB,uBAAuB,SACvB,OAAO,MAAM,sBAAsB;AAEnC,QAAE,IAAI,eAAe,MAAM,iBAAiB;AAC9C,WAAO,OAAO,MAAM,KAAK;AAAA,EAC3B;AACA,QAAM,SAAS,CAAC,OACd,GAAG,WAAW,iBAAiB,GAAG,WAAW,aAAc,MAAiB;AAC9E,QAAM,gBAAgB,IAAI,YAAY,MAAM;AAC5C,MAAI,IAAI,qBAAqB,CAAC,MAAM;AAClC,UAAM,QAAQ,EACX,OAAO;AAAA,MACN,MAAM,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE,QAAQ,EAAE;AAAA,MACrC,WAAW,EACR,OAAO,EACP,IAAI,GAAG,EACP,OAAO,CAAC,UAAU,CAAC,UAAU,KAAK,KAAK,KAAK,UAAU,OAAO,UAAU,IAAI,EAC3E,SAAS;AAAA,IACd,CAAC,EACA,MAAM,EAAE,MAAM,EAAE,IAAI,MAAM,MAAM,GAAG,WAAW,EAAE,IAAI,MAAM,WAAW,EAAE,CAAC;AAC3E,WAAO,EAAE,KAAK,mBAAmB,MAAM,KAAK,KAAK,GAAG,cAAc,SAAS,MAAM,SAAS,CAAC;AAAA,EAC7F,CAAC;AACD,MAAI,IAAI,gBAAgB,OAAO,GAAG,SAAS;AACzC,MAAE,OAAO,iBAAiB,UAAU;AACpC,UAAM,KAAK;AAAA,EACb,CAAC;AACD,MAAI,IAAI,eAAe,OAAO,MAAM,EAAE,KAAK,MAAM,cAAc,SAAS,CAAC,CAAC;AAC1E,MAAI,KAAK,eAAe,OAAO,MAAM,EAAE,KAAK,MAAM,cAAc,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,CAAC,CAAC;AACzF,MAAI;AAAA,IAAK;AAAA,IAAsB,OAAO,MACpC,EAAE,KAAK,MAAM,cAAc,cAAc,MAAM,EAAE,IAAI,KAAK,CAAC,CAAC;AAAA,EAC9D;AACA,MAAI,IAAI,sBAAsB,OAAO,MAAM;AACzC,MAAE,OAAO,uBAAuB,8CAA8C;AAC9E,WAAO,EAAE,KAAK,MAAM,cAAc,OAAO,CAAC;AAAA,EAC5C,CAAC;AACD,MAAI,IAAI,8BAA8B,OAAO,MAAM;AACjD,UAAM,WAAW,EAAE,IAAI,UAAU;AACjC,QAAI,OAAO,KAAK,SAAS,WAAW,CAAC,SAAS;AAC5C,YAAM,IAAI,SAAS,mBAAmB,gEAAc,GAAG;AACzD,UAAM,WAAW,MAAM,QAAQ,aAAa;AAG5C,UAAM,QAAQ,WAAW,QAAQ,EAC9B;AAAA,MACC,KAAK,UAAU;AAAA,QACb,QAAQ,OAAO;AAAA,QACf,QAAQ,UAAU,EAAE;AAAA,QACpB,OAAO,KAAK;AAAA,QACZ,SAAS,WAAW;AAAA,QACpB,SAAS,IAAI,CAAC,YAAY,CAAC,QAAQ,IAAI,QAAQ,UAAU,QAAQ,SAAS,CAAC;AAAA,MAC7E,CAAC;AAAA,IACH,EACC,OAAO,KAAK;AACf,WAAO,EAAE,KAAK,EAAE,MAAM,CAAC;AAAA,EACzB,CAAC;AACD,MAAI,IAAI,eAAe,CAAC,MAAM,EAAE,KAAK,QAAQ,UAAU,CAAC,CAAC;AACzD,MAAI;AAAA,IAAI;AAAA,IAAc,CAAC,MACrB,EAAE;AAAA,MACA,QAAQ,MAAM;AAAA,QACZ,EAAE,IAAI,MAAM,OAAO;AAAA,QACnB,EAAE,OACC,OAAO,EACP,IAAI,EACJ,IAAI,CAAC,EACL,IAAI,OAAO,gBAAgB,EAC3B,QAAQ,CAAC,EACT,MAAM,EAAE,IAAI,MAAM,OAAO,CAAC;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AACA,MAAI,KAAK,kCAAkC,OAAO,MAAM;AACtD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,WAAW,CAAC;AAAA,MAC3B,MAAM,MAAM,GAAG,gBAAgB;AAAA,IACjC;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,mCAAmC,OAAO,MAAM;AACvD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,WAAW,CAAC;AAAA,MAC3B,MAAM,MAAM,GAAG,QAAQ,eAAe;AAAA,IACxC;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,qCAAqC,OAAO,MAAM;AACzD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,MAAM,MAAM,GAAG,QAAQ,0BAA0B;AAAA,IACnD;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,IAAI,iBAAiB,OAAO,MAAM,EAAE,KAAK,EAAE,MAAM,MAAM,QAAQ,aAAa,EAAE,CAAC,CAAC;AACpF,MAAI;AAAA,IAAI;AAAA,IAAoC,OAAO,MACjD,EAAE,KAAK,MAAM,QAAQ,oBAAoB,IAAI,CAAC;AAAA,EAChD;AACA,MAAI,KAAK,kCAAkC,OAAO,MAAM;AACtD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB;AAAA,MACA,MAAM,MAAM,GAAG,QAAQ,uBAAuB;AAAA,IAChD;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI;AAAA,IAAI;AAAA,IAA2B,OAAO,MACxC,EAAE;AAAA,MACA,MAAM,QAAQ;AAAA,QACZ;AAAA,QACA,EAAE,IAAI,MAAM,QAAQ,MAAM,SACtB,SACA,QAAQ,aAAa,MAAM,EAAE,IAAI,MAAM,QAAQ,CAAC;AAAA,QACpD,QAAQ,oBAAoB,MAAM,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC3D;AAAA,IACF;AAAA,EACF;AACA,MAAI,KAAK,2BAA2B,OAAO,MAAM;AAC/C,UAAM,KAAK,MAAM,QAAQ,aAAa,MAAM,MAAM,MAAM,GAAG,QAAQ,kBAAkB,CAAC;AACtF,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI;AAAA,IAAK;AAAA,IAAuB,OAAO,MACrC,EAAE;AAAA,MACA,QAAQ;AAAA,QAAa,MAAM,MAAM,GAAG,QAAQ,kBAAkB;AAAA,QAAG,CAAC,SAChE,mBAAmB,MAAM,cAAc,OAAO;AAAA,MAChD;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,MAAI;AAAA,IAAI;AAAA,IAAgC,CAAC,MACvC,EAAE,KAAK,QAAQ,cAAc,IAAI,GAAG,EAAE,IAAI,MAAM,SAAS,CAAC,CAAC,CAAC;AAAA,EAC9D;AACA,MAAI,KAAK,uCAAuC,OAAO,MAAM;AAC3D,UAAM,MAAM,GAAG,QAAQ,mBAAmB;AAC1C,WAAO,EAAE,KAAK,QAAQ,cAAc,OAAO,GAAG,EAAE,IAAI,MAAM,SAAS,CAAC,CAAC,CAAC;AAAA,EACxE,CAAC;AACD,MAAI,KAAK,yCAAyC,OAAO,MAAM;AAC7D,UAAM,MAAM,GAAG,QAAQ,mBAAmB;AAC1C,WAAO,EAAE,KAAK,QAAQ,cAAc,kBAAkB,GAAG,EAAE,IAAI,MAAM,SAAS,CAAC,CAAC,CAAC;AAAA,EACnF,CAAC;AACD,MAAI;AAAA,IAAK;AAAA,IAAyB,OAAO,MACvC,EAAE,KAAK,QAAQ,gBAAgB,MAAM,MAAM,GAAG,QAAQ,qBAAqB,CAAC,CAAC;AAAA,EAC/E;AACA,MAAI;AAAA,IAAI;AAAA,IAA6C,OAAO,MAC1D,EAAE,KAAK,MAAM,QAAQ,oBAAoB,GAAG,EAAE,IAAI,MAAM,WAAW,CAAC,CAAC,CAAC;AAAA,EACxE;AACA,MAAI,KAAK,2CAA2C,OAAO,MAAM;AAC/D,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,WAAW,CAAC;AAAA,MAC3B,MAAM,MAAM,GAAG,QAAQ,uBAAuB;AAAA,IAChD;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,iBAAiB,OAAO,MAAM;AACrC,UAAM,QAAQ,MAAM,MAAM,GAAG,QAAQ,mBAAmB;AACxD,WAAO,EAAE;AAAA,MACP,QAAQ,WAAW,EAAE,GAAG,OAAO,MAAM,mBAAmB,MAAM,MAAM,cAAc,OAAO,EAAE,CAAC;AAAA,IAC9F;AAAA,EACF,CAAC;AACD,MAAI;AAAA,IAAK;AAAA,IAAmC,OAAO,MACjD,EAAE;AAAA,MACA,QAAQ;AAAA,QACN,GAAG,EAAE,IAAI,MAAM,WAAW,CAAC;AAAA,QAC3B,MAAM,MAAM,GAAG,QAAQ,mBAAmB;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AACA,MAAI,KAAK,mCAAmC,OAAO,MAAM;AACvD,UAAM,MAAM,GAAG,QAAQ,mBAAmB;AAC1C,WAAO,EAAE,KAAK,QAAQ,cAAc,GAAG,EAAE,IAAI,MAAM,WAAW,CAAC,CAAC,CAAC;AAAA,EACnE,CAAC;AACD,MAAI;AAAA,IAAI;AAAA,IAAoC,OAAO,MACjD,EAAE;AAAA,MACA,MAAM,QAAQ;AAAA,QACZ,GAAG,EAAE,IAAI,MAAM,WAAW,CAAC;AAAA,QAC3B,EAAE,IAAI,MAAM,QAAQ,MAAM,SACtB,SACA,QAAQ,aAAa,MAAM,EAAE,IAAI,MAAM,QAAQ,CAAC;AAAA,QACpD,QAAQ,oBAAoB,MAAM,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC3D;AAAA,IACF;AAAA,EACF;AACA,MAAI;AAAA,IAAI;AAAA,IAAgB,OAAO,MAC7B,EAAE;AAAA,MACA,MAAM,QAAQ;AAAA,QACZ,GAAG,EAAE,IAAI,MAAM,WAAW,KAAK,EAAE;AAAA,QACjC,EAAE,IAAI,MAAM,QAAQ,MAAM,SACtB,SACA,QAAQ,aAAa,MAAM,EAAE,IAAI,MAAM,QAAQ,CAAC;AAAA,QACpD,QAAQ,oBAAoB,MAAM,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC3D;AAAA,IACF;AAAA,EACF;AACA,MAAI,KAAK,kCAAkC,OAAO,MAAM;AACtD,WAAO,EAAE;AAAA,MACP,MAAM,QAAQ;AAAA,QACZ,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,QAC1B,MAAM,MAAM,GAAG,QAAQ,mBAAmB;AAAA,MAC5C;AAAA,IACF;AAAA,EACF,CAAC;AACD,MAAI;AAAA,IAAI;AAAA,IAA0B,OAAO,MACvC,EAAE,KAAK,MAAM,QAAQ,UAAU,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,CAAC,CAAC;AAAA,EAC7D;AACA,MAAI;AAAA,IAAI;AAAA,IAAkC,OAAO,MAC/C,EAAE,KAAK,MAAM,QAAQ,iBAAiB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,GAAG,EAAE,IAAI,MAAM,QAAQ,CAAC,CAAC;AAAA,EAC3F;AACA,MAAI;AAAA,IAAI;AAAA,IAAoC,CAAC,MAC3C,EAAE,KAAK,QAAQ,mBAAmB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,CAAC,CAAC;AAAA,EAChE;AACA,MAAI;AAAA,IAAI;AAAA,IAAmC,OAAO,MAChD,EAAE,KAAK,MAAM,QAAQ,kBAAkB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,CAAC,CAAC;AAAA,EACrE;AACA,MAAI,IAAI,iCAAiC,OAAO,MAAM;AACpD,UAAM,WAAW,MAAM,QAAQ,aAAa,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,CAAC;AACvE,MAAE,OAAO,gBAAgB,8BAA8B;AACvD,MAAE,OAAO,uBAAuB,yBAAyB,SAAS,QAAQ,GAAG;AAC7E,MAAE,OAAO,iBAAiB,UAAU;AACpC,MAAE,OAAO,0BAA0B,SAAS;AAC5C,MAAE,OAAO,yBAAyB,SAAS,UAAU,YAAY,eAAe;AAChF,WAAO,EAAE,KAAK,SAAS,QAAQ;AAAA,EACjC,CAAC;AACD,MAAI,IAAI,iCAAiC,OAAO,MAAM;AACpD,MAAE,OAAO,iBAAiB,mBAAmB;AAC7C,MAAE,OAAO,0BAA0B,SAAS;AAC5C,MAAE,OAAO,gCAAgC,aAAa;AACtD,MAAE,OAAO,2BAA2B,6BAA6B;AACjE,UAAM,QAAQ,MAAM,QAAQ,eAAe,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,GAAG,EAAE,IAAI,MAAM,MAAM,CAAC;AAE3F,UAAM,OAAO,IAAI,WAAW,QAAQ,EAAE,OAAO,MAAM,KAAK,EAAE,OAAO,KAAK,CAAC;AACvE,MAAE,OAAO,iBAAiB,mBAAmB;AAC7C,MAAE,OAAO,QAAQ,IAAI;AACrB,UAAM,cAAc,EAAE,IAAI,OAAO,eAAe;AAChD,QACE,gBAAgB,OAChB,aAAa,MAAM,GAAG,EAAE,KAAK,CAAC,QAAQ,IAAI,KAAK,EAAE,QAAQ,QAAQ,EAAE,MAAM,IAAI;AAE7E,aAAO,EAAE,KAAK,MAAM,GAAG;AACzB,WAAO,EAAE,KAAK,MAAM,OAAO,KAAK;AAAA,MAC9B,gBAAgB,MAAM;AAAA,MACtB,kBAAkB,OAAO,MAAM,MAAM,MAAM;AAAA,IAC7C,CAAC;AAAA,EACH,CAAC;AACD,MAAI,IAAI,mCAAmC,OAAO,MAAM;AACtD,MAAE,OAAO,iBAAiB,mBAAmB;AAC7C,MAAE,OAAO,0BAA0B,SAAS;AAC5C,MAAE,OAAO,gCAAgC,aAAa;AACtD,WAAO,EAAE;AAAA,MACP,MAAM,QAAQ,kBAAkB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,GAAG,EAAE,IAAI,MAAM,MAAM,CAAC;AAAA,IAClF;AAAA,EACF,CAAC;AACD,MAAI,IAAI,+BAA+B,OAAO,MAAM;AAClD,MAAE,OAAO,iBAAiB,mBAAmB;AAC7C,MAAE,OAAO,0BAA0B,SAAS;AAC5C,MAAE,OAAO,gCAAgC,aAAa;AACtD,WAAO,EAAE,KAAK,MAAM,QAAQ,cAAc,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,GAAG,EAAE,IAAI,MAAM,MAAM,CAAC,CAAC;AAAA,EAC7F,CAAC;AACD,MAAI,IAAI,+BAA+B,OAAO,MAAM;AAClD,MAAE,OAAO,iBAAiB,mBAAmB;AAC7C,MAAE,OAAO,0BAA0B,SAAS;AAC5C,MAAE,OAAO,gCAAgC,aAAa;AACtD,WAAO,EAAE,KAAK,MAAM,QAAQ,cAAc,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,GAAG,EAAE,IAAI,MAAM,MAAM,CAAC,CAAC;AAAA,EAC7F,CAAC;AACD,MAAI;AAAA,IAAI;AAAA,IAAgC,CAAC,MACvC,EAAE,KAAK,QAAQ,aAAa,GAAG,EAAE,IAAI,MAAM,aAAa,CAAC,CAAC,CAAC;AAAA,EAC7D;AACA,MAAI,KAAK,oCAAoC,OAAO,MAAM;AACxD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,WAAW,CAAC;AAAA,MAC3B,MAAM,MAAM,GAAG,QAAQ,kBAAkB;AAAA,IAC3C;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,iCAAiC,OAAO,MAAM;AACrD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,kBAAkB;AAAA,IAC3C;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,+BAA+B,OAAO,MAAM;AACnD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,gBAAgB;AAAA,IACzC;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,iCAAiC,OAAO,MAAM;AACrD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,kBAAkB;AAAA,IAC3C;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,gCAAgC,OAAO,MAAM;AACpD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,eAAe;AAAA,IACxC;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,iCAAiC,OAAO,MAAM;AACrD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,iBAAiB;AAAA,IAC1C;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,gCAAgC,OAAO,MAAM;AACpD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,WAAW;AAAA,IACpC;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,kCAAkC,OAAO,MAAM;AACtD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,eAAe;AAAA,IACxC;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,oCAAoC,OAAO,MAAM;AACxD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,eAAe;AAAA,IACxC;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,kCAAkC,OAAO,MAAM;AACtD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,mBAAmB;AAAA,IAC5C;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,0CAA0C,OAAO,MAAM;AAC9D,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,aAAa,CAAC;AAAA,MAC7B,MAAM,MAAM,GAAG,QAAQ,eAAe;AAAA,IACxC;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI;AAAA,IACF;AAAA,IACA;AAAA,MAAiB,CAAC,MAChB,eAAe,SAAS,QAAQ,EAAE,IAAI,UAAU,GAAG,EAAE,IAAI,MAAM,UAAU,MAAM,GAAG;AAAA,IACpF;AAAA,EACF;AACA,MAAI,IAAI,UAAU,MAAM;AACtB,UAAM,IAAI,SAAS,aAAa,uBAAuB,GAAG;AAAA,EAC5D,CAAC;AACD,MAAI,IAAI,QAAQ,MAAM;AACpB,UAAM,IAAI,SAAS,aAAa,uBAAuB,GAAG;AAAA,EAC5D,CAAC;AACD,MAAI,IAAI,SAAS,MAAM;AACrB,UAAM,IAAI,SAAS,aAAa,6BAA6B,GAAG;AAAA,EAClE,CAAC;AACD,MAAI,IAAI,KAAK,OAAO,GAAG,SAAS;AAC9B,QAAI,CAAC,EAAE,IAAI,KAAK,WAAW,UAAU,EAAG,GAAE,OAAO,iBAAiB,UAAU;AAC5E,MAAE,OAAO,0BAA0B,SAAS;AAC5C,MAAE,OAAO,mBAAmB,aAAa;AACzC,MAAE;AAAA,MACA;AAAA;AAAA;AAAA,MAGA;AAAA,IACF;AACA,UAAM,KAAK;AAAA,EACb,CAAC;AACD,MAAI,IAAI,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC,CAAC;AAC7C,MAAI,IAAI,KAAK,OAAO,GAAG,SAAS;AAC9B,QAAI,CAAC,EAAE,IAAI,OAAO,QAAQ,GAAG,SAAS,WAAW,KAAK,WAAW,KAAK,EAAE,IAAI,IAAI;AAC9E,aAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,SAAS,qBAAqB,EAAE,GAAG,GAAG;AACpF,WAAO,YAAY,EAAE,MAAM,GAAG,SAAS,cAAc,CAAC,EAAE,GAAG,IAAI;AAAA,EACjE,CAAC;AACD,MAAI,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,SAAS,qBAAqB,EAAE,GAAG,GAAG,CAAC;AAChG,SAAO;AACT;",
|
|
4
|
+
"sourcesContent": ["import type { BackupController } from '../shared/backups.js';\nimport { backupIdSchema } from '../shared/backups.js';\nimport { backupRequestSchema } from '../backups/manager.js';\nimport { createHash } from 'node:crypto';\nimport { Hono } from 'hono';\nimport { bodyLimit } from 'hono/body-limit';\nimport { serveStatic } from '@hono/node-server/serve-static';\nimport { upgradeWebSocket, type HttpBindings } from '@hono/node-server';\nimport type { ZodType } from 'zod';\nimport { ZodError } from 'zod';\nimport { AppError } from '../shared/errors.js';\nimport { IMAGE_REQUEST_BYTES } from '../shared/images.js';\nimport * as schemas from '../shared/validation.js';\nimport type { Operation } from '../shared/types.js';\nimport type { AppConfig } from './config.js';\nimport { ConfigStore } from './config-store.js';\nimport { projectPathPreview, resolveProjectPath } from './project-paths.js';\nimport { createAuthenticator, type Authenticator, type Identity } from './auth.js';\nimport type { GatewayService } from './service.js';\nimport { socketHandlers } from './websocket.js';\nimport { z } from 'zod';\nimport { releaseChannels, type UpdateController } from '../shared/updates.js';\nimport { settingsSchema, updateRequestSchema } from '../updates/manager.js';\nimport { createReleaseNotesLookup, releaseNotesQuery } from '../updates/release-notes.js';\nimport { startShellSchema } from '../shared/shell.js';\nexport interface HttpDependencies {\n config: AppConfig;\n service: GatewayService;\n staticDir: string;\n authenticate?: Authenticator;\n updates?: UpdateController;\n backups?: BackupController;\n}\nexport function createApp({\n config,\n service,\n staticDir,\n authenticate = createAuthenticator(config),\n updates,\n backups,\n}: HttpDependencies) {\n const app = new Hono<{\n Bindings: HttpBindings;\n Variables: { identity: Identity; operationId?: string };\n }>();\n app.onError((error, c) => {\n const failure =\n error instanceof AppError\n ? error\n : error instanceof ZodError || error instanceof SyntaxError\n ? new AppError('VALIDATION_FAILED', 'Invalid request data', 400)\n : new AppError('INTERNAL_ERROR', 'An internal error occurred', 500);\n return c.json({ error: failure.toJSON(c.get('operationId')) }, failure.status as 400);\n });\n app.get('/api/health', (c) => c.json({ ok: true }));\n app.use('*', async (c, next) => {\n c.set('identity', await authenticate(c.req.raw, c.req.path === '/ws'));\n await next();\n });\n app.use('/api/*', (c, next) =>\n bodyLimit({\n maxSize: /^\\/api\\/threads\\/[^/]+\\/(turns|steer)$/.test(c.req.path)\n ? IMAGE_REQUEST_BYTES\n : 512 * 1024,\n onError: () => {\n throw new AppError('BODY_TOO_LARGE', 'Request body exceeds limit', 413);\n },\n })(c, next),\n );\n app.use('/api/*', async (c, next) => {\n c.header('Cache-Control', 'no-store');\n if (\n service.isInMaintenance() &&\n !['GET', 'HEAD', 'OPTIONS'].includes(c.req.method) &&\n !c.req.path.startsWith('/api/updates') &&\n !c.req.path.startsWith('/api/backups')\n )\n throw service.maintenanceError();\n await next();\n });\n if (backups) {\n app.get('/api/backups', async (c) => c.json(await backups.status()));\n app.post('/api/backups', async (c) =>\n c.json(await backups.start(backupRequestSchema.parse(await c.req.json())), 202),\n );\n app.post('/api/backups/:id/cancel', async (c) =>\n c.json(await backups.cancel(backupIdSchema.parse(c.req.param('id')))),\n );\n app.post('/api/backups/:id/verify', async (c) =>\n c.json(await backups.verify(backupIdSchema.parse(c.req.param('id')))),\n );\n }\n if (updates) {\n const releaseNotes = createReleaseNotesLookup();\n app.get('/api/updates/release-notes', async (c) => {\n const { version, refresh } = releaseNotesQuery.parse(c.req.query());\n return c.json(await releaseNotes(version, refresh === '1'));\n });\n app.get('/api/updates', async (c) => c.json(await updates.status()));\n app.post('/api/updates/check', async (c) => {\n const input = z\n .object({ channel: z.enum(releaseChannels).optional() })\n .strict()\n .parse(await c.req.json());\n return c.json(await updates.check(input.channel));\n });\n app.post('/api/updates/settings', async (c) =>\n c.json(await updates.configure(settingsSchema.parse(await c.req.json()))),\n );\n app.post('/api/updates/run', async (c) =>\n c.json(await updates.start(updateRequestSchema.parse(await c.req.json())), 202),\n );\n }\n const id = (value: string) => schemas.idSchema.parse(value);\n const parse = async <T>(\n c: { req: { json: () => Promise<unknown> }; set: (key: 'operationId', value: string) => void },\n schema: ZodType<T>,\n ): Promise<T> => {\n const value: unknown = await c.req.json();\n if (\n value &&\n typeof value === 'object' &&\n 'clientOperationId' in value &&\n typeof value.clientOperationId === 'string'\n )\n c.set('operationId', value.clientOperationId);\n return schema.parse(value);\n };\n const status = (op: Operation) =>\n op.status === 'dispatching' || op.status === 'accepted' ? (202 as const) : (200 as const);\n const configuration = new ConfigStore(config);\n app.get('/api/project-path', (c) => {\n const input = z\n .object({\n path: z.string().max(4096).default(''),\n directory: z\n .string()\n .max(255)\n .refine((value) => !/[\\\\/\\0]/.test(value) && value !== '.' && value !== '..')\n .optional(),\n })\n .parse({ path: c.req.query('path'), directory: c.req.query('directory') });\n return c.json(projectPathPreview(input.path.trim(), configuration.workDir, input.directory));\n });\n app.use('/api/config*', async (c, next) => {\n c.header('Cache-Control', 'no-store');\n await next();\n });\n app.get('/api/config', async (c) => c.json(await configuration.snapshot()));\n app.post('/api/config', async (c) => c.json(await configuration.save(await c.req.json())));\n app.post('/api/config/import', async (c) =>\n c.json(await configuration.previewImport(await c.req.json())),\n );\n app.get('/api/config/export', async (c) => {\n c.header('Content-Disposition', 'attachment; filename=\"codex-web-config.json\"');\n return c.json(await configuration.export());\n });\n app.get('/api/history-cache-context', async (c) => {\n const identity = c.get('identity');\n if (config.auth.mode !== 'local' && !identity.subject)\n throw new AppError('UNAUTHENTICATED', '\u65E0\u6CD5\u786E\u8BA4\u7F13\u5B58\u6240\u5C5E\u7528\u6237', 401);\n const projects = await service.listProjects();\n // A restart, user change or project/permission change creates a new namespace.\n // The subject is hashed on the server and is never exposed to browser storage.\n const scope = createHash('sha256')\n .update(\n JSON.stringify([\n service.events.serverEpoch,\n service.getSystem().codexEpoch,\n config.auth.mode,\n identity.subject ?? 'local',\n projects.map((project) => [project.id, project.rootPath, project.available]),\n ]),\n )\n .digest('hex');\n return c.json({ scope });\n });\n app.get('/api/system', (c) => c.json(service.getSystem()));\n app.get('/api/shell', (c) =>\n c.json(\n service.shell.snapshot(\n c.req.query('epoch'),\n z.coerce\n .number()\n .int()\n .min(0)\n .max(Number.MAX_SAFE_INTEGER)\n .default(0)\n .parse(c.req.query('after')),\n ),\n ),\n );\n app.post('/api/projects/:projectId/shell', async (c) => {\n const op = await service.startShell(\n id(c.req.param('projectId')),\n await parse(c, startShellSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/shell/:commandId/interrupt', async (c) => {\n const op = await service.interruptShell(\n id(c.req.param('commandId')),\n await parse(c, schemas.operationSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/system/compatibility/confirm', async (c) => {\n const op = await service.confirmCompatibility(\n await parse(c, schemas.confirmCompatibilitySchema),\n );\n return c.json(op, status(op));\n });\n app.get('/api/projects', async (c) => c.json({ data: await service.listProjects() }));\n app.get('/api/projects/:projectId/github-repository', async (c) =>\n c.json(await service.getProjectGithubRepository(id(c.req.param('projectId')))),\n );\n app.get('/api/threads/:threadId/github-repository', async (c) =>\n c.json(await service.getThreadGithubRepository(id(c.req.param('threadId')))),\n );\n app.get('/api/unassigned/runtime-settings', async (c) =>\n c.json(await service.readRuntimeSettings(null)),\n );\n app.post('/api/unassigned/model-defaults', async (c) => {\n const op = await service.saveModelDefaults(\n null,\n await parse(c, schemas.saveModelDefaultsSchema),\n );\n return c.json(op, status(op));\n });\n app.get('/api/unassigned/threads', async (c) =>\n c.json(\n await service.listThreadSummaries(\n null,\n c.req.query('cursor') === undefined\n ? undefined\n : schemas.cursorSchema.parse(c.req.query('cursor')),\n schemas.archivedQuerySchema.parse(c.req.query('archived')),\n ),\n ),\n );\n app.post('/api/unassigned/threads', async (c) => {\n const op = await service.createThread(null, await parse(c, schemas.createThreadSchema));\n return c.json(op, status(op));\n });\n app.post('/api/project-clones', async (c) =>\n c.json(\n service.cloneProject(await parse(c, schemas.cloneProjectSchema), (path) =>\n resolveProjectPath(path, configuration.workDir),\n ),\n 202,\n ),\n );\n app.get('/api/project-clones/:cloneId', (c) =>\n c.json(service.projectClones.get(id(c.req.param('cloneId')))),\n );\n app.post('/api/project-clones/:cloneId/cancel', async (c) => {\n await parse(c, schemas.removeProjectSchema);\n return c.json(service.projectClones.cancel(id(c.req.param('cloneId'))));\n });\n app.post('/api/project-clones/:cloneId/register', async (c) => {\n await parse(c, schemas.removeProjectSchema);\n return c.json(service.projectClones.retryRegistration(id(c.req.param('cloneId'))));\n });\n app.post('/api/projects/reorder', async (c) =>\n c.json(service.reorderProjects(await parse(c, schemas.reorderProjectsSchema))),\n );\n app.get('/api/projects/:projectId/runtime-settings', async (c) =>\n c.json(await service.readRuntimeSettings(id(c.req.param('projectId')))),\n );\n app.post('/api/projects/:projectId/model-defaults', async (c) => {\n const op = await service.saveModelDefaults(\n id(c.req.param('projectId')),\n await parse(c, schemas.saveModelDefaultsSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/projects', async (c) => {\n const input = await parse(c, schemas.createProjectSchema);\n return c.json(\n service.addProject({ ...input, path: resolveProjectPath(input.path, configuration.workDir) }),\n );\n });\n app.post('/api/projects/:projectId/rename', async (c) =>\n c.json(\n service.renameProject(\n id(c.req.param('projectId')),\n await parse(c, schemas.renameProjectSchema),\n ),\n ),\n );\n app.post('/api/projects/:projectId/remove', async (c) => {\n await parse(c, schemas.removeProjectSchema);\n return c.json(service.removeProject(id(c.req.param('projectId'))));\n });\n app.get('/api/projects/:projectId/threads', async (c) =>\n c.json(\n await service.listThreadSummaries(\n id(c.req.param('projectId')),\n c.req.query('cursor') === undefined\n ? undefined\n : schemas.cursorSchema.parse(c.req.query('cursor')),\n schemas.archivedQuerySchema.parse(c.req.query('archived')),\n ),\n ),\n );\n app.get('/api/threads', async (c) =>\n c.json(\n await service.listThreads(\n id(c.req.query('projectId') ?? ''),\n c.req.query('cursor') === undefined\n ? undefined\n : schemas.cursorSchema.parse(c.req.query('cursor')),\n schemas.archivedQuerySchema.parse(c.req.query('archived')),\n ),\n ),\n );\n app.post('/api/threads/:threadId/archive', async (c) => {\n return c.json(\n await service.setThreadArchived(\n id(c.req.param('threadId')),\n await parse(c, schemas.archiveThreadSchema),\n ),\n );\n });\n app.get('/api/threads/:threadId', async (c) =>\n c.json(await service.getThread(id(c.req.param('threadId')))),\n );\n app.get('/api/threads/:threadId/history', async (c) =>\n c.json(await service.getThreadHistory(id(c.req.param('threadId')), c.req.query('cursor'))),\n );\n app.get('/api/threads/:threadId/attention', (c) =>\n c.json(service.getThreadAttention(id(c.req.param('threadId')))),\n );\n app.get('/api/threads/:threadId/metadata', async (c) =>\n c.json(await service.getThreadMetadata(id(c.req.param('threadId')))),\n );\n app.get('/api/threads/:threadId/export', async (c) => {\n const exported = await service.exportThread(id(c.req.param('threadId')));\n c.header('Content-Type', 'text/markdown; charset=utf-8');\n c.header('Content-Disposition', `attachment; filename=\"${exported.filename}\"`);\n c.header('Cache-Control', 'no-store');\n c.header('X-Content-Type-Options', 'nosniff');\n c.header('X-Export-Completeness', exported.partial ? 'partial' : 'saved-history');\n return c.body(exported.markdown);\n });\n app.get('/api/threads/:threadId/images', async (c) => {\n c.header('Cache-Control', 'private, no-store');\n c.header('X-Content-Type-Options', 'nosniff');\n c.header('Cross-Origin-Resource-Policy', 'same-origin');\n c.header('Content-Security-Policy', \"default-src 'none'; sandbox\");\n const image = await service.getThreadImage(id(c.req.param('threadId')), c.req.query('path'));\n // Hash the validated bytes so same-size overwrites with preserved mtimes also invalidate.\n const etag = `\"${createHash('sha256').update(image.bytes).digest('hex')}\"`;\n c.header('Cache-Control', 'private, no-cache');\n c.header('ETag', etag);\n const ifNoneMatch = c.req.header('If-None-Match');\n if (\n ifNoneMatch === '*' ||\n ifNoneMatch?.split(',').some((tag) => tag.trim().replace(/^W\\//, '') === etag)\n )\n return c.body(null, 304);\n return c.body(image.bytes, 200, {\n 'Content-Type': image.contentType,\n 'Content-Length': String(image.bytes.length),\n });\n });\n app.get('/api/threads/:threadId/markdown', async (c) => {\n c.header('Cache-Control', 'private, no-store');\n c.header('X-Content-Type-Options', 'nosniff');\n c.header('Cross-Origin-Resource-Policy', 'same-origin');\n return c.json(\n await service.getThreadMarkdown(id(c.req.param('threadId')), c.req.query('path')),\n );\n });\n app.get('/api/threads/:threadId/text', async (c) => {\n c.header('Cache-Control', 'private, no-store');\n c.header('X-Content-Type-Options', 'nosniff');\n c.header('Cross-Origin-Resource-Policy', 'same-origin');\n return c.json(await service.getThreadText(id(c.req.param('threadId')), c.req.query('path')));\n });\n app.get('/api/threads/:threadId/json', async (c) => {\n c.header('Cache-Control', 'private, no-store');\n c.header('X-Content-Type-Options', 'nosniff');\n c.header('Cross-Origin-Resource-Policy', 'same-origin');\n return c.json(await service.getThreadJson(id(c.req.param('threadId')), c.req.query('path')));\n });\n app.get('/api/operations/:operationId', (c) =>\n c.json(service.getOperation(id(c.req.param('operationId')))),\n );\n app.post('/api/projects/:projectId/threads', async (c) => {\n const op = await service.createThread(\n id(c.req.param('projectId')),\n await parse(c, schemas.createThreadSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/resume', async (c) => {\n const op = await service.resumeThread(\n id(c.req.param('threadId')),\n await parse(c, schemas.resumeThreadSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/fork', async (c) => {\n const op = await service.forkThread(\n id(c.req.param('threadId')),\n await parse(c, schemas.forkThreadSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/rename', async (c) => {\n const op = await service.renameThread(\n id(c.req.param('threadId')),\n await parse(c, schemas.renameThreadSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/turns', async (c) => {\n const op = await service.startTurn(\n id(c.req.param('threadId')),\n await parse(c, schemas.startTurnSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/review', async (c) => {\n const op = await service.startReview(\n id(c.req.param('threadId')),\n await parse(c, schemas.startReviewSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/steer', async (c) => {\n const op = await service.steer(\n id(c.req.param('threadId')),\n await parse(c, schemas.steerSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/compact', async (c) => {\n const op = await service.compactThread(\n id(c.req.param('threadId')),\n await parse(c, schemas.operationSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/interrupt', async (c) => {\n const op = await service.interrupt(\n id(c.req.param('threadId')),\n await parse(c, schemas.interruptSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/actions/:actionId/resolve', async (c) => {\n const op = await service.resolveAction(\n id(c.req.param('actionId')),\n await parse(c, schemas.resolveActionSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/operations/:operationId/reconcile', async (c) => {\n const op = await service.reconcileOperation(\n id(c.req.param('operationId')),\n await parse(c, schemas.reconcileSchema),\n );\n return c.json(op, status(op));\n });\n app.get(\n '/ws',\n upgradeWebSocket((c) =>\n socketHandlers(service, config, c.get('identity'), c.req.query('overview') === '1'),\n ),\n );\n app.all('/api/*', () => {\n throw new AppError('NOT_FOUND', 'API route not found', 404);\n });\n app.all('/api', () => {\n throw new AppError('NOT_FOUND', 'API route not found', 404);\n });\n app.all('/ws/*', () => {\n throw new AppError('NOT_FOUND', 'WebSocket route not found', 404);\n });\n app.use('*', async (c, next) => {\n if (!c.req.path.startsWith('/assets/')) c.header('Cache-Control', 'no-store');\n c.header('X-Content-Type-Options', 'nosniff');\n c.header('Referrer-Policy', 'same-origin');\n c.header(\n 'Content-Security-Policy',\n // Remote Markdown images load directly in the browser, including HTTPS redirects.\n // Keep scripts, connections and all other resource policies restricted as before.\n \"default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https:; connect-src 'self'; frame-ancestors 'none'; base-uri 'none'\",\n );\n await next();\n });\n app.get('*', serveStatic({ root: staticDir }));\n app.get('*', async (c, next) => {\n if (!c.req.header('accept')?.includes('text/html') || /\\.[^/]+$/.test(c.req.path))\n return c.json({ error: { code: 'NOT_FOUND', message: 'Resource not found' } }, 404);\n return serveStatic({ path: `${staticDir}/index.html` })(c, next);\n });\n app.notFound((c) => c.json({ error: { code: 'NOT_FOUND', message: 'Resource not found' } }, 404));\n return app;\n}\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,sBAAsB;AAC/B,SAAS,2BAA2B;AACpC,SAAS,kBAAkB;AAC3B,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAC1B,SAAS,mBAAmB;AAC5B,SAAS,wBAA2C;AAEpD,SAAS,gBAAgB;AACzB,SAAS,gBAAgB;AACzB,SAAS,2BAA2B;AACpC,YAAY,aAAa;AAGzB,SAAS,mBAAmB;AAC5B,SAAS,oBAAoB,0BAA0B;AACvD,SAAS,2BAA8D;AAEvE,SAAS,sBAAsB;AAC/B,SAAS,SAAS;AAClB,SAAS,uBAA8C;AACvD,SAAS,gBAAgB,2BAA2B;AACpD,SAAS,0BAA0B,yBAAyB;AAC5D,SAAS,wBAAwB;AAS1B,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe,oBAAoB,MAAM;AAAA,EACzC;AAAA,EACA;AACF,GAAqB;AACnB,QAAM,MAAM,IAAI,KAGb;AACH,MAAI,QAAQ,CAAC,OAAO,MAAM;AACxB,UAAM,UACJ,iBAAiB,WACb,QACA,iBAAiB,YAAY,iBAAiB,cAC5C,IAAI,SAAS,qBAAqB,wBAAwB,GAAG,IAC7D,IAAI,SAAS,kBAAkB,8BAA8B,GAAG;AACxE,WAAO,EAAE,KAAK,EAAE,OAAO,QAAQ,OAAO,EAAE,IAAI,aAAa,CAAC,EAAE,GAAG,QAAQ,MAAa;AAAA,EACtF,CAAC;AACD,MAAI,IAAI,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,KAAK,CAAC,CAAC;AAClD,MAAI,IAAI,KAAK,OAAO,GAAG,SAAS;AAC9B,MAAE,IAAI,YAAY,MAAM,aAAa,EAAE,IAAI,KAAK,EAAE,IAAI,SAAS,KAAK,CAAC;AACrE,UAAM,KAAK;AAAA,EACb,CAAC;AACD,MAAI;AAAA,IAAI;AAAA,IAAU,CAAC,GAAG,SACpB,UAAU;AAAA,MACR,SAAS,yCAAyC,KAAK,EAAE,IAAI,IAAI,IAC7D,sBACA,MAAM;AAAA,MACV,SAAS,MAAM;AACb,cAAM,IAAI,SAAS,kBAAkB,8BAA8B,GAAG;AAAA,MACxE;AAAA,IACF,CAAC,EAAE,GAAG,IAAI;AAAA,EACZ;AACA,MAAI,IAAI,UAAU,OAAO,GAAG,SAAS;AACnC,MAAE,OAAO,iBAAiB,UAAU;AACpC,QACE,QAAQ,gBAAgB,KACxB,CAAC,CAAC,OAAO,QAAQ,SAAS,EAAE,SAAS,EAAE,IAAI,MAAM,KACjD,CAAC,EAAE,IAAI,KAAK,WAAW,cAAc,KACrC,CAAC,EAAE,IAAI,KAAK,WAAW,cAAc;AAErC,YAAM,QAAQ,iBAAiB;AACjC,UAAM,KAAK;AAAA,EACb,CAAC;AACD,MAAI,SAAS;AACX,QAAI,IAAI,gBAAgB,OAAO,MAAM,EAAE,KAAK,MAAM,QAAQ,OAAO,CAAC,CAAC;AACnE,QAAI;AAAA,MAAK;AAAA,MAAgB,OAAO,MAC9B,EAAE,KAAK,MAAM,QAAQ,MAAM,oBAAoB,MAAM,MAAM,EAAE,IAAI,KAAK,CAAC,CAAC,GAAG,GAAG;AAAA,IAChF;AACA,QAAI;AAAA,MAAK;AAAA,MAA2B,OAAO,MACzC,EAAE,KAAK,MAAM,QAAQ,OAAO,eAAe,MAAM,EAAE,IAAI,MAAM,IAAI,CAAC,CAAC,CAAC;AAAA,IACtE;AACA,QAAI;AAAA,MAAK;AAAA,MAA2B,OAAO,MACzC,EAAE,KAAK,MAAM,QAAQ,OAAO,eAAe,MAAM,EAAE,IAAI,MAAM,IAAI,CAAC,CAAC,CAAC;AAAA,IACtE;AAAA,EACF;AACA,MAAI,SAAS;AACX,UAAM,eAAe,yBAAyB;AAC9C,QAAI,IAAI,8BAA8B,OAAO,MAAM;AACjD,YAAM,EAAE,SAAS,QAAQ,IAAI,kBAAkB,MAAM,EAAE,IAAI,MAAM,CAAC;AAClE,aAAO,EAAE,KAAK,MAAM,aAAa,SAAS,YAAY,GAAG,CAAC;AAAA,IAC5D,CAAC;AACD,QAAI,IAAI,gBAAgB,OAAO,MAAM,EAAE,KAAK,MAAM,QAAQ,OAAO,CAAC,CAAC;AACnE,QAAI,KAAK,sBAAsB,OAAO,MAAM;AAC1C,YAAM,QAAQ,EACX,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,SAAS,EAAE,CAAC,EACtD,OAAO,EACP,MAAM,MAAM,EAAE,IAAI,KAAK,CAAC;AAC3B,aAAO,EAAE,KAAK,MAAM,QAAQ,MAAM,MAAM,OAAO,CAAC;AAAA,IAClD,CAAC;AACD,QAAI;AAAA,MAAK;AAAA,MAAyB,OAAO,MACvC,EAAE,KAAK,MAAM,QAAQ,UAAU,eAAe,MAAM,MAAM,EAAE,IAAI,KAAK,CAAC,CAAC,CAAC;AAAA,IAC1E;AACA,QAAI;AAAA,MAAK;AAAA,MAAoB,OAAO,MAClC,EAAE,KAAK,MAAM,QAAQ,MAAM,oBAAoB,MAAM,MAAM,EAAE,IAAI,KAAK,CAAC,CAAC,GAAG,GAAG;AAAA,IAChF;AAAA,EACF;AACA,QAAM,KAAK,CAAC,UAAkB,QAAQ,SAAS,MAAM,KAAK;AAC1D,QAAM,QAAQ,OACZ,GACA,WACe;AACf,UAAM,QAAiB,MAAM,EAAE,IAAI,KAAK;AACxC,QACE,SACA,OAAO,UAAU,YACjB,uBAAuB,SACvB,OAAO,MAAM,sBAAsB;AAEnC,QAAE,IAAI,eAAe,MAAM,iBAAiB;AAC9C,WAAO,OAAO,MAAM,KAAK;AAAA,EAC3B;AACA,QAAM,SAAS,CAAC,OACd,GAAG,WAAW,iBAAiB,GAAG,WAAW,aAAc,MAAiB;AAC9E,QAAM,gBAAgB,IAAI,YAAY,MAAM;AAC5C,MAAI,IAAI,qBAAqB,CAAC,MAAM;AAClC,UAAM,QAAQ,EACX,OAAO;AAAA,MACN,MAAM,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE,QAAQ,EAAE;AAAA,MACrC,WAAW,EACR,OAAO,EACP,IAAI,GAAG,EACP,OAAO,CAAC,UAAU,CAAC,UAAU,KAAK,KAAK,KAAK,UAAU,OAAO,UAAU,IAAI,EAC3E,SAAS;AAAA,IACd,CAAC,EACA,MAAM,EAAE,MAAM,EAAE,IAAI,MAAM,MAAM,GAAG,WAAW,EAAE,IAAI,MAAM,WAAW,EAAE,CAAC;AAC3E,WAAO,EAAE,KAAK,mBAAmB,MAAM,KAAK,KAAK,GAAG,cAAc,SAAS,MAAM,SAAS,CAAC;AAAA,EAC7F,CAAC;AACD,MAAI,IAAI,gBAAgB,OAAO,GAAG,SAAS;AACzC,MAAE,OAAO,iBAAiB,UAAU;AACpC,UAAM,KAAK;AAAA,EACb,CAAC;AACD,MAAI,IAAI,eAAe,OAAO,MAAM,EAAE,KAAK,MAAM,cAAc,SAAS,CAAC,CAAC;AAC1E,MAAI,KAAK,eAAe,OAAO,MAAM,EAAE,KAAK,MAAM,cAAc,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,CAAC,CAAC;AACzF,MAAI;AAAA,IAAK;AAAA,IAAsB,OAAO,MACpC,EAAE,KAAK,MAAM,cAAc,cAAc,MAAM,EAAE,IAAI,KAAK,CAAC,CAAC;AAAA,EAC9D;AACA,MAAI,IAAI,sBAAsB,OAAO,MAAM;AACzC,MAAE,OAAO,uBAAuB,8CAA8C;AAC9E,WAAO,EAAE,KAAK,MAAM,cAAc,OAAO,CAAC;AAAA,EAC5C,CAAC;AACD,MAAI,IAAI,8BAA8B,OAAO,MAAM;AACjD,UAAM,WAAW,EAAE,IAAI,UAAU;AACjC,QAAI,OAAO,KAAK,SAAS,WAAW,CAAC,SAAS;AAC5C,YAAM,IAAI,SAAS,mBAAmB,gEAAc,GAAG;AACzD,UAAM,WAAW,MAAM,QAAQ,aAAa;AAG5C,UAAM,QAAQ,WAAW,QAAQ,EAC9B;AAAA,MACC,KAAK,UAAU;AAAA,QACb,QAAQ,OAAO;AAAA,QACf,QAAQ,UAAU,EAAE;AAAA,QACpB,OAAO,KAAK;AAAA,QACZ,SAAS,WAAW;AAAA,QACpB,SAAS,IAAI,CAAC,YAAY,CAAC,QAAQ,IAAI,QAAQ,UAAU,QAAQ,SAAS,CAAC;AAAA,MAC7E,CAAC;AAAA,IACH,EACC,OAAO,KAAK;AACf,WAAO,EAAE,KAAK,EAAE,MAAM,CAAC;AAAA,EACzB,CAAC;AACD,MAAI,IAAI,eAAe,CAAC,MAAM,EAAE,KAAK,QAAQ,UAAU,CAAC,CAAC;AACzD,MAAI;AAAA,IAAI;AAAA,IAAc,CAAC,MACrB,EAAE;AAAA,MACA,QAAQ,MAAM;AAAA,QACZ,EAAE,IAAI,MAAM,OAAO;AAAA,QACnB,EAAE,OACC,OAAO,EACP,IAAI,EACJ,IAAI,CAAC,EACL,IAAI,OAAO,gBAAgB,EAC3B,QAAQ,CAAC,EACT,MAAM,EAAE,IAAI,MAAM,OAAO,CAAC;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AACA,MAAI,KAAK,kCAAkC,OAAO,MAAM;AACtD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,WAAW,CAAC;AAAA,MAC3B,MAAM,MAAM,GAAG,gBAAgB;AAAA,IACjC;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,mCAAmC,OAAO,MAAM;AACvD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,WAAW,CAAC;AAAA,MAC3B,MAAM,MAAM,GAAG,QAAQ,eAAe;AAAA,IACxC;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,qCAAqC,OAAO,MAAM;AACzD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,MAAM,MAAM,GAAG,QAAQ,0BAA0B;AAAA,IACnD;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,IAAI,iBAAiB,OAAO,MAAM,EAAE,KAAK,EAAE,MAAM,MAAM,QAAQ,aAAa,EAAE,CAAC,CAAC;AACpF,MAAI;AAAA,IAAI;AAAA,IAA8C,OAAO,MAC3D,EAAE,KAAK,MAAM,QAAQ,2BAA2B,GAAG,EAAE,IAAI,MAAM,WAAW,CAAC,CAAC,CAAC;AAAA,EAC/E;AACA,MAAI;AAAA,IAAI;AAAA,IAA4C,OAAO,MACzD,EAAE,KAAK,MAAM,QAAQ,0BAA0B,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,CAAC,CAAC;AAAA,EAC7E;AACA,MAAI;AAAA,IAAI;AAAA,IAAoC,OAAO,MACjD,EAAE,KAAK,MAAM,QAAQ,oBAAoB,IAAI,CAAC;AAAA,EAChD;AACA,MAAI,KAAK,kCAAkC,OAAO,MAAM;AACtD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB;AAAA,MACA,MAAM,MAAM,GAAG,QAAQ,uBAAuB;AAAA,IAChD;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI;AAAA,IAAI;AAAA,IAA2B,OAAO,MACxC,EAAE;AAAA,MACA,MAAM,QAAQ;AAAA,QACZ;AAAA,QACA,EAAE,IAAI,MAAM,QAAQ,MAAM,SACtB,SACA,QAAQ,aAAa,MAAM,EAAE,IAAI,MAAM,QAAQ,CAAC;AAAA,QACpD,QAAQ,oBAAoB,MAAM,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC3D;AAAA,IACF;AAAA,EACF;AACA,MAAI,KAAK,2BAA2B,OAAO,MAAM;AAC/C,UAAM,KAAK,MAAM,QAAQ,aAAa,MAAM,MAAM,MAAM,GAAG,QAAQ,kBAAkB,CAAC;AACtF,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI;AAAA,IAAK;AAAA,IAAuB,OAAO,MACrC,EAAE;AAAA,MACA,QAAQ;AAAA,QAAa,MAAM,MAAM,GAAG,QAAQ,kBAAkB;AAAA,QAAG,CAAC,SAChE,mBAAmB,MAAM,cAAc,OAAO;AAAA,MAChD;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,MAAI;AAAA,IAAI;AAAA,IAAgC,CAAC,MACvC,EAAE,KAAK,QAAQ,cAAc,IAAI,GAAG,EAAE,IAAI,MAAM,SAAS,CAAC,CAAC,CAAC;AAAA,EAC9D;AACA,MAAI,KAAK,uCAAuC,OAAO,MAAM;AAC3D,UAAM,MAAM,GAAG,QAAQ,mBAAmB;AAC1C,WAAO,EAAE,KAAK,QAAQ,cAAc,OAAO,GAAG,EAAE,IAAI,MAAM,SAAS,CAAC,CAAC,CAAC;AAAA,EACxE,CAAC;AACD,MAAI,KAAK,yCAAyC,OAAO,MAAM;AAC7D,UAAM,MAAM,GAAG,QAAQ,mBAAmB;AAC1C,WAAO,EAAE,KAAK,QAAQ,cAAc,kBAAkB,GAAG,EAAE,IAAI,MAAM,SAAS,CAAC,CAAC,CAAC;AAAA,EACnF,CAAC;AACD,MAAI;AAAA,IAAK;AAAA,IAAyB,OAAO,MACvC,EAAE,KAAK,QAAQ,gBAAgB,MAAM,MAAM,GAAG,QAAQ,qBAAqB,CAAC,CAAC;AAAA,EAC/E;AACA,MAAI;AAAA,IAAI;AAAA,IAA6C,OAAO,MAC1D,EAAE,KAAK,MAAM,QAAQ,oBAAoB,GAAG,EAAE,IAAI,MAAM,WAAW,CAAC,CAAC,CAAC;AAAA,EACxE;AACA,MAAI,KAAK,2CAA2C,OAAO,MAAM;AAC/D,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,WAAW,CAAC;AAAA,MAC3B,MAAM,MAAM,GAAG,QAAQ,uBAAuB;AAAA,IAChD;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,iBAAiB,OAAO,MAAM;AACrC,UAAM,QAAQ,MAAM,MAAM,GAAG,QAAQ,mBAAmB;AACxD,WAAO,EAAE;AAAA,MACP,QAAQ,WAAW,EAAE,GAAG,OAAO,MAAM,mBAAmB,MAAM,MAAM,cAAc,OAAO,EAAE,CAAC;AAAA,IAC9F;AAAA,EACF,CAAC;AACD,MAAI;AAAA,IAAK;AAAA,IAAmC,OAAO,MACjD,EAAE;AAAA,MACA,QAAQ;AAAA,QACN,GAAG,EAAE,IAAI,MAAM,WAAW,CAAC;AAAA,QAC3B,MAAM,MAAM,GAAG,QAAQ,mBAAmB;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AACA,MAAI,KAAK,mCAAmC,OAAO,MAAM;AACvD,UAAM,MAAM,GAAG,QAAQ,mBAAmB;AAC1C,WAAO,EAAE,KAAK,QAAQ,cAAc,GAAG,EAAE,IAAI,MAAM,WAAW,CAAC,CAAC,CAAC;AAAA,EACnE,CAAC;AACD,MAAI;AAAA,IAAI;AAAA,IAAoC,OAAO,MACjD,EAAE;AAAA,MACA,MAAM,QAAQ;AAAA,QACZ,GAAG,EAAE,IAAI,MAAM,WAAW,CAAC;AAAA,QAC3B,EAAE,IAAI,MAAM,QAAQ,MAAM,SACtB,SACA,QAAQ,aAAa,MAAM,EAAE,IAAI,MAAM,QAAQ,CAAC;AAAA,QACpD,QAAQ,oBAAoB,MAAM,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC3D;AAAA,IACF;AAAA,EACF;AACA,MAAI;AAAA,IAAI;AAAA,IAAgB,OAAO,MAC7B,EAAE;AAAA,MACA,MAAM,QAAQ;AAAA,QACZ,GAAG,EAAE,IAAI,MAAM,WAAW,KAAK,EAAE;AAAA,QACjC,EAAE,IAAI,MAAM,QAAQ,MAAM,SACtB,SACA,QAAQ,aAAa,MAAM,EAAE,IAAI,MAAM,QAAQ,CAAC;AAAA,QACpD,QAAQ,oBAAoB,MAAM,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC3D;AAAA,IACF;AAAA,EACF;AACA,MAAI,KAAK,kCAAkC,OAAO,MAAM;AACtD,WAAO,EAAE;AAAA,MACP,MAAM,QAAQ;AAAA,QACZ,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,QAC1B,MAAM,MAAM,GAAG,QAAQ,mBAAmB;AAAA,MAC5C;AAAA,IACF;AAAA,EACF,CAAC;AACD,MAAI;AAAA,IAAI;AAAA,IAA0B,OAAO,MACvC,EAAE,KAAK,MAAM,QAAQ,UAAU,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,CAAC,CAAC;AAAA,EAC7D;AACA,MAAI;AAAA,IAAI;AAAA,IAAkC,OAAO,MAC/C,EAAE,KAAK,MAAM,QAAQ,iBAAiB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,GAAG,EAAE,IAAI,MAAM,QAAQ,CAAC,CAAC;AAAA,EAC3F;AACA,MAAI;AAAA,IAAI;AAAA,IAAoC,CAAC,MAC3C,EAAE,KAAK,QAAQ,mBAAmB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,CAAC,CAAC;AAAA,EAChE;AACA,MAAI;AAAA,IAAI;AAAA,IAAmC,OAAO,MAChD,EAAE,KAAK,MAAM,QAAQ,kBAAkB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,CAAC,CAAC;AAAA,EACrE;AACA,MAAI,IAAI,iCAAiC,OAAO,MAAM;AACpD,UAAM,WAAW,MAAM,QAAQ,aAAa,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,CAAC;AACvE,MAAE,OAAO,gBAAgB,8BAA8B;AACvD,MAAE,OAAO,uBAAuB,yBAAyB,SAAS,QAAQ,GAAG;AAC7E,MAAE,OAAO,iBAAiB,UAAU;AACpC,MAAE,OAAO,0BAA0B,SAAS;AAC5C,MAAE,OAAO,yBAAyB,SAAS,UAAU,YAAY,eAAe;AAChF,WAAO,EAAE,KAAK,SAAS,QAAQ;AAAA,EACjC,CAAC;AACD,MAAI,IAAI,iCAAiC,OAAO,MAAM;AACpD,MAAE,OAAO,iBAAiB,mBAAmB;AAC7C,MAAE,OAAO,0BAA0B,SAAS;AAC5C,MAAE,OAAO,gCAAgC,aAAa;AACtD,MAAE,OAAO,2BAA2B,6BAA6B;AACjE,UAAM,QAAQ,MAAM,QAAQ,eAAe,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,GAAG,EAAE,IAAI,MAAM,MAAM,CAAC;AAE3F,UAAM,OAAO,IAAI,WAAW,QAAQ,EAAE,OAAO,MAAM,KAAK,EAAE,OAAO,KAAK,CAAC;AACvE,MAAE,OAAO,iBAAiB,mBAAmB;AAC7C,MAAE,OAAO,QAAQ,IAAI;AACrB,UAAM,cAAc,EAAE,IAAI,OAAO,eAAe;AAChD,QACE,gBAAgB,OAChB,aAAa,MAAM,GAAG,EAAE,KAAK,CAAC,QAAQ,IAAI,KAAK,EAAE,QAAQ,QAAQ,EAAE,MAAM,IAAI;AAE7E,aAAO,EAAE,KAAK,MAAM,GAAG;AACzB,WAAO,EAAE,KAAK,MAAM,OAAO,KAAK;AAAA,MAC9B,gBAAgB,MAAM;AAAA,MACtB,kBAAkB,OAAO,MAAM,MAAM,MAAM;AAAA,IAC7C,CAAC;AAAA,EACH,CAAC;AACD,MAAI,IAAI,mCAAmC,OAAO,MAAM;AACtD,MAAE,OAAO,iBAAiB,mBAAmB;AAC7C,MAAE,OAAO,0BAA0B,SAAS;AAC5C,MAAE,OAAO,gCAAgC,aAAa;AACtD,WAAO,EAAE;AAAA,MACP,MAAM,QAAQ,kBAAkB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,GAAG,EAAE,IAAI,MAAM,MAAM,CAAC;AAAA,IAClF;AAAA,EACF,CAAC;AACD,MAAI,IAAI,+BAA+B,OAAO,MAAM;AAClD,MAAE,OAAO,iBAAiB,mBAAmB;AAC7C,MAAE,OAAO,0BAA0B,SAAS;AAC5C,MAAE,OAAO,gCAAgC,aAAa;AACtD,WAAO,EAAE,KAAK,MAAM,QAAQ,cAAc,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,GAAG,EAAE,IAAI,MAAM,MAAM,CAAC,CAAC;AAAA,EAC7F,CAAC;AACD,MAAI,IAAI,+BAA+B,OAAO,MAAM;AAClD,MAAE,OAAO,iBAAiB,mBAAmB;AAC7C,MAAE,OAAO,0BAA0B,SAAS;AAC5C,MAAE,OAAO,gCAAgC,aAAa;AACtD,WAAO,EAAE,KAAK,MAAM,QAAQ,cAAc,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,GAAG,EAAE,IAAI,MAAM,MAAM,CAAC,CAAC;AAAA,EAC7F,CAAC;AACD,MAAI;AAAA,IAAI;AAAA,IAAgC,CAAC,MACvC,EAAE,KAAK,QAAQ,aAAa,GAAG,EAAE,IAAI,MAAM,aAAa,CAAC,CAAC,CAAC;AAAA,EAC7D;AACA,MAAI,KAAK,oCAAoC,OAAO,MAAM;AACxD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,WAAW,CAAC;AAAA,MAC3B,MAAM,MAAM,GAAG,QAAQ,kBAAkB;AAAA,IAC3C;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,iCAAiC,OAAO,MAAM;AACrD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,kBAAkB;AAAA,IAC3C;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,+BAA+B,OAAO,MAAM;AACnD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,gBAAgB;AAAA,IACzC;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,iCAAiC,OAAO,MAAM;AACrD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,kBAAkB;AAAA,IAC3C;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,gCAAgC,OAAO,MAAM;AACpD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,eAAe;AAAA,IACxC;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,iCAAiC,OAAO,MAAM;AACrD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,iBAAiB;AAAA,IAC1C;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,gCAAgC,OAAO,MAAM;AACpD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,WAAW;AAAA,IACpC;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,kCAAkC,OAAO,MAAM;AACtD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,eAAe;AAAA,IACxC;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,oCAAoC,OAAO,MAAM;AACxD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,eAAe;AAAA,IACxC;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,kCAAkC,OAAO,MAAM;AACtD,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC;AAAA,MAC1B,MAAM,MAAM,GAAG,QAAQ,mBAAmB;AAAA,IAC5C;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI,KAAK,0CAA0C,OAAO,MAAM;AAC9D,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,GAAG,EAAE,IAAI,MAAM,aAAa,CAAC;AAAA,MAC7B,MAAM,MAAM,GAAG,QAAQ,eAAe;AAAA,IACxC;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI;AAAA,IACF;AAAA,IACA;AAAA,MAAiB,CAAC,MAChB,eAAe,SAAS,QAAQ,EAAE,IAAI,UAAU,GAAG,EAAE,IAAI,MAAM,UAAU,MAAM,GAAG;AAAA,IACpF;AAAA,EACF;AACA,MAAI,IAAI,UAAU,MAAM;AACtB,UAAM,IAAI,SAAS,aAAa,uBAAuB,GAAG;AAAA,EAC5D,CAAC;AACD,MAAI,IAAI,QAAQ,MAAM;AACpB,UAAM,IAAI,SAAS,aAAa,uBAAuB,GAAG;AAAA,EAC5D,CAAC;AACD,MAAI,IAAI,SAAS,MAAM;AACrB,UAAM,IAAI,SAAS,aAAa,6BAA6B,GAAG;AAAA,EAClE,CAAC;AACD,MAAI,IAAI,KAAK,OAAO,GAAG,SAAS;AAC9B,QAAI,CAAC,EAAE,IAAI,KAAK,WAAW,UAAU,EAAG,GAAE,OAAO,iBAAiB,UAAU;AAC5E,MAAE,OAAO,0BAA0B,SAAS;AAC5C,MAAE,OAAO,mBAAmB,aAAa;AACzC,MAAE;AAAA,MACA;AAAA;AAAA;AAAA,MAGA;AAAA,IACF;AACA,UAAM,KAAK;AAAA,EACb,CAAC;AACD,MAAI,IAAI,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC,CAAC;AAC7C,MAAI,IAAI,KAAK,OAAO,GAAG,SAAS;AAC9B,QAAI,CAAC,EAAE,IAAI,OAAO,QAAQ,GAAG,SAAS,WAAW,KAAK,WAAW,KAAK,EAAE,IAAI,IAAI;AAC9E,aAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,SAAS,qBAAqB,EAAE,GAAG,GAAG;AACpF,WAAO,YAAY,EAAE,MAAM,GAAG,SAAS,cAAc,CAAC,EAAE,GAAG,IAAI;AAAA,EACjE,CAAC;AACD,MAAI,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,SAAS,qBAAqB,EAAE,GAAG,GAAG,CAAC;AAChG,SAAO;AACT;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/server/service.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { attentionKey, pendingAttention } from "../shared/thread-attention.js";
|
|
2
2
|
import { ShellService } from "./shell.js";
|
|
3
|
+
import { readGithubRepository } from "./github-repository.js";
|
|
3
4
|
import { realpathSync } from "node:fs";
|
|
4
5
|
import { cp } from "node:fs/promises";
|
|
5
6
|
import { WorkspaceRegistry } from "./workspaces.js";
|
|
@@ -88,6 +89,23 @@ class GatewayService {
|
|
|
88
89
|
listProjects() {
|
|
89
90
|
return this.projects.list();
|
|
90
91
|
}
|
|
92
|
+
async getProjectGithubRepository(projectId) {
|
|
93
|
+
const project = this.projects.get(projectId);
|
|
94
|
+
const url = await readGithubRepository(project.canonicalRoot);
|
|
95
|
+
this.projects.get(projectId);
|
|
96
|
+
return { url };
|
|
97
|
+
}
|
|
98
|
+
async getThreadGithubRepository(threadId) {
|
|
99
|
+
let link = this.store.getThreadLink(threadId);
|
|
100
|
+
if (!link) {
|
|
101
|
+
this.normalize(await this.codex.readThreadMetadata(threadId));
|
|
102
|
+
link = this.store.getThreadLink(threadId);
|
|
103
|
+
}
|
|
104
|
+
const { cwd } = this.workspaces.assertOwnership(link.projectId, link.cwd, threadId);
|
|
105
|
+
const url = await readGithubRepository(cwd);
|
|
106
|
+
this.workspaces.assertOwnership(link.projectId, link.cwd, threadId);
|
|
107
|
+
return { url };
|
|
108
|
+
}
|
|
91
109
|
startShell(projectId, input) {
|
|
92
110
|
return this.perform("shell.start", projectId, input, async () => {
|
|
93
111
|
this.ensureCompatibilityConfirmed();
|