@schoolai/shipyard-mcp 0.1.0
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/LICENSE.md +105 -0
- package/README.md +221 -0
- package/apps/hook/README.md +273 -0
- package/apps/hook/dist/index.js +3078 -0
- package/apps/server/.env.example +20 -0
- package/apps/server/dist/chunk-7GPZDCWI.js +158 -0
- package/apps/server/dist/chunk-EBNL5ZX7.js +120 -0
- package/apps/server/dist/chunk-GSGLHRWX.js +62 -0
- package/apps/server/dist/chunk-JSBRDJBE.js +30 -0
- package/apps/server/dist/chunk-LTC26IRQ.js +2930 -0
- package/apps/server/dist/chunk-SIQIBECG.js +273 -0
- package/apps/server/dist/dist-LQBXUHLR.js +409 -0
- package/apps/server/dist/index.js +5450 -0
- package/apps/server/dist/input-request-manager-YVKAMQPF.js +9 -0
- package/apps/server/dist/server-identity-KUXYHULN.js +10 -0
- package/apps/server/dist/session-registry-DMV543RG.js +40 -0
- package/package.json +74 -0
|
@@ -0,0 +1,2930 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__commonJS,
|
|
3
|
+
__toESM
|
|
4
|
+
} from "./chunk-JSBRDJBE.js";
|
|
5
|
+
|
|
6
|
+
// ../../node_modules/.pnpm/lz-string@1.5.0/node_modules/lz-string/libs/lz-string.js
|
|
7
|
+
var require_lz_string = __commonJS({
|
|
8
|
+
"../../node_modules/.pnpm/lz-string@1.5.0/node_modules/lz-string/libs/lz-string.js"(exports, module) {
|
|
9
|
+
"use strict";
|
|
10
|
+
var LZString = (function() {
|
|
11
|
+
var f = String.fromCharCode;
|
|
12
|
+
var keyStrBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
|
13
|
+
var keyStrUriSafe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$";
|
|
14
|
+
var baseReverseDic = {};
|
|
15
|
+
function getBaseValue(alphabet, character) {
|
|
16
|
+
if (!baseReverseDic[alphabet]) {
|
|
17
|
+
baseReverseDic[alphabet] = {};
|
|
18
|
+
for (var i = 0; i < alphabet.length; i++) {
|
|
19
|
+
baseReverseDic[alphabet][alphabet.charAt(i)] = i;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return baseReverseDic[alphabet][character];
|
|
23
|
+
}
|
|
24
|
+
var LZString2 = {
|
|
25
|
+
compressToBase64: function(input) {
|
|
26
|
+
if (input == null) return "";
|
|
27
|
+
var res = LZString2._compress(input, 6, function(a) {
|
|
28
|
+
return keyStrBase64.charAt(a);
|
|
29
|
+
});
|
|
30
|
+
switch (res.length % 4) {
|
|
31
|
+
// To produce valid Base64
|
|
32
|
+
default:
|
|
33
|
+
// When could this happen ?
|
|
34
|
+
case 0:
|
|
35
|
+
return res;
|
|
36
|
+
case 1:
|
|
37
|
+
return res + "===";
|
|
38
|
+
case 2:
|
|
39
|
+
return res + "==";
|
|
40
|
+
case 3:
|
|
41
|
+
return res + "=";
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
decompressFromBase64: function(input) {
|
|
45
|
+
if (input == null) return "";
|
|
46
|
+
if (input == "") return null;
|
|
47
|
+
return LZString2._decompress(input.length, 32, function(index) {
|
|
48
|
+
return getBaseValue(keyStrBase64, input.charAt(index));
|
|
49
|
+
});
|
|
50
|
+
},
|
|
51
|
+
compressToUTF16: function(input) {
|
|
52
|
+
if (input == null) return "";
|
|
53
|
+
return LZString2._compress(input, 15, function(a) {
|
|
54
|
+
return f(a + 32);
|
|
55
|
+
}) + " ";
|
|
56
|
+
},
|
|
57
|
+
decompressFromUTF16: function(compressed) {
|
|
58
|
+
if (compressed == null) return "";
|
|
59
|
+
if (compressed == "") return null;
|
|
60
|
+
return LZString2._decompress(compressed.length, 16384, function(index) {
|
|
61
|
+
return compressed.charCodeAt(index) - 32;
|
|
62
|
+
});
|
|
63
|
+
},
|
|
64
|
+
//compress into uint8array (UCS-2 big endian format)
|
|
65
|
+
compressToUint8Array: function(uncompressed) {
|
|
66
|
+
var compressed = LZString2.compress(uncompressed);
|
|
67
|
+
var buf = new Uint8Array(compressed.length * 2);
|
|
68
|
+
for (var i = 0, TotalLen = compressed.length; i < TotalLen; i++) {
|
|
69
|
+
var current_value = compressed.charCodeAt(i);
|
|
70
|
+
buf[i * 2] = current_value >>> 8;
|
|
71
|
+
buf[i * 2 + 1] = current_value % 256;
|
|
72
|
+
}
|
|
73
|
+
return buf;
|
|
74
|
+
},
|
|
75
|
+
//decompress from uint8array (UCS-2 big endian format)
|
|
76
|
+
decompressFromUint8Array: function(compressed) {
|
|
77
|
+
if (compressed === null || compressed === void 0) {
|
|
78
|
+
return LZString2.decompress(compressed);
|
|
79
|
+
} else {
|
|
80
|
+
var buf = new Array(compressed.length / 2);
|
|
81
|
+
for (var i = 0, TotalLen = buf.length; i < TotalLen; i++) {
|
|
82
|
+
buf[i] = compressed[i * 2] * 256 + compressed[i * 2 + 1];
|
|
83
|
+
}
|
|
84
|
+
var result = [];
|
|
85
|
+
buf.forEach(function(c) {
|
|
86
|
+
result.push(f(c));
|
|
87
|
+
});
|
|
88
|
+
return LZString2.decompress(result.join(""));
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
//compress into a string that is already URI encoded
|
|
92
|
+
compressToEncodedURIComponent: function(input) {
|
|
93
|
+
if (input == null) return "";
|
|
94
|
+
return LZString2._compress(input, 6, function(a) {
|
|
95
|
+
return keyStrUriSafe.charAt(a);
|
|
96
|
+
});
|
|
97
|
+
},
|
|
98
|
+
//decompress from an output of compressToEncodedURIComponent
|
|
99
|
+
decompressFromEncodedURIComponent: function(input) {
|
|
100
|
+
if (input == null) return "";
|
|
101
|
+
if (input == "") return null;
|
|
102
|
+
input = input.replace(/ /g, "+");
|
|
103
|
+
return LZString2._decompress(input.length, 32, function(index) {
|
|
104
|
+
return getBaseValue(keyStrUriSafe, input.charAt(index));
|
|
105
|
+
});
|
|
106
|
+
},
|
|
107
|
+
compress: function(uncompressed) {
|
|
108
|
+
return LZString2._compress(uncompressed, 16, function(a) {
|
|
109
|
+
return f(a);
|
|
110
|
+
});
|
|
111
|
+
},
|
|
112
|
+
_compress: function(uncompressed, bitsPerChar, getCharFromInt) {
|
|
113
|
+
if (uncompressed == null) return "";
|
|
114
|
+
var i, value, context_dictionary = {}, context_dictionaryToCreate = {}, context_c = "", context_wc = "", context_w = "", context_enlargeIn = 2, context_dictSize = 3, context_numBits = 2, context_data = [], context_data_val = 0, context_data_position = 0, ii;
|
|
115
|
+
for (ii = 0; ii < uncompressed.length; ii += 1) {
|
|
116
|
+
context_c = uncompressed.charAt(ii);
|
|
117
|
+
if (!Object.prototype.hasOwnProperty.call(context_dictionary, context_c)) {
|
|
118
|
+
context_dictionary[context_c] = context_dictSize++;
|
|
119
|
+
context_dictionaryToCreate[context_c] = true;
|
|
120
|
+
}
|
|
121
|
+
context_wc = context_w + context_c;
|
|
122
|
+
if (Object.prototype.hasOwnProperty.call(context_dictionary, context_wc)) {
|
|
123
|
+
context_w = context_wc;
|
|
124
|
+
} else {
|
|
125
|
+
if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate, context_w)) {
|
|
126
|
+
if (context_w.charCodeAt(0) < 256) {
|
|
127
|
+
for (i = 0; i < context_numBits; i++) {
|
|
128
|
+
context_data_val = context_data_val << 1;
|
|
129
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
130
|
+
context_data_position = 0;
|
|
131
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
132
|
+
context_data_val = 0;
|
|
133
|
+
} else {
|
|
134
|
+
context_data_position++;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
value = context_w.charCodeAt(0);
|
|
138
|
+
for (i = 0; i < 8; i++) {
|
|
139
|
+
context_data_val = context_data_val << 1 | value & 1;
|
|
140
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
141
|
+
context_data_position = 0;
|
|
142
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
143
|
+
context_data_val = 0;
|
|
144
|
+
} else {
|
|
145
|
+
context_data_position++;
|
|
146
|
+
}
|
|
147
|
+
value = value >> 1;
|
|
148
|
+
}
|
|
149
|
+
} else {
|
|
150
|
+
value = 1;
|
|
151
|
+
for (i = 0; i < context_numBits; i++) {
|
|
152
|
+
context_data_val = context_data_val << 1 | value;
|
|
153
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
154
|
+
context_data_position = 0;
|
|
155
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
156
|
+
context_data_val = 0;
|
|
157
|
+
} else {
|
|
158
|
+
context_data_position++;
|
|
159
|
+
}
|
|
160
|
+
value = 0;
|
|
161
|
+
}
|
|
162
|
+
value = context_w.charCodeAt(0);
|
|
163
|
+
for (i = 0; i < 16; i++) {
|
|
164
|
+
context_data_val = context_data_val << 1 | value & 1;
|
|
165
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
166
|
+
context_data_position = 0;
|
|
167
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
168
|
+
context_data_val = 0;
|
|
169
|
+
} else {
|
|
170
|
+
context_data_position++;
|
|
171
|
+
}
|
|
172
|
+
value = value >> 1;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
context_enlargeIn--;
|
|
176
|
+
if (context_enlargeIn == 0) {
|
|
177
|
+
context_enlargeIn = Math.pow(2, context_numBits);
|
|
178
|
+
context_numBits++;
|
|
179
|
+
}
|
|
180
|
+
delete context_dictionaryToCreate[context_w];
|
|
181
|
+
} else {
|
|
182
|
+
value = context_dictionary[context_w];
|
|
183
|
+
for (i = 0; i < context_numBits; i++) {
|
|
184
|
+
context_data_val = context_data_val << 1 | value & 1;
|
|
185
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
186
|
+
context_data_position = 0;
|
|
187
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
188
|
+
context_data_val = 0;
|
|
189
|
+
} else {
|
|
190
|
+
context_data_position++;
|
|
191
|
+
}
|
|
192
|
+
value = value >> 1;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
context_enlargeIn--;
|
|
196
|
+
if (context_enlargeIn == 0) {
|
|
197
|
+
context_enlargeIn = Math.pow(2, context_numBits);
|
|
198
|
+
context_numBits++;
|
|
199
|
+
}
|
|
200
|
+
context_dictionary[context_wc] = context_dictSize++;
|
|
201
|
+
context_w = String(context_c);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
if (context_w !== "") {
|
|
205
|
+
if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate, context_w)) {
|
|
206
|
+
if (context_w.charCodeAt(0) < 256) {
|
|
207
|
+
for (i = 0; i < context_numBits; i++) {
|
|
208
|
+
context_data_val = context_data_val << 1;
|
|
209
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
210
|
+
context_data_position = 0;
|
|
211
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
212
|
+
context_data_val = 0;
|
|
213
|
+
} else {
|
|
214
|
+
context_data_position++;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
value = context_w.charCodeAt(0);
|
|
218
|
+
for (i = 0; i < 8; i++) {
|
|
219
|
+
context_data_val = context_data_val << 1 | value & 1;
|
|
220
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
221
|
+
context_data_position = 0;
|
|
222
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
223
|
+
context_data_val = 0;
|
|
224
|
+
} else {
|
|
225
|
+
context_data_position++;
|
|
226
|
+
}
|
|
227
|
+
value = value >> 1;
|
|
228
|
+
}
|
|
229
|
+
} else {
|
|
230
|
+
value = 1;
|
|
231
|
+
for (i = 0; i < context_numBits; i++) {
|
|
232
|
+
context_data_val = context_data_val << 1 | value;
|
|
233
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
234
|
+
context_data_position = 0;
|
|
235
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
236
|
+
context_data_val = 0;
|
|
237
|
+
} else {
|
|
238
|
+
context_data_position++;
|
|
239
|
+
}
|
|
240
|
+
value = 0;
|
|
241
|
+
}
|
|
242
|
+
value = context_w.charCodeAt(0);
|
|
243
|
+
for (i = 0; i < 16; i++) {
|
|
244
|
+
context_data_val = context_data_val << 1 | value & 1;
|
|
245
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
246
|
+
context_data_position = 0;
|
|
247
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
248
|
+
context_data_val = 0;
|
|
249
|
+
} else {
|
|
250
|
+
context_data_position++;
|
|
251
|
+
}
|
|
252
|
+
value = value >> 1;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
context_enlargeIn--;
|
|
256
|
+
if (context_enlargeIn == 0) {
|
|
257
|
+
context_enlargeIn = Math.pow(2, context_numBits);
|
|
258
|
+
context_numBits++;
|
|
259
|
+
}
|
|
260
|
+
delete context_dictionaryToCreate[context_w];
|
|
261
|
+
} else {
|
|
262
|
+
value = context_dictionary[context_w];
|
|
263
|
+
for (i = 0; i < context_numBits; i++) {
|
|
264
|
+
context_data_val = context_data_val << 1 | value & 1;
|
|
265
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
266
|
+
context_data_position = 0;
|
|
267
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
268
|
+
context_data_val = 0;
|
|
269
|
+
} else {
|
|
270
|
+
context_data_position++;
|
|
271
|
+
}
|
|
272
|
+
value = value >> 1;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
context_enlargeIn--;
|
|
276
|
+
if (context_enlargeIn == 0) {
|
|
277
|
+
context_enlargeIn = Math.pow(2, context_numBits);
|
|
278
|
+
context_numBits++;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
value = 2;
|
|
282
|
+
for (i = 0; i < context_numBits; i++) {
|
|
283
|
+
context_data_val = context_data_val << 1 | value & 1;
|
|
284
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
285
|
+
context_data_position = 0;
|
|
286
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
287
|
+
context_data_val = 0;
|
|
288
|
+
} else {
|
|
289
|
+
context_data_position++;
|
|
290
|
+
}
|
|
291
|
+
value = value >> 1;
|
|
292
|
+
}
|
|
293
|
+
while (true) {
|
|
294
|
+
context_data_val = context_data_val << 1;
|
|
295
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
296
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
297
|
+
break;
|
|
298
|
+
} else context_data_position++;
|
|
299
|
+
}
|
|
300
|
+
return context_data.join("");
|
|
301
|
+
},
|
|
302
|
+
decompress: function(compressed) {
|
|
303
|
+
if (compressed == null) return "";
|
|
304
|
+
if (compressed == "") return null;
|
|
305
|
+
return LZString2._decompress(compressed.length, 32768, function(index) {
|
|
306
|
+
return compressed.charCodeAt(index);
|
|
307
|
+
});
|
|
308
|
+
},
|
|
309
|
+
_decompress: function(length, resetValue, getNextValue) {
|
|
310
|
+
var dictionary = [], next, enlargeIn = 4, dictSize = 4, numBits = 3, entry = "", result = [], i, w, bits, resb, maxpower, power, c, data = { val: getNextValue(0), position: resetValue, index: 1 };
|
|
311
|
+
for (i = 0; i < 3; i += 1) {
|
|
312
|
+
dictionary[i] = i;
|
|
313
|
+
}
|
|
314
|
+
bits = 0;
|
|
315
|
+
maxpower = Math.pow(2, 2);
|
|
316
|
+
power = 1;
|
|
317
|
+
while (power != maxpower) {
|
|
318
|
+
resb = data.val & data.position;
|
|
319
|
+
data.position >>= 1;
|
|
320
|
+
if (data.position == 0) {
|
|
321
|
+
data.position = resetValue;
|
|
322
|
+
data.val = getNextValue(data.index++);
|
|
323
|
+
}
|
|
324
|
+
bits |= (resb > 0 ? 1 : 0) * power;
|
|
325
|
+
power <<= 1;
|
|
326
|
+
}
|
|
327
|
+
switch (next = bits) {
|
|
328
|
+
case 0:
|
|
329
|
+
bits = 0;
|
|
330
|
+
maxpower = Math.pow(2, 8);
|
|
331
|
+
power = 1;
|
|
332
|
+
while (power != maxpower) {
|
|
333
|
+
resb = data.val & data.position;
|
|
334
|
+
data.position >>= 1;
|
|
335
|
+
if (data.position == 0) {
|
|
336
|
+
data.position = resetValue;
|
|
337
|
+
data.val = getNextValue(data.index++);
|
|
338
|
+
}
|
|
339
|
+
bits |= (resb > 0 ? 1 : 0) * power;
|
|
340
|
+
power <<= 1;
|
|
341
|
+
}
|
|
342
|
+
c = f(bits);
|
|
343
|
+
break;
|
|
344
|
+
case 1:
|
|
345
|
+
bits = 0;
|
|
346
|
+
maxpower = Math.pow(2, 16);
|
|
347
|
+
power = 1;
|
|
348
|
+
while (power != maxpower) {
|
|
349
|
+
resb = data.val & data.position;
|
|
350
|
+
data.position >>= 1;
|
|
351
|
+
if (data.position == 0) {
|
|
352
|
+
data.position = resetValue;
|
|
353
|
+
data.val = getNextValue(data.index++);
|
|
354
|
+
}
|
|
355
|
+
bits |= (resb > 0 ? 1 : 0) * power;
|
|
356
|
+
power <<= 1;
|
|
357
|
+
}
|
|
358
|
+
c = f(bits);
|
|
359
|
+
break;
|
|
360
|
+
case 2:
|
|
361
|
+
return "";
|
|
362
|
+
}
|
|
363
|
+
dictionary[3] = c;
|
|
364
|
+
w = c;
|
|
365
|
+
result.push(c);
|
|
366
|
+
while (true) {
|
|
367
|
+
if (data.index > length) {
|
|
368
|
+
return "";
|
|
369
|
+
}
|
|
370
|
+
bits = 0;
|
|
371
|
+
maxpower = Math.pow(2, numBits);
|
|
372
|
+
power = 1;
|
|
373
|
+
while (power != maxpower) {
|
|
374
|
+
resb = data.val & data.position;
|
|
375
|
+
data.position >>= 1;
|
|
376
|
+
if (data.position == 0) {
|
|
377
|
+
data.position = resetValue;
|
|
378
|
+
data.val = getNextValue(data.index++);
|
|
379
|
+
}
|
|
380
|
+
bits |= (resb > 0 ? 1 : 0) * power;
|
|
381
|
+
power <<= 1;
|
|
382
|
+
}
|
|
383
|
+
switch (c = bits) {
|
|
384
|
+
case 0:
|
|
385
|
+
bits = 0;
|
|
386
|
+
maxpower = Math.pow(2, 8);
|
|
387
|
+
power = 1;
|
|
388
|
+
while (power != maxpower) {
|
|
389
|
+
resb = data.val & data.position;
|
|
390
|
+
data.position >>= 1;
|
|
391
|
+
if (data.position == 0) {
|
|
392
|
+
data.position = resetValue;
|
|
393
|
+
data.val = getNextValue(data.index++);
|
|
394
|
+
}
|
|
395
|
+
bits |= (resb > 0 ? 1 : 0) * power;
|
|
396
|
+
power <<= 1;
|
|
397
|
+
}
|
|
398
|
+
dictionary[dictSize++] = f(bits);
|
|
399
|
+
c = dictSize - 1;
|
|
400
|
+
enlargeIn--;
|
|
401
|
+
break;
|
|
402
|
+
case 1:
|
|
403
|
+
bits = 0;
|
|
404
|
+
maxpower = Math.pow(2, 16);
|
|
405
|
+
power = 1;
|
|
406
|
+
while (power != maxpower) {
|
|
407
|
+
resb = data.val & data.position;
|
|
408
|
+
data.position >>= 1;
|
|
409
|
+
if (data.position == 0) {
|
|
410
|
+
data.position = resetValue;
|
|
411
|
+
data.val = getNextValue(data.index++);
|
|
412
|
+
}
|
|
413
|
+
bits |= (resb > 0 ? 1 : 0) * power;
|
|
414
|
+
power <<= 1;
|
|
415
|
+
}
|
|
416
|
+
dictionary[dictSize++] = f(bits);
|
|
417
|
+
c = dictSize - 1;
|
|
418
|
+
enlargeIn--;
|
|
419
|
+
break;
|
|
420
|
+
case 2:
|
|
421
|
+
return result.join("");
|
|
422
|
+
}
|
|
423
|
+
if (enlargeIn == 0) {
|
|
424
|
+
enlargeIn = Math.pow(2, numBits);
|
|
425
|
+
numBits++;
|
|
426
|
+
}
|
|
427
|
+
if (dictionary[c]) {
|
|
428
|
+
entry = dictionary[c];
|
|
429
|
+
} else {
|
|
430
|
+
if (c === dictSize) {
|
|
431
|
+
entry = w + w.charAt(0);
|
|
432
|
+
} else {
|
|
433
|
+
return null;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
result.push(entry);
|
|
437
|
+
dictionary[dictSize++] = w + entry.charAt(0);
|
|
438
|
+
enlargeIn--;
|
|
439
|
+
w = entry;
|
|
440
|
+
if (enlargeIn == 0) {
|
|
441
|
+
enlargeIn = Math.pow(2, numBits);
|
|
442
|
+
numBits++;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
};
|
|
447
|
+
return LZString2;
|
|
448
|
+
})();
|
|
449
|
+
if (typeof define === "function" && define.amd) {
|
|
450
|
+
define(function() {
|
|
451
|
+
return LZString;
|
|
452
|
+
});
|
|
453
|
+
} else if (typeof module !== "undefined" && module != null) {
|
|
454
|
+
module.exports = LZString;
|
|
455
|
+
} else if (typeof angular !== "undefined" && angular != null) {
|
|
456
|
+
angular.module("LZString", []).factory("LZString", function() {
|
|
457
|
+
return LZString;
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
// ../../packages/schema/dist/plan.mjs
|
|
464
|
+
import { z } from "zod";
|
|
465
|
+
import { nanoid } from "nanoid";
|
|
466
|
+
var PlanStatusValues = [
|
|
467
|
+
"draft",
|
|
468
|
+
"pending_review",
|
|
469
|
+
"changes_requested",
|
|
470
|
+
"in_progress",
|
|
471
|
+
"completed"
|
|
472
|
+
];
|
|
473
|
+
var PlanViewTabValues = [
|
|
474
|
+
"plan",
|
|
475
|
+
"activity",
|
|
476
|
+
"deliverables",
|
|
477
|
+
"changes"
|
|
478
|
+
];
|
|
479
|
+
var OriginPlatformValues = [
|
|
480
|
+
"claude-code",
|
|
481
|
+
"devin",
|
|
482
|
+
"cursor",
|
|
483
|
+
"windsurf",
|
|
484
|
+
"aider",
|
|
485
|
+
"unknown"
|
|
486
|
+
];
|
|
487
|
+
var ClaudeCodeOriginMetadataSchema = z.object({
|
|
488
|
+
platform: z.literal("claude-code"),
|
|
489
|
+
sessionId: z.string(),
|
|
490
|
+
transcriptPath: z.string(),
|
|
491
|
+
cwd: z.string().optional()
|
|
492
|
+
});
|
|
493
|
+
var DevinOriginMetadataSchema = z.object({
|
|
494
|
+
platform: z.literal("devin"),
|
|
495
|
+
sessionId: z.string()
|
|
496
|
+
});
|
|
497
|
+
var CursorOriginMetadataSchema = z.object({
|
|
498
|
+
platform: z.literal("cursor"),
|
|
499
|
+
conversationId: z.string(),
|
|
500
|
+
generationId: z.string().optional()
|
|
501
|
+
});
|
|
502
|
+
var UnknownOriginMetadataSchema = z.object({ platform: z.literal("unknown") });
|
|
503
|
+
var OriginMetadataSchema = z.discriminatedUnion("platform", [
|
|
504
|
+
ClaudeCodeOriginMetadataSchema,
|
|
505
|
+
DevinOriginMetadataSchema,
|
|
506
|
+
CursorOriginMetadataSchema,
|
|
507
|
+
UnknownOriginMetadataSchema
|
|
508
|
+
]);
|
|
509
|
+
function parseClaudeCodeOrigin(hookMetadata) {
|
|
510
|
+
if (!hookMetadata) return null;
|
|
511
|
+
const result = ClaudeCodeOriginMetadataSchema.safeParse({
|
|
512
|
+
platform: "claude-code",
|
|
513
|
+
sessionId: hookMetadata.originSessionId,
|
|
514
|
+
transcriptPath: hookMetadata.originTranscriptPath,
|
|
515
|
+
cwd: hookMetadata.originCwd
|
|
516
|
+
});
|
|
517
|
+
return result.success ? result.data : null;
|
|
518
|
+
}
|
|
519
|
+
var ConversationVersionBaseSchema = z.object({
|
|
520
|
+
versionId: z.string(),
|
|
521
|
+
creator: z.string(),
|
|
522
|
+
platform: z.enum(OriginPlatformValues),
|
|
523
|
+
sessionId: z.string(),
|
|
524
|
+
messageCount: z.number(),
|
|
525
|
+
createdAt: z.number()
|
|
526
|
+
});
|
|
527
|
+
var ConversationVersionSchema = z.discriminatedUnion("handedOff", [ConversationVersionBaseSchema.extend({ handedOff: z.literal(false) }), ConversationVersionBaseSchema.extend({
|
|
528
|
+
handedOff: z.literal(true),
|
|
529
|
+
handedOffAt: z.number(),
|
|
530
|
+
handedOffTo: z.string()
|
|
531
|
+
})]);
|
|
532
|
+
var PlanEventTypes = [
|
|
533
|
+
"plan_created",
|
|
534
|
+
"status_changed",
|
|
535
|
+
"comment_added",
|
|
536
|
+
"comment_resolved",
|
|
537
|
+
"artifact_uploaded",
|
|
538
|
+
"deliverable_linked",
|
|
539
|
+
"pr_linked",
|
|
540
|
+
"content_edited",
|
|
541
|
+
"approved",
|
|
542
|
+
"changes_requested",
|
|
543
|
+
"completed",
|
|
544
|
+
"conversation_imported",
|
|
545
|
+
"conversation_handed_off",
|
|
546
|
+
"step_completed",
|
|
547
|
+
"plan_archived",
|
|
548
|
+
"plan_unarchived",
|
|
549
|
+
"conversation_exported",
|
|
550
|
+
"plan_shared",
|
|
551
|
+
"approval_requested",
|
|
552
|
+
"input_request_created",
|
|
553
|
+
"input_request_answered",
|
|
554
|
+
"input_request_declined",
|
|
555
|
+
"agent_activity"
|
|
556
|
+
];
|
|
557
|
+
var AgentActivityTypes = [
|
|
558
|
+
"help_request",
|
|
559
|
+
"help_request_resolved",
|
|
560
|
+
"blocker",
|
|
561
|
+
"blocker_resolved"
|
|
562
|
+
];
|
|
563
|
+
var PlanEventBaseSchema = z.object({
|
|
564
|
+
id: z.string(),
|
|
565
|
+
actor: z.string(),
|
|
566
|
+
timestamp: z.number(),
|
|
567
|
+
inboxWorthy: z.boolean().optional(),
|
|
568
|
+
inboxFor: z.union([z.string(), z.array(z.string())]).optional()
|
|
569
|
+
});
|
|
570
|
+
var AgentActivityDataSchema = z.discriminatedUnion("activityType", [
|
|
571
|
+
z.object({
|
|
572
|
+
activityType: z.literal("help_request"),
|
|
573
|
+
requestId: z.string(),
|
|
574
|
+
message: z.string()
|
|
575
|
+
}),
|
|
576
|
+
z.object({
|
|
577
|
+
activityType: z.literal("help_request_resolved"),
|
|
578
|
+
requestId: z.string(),
|
|
579
|
+
resolution: z.string().optional()
|
|
580
|
+
}),
|
|
581
|
+
z.object({
|
|
582
|
+
activityType: z.literal("blocker"),
|
|
583
|
+
message: z.string(),
|
|
584
|
+
requestId: z.string()
|
|
585
|
+
}),
|
|
586
|
+
z.object({
|
|
587
|
+
activityType: z.literal("blocker_resolved"),
|
|
588
|
+
requestId: z.string(),
|
|
589
|
+
resolution: z.string().optional()
|
|
590
|
+
})
|
|
591
|
+
]);
|
|
592
|
+
var PlanEventSchema = z.discriminatedUnion("type", [
|
|
593
|
+
PlanEventBaseSchema.extend({ type: z.enum([
|
|
594
|
+
"plan_created",
|
|
595
|
+
"content_edited",
|
|
596
|
+
"plan_archived",
|
|
597
|
+
"plan_unarchived",
|
|
598
|
+
"plan_shared"
|
|
599
|
+
]) }),
|
|
600
|
+
PlanEventBaseSchema.extend({
|
|
601
|
+
type: z.literal("status_changed"),
|
|
602
|
+
data: z.object({
|
|
603
|
+
fromStatus: z.enum(PlanStatusValues),
|
|
604
|
+
toStatus: z.enum(PlanStatusValues)
|
|
605
|
+
})
|
|
606
|
+
}),
|
|
607
|
+
PlanEventBaseSchema.extend({
|
|
608
|
+
type: z.literal("artifact_uploaded"),
|
|
609
|
+
data: z.object({ artifactId: z.string() })
|
|
610
|
+
}),
|
|
611
|
+
PlanEventBaseSchema.extend({
|
|
612
|
+
type: z.literal("comment_added"),
|
|
613
|
+
data: z.object({
|
|
614
|
+
commentId: z.string().optional(),
|
|
615
|
+
prNumber: z.number().optional(),
|
|
616
|
+
mentions: z.boolean().optional()
|
|
617
|
+
}).optional()
|
|
618
|
+
}),
|
|
619
|
+
PlanEventBaseSchema.extend({
|
|
620
|
+
type: z.literal("comment_resolved"),
|
|
621
|
+
data: z.object({
|
|
622
|
+
commentId: z.string().optional(),
|
|
623
|
+
resolvedCount: z.number().optional()
|
|
624
|
+
}).optional()
|
|
625
|
+
}),
|
|
626
|
+
PlanEventBaseSchema.extend({
|
|
627
|
+
type: z.literal("deliverable_linked"),
|
|
628
|
+
data: z.object({
|
|
629
|
+
deliverableId: z.string().optional(),
|
|
630
|
+
artifactId: z.string().optional(),
|
|
631
|
+
allFulfilled: z.boolean().optional()
|
|
632
|
+
}).optional()
|
|
633
|
+
}),
|
|
634
|
+
PlanEventBaseSchema.extend({
|
|
635
|
+
type: z.literal("pr_linked"),
|
|
636
|
+
data: z.object({
|
|
637
|
+
prNumber: z.number(),
|
|
638
|
+
url: z.string().optional()
|
|
639
|
+
})
|
|
640
|
+
}),
|
|
641
|
+
PlanEventBaseSchema.extend({
|
|
642
|
+
type: z.enum(["approved", "changes_requested"]),
|
|
643
|
+
data: z.object({ comment: z.string().optional() }).optional()
|
|
644
|
+
}),
|
|
645
|
+
PlanEventBaseSchema.extend({ type: z.literal("completed") }),
|
|
646
|
+
PlanEventBaseSchema.extend({
|
|
647
|
+
type: z.literal("step_completed"),
|
|
648
|
+
data: z.object({
|
|
649
|
+
stepId: z.string(),
|
|
650
|
+
completed: z.boolean()
|
|
651
|
+
})
|
|
652
|
+
}),
|
|
653
|
+
PlanEventBaseSchema.extend({
|
|
654
|
+
type: z.literal("conversation_imported"),
|
|
655
|
+
data: z.object({
|
|
656
|
+
sourcePlatform: z.string().optional(),
|
|
657
|
+
messageCount: z.number(),
|
|
658
|
+
sourceSessionId: z.string().optional()
|
|
659
|
+
})
|
|
660
|
+
}),
|
|
661
|
+
PlanEventBaseSchema.extend({
|
|
662
|
+
type: z.literal("conversation_exported"),
|
|
663
|
+
data: z.object({ messageCount: z.number() })
|
|
664
|
+
}),
|
|
665
|
+
PlanEventBaseSchema.extend({
|
|
666
|
+
type: z.literal("conversation_handed_off"),
|
|
667
|
+
data: z.object({
|
|
668
|
+
handedOffTo: z.string(),
|
|
669
|
+
messageCount: z.number()
|
|
670
|
+
})
|
|
671
|
+
}),
|
|
672
|
+
PlanEventBaseSchema.extend({
|
|
673
|
+
type: z.literal("approval_requested"),
|
|
674
|
+
data: z.object({ requesterName: z.string().optional() }).optional()
|
|
675
|
+
}),
|
|
676
|
+
PlanEventBaseSchema.extend({
|
|
677
|
+
type: z.literal("input_request_created"),
|
|
678
|
+
data: z.object({
|
|
679
|
+
requestId: z.string(),
|
|
680
|
+
requestType: z.enum([
|
|
681
|
+
"text",
|
|
682
|
+
"multiline",
|
|
683
|
+
"choice",
|
|
684
|
+
"confirm"
|
|
685
|
+
]),
|
|
686
|
+
requestMessage: z.string()
|
|
687
|
+
})
|
|
688
|
+
}),
|
|
689
|
+
PlanEventBaseSchema.extend({
|
|
690
|
+
type: z.literal("input_request_answered"),
|
|
691
|
+
data: z.object({
|
|
692
|
+
requestId: z.string(),
|
|
693
|
+
response: z.unknown(),
|
|
694
|
+
answeredBy: z.string()
|
|
695
|
+
})
|
|
696
|
+
}),
|
|
697
|
+
PlanEventBaseSchema.extend({
|
|
698
|
+
type: z.literal("input_request_declined"),
|
|
699
|
+
data: z.object({ requestId: z.string() })
|
|
700
|
+
}),
|
|
701
|
+
PlanEventBaseSchema.extend({
|
|
702
|
+
type: z.literal("agent_activity"),
|
|
703
|
+
data: AgentActivityDataSchema
|
|
704
|
+
})
|
|
705
|
+
]);
|
|
706
|
+
function isInboxWorthy(event, username, ownerId) {
|
|
707
|
+
if (!event.inboxWorthy) return false;
|
|
708
|
+
if (!event.inboxFor) return true;
|
|
709
|
+
const resolvedInboxFor = event.inboxFor === "owner" && ownerId ? ownerId : event.inboxFor;
|
|
710
|
+
if (Array.isArray(resolvedInboxFor)) return resolvedInboxFor.includes(username);
|
|
711
|
+
return resolvedInboxFor === username;
|
|
712
|
+
}
|
|
713
|
+
var PlanMetadataBaseSchema = z.object({
|
|
714
|
+
id: z.string(),
|
|
715
|
+
title: z.string(),
|
|
716
|
+
createdAt: z.number(),
|
|
717
|
+
updatedAt: z.number(),
|
|
718
|
+
repo: z.string().optional(),
|
|
719
|
+
pr: z.number().optional(),
|
|
720
|
+
ownerId: z.string().optional(),
|
|
721
|
+
approvalRequired: z.boolean().optional(),
|
|
722
|
+
approvedUsers: z.array(z.string()).optional(),
|
|
723
|
+
rejectedUsers: z.array(z.string()).optional(),
|
|
724
|
+
sessionTokenHash: z.string().optional(),
|
|
725
|
+
archivedAt: z.number().optional(),
|
|
726
|
+
archivedBy: z.string().optional(),
|
|
727
|
+
origin: OriginMetadataSchema.optional(),
|
|
728
|
+
viewedBy: z.record(z.string(), z.number()).optional(),
|
|
729
|
+
conversationVersions: z.array(ConversationVersionSchema).optional(),
|
|
730
|
+
events: z.array(PlanEventSchema).optional(),
|
|
731
|
+
tags: z.array(z.string()).optional()
|
|
732
|
+
});
|
|
733
|
+
var PlanMetadataSchema = z.discriminatedUnion("status", [
|
|
734
|
+
PlanMetadataBaseSchema.extend({ status: z.literal("draft") }),
|
|
735
|
+
PlanMetadataBaseSchema.extend({
|
|
736
|
+
status: z.literal("pending_review"),
|
|
737
|
+
reviewRequestId: z.string()
|
|
738
|
+
}),
|
|
739
|
+
PlanMetadataBaseSchema.extend({
|
|
740
|
+
status: z.literal("changes_requested"),
|
|
741
|
+
reviewedAt: z.number(),
|
|
742
|
+
reviewedBy: z.string(),
|
|
743
|
+
reviewComment: z.string().optional()
|
|
744
|
+
}),
|
|
745
|
+
PlanMetadataBaseSchema.extend({
|
|
746
|
+
status: z.literal("in_progress"),
|
|
747
|
+
reviewedAt: z.number(),
|
|
748
|
+
reviewedBy: z.string(),
|
|
749
|
+
reviewComment: z.string().optional()
|
|
750
|
+
}),
|
|
751
|
+
PlanMetadataBaseSchema.extend({
|
|
752
|
+
status: z.literal("completed"),
|
|
753
|
+
completedAt: z.number(),
|
|
754
|
+
completedBy: z.string(),
|
|
755
|
+
snapshotUrl: z.string().optional()
|
|
756
|
+
})
|
|
757
|
+
]);
|
|
758
|
+
var BaseArtifactSchema = z.object({
|
|
759
|
+
id: z.string(),
|
|
760
|
+
type: z.enum([
|
|
761
|
+
"screenshot",
|
|
762
|
+
"video",
|
|
763
|
+
"test_results",
|
|
764
|
+
"diff"
|
|
765
|
+
]),
|
|
766
|
+
filename: z.string(),
|
|
767
|
+
description: z.string().optional(),
|
|
768
|
+
uploadedAt: z.number().optional()
|
|
769
|
+
});
|
|
770
|
+
var GitHubArtifactSchema = BaseArtifactSchema.extend({
|
|
771
|
+
storage: z.literal("github"),
|
|
772
|
+
url: z.string()
|
|
773
|
+
});
|
|
774
|
+
var LocalArtifactSchema = BaseArtifactSchema.extend({
|
|
775
|
+
storage: z.literal("local"),
|
|
776
|
+
localArtifactId: z.string()
|
|
777
|
+
});
|
|
778
|
+
var ArtifactSchema = z.discriminatedUnion("storage", [GitHubArtifactSchema, LocalArtifactSchema]);
|
|
779
|
+
function getArtifactUrl(repo, pr, planId, filename) {
|
|
780
|
+
return `https://raw.githubusercontent.com/${repo}/plan-artifacts/pr-${pr}/${planId}/${filename}`;
|
|
781
|
+
}
|
|
782
|
+
var DeliverableSchema = z.object({
|
|
783
|
+
id: z.string(),
|
|
784
|
+
text: z.string(),
|
|
785
|
+
linkedArtifactId: z.string().optional(),
|
|
786
|
+
linkedAt: z.number().optional()
|
|
787
|
+
});
|
|
788
|
+
var PlanSnapshotSchema = z.object({
|
|
789
|
+
id: z.string(),
|
|
790
|
+
status: z.enum(PlanStatusValues),
|
|
791
|
+
createdBy: z.string(),
|
|
792
|
+
reason: z.string(),
|
|
793
|
+
createdAt: z.number(),
|
|
794
|
+
content: z.array(z.unknown()),
|
|
795
|
+
threadSummary: z.object({
|
|
796
|
+
total: z.number(),
|
|
797
|
+
unresolved: z.number()
|
|
798
|
+
}).optional(),
|
|
799
|
+
artifacts: z.array(ArtifactSchema).optional(),
|
|
800
|
+
deliverables: z.array(DeliverableSchema).optional()
|
|
801
|
+
});
|
|
802
|
+
var LinkedPRStatusValues = [
|
|
803
|
+
"draft",
|
|
804
|
+
"open",
|
|
805
|
+
"merged",
|
|
806
|
+
"closed"
|
|
807
|
+
];
|
|
808
|
+
var LinkedPRSchema = z.object({
|
|
809
|
+
prNumber: z.number(),
|
|
810
|
+
url: z.string(),
|
|
811
|
+
linkedAt: z.number(),
|
|
812
|
+
status: z.enum(LinkedPRStatusValues),
|
|
813
|
+
branch: z.string().optional(),
|
|
814
|
+
title: z.string().optional()
|
|
815
|
+
});
|
|
816
|
+
var PRReviewCommentSchema = z.object({
|
|
817
|
+
id: z.string(),
|
|
818
|
+
prNumber: z.number(),
|
|
819
|
+
path: z.string(),
|
|
820
|
+
line: z.number(),
|
|
821
|
+
body: z.string(),
|
|
822
|
+
author: z.string(),
|
|
823
|
+
createdAt: z.number(),
|
|
824
|
+
resolved: z.boolean().optional()
|
|
825
|
+
});
|
|
826
|
+
function createLinkedPR(params) {
|
|
827
|
+
const linkedPR = {
|
|
828
|
+
...params,
|
|
829
|
+
linkedAt: params.linkedAt ?? Date.now()
|
|
830
|
+
};
|
|
831
|
+
return LinkedPRSchema.parse(linkedPR);
|
|
832
|
+
}
|
|
833
|
+
function createGitHubArtifact(params) {
|
|
834
|
+
const artifact = {
|
|
835
|
+
id: nanoid(),
|
|
836
|
+
...params,
|
|
837
|
+
storage: "github",
|
|
838
|
+
uploadedAt: params.uploadedAt ?? Date.now()
|
|
839
|
+
};
|
|
840
|
+
return ArtifactSchema.parse(artifact);
|
|
841
|
+
}
|
|
842
|
+
function createLocalArtifact(params) {
|
|
843
|
+
const artifact = {
|
|
844
|
+
id: nanoid(),
|
|
845
|
+
...params,
|
|
846
|
+
storage: "local",
|
|
847
|
+
uploadedAt: params.uploadedAt ?? Date.now()
|
|
848
|
+
};
|
|
849
|
+
return ArtifactSchema.parse(artifact);
|
|
850
|
+
}
|
|
851
|
+
function createInitialConversationVersion(params) {
|
|
852
|
+
const version = {
|
|
853
|
+
...params,
|
|
854
|
+
handedOff: false
|
|
855
|
+
};
|
|
856
|
+
return ConversationVersionSchema.parse(version);
|
|
857
|
+
}
|
|
858
|
+
function createHandedOffConversationVersion(params) {
|
|
859
|
+
const version = {
|
|
860
|
+
...params,
|
|
861
|
+
handedOff: true
|
|
862
|
+
};
|
|
863
|
+
return ConversationVersionSchema.parse(version);
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
// ../../packages/schema/dist/yjs-helpers-xzZyVQl7.mjs
|
|
867
|
+
import { z as z2 } from "zod";
|
|
868
|
+
import { nanoid as nanoid2 } from "nanoid";
|
|
869
|
+
import * as Y from "yjs";
|
|
870
|
+
function assertNever(value) {
|
|
871
|
+
throw new Error(`Unhandled discriminated union member: ${JSON.stringify(value)}`);
|
|
872
|
+
}
|
|
873
|
+
var AgentPresenceSchema = z2.object({
|
|
874
|
+
agentType: z2.string(),
|
|
875
|
+
sessionId: z2.string(),
|
|
876
|
+
connectedAt: z2.number(),
|
|
877
|
+
lastSeenAt: z2.number()
|
|
878
|
+
});
|
|
879
|
+
var ReviewCommentSchema = z2.object({
|
|
880
|
+
author: z2.string(),
|
|
881
|
+
content: z2.string(),
|
|
882
|
+
createdAt: z2.number()
|
|
883
|
+
});
|
|
884
|
+
var ReviewFeedbackSchema = z2.object({
|
|
885
|
+
threadId: z2.string(),
|
|
886
|
+
blockId: z2.string().optional(),
|
|
887
|
+
comments: z2.array(ReviewCommentSchema)
|
|
888
|
+
});
|
|
889
|
+
var CreateHookSessionRequestSchema = z2.object({
|
|
890
|
+
sessionId: z2.string(),
|
|
891
|
+
agentType: z2.string().default("claude-code"),
|
|
892
|
+
metadata: z2.record(z2.string(), z2.unknown()).optional()
|
|
893
|
+
});
|
|
894
|
+
var CreateHookSessionResponseSchema = z2.object({
|
|
895
|
+
planId: z2.string(),
|
|
896
|
+
url: z2.string()
|
|
897
|
+
});
|
|
898
|
+
var UpdatePlanContentRequestSchema = z2.object({
|
|
899
|
+
content: z2.string(),
|
|
900
|
+
filePath: z2.string().optional()
|
|
901
|
+
});
|
|
902
|
+
var UpdatePlanContentResponseSchema = z2.object({
|
|
903
|
+
success: z2.boolean(),
|
|
904
|
+
updatedAt: z2.number()
|
|
905
|
+
});
|
|
906
|
+
var GetReviewStatusResponseSchema = z2.discriminatedUnion("status", [
|
|
907
|
+
z2.object({ status: z2.literal("draft") }),
|
|
908
|
+
z2.object({
|
|
909
|
+
status: z2.literal("pending_review"),
|
|
910
|
+
reviewRequestId: z2.string()
|
|
911
|
+
}),
|
|
912
|
+
z2.object({
|
|
913
|
+
status: z2.literal("changes_requested"),
|
|
914
|
+
reviewedAt: z2.number(),
|
|
915
|
+
reviewedBy: z2.string(),
|
|
916
|
+
reviewComment: z2.string().optional(),
|
|
917
|
+
feedback: z2.array(ReviewFeedbackSchema).optional()
|
|
918
|
+
}),
|
|
919
|
+
z2.object({
|
|
920
|
+
status: z2.literal("in_progress"),
|
|
921
|
+
reviewedAt: z2.number(),
|
|
922
|
+
reviewedBy: z2.string()
|
|
923
|
+
}),
|
|
924
|
+
z2.object({
|
|
925
|
+
status: z2.literal("completed"),
|
|
926
|
+
completedAt: z2.number(),
|
|
927
|
+
completedBy: z2.string(),
|
|
928
|
+
snapshotUrl: z2.string().optional()
|
|
929
|
+
})
|
|
930
|
+
]);
|
|
931
|
+
var UpdatePresenceRequestSchema = z2.object({
|
|
932
|
+
agentType: z2.string(),
|
|
933
|
+
sessionId: z2.string()
|
|
934
|
+
});
|
|
935
|
+
var UpdatePresenceResponseSchema = z2.object({ success: z2.boolean() });
|
|
936
|
+
var HookApiErrorSchema = z2.object({ error: z2.string() });
|
|
937
|
+
var RegisterServerRequestSchema = z2.object({
|
|
938
|
+
port: z2.number().int().positive(),
|
|
939
|
+
pid: z2.number().int().positive()
|
|
940
|
+
});
|
|
941
|
+
var RegisterServerResponseSchema = z2.object({
|
|
942
|
+
success: z2.boolean(),
|
|
943
|
+
entry: z2.object({
|
|
944
|
+
port: z2.number(),
|
|
945
|
+
pid: z2.number(),
|
|
946
|
+
url: z2.string(),
|
|
947
|
+
registeredAt: z2.number()
|
|
948
|
+
})
|
|
949
|
+
});
|
|
950
|
+
var UnregisterServerRequestSchema = z2.object({ pid: z2.number().int().positive() });
|
|
951
|
+
var UnregisterServerResponseSchema = z2.object({
|
|
952
|
+
success: z2.boolean(),
|
|
953
|
+
existed: z2.boolean()
|
|
954
|
+
});
|
|
955
|
+
var CreateSubscriptionRequestSchema = z2.object({
|
|
956
|
+
subscribe: z2.array(z2.string()).optional(),
|
|
957
|
+
windowMs: z2.number().positive().optional(),
|
|
958
|
+
maxWindowMs: z2.number().positive().optional(),
|
|
959
|
+
threshold: z2.number().positive().optional()
|
|
960
|
+
});
|
|
961
|
+
var CreateSubscriptionResponseSchema = z2.object({ clientId: z2.string() });
|
|
962
|
+
var InputRequestTypeValues = [
|
|
963
|
+
"text",
|
|
964
|
+
"multiline",
|
|
965
|
+
"choice",
|
|
966
|
+
"confirm"
|
|
967
|
+
];
|
|
968
|
+
var InputRequestStatusValues = [
|
|
969
|
+
"pending",
|
|
970
|
+
"answered",
|
|
971
|
+
"declined",
|
|
972
|
+
"cancelled"
|
|
973
|
+
];
|
|
974
|
+
var InputRequestBaseSchema = z2.object({
|
|
975
|
+
id: z2.string(),
|
|
976
|
+
createdAt: z2.number(),
|
|
977
|
+
message: z2.string().min(1, "Message cannot be empty"),
|
|
978
|
+
status: z2.enum(InputRequestStatusValues),
|
|
979
|
+
defaultValue: z2.string().optional(),
|
|
980
|
+
timeout: z2.number().int().min(10, "Timeout must be at least 10 seconds").max(900, "Timeout cannot exceed 15 minutes").optional(),
|
|
981
|
+
planId: z2.string().optional(),
|
|
982
|
+
response: z2.unknown().optional(),
|
|
983
|
+
answeredAt: z2.number().optional(),
|
|
984
|
+
answeredBy: z2.string().optional()
|
|
985
|
+
});
|
|
986
|
+
var TextInputSchema = InputRequestBaseSchema.extend({ type: z2.literal("text") });
|
|
987
|
+
var MultilineInputSchema = InputRequestBaseSchema.extend({ type: z2.literal("multiline") });
|
|
988
|
+
var ChoiceInputSchema = InputRequestBaseSchema.extend({
|
|
989
|
+
type: z2.literal("choice"),
|
|
990
|
+
options: z2.array(z2.string()).min(1, "Choice requests must have at least one option"),
|
|
991
|
+
multiSelect: z2.boolean().optional()
|
|
992
|
+
});
|
|
993
|
+
var ConfirmInputSchema = InputRequestBaseSchema.extend({ type: z2.literal("confirm") });
|
|
994
|
+
var InputRequestSchema = z2.discriminatedUnion("type", [
|
|
995
|
+
TextInputSchema,
|
|
996
|
+
MultilineInputSchema,
|
|
997
|
+
ChoiceInputSchema,
|
|
998
|
+
ConfirmInputSchema
|
|
999
|
+
]);
|
|
1000
|
+
function createInputRequest(params) {
|
|
1001
|
+
const baseFields = {
|
|
1002
|
+
id: nanoid2(),
|
|
1003
|
+
createdAt: Date.now(),
|
|
1004
|
+
message: params.message,
|
|
1005
|
+
defaultValue: params.defaultValue,
|
|
1006
|
+
status: "pending",
|
|
1007
|
+
timeout: params.timeout,
|
|
1008
|
+
planId: params.planId
|
|
1009
|
+
};
|
|
1010
|
+
let request;
|
|
1011
|
+
switch (params.type) {
|
|
1012
|
+
case "text":
|
|
1013
|
+
request = {
|
|
1014
|
+
...baseFields,
|
|
1015
|
+
type: "text"
|
|
1016
|
+
};
|
|
1017
|
+
break;
|
|
1018
|
+
case "multiline":
|
|
1019
|
+
request = {
|
|
1020
|
+
...baseFields,
|
|
1021
|
+
type: "multiline"
|
|
1022
|
+
};
|
|
1023
|
+
break;
|
|
1024
|
+
case "choice":
|
|
1025
|
+
request = {
|
|
1026
|
+
...baseFields,
|
|
1027
|
+
type: "choice",
|
|
1028
|
+
options: params.options,
|
|
1029
|
+
multiSelect: params.multiSelect
|
|
1030
|
+
};
|
|
1031
|
+
break;
|
|
1032
|
+
case "confirm":
|
|
1033
|
+
request = {
|
|
1034
|
+
...baseFields,
|
|
1035
|
+
type: "confirm"
|
|
1036
|
+
};
|
|
1037
|
+
break;
|
|
1038
|
+
}
|
|
1039
|
+
const parseResult = InputRequestSchema.safeParse(request);
|
|
1040
|
+
if (!parseResult.success) throw new Error(`Invalid input request: ${parseResult.error.issues[0]?.message}`);
|
|
1041
|
+
return parseResult.data;
|
|
1042
|
+
}
|
|
1043
|
+
var YDOC_KEYS = {
|
|
1044
|
+
METADATA: "metadata",
|
|
1045
|
+
DOCUMENT_FRAGMENT: "document",
|
|
1046
|
+
THREADS: "threads",
|
|
1047
|
+
STEP_COMPLETIONS: "stepCompletions",
|
|
1048
|
+
PLANS: "plans",
|
|
1049
|
+
ARTIFACTS: "artifacts",
|
|
1050
|
+
DELIVERABLES: "deliverables",
|
|
1051
|
+
PRESENCE: "presence",
|
|
1052
|
+
LINKED_PRS: "linkedPRs",
|
|
1053
|
+
PR_REVIEW_COMMENTS: "prReviewComments",
|
|
1054
|
+
EVENTS: "events",
|
|
1055
|
+
SNAPSHOTS: "snapshots",
|
|
1056
|
+
INPUT_REQUESTS: "inputRequests"
|
|
1057
|
+
};
|
|
1058
|
+
function isValidYDocKey(key) {
|
|
1059
|
+
return Object.values(YDOC_KEYS).includes(key);
|
|
1060
|
+
}
|
|
1061
|
+
var CommentBodySchema = z2.union([z2.string(), z2.array(z2.unknown())]);
|
|
1062
|
+
var ThreadCommentSchema = z2.object({
|
|
1063
|
+
id: z2.string(),
|
|
1064
|
+
userId: z2.string(),
|
|
1065
|
+
body: CommentBodySchema,
|
|
1066
|
+
createdAt: z2.number()
|
|
1067
|
+
});
|
|
1068
|
+
var ThreadSchema = z2.object({
|
|
1069
|
+
id: z2.string(),
|
|
1070
|
+
comments: z2.array(ThreadCommentSchema),
|
|
1071
|
+
resolved: z2.boolean().optional(),
|
|
1072
|
+
selectedText: z2.string().optional()
|
|
1073
|
+
});
|
|
1074
|
+
function isThread(value) {
|
|
1075
|
+
return ThreadSchema.safeParse(value).success;
|
|
1076
|
+
}
|
|
1077
|
+
function parseThreads(data) {
|
|
1078
|
+
const threads = [];
|
|
1079
|
+
for (const [_key, value] of Object.entries(data)) {
|
|
1080
|
+
const result = ThreadSchema.safeParse(value);
|
|
1081
|
+
if (result.success) threads.push(result.data);
|
|
1082
|
+
}
|
|
1083
|
+
return threads;
|
|
1084
|
+
}
|
|
1085
|
+
function extractTextFromCommentBody(body) {
|
|
1086
|
+
if (typeof body === "string") return body;
|
|
1087
|
+
if (!Array.isArray(body)) return "";
|
|
1088
|
+
return body.map((block) => {
|
|
1089
|
+
if (typeof block === "string") return block;
|
|
1090
|
+
if (typeof block !== "object" || block === null) return "";
|
|
1091
|
+
const blockObj = block;
|
|
1092
|
+
if (Array.isArray(blockObj.content)) return blockObj.content.map((item) => {
|
|
1093
|
+
if (typeof item === "string") return item;
|
|
1094
|
+
if (typeof item === "object" && item !== null && "text" in item) return item.text;
|
|
1095
|
+
return "";
|
|
1096
|
+
}).join("");
|
|
1097
|
+
return "";
|
|
1098
|
+
}).join("\n");
|
|
1099
|
+
}
|
|
1100
|
+
function extractMentions(body) {
|
|
1101
|
+
const text = extractTextFromCommentBody(body);
|
|
1102
|
+
const mentionRegex = /@([a-zA-Z0-9_-]+)/g;
|
|
1103
|
+
const mentions = [];
|
|
1104
|
+
let match;
|
|
1105
|
+
while ((match = mentionRegex.exec(text)) !== null) if (match[1]) mentions.push(match[1]);
|
|
1106
|
+
return [...new Set(mentions)];
|
|
1107
|
+
}
|
|
1108
|
+
var VALID_STATUS_TRANSITIONS = {
|
|
1109
|
+
draft: ["pending_review", "in_progress"],
|
|
1110
|
+
pending_review: ["in_progress", "changes_requested"],
|
|
1111
|
+
changes_requested: ["pending_review", "in_progress"],
|
|
1112
|
+
in_progress: ["completed"],
|
|
1113
|
+
completed: []
|
|
1114
|
+
};
|
|
1115
|
+
function getPlanMetadata(ydoc) {
|
|
1116
|
+
const result = getPlanMetadataWithValidation(ydoc);
|
|
1117
|
+
return result.success ? result.data : null;
|
|
1118
|
+
}
|
|
1119
|
+
function getPlanMetadataWithValidation(ydoc) {
|
|
1120
|
+
const data = ydoc.getMap(YDOC_KEYS.METADATA).toJSON();
|
|
1121
|
+
if (!data || Object.keys(data).length === 0) return {
|
|
1122
|
+
success: false,
|
|
1123
|
+
error: "No metadata found in Y.Doc"
|
|
1124
|
+
};
|
|
1125
|
+
const result = PlanMetadataSchema.safeParse(data);
|
|
1126
|
+
if (!result.success) return {
|
|
1127
|
+
success: false,
|
|
1128
|
+
error: `Invalid metadata: ${result.error.message}`
|
|
1129
|
+
};
|
|
1130
|
+
return {
|
|
1131
|
+
success: true,
|
|
1132
|
+
data: result.data
|
|
1133
|
+
};
|
|
1134
|
+
}
|
|
1135
|
+
function setPlanMetadata(ydoc, metadata, actor) {
|
|
1136
|
+
ydoc.transact(() => {
|
|
1137
|
+
const map = ydoc.getMap(YDOC_KEYS.METADATA);
|
|
1138
|
+
for (const [key, value] of Object.entries(metadata)) if (value !== void 0) map.set(key, value);
|
|
1139
|
+
map.set("updatedAt", Date.now());
|
|
1140
|
+
}, actor ? { actor } : void 0);
|
|
1141
|
+
}
|
|
1142
|
+
function applyPendingReviewTransition(map, transition) {
|
|
1143
|
+
map.set("reviewRequestId", transition.reviewRequestId);
|
|
1144
|
+
}
|
|
1145
|
+
function applyChangesRequestedTransition(map, transition) {
|
|
1146
|
+
map.set("reviewedAt", transition.reviewedAt);
|
|
1147
|
+
map.set("reviewedBy", transition.reviewedBy);
|
|
1148
|
+
if (transition.reviewComment !== void 0) map.set("reviewComment", transition.reviewComment);
|
|
1149
|
+
}
|
|
1150
|
+
function applyInProgressTransition(map, transition) {
|
|
1151
|
+
if (transition.reviewedAt !== void 0) map.set("reviewedAt", transition.reviewedAt);
|
|
1152
|
+
if (transition.reviewedBy !== void 0) map.set("reviewedBy", transition.reviewedBy);
|
|
1153
|
+
if (transition.reviewComment !== void 0) map.set("reviewComment", transition.reviewComment);
|
|
1154
|
+
}
|
|
1155
|
+
function applyCompletedTransition(map, transition) {
|
|
1156
|
+
map.set("completedAt", transition.completedAt);
|
|
1157
|
+
map.set("completedBy", transition.completedBy);
|
|
1158
|
+
if (transition.snapshotUrl !== void 0) map.set("snapshotUrl", transition.snapshotUrl);
|
|
1159
|
+
}
|
|
1160
|
+
function applyStatusTransitionFields(map, transition) {
|
|
1161
|
+
switch (transition.status) {
|
|
1162
|
+
case "pending_review":
|
|
1163
|
+
applyPendingReviewTransition(map, transition);
|
|
1164
|
+
break;
|
|
1165
|
+
case "changes_requested":
|
|
1166
|
+
applyChangesRequestedTransition(map, transition);
|
|
1167
|
+
break;
|
|
1168
|
+
case "in_progress":
|
|
1169
|
+
applyInProgressTransition(map, transition);
|
|
1170
|
+
break;
|
|
1171
|
+
case "completed":
|
|
1172
|
+
applyCompletedTransition(map, transition);
|
|
1173
|
+
break;
|
|
1174
|
+
default:
|
|
1175
|
+
assertNever(transition);
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
function transitionPlanStatus(ydoc, transition, actor) {
|
|
1179
|
+
const metadataResult = getPlanMetadataWithValidation(ydoc);
|
|
1180
|
+
if (!metadataResult.success) return {
|
|
1181
|
+
success: false,
|
|
1182
|
+
error: metadataResult.error
|
|
1183
|
+
};
|
|
1184
|
+
const currentStatus = metadataResult.data.status;
|
|
1185
|
+
const validTargets = VALID_STATUS_TRANSITIONS[currentStatus];
|
|
1186
|
+
if (!validTargets.includes(transition.status)) return {
|
|
1187
|
+
success: false,
|
|
1188
|
+
error: `Invalid transition: cannot go from '${currentStatus}' to '${transition.status}'. Valid targets: ${validTargets.join(", ") || "none (terminal state)"}`
|
|
1189
|
+
};
|
|
1190
|
+
ydoc.transact(() => {
|
|
1191
|
+
const map = ydoc.getMap(YDOC_KEYS.METADATA);
|
|
1192
|
+
map.set("status", transition.status);
|
|
1193
|
+
applyStatusTransitionFields(map, transition);
|
|
1194
|
+
map.set("updatedAt", Date.now());
|
|
1195
|
+
}, actor ? { actor } : void 0);
|
|
1196
|
+
return { success: true };
|
|
1197
|
+
}
|
|
1198
|
+
function initPlanMetadata(ydoc, init) {
|
|
1199
|
+
const map = ydoc.getMap(YDOC_KEYS.METADATA);
|
|
1200
|
+
const now = Date.now();
|
|
1201
|
+
map.set("id", init.id);
|
|
1202
|
+
map.set("title", init.title);
|
|
1203
|
+
map.set("status", "draft");
|
|
1204
|
+
map.set("createdAt", now);
|
|
1205
|
+
map.set("updatedAt", now);
|
|
1206
|
+
if (init.repo) map.set("repo", init.repo);
|
|
1207
|
+
if (init.pr) map.set("pr", init.pr);
|
|
1208
|
+
if (init.ownerId) {
|
|
1209
|
+
map.set("ownerId", init.ownerId);
|
|
1210
|
+
map.set("approvedUsers", [init.ownerId]);
|
|
1211
|
+
map.set("approvalRequired", init.approvalRequired ?? true);
|
|
1212
|
+
}
|
|
1213
|
+
if (init.sessionTokenHash) map.set("sessionTokenHash", init.sessionTokenHash);
|
|
1214
|
+
if (init.origin) map.set("origin", init.origin);
|
|
1215
|
+
if (init.tags) map.set("tags", init.tags);
|
|
1216
|
+
const result = getPlanMetadataWithValidation(ydoc);
|
|
1217
|
+
if (!result.success) throw new Error(`Failed to initialize metadata: ${result.error}`);
|
|
1218
|
+
}
|
|
1219
|
+
function getStepCompletions(ydoc) {
|
|
1220
|
+
const steps = ydoc.getMap("stepCompletions");
|
|
1221
|
+
return new Map(steps.entries());
|
|
1222
|
+
}
|
|
1223
|
+
function toggleStepCompletion(ydoc, stepId, actor) {
|
|
1224
|
+
ydoc.transact(() => {
|
|
1225
|
+
const steps = ydoc.getMap("stepCompletions");
|
|
1226
|
+
const current = steps.get(stepId) || false;
|
|
1227
|
+
steps.set(stepId, !current);
|
|
1228
|
+
}, actor ? { actor } : void 0);
|
|
1229
|
+
}
|
|
1230
|
+
function isStepCompleted(ydoc, stepId) {
|
|
1231
|
+
return ydoc.getMap("stepCompletions").get(stepId) || false;
|
|
1232
|
+
}
|
|
1233
|
+
function getArtifacts(ydoc) {
|
|
1234
|
+
return ydoc.getArray(YDOC_KEYS.ARTIFACTS).toJSON().map((item) => {
|
|
1235
|
+
if (!item || typeof item !== "object") return null;
|
|
1236
|
+
const artifact = item;
|
|
1237
|
+
if (artifact.url && !artifact.storage) return {
|
|
1238
|
+
...artifact,
|
|
1239
|
+
storage: "github"
|
|
1240
|
+
};
|
|
1241
|
+
if (!artifact.storage && !artifact.url && !artifact.localArtifactId) return null;
|
|
1242
|
+
return artifact;
|
|
1243
|
+
}).filter((item) => item !== null).map((item) => ArtifactSchema.safeParse(item)).filter((result) => result.success).map((result) => result.data);
|
|
1244
|
+
}
|
|
1245
|
+
function addArtifact(ydoc, artifact, actor) {
|
|
1246
|
+
const validated = ArtifactSchema.parse(artifact);
|
|
1247
|
+
ydoc.transact(() => {
|
|
1248
|
+
ydoc.getArray(YDOC_KEYS.ARTIFACTS).push([validated]);
|
|
1249
|
+
}, actor ? { actor } : void 0);
|
|
1250
|
+
}
|
|
1251
|
+
function removeArtifact(ydoc, artifactId) {
|
|
1252
|
+
const array = ydoc.getArray(YDOC_KEYS.ARTIFACTS);
|
|
1253
|
+
const index = array.toJSON().findIndex((a) => a.id === artifactId);
|
|
1254
|
+
if (index === -1) return false;
|
|
1255
|
+
array.delete(index, 1);
|
|
1256
|
+
return true;
|
|
1257
|
+
}
|
|
1258
|
+
function getAgentPresences(ydoc) {
|
|
1259
|
+
const map = ydoc.getMap(YDOC_KEYS.PRESENCE);
|
|
1260
|
+
const result = /* @__PURE__ */ new Map();
|
|
1261
|
+
for (const [sessionId, value] of map.entries()) {
|
|
1262
|
+
const parsed = AgentPresenceSchema.safeParse(value);
|
|
1263
|
+
if (parsed.success) result.set(sessionId, parsed.data);
|
|
1264
|
+
}
|
|
1265
|
+
return result;
|
|
1266
|
+
}
|
|
1267
|
+
function setAgentPresence(ydoc, presence, actor) {
|
|
1268
|
+
const validated = AgentPresenceSchema.parse(presence);
|
|
1269
|
+
ydoc.transact(() => {
|
|
1270
|
+
ydoc.getMap(YDOC_KEYS.PRESENCE).set(validated.sessionId, validated);
|
|
1271
|
+
}, actor ? { actor } : void 0);
|
|
1272
|
+
}
|
|
1273
|
+
function clearAgentPresence(ydoc, sessionId) {
|
|
1274
|
+
const map = ydoc.getMap(YDOC_KEYS.PRESENCE);
|
|
1275
|
+
if (!map.has(sessionId)) return false;
|
|
1276
|
+
map.delete(sessionId);
|
|
1277
|
+
return true;
|
|
1278
|
+
}
|
|
1279
|
+
function getAgentPresence(ydoc, sessionId) {
|
|
1280
|
+
const value = ydoc.getMap(YDOC_KEYS.PRESENCE).get(sessionId);
|
|
1281
|
+
if (!value) return null;
|
|
1282
|
+
const parsed = AgentPresenceSchema.safeParse(value);
|
|
1283
|
+
return parsed.success ? parsed.data : null;
|
|
1284
|
+
}
|
|
1285
|
+
function getDeliverables(ydoc) {
|
|
1286
|
+
return ydoc.getArray(YDOC_KEYS.DELIVERABLES).toJSON().map((item) => DeliverableSchema.safeParse(item)).filter((result) => result.success).map((result) => result.data);
|
|
1287
|
+
}
|
|
1288
|
+
function addDeliverable(ydoc, deliverable, actor) {
|
|
1289
|
+
const validated = DeliverableSchema.parse(deliverable);
|
|
1290
|
+
ydoc.transact(() => {
|
|
1291
|
+
ydoc.getArray(YDOC_KEYS.DELIVERABLES).push([validated]);
|
|
1292
|
+
}, actor ? { actor } : void 0);
|
|
1293
|
+
}
|
|
1294
|
+
function linkArtifactToDeliverable(ydoc, deliverableId, artifactId, actor) {
|
|
1295
|
+
const array = ydoc.getArray(YDOC_KEYS.DELIVERABLES);
|
|
1296
|
+
const deliverables = array.toJSON();
|
|
1297
|
+
const index = deliverables.findIndex((d) => d.id === deliverableId);
|
|
1298
|
+
if (index === -1) return false;
|
|
1299
|
+
const existing = deliverables[index];
|
|
1300
|
+
if (!existing) return false;
|
|
1301
|
+
const updated = {
|
|
1302
|
+
id: existing.id,
|
|
1303
|
+
text: existing.text,
|
|
1304
|
+
linkedArtifactId: artifactId,
|
|
1305
|
+
linkedAt: Date.now()
|
|
1306
|
+
};
|
|
1307
|
+
ydoc.transact(() => {
|
|
1308
|
+
array.delete(index, 1);
|
|
1309
|
+
array.insert(index, [updated]);
|
|
1310
|
+
}, actor ? { actor } : void 0);
|
|
1311
|
+
return true;
|
|
1312
|
+
}
|
|
1313
|
+
function getPlanOwnerId(ydoc) {
|
|
1314
|
+
const ownerId = ydoc.getMap(YDOC_KEYS.METADATA).get("ownerId");
|
|
1315
|
+
return typeof ownerId === "string" ? ownerId : null;
|
|
1316
|
+
}
|
|
1317
|
+
function isApprovalRequired(ydoc) {
|
|
1318
|
+
const map = ydoc.getMap(YDOC_KEYS.METADATA);
|
|
1319
|
+
const approvalRequired = map.get("approvalRequired");
|
|
1320
|
+
if (typeof approvalRequired === "boolean") return approvalRequired;
|
|
1321
|
+
const ownerId = map.get("ownerId");
|
|
1322
|
+
return typeof ownerId === "string" && ownerId.length > 0;
|
|
1323
|
+
}
|
|
1324
|
+
function getApprovedUsers(ydoc) {
|
|
1325
|
+
const approvedUsers = ydoc.getMap(YDOC_KEYS.METADATA).get("approvedUsers");
|
|
1326
|
+
if (!Array.isArray(approvedUsers)) return [];
|
|
1327
|
+
return approvedUsers.filter((id) => typeof id === "string");
|
|
1328
|
+
}
|
|
1329
|
+
function isUserApproved(ydoc, userId) {
|
|
1330
|
+
if (getPlanOwnerId(ydoc) === userId) return true;
|
|
1331
|
+
return getApprovedUsers(ydoc).includes(userId);
|
|
1332
|
+
}
|
|
1333
|
+
function approveUser(ydoc, userId, actor) {
|
|
1334
|
+
const currentApproved = getApprovedUsers(ydoc);
|
|
1335
|
+
if (currentApproved.includes(userId)) return;
|
|
1336
|
+
ydoc.transact(() => {
|
|
1337
|
+
const map = ydoc.getMap(YDOC_KEYS.METADATA);
|
|
1338
|
+
map.set("approvedUsers", [...currentApproved, userId]);
|
|
1339
|
+
map.set("updatedAt", Date.now());
|
|
1340
|
+
}, actor ? { actor } : void 0);
|
|
1341
|
+
}
|
|
1342
|
+
function revokeUser(ydoc, userId, actor) {
|
|
1343
|
+
if (userId === getPlanOwnerId(ydoc)) return false;
|
|
1344
|
+
const currentApproved = getApprovedUsers(ydoc);
|
|
1345
|
+
if (currentApproved.indexOf(userId) === -1) return false;
|
|
1346
|
+
ydoc.transact(() => {
|
|
1347
|
+
const map = ydoc.getMap(YDOC_KEYS.METADATA);
|
|
1348
|
+
map.set("approvedUsers", currentApproved.filter((id) => id !== userId));
|
|
1349
|
+
map.set("updatedAt", Date.now());
|
|
1350
|
+
}, actor ? { actor } : void 0);
|
|
1351
|
+
return true;
|
|
1352
|
+
}
|
|
1353
|
+
function getRejectedUsers(ydoc) {
|
|
1354
|
+
const rejectedUsers = ydoc.getMap(YDOC_KEYS.METADATA).get("rejectedUsers");
|
|
1355
|
+
if (!Array.isArray(rejectedUsers)) return [];
|
|
1356
|
+
return rejectedUsers.filter((id) => typeof id === "string");
|
|
1357
|
+
}
|
|
1358
|
+
function isUserRejected(ydoc, userId) {
|
|
1359
|
+
return getRejectedUsers(ydoc).includes(userId);
|
|
1360
|
+
}
|
|
1361
|
+
function rejectUser(ydoc, userId, actor) {
|
|
1362
|
+
if (userId === getPlanOwnerId(ydoc)) return;
|
|
1363
|
+
const currentRejected = getRejectedUsers(ydoc);
|
|
1364
|
+
const currentApproved = getApprovedUsers(ydoc);
|
|
1365
|
+
ydoc.transact(() => {
|
|
1366
|
+
const map = ydoc.getMap(YDOC_KEYS.METADATA);
|
|
1367
|
+
if (!currentRejected.includes(userId)) map.set("rejectedUsers", [...currentRejected, userId]);
|
|
1368
|
+
if (currentApproved.includes(userId)) map.set("approvedUsers", currentApproved.filter((id) => id !== userId));
|
|
1369
|
+
map.set("updatedAt", Date.now());
|
|
1370
|
+
}, actor ? { actor } : void 0);
|
|
1371
|
+
}
|
|
1372
|
+
function unrejectUser(ydoc, userId, actor) {
|
|
1373
|
+
const currentRejected = getRejectedUsers(ydoc);
|
|
1374
|
+
if (currentRejected.indexOf(userId) === -1) return false;
|
|
1375
|
+
ydoc.transact(() => {
|
|
1376
|
+
const map = ydoc.getMap(YDOC_KEYS.METADATA);
|
|
1377
|
+
map.set("rejectedUsers", currentRejected.filter((id) => id !== userId));
|
|
1378
|
+
map.set("updatedAt", Date.now());
|
|
1379
|
+
}, actor ? { actor } : void 0);
|
|
1380
|
+
return true;
|
|
1381
|
+
}
|
|
1382
|
+
function getLinkedPRs(ydoc) {
|
|
1383
|
+
return ydoc.getArray(YDOC_KEYS.LINKED_PRS).toJSON().map((item) => LinkedPRSchema.safeParse(item)).filter((result) => result.success).map((result) => result.data);
|
|
1384
|
+
}
|
|
1385
|
+
function linkPR(ydoc, pr, actor) {
|
|
1386
|
+
const validated = LinkedPRSchema.parse(pr);
|
|
1387
|
+
ydoc.transact(() => {
|
|
1388
|
+
const array = ydoc.getArray(YDOC_KEYS.LINKED_PRS);
|
|
1389
|
+
const index = array.toJSON().findIndex((p) => p.prNumber === validated.prNumber);
|
|
1390
|
+
if (index !== -1) array.delete(index, 1);
|
|
1391
|
+
array.push([validated]);
|
|
1392
|
+
}, actor ? { actor } : void 0);
|
|
1393
|
+
}
|
|
1394
|
+
function unlinkPR(ydoc, prNumber) {
|
|
1395
|
+
const array = ydoc.getArray(YDOC_KEYS.LINKED_PRS);
|
|
1396
|
+
const index = array.toJSON().findIndex((p) => p.prNumber === prNumber);
|
|
1397
|
+
if (index === -1) return false;
|
|
1398
|
+
array.delete(index, 1);
|
|
1399
|
+
return true;
|
|
1400
|
+
}
|
|
1401
|
+
function getLinkedPR(ydoc, prNumber) {
|
|
1402
|
+
return getLinkedPRs(ydoc).find((pr) => pr.prNumber === prNumber) ?? null;
|
|
1403
|
+
}
|
|
1404
|
+
function updateLinkedPRStatus(ydoc, prNumber, status) {
|
|
1405
|
+
const array = ydoc.getArray(YDOC_KEYS.LINKED_PRS);
|
|
1406
|
+
const existing = array.toJSON();
|
|
1407
|
+
const index = existing.findIndex((p) => p.prNumber === prNumber);
|
|
1408
|
+
if (index === -1) return false;
|
|
1409
|
+
const pr = existing[index];
|
|
1410
|
+
if (!pr) return false;
|
|
1411
|
+
array.delete(index, 1);
|
|
1412
|
+
array.insert(index, [{
|
|
1413
|
+
...pr,
|
|
1414
|
+
status
|
|
1415
|
+
}]);
|
|
1416
|
+
return true;
|
|
1417
|
+
}
|
|
1418
|
+
function getPRReviewComments(ydoc) {
|
|
1419
|
+
return ydoc.getArray(YDOC_KEYS.PR_REVIEW_COMMENTS).toJSON().map((item) => PRReviewCommentSchema.safeParse(item)).filter((result) => result.success).map((result) => result.data);
|
|
1420
|
+
}
|
|
1421
|
+
function getPRReviewCommentsForPR(ydoc, prNumber) {
|
|
1422
|
+
return getPRReviewComments(ydoc).filter((c) => c.prNumber === prNumber);
|
|
1423
|
+
}
|
|
1424
|
+
function addPRReviewComment(ydoc, comment, actor) {
|
|
1425
|
+
const validated = PRReviewCommentSchema.parse(comment);
|
|
1426
|
+
ydoc.transact(() => {
|
|
1427
|
+
ydoc.getArray(YDOC_KEYS.PR_REVIEW_COMMENTS).push([validated]);
|
|
1428
|
+
}, actor ? { actor } : void 0);
|
|
1429
|
+
}
|
|
1430
|
+
function resolvePRReviewComment(ydoc, commentId, resolved) {
|
|
1431
|
+
const array = ydoc.getArray(YDOC_KEYS.PR_REVIEW_COMMENTS);
|
|
1432
|
+
const existing = array.toJSON();
|
|
1433
|
+
const index = existing.findIndex((c) => c.id === commentId);
|
|
1434
|
+
if (index === -1) return false;
|
|
1435
|
+
const comment = existing[index];
|
|
1436
|
+
if (!comment) return false;
|
|
1437
|
+
array.delete(index, 1);
|
|
1438
|
+
array.insert(index, [{
|
|
1439
|
+
...comment,
|
|
1440
|
+
resolved
|
|
1441
|
+
}]);
|
|
1442
|
+
return true;
|
|
1443
|
+
}
|
|
1444
|
+
function removePRReviewComment(ydoc, commentId) {
|
|
1445
|
+
const array = ydoc.getArray(YDOC_KEYS.PR_REVIEW_COMMENTS);
|
|
1446
|
+
const index = array.toJSON().findIndex((c) => c.id === commentId);
|
|
1447
|
+
if (index === -1) return false;
|
|
1448
|
+
array.delete(index, 1);
|
|
1449
|
+
return true;
|
|
1450
|
+
}
|
|
1451
|
+
function markPlanAsViewed(ydoc, username) {
|
|
1452
|
+
const map = ydoc.getMap(YDOC_KEYS.METADATA);
|
|
1453
|
+
ydoc.transact(() => {
|
|
1454
|
+
const existingViewedBy = map.get("viewedBy");
|
|
1455
|
+
let viewedBy = {};
|
|
1456
|
+
if (existingViewedBy instanceof Y.Map) {
|
|
1457
|
+
for (const [key, value] of existingViewedBy.entries()) if (typeof value === "number") viewedBy[key] = value;
|
|
1458
|
+
} else if (existingViewedBy && typeof existingViewedBy === "object") viewedBy = { ...existingViewedBy };
|
|
1459
|
+
viewedBy[username] = Date.now();
|
|
1460
|
+
const viewedByMap = new Y.Map();
|
|
1461
|
+
for (const [user, timestamp] of Object.entries(viewedBy)) viewedByMap.set(user, timestamp);
|
|
1462
|
+
map.set("viewedBy", viewedByMap);
|
|
1463
|
+
});
|
|
1464
|
+
}
|
|
1465
|
+
function getViewedBy(ydoc) {
|
|
1466
|
+
const viewedBy = ydoc.getMap(YDOC_KEYS.METADATA).get("viewedBy");
|
|
1467
|
+
if (!viewedBy) return {};
|
|
1468
|
+
if (viewedBy instanceof Y.Map) {
|
|
1469
|
+
const result = {};
|
|
1470
|
+
for (const [key, value] of viewedBy.entries()) if (typeof value === "number") result[key] = value;
|
|
1471
|
+
return result;
|
|
1472
|
+
}
|
|
1473
|
+
if (typeof viewedBy === "object") return viewedBy;
|
|
1474
|
+
return {};
|
|
1475
|
+
}
|
|
1476
|
+
function isPlanUnread(metadata, username, viewedBy) {
|
|
1477
|
+
const lastViewed = (viewedBy ?? {})[username];
|
|
1478
|
+
if (!lastViewed) return true;
|
|
1479
|
+
return lastViewed < metadata.updatedAt;
|
|
1480
|
+
}
|
|
1481
|
+
function getConversationVersions(ydoc) {
|
|
1482
|
+
return getPlanMetadata(ydoc)?.conversationVersions || [];
|
|
1483
|
+
}
|
|
1484
|
+
function addConversationVersion(ydoc, version, actor) {
|
|
1485
|
+
const validated = ConversationVersionSchema.parse(version);
|
|
1486
|
+
ydoc.transact(() => {
|
|
1487
|
+
const metadata = ydoc.getMap(YDOC_KEYS.METADATA);
|
|
1488
|
+
const versions = metadata.get("conversationVersions") || [];
|
|
1489
|
+
metadata.set("conversationVersions", [...versions, validated]);
|
|
1490
|
+
}, actor ? { actor } : void 0);
|
|
1491
|
+
}
|
|
1492
|
+
function markVersionHandedOff(ydoc, versionId, handedOffTo, actor) {
|
|
1493
|
+
const updated = getConversationVersions(ydoc).map((v) => {
|
|
1494
|
+
if (v.versionId !== versionId) return v;
|
|
1495
|
+
const handedOffVersion = {
|
|
1496
|
+
...v,
|
|
1497
|
+
handedOff: true,
|
|
1498
|
+
handedOffAt: Date.now(),
|
|
1499
|
+
handedOffTo
|
|
1500
|
+
};
|
|
1501
|
+
return ConversationVersionSchema.parse(handedOffVersion);
|
|
1502
|
+
});
|
|
1503
|
+
ydoc.transact(() => {
|
|
1504
|
+
ydoc.getMap(YDOC_KEYS.METADATA).set("conversationVersions", updated);
|
|
1505
|
+
}, actor ? { actor } : void 0);
|
|
1506
|
+
}
|
|
1507
|
+
function logPlanEvent(ydoc, type, actor, ...args) {
|
|
1508
|
+
const eventsArray = ydoc.getArray(YDOC_KEYS.EVENTS);
|
|
1509
|
+
const [data, options] = args;
|
|
1510
|
+
const eventId = options?.id ?? nanoid2();
|
|
1511
|
+
const baseEvent = {
|
|
1512
|
+
id: eventId,
|
|
1513
|
+
type,
|
|
1514
|
+
actor,
|
|
1515
|
+
timestamp: Date.now(),
|
|
1516
|
+
inboxWorthy: options?.inboxWorthy,
|
|
1517
|
+
inboxFor: options?.inboxFor
|
|
1518
|
+
};
|
|
1519
|
+
const rawEvent = data !== void 0 ? {
|
|
1520
|
+
...baseEvent,
|
|
1521
|
+
data
|
|
1522
|
+
} : baseEvent;
|
|
1523
|
+
const parsed = PlanEventSchema.safeParse(rawEvent);
|
|
1524
|
+
if (!parsed.success) throw new Error(`Invalid plan event: ${parsed.error.message}`);
|
|
1525
|
+
eventsArray.push([parsed.data]);
|
|
1526
|
+
return eventId;
|
|
1527
|
+
}
|
|
1528
|
+
function getPlanEvents(ydoc) {
|
|
1529
|
+
return ydoc.getArray(YDOC_KEYS.EVENTS).toJSON().map((item) => PlanEventSchema.safeParse(item)).filter((result) => result.success).map((result) => result.data);
|
|
1530
|
+
}
|
|
1531
|
+
function getSnapshots(ydoc) {
|
|
1532
|
+
return ydoc.getArray(YDOC_KEYS.SNAPSHOTS).toJSON().map((item) => PlanSnapshotSchema.safeParse(item)).filter((result) => result.success).map((result) => result.data).sort((a, b) => a.createdAt - b.createdAt);
|
|
1533
|
+
}
|
|
1534
|
+
function addSnapshot(ydoc, snapshot, actor) {
|
|
1535
|
+
const validated = PlanSnapshotSchema.parse(snapshot);
|
|
1536
|
+
ydoc.transact(() => {
|
|
1537
|
+
ydoc.getArray(YDOC_KEYS.SNAPSHOTS).push([validated]);
|
|
1538
|
+
}, actor ? { actor } : void 0);
|
|
1539
|
+
}
|
|
1540
|
+
function createPlanSnapshot(ydoc, reason, actor, status, blocks) {
|
|
1541
|
+
const threads = parseThreads(ydoc.getMap(YDOC_KEYS.THREADS).toJSON());
|
|
1542
|
+
const unresolved = threads.filter((t2) => !t2.resolved).length;
|
|
1543
|
+
const artifacts = getArtifacts(ydoc);
|
|
1544
|
+
const deliverables = getDeliverables(ydoc);
|
|
1545
|
+
return {
|
|
1546
|
+
id: nanoid2(),
|
|
1547
|
+
status,
|
|
1548
|
+
createdBy: actor,
|
|
1549
|
+
reason,
|
|
1550
|
+
createdAt: Date.now(),
|
|
1551
|
+
content: blocks,
|
|
1552
|
+
threadSummary: threads.length > 0 ? {
|
|
1553
|
+
total: threads.length,
|
|
1554
|
+
unresolved
|
|
1555
|
+
} : void 0,
|
|
1556
|
+
artifacts: artifacts.length > 0 ? artifacts : void 0,
|
|
1557
|
+
deliverables: deliverables.length > 0 ? deliverables : void 0
|
|
1558
|
+
};
|
|
1559
|
+
}
|
|
1560
|
+
function getLatestSnapshot(ydoc) {
|
|
1561
|
+
const snapshots = getSnapshots(ydoc);
|
|
1562
|
+
if (snapshots.length === 0) return null;
|
|
1563
|
+
return snapshots[snapshots.length - 1] ?? null;
|
|
1564
|
+
}
|
|
1565
|
+
function addPlanTag(ydoc, tag, actor) {
|
|
1566
|
+
ydoc.transact(() => {
|
|
1567
|
+
const map = ydoc.getMap(YDOC_KEYS.METADATA);
|
|
1568
|
+
const currentTags = map.get("tags") || [];
|
|
1569
|
+
const normalizedTag = tag.toLowerCase().trim();
|
|
1570
|
+
if (!normalizedTag || currentTags.includes(normalizedTag)) return;
|
|
1571
|
+
map.set("tags", [...currentTags, normalizedTag]);
|
|
1572
|
+
map.set("updatedAt", Date.now());
|
|
1573
|
+
}, actor ? { actor } : void 0);
|
|
1574
|
+
}
|
|
1575
|
+
function removePlanTag(ydoc, tag, actor) {
|
|
1576
|
+
ydoc.transact(() => {
|
|
1577
|
+
const map = ydoc.getMap(YDOC_KEYS.METADATA);
|
|
1578
|
+
const currentTags = map.get("tags") || [];
|
|
1579
|
+
const normalizedTag = tag.toLowerCase().trim();
|
|
1580
|
+
map.set("tags", currentTags.filter((t2) => t2 !== normalizedTag));
|
|
1581
|
+
map.set("updatedAt", Date.now());
|
|
1582
|
+
}, actor ? { actor } : void 0);
|
|
1583
|
+
}
|
|
1584
|
+
function getAllTagsFromIndex(indexEntries) {
|
|
1585
|
+
const tagSet = /* @__PURE__ */ new Set();
|
|
1586
|
+
for (const entry of indexEntries) if (entry.tags) for (const tag of entry.tags) tagSet.add(tag);
|
|
1587
|
+
return Array.from(tagSet).sort();
|
|
1588
|
+
}
|
|
1589
|
+
function archivePlan(ydoc, actorId) {
|
|
1590
|
+
const metadata = getPlanMetadata(ydoc);
|
|
1591
|
+
if (!metadata) return {
|
|
1592
|
+
success: false,
|
|
1593
|
+
error: "Plan metadata not found"
|
|
1594
|
+
};
|
|
1595
|
+
if (metadata.archivedAt) return {
|
|
1596
|
+
success: false,
|
|
1597
|
+
error: "Plan is already archived"
|
|
1598
|
+
};
|
|
1599
|
+
ydoc.transact(() => {
|
|
1600
|
+
const metadataMap = ydoc.getMap(YDOC_KEYS.METADATA);
|
|
1601
|
+
metadataMap.set("archivedAt", Date.now());
|
|
1602
|
+
metadataMap.set("archivedBy", actorId);
|
|
1603
|
+
metadataMap.set("updatedAt", Date.now());
|
|
1604
|
+
}, { actor: actorId });
|
|
1605
|
+
return { success: true };
|
|
1606
|
+
}
|
|
1607
|
+
function unarchivePlan(ydoc, actorId) {
|
|
1608
|
+
const metadata = getPlanMetadata(ydoc);
|
|
1609
|
+
if (!metadata) return {
|
|
1610
|
+
success: false,
|
|
1611
|
+
error: "Plan metadata not found"
|
|
1612
|
+
};
|
|
1613
|
+
if (!metadata.archivedAt) return {
|
|
1614
|
+
success: false,
|
|
1615
|
+
error: "Plan is not archived"
|
|
1616
|
+
};
|
|
1617
|
+
ydoc.transact(() => {
|
|
1618
|
+
const metadataMap = ydoc.getMap(YDOC_KEYS.METADATA);
|
|
1619
|
+
metadataMap.delete("archivedAt");
|
|
1620
|
+
metadataMap.delete("archivedBy");
|
|
1621
|
+
metadataMap.set("updatedAt", Date.now());
|
|
1622
|
+
}, { actor: actorId });
|
|
1623
|
+
return { success: true };
|
|
1624
|
+
}
|
|
1625
|
+
function answerInputRequest(ydoc, requestId, response, answeredBy) {
|
|
1626
|
+
const requestsArray = ydoc.getArray(YDOC_KEYS.INPUT_REQUESTS);
|
|
1627
|
+
const requests = requestsArray.toJSON();
|
|
1628
|
+
const index = requests.findIndex((r) => r.id === requestId);
|
|
1629
|
+
if (index === -1) return {
|
|
1630
|
+
success: false,
|
|
1631
|
+
error: "Request not found"
|
|
1632
|
+
};
|
|
1633
|
+
const request = requests[index];
|
|
1634
|
+
if (!request) return {
|
|
1635
|
+
success: false,
|
|
1636
|
+
error: "Request not found"
|
|
1637
|
+
};
|
|
1638
|
+
if (request.status !== "pending") switch (request.status) {
|
|
1639
|
+
case "answered":
|
|
1640
|
+
return {
|
|
1641
|
+
success: false,
|
|
1642
|
+
error: "Request already answered",
|
|
1643
|
+
answeredBy: request.answeredBy
|
|
1644
|
+
};
|
|
1645
|
+
case "declined":
|
|
1646
|
+
return {
|
|
1647
|
+
success: false,
|
|
1648
|
+
error: "Request was declined"
|
|
1649
|
+
};
|
|
1650
|
+
case "cancelled":
|
|
1651
|
+
return {
|
|
1652
|
+
success: false,
|
|
1653
|
+
error: "Request was cancelled"
|
|
1654
|
+
};
|
|
1655
|
+
default:
|
|
1656
|
+
return {
|
|
1657
|
+
success: false,
|
|
1658
|
+
error: `Request is not pending`
|
|
1659
|
+
};
|
|
1660
|
+
}
|
|
1661
|
+
const answeredRequest = {
|
|
1662
|
+
...request,
|
|
1663
|
+
status: "answered",
|
|
1664
|
+
response,
|
|
1665
|
+
answeredAt: Date.now(),
|
|
1666
|
+
answeredBy
|
|
1667
|
+
};
|
|
1668
|
+
const validated = InputRequestSchema.parse(answeredRequest);
|
|
1669
|
+
ydoc.transact(() => {
|
|
1670
|
+
requestsArray.delete(index, 1);
|
|
1671
|
+
requestsArray.insert(index, [validated]);
|
|
1672
|
+
});
|
|
1673
|
+
return { success: true };
|
|
1674
|
+
}
|
|
1675
|
+
function cancelInputRequest(ydoc, requestId) {
|
|
1676
|
+
const requestsArray = ydoc.getArray(YDOC_KEYS.INPUT_REQUESTS);
|
|
1677
|
+
const requests = requestsArray.toJSON();
|
|
1678
|
+
const index = requests.findIndex((r) => r.id === requestId);
|
|
1679
|
+
if (index === -1) return {
|
|
1680
|
+
success: false,
|
|
1681
|
+
error: "Request not found"
|
|
1682
|
+
};
|
|
1683
|
+
const request = requests[index];
|
|
1684
|
+
if (!request) return {
|
|
1685
|
+
success: false,
|
|
1686
|
+
error: "Request not found"
|
|
1687
|
+
};
|
|
1688
|
+
if (request.status !== "pending") return {
|
|
1689
|
+
success: false,
|
|
1690
|
+
error: `Request is not pending`
|
|
1691
|
+
};
|
|
1692
|
+
const cancelledRequest = {
|
|
1693
|
+
...request,
|
|
1694
|
+
status: "cancelled"
|
|
1695
|
+
};
|
|
1696
|
+
const validated = InputRequestSchema.parse(cancelledRequest);
|
|
1697
|
+
ydoc.transact(() => {
|
|
1698
|
+
requestsArray.delete(index, 1);
|
|
1699
|
+
requestsArray.insert(index, [validated]);
|
|
1700
|
+
});
|
|
1701
|
+
return { success: true };
|
|
1702
|
+
}
|
|
1703
|
+
|
|
1704
|
+
// ../../packages/schema/dist/url-encoding.mjs
|
|
1705
|
+
var import_lz_string = __toESM(require_lz_string(), 1);
|
|
1706
|
+
function isUrlEncodedPlanV1(plan) {
|
|
1707
|
+
return plan.v === 1;
|
|
1708
|
+
}
|
|
1709
|
+
function isUrlEncodedPlanV2(plan) {
|
|
1710
|
+
return plan.v === 2;
|
|
1711
|
+
}
|
|
1712
|
+
function encodePlan(plan) {
|
|
1713
|
+
const json = JSON.stringify(plan);
|
|
1714
|
+
return import_lz_string.default.compressToEncodedURIComponent(json);
|
|
1715
|
+
}
|
|
1716
|
+
function decodePlan(encoded) {
|
|
1717
|
+
try {
|
|
1718
|
+
const json = import_lz_string.default.decompressFromEncodedURIComponent(encoded);
|
|
1719
|
+
if (!json) return null;
|
|
1720
|
+
return JSON.parse(json);
|
|
1721
|
+
} catch (_error) {
|
|
1722
|
+
return null;
|
|
1723
|
+
}
|
|
1724
|
+
}
|
|
1725
|
+
function createPlanUrl(baseUrl, plan) {
|
|
1726
|
+
const encoded = encodePlan(plan);
|
|
1727
|
+
const url = new URL(baseUrl);
|
|
1728
|
+
url.searchParams.set("d", encoded);
|
|
1729
|
+
return url.toString();
|
|
1730
|
+
}
|
|
1731
|
+
function selectKeyVersionIds(snapshots) {
|
|
1732
|
+
if (snapshots.length === 0) return [];
|
|
1733
|
+
if (snapshots.length <= 3) return snapshots.map((s) => s.id);
|
|
1734
|
+
const ids = [];
|
|
1735
|
+
const first = snapshots[0];
|
|
1736
|
+
if (first) ids.push(first.id);
|
|
1737
|
+
const firstApproval = snapshots.find((s) => s.status === "in_progress");
|
|
1738
|
+
if (firstApproval && !ids.includes(firstApproval.id)) ids.push(firstApproval.id);
|
|
1739
|
+
const last = snapshots[snapshots.length - 1];
|
|
1740
|
+
if (last && !ids.includes(last.id)) ids.push(last.id);
|
|
1741
|
+
return ids;
|
|
1742
|
+
}
|
|
1743
|
+
function createPlanUrlWithHistory(baseUrl, plan, snapshots) {
|
|
1744
|
+
const versionRefs = snapshots.map((s) => ({
|
|
1745
|
+
id: s.id,
|
|
1746
|
+
status: s.status,
|
|
1747
|
+
createdBy: s.createdBy,
|
|
1748
|
+
reason: s.reason,
|
|
1749
|
+
createdAt: s.createdAt,
|
|
1750
|
+
threads: s.threadSummary
|
|
1751
|
+
}));
|
|
1752
|
+
const keyVersionIds = selectKeyVersionIds(snapshots);
|
|
1753
|
+
const keyVersions = snapshots.filter((s) => keyVersionIds.includes(s.id)).map((s) => ({
|
|
1754
|
+
id: s.id,
|
|
1755
|
+
content: s.content
|
|
1756
|
+
}));
|
|
1757
|
+
return createPlanUrl(baseUrl, {
|
|
1758
|
+
v: 2,
|
|
1759
|
+
...plan,
|
|
1760
|
+
versionRefs: versionRefs.length > 0 ? versionRefs : void 0,
|
|
1761
|
+
keyVersions: keyVersions.length > 0 ? keyVersions : void 0
|
|
1762
|
+
});
|
|
1763
|
+
}
|
|
1764
|
+
function getPlanFromUrl() {
|
|
1765
|
+
if (typeof globalThis !== "undefined" && "location" in globalThis) {
|
|
1766
|
+
const location = globalThis.location;
|
|
1767
|
+
const encoded = new URLSearchParams(location.search).get("d");
|
|
1768
|
+
if (!encoded) return null;
|
|
1769
|
+
return decodePlan(encoded);
|
|
1770
|
+
}
|
|
1771
|
+
return null;
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1774
|
+
// ../../packages/schema/dist/index.mjs
|
|
1775
|
+
import { z as z3 } from "zod";
|
|
1776
|
+
import * as Y2 from "yjs";
|
|
1777
|
+
import { TRPCError, initTRPC } from "@trpc/server";
|
|
1778
|
+
var A2ATextPartSchema = z3.object({
|
|
1779
|
+
type: z3.literal("text"),
|
|
1780
|
+
text: z3.string()
|
|
1781
|
+
});
|
|
1782
|
+
var A2ADataPartSchema = z3.object({
|
|
1783
|
+
type: z3.literal("data"),
|
|
1784
|
+
data: z3.unknown()
|
|
1785
|
+
});
|
|
1786
|
+
var A2AFilePartSchema = z3.object({
|
|
1787
|
+
type: z3.literal("file"),
|
|
1788
|
+
uri: z3.string(),
|
|
1789
|
+
mediaType: z3.string().optional(),
|
|
1790
|
+
name: z3.string().optional()
|
|
1791
|
+
});
|
|
1792
|
+
var A2APartSchema = z3.object({ type: z3.enum([
|
|
1793
|
+
"text",
|
|
1794
|
+
"data",
|
|
1795
|
+
"file"
|
|
1796
|
+
]) }).passthrough().superRefine((val, ctx) => {
|
|
1797
|
+
if (val.type === "text") {
|
|
1798
|
+
if (typeof val.text !== "string") ctx.addIssue({
|
|
1799
|
+
code: z3.ZodIssueCode.custom,
|
|
1800
|
+
message: "text part must have a string text field"
|
|
1801
|
+
});
|
|
1802
|
+
} else if (val.type === "data") {
|
|
1803
|
+
if (!("data" in val)) ctx.addIssue({
|
|
1804
|
+
code: z3.ZodIssueCode.custom,
|
|
1805
|
+
message: "data part must have a data field"
|
|
1806
|
+
});
|
|
1807
|
+
} else if (val.type === "file") {
|
|
1808
|
+
if (typeof val.uri !== "string") ctx.addIssue({
|
|
1809
|
+
code: z3.ZodIssueCode.custom,
|
|
1810
|
+
message: "file part must have a string uri field"
|
|
1811
|
+
});
|
|
1812
|
+
}
|
|
1813
|
+
});
|
|
1814
|
+
function isValidA2APart(part) {
|
|
1815
|
+
if (!part || typeof part !== "object") return false;
|
|
1816
|
+
const p = part;
|
|
1817
|
+
const t$1 = p.type;
|
|
1818
|
+
if (t$1 === "text") return typeof p.text === "string";
|
|
1819
|
+
else if (t$1 === "data") return "data" in p;
|
|
1820
|
+
else if (t$1 === "file") return typeof p.uri === "string";
|
|
1821
|
+
return false;
|
|
1822
|
+
}
|
|
1823
|
+
function isValidA2AParts(parts) {
|
|
1824
|
+
if (!Array.isArray(parts)) return false;
|
|
1825
|
+
return parts.every(isValidA2APart);
|
|
1826
|
+
}
|
|
1827
|
+
var A2AMessageSchema = z3.object({
|
|
1828
|
+
messageId: z3.string(),
|
|
1829
|
+
role: z3.enum(["user", "agent"]),
|
|
1830
|
+
contextId: z3.string().optional(),
|
|
1831
|
+
taskId: z3.string().optional(),
|
|
1832
|
+
referenceTaskIds: z3.array(z3.string()).optional(),
|
|
1833
|
+
metadata: z3.record(z3.string(), z3.unknown()).optional(),
|
|
1834
|
+
extensions: z3.array(z3.string()).optional()
|
|
1835
|
+
}).passthrough().refine((val) => {
|
|
1836
|
+
const parts = val.parts;
|
|
1837
|
+
return isValidA2AParts(parts);
|
|
1838
|
+
}, {
|
|
1839
|
+
message: "Invalid parts array - each part must have valid type and required fields",
|
|
1840
|
+
path: ["parts"]
|
|
1841
|
+
}).transform((val) => ({
|
|
1842
|
+
...val,
|
|
1843
|
+
parts: val.parts
|
|
1844
|
+
}));
|
|
1845
|
+
var ConversationExportMetaSchema = z3.object({
|
|
1846
|
+
exportId: z3.string(),
|
|
1847
|
+
sourcePlatform: z3.string(),
|
|
1848
|
+
sourceSessionId: z3.string(),
|
|
1849
|
+
planId: z3.string(),
|
|
1850
|
+
exportedAt: z3.number(),
|
|
1851
|
+
messageCount: z3.number(),
|
|
1852
|
+
compressedBytes: z3.number(),
|
|
1853
|
+
uncompressedBytes: z3.number()
|
|
1854
|
+
});
|
|
1855
|
+
z3.object({
|
|
1856
|
+
type: z3.literal("text"),
|
|
1857
|
+
text: z3.string()
|
|
1858
|
+
});
|
|
1859
|
+
z3.object({
|
|
1860
|
+
type: z3.literal("tool_use"),
|
|
1861
|
+
id: z3.string(),
|
|
1862
|
+
name: z3.string(),
|
|
1863
|
+
input: z3.record(z3.string(), z3.unknown())
|
|
1864
|
+
});
|
|
1865
|
+
z3.object({
|
|
1866
|
+
type: z3.literal("tool_result"),
|
|
1867
|
+
tool_use_id: z3.string(),
|
|
1868
|
+
content: z3.unknown(),
|
|
1869
|
+
is_error: z3.boolean().optional()
|
|
1870
|
+
});
|
|
1871
|
+
var ClaudeCodeContentBlockSchema = z3.object({ type: z3.enum([
|
|
1872
|
+
"text",
|
|
1873
|
+
"tool_use",
|
|
1874
|
+
"tool_result"
|
|
1875
|
+
]) }).passthrough().superRefine((val, ctx) => {
|
|
1876
|
+
const typedVal = val;
|
|
1877
|
+
if (val.type === "text") {
|
|
1878
|
+
if (typeof typedVal.text !== "string") ctx.addIssue({
|
|
1879
|
+
code: z3.ZodIssueCode.custom,
|
|
1880
|
+
message: "text block must have a string text field"
|
|
1881
|
+
});
|
|
1882
|
+
} else if (val.type === "tool_use") {
|
|
1883
|
+
if (typeof typedVal.id !== "string") ctx.addIssue({
|
|
1884
|
+
code: z3.ZodIssueCode.custom,
|
|
1885
|
+
message: "tool_use block must have a string id field"
|
|
1886
|
+
});
|
|
1887
|
+
if (typeof typedVal.name !== "string") ctx.addIssue({
|
|
1888
|
+
code: z3.ZodIssueCode.custom,
|
|
1889
|
+
message: "tool_use block must have a string name field"
|
|
1890
|
+
});
|
|
1891
|
+
if (typeof typedVal.input !== "object" || typedVal.input === null) ctx.addIssue({
|
|
1892
|
+
code: z3.ZodIssueCode.custom,
|
|
1893
|
+
message: "tool_use block must have an object input field"
|
|
1894
|
+
});
|
|
1895
|
+
} else if (val.type === "tool_result") {
|
|
1896
|
+
if (typeof typedVal.tool_use_id !== "string") ctx.addIssue({
|
|
1897
|
+
code: z3.ZodIssueCode.custom,
|
|
1898
|
+
message: "tool_result block must have a string tool_use_id field"
|
|
1899
|
+
});
|
|
1900
|
+
}
|
|
1901
|
+
});
|
|
1902
|
+
var ClaudeCodeUsageSchema = z3.object({
|
|
1903
|
+
input_tokens: z3.number(),
|
|
1904
|
+
output_tokens: z3.number(),
|
|
1905
|
+
cache_creation_input_tokens: z3.number().optional(),
|
|
1906
|
+
cache_read_input_tokens: z3.number().optional()
|
|
1907
|
+
});
|
|
1908
|
+
var ClaudeCodeMessageInnerSchema = z3.object({
|
|
1909
|
+
role: z3.string(),
|
|
1910
|
+
content: z3.array(ClaudeCodeContentBlockSchema),
|
|
1911
|
+
id: z3.string().optional(),
|
|
1912
|
+
model: z3.string().optional(),
|
|
1913
|
+
usage: ClaudeCodeUsageSchema.optional()
|
|
1914
|
+
});
|
|
1915
|
+
var ClaudeCodeMessageSchema = z3.object({
|
|
1916
|
+
sessionId: z3.string(),
|
|
1917
|
+
type: z3.enum([
|
|
1918
|
+
"user",
|
|
1919
|
+
"assistant",
|
|
1920
|
+
"summary"
|
|
1921
|
+
]),
|
|
1922
|
+
message: ClaudeCodeMessageInnerSchema,
|
|
1923
|
+
uuid: z3.string(),
|
|
1924
|
+
timestamp: z3.string(),
|
|
1925
|
+
parentUuid: z3.string().optional(),
|
|
1926
|
+
costUSD: z3.number().optional(),
|
|
1927
|
+
durationMs: z3.number().optional()
|
|
1928
|
+
});
|
|
1929
|
+
function parseClaudeCodeTranscriptString(content) {
|
|
1930
|
+
const lines = content.split("\n").filter((line) => line.trim());
|
|
1931
|
+
const messages = [];
|
|
1932
|
+
const errors = [];
|
|
1933
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1934
|
+
const line = lines[i];
|
|
1935
|
+
if (!line) continue;
|
|
1936
|
+
try {
|
|
1937
|
+
const parsed = JSON.parse(line);
|
|
1938
|
+
const result = ClaudeCodeMessageSchema.safeParse(parsed);
|
|
1939
|
+
if (result.success) messages.push(result.data);
|
|
1940
|
+
else errors.push({
|
|
1941
|
+
line: i + 1,
|
|
1942
|
+
error: `Validation failed: ${result.error.message}`
|
|
1943
|
+
});
|
|
1944
|
+
} catch (err) {
|
|
1945
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
1946
|
+
errors.push({
|
|
1947
|
+
line: i + 1,
|
|
1948
|
+
error: `JSON parse error: ${errorMessage}`
|
|
1949
|
+
});
|
|
1950
|
+
}
|
|
1951
|
+
}
|
|
1952
|
+
return {
|
|
1953
|
+
messages,
|
|
1954
|
+
errors
|
|
1955
|
+
};
|
|
1956
|
+
}
|
|
1957
|
+
function assertNever$1(x) {
|
|
1958
|
+
throw new Error(`Unhandled case: ${JSON.stringify(x)}`);
|
|
1959
|
+
}
|
|
1960
|
+
function convertContentBlock(block) {
|
|
1961
|
+
switch (block.type) {
|
|
1962
|
+
case "text":
|
|
1963
|
+
return [{
|
|
1964
|
+
type: "text",
|
|
1965
|
+
text: block.text
|
|
1966
|
+
}];
|
|
1967
|
+
case "tool_use":
|
|
1968
|
+
return [{
|
|
1969
|
+
type: "data",
|
|
1970
|
+
data: { toolUse: {
|
|
1971
|
+
name: block.name,
|
|
1972
|
+
id: block.id,
|
|
1973
|
+
input: block.input
|
|
1974
|
+
} }
|
|
1975
|
+
}];
|
|
1976
|
+
case "tool_result":
|
|
1977
|
+
return [{
|
|
1978
|
+
type: "data",
|
|
1979
|
+
data: { toolResult: {
|
|
1980
|
+
toolUseId: block.tool_use_id,
|
|
1981
|
+
content: block.content,
|
|
1982
|
+
isError: block.is_error ?? false
|
|
1983
|
+
} }
|
|
1984
|
+
}];
|
|
1985
|
+
default:
|
|
1986
|
+
return assertNever$1(block);
|
|
1987
|
+
}
|
|
1988
|
+
}
|
|
1989
|
+
function convertMessage(msg, contextId) {
|
|
1990
|
+
const role = msg.message.role === "user" ? "user" : "agent";
|
|
1991
|
+
const parts = msg.message.content.flatMap((block) => convertContentBlock(block));
|
|
1992
|
+
return {
|
|
1993
|
+
messageId: msg.uuid,
|
|
1994
|
+
role,
|
|
1995
|
+
parts,
|
|
1996
|
+
contextId,
|
|
1997
|
+
metadata: {
|
|
1998
|
+
timestamp: msg.timestamp,
|
|
1999
|
+
platform: "claude-code",
|
|
2000
|
+
parentMessageId: msg.parentUuid,
|
|
2001
|
+
model: msg.message.model,
|
|
2002
|
+
usage: msg.message.usage,
|
|
2003
|
+
costUSD: msg.costUSD,
|
|
2004
|
+
durationMs: msg.durationMs
|
|
2005
|
+
}
|
|
2006
|
+
};
|
|
2007
|
+
}
|
|
2008
|
+
function claudeCodeToA2A(messages, contextId) {
|
|
2009
|
+
return messages.filter((msg) => msg.type !== "summary").map((msg) => convertMessage(msg, contextId));
|
|
2010
|
+
}
|
|
2011
|
+
function validateA2AMessages(messages) {
|
|
2012
|
+
const valid = [];
|
|
2013
|
+
const errors = [];
|
|
2014
|
+
for (let i = 0; i < messages.length; i++) {
|
|
2015
|
+
const result = A2AMessageSchema.safeParse(messages[i]);
|
|
2016
|
+
if (result.success) valid.push(result.data);
|
|
2017
|
+
else errors.push({
|
|
2018
|
+
index: i,
|
|
2019
|
+
error: result.error.message
|
|
2020
|
+
});
|
|
2021
|
+
}
|
|
2022
|
+
return {
|
|
2023
|
+
valid,
|
|
2024
|
+
errors
|
|
2025
|
+
};
|
|
2026
|
+
}
|
|
2027
|
+
function getFirstTextPart(parts) {
|
|
2028
|
+
return parts.filter((p) => p.type === "text")[0];
|
|
2029
|
+
}
|
|
2030
|
+
function extractTitleFromMessage(msg) {
|
|
2031
|
+
if (!msg) return "Imported Conversation";
|
|
2032
|
+
const firstPart = getFirstTextPart(msg.parts);
|
|
2033
|
+
if (!firstPart) return "Imported Conversation";
|
|
2034
|
+
const text = firstPart.text;
|
|
2035
|
+
return text.length > 50 ? `${text.slice(0, 50)}...` : text;
|
|
2036
|
+
}
|
|
2037
|
+
function isToolDataPart(part) {
|
|
2038
|
+
const data = part.data;
|
|
2039
|
+
return Boolean(data && typeof data === "object" && ("toolUse" in data || "toolResult" in data));
|
|
2040
|
+
}
|
|
2041
|
+
function countToolInteractions(parts) {
|
|
2042
|
+
return parts.filter((p) => p.type === "data").filter(isToolDataPart).length;
|
|
2043
|
+
}
|
|
2044
|
+
function summarizeMessage(msg) {
|
|
2045
|
+
const prefix = msg.role === "user" ? "User" : "Agent";
|
|
2046
|
+
const firstTextPart = getFirstTextPart(msg.parts);
|
|
2047
|
+
if (firstTextPart) return `${prefix}: ${firstTextPart.text.slice(0, 100)}${firstTextPart.text.length > 100 ? "..." : ""}`;
|
|
2048
|
+
const toolCount = countToolInteractions(msg.parts);
|
|
2049
|
+
if (toolCount > 0) return `${prefix}: [${toolCount} tool interaction(s)]`;
|
|
2050
|
+
}
|
|
2051
|
+
function summarizeA2AConversation(messages, maxMessages = 3) {
|
|
2052
|
+
const title = extractTitleFromMessage(messages.find((m) => m.role === "user"));
|
|
2053
|
+
const summaryLines = messages.slice(0, maxMessages).map(summarizeMessage).filter(Boolean);
|
|
2054
|
+
if (messages.length > maxMessages) summaryLines.push(`... and ${messages.length - maxMessages} more messages`);
|
|
2055
|
+
return {
|
|
2056
|
+
title,
|
|
2057
|
+
text: summaryLines.join("\n")
|
|
2058
|
+
};
|
|
2059
|
+
}
|
|
2060
|
+
function isToolUseData(data) {
|
|
2061
|
+
if (!data || typeof data !== "object") return false;
|
|
2062
|
+
const d = data;
|
|
2063
|
+
if (!d.toolUse || typeof d.toolUse !== "object") return false;
|
|
2064
|
+
const toolUse = d.toolUse;
|
|
2065
|
+
return typeof toolUse.name === "string" && typeof toolUse.id === "string" && typeof toolUse.input === "object";
|
|
2066
|
+
}
|
|
2067
|
+
function isToolResultData(data) {
|
|
2068
|
+
if (!data || typeof data !== "object") return false;
|
|
2069
|
+
const d = data;
|
|
2070
|
+
if (!d.toolResult || typeof d.toolResult !== "object") return false;
|
|
2071
|
+
return typeof d.toolResult.toolUseId === "string";
|
|
2072
|
+
}
|
|
2073
|
+
function convertA2APartToContentBlock(part) {
|
|
2074
|
+
switch (part.type) {
|
|
2075
|
+
case "text":
|
|
2076
|
+
return [{
|
|
2077
|
+
type: "text",
|
|
2078
|
+
text: part.text
|
|
2079
|
+
}];
|
|
2080
|
+
case "data": {
|
|
2081
|
+
const data = part.data;
|
|
2082
|
+
if (isToolUseData(data)) return [{
|
|
2083
|
+
type: "tool_use",
|
|
2084
|
+
id: data.toolUse.id,
|
|
2085
|
+
name: data.toolUse.name,
|
|
2086
|
+
input: data.toolUse.input
|
|
2087
|
+
}];
|
|
2088
|
+
if (isToolResultData(data)) return [{
|
|
2089
|
+
type: "tool_result",
|
|
2090
|
+
tool_use_id: data.toolResult.toolUseId,
|
|
2091
|
+
content: data.toolResult.content,
|
|
2092
|
+
is_error: data.toolResult.isError
|
|
2093
|
+
}];
|
|
2094
|
+
return [{
|
|
2095
|
+
type: "text",
|
|
2096
|
+
text: `[Data: ${JSON.stringify(data)}]`
|
|
2097
|
+
}];
|
|
2098
|
+
}
|
|
2099
|
+
case "file":
|
|
2100
|
+
return [{
|
|
2101
|
+
type: "text",
|
|
2102
|
+
text: `[File: ${part.name ?? part.uri}${part.mediaType ? ` (${part.mediaType})` : ""}]`
|
|
2103
|
+
}];
|
|
2104
|
+
default:
|
|
2105
|
+
return assertNever$1(part);
|
|
2106
|
+
}
|
|
2107
|
+
}
|
|
2108
|
+
function convertA2AToClaudeCodeMessage(msg, sessionId, parentUuid) {
|
|
2109
|
+
const role = msg.role === "user" ? "user" : "assistant";
|
|
2110
|
+
const type = msg.role === "user" ? "user" : "assistant";
|
|
2111
|
+
const content = msg.parts.flatMap(convertA2APartToContentBlock);
|
|
2112
|
+
const metadata = msg.metadata || {};
|
|
2113
|
+
const timestamp = typeof metadata.timestamp === "string" ? metadata.timestamp : (/* @__PURE__ */ new Date()).toISOString();
|
|
2114
|
+
const model = typeof metadata.model === "string" ? metadata.model : void 0;
|
|
2115
|
+
const usage = metadata.usage;
|
|
2116
|
+
const costUSD = typeof metadata.costUSD === "number" ? metadata.costUSD : void 0;
|
|
2117
|
+
const durationMs = typeof metadata.durationMs === "number" ? metadata.durationMs : void 0;
|
|
2118
|
+
return {
|
|
2119
|
+
sessionId,
|
|
2120
|
+
type,
|
|
2121
|
+
message: {
|
|
2122
|
+
role,
|
|
2123
|
+
content,
|
|
2124
|
+
...model && { model },
|
|
2125
|
+
...usage && { usage }
|
|
2126
|
+
},
|
|
2127
|
+
uuid: msg.messageId,
|
|
2128
|
+
timestamp,
|
|
2129
|
+
...parentUuid && { parentUuid },
|
|
2130
|
+
...costUSD !== void 0 && { costUSD },
|
|
2131
|
+
...durationMs !== void 0 && { durationMs }
|
|
2132
|
+
};
|
|
2133
|
+
}
|
|
2134
|
+
function a2aToClaudeCode(messages, sessionId) {
|
|
2135
|
+
const resolvedSessionId = sessionId ?? crypto.randomUUID();
|
|
2136
|
+
let parentUuid;
|
|
2137
|
+
return messages.map((msg) => {
|
|
2138
|
+
const claudeMsg = convertA2AToClaudeCodeMessage(msg, resolvedSessionId, parentUuid);
|
|
2139
|
+
parentUuid = claudeMsg.uuid;
|
|
2140
|
+
return claudeMsg;
|
|
2141
|
+
});
|
|
2142
|
+
}
|
|
2143
|
+
function formatAsClaudeCodeJSONL(messages) {
|
|
2144
|
+
return messages.map((msg) => JSON.stringify(msg)).join("\n");
|
|
2145
|
+
}
|
|
2146
|
+
function formatDeliverablesForLLM(deliverables) {
|
|
2147
|
+
if (deliverables.length === 0) return "";
|
|
2148
|
+
let output = "## Deliverables\n\n";
|
|
2149
|
+
output += "Available deliverable IDs for artifact linking:\n\n";
|
|
2150
|
+
for (const deliverable of deliverables) {
|
|
2151
|
+
const checkbox = deliverable.linkedArtifactId ? "[x]" : "[ ]";
|
|
2152
|
+
const linkedInfo = deliverable.linkedArtifactId ? ` (linked to artifact: ${deliverable.linkedArtifactId})` : "";
|
|
2153
|
+
output += `- ${checkbox} ${deliverable.text} {id="${deliverable.id}"}${linkedInfo}
|
|
2154
|
+
`;
|
|
2155
|
+
}
|
|
2156
|
+
return output;
|
|
2157
|
+
}
|
|
2158
|
+
var DELIVERABLE_MARKER = "{#deliverable}";
|
|
2159
|
+
function extractDeliverables(blocks) {
|
|
2160
|
+
const deliverables = [];
|
|
2161
|
+
function processBlock(block) {
|
|
2162
|
+
const text = extractTextFromBlock(block);
|
|
2163
|
+
if (text.includes(DELIVERABLE_MARKER)) {
|
|
2164
|
+
const markerRegex = new RegExp(`\\s*${DELIVERABLE_MARKER.replace(/[{}#]/g, "\\$&")}\\s*`, "g");
|
|
2165
|
+
const cleanText = text.replace(markerRegex, "").trim();
|
|
2166
|
+
deliverables.push({
|
|
2167
|
+
id: block.id,
|
|
2168
|
+
text: cleanText
|
|
2169
|
+
});
|
|
2170
|
+
}
|
|
2171
|
+
if (block.children && Array.isArray(block.children)) for (const child of block.children) processBlock(child);
|
|
2172
|
+
}
|
|
2173
|
+
for (const block of blocks) processBlock(block);
|
|
2174
|
+
return deliverables;
|
|
2175
|
+
}
|
|
2176
|
+
function extractTextFromBlock(block) {
|
|
2177
|
+
if (!block.content || !Array.isArray(block.content) || block.content.length === 0) return "";
|
|
2178
|
+
return block.content.map((item) => item.text || "").join("").trim();
|
|
2179
|
+
}
|
|
2180
|
+
var GitHubPRResponseSchema = z3.object({
|
|
2181
|
+
number: z3.number(),
|
|
2182
|
+
html_url: z3.string().url(),
|
|
2183
|
+
title: z3.string(),
|
|
2184
|
+
state: z3.enum(["open", "closed"]),
|
|
2185
|
+
draft: z3.boolean(),
|
|
2186
|
+
merged: z3.boolean(),
|
|
2187
|
+
head: z3.object({ ref: z3.string() })
|
|
2188
|
+
});
|
|
2189
|
+
function asPlanId(id) {
|
|
2190
|
+
return id;
|
|
2191
|
+
}
|
|
2192
|
+
function asAwarenessClientId(id) {
|
|
2193
|
+
return id;
|
|
2194
|
+
}
|
|
2195
|
+
function asWebRTCPeerId(id) {
|
|
2196
|
+
return id;
|
|
2197
|
+
}
|
|
2198
|
+
function asGitHubUsername(username) {
|
|
2199
|
+
return username;
|
|
2200
|
+
}
|
|
2201
|
+
var InviteTokenSchema = z3.object({
|
|
2202
|
+
id: z3.string(),
|
|
2203
|
+
tokenHash: z3.string(),
|
|
2204
|
+
planId: z3.string(),
|
|
2205
|
+
createdBy: z3.string(),
|
|
2206
|
+
createdAt: z3.number(),
|
|
2207
|
+
expiresAt: z3.number(),
|
|
2208
|
+
maxUses: z3.number().nullable(),
|
|
2209
|
+
useCount: z3.number(),
|
|
2210
|
+
revoked: z3.boolean(),
|
|
2211
|
+
label: z3.string().optional()
|
|
2212
|
+
});
|
|
2213
|
+
var InviteRedemptionSchema = z3.object({
|
|
2214
|
+
redeemedBy: z3.string(),
|
|
2215
|
+
redeemedAt: z3.number(),
|
|
2216
|
+
tokenId: z3.string()
|
|
2217
|
+
});
|
|
2218
|
+
function parseInviteFromUrl(url) {
|
|
2219
|
+
try {
|
|
2220
|
+
const inviteParam = new URL(url).searchParams.get("invite");
|
|
2221
|
+
if (!inviteParam) return null;
|
|
2222
|
+
const [tokenId, tokenValue] = inviteParam.split(":");
|
|
2223
|
+
if (!tokenId || !tokenValue) return null;
|
|
2224
|
+
return {
|
|
2225
|
+
tokenId,
|
|
2226
|
+
tokenValue
|
|
2227
|
+
};
|
|
2228
|
+
} catch {
|
|
2229
|
+
return null;
|
|
2230
|
+
}
|
|
2231
|
+
}
|
|
2232
|
+
function buildInviteUrl(baseUrl, planId, tokenId, tokenValue) {
|
|
2233
|
+
const normalizedBase = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
|
|
2234
|
+
const url = new URL(`${normalizedBase}/task/${planId}`);
|
|
2235
|
+
url.searchParams.set("invite", `${tokenId}:${tokenValue}`);
|
|
2236
|
+
return url.toString();
|
|
2237
|
+
}
|
|
2238
|
+
function getTokenTimeRemaining(expiresAt) {
|
|
2239
|
+
const remaining = expiresAt - Date.now();
|
|
2240
|
+
if (remaining <= 0) return {
|
|
2241
|
+
expired: true,
|
|
2242
|
+
minutes: 0,
|
|
2243
|
+
formatted: "Expired"
|
|
2244
|
+
};
|
|
2245
|
+
const minutes = Math.ceil(remaining / 6e4);
|
|
2246
|
+
if (minutes >= 60) {
|
|
2247
|
+
const hours = Math.floor(minutes / 60);
|
|
2248
|
+
const mins = minutes % 60;
|
|
2249
|
+
return {
|
|
2250
|
+
expired: false,
|
|
2251
|
+
minutes,
|
|
2252
|
+
formatted: mins > 0 ? `${hours}h ${mins}m` : `${hours}h`
|
|
2253
|
+
};
|
|
2254
|
+
}
|
|
2255
|
+
return {
|
|
2256
|
+
expired: false,
|
|
2257
|
+
minutes,
|
|
2258
|
+
formatted: `${minutes}m`
|
|
2259
|
+
};
|
|
2260
|
+
}
|
|
2261
|
+
var P2PMessageType = {
|
|
2262
|
+
CONVERSATION_EXPORT_START: 240,
|
|
2263
|
+
CONVERSATION_CHUNK: 241,
|
|
2264
|
+
CONVERSATION_EXPORT_END: 242
|
|
2265
|
+
};
|
|
2266
|
+
var ConversationExportStartMetaSchema = z3.object({
|
|
2267
|
+
exportId: z3.string(),
|
|
2268
|
+
totalChunks: z3.number().int().positive(),
|
|
2269
|
+
totalBytes: z3.number().int().nonnegative(),
|
|
2270
|
+
compressedBytes: z3.number().int().nonnegative(),
|
|
2271
|
+
sourcePlatform: z3.string(),
|
|
2272
|
+
sourceSessionId: z3.string(),
|
|
2273
|
+
planId: z3.string(),
|
|
2274
|
+
exportedAt: z3.number().int().positive()
|
|
2275
|
+
});
|
|
2276
|
+
var ChunkMessageSchema = z3.object({
|
|
2277
|
+
exportId: z3.string(),
|
|
2278
|
+
chunkIndex: z3.number().int().nonnegative(),
|
|
2279
|
+
data: z3.instanceof(Uint8Array)
|
|
2280
|
+
});
|
|
2281
|
+
var ConversationExportEndSchema = z3.object({
|
|
2282
|
+
exportId: z3.string(),
|
|
2283
|
+
checksum: z3.string()
|
|
2284
|
+
});
|
|
2285
|
+
function isConversationExportStart(data) {
|
|
2286
|
+
return data.length > 0 && data[0] === P2PMessageType.CONVERSATION_EXPORT_START;
|
|
2287
|
+
}
|
|
2288
|
+
function isConversationChunk(data) {
|
|
2289
|
+
return data.length > 0 && data[0] === P2PMessageType.CONVERSATION_CHUNK;
|
|
2290
|
+
}
|
|
2291
|
+
function isConversationExportEnd(data) {
|
|
2292
|
+
return data.length > 0 && data[0] === P2PMessageType.CONVERSATION_EXPORT_END;
|
|
2293
|
+
}
|
|
2294
|
+
function isP2PConversationMessage(data) {
|
|
2295
|
+
if (data.length === 0) return false;
|
|
2296
|
+
const type = data[0];
|
|
2297
|
+
return type === P2PMessageType.CONVERSATION_EXPORT_START || type === P2PMessageType.CONVERSATION_CHUNK || type === P2PMessageType.CONVERSATION_EXPORT_END;
|
|
2298
|
+
}
|
|
2299
|
+
var textEncoder = new TextEncoder();
|
|
2300
|
+
var textDecoder = new TextDecoder();
|
|
2301
|
+
function encodeExportStartMessage(meta) {
|
|
2302
|
+
const jsonBytes = textEncoder.encode(JSON.stringify(meta));
|
|
2303
|
+
const result = new Uint8Array(1 + jsonBytes.length);
|
|
2304
|
+
result[0] = P2PMessageType.CONVERSATION_EXPORT_START;
|
|
2305
|
+
result.set(jsonBytes, 1);
|
|
2306
|
+
return result;
|
|
2307
|
+
}
|
|
2308
|
+
function decodeExportStartMessage(data) {
|
|
2309
|
+
if (data.length === 0 || data[0] !== P2PMessageType.CONVERSATION_EXPORT_START) throw new Error("Invalid export start message: wrong type byte");
|
|
2310
|
+
const jsonStr = textDecoder.decode(data.slice(1));
|
|
2311
|
+
const parsed = JSON.parse(jsonStr);
|
|
2312
|
+
return ConversationExportStartMetaSchema.parse(parsed);
|
|
2313
|
+
}
|
|
2314
|
+
function encodeChunkMessage(chunk) {
|
|
2315
|
+
const exportIdBytes = textEncoder.encode(chunk.exportId);
|
|
2316
|
+
const result = new Uint8Array(5 + exportIdBytes.length + 4 + chunk.data.length);
|
|
2317
|
+
let offset = 0;
|
|
2318
|
+
result[offset] = P2PMessageType.CONVERSATION_CHUNK;
|
|
2319
|
+
offset += 1;
|
|
2320
|
+
const view = new DataView(result.buffer);
|
|
2321
|
+
view.setUint32(offset, exportIdBytes.length, false);
|
|
2322
|
+
offset += 4;
|
|
2323
|
+
result.set(exportIdBytes, offset);
|
|
2324
|
+
offset += exportIdBytes.length;
|
|
2325
|
+
view.setUint32(offset, chunk.chunkIndex, false);
|
|
2326
|
+
offset += 4;
|
|
2327
|
+
result.set(chunk.data, offset);
|
|
2328
|
+
return result;
|
|
2329
|
+
}
|
|
2330
|
+
function decodeChunkMessage(data) {
|
|
2331
|
+
if (data.length < 9 || data[0] !== P2PMessageType.CONVERSATION_CHUNK) throw new Error("Invalid chunk message: too short or wrong type byte");
|
|
2332
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
2333
|
+
let offset = 1;
|
|
2334
|
+
const exportIdLength = view.getUint32(offset, false);
|
|
2335
|
+
offset += 4;
|
|
2336
|
+
if (data.length < 9 + exportIdLength) throw new Error("Invalid chunk message: exportId extends beyond message");
|
|
2337
|
+
const exportId = textDecoder.decode(data.slice(offset, offset + exportIdLength));
|
|
2338
|
+
offset += exportIdLength;
|
|
2339
|
+
const chunkIndex = view.getUint32(offset, false);
|
|
2340
|
+
offset += 4;
|
|
2341
|
+
const chunkData = data.slice(offset);
|
|
2342
|
+
return ChunkMessageSchema.parse({
|
|
2343
|
+
exportId,
|
|
2344
|
+
chunkIndex,
|
|
2345
|
+
data: chunkData
|
|
2346
|
+
});
|
|
2347
|
+
}
|
|
2348
|
+
function encodeExportEndMessage(end) {
|
|
2349
|
+
const jsonBytes = textEncoder.encode(JSON.stringify(end));
|
|
2350
|
+
const result = new Uint8Array(1 + jsonBytes.length);
|
|
2351
|
+
result[0] = P2PMessageType.CONVERSATION_EXPORT_END;
|
|
2352
|
+
result.set(jsonBytes, 1);
|
|
2353
|
+
return result;
|
|
2354
|
+
}
|
|
2355
|
+
function decodeExportEndMessage(data) {
|
|
2356
|
+
if (data.length === 0 || data[0] !== P2PMessageType.CONVERSATION_EXPORT_END) throw new Error("Invalid export end message: wrong type byte");
|
|
2357
|
+
const jsonStr = textDecoder.decode(data.slice(1));
|
|
2358
|
+
const parsed = JSON.parse(jsonStr);
|
|
2359
|
+
return ConversationExportEndSchema.parse(parsed);
|
|
2360
|
+
}
|
|
2361
|
+
function decodeP2PMessage(data) {
|
|
2362
|
+
if (data.length === 0) throw new Error("Cannot decode empty message");
|
|
2363
|
+
const type = data[0];
|
|
2364
|
+
if (type === void 0) throw new Error("Message type byte is missing");
|
|
2365
|
+
switch (type) {
|
|
2366
|
+
case P2PMessageType.CONVERSATION_EXPORT_START:
|
|
2367
|
+
return {
|
|
2368
|
+
type: "export_start",
|
|
2369
|
+
payload: decodeExportStartMessage(data)
|
|
2370
|
+
};
|
|
2371
|
+
case P2PMessageType.CONVERSATION_CHUNK:
|
|
2372
|
+
return {
|
|
2373
|
+
type: "chunk",
|
|
2374
|
+
payload: decodeChunkMessage(data)
|
|
2375
|
+
};
|
|
2376
|
+
case P2PMessageType.CONVERSATION_EXPORT_END:
|
|
2377
|
+
return {
|
|
2378
|
+
type: "export_end",
|
|
2379
|
+
payload: decodeExportEndMessage(data)
|
|
2380
|
+
};
|
|
2381
|
+
default:
|
|
2382
|
+
throw new Error(`Unknown P2P message type: 0x${type.toString(16)}`);
|
|
2383
|
+
}
|
|
2384
|
+
}
|
|
2385
|
+
function assertNeverP2PMessage(msg) {
|
|
2386
|
+
throw new Error(`Unhandled P2P message type: ${JSON.stringify(msg)}`);
|
|
2387
|
+
}
|
|
2388
|
+
var PLAN_INDEX_DOC_NAME = "plan-index";
|
|
2389
|
+
var PLAN_INDEX_VIEWED_BY_KEY = "viewedBy";
|
|
2390
|
+
var NON_PLAN_DB_NAMES = ["plan-index", "idb-keyval"];
|
|
2391
|
+
var PlanIndexEntrySchema = z3.discriminatedUnion("deleted", [z3.object({
|
|
2392
|
+
deleted: z3.literal(false),
|
|
2393
|
+
id: z3.string(),
|
|
2394
|
+
title: z3.string(),
|
|
2395
|
+
status: z3.enum(PlanStatusValues),
|
|
2396
|
+
createdAt: z3.number(),
|
|
2397
|
+
updatedAt: z3.number(),
|
|
2398
|
+
ownerId: z3.string(),
|
|
2399
|
+
tags: z3.array(z3.string()).optional()
|
|
2400
|
+
}), z3.object({
|
|
2401
|
+
deleted: z3.literal(true),
|
|
2402
|
+
id: z3.string(),
|
|
2403
|
+
title: z3.string(),
|
|
2404
|
+
status: z3.enum(PlanStatusValues),
|
|
2405
|
+
createdAt: z3.number(),
|
|
2406
|
+
updatedAt: z3.number(),
|
|
2407
|
+
ownerId: z3.string(),
|
|
2408
|
+
tags: z3.array(z3.string()).optional(),
|
|
2409
|
+
deletedAt: z3.number(),
|
|
2410
|
+
deletedBy: z3.string()
|
|
2411
|
+
})]);
|
|
2412
|
+
function getPlanIndex(ydoc, includeArchived = false) {
|
|
2413
|
+
const plansMap = ydoc.getMap(YDOC_KEYS.PLANS);
|
|
2414
|
+
const entries = [];
|
|
2415
|
+
for (const [_id, data] of plansMap.entries()) {
|
|
2416
|
+
const result = PlanIndexEntrySchema.safeParse(data);
|
|
2417
|
+
if (result.success) {
|
|
2418
|
+
if (!includeArchived && result.data.deleted) continue;
|
|
2419
|
+
entries.push(result.data);
|
|
2420
|
+
}
|
|
2421
|
+
}
|
|
2422
|
+
return entries.sort((a, b) => b.updatedAt - a.updatedAt);
|
|
2423
|
+
}
|
|
2424
|
+
function getPlanIndexEntry(ydoc, planId) {
|
|
2425
|
+
const data = ydoc.getMap(YDOC_KEYS.PLANS).get(planId);
|
|
2426
|
+
if (!data) return null;
|
|
2427
|
+
const result = PlanIndexEntrySchema.safeParse(data);
|
|
2428
|
+
return result.success ? result.data : null;
|
|
2429
|
+
}
|
|
2430
|
+
function setPlanIndexEntry(ydoc, entry) {
|
|
2431
|
+
const validated = PlanIndexEntrySchema.parse(entry);
|
|
2432
|
+
ydoc.getMap(YDOC_KEYS.PLANS).set(validated.id, validated);
|
|
2433
|
+
}
|
|
2434
|
+
function removePlanIndexEntry(ydoc, planId) {
|
|
2435
|
+
ydoc.getMap(YDOC_KEYS.PLANS).delete(planId);
|
|
2436
|
+
}
|
|
2437
|
+
function touchPlanIndexEntry(ydoc, planId) {
|
|
2438
|
+
const entry = getPlanIndexEntry(ydoc, planId);
|
|
2439
|
+
if (entry) setPlanIndexEntry(ydoc, {
|
|
2440
|
+
...entry,
|
|
2441
|
+
updatedAt: Date.now()
|
|
2442
|
+
});
|
|
2443
|
+
}
|
|
2444
|
+
function getViewedByFromIndex(ydoc, planId) {
|
|
2445
|
+
const planViewedBy = ydoc.getMap(PLAN_INDEX_VIEWED_BY_KEY).get(planId);
|
|
2446
|
+
if (!planViewedBy || !(planViewedBy instanceof Y2.Map)) return {};
|
|
2447
|
+
const result = {};
|
|
2448
|
+
for (const [username, timestamp] of planViewedBy.entries()) if (typeof timestamp === "number") result[username] = timestamp;
|
|
2449
|
+
return result;
|
|
2450
|
+
}
|
|
2451
|
+
function updatePlanIndexViewedBy(ydoc, planId, username) {
|
|
2452
|
+
ydoc.transact(() => {
|
|
2453
|
+
const viewedByRoot = ydoc.getMap(PLAN_INDEX_VIEWED_BY_KEY);
|
|
2454
|
+
let planViewedBy = viewedByRoot.get(planId);
|
|
2455
|
+
if (!planViewedBy || !(planViewedBy instanceof Y2.Map)) {
|
|
2456
|
+
planViewedBy = new Y2.Map();
|
|
2457
|
+
viewedByRoot.set(planId, planViewedBy);
|
|
2458
|
+
}
|
|
2459
|
+
planViewedBy.set(username, Date.now());
|
|
2460
|
+
});
|
|
2461
|
+
}
|
|
2462
|
+
function clearPlanIndexViewedBy(ydoc, planId, username) {
|
|
2463
|
+
ydoc.transact(() => {
|
|
2464
|
+
const planViewedBy = ydoc.getMap(PLAN_INDEX_VIEWED_BY_KEY).get(planId);
|
|
2465
|
+
if (planViewedBy && planViewedBy instanceof Y2.Map) planViewedBy.delete(username);
|
|
2466
|
+
});
|
|
2467
|
+
}
|
|
2468
|
+
function getAllViewedByFromIndex(ydoc, planIds) {
|
|
2469
|
+
const result = {};
|
|
2470
|
+
for (const planId of planIds) result[planId] = getViewedByFromIndex(ydoc, planId);
|
|
2471
|
+
return result;
|
|
2472
|
+
}
|
|
2473
|
+
function removeViewedByFromIndex(ydoc, planId) {
|
|
2474
|
+
ydoc.getMap(PLAN_INDEX_VIEWED_BY_KEY).delete(planId);
|
|
2475
|
+
}
|
|
2476
|
+
var PLAN_INDEX_EVENT_VIEWED_BY_KEY = "event-viewedBy";
|
|
2477
|
+
function markEventAsViewed(ydoc, planId, eventId, username) {
|
|
2478
|
+
const viewedByRoot = ydoc.getMap(PLAN_INDEX_EVENT_VIEWED_BY_KEY);
|
|
2479
|
+
let planEvents = viewedByRoot.get(planId);
|
|
2480
|
+
if (!planEvents) {
|
|
2481
|
+
planEvents = new Y2.Map();
|
|
2482
|
+
viewedByRoot.set(planId, planEvents);
|
|
2483
|
+
}
|
|
2484
|
+
let eventViews = planEvents.get(eventId);
|
|
2485
|
+
if (!eventViews) {
|
|
2486
|
+
eventViews = new Y2.Map();
|
|
2487
|
+
planEvents.set(eventId, eventViews);
|
|
2488
|
+
}
|
|
2489
|
+
eventViews.set(username, Date.now());
|
|
2490
|
+
}
|
|
2491
|
+
function clearEventViewedBy(ydoc, planId, eventId, username) {
|
|
2492
|
+
const planEvents = ydoc.getMap(PLAN_INDEX_EVENT_VIEWED_BY_KEY).get(planId);
|
|
2493
|
+
if (!planEvents) return;
|
|
2494
|
+
const eventViews = planEvents.get(eventId);
|
|
2495
|
+
if (!eventViews) return;
|
|
2496
|
+
eventViews.delete(username);
|
|
2497
|
+
}
|
|
2498
|
+
function isEventUnread(ydoc, planId, eventId, username) {
|
|
2499
|
+
const planEvents = ydoc.getMap(PLAN_INDEX_EVENT_VIEWED_BY_KEY).get(planId);
|
|
2500
|
+
if (!planEvents) return true;
|
|
2501
|
+
const eventViews = planEvents.get(eventId);
|
|
2502
|
+
if (!eventViews) return true;
|
|
2503
|
+
return !eventViews.has(username);
|
|
2504
|
+
}
|
|
2505
|
+
function getAllEventViewedByForPlan(ydoc, planId) {
|
|
2506
|
+
const planEvents = ydoc.getMap(PLAN_INDEX_EVENT_VIEWED_BY_KEY).get(planId);
|
|
2507
|
+
if (!planEvents) return {};
|
|
2508
|
+
const result = {};
|
|
2509
|
+
for (const [eventId, eventViews] of planEvents.entries()) {
|
|
2510
|
+
const views = eventViews;
|
|
2511
|
+
result[eventId] = Object.fromEntries(views.entries());
|
|
2512
|
+
}
|
|
2513
|
+
return result;
|
|
2514
|
+
}
|
|
2515
|
+
var ROUTES = {
|
|
2516
|
+
REGISTRY_LIST: "/registry",
|
|
2517
|
+
REGISTRY_REGISTER: "/register",
|
|
2518
|
+
REGISTRY_UNREGISTER: "/unregister",
|
|
2519
|
+
PLAN_STATUS: (planId) => `/api/plan/${planId}/status`,
|
|
2520
|
+
PLAN_HAS_CONNECTIONS: (planId) => `/api/plan/${planId}/has-connections`,
|
|
2521
|
+
PLAN_TRANSCRIPT: (planId) => `/api/plan/${planId}/transcript`,
|
|
2522
|
+
PLAN_SUBSCRIBE: (planId) => `/api/plan/${planId}/subscribe`,
|
|
2523
|
+
PLAN_CHANGES: (planId) => `/api/plan/${planId}/changes`,
|
|
2524
|
+
PLAN_UNSUBSCRIBE: (planId) => `/api/plan/${planId}/unsubscribe`,
|
|
2525
|
+
PLAN_PR_DIFF: (planId, prNumber) => `/api/plans/${planId}/pr-diff/${prNumber}`,
|
|
2526
|
+
PLAN_PR_FILES: (planId, prNumber) => `/api/plans/${planId}/pr-files/${prNumber}`,
|
|
2527
|
+
HOOK_SESSION: "/api/hook/session",
|
|
2528
|
+
HOOK_CONTENT: (planId) => `/api/hook/plan/${planId}/content`,
|
|
2529
|
+
HOOK_REVIEW: (planId) => `/api/hook/plan/${planId}/review`,
|
|
2530
|
+
HOOK_SESSION_TOKEN: (planId) => `/api/hook/plan/${planId}/session-token`,
|
|
2531
|
+
HOOK_PRESENCE: (planId) => `/api/hook/plan/${planId}/presence`,
|
|
2532
|
+
CONVERSATION_IMPORT: "/api/conversation/import"
|
|
2533
|
+
};
|
|
2534
|
+
function formatThreadsForLLM(threads, options = {}) {
|
|
2535
|
+
const { includeResolved = false, selectedTextMaxLength = 100, resolveUser } = options;
|
|
2536
|
+
const unresolvedThreads = threads.filter((t$1) => !t$1.resolved);
|
|
2537
|
+
const resolvedCount = threads.length - unresolvedThreads.length;
|
|
2538
|
+
const threadsToShow = includeResolved ? threads : unresolvedThreads;
|
|
2539
|
+
if (threadsToShow.length === 0) {
|
|
2540
|
+
if (resolvedCount > 0) return `All ${resolvedCount} comment(s) have been resolved.`;
|
|
2541
|
+
return "";
|
|
2542
|
+
}
|
|
2543
|
+
let output = threadsToShow.map((thread, index) => {
|
|
2544
|
+
const location = thread.selectedText ? `On: "${truncate(thread.selectedText, selectedTextMaxLength)}"` : `Comment ${index + 1}`;
|
|
2545
|
+
const comments = thread.comments.map((c, idx) => {
|
|
2546
|
+
const text = extractTextFromCommentBody(c.body);
|
|
2547
|
+
const author = resolveUser ? resolveUser(c.userId) : c.userId.slice(0, 8);
|
|
2548
|
+
if (idx === 0) return `${author}: ${text}`;
|
|
2549
|
+
return `${author} (reply): ${text}`;
|
|
2550
|
+
}).join("\n");
|
|
2551
|
+
return `${location}${thread.resolved ? " [Resolved]" : ""}
|
|
2552
|
+
${comments}`;
|
|
2553
|
+
}).join("\n\n");
|
|
2554
|
+
if (!includeResolved && resolvedCount > 0) output += `
|
|
2555
|
+
|
|
2556
|
+
---
|
|
2557
|
+
(${resolvedCount} resolved comment(s) not shown)`;
|
|
2558
|
+
return output;
|
|
2559
|
+
}
|
|
2560
|
+
function truncate(text, maxLength) {
|
|
2561
|
+
const cleaned = text.replace(/\n/g, " ").trim();
|
|
2562
|
+
if (cleaned.length <= maxLength) return cleaned;
|
|
2563
|
+
return `${cleaned.slice(0, maxLength)}...`;
|
|
2564
|
+
}
|
|
2565
|
+
var PlanIdSchema = z3.object({ planId: z3.string().min(1) });
|
|
2566
|
+
var PlanStatusResponseSchema = z3.object({ status: z3.string() });
|
|
2567
|
+
var HasConnectionsResponseSchema = z3.object({ hasConnections: z3.boolean() });
|
|
2568
|
+
var SubscriptionClientIdSchema = z3.object({
|
|
2569
|
+
planId: z3.string().min(1),
|
|
2570
|
+
clientId: z3.string().min(1)
|
|
2571
|
+
});
|
|
2572
|
+
var ChangeTypeSchema = z3.enum([
|
|
2573
|
+
"status",
|
|
2574
|
+
"comments",
|
|
2575
|
+
"resolved",
|
|
2576
|
+
"content",
|
|
2577
|
+
"artifacts"
|
|
2578
|
+
]);
|
|
2579
|
+
var ChangeSchema = z3.object({
|
|
2580
|
+
type: ChangeTypeSchema,
|
|
2581
|
+
timestamp: z3.number(),
|
|
2582
|
+
summary: z3.string(),
|
|
2583
|
+
details: z3.record(z3.string(), z3.unknown()).optional()
|
|
2584
|
+
});
|
|
2585
|
+
var ChangesResponseSchema = z3.discriminatedUnion("ready", [z3.object({
|
|
2586
|
+
ready: z3.literal(true),
|
|
2587
|
+
changes: z3.string(),
|
|
2588
|
+
details: z3.array(ChangeSchema)
|
|
2589
|
+
}), z3.object({
|
|
2590
|
+
ready: z3.literal(false),
|
|
2591
|
+
pending: z3.number(),
|
|
2592
|
+
windowExpiresIn: z3.number()
|
|
2593
|
+
})]);
|
|
2594
|
+
var DeleteSubscriptionResponseSchema = z3.object({ success: z3.boolean() });
|
|
2595
|
+
var SetSessionTokenRequestSchema = z3.object({ sessionTokenHash: z3.string().min(1) });
|
|
2596
|
+
var GetDeliverableContextRequestSchema = z3.object({ sessionToken: z3.string().min(1) });
|
|
2597
|
+
var GetDeliverableContextResponseSchema = z3.object({ context: z3.string() });
|
|
2598
|
+
var SetSessionTokenResponseSchema = z3.object({ url: z3.string() });
|
|
2599
|
+
var ImportConversationRequestSchema = z3.object({
|
|
2600
|
+
a2aMessages: z3.array(A2AMessageSchema),
|
|
2601
|
+
meta: z3.object({
|
|
2602
|
+
planId: z3.string().optional(),
|
|
2603
|
+
sourcePlatform: z3.string().optional(),
|
|
2604
|
+
sessionId: z3.string().optional()
|
|
2605
|
+
}).optional()
|
|
2606
|
+
});
|
|
2607
|
+
var ImportConversationResponseSchema = z3.discriminatedUnion("success", [z3.object({
|
|
2608
|
+
success: z3.literal(true),
|
|
2609
|
+
sessionId: z3.string(),
|
|
2610
|
+
transcriptPath: z3.string(),
|
|
2611
|
+
messageCount: z3.number()
|
|
2612
|
+
}), z3.object({
|
|
2613
|
+
success: z3.literal(false),
|
|
2614
|
+
error: z3.string()
|
|
2615
|
+
})]);
|
|
2616
|
+
var t = initTRPC.context().create({ allowOutsideOfServer: true });
|
|
2617
|
+
var router = t.router;
|
|
2618
|
+
var publicProcedure = t.procedure;
|
|
2619
|
+
var middleware = t.middleware;
|
|
2620
|
+
var conversationRouter = router({ import: publicProcedure.input(ImportConversationRequestSchema).output(ImportConversationResponseSchema).mutation(async ({ input, ctx }) => {
|
|
2621
|
+
return ctx.conversationHandlers.importConversation(input, ctx);
|
|
2622
|
+
}) });
|
|
2623
|
+
var hookRouter = router({
|
|
2624
|
+
createSession: publicProcedure.input(CreateHookSessionRequestSchema).output(CreateHookSessionResponseSchema).mutation(async ({ input, ctx }) => {
|
|
2625
|
+
return ctx.hookHandlers.createSession(input, ctx);
|
|
2626
|
+
}),
|
|
2627
|
+
updateContent: publicProcedure.input(PlanIdSchema.merge(UpdatePlanContentRequestSchema)).output(UpdatePlanContentResponseSchema).mutation(async ({ input, ctx }) => {
|
|
2628
|
+
const { planId, ...contentInput } = input;
|
|
2629
|
+
return ctx.hookHandlers.updateContent(planId, contentInput, ctx);
|
|
2630
|
+
}),
|
|
2631
|
+
getReviewStatus: publicProcedure.input(PlanIdSchema).output(GetReviewStatusResponseSchema).query(async ({ input, ctx }) => {
|
|
2632
|
+
return ctx.hookHandlers.getReviewStatus(input.planId, ctx);
|
|
2633
|
+
}),
|
|
2634
|
+
updatePresence: publicProcedure.input(PlanIdSchema.merge(UpdatePresenceRequestSchema)).output(UpdatePresenceResponseSchema).mutation(async ({ input, ctx }) => {
|
|
2635
|
+
const { planId, ...presenceInput } = input;
|
|
2636
|
+
return ctx.hookHandlers.updatePresence(planId, presenceInput, ctx);
|
|
2637
|
+
}),
|
|
2638
|
+
setSessionToken: publicProcedure.input(PlanIdSchema.merge(SetSessionTokenRequestSchema)).output(SetSessionTokenResponseSchema).mutation(async ({ input, ctx }) => {
|
|
2639
|
+
const { planId, sessionTokenHash } = input;
|
|
2640
|
+
return ctx.hookHandlers.setSessionToken(planId, sessionTokenHash, ctx);
|
|
2641
|
+
}),
|
|
2642
|
+
waitForApproval: publicProcedure.input(z3.object({
|
|
2643
|
+
planId: z3.string(),
|
|
2644
|
+
reviewRequestId: z3.string()
|
|
2645
|
+
})).output(z3.object({
|
|
2646
|
+
approved: z3.boolean(),
|
|
2647
|
+
feedback: z3.string().optional(),
|
|
2648
|
+
deliverables: z3.array(z3.any()).optional(),
|
|
2649
|
+
reviewComment: z3.string().optional(),
|
|
2650
|
+
reviewedBy: z3.string().optional(),
|
|
2651
|
+
status: z3.string().optional()
|
|
2652
|
+
})).mutation(async ({ input, ctx }) => {
|
|
2653
|
+
const { planId, reviewRequestId } = input;
|
|
2654
|
+
return ctx.hookHandlers.waitForApproval(planId, reviewRequestId, ctx);
|
|
2655
|
+
}),
|
|
2656
|
+
getDeliverableContext: publicProcedure.input(PlanIdSchema.merge(GetDeliverableContextRequestSchema)).output(GetDeliverableContextResponseSchema).query(async ({ input, ctx }) => {
|
|
2657
|
+
const { planId, sessionToken } = input;
|
|
2658
|
+
return ctx.hookHandlers.getDeliverableContext(planId, sessionToken, ctx);
|
|
2659
|
+
}),
|
|
2660
|
+
getSessionContext: publicProcedure.input(z3.object({ sessionId: z3.string() })).output(z3.discriminatedUnion("found", [z3.object({
|
|
2661
|
+
found: z3.literal(true),
|
|
2662
|
+
planId: z3.string(),
|
|
2663
|
+
sessionToken: z3.string(),
|
|
2664
|
+
url: z3.string(),
|
|
2665
|
+
deliverables: z3.array(z3.object({
|
|
2666
|
+
id: z3.string(),
|
|
2667
|
+
text: z3.string()
|
|
2668
|
+
})),
|
|
2669
|
+
reviewComment: z3.string().optional(),
|
|
2670
|
+
reviewedBy: z3.string().optional(),
|
|
2671
|
+
reviewStatus: z3.string().optional()
|
|
2672
|
+
}), z3.object({ found: z3.literal(false) })])).query(async ({ input, ctx }) => {
|
|
2673
|
+
return ctx.hookHandlers.getSessionContext(input.sessionId, ctx);
|
|
2674
|
+
})
|
|
2675
|
+
});
|
|
2676
|
+
var planRouter = router({
|
|
2677
|
+
getStatus: publicProcedure.input(PlanIdSchema).output(PlanStatusResponseSchema).query(async ({ input, ctx }) => {
|
|
2678
|
+
const metadata = getPlanMetadata(await ctx.getOrCreateDoc(input.planId));
|
|
2679
|
+
if (!metadata) throw new TRPCError({
|
|
2680
|
+
code: "NOT_FOUND",
|
|
2681
|
+
message: "Plan not found"
|
|
2682
|
+
});
|
|
2683
|
+
return { status: metadata.status };
|
|
2684
|
+
}),
|
|
2685
|
+
hasConnections: publicProcedure.input(PlanIdSchema).output(HasConnectionsResponseSchema).query(async ({ input, ctx }) => {
|
|
2686
|
+
return { hasConnections: await ctx.getPlanStore().hasActiveConnections(input.planId) };
|
|
2687
|
+
})
|
|
2688
|
+
});
|
|
2689
|
+
var subscriptionRouter = router({
|
|
2690
|
+
create: publicProcedure.input(PlanIdSchema.merge(CreateSubscriptionRequestSchema)).output(CreateSubscriptionResponseSchema).mutation(async ({ input, ctx }) => {
|
|
2691
|
+
const { planId, subscribe, windowMs, maxWindowMs, threshold } = input;
|
|
2692
|
+
return { clientId: ctx.getPlanStore().createSubscription({
|
|
2693
|
+
planId,
|
|
2694
|
+
subscribe: subscribe || ["status"],
|
|
2695
|
+
windowMs: windowMs ?? 5e3,
|
|
2696
|
+
maxWindowMs: maxWindowMs ?? 3e4,
|
|
2697
|
+
threshold: threshold ?? 1
|
|
2698
|
+
}) };
|
|
2699
|
+
}),
|
|
2700
|
+
getChanges: publicProcedure.input(SubscriptionClientIdSchema).output(ChangesResponseSchema).query(async ({ input, ctx }) => {
|
|
2701
|
+
const { planId, clientId } = input;
|
|
2702
|
+
const result = ctx.getPlanStore().getChanges(planId, clientId);
|
|
2703
|
+
if (!result) throw new TRPCError({
|
|
2704
|
+
code: "NOT_FOUND",
|
|
2705
|
+
message: "Subscription not found"
|
|
2706
|
+
});
|
|
2707
|
+
return result;
|
|
2708
|
+
}),
|
|
2709
|
+
delete: publicProcedure.input(SubscriptionClientIdSchema).output(DeleteSubscriptionResponseSchema).mutation(async ({ input, ctx }) => {
|
|
2710
|
+
const { planId, clientId } = input;
|
|
2711
|
+
return { success: ctx.getPlanStore().deleteSubscription(planId, clientId) };
|
|
2712
|
+
})
|
|
2713
|
+
});
|
|
2714
|
+
var appRouter = router({
|
|
2715
|
+
hook: hookRouter,
|
|
2716
|
+
plan: planRouter,
|
|
2717
|
+
subscription: subscriptionRouter,
|
|
2718
|
+
conversation: conversationRouter
|
|
2719
|
+
});
|
|
2720
|
+
function createUserResolver(ydoc, fallbackLength = 8) {
|
|
2721
|
+
const usersMap = ydoc.getMap("users");
|
|
2722
|
+
return (userId) => {
|
|
2723
|
+
return usersMap.get(userId)?.displayName ?? userId.slice(0, fallbackLength);
|
|
2724
|
+
};
|
|
2725
|
+
}
|
|
2726
|
+
|
|
2727
|
+
export {
|
|
2728
|
+
PlanStatusValues,
|
|
2729
|
+
PlanViewTabValues,
|
|
2730
|
+
OriginPlatformValues,
|
|
2731
|
+
ClaudeCodeOriginMetadataSchema,
|
|
2732
|
+
DevinOriginMetadataSchema,
|
|
2733
|
+
CursorOriginMetadataSchema,
|
|
2734
|
+
OriginMetadataSchema,
|
|
2735
|
+
parseClaudeCodeOrigin,
|
|
2736
|
+
ConversationVersionSchema,
|
|
2737
|
+
PlanEventTypes,
|
|
2738
|
+
AgentActivityTypes,
|
|
2739
|
+
AgentActivityDataSchema,
|
|
2740
|
+
PlanEventSchema,
|
|
2741
|
+
isInboxWorthy,
|
|
2742
|
+
PlanMetadataSchema,
|
|
2743
|
+
ArtifactSchema,
|
|
2744
|
+
getArtifactUrl,
|
|
2745
|
+
DeliverableSchema,
|
|
2746
|
+
PlanSnapshotSchema,
|
|
2747
|
+
LinkedPRStatusValues,
|
|
2748
|
+
LinkedPRSchema,
|
|
2749
|
+
PRReviewCommentSchema,
|
|
2750
|
+
createLinkedPR,
|
|
2751
|
+
createGitHubArtifact,
|
|
2752
|
+
createLocalArtifact,
|
|
2753
|
+
createInitialConversationVersion,
|
|
2754
|
+
createHandedOffConversationVersion,
|
|
2755
|
+
assertNever,
|
|
2756
|
+
AgentPresenceSchema,
|
|
2757
|
+
ReviewCommentSchema,
|
|
2758
|
+
ReviewFeedbackSchema,
|
|
2759
|
+
CreateHookSessionRequestSchema,
|
|
2760
|
+
CreateHookSessionResponseSchema,
|
|
2761
|
+
UpdatePlanContentRequestSchema,
|
|
2762
|
+
UpdatePlanContentResponseSchema,
|
|
2763
|
+
GetReviewStatusResponseSchema,
|
|
2764
|
+
UpdatePresenceRequestSchema,
|
|
2765
|
+
UpdatePresenceResponseSchema,
|
|
2766
|
+
HookApiErrorSchema,
|
|
2767
|
+
RegisterServerRequestSchema,
|
|
2768
|
+
RegisterServerResponseSchema,
|
|
2769
|
+
UnregisterServerRequestSchema,
|
|
2770
|
+
UnregisterServerResponseSchema,
|
|
2771
|
+
CreateSubscriptionRequestSchema,
|
|
2772
|
+
CreateSubscriptionResponseSchema,
|
|
2773
|
+
InputRequestTypeValues,
|
|
2774
|
+
InputRequestStatusValues,
|
|
2775
|
+
InputRequestSchema,
|
|
2776
|
+
createInputRequest,
|
|
2777
|
+
YDOC_KEYS,
|
|
2778
|
+
isValidYDocKey,
|
|
2779
|
+
ThreadCommentSchema,
|
|
2780
|
+
ThreadSchema,
|
|
2781
|
+
isThread,
|
|
2782
|
+
parseThreads,
|
|
2783
|
+
extractTextFromCommentBody,
|
|
2784
|
+
extractMentions,
|
|
2785
|
+
VALID_STATUS_TRANSITIONS,
|
|
2786
|
+
getPlanMetadata,
|
|
2787
|
+
getPlanMetadataWithValidation,
|
|
2788
|
+
setPlanMetadata,
|
|
2789
|
+
transitionPlanStatus,
|
|
2790
|
+
initPlanMetadata,
|
|
2791
|
+
getStepCompletions,
|
|
2792
|
+
toggleStepCompletion,
|
|
2793
|
+
isStepCompleted,
|
|
2794
|
+
getArtifacts,
|
|
2795
|
+
addArtifact,
|
|
2796
|
+
removeArtifact,
|
|
2797
|
+
getAgentPresences,
|
|
2798
|
+
setAgentPresence,
|
|
2799
|
+
clearAgentPresence,
|
|
2800
|
+
getAgentPresence,
|
|
2801
|
+
getDeliverables,
|
|
2802
|
+
addDeliverable,
|
|
2803
|
+
linkArtifactToDeliverable,
|
|
2804
|
+
getPlanOwnerId,
|
|
2805
|
+
isApprovalRequired,
|
|
2806
|
+
getApprovedUsers,
|
|
2807
|
+
isUserApproved,
|
|
2808
|
+
approveUser,
|
|
2809
|
+
revokeUser,
|
|
2810
|
+
getRejectedUsers,
|
|
2811
|
+
isUserRejected,
|
|
2812
|
+
rejectUser,
|
|
2813
|
+
unrejectUser,
|
|
2814
|
+
getLinkedPRs,
|
|
2815
|
+
linkPR,
|
|
2816
|
+
unlinkPR,
|
|
2817
|
+
getLinkedPR,
|
|
2818
|
+
updateLinkedPRStatus,
|
|
2819
|
+
getPRReviewComments,
|
|
2820
|
+
getPRReviewCommentsForPR,
|
|
2821
|
+
addPRReviewComment,
|
|
2822
|
+
resolvePRReviewComment,
|
|
2823
|
+
removePRReviewComment,
|
|
2824
|
+
markPlanAsViewed,
|
|
2825
|
+
getViewedBy,
|
|
2826
|
+
isPlanUnread,
|
|
2827
|
+
getConversationVersions,
|
|
2828
|
+
addConversationVersion,
|
|
2829
|
+
markVersionHandedOff,
|
|
2830
|
+
logPlanEvent,
|
|
2831
|
+
getPlanEvents,
|
|
2832
|
+
getSnapshots,
|
|
2833
|
+
addSnapshot,
|
|
2834
|
+
createPlanSnapshot,
|
|
2835
|
+
getLatestSnapshot,
|
|
2836
|
+
addPlanTag,
|
|
2837
|
+
removePlanTag,
|
|
2838
|
+
getAllTagsFromIndex,
|
|
2839
|
+
archivePlan,
|
|
2840
|
+
unarchivePlan,
|
|
2841
|
+
answerInputRequest,
|
|
2842
|
+
cancelInputRequest,
|
|
2843
|
+
isUrlEncodedPlanV1,
|
|
2844
|
+
isUrlEncodedPlanV2,
|
|
2845
|
+
encodePlan,
|
|
2846
|
+
decodePlan,
|
|
2847
|
+
createPlanUrl,
|
|
2848
|
+
createPlanUrlWithHistory,
|
|
2849
|
+
getPlanFromUrl,
|
|
2850
|
+
A2ATextPartSchema,
|
|
2851
|
+
A2ADataPartSchema,
|
|
2852
|
+
A2AFilePartSchema,
|
|
2853
|
+
A2APartSchema,
|
|
2854
|
+
A2AMessageSchema,
|
|
2855
|
+
ConversationExportMetaSchema,
|
|
2856
|
+
ClaudeCodeMessageSchema,
|
|
2857
|
+
parseClaudeCodeTranscriptString,
|
|
2858
|
+
claudeCodeToA2A,
|
|
2859
|
+
validateA2AMessages,
|
|
2860
|
+
summarizeA2AConversation,
|
|
2861
|
+
a2aToClaudeCode,
|
|
2862
|
+
formatAsClaudeCodeJSONL,
|
|
2863
|
+
formatDeliverablesForLLM,
|
|
2864
|
+
extractDeliverables,
|
|
2865
|
+
GitHubPRResponseSchema,
|
|
2866
|
+
asPlanId,
|
|
2867
|
+
asAwarenessClientId,
|
|
2868
|
+
asWebRTCPeerId,
|
|
2869
|
+
asGitHubUsername,
|
|
2870
|
+
InviteTokenSchema,
|
|
2871
|
+
InviteRedemptionSchema,
|
|
2872
|
+
parseInviteFromUrl,
|
|
2873
|
+
buildInviteUrl,
|
|
2874
|
+
getTokenTimeRemaining,
|
|
2875
|
+
P2PMessageType,
|
|
2876
|
+
ConversationExportStartMetaSchema,
|
|
2877
|
+
ChunkMessageSchema,
|
|
2878
|
+
ConversationExportEndSchema,
|
|
2879
|
+
isConversationExportStart,
|
|
2880
|
+
isConversationChunk,
|
|
2881
|
+
isConversationExportEnd,
|
|
2882
|
+
isP2PConversationMessage,
|
|
2883
|
+
encodeExportStartMessage,
|
|
2884
|
+
decodeExportStartMessage,
|
|
2885
|
+
encodeChunkMessage,
|
|
2886
|
+
decodeChunkMessage,
|
|
2887
|
+
encodeExportEndMessage,
|
|
2888
|
+
decodeExportEndMessage,
|
|
2889
|
+
decodeP2PMessage,
|
|
2890
|
+
assertNeverP2PMessage,
|
|
2891
|
+
PLAN_INDEX_DOC_NAME,
|
|
2892
|
+
PLAN_INDEX_VIEWED_BY_KEY,
|
|
2893
|
+
NON_PLAN_DB_NAMES,
|
|
2894
|
+
PlanIndexEntrySchema,
|
|
2895
|
+
getPlanIndex,
|
|
2896
|
+
getPlanIndexEntry,
|
|
2897
|
+
setPlanIndexEntry,
|
|
2898
|
+
removePlanIndexEntry,
|
|
2899
|
+
touchPlanIndexEntry,
|
|
2900
|
+
getViewedByFromIndex,
|
|
2901
|
+
updatePlanIndexViewedBy,
|
|
2902
|
+
clearPlanIndexViewedBy,
|
|
2903
|
+
getAllViewedByFromIndex,
|
|
2904
|
+
removeViewedByFromIndex,
|
|
2905
|
+
PLAN_INDEX_EVENT_VIEWED_BY_KEY,
|
|
2906
|
+
markEventAsViewed,
|
|
2907
|
+
clearEventViewedBy,
|
|
2908
|
+
isEventUnread,
|
|
2909
|
+
getAllEventViewedByForPlan,
|
|
2910
|
+
ROUTES,
|
|
2911
|
+
formatThreadsForLLM,
|
|
2912
|
+
PlanIdSchema,
|
|
2913
|
+
PlanStatusResponseSchema,
|
|
2914
|
+
HasConnectionsResponseSchema,
|
|
2915
|
+
SubscriptionClientIdSchema,
|
|
2916
|
+
ChangeTypeSchema,
|
|
2917
|
+
ChangeSchema,
|
|
2918
|
+
ChangesResponseSchema,
|
|
2919
|
+
DeleteSubscriptionResponseSchema,
|
|
2920
|
+
SetSessionTokenRequestSchema,
|
|
2921
|
+
SetSessionTokenResponseSchema,
|
|
2922
|
+
ImportConversationRequestSchema,
|
|
2923
|
+
ImportConversationResponseSchema,
|
|
2924
|
+
conversationRouter,
|
|
2925
|
+
hookRouter,
|
|
2926
|
+
planRouter,
|
|
2927
|
+
subscriptionRouter,
|
|
2928
|
+
appRouter,
|
|
2929
|
+
createUserResolver
|
|
2930
|
+
};
|