@covro/covro 0.2.1-dev.2 → 0.2.1-dev.4
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 +9 -2
- package/README.zh-CN.md +9 -2
- package/dist/codex/adapter.js +8 -1
- package/dist/codex/adapter.js.map +2 -2
- package/dist/drizzle/0005_session_workspaces.sql +24 -0
- package/dist/drizzle/meta/0005_snapshot.json +480 -0
- package/dist/drizzle/meta/_journal.json +7 -0
- package/dist/server/db/operations.js +14 -1
- package/dist/server/db/operations.js.map +2 -2
- package/dist/server/db/schema.js +9 -1
- package/dist/server/db/schema.js.map +2 -2
- package/dist/server/http.js +25 -0
- package/dist/server/http.js.map +2 -2
- package/dist/server/local-files.js +2 -2
- package/dist/server/local-files.js.map +2 -2
- package/dist/server/main.js +1 -0
- package/dist/server/main.js.map +2 -2
- package/dist/server/service.js +96 -51
- package/dist/server/service.js.map +2 -2
- package/dist/server/workspaces.js +138 -0
- package/dist/server/workspaces.js.map +7 -0
- package/dist/shared/workspace-scope.js +9 -0
- package/dist/shared/workspace-scope.js.map +7 -0
- package/dist/web/assets/abnfDiagram-WEYOIA3C-DTTcFQGL.js +1 -0
- package/dist/web/assets/arc-K2pKIwfu.js +1 -0
- package/dist/web/assets/architecture-WOLXFQ4H-DrxN_1CG.js +1 -0
- package/dist/web/assets/architectureDiagram-ZHVYKT53-CyyCrVAb.js +36 -0
- package/dist/web/assets/array-BifhSqXX.js +1 -0
- package/dist/web/assets/blockDiagram-RJAE7QA3-C8vl8QXS.js +140 -0
- package/dist/web/assets/c4Diagram-XDPPPE54-BtnIITFN.js +38 -0
- package/dist/web/assets/channel-CDExoPVe.js +1 -0
- package/dist/web/assets/chunk-2E7WHVMD-BssauSch.js +88 -0
- package/dist/web/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
- package/dist/web/assets/chunk-4EMNKR2T-BZOo1RWg.js +1 -0
- package/dist/web/assets/chunk-55XCU76K-D8ZWazMQ.js +1 -0
- package/dist/web/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
- package/dist/web/assets/chunk-7S6XSTFO-C8WqPzUl.js +2 -0
- package/dist/web/assets/chunk-AQDTSKZB-Coo6Axpg.js +72 -0
- package/dist/web/assets/chunk-DSNLSHJZ-5TwmEPWR.js +129 -0
- package/dist/web/assets/chunk-DUW6YSOI-Dgx8z5s3.js +1 -0
- package/dist/web/assets/chunk-HAGFOTED-Dgtj-Fc_.js +62 -0
- package/dist/web/assets/chunk-HNE4Q36P-COoS4UPL.js +1 -0
- package/dist/web/assets/chunk-J5ZVWO5B-oDCd-gWO.js +1 -0
- package/dist/web/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
- package/dist/web/assets/chunk-NGNAAXSQ-C2Wy9Xmz.js +136 -0
- package/dist/web/assets/chunk-NQOKRVIF-tPhNkBBj.js +213 -0
- package/dist/web/assets/chunk-UHW7PFBP-BLk_BkCl.js +1 -0
- package/dist/web/assets/chunk-VQ5W62QI-HBeSVTU0.js +1 -0
- package/dist/web/assets/chunk-WQQL4CDK-LmZUm8If.js +10 -0
- package/dist/web/assets/chunk-XXDRQBXY-49rKU8Nk.js +1 -0
- package/dist/web/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
- package/dist/web/assets/chunk-YZO67HFG-B_TgpaEG.js +1 -0
- package/dist/web/assets/chunk-ZAUX2LTX-f7-DSOrY.js +1 -0
- package/dist/web/assets/chunk-ZCHMQSOR-QhJOh7x0.js +2 -0
- package/dist/web/assets/classDiagram-v2-4MYWR3UA-CwF2HuoZ.js +217 -0
- package/dist/web/assets/cose-bilkent-JH36ORCC-CLvKOlx5.js +1 -0
- package/dist/web/assets/cynefin-EF2NZ3EQ-BNRVavZN.js +1 -0
- package/dist/web/assets/cynefinDiagram-WF24UDRP-DEd83kgI.js +62 -0
- package/dist/web/assets/cytoscape.esm-BegBNzOV.js +321 -0
- package/dist/web/assets/dagre-NK4GIZVX-C340UEI3.js +4 -0
- package/dist/web/assets/defaultLocale-BFoDCU3G.js +1 -0
- package/dist/web/assets/diagram-CBK3MWTC-CuN7ncUm.js +24 -0
- package/dist/web/assets/diagram-I5XIIV2D-D9mGAfA7.js +24 -0
- package/dist/web/assets/diagram-ODIL2UCW-CXtBv4bI.js +30 -0
- package/dist/web/assets/diagram-PFBEJUXE-B8qP5nGT.js +3 -0
- package/dist/web/assets/diagram-RJA3I4VV-BVrzsw2b.js +41 -0
- package/dist/web/assets/diagram-TYUNFSNR-Djfine3D.js +200 -0
- package/dist/web/assets/dist-D8kDnYqD.js +1 -0
- package/dist/web/assets/ebnfDiagram-V4P3TTPT-C69Oiekp.js +1 -0
- package/dist/web/assets/elk-QONTBCTQ-Bd3BP1h1.js +27 -0
- package/dist/web/assets/erDiagram-KYQIGQAA-Dxcl5jVl.js +99 -0
- package/dist/web/assets/eventmodeling-K75KTNOO-Do8p535i.js +1 -0
- package/dist/web/assets/flowDiagram-IUGLLWBU-X85uzgrG.js +1 -0
- package/dist/web/assets/ganttDiagram-R7GPNTJY-MBGUZbVy.js +292 -0
- package/dist/web/assets/gitGraph-VSP46ZUC-CHxRIbkg.js +1 -0
- package/dist/web/assets/gitGraphDiagram-PDYL7XHY-DbW0GeW4.js +106 -0
- package/dist/web/assets/graphlib-DS17s2tU.js +1 -0
- package/dist/web/assets/index-Cz3AOJOw.js +142 -0
- package/dist/web/assets/index-DaMLk_sl.css +1 -0
- package/dist/web/assets/info-OHQRW6UA-K8BF1xZb.js +1 -0
- package/dist/web/assets/infoDiagram-MVDRKAX5-QaWV5-SY.js +2 -0
- package/dist/web/assets/init-C-OQMol4.js +1 -0
- package/dist/web/assets/ishikawaDiagram-HPEHV2GE-DpVz_sC0.js +70 -0
- package/dist/web/assets/journeyDiagram-BOSHW7O7-S9MzozV7.js +139 -0
- package/dist/web/assets/kanban-definition-FNSA4HC5-BiU8Ibw-.js +89 -0
- package/dist/web/assets/katex-B_JcIwqj.js +257 -0
- package/dist/web/assets/line-B1KaX5ms.js +1 -0
- package/dist/web/assets/linear-Cg1dwAtU.js +1 -0
- package/dist/web/assets/mermaid-parser.core-hzYHYxfI.js +7 -0
- package/dist/web/assets/mermaid.core-N8xYYvXy.js +44 -0
- package/dist/web/assets/mindmap-definition-6OY57UG3-BmIQCrEd.js +98 -0
- package/dist/web/assets/ordinal-BDEzSJ7C.js +1 -0
- package/dist/web/assets/packet-JDAUHWVQ-DhOTX9De.js +1 -0
- package/dist/web/assets/path-fybaL0A-.js +1 -0
- package/dist/web/assets/pegDiagram-ECIUJNBX-CVfE6yUu.js +1 -0
- package/dist/web/assets/pie-XZMESJXO-BayfKVL8.js +1 -0
- package/dist/web/assets/pieDiagram-GNMPY74T-ClbMRve3.js +39 -0
- package/dist/web/assets/quadrantDiagram-D57K4MC3-DFp-P_EZ.js +7 -0
- package/dist/web/assets/radar-ABXABTNO-Bt1EAsxC.js +1 -0
- package/dist/web/assets/railroad-I3PHUGI6-CSos2Rm9.js +1 -0
- package/dist/web/assets/railroad-abnf-LNEFI6M7-CebY-3Kh.js +1 -0
- package/dist/web/assets/railroad-ebnf-DWYD2UWJ-DpA6-TBs.js +1 -0
- package/dist/web/assets/railroad-peg-JR7BVNR7-Bg3QPvi5.js +1 -0
- package/dist/web/assets/railroadDiagram-Y72NRBL7-BM4RAgqS.js +1 -0
- package/dist/web/assets/requirementDiagram-EQYSW5RA-CqP9bCS_.js +84 -0
- package/dist/web/assets/rough.esm-Dy-Kn_BL.js +1 -0
- package/dist/web/assets/sankeyDiagram-SY24JHO5-BhS8f6-k.js +40 -0
- package/dist/web/assets/sequenceDiagram-BLEHNHQU-p3C1DgeC.js +169 -0
- package/dist/web/assets/sizeCapture-INFHLROL-3uHXrFqA.js +1 -0
- package/dist/web/assets/src-9XJAFibc.js +1 -0
- package/dist/web/assets/stateDiagram-v2-A6IESKWZ-DVVy8chY.js +291 -0
- package/dist/web/assets/swimlanes-B3ENRKFQ-CtMPO6Gw.js +1 -0
- package/dist/web/assets/swimlanesDiagram-AYQRV4AK-BRXJWgnO.js +8 -0
- package/dist/web/assets/timeline-definition-JXYKGLGB-DuTqpjLQ.js +120 -0
- package/dist/web/assets/treeView-D4JQ5SDB-qpOZEphu.js +1 -0
- package/dist/web/assets/treemap-SAJKECNS-Dm6e3TpG.js +1 -0
- package/dist/web/assets/usecaseDiagram-WPOLBNNX-DoCSdm5y.js +328 -0
- package/dist/web/assets/vennDiagram-Q3Y3IDCW-qzd4yvh5.js +34 -0
- package/dist/web/assets/wardley-7MLQ67FV-CkcgIQgQ.js +1 -0
- package/dist/web/assets/wardleyDiagram-IVAIDKWA-CE6OR9hA.js +78 -0
- package/dist/web/assets/xychartDiagram-4URNHDU4-OrFXHVc6.js +7 -0
- package/dist/web/index.html +2 -2
- package/package.json +4 -3
- package/dist/web/assets/index-D4yT2i6A.js +0 -140
- package/dist/web/assets/index-Du6go0-C.css +0 -1
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
CREATE TABLE `session_workspaces` (
|
|
2
|
+
`operation_id` text PRIMARY KEY NOT NULL,
|
|
3
|
+
`thread_id` text,
|
|
4
|
+
`root_path` text NOT NULL,
|
|
5
|
+
`canonical_root` text NOT NULL,
|
|
6
|
+
`created_at` integer NOT NULL
|
|
7
|
+
);
|
|
8
|
+
--> statement-breakpoint
|
|
9
|
+
CREATE UNIQUE INDEX `session_workspaces_thread_id_unique` ON `session_workspaces` (`thread_id`);--> statement-breakpoint
|
|
10
|
+
CREATE UNIQUE INDEX `session_workspaces_canonical_root_unique` ON `session_workspaces` (`canonical_root`);--> statement-breakpoint
|
|
11
|
+
PRAGMA foreign_keys=OFF;--> statement-breakpoint
|
|
12
|
+
CREATE TABLE `__new_thread_links` (
|
|
13
|
+
`thread_id` text PRIMARY KEY NOT NULL,
|
|
14
|
+
`project_id` text,
|
|
15
|
+
`cwd` text NOT NULL,
|
|
16
|
+
`source` text NOT NULL,
|
|
17
|
+
`managed_epoch` text,
|
|
18
|
+
`updated_at` integer NOT NULL
|
|
19
|
+
);
|
|
20
|
+
--> statement-breakpoint
|
|
21
|
+
INSERT INTO `__new_thread_links`("thread_id", "project_id", "cwd", "source", "managed_epoch", "updated_at") SELECT "thread_id", "project_id", "cwd", "source", "managed_epoch", "updated_at" FROM `thread_links`;--> statement-breakpoint
|
|
22
|
+
DROP TABLE `thread_links`;--> statement-breakpoint
|
|
23
|
+
ALTER TABLE `__new_thread_links` RENAME TO `thread_links`;--> statement-breakpoint
|
|
24
|
+
PRAGMA foreign_keys=ON;
|
|
@@ -0,0 +1,480 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "6",
|
|
3
|
+
"dialect": "sqlite",
|
|
4
|
+
"id": "ef2ed4be-1aca-4f12-81c5-389062f9da5c",
|
|
5
|
+
"prevId": "51088300-eeac-40ca-99e1-b8f2b1bb4939",
|
|
6
|
+
"tables": {
|
|
7
|
+
"execution_markers": {
|
|
8
|
+
"name": "execution_markers",
|
|
9
|
+
"columns": {
|
|
10
|
+
"operation_id": {
|
|
11
|
+
"name": "operation_id",
|
|
12
|
+
"type": "text",
|
|
13
|
+
"primaryKey": true,
|
|
14
|
+
"notNull": true,
|
|
15
|
+
"autoincrement": false
|
|
16
|
+
},
|
|
17
|
+
"thread_id": {
|
|
18
|
+
"name": "thread_id",
|
|
19
|
+
"type": "text",
|
|
20
|
+
"primaryKey": false,
|
|
21
|
+
"notNull": true,
|
|
22
|
+
"autoincrement": false
|
|
23
|
+
},
|
|
24
|
+
"turn_id": {
|
|
25
|
+
"name": "turn_id",
|
|
26
|
+
"type": "text",
|
|
27
|
+
"primaryKey": false,
|
|
28
|
+
"notNull": false,
|
|
29
|
+
"autoincrement": false
|
|
30
|
+
},
|
|
31
|
+
"workspace_key": {
|
|
32
|
+
"name": "workspace_key",
|
|
33
|
+
"type": "text",
|
|
34
|
+
"primaryKey": false,
|
|
35
|
+
"notNull": true,
|
|
36
|
+
"autoincrement": false
|
|
37
|
+
},
|
|
38
|
+
"codex_epoch": {
|
|
39
|
+
"name": "codex_epoch",
|
|
40
|
+
"type": "text",
|
|
41
|
+
"primaryKey": false,
|
|
42
|
+
"notNull": true,
|
|
43
|
+
"autoincrement": false
|
|
44
|
+
},
|
|
45
|
+
"state": {
|
|
46
|
+
"name": "state",
|
|
47
|
+
"type": "text",
|
|
48
|
+
"primaryKey": false,
|
|
49
|
+
"notNull": true,
|
|
50
|
+
"autoincrement": false
|
|
51
|
+
},
|
|
52
|
+
"created_at": {
|
|
53
|
+
"name": "created_at",
|
|
54
|
+
"type": "integer",
|
|
55
|
+
"primaryKey": false,
|
|
56
|
+
"notNull": true,
|
|
57
|
+
"autoincrement": false
|
|
58
|
+
},
|
|
59
|
+
"ended_at": {
|
|
60
|
+
"name": "ended_at",
|
|
61
|
+
"type": "integer",
|
|
62
|
+
"primaryKey": false,
|
|
63
|
+
"notNull": false,
|
|
64
|
+
"autoincrement": false
|
|
65
|
+
},
|
|
66
|
+
"reconciled_at": {
|
|
67
|
+
"name": "reconciled_at",
|
|
68
|
+
"type": "integer",
|
|
69
|
+
"primaryKey": false,
|
|
70
|
+
"notNull": false,
|
|
71
|
+
"autoincrement": false
|
|
72
|
+
},
|
|
73
|
+
"reconciliation_operation_id": {
|
|
74
|
+
"name": "reconciliation_operation_id",
|
|
75
|
+
"type": "text",
|
|
76
|
+
"primaryKey": false,
|
|
77
|
+
"notNull": false,
|
|
78
|
+
"autoincrement": false
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"indexes": {
|
|
82
|
+
"execution_markers_active_thread": {
|
|
83
|
+
"name": "execution_markers_active_thread",
|
|
84
|
+
"columns": [
|
|
85
|
+
"thread_id"
|
|
86
|
+
],
|
|
87
|
+
"isUnique": true,
|
|
88
|
+
"where": "\"execution_markers\".\"ended_at\" is null"
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
"foreignKeys": {
|
|
92
|
+
"execution_markers_operation_id_operations_client_operation_id_fk": {
|
|
93
|
+
"name": "execution_markers_operation_id_operations_client_operation_id_fk",
|
|
94
|
+
"tableFrom": "execution_markers",
|
|
95
|
+
"tableTo": "operations",
|
|
96
|
+
"columnsFrom": [
|
|
97
|
+
"operation_id"
|
|
98
|
+
],
|
|
99
|
+
"columnsTo": [
|
|
100
|
+
"client_operation_id"
|
|
101
|
+
],
|
|
102
|
+
"onDelete": "no action",
|
|
103
|
+
"onUpdate": "no action"
|
|
104
|
+
},
|
|
105
|
+
"execution_markers_reconciliation_operation_id_operations_client_operation_id_fk": {
|
|
106
|
+
"name": "execution_markers_reconciliation_operation_id_operations_client_operation_id_fk",
|
|
107
|
+
"tableFrom": "execution_markers",
|
|
108
|
+
"tableTo": "operations",
|
|
109
|
+
"columnsFrom": [
|
|
110
|
+
"reconciliation_operation_id"
|
|
111
|
+
],
|
|
112
|
+
"columnsTo": [
|
|
113
|
+
"client_operation_id"
|
|
114
|
+
],
|
|
115
|
+
"onDelete": "no action",
|
|
116
|
+
"onUpdate": "no action"
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
"compositePrimaryKeys": {},
|
|
120
|
+
"uniqueConstraints": {},
|
|
121
|
+
"checkConstraints": {
|
|
122
|
+
"execution_markers_state_check": {
|
|
123
|
+
"name": "execution_markers_state_check",
|
|
124
|
+
"value": "\"execution_markers\".\"state\" in ('active', 'unknown', 'terminal', 'reconciled')"
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
"operations": {
|
|
129
|
+
"name": "operations",
|
|
130
|
+
"columns": {
|
|
131
|
+
"client_operation_id": {
|
|
132
|
+
"name": "client_operation_id",
|
|
133
|
+
"type": "text",
|
|
134
|
+
"primaryKey": true,
|
|
135
|
+
"notNull": true,
|
|
136
|
+
"autoincrement": false
|
|
137
|
+
},
|
|
138
|
+
"kind": {
|
|
139
|
+
"name": "kind",
|
|
140
|
+
"type": "text",
|
|
141
|
+
"primaryKey": false,
|
|
142
|
+
"notNull": true,
|
|
143
|
+
"autoincrement": false
|
|
144
|
+
},
|
|
145
|
+
"target": {
|
|
146
|
+
"name": "target",
|
|
147
|
+
"type": "text",
|
|
148
|
+
"primaryKey": false,
|
|
149
|
+
"notNull": true,
|
|
150
|
+
"autoincrement": false
|
|
151
|
+
},
|
|
152
|
+
"project_id": {
|
|
153
|
+
"name": "project_id",
|
|
154
|
+
"type": "text",
|
|
155
|
+
"primaryKey": false,
|
|
156
|
+
"notNull": false,
|
|
157
|
+
"autoincrement": false
|
|
158
|
+
},
|
|
159
|
+
"request_digest": {
|
|
160
|
+
"name": "request_digest",
|
|
161
|
+
"type": "text",
|
|
162
|
+
"primaryKey": false,
|
|
163
|
+
"notNull": true,
|
|
164
|
+
"autoincrement": false
|
|
165
|
+
},
|
|
166
|
+
"state": {
|
|
167
|
+
"name": "state",
|
|
168
|
+
"type": "text",
|
|
169
|
+
"primaryKey": false,
|
|
170
|
+
"notNull": true,
|
|
171
|
+
"autoincrement": false
|
|
172
|
+
},
|
|
173
|
+
"result": {
|
|
174
|
+
"name": "result",
|
|
175
|
+
"type": "text",
|
|
176
|
+
"primaryKey": false,
|
|
177
|
+
"notNull": false,
|
|
178
|
+
"autoincrement": false
|
|
179
|
+
},
|
|
180
|
+
"error": {
|
|
181
|
+
"name": "error",
|
|
182
|
+
"type": "text",
|
|
183
|
+
"primaryKey": false,
|
|
184
|
+
"notNull": false,
|
|
185
|
+
"autoincrement": false
|
|
186
|
+
},
|
|
187
|
+
"created_at": {
|
|
188
|
+
"name": "created_at",
|
|
189
|
+
"type": "integer",
|
|
190
|
+
"primaryKey": false,
|
|
191
|
+
"notNull": true,
|
|
192
|
+
"autoincrement": false
|
|
193
|
+
},
|
|
194
|
+
"updated_at": {
|
|
195
|
+
"name": "updated_at",
|
|
196
|
+
"type": "integer",
|
|
197
|
+
"primaryKey": false,
|
|
198
|
+
"notNull": true,
|
|
199
|
+
"autoincrement": false
|
|
200
|
+
},
|
|
201
|
+
"reconciled_at": {
|
|
202
|
+
"name": "reconciled_at",
|
|
203
|
+
"type": "integer",
|
|
204
|
+
"primaryKey": false,
|
|
205
|
+
"notNull": false,
|
|
206
|
+
"autoincrement": false
|
|
207
|
+
},
|
|
208
|
+
"reconciliation_decision": {
|
|
209
|
+
"name": "reconciliation_decision",
|
|
210
|
+
"type": "text",
|
|
211
|
+
"primaryKey": false,
|
|
212
|
+
"notNull": false,
|
|
213
|
+
"autoincrement": false
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
"indexes": {
|
|
217
|
+
"operations_state_idx": {
|
|
218
|
+
"name": "operations_state_idx",
|
|
219
|
+
"columns": [
|
|
220
|
+
"state"
|
|
221
|
+
],
|
|
222
|
+
"isUnique": false
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
"foreignKeys": {},
|
|
226
|
+
"compositePrimaryKeys": {},
|
|
227
|
+
"uniqueConstraints": {},
|
|
228
|
+
"checkConstraints": {
|
|
229
|
+
"operations_state_check": {
|
|
230
|
+
"name": "operations_state_check",
|
|
231
|
+
"value": "\"operations\".\"state\" in ('accepted', 'dispatching', 'acknowledged', 'failed', 'unknown')"
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
},
|
|
235
|
+
"preferences": {
|
|
236
|
+
"name": "preferences",
|
|
237
|
+
"columns": {
|
|
238
|
+
"key": {
|
|
239
|
+
"name": "key",
|
|
240
|
+
"type": "text",
|
|
241
|
+
"primaryKey": true,
|
|
242
|
+
"notNull": true,
|
|
243
|
+
"autoincrement": false
|
|
244
|
+
},
|
|
245
|
+
"value": {
|
|
246
|
+
"name": "value",
|
|
247
|
+
"type": "text",
|
|
248
|
+
"primaryKey": false,
|
|
249
|
+
"notNull": true,
|
|
250
|
+
"autoincrement": false
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
"indexes": {},
|
|
254
|
+
"foreignKeys": {},
|
|
255
|
+
"compositePrimaryKeys": {},
|
|
256
|
+
"uniqueConstraints": {},
|
|
257
|
+
"checkConstraints": {}
|
|
258
|
+
},
|
|
259
|
+
"project_registrations": {
|
|
260
|
+
"name": "project_registrations",
|
|
261
|
+
"columns": {
|
|
262
|
+
"id": {
|
|
263
|
+
"name": "id",
|
|
264
|
+
"type": "text",
|
|
265
|
+
"primaryKey": true,
|
|
266
|
+
"notNull": true,
|
|
267
|
+
"autoincrement": false
|
|
268
|
+
},
|
|
269
|
+
"name": {
|
|
270
|
+
"name": "name",
|
|
271
|
+
"type": "text",
|
|
272
|
+
"primaryKey": false,
|
|
273
|
+
"notNull": true,
|
|
274
|
+
"autoincrement": false
|
|
275
|
+
},
|
|
276
|
+
"path": {
|
|
277
|
+
"name": "path",
|
|
278
|
+
"type": "text",
|
|
279
|
+
"primaryKey": false,
|
|
280
|
+
"notNull": true,
|
|
281
|
+
"autoincrement": false
|
|
282
|
+
},
|
|
283
|
+
"canonical_root": {
|
|
284
|
+
"name": "canonical_root",
|
|
285
|
+
"type": "text",
|
|
286
|
+
"primaryKey": false,
|
|
287
|
+
"notNull": false,
|
|
288
|
+
"autoincrement": false
|
|
289
|
+
},
|
|
290
|
+
"removed_at": {
|
|
291
|
+
"name": "removed_at",
|
|
292
|
+
"type": "integer",
|
|
293
|
+
"primaryKey": false,
|
|
294
|
+
"notNull": false,
|
|
295
|
+
"autoincrement": false
|
|
296
|
+
},
|
|
297
|
+
"created_at": {
|
|
298
|
+
"name": "created_at",
|
|
299
|
+
"type": "integer",
|
|
300
|
+
"primaryKey": false,
|
|
301
|
+
"notNull": true,
|
|
302
|
+
"autoincrement": false
|
|
303
|
+
},
|
|
304
|
+
"updated_at": {
|
|
305
|
+
"name": "updated_at",
|
|
306
|
+
"type": "integer",
|
|
307
|
+
"primaryKey": false,
|
|
308
|
+
"notNull": true,
|
|
309
|
+
"autoincrement": false
|
|
310
|
+
}
|
|
311
|
+
},
|
|
312
|
+
"indexes": {},
|
|
313
|
+
"foreignKeys": {},
|
|
314
|
+
"compositePrimaryKeys": {},
|
|
315
|
+
"uniqueConstraints": {},
|
|
316
|
+
"checkConstraints": {}
|
|
317
|
+
},
|
|
318
|
+
"session_workspaces": {
|
|
319
|
+
"name": "session_workspaces",
|
|
320
|
+
"columns": {
|
|
321
|
+
"operation_id": {
|
|
322
|
+
"name": "operation_id",
|
|
323
|
+
"type": "text",
|
|
324
|
+
"primaryKey": true,
|
|
325
|
+
"notNull": true,
|
|
326
|
+
"autoincrement": false
|
|
327
|
+
},
|
|
328
|
+
"thread_id": {
|
|
329
|
+
"name": "thread_id",
|
|
330
|
+
"type": "text",
|
|
331
|
+
"primaryKey": false,
|
|
332
|
+
"notNull": false,
|
|
333
|
+
"autoincrement": false
|
|
334
|
+
},
|
|
335
|
+
"root_path": {
|
|
336
|
+
"name": "root_path",
|
|
337
|
+
"type": "text",
|
|
338
|
+
"primaryKey": false,
|
|
339
|
+
"notNull": true,
|
|
340
|
+
"autoincrement": false
|
|
341
|
+
},
|
|
342
|
+
"canonical_root": {
|
|
343
|
+
"name": "canonical_root",
|
|
344
|
+
"type": "text",
|
|
345
|
+
"primaryKey": false,
|
|
346
|
+
"notNull": true,
|
|
347
|
+
"autoincrement": false
|
|
348
|
+
},
|
|
349
|
+
"created_at": {
|
|
350
|
+
"name": "created_at",
|
|
351
|
+
"type": "integer",
|
|
352
|
+
"primaryKey": false,
|
|
353
|
+
"notNull": true,
|
|
354
|
+
"autoincrement": false
|
|
355
|
+
}
|
|
356
|
+
},
|
|
357
|
+
"indexes": {
|
|
358
|
+
"session_workspaces_thread_id_unique": {
|
|
359
|
+
"name": "session_workspaces_thread_id_unique",
|
|
360
|
+
"columns": [
|
|
361
|
+
"thread_id"
|
|
362
|
+
],
|
|
363
|
+
"isUnique": true
|
|
364
|
+
},
|
|
365
|
+
"session_workspaces_canonical_root_unique": {
|
|
366
|
+
"name": "session_workspaces_canonical_root_unique",
|
|
367
|
+
"columns": [
|
|
368
|
+
"canonical_root"
|
|
369
|
+
],
|
|
370
|
+
"isUnique": true
|
|
371
|
+
}
|
|
372
|
+
},
|
|
373
|
+
"foreignKeys": {},
|
|
374
|
+
"compositePrimaryKeys": {},
|
|
375
|
+
"uniqueConstraints": {},
|
|
376
|
+
"checkConstraints": {}
|
|
377
|
+
},
|
|
378
|
+
"thread_links": {
|
|
379
|
+
"name": "thread_links",
|
|
380
|
+
"columns": {
|
|
381
|
+
"thread_id": {
|
|
382
|
+
"name": "thread_id",
|
|
383
|
+
"type": "text",
|
|
384
|
+
"primaryKey": true,
|
|
385
|
+
"notNull": true,
|
|
386
|
+
"autoincrement": false
|
|
387
|
+
},
|
|
388
|
+
"project_id": {
|
|
389
|
+
"name": "project_id",
|
|
390
|
+
"type": "text",
|
|
391
|
+
"primaryKey": false,
|
|
392
|
+
"notNull": false,
|
|
393
|
+
"autoincrement": false
|
|
394
|
+
},
|
|
395
|
+
"cwd": {
|
|
396
|
+
"name": "cwd",
|
|
397
|
+
"type": "text",
|
|
398
|
+
"primaryKey": false,
|
|
399
|
+
"notNull": true,
|
|
400
|
+
"autoincrement": false
|
|
401
|
+
},
|
|
402
|
+
"source": {
|
|
403
|
+
"name": "source",
|
|
404
|
+
"type": "text",
|
|
405
|
+
"primaryKey": false,
|
|
406
|
+
"notNull": true,
|
|
407
|
+
"autoincrement": false
|
|
408
|
+
},
|
|
409
|
+
"managed_epoch": {
|
|
410
|
+
"name": "managed_epoch",
|
|
411
|
+
"type": "text",
|
|
412
|
+
"primaryKey": false,
|
|
413
|
+
"notNull": false,
|
|
414
|
+
"autoincrement": false
|
|
415
|
+
},
|
|
416
|
+
"updated_at": {
|
|
417
|
+
"name": "updated_at",
|
|
418
|
+
"type": "integer",
|
|
419
|
+
"primaryKey": false,
|
|
420
|
+
"notNull": true,
|
|
421
|
+
"autoincrement": false
|
|
422
|
+
}
|
|
423
|
+
},
|
|
424
|
+
"indexes": {},
|
|
425
|
+
"foreignKeys": {},
|
|
426
|
+
"compositePrimaryKeys": {},
|
|
427
|
+
"uniqueConstraints": {},
|
|
428
|
+
"checkConstraints": {}
|
|
429
|
+
},
|
|
430
|
+
"turn_usage": {
|
|
431
|
+
"name": "turn_usage",
|
|
432
|
+
"columns": {
|
|
433
|
+
"thread_id": {
|
|
434
|
+
"name": "thread_id",
|
|
435
|
+
"type": "text",
|
|
436
|
+
"primaryKey": false,
|
|
437
|
+
"notNull": true,
|
|
438
|
+
"autoincrement": false
|
|
439
|
+
},
|
|
440
|
+
"turn_id": {
|
|
441
|
+
"name": "turn_id",
|
|
442
|
+
"type": "text",
|
|
443
|
+
"primaryKey": false,
|
|
444
|
+
"notNull": true,
|
|
445
|
+
"autoincrement": false
|
|
446
|
+
},
|
|
447
|
+
"output_tokens": {
|
|
448
|
+
"name": "output_tokens",
|
|
449
|
+
"type": "integer",
|
|
450
|
+
"primaryKey": false,
|
|
451
|
+
"notNull": true,
|
|
452
|
+
"autoincrement": false
|
|
453
|
+
}
|
|
454
|
+
},
|
|
455
|
+
"indexes": {},
|
|
456
|
+
"foreignKeys": {},
|
|
457
|
+
"compositePrimaryKeys": {
|
|
458
|
+
"turn_usage_thread_id_turn_id_pk": {
|
|
459
|
+
"columns": [
|
|
460
|
+
"thread_id",
|
|
461
|
+
"turn_id"
|
|
462
|
+
],
|
|
463
|
+
"name": "turn_usage_thread_id_turn_id_pk"
|
|
464
|
+
}
|
|
465
|
+
},
|
|
466
|
+
"uniqueConstraints": {},
|
|
467
|
+
"checkConstraints": {}
|
|
468
|
+
}
|
|
469
|
+
},
|
|
470
|
+
"views": {},
|
|
471
|
+
"enums": {},
|
|
472
|
+
"_meta": {
|
|
473
|
+
"schemas": {},
|
|
474
|
+
"tables": {},
|
|
475
|
+
"columns": {}
|
|
476
|
+
},
|
|
477
|
+
"internal": {
|
|
478
|
+
"indexes": {}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
@@ -69,7 +69,7 @@ class OperationStore {
|
|
|
69
69
|
"thread.rename"
|
|
70
70
|
].includes(operation.kind))
|
|
71
71
|
return false;
|
|
72
|
-
const owner = operation.projectId ?? (operation.kind === "thread.create" ? operation.target : this.getThreadLink(operation.target)?.projectId);
|
|
72
|
+
const owner = operation.projectId ?? (operation.kind === "thread.create" ? operation.target === "@unassigned" ? null : operation.target : this.getThreadLink(operation.target)?.projectId);
|
|
73
73
|
return owner === projectId;
|
|
74
74
|
});
|
|
75
75
|
}
|
|
@@ -101,6 +101,19 @@ class OperationStore {
|
|
|
101
101
|
});
|
|
102
102
|
return this.get(id);
|
|
103
103
|
}
|
|
104
|
+
confirmWorkspaceCreation(id, threadId) {
|
|
105
|
+
const operation = this.get(id);
|
|
106
|
+
this.database.update(operations).set({
|
|
107
|
+
state: "acknowledged",
|
|
108
|
+
error: null,
|
|
109
|
+
updatedAt: Date.now(),
|
|
110
|
+
result: {
|
|
111
|
+
threadId,
|
|
112
|
+
...operation.kind === "thread.fork" ? { forkedFromId: operation.target } : {}
|
|
113
|
+
}
|
|
114
|
+
}).where(and(eq(operations.clientOperationId, id), eq(operations.state, "unknown"))).run();
|
|
115
|
+
return this.get(id);
|
|
116
|
+
}
|
|
104
117
|
fail(id, error, uncertain = false) {
|
|
105
118
|
this.database.transaction((tx) => {
|
|
106
119
|
const changed = tx.update(operations).set({ state: uncertain ? "unknown" : "failed", error, updatedAt: Date.now() }).where(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/server/db/operations.ts"],
|
|
4
|
-
"sourcesContent": ["import { createHash } from 'node:crypto';\nimport { and, eq, isNull, or } from 'drizzle-orm';\nimport type { AppDatabase } from './index.js';\nimport { executionMarkers, operations, threadLinks } from './schema.js';\nimport type { ApiError } from '../../shared/types.js';\n\nexport type OperationRow = typeof operations.$inferSelect;\nexport type ExecutionMarker = typeof executionMarkers.$inferSelect;\nexport type ThreadLink = typeof threadLinks.$inferSelect;\n\nexport class StoreConflict extends Error {\n constructor(\n public readonly code: 'OPERATION_CONFLICT' | 'THREAD_BUSY',\n message: string,\n public readonly threadId?: string,\n ) {\n super(message);\n }\n}\n\nfunction canonical(value: unknown): string {\n if (Array.isArray(value)) return `[${value.map(canonical).join(',')}]`;\n if (value !== null && typeof value === 'object') {\n return `{${Object.entries(value)\n .filter(([, item]) => item !== undefined)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([key, item]) => `${JSON.stringify(key)}:${canonical(item)}`)\n .join(',')}}`;\n }\n return JSON.stringify(value) ?? 'null';\n}\n\nexport function requestDigest(value: unknown): string {\n return createHash('sha256').update(canonical(value)).digest('hex');\n}\n\n/** Every transaction is synchronous; no process/network work occurs inside one. */\nexport class OperationStore {\n constructor(public readonly database: AppDatabase) {}\n\n accept(\n clientOperationId: string,\n kind: string,\n target: string,\n request: unknown,\n ): { operation: OperationRow; inserted: boolean } {\n const digest = requestDigest(request);\n return this.database.transaction((tx) => {\n const now = Date.now();\n const inserted =\n tx\n .insert(operations)\n .values({\n clientOperationId,\n kind,\n target,\n requestDigest: digest,\n state: 'accepted',\n createdAt: now,\n updatedAt: now,\n })\n .onConflictDoNothing({ target: operations.clientOperationId })\n .run().changes === 1;\n const operation = tx\n .select()\n .from(operations)\n .where(eq(operations.clientOperationId, clientOperationId))\n .get();\n if (!operation) throw new Error('Operation insert did not persist');\n if (\n operation.kind !== kind ||\n operation.target !== target ||\n operation.requestDigest !== digest\n ) {\n throw new StoreConflict('OPERATION_CONFLICT', '\u540C\u4E00\u64CD\u4F5C ID \u5DF2\u7528\u4E8E\u4E0D\u540C\u7684\u8BF7\u6C42');\n }\n return { operation, inserted };\n });\n }\n\n get(id: string): OperationRow | undefined {\n return this.database\n .select()\n .from(operations)\n .where(eq(operations.clientOperationId, id))\n .get();\n }\n\n associateProject(id: string, projectId: string): void {\n this.database\n .update(operations)\n .set({ projectId })\n .where(and(eq(operations.clientOperationId, id), eq(operations.state, 'accepted')))\n .run();\n }\n\n /** Includes older rows whose project can be recovered from their stable target/link. */\n pendingProjectOperations(projectId: string): OperationRow[] {\n return this.database\n .select()\n .from(operations)\n .where(\n or(\n eq(operations.state, 'accepted'),\n eq(operations.state, 'dispatching'),\n and(eq(operations.state, 'unknown'), isNull(operations.reconciledAt)),\n ),\n )\n .all()\n .filter((operation) => {\n if (\n ![\n 'thread.create',\n 'thread.resume',\n 'thread.fork',\n 'thread.archive',\n 'thread.rename',\n ].includes(operation.kind)\n )\n return false;\n const owner =\n operation.projectId ??\n (operation.kind === 'thread.create'\n ? operation.target\n : this.getThreadLink(operation.target)?.projectId);\n return owner === projectId;\n });\n }\n\n dispatch(\n id: string,\n marker?: { threadId: string; workspaceKey: string; codexEpoch: string },\n ): void {\n this.database.transaction((tx) => {\n if (marker) {\n const occupied = tx\n .select()\n .from(executionMarkers)\n .where(\n and(isNull(executionMarkers.endedAt), eq(executionMarkers.threadId, marker.threadId)),\n )\n .get();\n if (occupied)\n throw new StoreConflict(\n 'THREAD_BUSY',\n '\u8BE5\u4F1A\u8BDD\u7684\u4E0A\u4E00\u8F6E\u6267\u884C\u5C1A\u672A\u7ED3\u675F\uFF0C\u8BF7\u8FFD\u52A0\u8981\u6C42\u6216\u7B49\u5F85\u7ED3\u675F',\n occupied.threadId,\n );\n }\n const updated = tx\n .update(operations)\n .set({ state: 'dispatching', updatedAt: Date.now() })\n .where(and(eq(operations.clientOperationId, id), eq(operations.state, 'accepted')))\n .run();\n if (updated.changes !== 1)\n throw new StoreConflict('OPERATION_CONFLICT', '\u64CD\u4F5C\u5DF2\u7ECF\u6D3E\u53D1\u6216\u7ED3\u675F');\n if (marker)\n tx.insert(executionMarkers)\n .values({ operationId: id, ...marker, state: 'active', createdAt: Date.now() })\n .run();\n });\n }\n\n acknowledge(id: string, result: unknown, turnId?: string): OperationRow {\n this.database.transaction((tx) => {\n tx.update(operations)\n .set({ state: 'acknowledged', result, error: null, updatedAt: Date.now() })\n .where(and(eq(operations.clientOperationId, id), eq(operations.state, 'dispatching')))\n .run();\n if (turnId !== undefined)\n tx.update(executionMarkers)\n .set({ turnId })\n .where(eq(executionMarkers.operationId, id))\n .run();\n });\n return this.get(id)!;\n }\n\n fail(id: string, error: ApiError, uncertain = false): OperationRow {\n this.database.transaction((tx) => {\n const changed = tx\n .update(operations)\n .set({ state: uncertain ? 'unknown' : 'failed', error, updatedAt: Date.now() })\n .where(\n and(\n eq(operations.clientOperationId, id),\n or(eq(operations.state, 'accepted'), eq(operations.state, 'dispatching')),\n ),\n )\n .run();\n // A late rejection must not turn an already-recovered unknown execution into a release.\n if (changed.changes === 0) return;\n tx.update(executionMarkers)\n .set(uncertain ? { state: 'unknown' } : { state: 'terminal', endedAt: Date.now() })\n .where(and(eq(executionMarkers.operationId, id), isNull(executionMarkers.endedAt)))\n .run();\n });\n return this.get(id)!;\n }\n\n /** Includes acknowledged requests with unfinished turns; none of these are retried. */\n recover(): void {\n this.database.transaction((tx) => {\n tx.update(operations)\n .set({\n state: 'failed',\n error: { code: 'NOT_DISPATCHED', message: '\u670D\u52A1\u5728\u6D3E\u53D1\u524D\u505C\u6B62\uFF1B\u64CD\u4F5C\u6CA1\u6709\u6267\u884C' },\n updatedAt: Date.now(),\n })\n .where(eq(operations.state, 'accepted'))\n .run();\n tx.update(operations)\n .set({\n state: 'unknown',\n error: { code: 'RESULT_UNKNOWN', message: '\u8FD0\u884C\u65F6\u5DF2\u505C\u6B62\uFF0C\u63D0\u4EA4\u7ED3\u679C\u9700\u8981\u6838\u5BF9' },\n updatedAt: Date.now(),\n })\n .where(eq(operations.state, 'dispatching'))\n .run();\n tx.update(executionMarkers)\n .set({ state: 'unknown' })\n .where(isNull(executionMarkers.endedAt))\n .run();\n });\n }\n\n activeMarkers(): ExecutionMarker[] {\n return this.database\n .select()\n .from(executionMarkers)\n .where(isNull(executionMarkers.endedAt))\n .all();\n }\n\n unresolvedOperations(): OperationRow[] {\n return this.database\n .select()\n .from(operations)\n .where(\n or(\n eq(operations.state, 'accepted'),\n eq(operations.state, 'dispatching'),\n and(eq(operations.state, 'unknown'), isNull(operations.reconciledAt)),\n ),\n )\n .all();\n }\n\n marker(operationId: string): ExecutionMarker | undefined {\n return this.database\n .select()\n .from(executionMarkers)\n .where(eq(executionMarkers.operationId, operationId))\n .get();\n }\n\n activeForThread(threadId: string): ExecutionMarker | undefined {\n return this.database\n .select()\n .from(executionMarkers)\n .where(and(eq(executionMarkers.threadId, threadId), isNull(executionMarkers.endedAt)))\n .get();\n }\n\n attachTurn(operationId: string, turnId: string): void {\n this.database\n .update(executionMarkers)\n .set({ turnId })\n .where(and(eq(executionMarkers.operationId, operationId), isNull(executionMarkers.endedAt)))\n .run();\n }\n\n finishTurn(threadId: string, turnId: string, codexEpoch: string): void {\n this.database\n .update(executionMarkers)\n .set({ state: 'terminal', endedAt: Date.now() })\n .where(\n and(\n eq(executionMarkers.threadId, threadId),\n eq(executionMarkers.turnId, turnId),\n eq(executionMarkers.codexEpoch, codexEpoch),\n isNull(executionMarkers.endedAt),\n ),\n )\n .run();\n }\n\n /** Keys the release to the original execution; an old decision cannot unlock a later turn. */\n reconcile(targetOperationId: string, reconciliationOperationId: string): void {\n this.database.transaction((tx) => {\n const now = Date.now();\n tx.update(operations)\n .set({ reconciledAt: now, reconciliationDecision: 'confirmed-ended' })\n .where(\n and(eq(operations.clientOperationId, targetOperationId), isNull(operations.reconciledAt)),\n )\n .run();\n tx.update(executionMarkers)\n .set({ state: 'reconciled', endedAt: now, reconciledAt: now, reconciliationOperationId })\n .where(\n and(\n eq(executionMarkers.operationId, targetOperationId),\n isNull(executionMarkers.endedAt),\n ),\n )\n .run();\n tx.update(operations)\n .set({\n state: 'acknowledged',\n result: { targetOperationId, decision: 'confirmed-ended', reconciledAt: now },\n updatedAt: now,\n })\n .where(\n and(\n eq(operations.clientOperationId, reconciliationOperationId),\n eq(operations.state, 'dispatching'),\n ),\n )\n .run();\n });\n }\n\n linkThread(link: Omit<ThreadLink, 'updatedAt'>): void {\n this.database\n .insert(threadLinks)\n .values({ ...link, updatedAt: Date.now() })\n .onConflictDoUpdate({ target: threadLinks.threadId, set: { ...link, updatedAt: Date.now() } })\n .run();\n }\n\n getThreadLink(threadId: string): ThreadLink | undefined {\n return this.database.select().from(threadLinks).where(eq(threadLinks.threadId, threadId)).get();\n }\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,kBAAkB;AAC3B,SAAS,KAAK,IAAI,QAAQ,UAAU;AAEpC,SAAS,kBAAkB,YAAY,mBAAmB;AAOnD,MAAM,sBAAsB,MAAM;AAAA,EACvC,YACkB,MAChB,SACgB,UAChB;AACA,UAAM,OAAO;AAJG;AAEA;AAAA,EAGlB;AAAA,EALkB;AAAA,EAEA;AAIpB;AAEA,SAAS,UAAU,OAAwB;AACzC,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,IAAI,MAAM,IAAI,SAAS,EAAE,KAAK,GAAG,CAAC;AACnE,MAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;AAC/C,WAAO,IAAI,OAAO,QAAQ,KAAK,EAC5B,OAAO,CAAC,CAAC,EAAE,IAAI,MAAM,SAAS,MAAS,EACvC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,EACrC,IAAI,CAAC,CAAC,KAAK,IAAI,MAAM,GAAG,KAAK,UAAU,GAAG,CAAC,IAAI,UAAU,IAAI,CAAC,EAAE,EAChE,KAAK,GAAG,CAAC;AAAA,EACd;AACA,SAAO,KAAK,UAAU,KAAK,KAAK;AAClC;AAEO,SAAS,cAAc,OAAwB;AACpD,SAAO,WAAW,QAAQ,EAAE,OAAO,UAAU,KAAK,CAAC,EAAE,OAAO,KAAK;AACnE;AAGO,MAAM,eAAe;AAAA,EAC1B,YAA4B,UAAuB;AAAvB;AAAA,EAAwB;AAAA,EAAxB;AAAA,EAE5B,OACE,mBACA,MACA,QACA,SACgD;AAChD,UAAM,SAAS,cAAc,OAAO;AACpC,WAAO,KAAK,SAAS,YAAY,CAAC,OAAO;AACvC,YAAM,MAAM,KAAK,IAAI;AACrB,YAAM,WACJ,GACG,OAAO,UAAU,EACjB,OAAO;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,QACA,eAAe;AAAA,QACf,OAAO;AAAA,QACP,WAAW;AAAA,QACX,WAAW;AAAA,MACb,CAAC,EACA,oBAAoB,EAAE,QAAQ,WAAW,kBAAkB,CAAC,EAC5D,IAAI,EAAE,YAAY;AACvB,YAAM,YAAY,GACf,OAAO,EACP,KAAK,UAAU,EACf,MAAM,GAAG,WAAW,mBAAmB,iBAAiB,CAAC,EACzD,IAAI;AACP,UAAI,CAAC,UAAW,OAAM,IAAI,MAAM,kCAAkC;AAClE,UACE,UAAU,SAAS,QACnB,UAAU,WAAW,UACrB,UAAU,kBAAkB,QAC5B;AACA,cAAM,IAAI,cAAc,sBAAsB,8EAAkB;AAAA,MAClE;AACA,aAAO,EAAE,WAAW,SAAS;AAAA,IAC/B,CAAC;AAAA,EACH;AAAA,EAEA,IAAI,IAAsC;AACxC,WAAO,KAAK,SACT,OAAO,EACP,KAAK,UAAU,EACf,MAAM,GAAG,WAAW,mBAAmB,EAAE,CAAC,EAC1C,IAAI;AAAA,EACT;AAAA,EAEA,iBAAiB,IAAY,
|
|
4
|
+
"sourcesContent": ["import { createHash } from 'node:crypto';\nimport { and, eq, isNull, or } from 'drizzle-orm';\nimport type { AppDatabase } from './index.js';\nimport { executionMarkers, operations, threadLinks } from './schema.js';\nimport type { ApiError } from '../../shared/types.js';\n\nexport type OperationRow = typeof operations.$inferSelect;\nexport type ExecutionMarker = typeof executionMarkers.$inferSelect;\nexport type ThreadLink = typeof threadLinks.$inferSelect;\n\nexport class StoreConflict extends Error {\n constructor(\n public readonly code: 'OPERATION_CONFLICT' | 'THREAD_BUSY',\n message: string,\n public readonly threadId?: string,\n ) {\n super(message);\n }\n}\n\nfunction canonical(value: unknown): string {\n if (Array.isArray(value)) return `[${value.map(canonical).join(',')}]`;\n if (value !== null && typeof value === 'object') {\n return `{${Object.entries(value)\n .filter(([, item]) => item !== undefined)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([key, item]) => `${JSON.stringify(key)}:${canonical(item)}`)\n .join(',')}}`;\n }\n return JSON.stringify(value) ?? 'null';\n}\n\nexport function requestDigest(value: unknown): string {\n return createHash('sha256').update(canonical(value)).digest('hex');\n}\n\n/** Every transaction is synchronous; no process/network work occurs inside one. */\nexport class OperationStore {\n constructor(public readonly database: AppDatabase) {}\n\n accept(\n clientOperationId: string,\n kind: string,\n target: string,\n request: unknown,\n ): { operation: OperationRow; inserted: boolean } {\n const digest = requestDigest(request);\n return this.database.transaction((tx) => {\n const now = Date.now();\n const inserted =\n tx\n .insert(operations)\n .values({\n clientOperationId,\n kind,\n target,\n requestDigest: digest,\n state: 'accepted',\n createdAt: now,\n updatedAt: now,\n })\n .onConflictDoNothing({ target: operations.clientOperationId })\n .run().changes === 1;\n const operation = tx\n .select()\n .from(operations)\n .where(eq(operations.clientOperationId, clientOperationId))\n .get();\n if (!operation) throw new Error('Operation insert did not persist');\n if (\n operation.kind !== kind ||\n operation.target !== target ||\n operation.requestDigest !== digest\n ) {\n throw new StoreConflict('OPERATION_CONFLICT', '\u540C\u4E00\u64CD\u4F5C ID \u5DF2\u7528\u4E8E\u4E0D\u540C\u7684\u8BF7\u6C42');\n }\n return { operation, inserted };\n });\n }\n\n get(id: string): OperationRow | undefined {\n return this.database\n .select()\n .from(operations)\n .where(eq(operations.clientOperationId, id))\n .get();\n }\n\n associateProject(id: string, projectId: string | null): void {\n this.database\n .update(operations)\n .set({ projectId })\n .where(and(eq(operations.clientOperationId, id), eq(operations.state, 'accepted')))\n .run();\n }\n\n /** Includes older rows whose project can be recovered from their stable target/link. */\n pendingProjectOperations(projectId: string | null): OperationRow[] {\n return this.database\n .select()\n .from(operations)\n .where(\n or(\n eq(operations.state, 'accepted'),\n eq(operations.state, 'dispatching'),\n and(eq(operations.state, 'unknown'), isNull(operations.reconciledAt)),\n ),\n )\n .all()\n .filter((operation) => {\n if (\n ![\n 'thread.create',\n 'thread.resume',\n 'thread.fork',\n 'thread.archive',\n 'thread.rename',\n ].includes(operation.kind)\n )\n return false;\n const owner =\n operation.projectId ??\n (operation.kind === 'thread.create'\n ? operation.target === '@unassigned'\n ? null\n : operation.target\n : this.getThreadLink(operation.target)?.projectId);\n return owner === projectId;\n });\n }\n\n dispatch(\n id: string,\n marker?: { threadId: string; workspaceKey: string; codexEpoch: string },\n ): void {\n this.database.transaction((tx) => {\n if (marker) {\n const occupied = tx\n .select()\n .from(executionMarkers)\n .where(\n and(isNull(executionMarkers.endedAt), eq(executionMarkers.threadId, marker.threadId)),\n )\n .get();\n if (occupied)\n throw new StoreConflict(\n 'THREAD_BUSY',\n '\u8BE5\u4F1A\u8BDD\u7684\u4E0A\u4E00\u8F6E\u6267\u884C\u5C1A\u672A\u7ED3\u675F\uFF0C\u8BF7\u8FFD\u52A0\u8981\u6C42\u6216\u7B49\u5F85\u7ED3\u675F',\n occupied.threadId,\n );\n }\n const updated = tx\n .update(operations)\n .set({ state: 'dispatching', updatedAt: Date.now() })\n .where(and(eq(operations.clientOperationId, id), eq(operations.state, 'accepted')))\n .run();\n if (updated.changes !== 1)\n throw new StoreConflict('OPERATION_CONFLICT', '\u64CD\u4F5C\u5DF2\u7ECF\u6D3E\u53D1\u6216\u7ED3\u675F');\n if (marker)\n tx.insert(executionMarkers)\n .values({ operationId: id, ...marker, state: 'active', createdAt: Date.now() })\n .run();\n });\n }\n\n acknowledge(id: string, result: unknown, turnId?: string): OperationRow {\n this.database.transaction((tx) => {\n tx.update(operations)\n .set({ state: 'acknowledged', result, error: null, updatedAt: Date.now() })\n .where(and(eq(operations.clientOperationId, id), eq(operations.state, 'dispatching')))\n .run();\n if (turnId !== undefined)\n tx.update(executionMarkers)\n .set({ turnId })\n .where(eq(executionMarkers.operationId, id))\n .run();\n });\n return this.get(id)!;\n }\n\n confirmWorkspaceCreation(id: string, threadId: string): OperationRow {\n const operation = this.get(id)!;\n this.database\n .update(operations)\n .set({\n state: 'acknowledged',\n error: null,\n updatedAt: Date.now(),\n result: {\n threadId,\n ...(operation.kind === 'thread.fork' ? { forkedFromId: operation.target } : {}),\n },\n })\n .where(and(eq(operations.clientOperationId, id), eq(operations.state, 'unknown')))\n .run();\n return this.get(id)!;\n }\n\n fail(id: string, error: ApiError, uncertain = false): OperationRow {\n this.database.transaction((tx) => {\n const changed = tx\n .update(operations)\n .set({ state: uncertain ? 'unknown' : 'failed', error, updatedAt: Date.now() })\n .where(\n and(\n eq(operations.clientOperationId, id),\n or(eq(operations.state, 'accepted'), eq(operations.state, 'dispatching')),\n ),\n )\n .run();\n // A late rejection must not turn an already-recovered unknown execution into a release.\n if (changed.changes === 0) return;\n tx.update(executionMarkers)\n .set(uncertain ? { state: 'unknown' } : { state: 'terminal', endedAt: Date.now() })\n .where(and(eq(executionMarkers.operationId, id), isNull(executionMarkers.endedAt)))\n .run();\n });\n return this.get(id)!;\n }\n\n /** Includes acknowledged requests with unfinished turns; none of these are retried. */\n recover(): void {\n this.database.transaction((tx) => {\n tx.update(operations)\n .set({\n state: 'failed',\n error: { code: 'NOT_DISPATCHED', message: '\u670D\u52A1\u5728\u6D3E\u53D1\u524D\u505C\u6B62\uFF1B\u64CD\u4F5C\u6CA1\u6709\u6267\u884C' },\n updatedAt: Date.now(),\n })\n .where(eq(operations.state, 'accepted'))\n .run();\n tx.update(operations)\n .set({\n state: 'unknown',\n error: { code: 'RESULT_UNKNOWN', message: '\u8FD0\u884C\u65F6\u5DF2\u505C\u6B62\uFF0C\u63D0\u4EA4\u7ED3\u679C\u9700\u8981\u6838\u5BF9' },\n updatedAt: Date.now(),\n })\n .where(eq(operations.state, 'dispatching'))\n .run();\n tx.update(executionMarkers)\n .set({ state: 'unknown' })\n .where(isNull(executionMarkers.endedAt))\n .run();\n });\n }\n\n activeMarkers(): ExecutionMarker[] {\n return this.database\n .select()\n .from(executionMarkers)\n .where(isNull(executionMarkers.endedAt))\n .all();\n }\n\n unresolvedOperations(): OperationRow[] {\n return this.database\n .select()\n .from(operations)\n .where(\n or(\n eq(operations.state, 'accepted'),\n eq(operations.state, 'dispatching'),\n and(eq(operations.state, 'unknown'), isNull(operations.reconciledAt)),\n ),\n )\n .all();\n }\n\n marker(operationId: string): ExecutionMarker | undefined {\n return this.database\n .select()\n .from(executionMarkers)\n .where(eq(executionMarkers.operationId, operationId))\n .get();\n }\n\n activeForThread(threadId: string): ExecutionMarker | undefined {\n return this.database\n .select()\n .from(executionMarkers)\n .where(and(eq(executionMarkers.threadId, threadId), isNull(executionMarkers.endedAt)))\n .get();\n }\n\n attachTurn(operationId: string, turnId: string): void {\n this.database\n .update(executionMarkers)\n .set({ turnId })\n .where(and(eq(executionMarkers.operationId, operationId), isNull(executionMarkers.endedAt)))\n .run();\n }\n\n finishTurn(threadId: string, turnId: string, codexEpoch: string): void {\n this.database\n .update(executionMarkers)\n .set({ state: 'terminal', endedAt: Date.now() })\n .where(\n and(\n eq(executionMarkers.threadId, threadId),\n eq(executionMarkers.turnId, turnId),\n eq(executionMarkers.codexEpoch, codexEpoch),\n isNull(executionMarkers.endedAt),\n ),\n )\n .run();\n }\n\n /** Keys the release to the original execution; an old decision cannot unlock a later turn. */\n reconcile(targetOperationId: string, reconciliationOperationId: string): void {\n this.database.transaction((tx) => {\n const now = Date.now();\n tx.update(operations)\n .set({ reconciledAt: now, reconciliationDecision: 'confirmed-ended' })\n .where(\n and(eq(operations.clientOperationId, targetOperationId), isNull(operations.reconciledAt)),\n )\n .run();\n tx.update(executionMarkers)\n .set({ state: 'reconciled', endedAt: now, reconciledAt: now, reconciliationOperationId })\n .where(\n and(\n eq(executionMarkers.operationId, targetOperationId),\n isNull(executionMarkers.endedAt),\n ),\n )\n .run();\n tx.update(operations)\n .set({\n state: 'acknowledged',\n result: { targetOperationId, decision: 'confirmed-ended', reconciledAt: now },\n updatedAt: now,\n })\n .where(\n and(\n eq(operations.clientOperationId, reconciliationOperationId),\n eq(operations.state, 'dispatching'),\n ),\n )\n .run();\n });\n }\n\n linkThread(link: Omit<ThreadLink, 'updatedAt'>): void {\n this.database\n .insert(threadLinks)\n .values({ ...link, updatedAt: Date.now() })\n .onConflictDoUpdate({ target: threadLinks.threadId, set: { ...link, updatedAt: Date.now() } })\n .run();\n }\n\n getThreadLink(threadId: string): ThreadLink | undefined {\n return this.database.select().from(threadLinks).where(eq(threadLinks.threadId, threadId)).get();\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/server/db/schema.js
CHANGED
|
@@ -60,12 +60,19 @@ const executionMarkers = sqliteTable(
|
|
|
60
60
|
);
|
|
61
61
|
const threadLinks = sqliteTable("thread_links", {
|
|
62
62
|
threadId: text("thread_id").primaryKey(),
|
|
63
|
-
projectId: text("project_id")
|
|
63
|
+
projectId: text("project_id"),
|
|
64
64
|
cwd: text("cwd").notNull(),
|
|
65
65
|
source: text("source").notNull(),
|
|
66
66
|
managedEpoch: text("managed_epoch"),
|
|
67
67
|
updatedAt: integer("updated_at").notNull()
|
|
68
68
|
});
|
|
69
|
+
const sessionWorkspaces = sqliteTable("session_workspaces", {
|
|
70
|
+
operationId: text("operation_id").primaryKey(),
|
|
71
|
+
threadId: text("thread_id").unique(),
|
|
72
|
+
rootPath: text("root_path").notNull(),
|
|
73
|
+
canonicalRoot: text("canonical_root").notNull().unique(),
|
|
74
|
+
createdAt: integer("created_at").notNull()
|
|
75
|
+
});
|
|
69
76
|
const preferences = sqliteTable("preferences", {
|
|
70
77
|
key: text("key").primaryKey(),
|
|
71
78
|
value: text("value", { mode: "json" }).$type().notNull()
|
|
@@ -93,6 +100,7 @@ export {
|
|
|
93
100
|
operations,
|
|
94
101
|
preferences,
|
|
95
102
|
projectRegistrations,
|
|
103
|
+
sessionWorkspaces,
|
|
96
104
|
threadLinks,
|
|
97
105
|
turnUsage
|
|
98
106
|
};
|