@covro/covro 0.6.1-dev.1 → 0.7.0-beta.1
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 +1 -1
- package/README.zh-CN.md +1 -1
- package/dist/server/events.js +20 -3
- package/dist/server/events.js.map +2 -2
- package/dist/server/http.js +4 -0
- package/dist/server/http.js.map +2 -2
- package/dist/server/service.js +21 -11
- package/dist/server/service.js.map +2 -2
- package/dist/server/thread-patch.js +58 -0
- package/dist/server/thread-patch.js.map +7 -0
- package/dist/server/websocket.js +14 -1
- package/dist/server/websocket.js.map +2 -2
- package/dist/shared/thread-patch.js +38 -0
- package/dist/shared/thread-patch.js.map +7 -0
- package/dist/shared/validation.js +1 -0
- package/dist/shared/validation.js.map +2 -2
- package/dist/web/assets/{abnfDiagram-WEYOIA3C-12kbP4fE.js → abnfDiagram-WEYOIA3C-DPrSyxx5.js} +1 -1
- package/dist/web/assets/{arc-3Cwtj2dL.js → arc-4B8zsDlv.js} +1 -1
- package/dist/web/assets/{architecture-WOLXFQ4H-DLpj2b3w.js → architecture-WOLXFQ4H-DzDNYcvm.js} +1 -1
- package/dist/web/assets/{architectureDiagram-ZHVYKT53-RlF4-Ioc.js → architectureDiagram-ZHVYKT53-CJ9tt7RD.js} +1 -1
- package/dist/web/assets/{blockDiagram-RJAE7QA3-C4qOX-bt.js → blockDiagram-RJAE7QA3-C9ljbm6J.js} +1 -1
- package/dist/web/assets/{c4Diagram-XDPPPE54-D7JMbo-C.js → c4Diagram-XDPPPE54-Sd9QMUQp.js} +1 -1
- package/dist/web/assets/channel-DKYuZv8c.js +1 -0
- package/dist/web/assets/{chunk-2E7WHVMD-IDKX-Tea.js → chunk-2E7WHVMD-DsUWsTrf.js} +1 -1
- package/dist/web/assets/{chunk-4EMNKR2T-Dc-yhxET.js → chunk-4EMNKR2T-Bh91FySB.js} +1 -1
- package/dist/web/assets/{chunk-55XCU76K-CGd2UwoZ.js → chunk-55XCU76K-BRxH4G9N.js} +1 -1
- package/dist/web/assets/{chunk-7S6XSTFO-BvKa88G4.js → chunk-7S6XSTFO-DbTYm4kS.js} +1 -1
- package/dist/web/assets/{chunk-AQDTSKZB-C7nMX4W-.js → chunk-AQDTSKZB-D1NiDG4T.js} +1 -1
- package/dist/web/assets/{chunk-DSNLSHJZ-BzJy_vEu.js → chunk-DSNLSHJZ-C0LQPoI8.js} +1 -1
- package/dist/web/assets/{chunk-HAGFOTED-r9b5k0Ex.js → chunk-HAGFOTED-DRrIOJjB.js} +1 -1
- package/dist/web/assets/{chunk-HNE4Q36P-DQoXCaGC.js → chunk-HNE4Q36P-Bok-UYL9.js} +1 -1
- package/dist/web/assets/{chunk-NQOKRVIF-1bL6YAHF.js → chunk-NQOKRVIF-D1zmT8gY.js} +1 -1
- package/dist/web/assets/{chunk-UHW7PFBP-psrTYP5z.js → chunk-UHW7PFBP-BDwjuCRk.js} +1 -1
- package/dist/web/assets/{chunk-VQ5W62QI-E2m7QCpn.js → chunk-VQ5W62QI-DAHWoS2u.js} +1 -1
- package/dist/web/assets/{chunk-WQQL4CDK-Y328jV78.js → chunk-WQQL4CDK-ggfsBWta.js} +1 -1
- package/dist/web/assets/{chunk-XXDRQBXY-D4uat8z8.js → chunk-XXDRQBXY-DBRGTT6L.js} +1 -1
- package/dist/web/assets/{chunk-YZO67HFG-C5FacS0u.js → chunk-YZO67HFG-BCM-hzbV.js} +1 -1
- package/dist/web/assets/{chunk-ZAUX2LTX-lmxyuzUz.js → chunk-ZAUX2LTX-MnMFUU_S.js} +1 -1
- package/dist/web/assets/{chunk-ZCHMQSOR-B-eLKLDi.js → chunk-ZCHMQSOR-ClT-_dGN.js} +1 -1
- package/dist/web/assets/{classDiagram-v2-4MYWR3UA-ClhXABmk.js → classDiagram-v2-4MYWR3UA-CPV9IWEk.js} +1 -1
- package/dist/web/assets/{cose-bilkent-JH36ORCC-BwPkaA_U.js → cose-bilkent-JH36ORCC-DqgOWzoX.js} +1 -1
- package/dist/web/assets/{cynefin-EF2NZ3EQ-Bsl3oI8o.js → cynefin-EF2NZ3EQ-Dkit62ND.js} +1 -1
- package/dist/web/assets/{cynefinDiagram-WF24UDRP-ap8wP3TK.js → cynefinDiagram-WF24UDRP-DSiF7XN6.js} +1 -1
- package/dist/web/assets/{dagre-NK4GIZVX-D93ljWDv.js → dagre-NK4GIZVX-DPMP_fYv.js} +1 -1
- package/dist/web/assets/{diagram-CBK3MWTC-CgXKZEzJ.js → diagram-CBK3MWTC-CyMSNHt0.js} +1 -1
- package/dist/web/assets/{diagram-I5XIIV2D-Ce32mo7i.js → diagram-I5XIIV2D-tQ2bMi8B.js} +1 -1
- package/dist/web/assets/{diagram-ODIL2UCW-WM-FVzky.js → diagram-ODIL2UCW-BGZKonG-.js} +1 -1
- package/dist/web/assets/{diagram-PFBEJUXE-4gCFo57A.js → diagram-PFBEJUXE-ChscR483.js} +1 -1
- package/dist/web/assets/{diagram-RJA3I4VV-BsUVCONT.js → diagram-RJA3I4VV-frBsA7DX.js} +1 -1
- package/dist/web/assets/{diagram-TYUNFSNR-CuIasd0o.js → diagram-TYUNFSNR-B8qZBREp.js} +1 -1
- package/dist/web/assets/{dist-DE2aWlVX.js → dist-7U4_LxsV.js} +1 -1
- package/dist/web/assets/{ebnfDiagram-V4P3TTPT-BMFDt5P9.js → ebnfDiagram-V4P3TTPT-CfnjkhXT.js} +1 -1
- package/dist/web/assets/{elk-QONTBCTQ-CbWBnkf9.js → elk-QONTBCTQ-D6KBNmbF.js} +1 -1
- package/dist/web/assets/{erDiagram-KYQIGQAA-BfujTOMs.js → erDiagram-KYQIGQAA-Sx8YaD42.js} +1 -1
- package/dist/web/assets/{eventmodeling-K75KTNOO-D9yPZPJr.js → eventmodeling-K75KTNOO-DgI4Zm6z.js} +1 -1
- package/dist/web/assets/flowDiagram-IUGLLWBU-AdTZW4EM.js +1 -0
- package/dist/web/assets/{ganttDiagram-R7GPNTJY-BQailqpt.js → ganttDiagram-R7GPNTJY-FN9ghlFf.js} +1 -1
- package/dist/web/assets/{gitGraph-VSP46ZUC-Cn0-LfrH.js → gitGraph-VSP46ZUC-B6RMx5nS.js} +1 -1
- package/dist/web/assets/{gitGraphDiagram-PDYL7XHY-D_Bv68A5.js → gitGraphDiagram-PDYL7XHY-BUfDV32d.js} +1 -1
- package/dist/web/assets/{index-B3yair14.js → index-BayHb2le.js} +41 -41
- package/dist/web/assets/{info-OHQRW6UA-C-rFhEgh.js → info-OHQRW6UA-i9U_Vjx9.js} +1 -1
- package/dist/web/assets/{infoDiagram-MVDRKAX5-yWVzvl2L.js → infoDiagram-MVDRKAX5-BcIiBHfp.js} +1 -1
- package/dist/web/assets/{ishikawaDiagram-HPEHV2GE-DFYQOW9-.js → ishikawaDiagram-HPEHV2GE-CBq8uWqz.js} +1 -1
- package/dist/web/assets/{journeyDiagram-BOSHW7O7-B1zy7CA-.js → journeyDiagram-BOSHW7O7-BoH8zvhM.js} +1 -1
- package/dist/web/assets/{kanban-definition-FNSA4HC5-CxyXZtX-.js → kanban-definition-FNSA4HC5-DqWoSu__.js} +1 -1
- package/dist/web/assets/{line-DU2ihvUj.js → line-mJzmbB6p.js} +1 -1
- package/dist/web/assets/{linear-CFRZhmcT.js → linear-BwkmaM-M.js} +1 -1
- package/dist/web/assets/{mermaid-parser.core-DKeYv3x5.js → mermaid-parser.core-DwFqVvpp.js} +3 -3
- package/dist/web/assets/{mermaid.core-D8iJrzMj.js → mermaid.core-DcF8gYr_.js} +4 -4
- package/dist/web/assets/{mindmap-definition-6OY57UG3-CKbrIT8N.js → mindmap-definition-6OY57UG3-D4XGBbWO.js} +1 -1
- package/dist/web/assets/{packet-JDAUHWVQ-B9qYbkxZ.js → packet-JDAUHWVQ-Da_cMCDo.js} +1 -1
- package/dist/web/assets/{pegDiagram-ECIUJNBX-QnJNmnXC.js → pegDiagram-ECIUJNBX-CVgVmFmC.js} +1 -1
- package/dist/web/assets/{pie-XZMESJXO-BWBbsmjp.js → pie-XZMESJXO-7pec9CJT.js} +1 -1
- package/dist/web/assets/{pieDiagram-GNMPY74T-Bubnnbvj.js → pieDiagram-GNMPY74T-97N9EH_E.js} +1 -1
- package/dist/web/assets/{quadrantDiagram-D57K4MC3-Cs_Ch2cN.js → quadrantDiagram-D57K4MC3-FJDGQ0ZC.js} +1 -1
- package/dist/web/assets/{radar-ABXABTNO-DR6emy7T.js → radar-ABXABTNO-DsWXE4id.js} +1 -1
- package/dist/web/assets/{railroad-I3PHUGI6-B0D7AskV.js → railroad-I3PHUGI6-Cs3NR5Rp.js} +1 -1
- package/dist/web/assets/{railroad-abnf-LNEFI6M7-Bz6aNqE_.js → railroad-abnf-LNEFI6M7-fn-KtM-H.js} +1 -1
- package/dist/web/assets/{railroad-ebnf-DWYD2UWJ-D0OpFEED.js → railroad-ebnf-DWYD2UWJ-BuexEj3O.js} +1 -1
- package/dist/web/assets/{railroad-peg-JR7BVNR7-C_NZ01lj.js → railroad-peg-JR7BVNR7-C59VHWhm.js} +1 -1
- package/dist/web/assets/{railroadDiagram-Y72NRBL7-Dj39CKJS.js → railroadDiagram-Y72NRBL7-Dwpn4kqo.js} +1 -1
- package/dist/web/assets/{requirementDiagram-EQYSW5RA-B3LvvxeY.js → requirementDiagram-EQYSW5RA-BE9cDXG8.js} +1 -1
- package/dist/web/assets/{sankeyDiagram-SY24JHO5-DZRJovJs.js → sankeyDiagram-SY24JHO5-BiPoxRoH.js} +1 -1
- package/dist/web/assets/{sequenceDiagram-BLEHNHQU-Cjtr9DEf.js → sequenceDiagram-BLEHNHQU-OHewZwiU.js} +1 -1
- package/dist/web/assets/{src-CiORhf3I.js → src-CAqT2rVv.js} +1 -1
- package/dist/web/assets/{stateDiagram-v2-A6IESKWZ-CRWe83GV.js → stateDiagram-v2-A6IESKWZ-BHul6PGu.js} +1 -1
- package/dist/web/assets/{swimlanes-B3ENRKFQ-Dl64HZAr.js → swimlanes-B3ENRKFQ-BBjoKZII.js} +1 -1
- package/dist/web/assets/swimlanesDiagram-AYQRV4AK-Cp-6Y0VO.js +8 -0
- package/dist/web/assets/{timeline-definition-JXYKGLGB-CNMLxrA1.js → timeline-definition-JXYKGLGB-D7reGFUV.js} +1 -1
- package/dist/web/assets/{treeView-D4JQ5SDB-DJKJS2TK.js → treeView-D4JQ5SDB-BC4PBy2z.js} +1 -1
- package/dist/web/assets/{treemap-SAJKECNS-Bys6-NSp.js → treemap-SAJKECNS-C-L3y3B0.js} +1 -1
- package/dist/web/assets/{usecaseDiagram-WPOLBNNX-tYc1Q8xT.js → usecaseDiagram-WPOLBNNX-DqReWsLT.js} +1 -1
- package/dist/web/assets/{vennDiagram-Q3Y3IDCW-yr790RR-.js → vennDiagram-Q3Y3IDCW-RB21WgMG.js} +1 -1
- package/dist/web/assets/{wardley-7MLQ67FV-d-Le2twL.js → wardley-7MLQ67FV-CAGdvTyZ.js} +1 -1
- package/dist/web/assets/{wardleyDiagram-IVAIDKWA-1Q-unpfn.js → wardleyDiagram-IVAIDKWA-DXN5Mh5B.js} +1 -1
- package/dist/web/assets/{xychartDiagram-4URNHDU4-zofaLTye.js → xychartDiagram-4URNHDU4-Y2Tpnzwb.js} +1 -1
- package/dist/web/index.html +1 -1
- package/package.json +4 -4
- package/dist/web/assets/channel-AXdPKUi0.js +0 -1
- package/dist/web/assets/flowDiagram-IUGLLWBU-DosDBlJM.js +0 -1
- package/dist/web/assets/swimlanesDiagram-AYQRV4AK-Cmp6k7s_.js +0 -8
package/README.md
CHANGED
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
|
|
32
32
|
- 📱 **Follow tasks from any device.** Review changes, handle approvals, and answer questions on desktop or mobile. Tasks keep running when you close the page.
|
|
33
33
|
- 🗂️ **Keep projects and conversations together.** Start without a project, track parallel tasks, and resume or fork your Codex CLI conversations.
|
|
34
|
-
- 📖 **Read results while you chat.** Preview documents, diagrams, and code changes beside the conversation on desktop, or full-screen on mobile.
|
|
34
|
+
- 📖 **Read results while you chat.** Preview documents, diagrams, and code changes beside the conversation on desktop, or full-screen on mobile. Loaded history stays complete as new responses stream in.
|
|
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
37
|
Find controls, shortcuts, and supported commands in the [usage guide · 中文](docs/usage.zh-CN.md) and [command guide](docs/slash-commands.md).
|
package/README.zh-CN.md
CHANGED
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
|
|
32
32
|
- 📱 **随时随地跟进任务。** 用电脑或手机查看改动、处理审批、回答问题。关闭页面,任务仍会继续。
|
|
33
33
|
- 🗂️ **集中管理项目与会话。** 无需项目即可开始任务,在一个工作台查看并行进展,接续或 Fork Codex CLI 会话。
|
|
34
|
-
- 📖 **一边看产出,一边讨论。**
|
|
34
|
+
- 📖 **一边看产出,一边讨论。** 电脑上将文档、图表和代码变更与会话并排阅读,手机上使用全屏阅读器。新回复实时到达时,已加载的历史正文保持完整。
|
|
35
35
|
- 🔔 **及时收到待办提醒。** 开启浏览器通知,在工作结束、需要回答或审批时收到提醒;需在支持通知的桌面浏览器中保持页面运行。
|
|
36
36
|
|
|
37
37
|
操作、快捷键和命令用法见[使用指南](docs/usage.zh-CN.md)与[Slash 命令说明](docs/slash-commands.md)。
|
package/dist/server/events.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { ThreadPatchBuilder } from "./thread-patch.js";
|
|
2
3
|
class EventHub {
|
|
3
4
|
constructor(maxBytes = 16 * 1024 * 1024) {
|
|
4
5
|
this.maxBytes = maxBytes;
|
|
@@ -12,6 +13,7 @@ class EventHub {
|
|
|
12
13
|
listeners = /* @__PURE__ */ new Set();
|
|
13
14
|
runtimeListeners = /* @__PURE__ */ new Set();
|
|
14
15
|
overviewListeners = /* @__PURE__ */ new Set();
|
|
16
|
+
threadPatches = /* @__PURE__ */ new Map();
|
|
15
17
|
cursor() {
|
|
16
18
|
return { serverEpoch: this.serverEpoch, seq: this.seq };
|
|
17
19
|
}
|
|
@@ -43,6 +45,14 @@ class EventHub {
|
|
|
43
45
|
this.runtimeListeners.delete(send);
|
|
44
46
|
};
|
|
45
47
|
}
|
|
48
|
+
publishThread(thread, streamed) {
|
|
49
|
+
let builder = this.threadPatches.get(thread.id);
|
|
50
|
+
if (!builder) {
|
|
51
|
+
builder = new ThreadPatchBuilder();
|
|
52
|
+
this.threadPatches.set(thread.id, builder);
|
|
53
|
+
}
|
|
54
|
+
this.publish("threadPatch", builder.build(thread, streamed), thread.id);
|
|
55
|
+
}
|
|
46
56
|
/** Overview is recovered via HTTP; it never consumes the detailed replay buffer. */
|
|
47
57
|
publishSummary(summary) {
|
|
48
58
|
const event = {
|
|
@@ -91,7 +101,7 @@ class EventHub {
|
|
|
91
101
|
};
|
|
92
102
|
for (const listener of this.overviewListeners) this.deliver(listener, event);
|
|
93
103
|
}
|
|
94
|
-
subscribe(threadId, snapshot, after, send) {
|
|
104
|
+
subscribe(threadId, snapshot, after, send, incremental = false) {
|
|
95
105
|
const replayable = after?.serverEpoch === this.serverEpoch && after.seq >= this.discardedThrough && after.seq <= this.seq;
|
|
96
106
|
const queued = [];
|
|
97
107
|
let initializing = true;
|
|
@@ -109,9 +119,16 @@ class EventHub {
|
|
|
109
119
|
if (event.cursor.seq > after.seq && event.cursor.seq <= boundary && (!event.threadId || event.threadId === threadId))
|
|
110
120
|
this.deliver(send, event);
|
|
111
121
|
} else {
|
|
112
|
-
const data = structuredClone(snapshot());
|
|
113
122
|
boundary = this.seq;
|
|
114
|
-
this.deliver(
|
|
123
|
+
this.deliver(
|
|
124
|
+
send,
|
|
125
|
+
incremental ? { type: "resync", cursor: this.cursor(), threadId } : {
|
|
126
|
+
type: "snapshot",
|
|
127
|
+
cursor: this.cursor(),
|
|
128
|
+
threadId,
|
|
129
|
+
data: structuredClone(snapshot())
|
|
130
|
+
}
|
|
131
|
+
);
|
|
115
132
|
}
|
|
116
133
|
initializing = false;
|
|
117
134
|
for (const message of queued)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/server/events.ts"],
|
|
4
|
-
"sourcesContent": ["import { randomUUID } from 'node:crypto';\nimport type {\n Cursor,\n Operation,\n Project,\n ServerMessage,\n SystemInfo,\n ThreadSummary,\n ThreadView,\n TurnCompletion,\n AttentionRequest,\n} from '../shared/types.js';\n\ntype BusinessEvent = Extract<ServerMessage, { type: 'event' }>;\ntype Listener = (message: ServerMessage) => void;\n\n/** Synchronous snapshot+subscription forms one JS event-loop boundary. */\nexport class EventHub {\n readonly serverEpoch = randomUUID();\n private seq = 0;\n private discardedThrough = 0;\n private bytes = 0;\n private readonly events: { event: BusinessEvent; bytes: number }[] = [];\n private readonly listeners = new Set<{ threadId: string; send: Listener }>();\n private readonly runtimeListeners = new Set<Listener>();\n private readonly overviewListeners = new Set<Listener>();\n\n constructor(private readonly maxBytes = 16 * 1024 * 1024) {}\n\n cursor(): Cursor {\n return { serverEpoch: this.serverEpoch, seq: this.seq };\n }\n\n publish(\n kind: 'thread' | 'runtime' | 'operation',\n payload: ThreadView | SystemInfo | Operation,\n threadId?: string,\n ): void {\n const event: BusinessEvent = {\n type: 'event',\n cursor: { serverEpoch: this.serverEpoch, seq: ++this.seq },\n kind,\n payload: structuredClone(payload),\n ...(threadId === undefined ? {} : { threadId }),\n };\n const bytes = Buffer.byteLength(JSON.stringify(event));\n this.events.push({ event, bytes });\n this.bytes += bytes;\n while (this.bytes > this.maxBytes && this.events.length > 0) {\n const removed = this.events.shift()!;\n this.bytes -= removed.bytes;\n this.discardedThrough = removed.event.cursor.seq;\n }\n for (const listener of this.listeners)\n if (!event.threadId || event.threadId === listener.threadId)\n this.deliver(listener.send, event);\n if (kind === 'runtime')\n for (const listener of this.runtimeListeners) this.deliver(listener, event);\n }\n\n subscribeRuntime(send: Listener): () => void {\n this.runtimeListeners.add(send);\n return () => {\n this.runtimeListeners.delete(send);\n };\n }\n\n /** Overview is recovered via HTTP; it never consumes the detailed replay buffer. */\n publishSummary(summary: ThreadSummary): void {\n const event: BusinessEvent = {\n type: 'event',\n kind: 'threadSummary',\n threadId: summary.id,\n cursor: this.cursor(),\n payload: structuredClone(summary),\n };\n for (const listener of this.overviewListeners) this.deliver(listener, event);\n }\n\n subscribeOverview(send: Listener): () => void {\n this.overviewListeners.add(send);\n return () => {\n this.overviewListeners.delete(send);\n };\n }\n\n /** Only connected overview clients receive this signal. It never enters the replay buffer. */\n publishCompletion(completion: TurnCompletion): void {\n const event: BusinessEvent = {\n type: 'event',\n kind: 'turnCompletion',\n threadId: completion.threadId,\n cursor: this.cursor(),\n payload: structuredClone(completion),\n };\n for (const listener of this.overviewListeners) this.deliver(listener, event);\n }\n\n publishAttention(request: AttentionRequest): void {\n const event: BusinessEvent = {\n type: 'event',\n kind: 'attentionRequest',\n threadId: request.threadId,\n cursor: this.cursor(),\n payload: structuredClone(request),\n };\n for (const listener of this.overviewListeners) this.deliver(listener, event);\n }\n\n /** Project snapshots have their own update boundary even without a thread event. */\n publishProjects(projects: Project[]): void {\n const event: BusinessEvent = {\n type: 'event',\n kind: 'projects',\n cursor: { serverEpoch: this.serverEpoch, seq: ++this.seq },\n payload: structuredClone(projects),\n };\n for (const listener of this.overviewListeners) this.deliver(listener, event);\n }\n\n subscribe(\n threadId: string,\n snapshot: () => ThreadView,\n after: Cursor | undefined,\n send: Listener,\n ): () => void {\n const replayable =\n after?.serverEpoch === this.serverEpoch &&\n after.seq >= this.discardedThrough &&\n after.seq <= this.seq;\n const queued: ServerMessage[] = [];\n let initializing = true;\n const listener = {\n threadId,\n send: (message: ServerMessage) => {\n if (initializing) queued.push(message);\n else send(message);\n },\n };\n this.listeners.add(listener);\n // No await may occur between reading the snapshot and registering the listener.\n let boundary = this.seq;\n if (replayable && after) {\n for (const { event } of [...this.events])\n if (\n event.cursor.seq > after.seq &&\n event.cursor.seq <= boundary &&\n (!event.threadId || event.threadId === threadId)\n )\n this.deliver(send, event);\n } else {\n
|
|
5
|
-
"mappings": "AAAA,SAAS,kBAAkB;
|
|
4
|
+
"sourcesContent": ["import { randomUUID } from 'node:crypto';\nimport type { ThreadPatch } from '../shared/thread-patch.js';\nimport { ThreadPatchBuilder, type StreamedItem } from './thread-patch.js';\nimport type {\n Cursor,\n Operation,\n Project,\n ServerMessage,\n SystemInfo,\n ThreadSummary,\n ThreadView,\n TurnCompletion,\n AttentionRequest,\n} from '../shared/types.js';\n\ntype BusinessEvent = Extract<ServerMessage, { type: 'event' }>;\ntype Listener = (message: ServerMessage) => void;\n\n/** Synchronous snapshot+subscription forms one JS event-loop boundary. */\nexport class EventHub {\n readonly serverEpoch = randomUUID();\n private seq = 0;\n private discardedThrough = 0;\n private bytes = 0;\n private readonly events: { event: BusinessEvent; bytes: number }[] = [];\n private readonly listeners = new Set<{ threadId: string; send: Listener }>();\n private readonly runtimeListeners = new Set<Listener>();\n private readonly overviewListeners = new Set<Listener>();\n private readonly threadPatches = new Map<string, ThreadPatchBuilder>();\n\n constructor(private readonly maxBytes = 16 * 1024 * 1024) {}\n\n cursor(): Cursor {\n return { serverEpoch: this.serverEpoch, seq: this.seq };\n }\n\n publish(\n kind: 'thread' | 'threadPatch' | 'runtime' | 'operation',\n payload: ThreadView | ThreadPatch | SystemInfo | Operation,\n threadId?: string,\n ): void {\n const event: BusinessEvent = {\n type: 'event',\n cursor: { serverEpoch: this.serverEpoch, seq: ++this.seq },\n kind,\n payload: structuredClone(payload),\n ...(threadId === undefined ? {} : { threadId }),\n };\n const bytes = Buffer.byteLength(JSON.stringify(event));\n this.events.push({ event, bytes });\n this.bytes += bytes;\n while (this.bytes > this.maxBytes && this.events.length > 0) {\n const removed = this.events.shift()!;\n this.bytes -= removed.bytes;\n this.discardedThrough = removed.event.cursor.seq;\n }\n for (const listener of this.listeners)\n if (!event.threadId || event.threadId === listener.threadId)\n this.deliver(listener.send, event);\n if (kind === 'runtime')\n for (const listener of this.runtimeListeners) this.deliver(listener, event);\n }\n\n subscribeRuntime(send: Listener): () => void {\n this.runtimeListeners.add(send);\n return () => {\n this.runtimeListeners.delete(send);\n };\n }\n\n publishThread(thread: ThreadView, streamed?: StreamedItem): void {\n let builder = this.threadPatches.get(thread.id);\n if (!builder) {\n builder = new ThreadPatchBuilder();\n this.threadPatches.set(thread.id, builder);\n }\n this.publish('threadPatch', builder.build(thread, streamed), thread.id);\n }\n\n /** Overview is recovered via HTTP; it never consumes the detailed replay buffer. */\n publishSummary(summary: ThreadSummary): void {\n const event: BusinessEvent = {\n type: 'event',\n kind: 'threadSummary',\n threadId: summary.id,\n cursor: this.cursor(),\n payload: structuredClone(summary),\n };\n for (const listener of this.overviewListeners) this.deliver(listener, event);\n }\n\n subscribeOverview(send: Listener): () => void {\n this.overviewListeners.add(send);\n return () => {\n this.overviewListeners.delete(send);\n };\n }\n\n /** Only connected overview clients receive this signal. It never enters the replay buffer. */\n publishCompletion(completion: TurnCompletion): void {\n const event: BusinessEvent = {\n type: 'event',\n kind: 'turnCompletion',\n threadId: completion.threadId,\n cursor: this.cursor(),\n payload: structuredClone(completion),\n };\n for (const listener of this.overviewListeners) this.deliver(listener, event);\n }\n\n publishAttention(request: AttentionRequest): void {\n const event: BusinessEvent = {\n type: 'event',\n kind: 'attentionRequest',\n threadId: request.threadId,\n cursor: this.cursor(),\n payload: structuredClone(request),\n };\n for (const listener of this.overviewListeners) this.deliver(listener, event);\n }\n\n /** Project snapshots have their own update boundary even without a thread event. */\n publishProjects(projects: Project[]): void {\n const event: BusinessEvent = {\n type: 'event',\n kind: 'projects',\n cursor: { serverEpoch: this.serverEpoch, seq: ++this.seq },\n payload: structuredClone(projects),\n };\n for (const listener of this.overviewListeners) this.deliver(listener, event);\n }\n\n subscribe(\n threadId: string,\n snapshot: () => ThreadView,\n after: Cursor | undefined,\n send: Listener,\n incremental = false,\n ): () => void {\n const replayable =\n after?.serverEpoch === this.serverEpoch &&\n after.seq >= this.discardedThrough &&\n after.seq <= this.seq;\n const queued: ServerMessage[] = [];\n let initializing = true;\n const listener = {\n threadId,\n send: (message: ServerMessage) => {\n if (initializing) queued.push(message);\n else send(message);\n },\n };\n this.listeners.add(listener);\n // No await may occur between reading the snapshot and registering the listener.\n let boundary = this.seq;\n if (replayable && after) {\n for (const { event } of [...this.events])\n if (\n event.cursor.seq > after.seq &&\n event.cursor.seq <= boundary &&\n (!event.threadId || event.threadId === threadId)\n )\n this.deliver(send, event);\n } else {\n boundary = this.seq;\n this.deliver(\n send,\n incremental\n ? { type: 'resync', cursor: this.cursor(), threadId }\n : {\n type: 'snapshot',\n cursor: this.cursor(),\n threadId,\n data: structuredClone(snapshot()),\n },\n );\n }\n initializing = false;\n for (const message of queued)\n if (message.type === 'event' && message.cursor.seq > boundary) this.deliver(send, message);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n private deliver(send: Listener, message: ServerMessage): void {\n // A closed or slow browser must never unwind the upstream event consumer.\n try {\n send(message);\n } catch {\n /* Transport closes or unsubscribes its own failed socket. */\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/server/http.js
CHANGED
|
@@ -296,6 +296,10 @@ function createApp({
|
|
|
296
296
|
"/api/threads/:threadId/history",
|
|
297
297
|
async (c) => c.json(await service.getThreadHistory(id(c.req.param("threadId")), c.req.query("cursor")))
|
|
298
298
|
);
|
|
299
|
+
app.get(
|
|
300
|
+
"/api/threads/:threadId/snapshot",
|
|
301
|
+
async (c) => c.json(await service.getThreadSnapshot(id(c.req.param("threadId"))))
|
|
302
|
+
);
|
|
299
303
|
app.get(
|
|
300
304
|
"/api/threads/:threadId/attention",
|
|
301
305
|
(c) => c.json(service.getThreadAttention(id(c.req.param("threadId"))))
|
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/projects/:projectId/diff', async (c) =>\n c.json(await service.getProjectDiff(id(c.req.param('projectId')))),\n );\n app.get('/api/threads/:threadId/diff', async (c) =>\n c.json(await service.getThreadDiff(id(c.req.param('threadId')))),\n );\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/retry', async (c) => {\n const op = await service.retryTurn(\n id(c.req.param('threadId')),\n await parse(c, schemas.retryTurnSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/retry/cancel', async (c) => {\n const op = await service.cancelCapacityRetry(\n id(c.req.param('threadId')),\n await parse(c, schemas.interruptSchema),\n );\n return c.json(op, status(op));\n });\n app.get('/api/threads/:threadId/goal', async (c) =>\n c.json(await service.getGoal(id(c.req.param('threadId')))),\n );\n app.post('/api/threads/:threadId/goal', async (c) => {\n const op = await service.mutateGoal(\n id(c.req.param('threadId')),\n await parse(c, schemas.goalMutationSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/recap', async (c) => {\n const op = await service.recapThread(\n id(c.req.param('threadId')),\n await parse(c, schemas.recapSchema),\n );\n return c.json(op, status(op));\n });\n app.get('/api/threads/:threadId/denials', async (c) =>\n c.json(await service.getGuardianDenials(id(c.req.param('threadId')))),\n );\n app.post('/api/threads/:threadId/approve', async (c) => {\n const op = await service.approveGuardianDenial(\n id(c.req.param('threadId')),\n await parse(c, schemas.approveDenialSchema),\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": "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",
|
|
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/diff', async (c) =>\n c.json(await service.getProjectDiff(id(c.req.param('projectId')))),\n );\n app.get('/api/threads/:threadId/diff', async (c) =>\n c.json(await service.getThreadDiff(id(c.req.param('threadId')))),\n );\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/snapshot', async (c) =>\n c.json(await service.getThreadSnapshot(id(c.req.param('threadId')))),\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/retry', async (c) => {\n const op = await service.retryTurn(\n id(c.req.param('threadId')),\n await parse(c, schemas.retryTurnSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/retry/cancel', async (c) => {\n const op = await service.cancelCapacityRetry(\n id(c.req.param('threadId')),\n await parse(c, schemas.interruptSchema),\n );\n return c.json(op, status(op));\n });\n app.get('/api/threads/:threadId/goal', async (c) =>\n c.json(await service.getGoal(id(c.req.param('threadId')))),\n );\n app.post('/api/threads/:threadId/goal', async (c) => {\n const op = await service.mutateGoal(\n id(c.req.param('threadId')),\n await parse(c, schemas.goalMutationSchema),\n );\n return c.json(op, status(op));\n });\n app.post('/api/threads/:threadId/recap', async (c) => {\n const op = await service.recapThread(\n id(c.req.param('threadId')),\n await parse(c, schemas.recapSchema),\n );\n return c.json(op, status(op));\n });\n app.get('/api/threads/:threadId/denials', async (c) =>\n c.json(await service.getGuardianDenials(id(c.req.param('threadId')))),\n );\n app.post('/api/threads/:threadId/approve', async (c) => {\n const op = await service.approveGuardianDenial(\n id(c.req.param('threadId')),\n await parse(c, schemas.approveDenialSchema),\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,IAAiC,OAAO,MAC9C,EAAE,KAAK,MAAM,QAAQ,eAAe,GAAG,EAAE,IAAI,MAAM,WAAW,CAAC,CAAC,CAAC;AAAA,EACnE;AACA,MAAI;AAAA,IAAI;AAAA,IAA+B,OAAO,MAC5C,EAAE,KAAK,MAAM,QAAQ,cAAc,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,CAAC,CAAC;AAAA,EACjE;AACA,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,IAAmC,OAAO,MAChD,EAAE,KAAK,MAAM,QAAQ,kBAAkB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,CAAC,CAAC;AAAA,EACrE;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,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,uCAAuC,OAAO,MAAM;AAC3D,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;AAAA,IAAI;AAAA,IAA+B,OAAO,MAC5C,EAAE,KAAK,MAAM,QAAQ,QAAQ,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,CAAC,CAAC;AAAA,EAC3D;AACA,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,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,WAAW;AAAA,IACpC;AACA,WAAO,EAAE,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,EAC9B,CAAC;AACD,MAAI;AAAA,IAAI;AAAA,IAAkC,OAAO,MAC/C,EAAE,KAAK,MAAM,QAAQ,mBAAmB,GAAG,EAAE,IAAI,MAAM,UAAU,CAAC,CAAC,CAAC;AAAA,EACtE;AACA,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,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
|
@@ -537,6 +537,15 @@ class GatewayService {
|
|
|
537
537
|
this.workspaces.assertOwnership(thread.projectId, thread.cwd, thread.id);
|
|
538
538
|
return pendingAttention(thread);
|
|
539
539
|
}
|
|
540
|
+
async getThreadSnapshot(threadId) {
|
|
541
|
+
await this.getThread(threadId);
|
|
542
|
+
const thread = this.projection.get(threadId);
|
|
543
|
+
this.workspaces.assertOwnership(thread.projectId, thread.cwd, thread.id);
|
|
544
|
+
return {
|
|
545
|
+
data: this.threadView(thread),
|
|
546
|
+
cursor: this.events.cursor()
|
|
547
|
+
};
|
|
548
|
+
}
|
|
540
549
|
async getThreadHistory(threadId, cursor) {
|
|
541
550
|
if (!cursor || cursor.length > 8192)
|
|
542
551
|
throw new AppError("VALIDATION_FAILED", "Missing or invalid history cursor", 400);
|
|
@@ -1143,13 +1152,14 @@ class GatewayService {
|
|
|
1143
1152
|
return { result: this.store.get(input.clientOperationId)?.result };
|
|
1144
1153
|
});
|
|
1145
1154
|
}
|
|
1146
|
-
async subscribe(threadId, after, listener) {
|
|
1155
|
+
async subscribe(threadId, after, listener, incremental = false) {
|
|
1147
1156
|
await this.getThread(threadId);
|
|
1148
1157
|
return this.events.subscribe(
|
|
1149
1158
|
threadId,
|
|
1150
1159
|
() => this.threadView(this.projection.get(threadId)),
|
|
1151
1160
|
after,
|
|
1152
|
-
listener
|
|
1161
|
+
listener,
|
|
1162
|
+
incremental
|
|
1153
1163
|
);
|
|
1154
1164
|
}
|
|
1155
1165
|
async shutdown() {
|
|
@@ -1410,11 +1420,11 @@ class GatewayService {
|
|
|
1410
1420
|
);
|
|
1411
1421
|
return new AppError("INTERNAL_ERROR", error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF", 500);
|
|
1412
1422
|
}
|
|
1413
|
-
publishThread(threadId) {
|
|
1423
|
+
publishThread(threadId, streamed) {
|
|
1414
1424
|
const thread = this.projection.get(threadId);
|
|
1415
1425
|
if (!thread) return;
|
|
1416
|
-
const view = this.threadView(thread);
|
|
1417
|
-
this.events.
|
|
1426
|
+
const view = this.threadView(thread, false);
|
|
1427
|
+
this.events.publishThread(view, streamed);
|
|
1418
1428
|
const summary = toThreadSummary(view);
|
|
1419
1429
|
const encoded = JSON.stringify(summary);
|
|
1420
1430
|
if (this.summaries.get(threadId) === encoded) return;
|
|
@@ -1439,13 +1449,13 @@ class GatewayService {
|
|
|
1439
1449
|
}
|
|
1440
1450
|
return links;
|
|
1441
1451
|
}
|
|
1442
|
-
threadView(thread) {
|
|
1443
|
-
const result = structuredClone(thread);
|
|
1452
|
+
threadView(thread, copy = true) {
|
|
1453
|
+
const result = copy ? structuredClone(thread) : { ...thread };
|
|
1444
1454
|
const links = this.capacityLinks.get(thread.id) ?? (thread.turns.some((turn) => !turn.items.some((item) => item.type === "userMessage")) ? this.retryLinks(thread.id) : void 0);
|
|
1445
|
-
|
|
1455
|
+
result.turns = result.turns.map((turn) => {
|
|
1446
1456
|
const root = links?.get(turn.id);
|
|
1447
|
-
|
|
1448
|
-
}
|
|
1457
|
+
return root ? { ...turn, retryOf: root } : turn;
|
|
1458
|
+
});
|
|
1449
1459
|
const retry = this.capacityRetries.view(thread.id);
|
|
1450
1460
|
if (retry) result.capacityRetry = structuredClone(retry);
|
|
1451
1461
|
else delete result.capacityRetry;
|
|
@@ -1672,7 +1682,7 @@ class GatewayService {
|
|
|
1672
1682
|
else if (event.type === "diff") {
|
|
1673
1683
|
this.projection.diff(thread.id, event.turnId, event.diff);
|
|
1674
1684
|
}
|
|
1675
|
-
this.publishThread(thread.id);
|
|
1685
|
+
this.publishThread(thread.id, event.type === "delta" ? event : void 0);
|
|
1676
1686
|
if (event.type === "item" || event.type === "turn")
|
|
1677
1687
|
this.publishNewAttention(thread.id, previousAttention);
|
|
1678
1688
|
}
|