@schoolai/shipyard-mcp 0.1.0-next.433

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.
@@ -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
+ };