@covro/covro 0.2.1-dev.3 → 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.
Files changed (111) hide show
  1. package/README.md +6 -1
  2. package/README.zh-CN.md +6 -1
  3. package/dist/codex/adapter.js +8 -1
  4. package/dist/codex/adapter.js.map +2 -2
  5. package/dist/drizzle/0005_session_workspaces.sql +24 -0
  6. package/dist/drizzle/meta/0005_snapshot.json +480 -0
  7. package/dist/drizzle/meta/_journal.json +7 -0
  8. package/dist/server/db/operations.js +14 -1
  9. package/dist/server/db/operations.js.map +2 -2
  10. package/dist/server/db/schema.js +9 -1
  11. package/dist/server/db/schema.js.map +2 -2
  12. package/dist/server/http.js +25 -0
  13. package/dist/server/http.js.map +2 -2
  14. package/dist/server/local-files.js +2 -2
  15. package/dist/server/local-files.js.map +2 -2
  16. package/dist/server/main.js +1 -0
  17. package/dist/server/main.js.map +2 -2
  18. package/dist/server/service.js +96 -51
  19. package/dist/server/service.js.map +2 -2
  20. package/dist/server/workspaces.js +138 -0
  21. package/dist/server/workspaces.js.map +7 -0
  22. package/dist/shared/workspace-scope.js +9 -0
  23. package/dist/shared/workspace-scope.js.map +7 -0
  24. package/dist/web/assets/{abnfDiagram-WEYOIA3C-6n1mVJ0V.js → abnfDiagram-WEYOIA3C-DTTcFQGL.js} +1 -1
  25. package/dist/web/assets/{arc-DFIzIYgQ.js → arc-K2pKIwfu.js} +1 -1
  26. package/dist/web/assets/{architecture-WOLXFQ4H-CoZpoP0F.js → architecture-WOLXFQ4H-DrxN_1CG.js} +1 -1
  27. package/dist/web/assets/{architectureDiagram-ZHVYKT53-LcqVhgRh.js → architectureDiagram-ZHVYKT53-CyyCrVAb.js} +1 -1
  28. package/dist/web/assets/{blockDiagram-RJAE7QA3-CnVQsmM8.js → blockDiagram-RJAE7QA3-C8vl8QXS.js} +1 -1
  29. package/dist/web/assets/{c4Diagram-XDPPPE54-C38UO-rV.js → c4Diagram-XDPPPE54-BtnIITFN.js} +1 -1
  30. package/dist/web/assets/channel-CDExoPVe.js +1 -0
  31. package/dist/web/assets/{chunk-2E7WHVMD-SlpXCVVC.js → chunk-2E7WHVMD-BssauSch.js} +1 -1
  32. package/dist/web/assets/{chunk-4EMNKR2T-BPJa0lfJ.js → chunk-4EMNKR2T-BZOo1RWg.js} +1 -1
  33. package/dist/web/assets/{chunk-55XCU76K-CkP_cE5N.js → chunk-55XCU76K-D8ZWazMQ.js} +1 -1
  34. package/dist/web/assets/{chunk-7S6XSTFO-BnrWU32l.js → chunk-7S6XSTFO-C8WqPzUl.js} +1 -1
  35. package/dist/web/assets/{chunk-AQDTSKZB-J2M9tBY-.js → chunk-AQDTSKZB-Coo6Axpg.js} +1 -1
  36. package/dist/web/assets/{chunk-DSNLSHJZ-ClfNpgVO.js → chunk-DSNLSHJZ-5TwmEPWR.js} +1 -1
  37. package/dist/web/assets/{chunk-HAGFOTED-k7XcZqWB.js → chunk-HAGFOTED-Dgtj-Fc_.js} +1 -1
  38. package/dist/web/assets/{chunk-HNE4Q36P-DHHenyG4.js → chunk-HNE4Q36P-COoS4UPL.js} +1 -1
  39. package/dist/web/assets/{chunk-NQOKRVIF-CkA3TLYc.js → chunk-NQOKRVIF-tPhNkBBj.js} +1 -1
  40. package/dist/web/assets/{chunk-UHW7PFBP-DSLKZJoJ.js → chunk-UHW7PFBP-BLk_BkCl.js} +1 -1
  41. package/dist/web/assets/{chunk-VQ5W62QI-BBkSWILl.js → chunk-VQ5W62QI-HBeSVTU0.js} +1 -1
  42. package/dist/web/assets/{chunk-WQQL4CDK-BeKgda0U.js → chunk-WQQL4CDK-LmZUm8If.js} +1 -1
  43. package/dist/web/assets/{chunk-XXDRQBXY-BC-ozzjn.js → chunk-XXDRQBXY-49rKU8Nk.js} +1 -1
  44. package/dist/web/assets/{chunk-YZO67HFG-C19e3AP5.js → chunk-YZO67HFG-B_TgpaEG.js} +1 -1
  45. package/dist/web/assets/{chunk-ZAUX2LTX-C03NsQfr.js → chunk-ZAUX2LTX-f7-DSOrY.js} +1 -1
  46. package/dist/web/assets/{chunk-ZCHMQSOR-CrXzPEWh.js → chunk-ZCHMQSOR-QhJOh7x0.js} +1 -1
  47. package/dist/web/assets/{classDiagram-v2-4MYWR3UA-DCbxTUm6.js → classDiagram-v2-4MYWR3UA-CwF2HuoZ.js} +1 -1
  48. package/dist/web/assets/{cose-bilkent-JH36ORCC-CQZjK1BR.js → cose-bilkent-JH36ORCC-CLvKOlx5.js} +1 -1
  49. package/dist/web/assets/{cynefin-EF2NZ3EQ-i1jWxeqI.js → cynefin-EF2NZ3EQ-BNRVavZN.js} +1 -1
  50. package/dist/web/assets/{cynefinDiagram-WF24UDRP-DfVYiPE9.js → cynefinDiagram-WF24UDRP-DEd83kgI.js} +1 -1
  51. package/dist/web/assets/{dagre-NK4GIZVX-OhkyZBvK.js → dagre-NK4GIZVX-C340UEI3.js} +1 -1
  52. package/dist/web/assets/{diagram-CBK3MWTC-CXdVEIne.js → diagram-CBK3MWTC-CuN7ncUm.js} +1 -1
  53. package/dist/web/assets/{diagram-I5XIIV2D-BjrxVPW0.js → diagram-I5XIIV2D-D9mGAfA7.js} +1 -1
  54. package/dist/web/assets/{diagram-ODIL2UCW-C5BpAqPG.js → diagram-ODIL2UCW-CXtBv4bI.js} +1 -1
  55. package/dist/web/assets/{diagram-PFBEJUXE-3yWOE5ZP.js → diagram-PFBEJUXE-B8qP5nGT.js} +1 -1
  56. package/dist/web/assets/{diagram-RJA3I4VV-DdRZojn9.js → diagram-RJA3I4VV-BVrzsw2b.js} +1 -1
  57. package/dist/web/assets/{diagram-TYUNFSNR-m_gnI0-3.js → diagram-TYUNFSNR-Djfine3D.js} +1 -1
  58. package/dist/web/assets/{dist-DMGebNoK.js → dist-D8kDnYqD.js} +1 -1
  59. package/dist/web/assets/{ebnfDiagram-V4P3TTPT-CVwc9K-O.js → ebnfDiagram-V4P3TTPT-C69Oiekp.js} +1 -1
  60. package/dist/web/assets/{elk-QONTBCTQ-BDC-J8E3.js → elk-QONTBCTQ-Bd3BP1h1.js} +1 -1
  61. package/dist/web/assets/{erDiagram-KYQIGQAA-D-dqUb0a.js → erDiagram-KYQIGQAA-Dxcl5jVl.js} +1 -1
  62. package/dist/web/assets/{eventmodeling-K75KTNOO-ByZ_MfSZ.js → eventmodeling-K75KTNOO-Do8p535i.js} +1 -1
  63. package/dist/web/assets/flowDiagram-IUGLLWBU-X85uzgrG.js +1 -0
  64. package/dist/web/assets/{ganttDiagram-R7GPNTJY-BHzyPnqV.js → ganttDiagram-R7GPNTJY-MBGUZbVy.js} +1 -1
  65. package/dist/web/assets/{gitGraph-VSP46ZUC-DQhxrj3o.js → gitGraph-VSP46ZUC-CHxRIbkg.js} +1 -1
  66. package/dist/web/assets/{gitGraphDiagram-PDYL7XHY-8M2oNXTx.js → gitGraphDiagram-PDYL7XHY-DbW0GeW4.js} +1 -1
  67. package/dist/web/assets/index-Cz3AOJOw.js +142 -0
  68. package/dist/web/assets/index-DaMLk_sl.css +1 -0
  69. package/dist/web/assets/{info-OHQRW6UA-717A6Kfa.js → info-OHQRW6UA-K8BF1xZb.js} +1 -1
  70. package/dist/web/assets/{infoDiagram-MVDRKAX5-D-fxOvE-.js → infoDiagram-MVDRKAX5-QaWV5-SY.js} +1 -1
  71. package/dist/web/assets/{ishikawaDiagram-HPEHV2GE-CKrXOGrR.js → ishikawaDiagram-HPEHV2GE-DpVz_sC0.js} +1 -1
  72. package/dist/web/assets/{journeyDiagram-BOSHW7O7-BLD4lmI6.js → journeyDiagram-BOSHW7O7-S9MzozV7.js} +1 -1
  73. package/dist/web/assets/{kanban-definition-FNSA4HC5-Mj1GI5Fb.js → kanban-definition-FNSA4HC5-BiU8Ibw-.js} +1 -1
  74. package/dist/web/assets/{line-DotNyRbu.js → line-B1KaX5ms.js} +1 -1
  75. package/dist/web/assets/{linear-DQ0Uvp2K.js → linear-Cg1dwAtU.js} +1 -1
  76. package/dist/web/assets/{mermaid-parser.core-BtFC_UVn.js → mermaid-parser.core-hzYHYxfI.js} +3 -3
  77. package/dist/web/assets/{mermaid.core-DHL14mKq.js → mermaid.core-N8xYYvXy.js} +4 -4
  78. package/dist/web/assets/{mindmap-definition-6OY57UG3-CMCguBhk.js → mindmap-definition-6OY57UG3-BmIQCrEd.js} +1 -1
  79. package/dist/web/assets/{packet-JDAUHWVQ-CGyEqUmo.js → packet-JDAUHWVQ-DhOTX9De.js} +1 -1
  80. package/dist/web/assets/{pegDiagram-ECIUJNBX-DPgLxTHJ.js → pegDiagram-ECIUJNBX-CVfE6yUu.js} +1 -1
  81. package/dist/web/assets/{pie-XZMESJXO-Ddsl6geS.js → pie-XZMESJXO-BayfKVL8.js} +1 -1
  82. package/dist/web/assets/{pieDiagram-GNMPY74T-BJdkqrU_.js → pieDiagram-GNMPY74T-ClbMRve3.js} +1 -1
  83. package/dist/web/assets/{quadrantDiagram-D57K4MC3-47l23gov.js → quadrantDiagram-D57K4MC3-DFp-P_EZ.js} +1 -1
  84. package/dist/web/assets/{radar-ABXABTNO-DAyB1li0.js → radar-ABXABTNO-Bt1EAsxC.js} +1 -1
  85. package/dist/web/assets/{railroad-I3PHUGI6-BZYuBfPR.js → railroad-I3PHUGI6-CSos2Rm9.js} +1 -1
  86. package/dist/web/assets/{railroad-abnf-LNEFI6M7-PBkoxIWP.js → railroad-abnf-LNEFI6M7-CebY-3Kh.js} +1 -1
  87. package/dist/web/assets/{railroad-ebnf-DWYD2UWJ-Bl_rTgpR.js → railroad-ebnf-DWYD2UWJ-DpA6-TBs.js} +1 -1
  88. package/dist/web/assets/{railroad-peg-JR7BVNR7-U9kj7aP3.js → railroad-peg-JR7BVNR7-Bg3QPvi5.js} +1 -1
  89. package/dist/web/assets/{railroadDiagram-Y72NRBL7-Dpq4us5_.js → railroadDiagram-Y72NRBL7-BM4RAgqS.js} +1 -1
  90. package/dist/web/assets/{requirementDiagram-EQYSW5RA-CCqQbcTz.js → requirementDiagram-EQYSW5RA-CqP9bCS_.js} +1 -1
  91. package/dist/web/assets/{sankeyDiagram-SY24JHO5-DDwytZM3.js → sankeyDiagram-SY24JHO5-BhS8f6-k.js} +1 -1
  92. package/dist/web/assets/{sequenceDiagram-BLEHNHQU-C-z57Y06.js → sequenceDiagram-BLEHNHQU-p3C1DgeC.js} +1 -1
  93. package/dist/web/assets/{src-CK51kAyQ.js → src-9XJAFibc.js} +1 -1
  94. package/dist/web/assets/{stateDiagram-v2-A6IESKWZ-DgTp0O6g.js → stateDiagram-v2-A6IESKWZ-DVVy8chY.js} +1 -1
  95. package/dist/web/assets/{swimlanes-B3ENRKFQ-BiyS7wH3.js → swimlanes-B3ENRKFQ-CtMPO6Gw.js} +1 -1
  96. package/dist/web/assets/swimlanesDiagram-AYQRV4AK-BRXJWgnO.js +8 -0
  97. package/dist/web/assets/{timeline-definition-JXYKGLGB-D_PAPA8Z.js → timeline-definition-JXYKGLGB-DuTqpjLQ.js} +1 -1
  98. package/dist/web/assets/{treeView-D4JQ5SDB-m1fbOydD.js → treeView-D4JQ5SDB-qpOZEphu.js} +1 -1
  99. package/dist/web/assets/{treemap-SAJKECNS-Bxt7Udu9.js → treemap-SAJKECNS-Dm6e3TpG.js} +1 -1
  100. package/dist/web/assets/{usecaseDiagram-WPOLBNNX-BTrMcoPL.js → usecaseDiagram-WPOLBNNX-DoCSdm5y.js} +1 -1
  101. package/dist/web/assets/{vennDiagram-Q3Y3IDCW-C_kOOxPJ.js → vennDiagram-Q3Y3IDCW-qzd4yvh5.js} +1 -1
  102. package/dist/web/assets/{wardley-7MLQ67FV-C33rdYbB.js → wardley-7MLQ67FV-CkcgIQgQ.js} +1 -1
  103. package/dist/web/assets/{wardleyDiagram-IVAIDKWA-DpG2rl09.js → wardleyDiagram-IVAIDKWA-CE6OR9hA.js} +1 -1
  104. package/dist/web/assets/{xychartDiagram-4URNHDU4-5a7LnsSZ.js → xychartDiagram-4URNHDU4-OrFXHVc6.js} +1 -1
  105. package/dist/web/index.html +2 -2
  106. package/package.json +3 -3
  107. package/dist/web/assets/channel-CV6Myu73.js +0 -1
  108. package/dist/web/assets/flowDiagram-IUGLLWBU-CiUTloqN.js +0 -1
  109. package/dist/web/assets/index-DYwdlB-_.js +0 -142
  110. package/dist/web/assets/index-TP24ydrn.css +0 -1
  111. package/dist/web/assets/swimlanesDiagram-AYQRV4AK-DJ90Jhqq.js +0 -8
@@ -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
+ }
@@ -36,6 +36,13 @@
36
36
  "when": 1792166745097,
37
37
  "tag": "0004_turn_usage",
38
38
  "breakpoints": true
39
+ },
40
+ {
41
+ "idx": 5,
42
+ "version": "6",
43
+ "when": 1792508483748,
44
+ "tag": "0005_session_workspaces",
45
+ "breakpoints": true
39
46
  }
40
47
  ]
41
48
  }
@@ -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": "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",
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
  }
@@ -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").notNull(),
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
  };