@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,3078 @@
1
+ #!/usr/bin/env node
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __commonJS = (cb, mod) => function __require() {
9
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+
28
+ // ../../node_modules/.pnpm/lz-string@1.5.0/node_modules/lz-string/libs/lz-string.js
29
+ var require_lz_string = __commonJS({
30
+ "../../node_modules/.pnpm/lz-string@1.5.0/node_modules/lz-string/libs/lz-string.js"(exports, module) {
31
+ "use strict";
32
+ var LZString = (function() {
33
+ var f = String.fromCharCode;
34
+ var keyStrBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
35
+ var keyStrUriSafe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$";
36
+ var baseReverseDic = {};
37
+ function getBaseValue(alphabet, character) {
38
+ if (!baseReverseDic[alphabet]) {
39
+ baseReverseDic[alphabet] = {};
40
+ for (var i = 0; i < alphabet.length; i++) {
41
+ baseReverseDic[alphabet][alphabet.charAt(i)] = i;
42
+ }
43
+ }
44
+ return baseReverseDic[alphabet][character];
45
+ }
46
+ var LZString2 = {
47
+ compressToBase64: function(input) {
48
+ if (input == null) return "";
49
+ var res = LZString2._compress(input, 6, function(a) {
50
+ return keyStrBase64.charAt(a);
51
+ });
52
+ switch (res.length % 4) {
53
+ // To produce valid Base64
54
+ default:
55
+ // When could this happen ?
56
+ case 0:
57
+ return res;
58
+ case 1:
59
+ return res + "===";
60
+ case 2:
61
+ return res + "==";
62
+ case 3:
63
+ return res + "=";
64
+ }
65
+ },
66
+ decompressFromBase64: function(input) {
67
+ if (input == null) return "";
68
+ if (input == "") return null;
69
+ return LZString2._decompress(input.length, 32, function(index) {
70
+ return getBaseValue(keyStrBase64, input.charAt(index));
71
+ });
72
+ },
73
+ compressToUTF16: function(input) {
74
+ if (input == null) return "";
75
+ return LZString2._compress(input, 15, function(a) {
76
+ return f(a + 32);
77
+ }) + " ";
78
+ },
79
+ decompressFromUTF16: function(compressed) {
80
+ if (compressed == null) return "";
81
+ if (compressed == "") return null;
82
+ return LZString2._decompress(compressed.length, 16384, function(index) {
83
+ return compressed.charCodeAt(index) - 32;
84
+ });
85
+ },
86
+ //compress into uint8array (UCS-2 big endian format)
87
+ compressToUint8Array: function(uncompressed) {
88
+ var compressed = LZString2.compress(uncompressed);
89
+ var buf = new Uint8Array(compressed.length * 2);
90
+ for (var i = 0, TotalLen = compressed.length; i < TotalLen; i++) {
91
+ var current_value = compressed.charCodeAt(i);
92
+ buf[i * 2] = current_value >>> 8;
93
+ buf[i * 2 + 1] = current_value % 256;
94
+ }
95
+ return buf;
96
+ },
97
+ //decompress from uint8array (UCS-2 big endian format)
98
+ decompressFromUint8Array: function(compressed) {
99
+ if (compressed === null || compressed === void 0) {
100
+ return LZString2.decompress(compressed);
101
+ } else {
102
+ var buf = new Array(compressed.length / 2);
103
+ for (var i = 0, TotalLen = buf.length; i < TotalLen; i++) {
104
+ buf[i] = compressed[i * 2] * 256 + compressed[i * 2 + 1];
105
+ }
106
+ var result = [];
107
+ buf.forEach(function(c) {
108
+ result.push(f(c));
109
+ });
110
+ return LZString2.decompress(result.join(""));
111
+ }
112
+ },
113
+ //compress into a string that is already URI encoded
114
+ compressToEncodedURIComponent: function(input) {
115
+ if (input == null) return "";
116
+ return LZString2._compress(input, 6, function(a) {
117
+ return keyStrUriSafe.charAt(a);
118
+ });
119
+ },
120
+ //decompress from an output of compressToEncodedURIComponent
121
+ decompressFromEncodedURIComponent: function(input) {
122
+ if (input == null) return "";
123
+ if (input == "") return null;
124
+ input = input.replace(/ /g, "+");
125
+ return LZString2._decompress(input.length, 32, function(index) {
126
+ return getBaseValue(keyStrUriSafe, input.charAt(index));
127
+ });
128
+ },
129
+ compress: function(uncompressed) {
130
+ return LZString2._compress(uncompressed, 16, function(a) {
131
+ return f(a);
132
+ });
133
+ },
134
+ _compress: function(uncompressed, bitsPerChar, getCharFromInt) {
135
+ if (uncompressed == null) return "";
136
+ 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;
137
+ for (ii = 0; ii < uncompressed.length; ii += 1) {
138
+ context_c = uncompressed.charAt(ii);
139
+ if (!Object.prototype.hasOwnProperty.call(context_dictionary, context_c)) {
140
+ context_dictionary[context_c] = context_dictSize++;
141
+ context_dictionaryToCreate[context_c] = true;
142
+ }
143
+ context_wc = context_w + context_c;
144
+ if (Object.prototype.hasOwnProperty.call(context_dictionary, context_wc)) {
145
+ context_w = context_wc;
146
+ } else {
147
+ if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate, context_w)) {
148
+ if (context_w.charCodeAt(0) < 256) {
149
+ for (i = 0; i < context_numBits; i++) {
150
+ context_data_val = context_data_val << 1;
151
+ if (context_data_position == bitsPerChar - 1) {
152
+ context_data_position = 0;
153
+ context_data.push(getCharFromInt(context_data_val));
154
+ context_data_val = 0;
155
+ } else {
156
+ context_data_position++;
157
+ }
158
+ }
159
+ value = context_w.charCodeAt(0);
160
+ for (i = 0; i < 8; i++) {
161
+ context_data_val = context_data_val << 1 | value & 1;
162
+ if (context_data_position == bitsPerChar - 1) {
163
+ context_data_position = 0;
164
+ context_data.push(getCharFromInt(context_data_val));
165
+ context_data_val = 0;
166
+ } else {
167
+ context_data_position++;
168
+ }
169
+ value = value >> 1;
170
+ }
171
+ } else {
172
+ value = 1;
173
+ for (i = 0; i < context_numBits; i++) {
174
+ context_data_val = context_data_val << 1 | value;
175
+ if (context_data_position == bitsPerChar - 1) {
176
+ context_data_position = 0;
177
+ context_data.push(getCharFromInt(context_data_val));
178
+ context_data_val = 0;
179
+ } else {
180
+ context_data_position++;
181
+ }
182
+ value = 0;
183
+ }
184
+ value = context_w.charCodeAt(0);
185
+ for (i = 0; i < 16; i++) {
186
+ context_data_val = context_data_val << 1 | value & 1;
187
+ if (context_data_position == bitsPerChar - 1) {
188
+ context_data_position = 0;
189
+ context_data.push(getCharFromInt(context_data_val));
190
+ context_data_val = 0;
191
+ } else {
192
+ context_data_position++;
193
+ }
194
+ value = value >> 1;
195
+ }
196
+ }
197
+ context_enlargeIn--;
198
+ if (context_enlargeIn == 0) {
199
+ context_enlargeIn = Math.pow(2, context_numBits);
200
+ context_numBits++;
201
+ }
202
+ delete context_dictionaryToCreate[context_w];
203
+ } else {
204
+ value = context_dictionary[context_w];
205
+ for (i = 0; i < context_numBits; i++) {
206
+ context_data_val = context_data_val << 1 | value & 1;
207
+ if (context_data_position == bitsPerChar - 1) {
208
+ context_data_position = 0;
209
+ context_data.push(getCharFromInt(context_data_val));
210
+ context_data_val = 0;
211
+ } else {
212
+ context_data_position++;
213
+ }
214
+ value = value >> 1;
215
+ }
216
+ }
217
+ context_enlargeIn--;
218
+ if (context_enlargeIn == 0) {
219
+ context_enlargeIn = Math.pow(2, context_numBits);
220
+ context_numBits++;
221
+ }
222
+ context_dictionary[context_wc] = context_dictSize++;
223
+ context_w = String(context_c);
224
+ }
225
+ }
226
+ if (context_w !== "") {
227
+ if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate, context_w)) {
228
+ if (context_w.charCodeAt(0) < 256) {
229
+ for (i = 0; i < context_numBits; i++) {
230
+ context_data_val = context_data_val << 1;
231
+ if (context_data_position == bitsPerChar - 1) {
232
+ context_data_position = 0;
233
+ context_data.push(getCharFromInt(context_data_val));
234
+ context_data_val = 0;
235
+ } else {
236
+ context_data_position++;
237
+ }
238
+ }
239
+ value = context_w.charCodeAt(0);
240
+ for (i = 0; i < 8; i++) {
241
+ context_data_val = context_data_val << 1 | value & 1;
242
+ if (context_data_position == bitsPerChar - 1) {
243
+ context_data_position = 0;
244
+ context_data.push(getCharFromInt(context_data_val));
245
+ context_data_val = 0;
246
+ } else {
247
+ context_data_position++;
248
+ }
249
+ value = value >> 1;
250
+ }
251
+ } else {
252
+ value = 1;
253
+ for (i = 0; i < context_numBits; i++) {
254
+ context_data_val = context_data_val << 1 | value;
255
+ if (context_data_position == bitsPerChar - 1) {
256
+ context_data_position = 0;
257
+ context_data.push(getCharFromInt(context_data_val));
258
+ context_data_val = 0;
259
+ } else {
260
+ context_data_position++;
261
+ }
262
+ value = 0;
263
+ }
264
+ value = context_w.charCodeAt(0);
265
+ for (i = 0; i < 16; i++) {
266
+ context_data_val = context_data_val << 1 | value & 1;
267
+ if (context_data_position == bitsPerChar - 1) {
268
+ context_data_position = 0;
269
+ context_data.push(getCharFromInt(context_data_val));
270
+ context_data_val = 0;
271
+ } else {
272
+ context_data_position++;
273
+ }
274
+ value = value >> 1;
275
+ }
276
+ }
277
+ context_enlargeIn--;
278
+ if (context_enlargeIn == 0) {
279
+ context_enlargeIn = Math.pow(2, context_numBits);
280
+ context_numBits++;
281
+ }
282
+ delete context_dictionaryToCreate[context_w];
283
+ } else {
284
+ value = context_dictionary[context_w];
285
+ for (i = 0; i < context_numBits; i++) {
286
+ context_data_val = context_data_val << 1 | value & 1;
287
+ if (context_data_position == bitsPerChar - 1) {
288
+ context_data_position = 0;
289
+ context_data.push(getCharFromInt(context_data_val));
290
+ context_data_val = 0;
291
+ } else {
292
+ context_data_position++;
293
+ }
294
+ value = value >> 1;
295
+ }
296
+ }
297
+ context_enlargeIn--;
298
+ if (context_enlargeIn == 0) {
299
+ context_enlargeIn = Math.pow(2, context_numBits);
300
+ context_numBits++;
301
+ }
302
+ }
303
+ value = 2;
304
+ for (i = 0; i < context_numBits; i++) {
305
+ context_data_val = context_data_val << 1 | value & 1;
306
+ if (context_data_position == bitsPerChar - 1) {
307
+ context_data_position = 0;
308
+ context_data.push(getCharFromInt(context_data_val));
309
+ context_data_val = 0;
310
+ } else {
311
+ context_data_position++;
312
+ }
313
+ value = value >> 1;
314
+ }
315
+ while (true) {
316
+ context_data_val = context_data_val << 1;
317
+ if (context_data_position == bitsPerChar - 1) {
318
+ context_data.push(getCharFromInt(context_data_val));
319
+ break;
320
+ } else context_data_position++;
321
+ }
322
+ return context_data.join("");
323
+ },
324
+ decompress: function(compressed) {
325
+ if (compressed == null) return "";
326
+ if (compressed == "") return null;
327
+ return LZString2._decompress(compressed.length, 32768, function(index) {
328
+ return compressed.charCodeAt(index);
329
+ });
330
+ },
331
+ _decompress: function(length, resetValue, getNextValue) {
332
+ 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 };
333
+ for (i = 0; i < 3; i += 1) {
334
+ dictionary[i] = i;
335
+ }
336
+ bits = 0;
337
+ maxpower = Math.pow(2, 2);
338
+ power = 1;
339
+ while (power != maxpower) {
340
+ resb = data.val & data.position;
341
+ data.position >>= 1;
342
+ if (data.position == 0) {
343
+ data.position = resetValue;
344
+ data.val = getNextValue(data.index++);
345
+ }
346
+ bits |= (resb > 0 ? 1 : 0) * power;
347
+ power <<= 1;
348
+ }
349
+ switch (next = bits) {
350
+ case 0:
351
+ bits = 0;
352
+ maxpower = Math.pow(2, 8);
353
+ power = 1;
354
+ while (power != maxpower) {
355
+ resb = data.val & data.position;
356
+ data.position >>= 1;
357
+ if (data.position == 0) {
358
+ data.position = resetValue;
359
+ data.val = getNextValue(data.index++);
360
+ }
361
+ bits |= (resb > 0 ? 1 : 0) * power;
362
+ power <<= 1;
363
+ }
364
+ c = f(bits);
365
+ break;
366
+ case 1:
367
+ bits = 0;
368
+ maxpower = Math.pow(2, 16);
369
+ power = 1;
370
+ while (power != maxpower) {
371
+ resb = data.val & data.position;
372
+ data.position >>= 1;
373
+ if (data.position == 0) {
374
+ data.position = resetValue;
375
+ data.val = getNextValue(data.index++);
376
+ }
377
+ bits |= (resb > 0 ? 1 : 0) * power;
378
+ power <<= 1;
379
+ }
380
+ c = f(bits);
381
+ break;
382
+ case 2:
383
+ return "";
384
+ }
385
+ dictionary[3] = c;
386
+ w = c;
387
+ result.push(c);
388
+ while (true) {
389
+ if (data.index > length) {
390
+ return "";
391
+ }
392
+ bits = 0;
393
+ maxpower = Math.pow(2, numBits);
394
+ power = 1;
395
+ while (power != maxpower) {
396
+ resb = data.val & data.position;
397
+ data.position >>= 1;
398
+ if (data.position == 0) {
399
+ data.position = resetValue;
400
+ data.val = getNextValue(data.index++);
401
+ }
402
+ bits |= (resb > 0 ? 1 : 0) * power;
403
+ power <<= 1;
404
+ }
405
+ switch (c = bits) {
406
+ case 0:
407
+ bits = 0;
408
+ maxpower = Math.pow(2, 8);
409
+ power = 1;
410
+ while (power != maxpower) {
411
+ resb = data.val & data.position;
412
+ data.position >>= 1;
413
+ if (data.position == 0) {
414
+ data.position = resetValue;
415
+ data.val = getNextValue(data.index++);
416
+ }
417
+ bits |= (resb > 0 ? 1 : 0) * power;
418
+ power <<= 1;
419
+ }
420
+ dictionary[dictSize++] = f(bits);
421
+ c = dictSize - 1;
422
+ enlargeIn--;
423
+ break;
424
+ case 1:
425
+ bits = 0;
426
+ maxpower = Math.pow(2, 16);
427
+ power = 1;
428
+ while (power != maxpower) {
429
+ resb = data.val & data.position;
430
+ data.position >>= 1;
431
+ if (data.position == 0) {
432
+ data.position = resetValue;
433
+ data.val = getNextValue(data.index++);
434
+ }
435
+ bits |= (resb > 0 ? 1 : 0) * power;
436
+ power <<= 1;
437
+ }
438
+ dictionary[dictSize++] = f(bits);
439
+ c = dictSize - 1;
440
+ enlargeIn--;
441
+ break;
442
+ case 2:
443
+ return result.join("");
444
+ }
445
+ if (enlargeIn == 0) {
446
+ enlargeIn = Math.pow(2, numBits);
447
+ numBits++;
448
+ }
449
+ if (dictionary[c]) {
450
+ entry = dictionary[c];
451
+ } else {
452
+ if (c === dictSize) {
453
+ entry = w + w.charAt(0);
454
+ } else {
455
+ return null;
456
+ }
457
+ }
458
+ result.push(entry);
459
+ dictionary[dictSize++] = w + entry.charAt(0);
460
+ enlargeIn--;
461
+ w = entry;
462
+ if (enlargeIn == 0) {
463
+ enlargeIn = Math.pow(2, numBits);
464
+ numBits++;
465
+ }
466
+ }
467
+ }
468
+ };
469
+ return LZString2;
470
+ })();
471
+ if (typeof define === "function" && define.amd) {
472
+ define(function() {
473
+ return LZString;
474
+ });
475
+ } else if (typeof module !== "undefined" && module != null) {
476
+ module.exports = LZString;
477
+ } else if (typeof angular !== "undefined" && angular != null) {
478
+ angular.module("LZString", []).factory("LZString", function() {
479
+ return LZString;
480
+ });
481
+ }
482
+ }
483
+ });
484
+
485
+ // ../../packages/schema/dist/plan.mjs
486
+ import { z } from "zod";
487
+ import { nanoid } from "nanoid";
488
+ var PlanStatusValues = [
489
+ "draft",
490
+ "pending_review",
491
+ "changes_requested",
492
+ "in_progress",
493
+ "completed"
494
+ ];
495
+ var OriginPlatformValues = [
496
+ "claude-code",
497
+ "devin",
498
+ "cursor",
499
+ "windsurf",
500
+ "aider",
501
+ "unknown"
502
+ ];
503
+ var ClaudeCodeOriginMetadataSchema = z.object({
504
+ platform: z.literal("claude-code"),
505
+ sessionId: z.string(),
506
+ transcriptPath: z.string(),
507
+ cwd: z.string().optional()
508
+ });
509
+ var DevinOriginMetadataSchema = z.object({
510
+ platform: z.literal("devin"),
511
+ sessionId: z.string()
512
+ });
513
+ var CursorOriginMetadataSchema = z.object({
514
+ platform: z.literal("cursor"),
515
+ conversationId: z.string(),
516
+ generationId: z.string().optional()
517
+ });
518
+ var UnknownOriginMetadataSchema = z.object({ platform: z.literal("unknown") });
519
+ var OriginMetadataSchema = z.discriminatedUnion("platform", [
520
+ ClaudeCodeOriginMetadataSchema,
521
+ DevinOriginMetadataSchema,
522
+ CursorOriginMetadataSchema,
523
+ UnknownOriginMetadataSchema
524
+ ]);
525
+ var ConversationVersionBaseSchema = z.object({
526
+ versionId: z.string(),
527
+ creator: z.string(),
528
+ platform: z.enum(OriginPlatformValues),
529
+ sessionId: z.string(),
530
+ messageCount: z.number(),
531
+ createdAt: z.number()
532
+ });
533
+ var ConversationVersionSchema = z.discriminatedUnion("handedOff", [ConversationVersionBaseSchema.extend({ handedOff: z.literal(false) }), ConversationVersionBaseSchema.extend({
534
+ handedOff: z.literal(true),
535
+ handedOffAt: z.number(),
536
+ handedOffTo: z.string()
537
+ })]);
538
+ var PlanEventBaseSchema = z.object({
539
+ id: z.string(),
540
+ actor: z.string(),
541
+ timestamp: z.number(),
542
+ inboxWorthy: z.boolean().optional(),
543
+ inboxFor: z.union([z.string(), z.array(z.string())]).optional()
544
+ });
545
+ var AgentActivityDataSchema = z.discriminatedUnion("activityType", [
546
+ z.object({
547
+ activityType: z.literal("help_request"),
548
+ requestId: z.string(),
549
+ message: z.string()
550
+ }),
551
+ z.object({
552
+ activityType: z.literal("help_request_resolved"),
553
+ requestId: z.string(),
554
+ resolution: z.string().optional()
555
+ }),
556
+ z.object({
557
+ activityType: z.literal("blocker"),
558
+ message: z.string(),
559
+ requestId: z.string()
560
+ }),
561
+ z.object({
562
+ activityType: z.literal("blocker_resolved"),
563
+ requestId: z.string(),
564
+ resolution: z.string().optional()
565
+ })
566
+ ]);
567
+ var PlanEventSchema = z.discriminatedUnion("type", [
568
+ PlanEventBaseSchema.extend({ type: z.enum([
569
+ "plan_created",
570
+ "content_edited",
571
+ "plan_archived",
572
+ "plan_unarchived",
573
+ "plan_shared"
574
+ ]) }),
575
+ PlanEventBaseSchema.extend({
576
+ type: z.literal("status_changed"),
577
+ data: z.object({
578
+ fromStatus: z.enum(PlanStatusValues),
579
+ toStatus: z.enum(PlanStatusValues)
580
+ })
581
+ }),
582
+ PlanEventBaseSchema.extend({
583
+ type: z.literal("artifact_uploaded"),
584
+ data: z.object({ artifactId: z.string() })
585
+ }),
586
+ PlanEventBaseSchema.extend({
587
+ type: z.literal("comment_added"),
588
+ data: z.object({
589
+ commentId: z.string().optional(),
590
+ prNumber: z.number().optional(),
591
+ mentions: z.boolean().optional()
592
+ }).optional()
593
+ }),
594
+ PlanEventBaseSchema.extend({
595
+ type: z.literal("comment_resolved"),
596
+ data: z.object({
597
+ commentId: z.string().optional(),
598
+ resolvedCount: z.number().optional()
599
+ }).optional()
600
+ }),
601
+ PlanEventBaseSchema.extend({
602
+ type: z.literal("deliverable_linked"),
603
+ data: z.object({
604
+ deliverableId: z.string().optional(),
605
+ artifactId: z.string().optional(),
606
+ allFulfilled: z.boolean().optional()
607
+ }).optional()
608
+ }),
609
+ PlanEventBaseSchema.extend({
610
+ type: z.literal("pr_linked"),
611
+ data: z.object({
612
+ prNumber: z.number(),
613
+ url: z.string().optional()
614
+ })
615
+ }),
616
+ PlanEventBaseSchema.extend({
617
+ type: z.enum(["approved", "changes_requested"]),
618
+ data: z.object({ comment: z.string().optional() }).optional()
619
+ }),
620
+ PlanEventBaseSchema.extend({ type: z.literal("completed") }),
621
+ PlanEventBaseSchema.extend({
622
+ type: z.literal("step_completed"),
623
+ data: z.object({
624
+ stepId: z.string(),
625
+ completed: z.boolean()
626
+ })
627
+ }),
628
+ PlanEventBaseSchema.extend({
629
+ type: z.literal("conversation_imported"),
630
+ data: z.object({
631
+ sourcePlatform: z.string().optional(),
632
+ messageCount: z.number(),
633
+ sourceSessionId: z.string().optional()
634
+ })
635
+ }),
636
+ PlanEventBaseSchema.extend({
637
+ type: z.literal("conversation_exported"),
638
+ data: z.object({ messageCount: z.number() })
639
+ }),
640
+ PlanEventBaseSchema.extend({
641
+ type: z.literal("conversation_handed_off"),
642
+ data: z.object({
643
+ handedOffTo: z.string(),
644
+ messageCount: z.number()
645
+ })
646
+ }),
647
+ PlanEventBaseSchema.extend({
648
+ type: z.literal("approval_requested"),
649
+ data: z.object({ requesterName: z.string().optional() }).optional()
650
+ }),
651
+ PlanEventBaseSchema.extend({
652
+ type: z.literal("input_request_created"),
653
+ data: z.object({
654
+ requestId: z.string(),
655
+ requestType: z.enum([
656
+ "text",
657
+ "multiline",
658
+ "choice",
659
+ "confirm"
660
+ ]),
661
+ requestMessage: z.string()
662
+ })
663
+ }),
664
+ PlanEventBaseSchema.extend({
665
+ type: z.literal("input_request_answered"),
666
+ data: z.object({
667
+ requestId: z.string(),
668
+ response: z.unknown(),
669
+ answeredBy: z.string()
670
+ })
671
+ }),
672
+ PlanEventBaseSchema.extend({
673
+ type: z.literal("input_request_declined"),
674
+ data: z.object({ requestId: z.string() })
675
+ }),
676
+ PlanEventBaseSchema.extend({
677
+ type: z.literal("agent_activity"),
678
+ data: AgentActivityDataSchema
679
+ })
680
+ ]);
681
+ var PlanMetadataBaseSchema = z.object({
682
+ id: z.string(),
683
+ title: z.string(),
684
+ createdAt: z.number(),
685
+ updatedAt: z.number(),
686
+ repo: z.string().optional(),
687
+ pr: z.number().optional(),
688
+ ownerId: z.string().optional(),
689
+ approvalRequired: z.boolean().optional(),
690
+ approvedUsers: z.array(z.string()).optional(),
691
+ rejectedUsers: z.array(z.string()).optional(),
692
+ sessionTokenHash: z.string().optional(),
693
+ archivedAt: z.number().optional(),
694
+ archivedBy: z.string().optional(),
695
+ origin: OriginMetadataSchema.optional(),
696
+ viewedBy: z.record(z.string(), z.number()).optional(),
697
+ conversationVersions: z.array(ConversationVersionSchema).optional(),
698
+ events: z.array(PlanEventSchema).optional(),
699
+ tags: z.array(z.string()).optional()
700
+ });
701
+ var PlanMetadataSchema = z.discriminatedUnion("status", [
702
+ PlanMetadataBaseSchema.extend({ status: z.literal("draft") }),
703
+ PlanMetadataBaseSchema.extend({
704
+ status: z.literal("pending_review"),
705
+ reviewRequestId: z.string()
706
+ }),
707
+ PlanMetadataBaseSchema.extend({
708
+ status: z.literal("changes_requested"),
709
+ reviewedAt: z.number(),
710
+ reviewedBy: z.string(),
711
+ reviewComment: z.string().optional()
712
+ }),
713
+ PlanMetadataBaseSchema.extend({
714
+ status: z.literal("in_progress"),
715
+ reviewedAt: z.number(),
716
+ reviewedBy: z.string(),
717
+ reviewComment: z.string().optional()
718
+ }),
719
+ PlanMetadataBaseSchema.extend({
720
+ status: z.literal("completed"),
721
+ completedAt: z.number(),
722
+ completedBy: z.string(),
723
+ snapshotUrl: z.string().optional()
724
+ })
725
+ ]);
726
+ var BaseArtifactSchema = z.object({
727
+ id: z.string(),
728
+ type: z.enum([
729
+ "screenshot",
730
+ "video",
731
+ "test_results",
732
+ "diff"
733
+ ]),
734
+ filename: z.string(),
735
+ description: z.string().optional(),
736
+ uploadedAt: z.number().optional()
737
+ });
738
+ var GitHubArtifactSchema = BaseArtifactSchema.extend({
739
+ storage: z.literal("github"),
740
+ url: z.string()
741
+ });
742
+ var LocalArtifactSchema = BaseArtifactSchema.extend({
743
+ storage: z.literal("local"),
744
+ localArtifactId: z.string()
745
+ });
746
+ var ArtifactSchema = z.discriminatedUnion("storage", [GitHubArtifactSchema, LocalArtifactSchema]);
747
+ var DeliverableSchema = z.object({
748
+ id: z.string(),
749
+ text: z.string(),
750
+ linkedArtifactId: z.string().optional(),
751
+ linkedAt: z.number().optional()
752
+ });
753
+ var PlanSnapshotSchema = z.object({
754
+ id: z.string(),
755
+ status: z.enum(PlanStatusValues),
756
+ createdBy: z.string(),
757
+ reason: z.string(),
758
+ createdAt: z.number(),
759
+ content: z.array(z.unknown()),
760
+ threadSummary: z.object({
761
+ total: z.number(),
762
+ unresolved: z.number()
763
+ }).optional(),
764
+ artifacts: z.array(ArtifactSchema).optional(),
765
+ deliverables: z.array(DeliverableSchema).optional()
766
+ });
767
+ var LinkedPRStatusValues = [
768
+ "draft",
769
+ "open",
770
+ "merged",
771
+ "closed"
772
+ ];
773
+ var LinkedPRSchema = z.object({
774
+ prNumber: z.number(),
775
+ url: z.string(),
776
+ linkedAt: z.number(),
777
+ status: z.enum(LinkedPRStatusValues),
778
+ branch: z.string().optional(),
779
+ title: z.string().optional()
780
+ });
781
+ var PRReviewCommentSchema = z.object({
782
+ id: z.string(),
783
+ prNumber: z.number(),
784
+ path: z.string(),
785
+ line: z.number(),
786
+ body: z.string(),
787
+ author: z.string(),
788
+ createdAt: z.number(),
789
+ resolved: z.boolean().optional()
790
+ });
791
+
792
+ // ../../packages/schema/dist/yjs-helpers-xzZyVQl7.mjs
793
+ import { z as z2 } from "zod";
794
+ import { nanoid as nanoid2 } from "nanoid";
795
+ import * as Y from "yjs";
796
+ function assertNever(value) {
797
+ throw new Error(`Unhandled discriminated union member: ${JSON.stringify(value)}`);
798
+ }
799
+ var AgentPresenceSchema = z2.object({
800
+ agentType: z2.string(),
801
+ sessionId: z2.string(),
802
+ connectedAt: z2.number(),
803
+ lastSeenAt: z2.number()
804
+ });
805
+ var ReviewCommentSchema = z2.object({
806
+ author: z2.string(),
807
+ content: z2.string(),
808
+ createdAt: z2.number()
809
+ });
810
+ var ReviewFeedbackSchema = z2.object({
811
+ threadId: z2.string(),
812
+ blockId: z2.string().optional(),
813
+ comments: z2.array(ReviewCommentSchema)
814
+ });
815
+ var CreateHookSessionRequestSchema = z2.object({
816
+ sessionId: z2.string(),
817
+ agentType: z2.string().default("claude-code"),
818
+ metadata: z2.record(z2.string(), z2.unknown()).optional()
819
+ });
820
+ var CreateHookSessionResponseSchema = z2.object({
821
+ planId: z2.string(),
822
+ url: z2.string()
823
+ });
824
+ var UpdatePlanContentRequestSchema = z2.object({
825
+ content: z2.string(),
826
+ filePath: z2.string().optional()
827
+ });
828
+ var UpdatePlanContentResponseSchema = z2.object({
829
+ success: z2.boolean(),
830
+ updatedAt: z2.number()
831
+ });
832
+ var GetReviewStatusResponseSchema = z2.discriminatedUnion("status", [
833
+ z2.object({ status: z2.literal("draft") }),
834
+ z2.object({
835
+ status: z2.literal("pending_review"),
836
+ reviewRequestId: z2.string()
837
+ }),
838
+ z2.object({
839
+ status: z2.literal("changes_requested"),
840
+ reviewedAt: z2.number(),
841
+ reviewedBy: z2.string(),
842
+ reviewComment: z2.string().optional(),
843
+ feedback: z2.array(ReviewFeedbackSchema).optional()
844
+ }),
845
+ z2.object({
846
+ status: z2.literal("in_progress"),
847
+ reviewedAt: z2.number(),
848
+ reviewedBy: z2.string()
849
+ }),
850
+ z2.object({
851
+ status: z2.literal("completed"),
852
+ completedAt: z2.number(),
853
+ completedBy: z2.string(),
854
+ snapshotUrl: z2.string().optional()
855
+ })
856
+ ]);
857
+ var UpdatePresenceRequestSchema = z2.object({
858
+ agentType: z2.string(),
859
+ sessionId: z2.string()
860
+ });
861
+ var UpdatePresenceResponseSchema = z2.object({ success: z2.boolean() });
862
+ var HookApiErrorSchema = z2.object({ error: z2.string() });
863
+ var RegisterServerRequestSchema = z2.object({
864
+ port: z2.number().int().positive(),
865
+ pid: z2.number().int().positive()
866
+ });
867
+ var RegisterServerResponseSchema = z2.object({
868
+ success: z2.boolean(),
869
+ entry: z2.object({
870
+ port: z2.number(),
871
+ pid: z2.number(),
872
+ url: z2.string(),
873
+ registeredAt: z2.number()
874
+ })
875
+ });
876
+ var UnregisterServerRequestSchema = z2.object({ pid: z2.number().int().positive() });
877
+ var UnregisterServerResponseSchema = z2.object({
878
+ success: z2.boolean(),
879
+ existed: z2.boolean()
880
+ });
881
+ var CreateSubscriptionRequestSchema = z2.object({
882
+ subscribe: z2.array(z2.string()).optional(),
883
+ windowMs: z2.number().positive().optional(),
884
+ maxWindowMs: z2.number().positive().optional(),
885
+ threshold: z2.number().positive().optional()
886
+ });
887
+ var CreateSubscriptionResponseSchema = z2.object({ clientId: z2.string() });
888
+ var InputRequestStatusValues = [
889
+ "pending",
890
+ "answered",
891
+ "declined",
892
+ "cancelled"
893
+ ];
894
+ var InputRequestBaseSchema = z2.object({
895
+ id: z2.string(),
896
+ createdAt: z2.number(),
897
+ message: z2.string().min(1, "Message cannot be empty"),
898
+ status: z2.enum(InputRequestStatusValues),
899
+ defaultValue: z2.string().optional(),
900
+ timeout: z2.number().int().min(10, "Timeout must be at least 10 seconds").max(900, "Timeout cannot exceed 15 minutes").optional(),
901
+ planId: z2.string().optional(),
902
+ response: z2.unknown().optional(),
903
+ answeredAt: z2.number().optional(),
904
+ answeredBy: z2.string().optional()
905
+ });
906
+ var TextInputSchema = InputRequestBaseSchema.extend({ type: z2.literal("text") });
907
+ var MultilineInputSchema = InputRequestBaseSchema.extend({ type: z2.literal("multiline") });
908
+ var ChoiceInputSchema = InputRequestBaseSchema.extend({
909
+ type: z2.literal("choice"),
910
+ options: z2.array(z2.string()).min(1, "Choice requests must have at least one option"),
911
+ multiSelect: z2.boolean().optional()
912
+ });
913
+ var ConfirmInputSchema = InputRequestBaseSchema.extend({ type: z2.literal("confirm") });
914
+ var InputRequestSchema = z2.discriminatedUnion("type", [
915
+ TextInputSchema,
916
+ MultilineInputSchema,
917
+ ChoiceInputSchema,
918
+ ConfirmInputSchema
919
+ ]);
920
+ var YDOC_KEYS = {
921
+ METADATA: "metadata",
922
+ DOCUMENT_FRAGMENT: "document",
923
+ THREADS: "threads",
924
+ STEP_COMPLETIONS: "stepCompletions",
925
+ PLANS: "plans",
926
+ ARTIFACTS: "artifacts",
927
+ DELIVERABLES: "deliverables",
928
+ PRESENCE: "presence",
929
+ LINKED_PRS: "linkedPRs",
930
+ PR_REVIEW_COMMENTS: "prReviewComments",
931
+ EVENTS: "events",
932
+ SNAPSHOTS: "snapshots",
933
+ INPUT_REQUESTS: "inputRequests"
934
+ };
935
+ var CommentBodySchema = z2.union([z2.string(), z2.array(z2.unknown())]);
936
+ var ThreadCommentSchema = z2.object({
937
+ id: z2.string(),
938
+ userId: z2.string(),
939
+ body: CommentBodySchema,
940
+ createdAt: z2.number()
941
+ });
942
+ var ThreadSchema = z2.object({
943
+ id: z2.string(),
944
+ comments: z2.array(ThreadCommentSchema),
945
+ resolved: z2.boolean().optional(),
946
+ selectedText: z2.string().optional()
947
+ });
948
+ function extractTextFromCommentBody(body) {
949
+ if (typeof body === "string") return body;
950
+ if (!Array.isArray(body)) return "";
951
+ return body.map((block) => {
952
+ if (typeof block === "string") return block;
953
+ if (typeof block !== "object" || block === null) return "";
954
+ const blockObj = block;
955
+ if (Array.isArray(blockObj.content)) return blockObj.content.map((item) => {
956
+ if (typeof item === "string") return item;
957
+ if (typeof item === "object" && item !== null && "text" in item) return item.text;
958
+ return "";
959
+ }).join("");
960
+ return "";
961
+ }).join("\n");
962
+ }
963
+ function getPlanMetadata(ydoc) {
964
+ const result = getPlanMetadataWithValidation(ydoc);
965
+ return result.success ? result.data : null;
966
+ }
967
+ function getPlanMetadataWithValidation(ydoc) {
968
+ const data = ydoc.getMap(YDOC_KEYS.METADATA).toJSON();
969
+ if (!data || Object.keys(data).length === 0) return {
970
+ success: false,
971
+ error: "No metadata found in Y.Doc"
972
+ };
973
+ const result = PlanMetadataSchema.safeParse(data);
974
+ if (!result.success) return {
975
+ success: false,
976
+ error: `Invalid metadata: ${result.error.message}`
977
+ };
978
+ return {
979
+ success: true,
980
+ data: result.data
981
+ };
982
+ }
983
+
984
+ // ../../packages/schema/dist/url-encoding.mjs
985
+ var import_lz_string = __toESM(require_lz_string(), 1);
986
+
987
+ // ../../packages/schema/dist/index.mjs
988
+ import { z as z3 } from "zod";
989
+ import * as Y2 from "yjs";
990
+
991
+ // ../../node_modules/.pnpm/@trpc+server@11.8.1_typescript@5.9.3/node_modules/@trpc/server/dist/codes-DagpWZLc.mjs
992
+ function mergeWithoutOverrides(obj1, ...objs) {
993
+ const newObj = Object.assign(emptyObject(), obj1);
994
+ for (const overrides of objs) for (const key in overrides) {
995
+ if (key in newObj && newObj[key] !== overrides[key]) throw new Error(`Duplicate key ${key}`);
996
+ newObj[key] = overrides[key];
997
+ }
998
+ return newObj;
999
+ }
1000
+ function isObject(value) {
1001
+ return !!value && !Array.isArray(value) && typeof value === "object";
1002
+ }
1003
+ function isFunction(fn) {
1004
+ return typeof fn === "function";
1005
+ }
1006
+ function emptyObject() {
1007
+ return /* @__PURE__ */ Object.create(null);
1008
+ }
1009
+ var TRPC_ERROR_CODES_BY_KEY = {
1010
+ PARSE_ERROR: -32700,
1011
+ BAD_REQUEST: -32600,
1012
+ INTERNAL_SERVER_ERROR: -32603,
1013
+ NOT_IMPLEMENTED: -32603,
1014
+ BAD_GATEWAY: -32603,
1015
+ SERVICE_UNAVAILABLE: -32603,
1016
+ GATEWAY_TIMEOUT: -32603,
1017
+ UNAUTHORIZED: -32001,
1018
+ PAYMENT_REQUIRED: -32002,
1019
+ FORBIDDEN: -32003,
1020
+ NOT_FOUND: -32004,
1021
+ METHOD_NOT_SUPPORTED: -32005,
1022
+ TIMEOUT: -32008,
1023
+ CONFLICT: -32009,
1024
+ PRECONDITION_FAILED: -32012,
1025
+ PAYLOAD_TOO_LARGE: -32013,
1026
+ UNSUPPORTED_MEDIA_TYPE: -32015,
1027
+ UNPROCESSABLE_CONTENT: -32022,
1028
+ PRECONDITION_REQUIRED: -32028,
1029
+ TOO_MANY_REQUESTS: -32029,
1030
+ CLIENT_CLOSED_REQUEST: -32099
1031
+ };
1032
+ var retryableRpcCodes = [
1033
+ TRPC_ERROR_CODES_BY_KEY.BAD_GATEWAY,
1034
+ TRPC_ERROR_CODES_BY_KEY.SERVICE_UNAVAILABLE,
1035
+ TRPC_ERROR_CODES_BY_KEY.GATEWAY_TIMEOUT,
1036
+ TRPC_ERROR_CODES_BY_KEY.INTERNAL_SERVER_ERROR
1037
+ ];
1038
+
1039
+ // ../../node_modules/.pnpm/@trpc+server@11.8.1_typescript@5.9.3/node_modules/@trpc/server/dist/getErrorShape-vC8mUXJD.mjs
1040
+ var __create2 = Object.create;
1041
+ var __defProp2 = Object.defineProperty;
1042
+ var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
1043
+ var __getOwnPropNames2 = Object.getOwnPropertyNames;
1044
+ var __getProtoOf2 = Object.getPrototypeOf;
1045
+ var __hasOwnProp2 = Object.prototype.hasOwnProperty;
1046
+ var __commonJS2 = (cb, mod) => function() {
1047
+ return mod || (0, cb[__getOwnPropNames2(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
1048
+ };
1049
+ var __copyProps2 = (to, from, except, desc) => {
1050
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames2(from), i = 0, n = keys.length, key; i < n; i++) {
1051
+ key = keys[i];
1052
+ if (!__hasOwnProp2.call(to, key) && key !== except) __defProp2(to, key, {
1053
+ get: ((k) => from[k]).bind(null, key),
1054
+ enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable
1055
+ });
1056
+ }
1057
+ return to;
1058
+ };
1059
+ var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps2(isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", {
1060
+ value: mod,
1061
+ enumerable: true
1062
+ }) : target, mod));
1063
+ var noop = () => {
1064
+ };
1065
+ var freezeIfAvailable = (obj) => {
1066
+ if (Object.freeze) Object.freeze(obj);
1067
+ };
1068
+ function createInnerProxy(callback, path, memo) {
1069
+ var _memo$cacheKey;
1070
+ const cacheKey = path.join(".");
1071
+ (_memo$cacheKey = memo[cacheKey]) !== null && _memo$cacheKey !== void 0 || (memo[cacheKey] = new Proxy(noop, {
1072
+ get(_obj, key) {
1073
+ if (typeof key !== "string" || key === "then") return void 0;
1074
+ return createInnerProxy(callback, [...path, key], memo);
1075
+ },
1076
+ apply(_1, _2, args) {
1077
+ const lastOfPath = path[path.length - 1];
1078
+ let opts = {
1079
+ args,
1080
+ path
1081
+ };
1082
+ if (lastOfPath === "call") opts = {
1083
+ args: args.length >= 2 ? [args[1]] : [],
1084
+ path: path.slice(0, -1)
1085
+ };
1086
+ else if (lastOfPath === "apply") opts = {
1087
+ args: args.length >= 2 ? args[1] : [],
1088
+ path: path.slice(0, -1)
1089
+ };
1090
+ freezeIfAvailable(opts.args);
1091
+ freezeIfAvailable(opts.path);
1092
+ return callback(opts);
1093
+ }
1094
+ }));
1095
+ return memo[cacheKey];
1096
+ }
1097
+ var createRecursiveProxy = (callback) => createInnerProxy(callback, [], emptyObject());
1098
+ var require_typeof = __commonJS2({ "../../node_modules/.pnpm/@oxc-project+runtime@0.72.2/node_modules/@oxc-project/runtime/src/helpers/typeof.js"(exports, module) {
1099
+ function _typeof$2(o) {
1100
+ "@babel/helpers - typeof";
1101
+ return module.exports = _typeof$2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o$1) {
1102
+ return typeof o$1;
1103
+ } : function(o$1) {
1104
+ return o$1 && "function" == typeof Symbol && o$1.constructor === Symbol && o$1 !== Symbol.prototype ? "symbol" : typeof o$1;
1105
+ }, module.exports.__esModule = true, module.exports["default"] = module.exports, _typeof$2(o);
1106
+ }
1107
+ module.exports = _typeof$2, module.exports.__esModule = true, module.exports["default"] = module.exports;
1108
+ } });
1109
+ var require_toPrimitive = __commonJS2({ "../../node_modules/.pnpm/@oxc-project+runtime@0.72.2/node_modules/@oxc-project/runtime/src/helpers/toPrimitive.js"(exports, module) {
1110
+ var _typeof$1 = require_typeof()["default"];
1111
+ function toPrimitive$1(t2, r) {
1112
+ if ("object" != _typeof$1(t2) || !t2) return t2;
1113
+ var e = t2[Symbol.toPrimitive];
1114
+ if (void 0 !== e) {
1115
+ var i = e.call(t2, r || "default");
1116
+ if ("object" != _typeof$1(i)) return i;
1117
+ throw new TypeError("@@toPrimitive must return a primitive value.");
1118
+ }
1119
+ return ("string" === r ? String : Number)(t2);
1120
+ }
1121
+ module.exports = toPrimitive$1, module.exports.__esModule = true, module.exports["default"] = module.exports;
1122
+ } });
1123
+ var require_toPropertyKey = __commonJS2({ "../../node_modules/.pnpm/@oxc-project+runtime@0.72.2/node_modules/@oxc-project/runtime/src/helpers/toPropertyKey.js"(exports, module) {
1124
+ var _typeof = require_typeof()["default"];
1125
+ var toPrimitive = require_toPrimitive();
1126
+ function toPropertyKey$1(t2) {
1127
+ var i = toPrimitive(t2, "string");
1128
+ return "symbol" == _typeof(i) ? i : i + "";
1129
+ }
1130
+ module.exports = toPropertyKey$1, module.exports.__esModule = true, module.exports["default"] = module.exports;
1131
+ } });
1132
+ var require_defineProperty = __commonJS2({ "../../node_modules/.pnpm/@oxc-project+runtime@0.72.2/node_modules/@oxc-project/runtime/src/helpers/defineProperty.js"(exports, module) {
1133
+ var toPropertyKey = require_toPropertyKey();
1134
+ function _defineProperty(e, r, t2) {
1135
+ return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
1136
+ value: t2,
1137
+ enumerable: true,
1138
+ configurable: true,
1139
+ writable: true
1140
+ }) : e[r] = t2, e;
1141
+ }
1142
+ module.exports = _defineProperty, module.exports.__esModule = true, module.exports["default"] = module.exports;
1143
+ } });
1144
+ var require_objectSpread2 = __commonJS2({ "../../node_modules/.pnpm/@oxc-project+runtime@0.72.2/node_modules/@oxc-project/runtime/src/helpers/objectSpread2.js"(exports, module) {
1145
+ var defineProperty = require_defineProperty();
1146
+ function ownKeys(e, r) {
1147
+ var t2 = Object.keys(e);
1148
+ if (Object.getOwnPropertySymbols) {
1149
+ var o = Object.getOwnPropertySymbols(e);
1150
+ r && (o = o.filter(function(r$1) {
1151
+ return Object.getOwnPropertyDescriptor(e, r$1).enumerable;
1152
+ })), t2.push.apply(t2, o);
1153
+ }
1154
+ return t2;
1155
+ }
1156
+ function _objectSpread2(e) {
1157
+ for (var r = 1; r < arguments.length; r++) {
1158
+ var t2 = null != arguments[r] ? arguments[r] : {};
1159
+ r % 2 ? ownKeys(Object(t2), true).forEach(function(r$1) {
1160
+ defineProperty(e, r$1, t2[r$1]);
1161
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t2)) : ownKeys(Object(t2)).forEach(function(r$1) {
1162
+ Object.defineProperty(e, r$1, Object.getOwnPropertyDescriptor(t2, r$1));
1163
+ });
1164
+ }
1165
+ return e;
1166
+ }
1167
+ module.exports = _objectSpread2, module.exports.__esModule = true, module.exports["default"] = module.exports;
1168
+ } });
1169
+ var import_objectSpread2 = __toESM2(require_objectSpread2(), 1);
1170
+
1171
+ // ../../node_modules/.pnpm/@trpc+server@11.8.1_typescript@5.9.3/node_modules/@trpc/server/dist/tracked-D4V22yc5.mjs
1172
+ var defaultFormatter = ({ shape }) => {
1173
+ return shape;
1174
+ };
1175
+ var import_defineProperty = __toESM2(require_defineProperty(), 1);
1176
+ var UnknownCauseError = class extends Error {
1177
+ };
1178
+ function getCauseFromUnknown(cause) {
1179
+ if (cause instanceof Error) return cause;
1180
+ const type = typeof cause;
1181
+ if (type === "undefined" || type === "function" || cause === null) return void 0;
1182
+ if (type !== "object") return new Error(String(cause));
1183
+ if (isObject(cause)) return Object.assign(new UnknownCauseError(), cause);
1184
+ return void 0;
1185
+ }
1186
+ function getTRPCErrorFromUnknown(cause) {
1187
+ if (cause instanceof TRPCError) return cause;
1188
+ if (cause instanceof Error && cause.name === "TRPCError") return cause;
1189
+ const trpcError = new TRPCError({
1190
+ code: "INTERNAL_SERVER_ERROR",
1191
+ cause
1192
+ });
1193
+ if (cause instanceof Error && cause.stack) trpcError.stack = cause.stack;
1194
+ return trpcError;
1195
+ }
1196
+ var TRPCError = class extends Error {
1197
+ constructor(opts) {
1198
+ var _ref, _opts$message, _this$cause;
1199
+ const cause = getCauseFromUnknown(opts.cause);
1200
+ const message = (_ref = (_opts$message = opts.message) !== null && _opts$message !== void 0 ? _opts$message : cause === null || cause === void 0 ? void 0 : cause.message) !== null && _ref !== void 0 ? _ref : opts.code;
1201
+ super(message, { cause });
1202
+ (0, import_defineProperty.default)(this, "cause", void 0);
1203
+ (0, import_defineProperty.default)(this, "code", void 0);
1204
+ this.code = opts.code;
1205
+ this.name = "TRPCError";
1206
+ (_this$cause = this.cause) !== null && _this$cause !== void 0 || (this.cause = cause);
1207
+ }
1208
+ };
1209
+ var import_objectSpread2$1 = __toESM2(require_objectSpread2(), 1);
1210
+ function getDataTransformer(transformer) {
1211
+ if ("input" in transformer) return transformer;
1212
+ return {
1213
+ input: transformer,
1214
+ output: transformer
1215
+ };
1216
+ }
1217
+ var defaultTransformer = {
1218
+ input: {
1219
+ serialize: (obj) => obj,
1220
+ deserialize: (obj) => obj
1221
+ },
1222
+ output: {
1223
+ serialize: (obj) => obj,
1224
+ deserialize: (obj) => obj
1225
+ }
1226
+ };
1227
+ var import_objectSpread22 = __toESM2(require_objectSpread2(), 1);
1228
+ var lazyMarker = "lazyMarker";
1229
+ function once(fn) {
1230
+ const uncalled = /* @__PURE__ */ Symbol();
1231
+ let result = uncalled;
1232
+ return () => {
1233
+ if (result === uncalled) result = fn();
1234
+ return result;
1235
+ };
1236
+ }
1237
+ function isLazy(input) {
1238
+ return typeof input === "function" && lazyMarker in input;
1239
+ }
1240
+ function isRouter(value) {
1241
+ return isObject(value) && isObject(value["_def"]) && "router" in value["_def"];
1242
+ }
1243
+ var emptyRouter = {
1244
+ _ctx: null,
1245
+ _errorShape: null,
1246
+ _meta: null,
1247
+ queries: {},
1248
+ mutations: {},
1249
+ subscriptions: {},
1250
+ errorFormatter: defaultFormatter,
1251
+ transformer: defaultTransformer
1252
+ };
1253
+ var reservedWords = [
1254
+ "then",
1255
+ "call",
1256
+ "apply"
1257
+ ];
1258
+ function createRouterFactory(config) {
1259
+ function createRouterInner(input) {
1260
+ const reservedWordsUsed = new Set(Object.keys(input).filter((v) => reservedWords.includes(v)));
1261
+ if (reservedWordsUsed.size > 0) throw new Error("Reserved words used in `router({})` call: " + Array.from(reservedWordsUsed).join(", "));
1262
+ const procedures = emptyObject();
1263
+ const lazy$1 = emptyObject();
1264
+ function createLazyLoader(opts) {
1265
+ return {
1266
+ ref: opts.ref,
1267
+ load: once(async () => {
1268
+ const router$1 = await opts.ref();
1269
+ const lazyPath = [...opts.path, opts.key];
1270
+ const lazyKey = lazyPath.join(".");
1271
+ opts.aggregate[opts.key] = step(router$1._def.record, lazyPath);
1272
+ delete lazy$1[lazyKey];
1273
+ for (const [nestedKey, nestedItem] of Object.entries(router$1._def.lazy)) {
1274
+ const nestedRouterKey = [...lazyPath, nestedKey].join(".");
1275
+ lazy$1[nestedRouterKey] = createLazyLoader({
1276
+ ref: nestedItem.ref,
1277
+ path: lazyPath,
1278
+ key: nestedKey,
1279
+ aggregate: opts.aggregate[opts.key]
1280
+ });
1281
+ }
1282
+ })
1283
+ };
1284
+ }
1285
+ function step(from, path = []) {
1286
+ const aggregate = emptyObject();
1287
+ for (const [key, item] of Object.entries(from !== null && from !== void 0 ? from : {})) {
1288
+ if (isLazy(item)) {
1289
+ lazy$1[[...path, key].join(".")] = createLazyLoader({
1290
+ path,
1291
+ ref: item,
1292
+ key,
1293
+ aggregate
1294
+ });
1295
+ continue;
1296
+ }
1297
+ if (isRouter(item)) {
1298
+ aggregate[key] = step(item._def.record, [...path, key]);
1299
+ continue;
1300
+ }
1301
+ if (!isProcedure(item)) {
1302
+ aggregate[key] = step(item, [...path, key]);
1303
+ continue;
1304
+ }
1305
+ const newPath = [...path, key].join(".");
1306
+ if (procedures[newPath]) throw new Error(`Duplicate key: ${newPath}`);
1307
+ procedures[newPath] = item;
1308
+ aggregate[key] = item;
1309
+ }
1310
+ return aggregate;
1311
+ }
1312
+ const record = step(input);
1313
+ const _def = (0, import_objectSpread22.default)((0, import_objectSpread22.default)({
1314
+ _config: config,
1315
+ router: true,
1316
+ procedures,
1317
+ lazy: lazy$1
1318
+ }, emptyRouter), {}, { record });
1319
+ const router2 = (0, import_objectSpread22.default)((0, import_objectSpread22.default)({}, record), {}, {
1320
+ _def,
1321
+ createCaller: createCallerFactory()({ _def })
1322
+ });
1323
+ return router2;
1324
+ }
1325
+ return createRouterInner;
1326
+ }
1327
+ function isProcedure(procedureOrRouter) {
1328
+ return typeof procedureOrRouter === "function";
1329
+ }
1330
+ async function getProcedureAtPath(router2, path) {
1331
+ const { _def } = router2;
1332
+ let procedure = _def.procedures[path];
1333
+ while (!procedure) {
1334
+ const key = Object.keys(_def.lazy).find((key$1) => path.startsWith(key$1));
1335
+ if (!key) return null;
1336
+ const lazyRouter = _def.lazy[key];
1337
+ await lazyRouter.load();
1338
+ procedure = _def.procedures[path];
1339
+ }
1340
+ return procedure;
1341
+ }
1342
+ function createCallerFactory() {
1343
+ return function createCallerInner(router2) {
1344
+ const { _def } = router2;
1345
+ return function createCaller(ctxOrCallback, opts) {
1346
+ return createRecursiveProxy(async (innerOpts) => {
1347
+ const { path, args } = innerOpts;
1348
+ const fullPath = path.join(".");
1349
+ if (path.length === 1 && path[0] === "_def") return _def;
1350
+ const procedure = await getProcedureAtPath(router2, fullPath);
1351
+ let ctx = void 0;
1352
+ try {
1353
+ if (!procedure) throw new TRPCError({
1354
+ code: "NOT_FOUND",
1355
+ message: `No procedure found on path "${path}"`
1356
+ });
1357
+ ctx = isFunction(ctxOrCallback) ? await Promise.resolve(ctxOrCallback()) : ctxOrCallback;
1358
+ return await procedure({
1359
+ path: fullPath,
1360
+ getRawInput: async () => args[0],
1361
+ ctx,
1362
+ type: procedure._def.type,
1363
+ signal: opts === null || opts === void 0 ? void 0 : opts.signal
1364
+ });
1365
+ } catch (cause) {
1366
+ var _opts$onError, _procedure$_def$type;
1367
+ opts === null || opts === void 0 || (_opts$onError = opts.onError) === null || _opts$onError === void 0 || _opts$onError.call(opts, {
1368
+ ctx,
1369
+ error: getTRPCErrorFromUnknown(cause),
1370
+ input: args[0],
1371
+ path: fullPath,
1372
+ type: (_procedure$_def$type = procedure === null || procedure === void 0 ? void 0 : procedure._def.type) !== null && _procedure$_def$type !== void 0 ? _procedure$_def$type : "unknown"
1373
+ });
1374
+ throw cause;
1375
+ }
1376
+ });
1377
+ };
1378
+ };
1379
+ }
1380
+ function mergeRouters(...routerList) {
1381
+ var _routerList$, _routerList$2;
1382
+ const record = mergeWithoutOverrides({}, ...routerList.map((r) => r._def.record));
1383
+ const errorFormatter = routerList.reduce((currentErrorFormatter, nextRouter) => {
1384
+ if (nextRouter._def._config.errorFormatter && nextRouter._def._config.errorFormatter !== defaultFormatter) {
1385
+ if (currentErrorFormatter !== defaultFormatter && currentErrorFormatter !== nextRouter._def._config.errorFormatter) throw new Error("You seem to have several error formatters");
1386
+ return nextRouter._def._config.errorFormatter;
1387
+ }
1388
+ return currentErrorFormatter;
1389
+ }, defaultFormatter);
1390
+ const transformer = routerList.reduce((prev, current) => {
1391
+ if (current._def._config.transformer && current._def._config.transformer !== defaultTransformer) {
1392
+ if (prev !== defaultTransformer && prev !== current._def._config.transformer) throw new Error("You seem to have several transformers");
1393
+ return current._def._config.transformer;
1394
+ }
1395
+ return prev;
1396
+ }, defaultTransformer);
1397
+ const router2 = createRouterFactory({
1398
+ errorFormatter,
1399
+ transformer,
1400
+ isDev: routerList.every((r) => r._def._config.isDev),
1401
+ allowOutsideOfServer: routerList.every((r) => r._def._config.allowOutsideOfServer),
1402
+ isServer: routerList.every((r) => r._def._config.isServer),
1403
+ $types: (_routerList$ = routerList[0]) === null || _routerList$ === void 0 ? void 0 : _routerList$._def._config.$types,
1404
+ sse: (_routerList$2 = routerList[0]) === null || _routerList$2 === void 0 ? void 0 : _routerList$2._def._config.sse
1405
+ })(record);
1406
+ return router2;
1407
+ }
1408
+
1409
+ // ../../node_modules/.pnpm/@trpc+server@11.8.1_typescript@5.9.3/node_modules/@trpc/server/dist/initTRPC-T5bbc89W.mjs
1410
+ var import_objectSpread2$2 = __toESM2(require_objectSpread2(), 1);
1411
+ var middlewareMarker = "middlewareMarker";
1412
+ function createMiddlewareFactory() {
1413
+ function createMiddlewareInner(middlewares) {
1414
+ return {
1415
+ _middlewares: middlewares,
1416
+ unstable_pipe(middlewareBuilderOrFn) {
1417
+ const pipedMiddleware = "_middlewares" in middlewareBuilderOrFn ? middlewareBuilderOrFn._middlewares : [middlewareBuilderOrFn];
1418
+ return createMiddlewareInner([...middlewares, ...pipedMiddleware]);
1419
+ }
1420
+ };
1421
+ }
1422
+ function createMiddleware(fn) {
1423
+ return createMiddlewareInner([fn]);
1424
+ }
1425
+ return createMiddleware;
1426
+ }
1427
+ function createInputMiddleware(parse) {
1428
+ const inputMiddleware = async function inputValidatorMiddleware(opts) {
1429
+ let parsedInput;
1430
+ const rawInput = await opts.getRawInput();
1431
+ try {
1432
+ parsedInput = await parse(rawInput);
1433
+ } catch (cause) {
1434
+ throw new TRPCError({
1435
+ code: "BAD_REQUEST",
1436
+ cause
1437
+ });
1438
+ }
1439
+ const combinedInput = isObject(opts.input) && isObject(parsedInput) ? (0, import_objectSpread2$2.default)((0, import_objectSpread2$2.default)({}, opts.input), parsedInput) : parsedInput;
1440
+ return opts.next({ input: combinedInput });
1441
+ };
1442
+ inputMiddleware._type = "input";
1443
+ return inputMiddleware;
1444
+ }
1445
+ function createOutputMiddleware(parse) {
1446
+ const outputMiddleware = async function outputValidatorMiddleware({ next }) {
1447
+ const result = await next();
1448
+ if (!result.ok) return result;
1449
+ try {
1450
+ const data = await parse(result.data);
1451
+ return (0, import_objectSpread2$2.default)((0, import_objectSpread2$2.default)({}, result), {}, { data });
1452
+ } catch (cause) {
1453
+ throw new TRPCError({
1454
+ message: "Output validation failed",
1455
+ code: "INTERNAL_SERVER_ERROR",
1456
+ cause
1457
+ });
1458
+ }
1459
+ };
1460
+ outputMiddleware._type = "output";
1461
+ return outputMiddleware;
1462
+ }
1463
+ var import_defineProperty2 = __toESM2(require_defineProperty(), 1);
1464
+ var StandardSchemaV1Error = class extends Error {
1465
+ /**
1466
+ * Creates a schema error with useful information.
1467
+ *
1468
+ * @param issues The schema issues.
1469
+ */
1470
+ constructor(issues) {
1471
+ var _issues$;
1472
+ super((_issues$ = issues[0]) === null || _issues$ === void 0 ? void 0 : _issues$.message);
1473
+ (0, import_defineProperty2.default)(this, "issues", void 0);
1474
+ this.name = "SchemaError";
1475
+ this.issues = issues;
1476
+ }
1477
+ };
1478
+ function getParseFn(procedureParser) {
1479
+ const parser = procedureParser;
1480
+ const isStandardSchema = "~standard" in parser;
1481
+ if (typeof parser === "function" && typeof parser.assert === "function") return parser.assert.bind(parser);
1482
+ if (typeof parser === "function" && !isStandardSchema) return parser;
1483
+ if (typeof parser.parseAsync === "function") return parser.parseAsync.bind(parser);
1484
+ if (typeof parser.parse === "function") return parser.parse.bind(parser);
1485
+ if (typeof parser.validateSync === "function") return parser.validateSync.bind(parser);
1486
+ if (typeof parser.create === "function") return parser.create.bind(parser);
1487
+ if (typeof parser.assert === "function") return (value) => {
1488
+ parser.assert(value);
1489
+ return value;
1490
+ };
1491
+ if (isStandardSchema) return async (value) => {
1492
+ const result = await parser["~standard"].validate(value);
1493
+ if (result.issues) throw new StandardSchemaV1Error(result.issues);
1494
+ return result.value;
1495
+ };
1496
+ throw new Error("Could not find a validator fn");
1497
+ }
1498
+ var require_objectWithoutPropertiesLoose = __commonJS2({ "../../node_modules/.pnpm/@oxc-project+runtime@0.72.2/node_modules/@oxc-project/runtime/src/helpers/objectWithoutPropertiesLoose.js"(exports, module) {
1499
+ function _objectWithoutPropertiesLoose(r, e) {
1500
+ if (null == r) return {};
1501
+ var t2 = {};
1502
+ for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
1503
+ if (e.includes(n)) continue;
1504
+ t2[n] = r[n];
1505
+ }
1506
+ return t2;
1507
+ }
1508
+ module.exports = _objectWithoutPropertiesLoose, module.exports.__esModule = true, module.exports["default"] = module.exports;
1509
+ } });
1510
+ var require_objectWithoutProperties = __commonJS2({ "../../node_modules/.pnpm/@oxc-project+runtime@0.72.2/node_modules/@oxc-project/runtime/src/helpers/objectWithoutProperties.js"(exports, module) {
1511
+ var objectWithoutPropertiesLoose = require_objectWithoutPropertiesLoose();
1512
+ function _objectWithoutProperties$1(e, t2) {
1513
+ if (null == e) return {};
1514
+ var o, r, i = objectWithoutPropertiesLoose(e, t2);
1515
+ if (Object.getOwnPropertySymbols) {
1516
+ var s = Object.getOwnPropertySymbols(e);
1517
+ for (r = 0; r < s.length; r++) o = s[r], t2.includes(o) || {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
1518
+ }
1519
+ return i;
1520
+ }
1521
+ module.exports = _objectWithoutProperties$1, module.exports.__esModule = true, module.exports["default"] = module.exports;
1522
+ } });
1523
+ var import_objectWithoutProperties = __toESM2(require_objectWithoutProperties(), 1);
1524
+ var import_objectSpread2$12 = __toESM2(require_objectSpread2(), 1);
1525
+ var _excluded = [
1526
+ "middlewares",
1527
+ "inputs",
1528
+ "meta"
1529
+ ];
1530
+ function createNewBuilder(def1, def2) {
1531
+ const { middlewares = [], inputs, meta } = def2, rest = (0, import_objectWithoutProperties.default)(def2, _excluded);
1532
+ return createBuilder((0, import_objectSpread2$12.default)((0, import_objectSpread2$12.default)({}, mergeWithoutOverrides(def1, rest)), {}, {
1533
+ inputs: [...def1.inputs, ...inputs !== null && inputs !== void 0 ? inputs : []],
1534
+ middlewares: [...def1.middlewares, ...middlewares],
1535
+ meta: def1.meta && meta ? (0, import_objectSpread2$12.default)((0, import_objectSpread2$12.default)({}, def1.meta), meta) : meta !== null && meta !== void 0 ? meta : def1.meta
1536
+ }));
1537
+ }
1538
+ function createBuilder(initDef = {}) {
1539
+ const _def = (0, import_objectSpread2$12.default)({
1540
+ procedure: true,
1541
+ inputs: [],
1542
+ middlewares: []
1543
+ }, initDef);
1544
+ const builder = {
1545
+ _def,
1546
+ input(input) {
1547
+ const parser = getParseFn(input);
1548
+ return createNewBuilder(_def, {
1549
+ inputs: [input],
1550
+ middlewares: [createInputMiddleware(parser)]
1551
+ });
1552
+ },
1553
+ output(output) {
1554
+ const parser = getParseFn(output);
1555
+ return createNewBuilder(_def, {
1556
+ output,
1557
+ middlewares: [createOutputMiddleware(parser)]
1558
+ });
1559
+ },
1560
+ meta(meta) {
1561
+ return createNewBuilder(_def, { meta });
1562
+ },
1563
+ use(middlewareBuilderOrFn) {
1564
+ const middlewares = "_middlewares" in middlewareBuilderOrFn ? middlewareBuilderOrFn._middlewares : [middlewareBuilderOrFn];
1565
+ return createNewBuilder(_def, { middlewares });
1566
+ },
1567
+ unstable_concat(builder$1) {
1568
+ return createNewBuilder(_def, builder$1._def);
1569
+ },
1570
+ concat(builder$1) {
1571
+ return createNewBuilder(_def, builder$1._def);
1572
+ },
1573
+ query(resolver) {
1574
+ return createResolver((0, import_objectSpread2$12.default)((0, import_objectSpread2$12.default)({}, _def), {}, { type: "query" }), resolver);
1575
+ },
1576
+ mutation(resolver) {
1577
+ return createResolver((0, import_objectSpread2$12.default)((0, import_objectSpread2$12.default)({}, _def), {}, { type: "mutation" }), resolver);
1578
+ },
1579
+ subscription(resolver) {
1580
+ return createResolver((0, import_objectSpread2$12.default)((0, import_objectSpread2$12.default)({}, _def), {}, { type: "subscription" }), resolver);
1581
+ },
1582
+ experimental_caller(caller) {
1583
+ return createNewBuilder(_def, { caller });
1584
+ }
1585
+ };
1586
+ return builder;
1587
+ }
1588
+ function createResolver(_defIn, resolver) {
1589
+ const finalBuilder = createNewBuilder(_defIn, {
1590
+ resolver,
1591
+ middlewares: [async function resolveMiddleware(opts) {
1592
+ const data = await resolver(opts);
1593
+ return {
1594
+ marker: middlewareMarker,
1595
+ ok: true,
1596
+ data,
1597
+ ctx: opts.ctx
1598
+ };
1599
+ }]
1600
+ });
1601
+ const _def = (0, import_objectSpread2$12.default)((0, import_objectSpread2$12.default)({}, finalBuilder._def), {}, {
1602
+ type: _defIn.type,
1603
+ experimental_caller: Boolean(finalBuilder._def.caller),
1604
+ meta: finalBuilder._def.meta,
1605
+ $types: null
1606
+ });
1607
+ const invoke = createProcedureCaller(finalBuilder._def);
1608
+ const callerOverride = finalBuilder._def.caller;
1609
+ if (!callerOverride) return invoke;
1610
+ const callerWrapper = async (...args) => {
1611
+ return await callerOverride({
1612
+ args,
1613
+ invoke,
1614
+ _def
1615
+ });
1616
+ };
1617
+ callerWrapper._def = _def;
1618
+ return callerWrapper;
1619
+ }
1620
+ var codeblock = `
1621
+ This is a client-only function.
1622
+ If you want to call this function on the server, see https://trpc.io/docs/v11/server/server-side-calls
1623
+ `.trim();
1624
+ async function callRecursive(index, _def, opts) {
1625
+ try {
1626
+ const middleware2 = _def.middlewares[index];
1627
+ const result = await middleware2((0, import_objectSpread2$12.default)((0, import_objectSpread2$12.default)({}, opts), {}, {
1628
+ meta: _def.meta,
1629
+ input: opts.input,
1630
+ next(_nextOpts) {
1631
+ var _nextOpts$getRawInput;
1632
+ const nextOpts = _nextOpts;
1633
+ return callRecursive(index + 1, _def, (0, import_objectSpread2$12.default)((0, import_objectSpread2$12.default)({}, opts), {}, {
1634
+ ctx: (nextOpts === null || nextOpts === void 0 ? void 0 : nextOpts.ctx) ? (0, import_objectSpread2$12.default)((0, import_objectSpread2$12.default)({}, opts.ctx), nextOpts.ctx) : opts.ctx,
1635
+ input: nextOpts && "input" in nextOpts ? nextOpts.input : opts.input,
1636
+ getRawInput: (_nextOpts$getRawInput = nextOpts === null || nextOpts === void 0 ? void 0 : nextOpts.getRawInput) !== null && _nextOpts$getRawInput !== void 0 ? _nextOpts$getRawInput : opts.getRawInput
1637
+ }));
1638
+ }
1639
+ }));
1640
+ return result;
1641
+ } catch (cause) {
1642
+ return {
1643
+ ok: false,
1644
+ error: getTRPCErrorFromUnknown(cause),
1645
+ marker: middlewareMarker
1646
+ };
1647
+ }
1648
+ }
1649
+ function createProcedureCaller(_def) {
1650
+ async function procedure(opts) {
1651
+ if (!opts || !("getRawInput" in opts)) throw new Error(codeblock);
1652
+ const result = await callRecursive(0, _def, opts);
1653
+ if (!result) throw new TRPCError({
1654
+ code: "INTERNAL_SERVER_ERROR",
1655
+ message: "No result from middlewares - did you forget to `return next()`?"
1656
+ });
1657
+ if (!result.ok) throw result.error;
1658
+ return result.data;
1659
+ }
1660
+ procedure._def = _def;
1661
+ procedure.procedure = true;
1662
+ procedure.meta = _def.meta;
1663
+ return procedure;
1664
+ }
1665
+ var _globalThis$process;
1666
+ var _globalThis$process2;
1667
+ var _globalThis$process3;
1668
+ var isServerDefault = typeof window === "undefined" || "Deno" in window || ((_globalThis$process = globalThis.process) === null || _globalThis$process === void 0 || (_globalThis$process = _globalThis$process.env) === null || _globalThis$process === void 0 ? void 0 : _globalThis$process["NODE_ENV"]) === "test" || !!((_globalThis$process2 = globalThis.process) === null || _globalThis$process2 === void 0 || (_globalThis$process2 = _globalThis$process2.env) === null || _globalThis$process2 === void 0 ? void 0 : _globalThis$process2["JEST_WORKER_ID"]) || !!((_globalThis$process3 = globalThis.process) === null || _globalThis$process3 === void 0 || (_globalThis$process3 = _globalThis$process3.env) === null || _globalThis$process3 === void 0 ? void 0 : _globalThis$process3["VITEST_WORKER_ID"]);
1669
+ var import_objectSpread23 = __toESM2(require_objectSpread2(), 1);
1670
+ var TRPCBuilder = class TRPCBuilder2 {
1671
+ /**
1672
+ * Add a context shape as a generic to the root object
1673
+ * @see https://trpc.io/docs/v11/server/context
1674
+ */
1675
+ context() {
1676
+ return new TRPCBuilder2();
1677
+ }
1678
+ /**
1679
+ * Add a meta shape as a generic to the root object
1680
+ * @see https://trpc.io/docs/v11/quickstart
1681
+ */
1682
+ meta() {
1683
+ return new TRPCBuilder2();
1684
+ }
1685
+ /**
1686
+ * Create the root object
1687
+ * @see https://trpc.io/docs/v11/server/routers#initialize-trpc
1688
+ */
1689
+ create(opts) {
1690
+ var _opts$transformer, _opts$isDev, _globalThis$process$1, _opts$allowOutsideOfS, _opts$errorFormatter, _opts$isServer;
1691
+ const config = (0, import_objectSpread23.default)((0, import_objectSpread23.default)({}, opts), {}, {
1692
+ transformer: getDataTransformer((_opts$transformer = opts === null || opts === void 0 ? void 0 : opts.transformer) !== null && _opts$transformer !== void 0 ? _opts$transformer : defaultTransformer),
1693
+ isDev: (_opts$isDev = opts === null || opts === void 0 ? void 0 : opts.isDev) !== null && _opts$isDev !== void 0 ? _opts$isDev : ((_globalThis$process$1 = globalThis.process) === null || _globalThis$process$1 === void 0 ? void 0 : _globalThis$process$1.env["NODE_ENV"]) !== "production",
1694
+ allowOutsideOfServer: (_opts$allowOutsideOfS = opts === null || opts === void 0 ? void 0 : opts.allowOutsideOfServer) !== null && _opts$allowOutsideOfS !== void 0 ? _opts$allowOutsideOfS : false,
1695
+ errorFormatter: (_opts$errorFormatter = opts === null || opts === void 0 ? void 0 : opts.errorFormatter) !== null && _opts$errorFormatter !== void 0 ? _opts$errorFormatter : defaultFormatter,
1696
+ isServer: (_opts$isServer = opts === null || opts === void 0 ? void 0 : opts.isServer) !== null && _opts$isServer !== void 0 ? _opts$isServer : isServerDefault,
1697
+ $types: null
1698
+ });
1699
+ {
1700
+ var _opts$isServer2;
1701
+ const isServer = (_opts$isServer2 = opts === null || opts === void 0 ? void 0 : opts.isServer) !== null && _opts$isServer2 !== void 0 ? _opts$isServer2 : isServerDefault;
1702
+ if (!isServer && (opts === null || opts === void 0 ? void 0 : opts.allowOutsideOfServer) !== true) throw new Error(`You're trying to use @trpc/server in a non-server environment. This is not supported by default.`);
1703
+ }
1704
+ return {
1705
+ _config: config,
1706
+ procedure: createBuilder({ meta: opts === null || opts === void 0 ? void 0 : opts.defaultMeta }),
1707
+ middleware: createMiddlewareFactory(),
1708
+ router: createRouterFactory(config),
1709
+ mergeRouters,
1710
+ createCallerFactory: createCallerFactory()
1711
+ };
1712
+ }
1713
+ };
1714
+ var initTRPC = new TRPCBuilder();
1715
+
1716
+ // ../../packages/schema/dist/index.mjs
1717
+ var A2ATextPartSchema = z3.object({
1718
+ type: z3.literal("text"),
1719
+ text: z3.string()
1720
+ });
1721
+ var A2ADataPartSchema = z3.object({
1722
+ type: z3.literal("data"),
1723
+ data: z3.unknown()
1724
+ });
1725
+ var A2AFilePartSchema = z3.object({
1726
+ type: z3.literal("file"),
1727
+ uri: z3.string(),
1728
+ mediaType: z3.string().optional(),
1729
+ name: z3.string().optional()
1730
+ });
1731
+ var A2APartSchema = z3.object({ type: z3.enum([
1732
+ "text",
1733
+ "data",
1734
+ "file"
1735
+ ]) }).passthrough().superRefine((val, ctx) => {
1736
+ if (val.type === "text") {
1737
+ if (typeof val.text !== "string") ctx.addIssue({
1738
+ code: z3.ZodIssueCode.custom,
1739
+ message: "text part must have a string text field"
1740
+ });
1741
+ } else if (val.type === "data") {
1742
+ if (!("data" in val)) ctx.addIssue({
1743
+ code: z3.ZodIssueCode.custom,
1744
+ message: "data part must have a data field"
1745
+ });
1746
+ } else if (val.type === "file") {
1747
+ if (typeof val.uri !== "string") ctx.addIssue({
1748
+ code: z3.ZodIssueCode.custom,
1749
+ message: "file part must have a string uri field"
1750
+ });
1751
+ }
1752
+ });
1753
+ function isValidA2APart(part) {
1754
+ if (!part || typeof part !== "object") return false;
1755
+ const p = part;
1756
+ const t$1 = p.type;
1757
+ if (t$1 === "text") return typeof p.text === "string";
1758
+ else if (t$1 === "data") return "data" in p;
1759
+ else if (t$1 === "file") return typeof p.uri === "string";
1760
+ return false;
1761
+ }
1762
+ function isValidA2AParts(parts) {
1763
+ if (!Array.isArray(parts)) return false;
1764
+ return parts.every(isValidA2APart);
1765
+ }
1766
+ var A2AMessageSchema = z3.object({
1767
+ messageId: z3.string(),
1768
+ role: z3.enum(["user", "agent"]),
1769
+ contextId: z3.string().optional(),
1770
+ taskId: z3.string().optional(),
1771
+ referenceTaskIds: z3.array(z3.string()).optional(),
1772
+ metadata: z3.record(z3.string(), z3.unknown()).optional(),
1773
+ extensions: z3.array(z3.string()).optional()
1774
+ }).passthrough().refine((val) => {
1775
+ const parts = val.parts;
1776
+ return isValidA2AParts(parts);
1777
+ }, {
1778
+ message: "Invalid parts array - each part must have valid type and required fields",
1779
+ path: ["parts"]
1780
+ }).transform((val) => ({
1781
+ ...val,
1782
+ parts: val.parts
1783
+ }));
1784
+ var ConversationExportMetaSchema = z3.object({
1785
+ exportId: z3.string(),
1786
+ sourcePlatform: z3.string(),
1787
+ sourceSessionId: z3.string(),
1788
+ planId: z3.string(),
1789
+ exportedAt: z3.number(),
1790
+ messageCount: z3.number(),
1791
+ compressedBytes: z3.number(),
1792
+ uncompressedBytes: z3.number()
1793
+ });
1794
+ z3.object({
1795
+ type: z3.literal("text"),
1796
+ text: z3.string()
1797
+ });
1798
+ z3.object({
1799
+ type: z3.literal("tool_use"),
1800
+ id: z3.string(),
1801
+ name: z3.string(),
1802
+ input: z3.record(z3.string(), z3.unknown())
1803
+ });
1804
+ z3.object({
1805
+ type: z3.literal("tool_result"),
1806
+ tool_use_id: z3.string(),
1807
+ content: z3.unknown(),
1808
+ is_error: z3.boolean().optional()
1809
+ });
1810
+ var ClaudeCodeContentBlockSchema = z3.object({ type: z3.enum([
1811
+ "text",
1812
+ "tool_use",
1813
+ "tool_result"
1814
+ ]) }).passthrough().superRefine((val, ctx) => {
1815
+ const typedVal = val;
1816
+ if (val.type === "text") {
1817
+ if (typeof typedVal.text !== "string") ctx.addIssue({
1818
+ code: z3.ZodIssueCode.custom,
1819
+ message: "text block must have a string text field"
1820
+ });
1821
+ } else if (val.type === "tool_use") {
1822
+ if (typeof typedVal.id !== "string") ctx.addIssue({
1823
+ code: z3.ZodIssueCode.custom,
1824
+ message: "tool_use block must have a string id field"
1825
+ });
1826
+ if (typeof typedVal.name !== "string") ctx.addIssue({
1827
+ code: z3.ZodIssueCode.custom,
1828
+ message: "tool_use block must have a string name field"
1829
+ });
1830
+ if (typeof typedVal.input !== "object" || typedVal.input === null) ctx.addIssue({
1831
+ code: z3.ZodIssueCode.custom,
1832
+ message: "tool_use block must have an object input field"
1833
+ });
1834
+ } else if (val.type === "tool_result") {
1835
+ if (typeof typedVal.tool_use_id !== "string") ctx.addIssue({
1836
+ code: z3.ZodIssueCode.custom,
1837
+ message: "tool_result block must have a string tool_use_id field"
1838
+ });
1839
+ }
1840
+ });
1841
+ var ClaudeCodeUsageSchema = z3.object({
1842
+ input_tokens: z3.number(),
1843
+ output_tokens: z3.number(),
1844
+ cache_creation_input_tokens: z3.number().optional(),
1845
+ cache_read_input_tokens: z3.number().optional()
1846
+ });
1847
+ var ClaudeCodeMessageInnerSchema = z3.object({
1848
+ role: z3.string(),
1849
+ content: z3.array(ClaudeCodeContentBlockSchema),
1850
+ id: z3.string().optional(),
1851
+ model: z3.string().optional(),
1852
+ usage: ClaudeCodeUsageSchema.optional()
1853
+ });
1854
+ var ClaudeCodeMessageSchema = z3.object({
1855
+ sessionId: z3.string(),
1856
+ type: z3.enum([
1857
+ "user",
1858
+ "assistant",
1859
+ "summary"
1860
+ ]),
1861
+ message: ClaudeCodeMessageInnerSchema,
1862
+ uuid: z3.string(),
1863
+ timestamp: z3.string(),
1864
+ parentUuid: z3.string().optional(),
1865
+ costUSD: z3.number().optional(),
1866
+ durationMs: z3.number().optional()
1867
+ });
1868
+ var GitHubPRResponseSchema = z3.object({
1869
+ number: z3.number(),
1870
+ html_url: z3.string().url(),
1871
+ title: z3.string(),
1872
+ state: z3.enum(["open", "closed"]),
1873
+ draft: z3.boolean(),
1874
+ merged: z3.boolean(),
1875
+ head: z3.object({ ref: z3.string() })
1876
+ });
1877
+ var InviteTokenSchema = z3.object({
1878
+ id: z3.string(),
1879
+ tokenHash: z3.string(),
1880
+ planId: z3.string(),
1881
+ createdBy: z3.string(),
1882
+ createdAt: z3.number(),
1883
+ expiresAt: z3.number(),
1884
+ maxUses: z3.number().nullable(),
1885
+ useCount: z3.number(),
1886
+ revoked: z3.boolean(),
1887
+ label: z3.string().optional()
1888
+ });
1889
+ var InviteRedemptionSchema = z3.object({
1890
+ redeemedBy: z3.string(),
1891
+ redeemedAt: z3.number(),
1892
+ tokenId: z3.string()
1893
+ });
1894
+ var ConversationExportStartMetaSchema = z3.object({
1895
+ exportId: z3.string(),
1896
+ totalChunks: z3.number().int().positive(),
1897
+ totalBytes: z3.number().int().nonnegative(),
1898
+ compressedBytes: z3.number().int().nonnegative(),
1899
+ sourcePlatform: z3.string(),
1900
+ sourceSessionId: z3.string(),
1901
+ planId: z3.string(),
1902
+ exportedAt: z3.number().int().positive()
1903
+ });
1904
+ var ChunkMessageSchema = z3.object({
1905
+ exportId: z3.string(),
1906
+ chunkIndex: z3.number().int().nonnegative(),
1907
+ data: z3.instanceof(Uint8Array)
1908
+ });
1909
+ var ConversationExportEndSchema = z3.object({
1910
+ exportId: z3.string(),
1911
+ checksum: z3.string()
1912
+ });
1913
+ var textEncoder = new TextEncoder();
1914
+ var textDecoder = new TextDecoder();
1915
+ var PlanIndexEntrySchema = z3.discriminatedUnion("deleted", [z3.object({
1916
+ deleted: z3.literal(false),
1917
+ id: z3.string(),
1918
+ title: z3.string(),
1919
+ status: z3.enum(PlanStatusValues),
1920
+ createdAt: z3.number(),
1921
+ updatedAt: z3.number(),
1922
+ ownerId: z3.string(),
1923
+ tags: z3.array(z3.string()).optional()
1924
+ }), z3.object({
1925
+ deleted: z3.literal(true),
1926
+ id: z3.string(),
1927
+ title: z3.string(),
1928
+ status: z3.enum(PlanStatusValues),
1929
+ createdAt: z3.number(),
1930
+ updatedAt: z3.number(),
1931
+ ownerId: z3.string(),
1932
+ tags: z3.array(z3.string()).optional(),
1933
+ deletedAt: z3.number(),
1934
+ deletedBy: z3.string()
1935
+ })]);
1936
+ function formatThreadsForLLM(threads, options = {}) {
1937
+ const { includeResolved = false, selectedTextMaxLength = 100, resolveUser } = options;
1938
+ const unresolvedThreads = threads.filter((t$1) => !t$1.resolved);
1939
+ const resolvedCount = threads.length - unresolvedThreads.length;
1940
+ const threadsToShow = includeResolved ? threads : unresolvedThreads;
1941
+ if (threadsToShow.length === 0) {
1942
+ if (resolvedCount > 0) return `All ${resolvedCount} comment(s) have been resolved.`;
1943
+ return "";
1944
+ }
1945
+ let output = threadsToShow.map((thread, index) => {
1946
+ const location = thread.selectedText ? `On: "${truncate(thread.selectedText, selectedTextMaxLength)}"` : `Comment ${index + 1}`;
1947
+ const comments = thread.comments.map((c, idx) => {
1948
+ const text = extractTextFromCommentBody(c.body);
1949
+ const author = resolveUser ? resolveUser(c.userId) : c.userId.slice(0, 8);
1950
+ if (idx === 0) return `${author}: ${text}`;
1951
+ return `${author} (reply): ${text}`;
1952
+ }).join("\n");
1953
+ return `${location}${thread.resolved ? " [Resolved]" : ""}
1954
+ ${comments}`;
1955
+ }).join("\n\n");
1956
+ if (!includeResolved && resolvedCount > 0) output += `
1957
+
1958
+ ---
1959
+ (${resolvedCount} resolved comment(s) not shown)`;
1960
+ return output;
1961
+ }
1962
+ function truncate(text, maxLength) {
1963
+ const cleaned = text.replace(/\n/g, " ").trim();
1964
+ if (cleaned.length <= maxLength) return cleaned;
1965
+ return `${cleaned.slice(0, maxLength)}...`;
1966
+ }
1967
+ var PlanIdSchema = z3.object({ planId: z3.string().min(1) });
1968
+ var PlanStatusResponseSchema = z3.object({ status: z3.string() });
1969
+ var HasConnectionsResponseSchema = z3.object({ hasConnections: z3.boolean() });
1970
+ var SubscriptionClientIdSchema = z3.object({
1971
+ planId: z3.string().min(1),
1972
+ clientId: z3.string().min(1)
1973
+ });
1974
+ var ChangeTypeSchema = z3.enum([
1975
+ "status",
1976
+ "comments",
1977
+ "resolved",
1978
+ "content",
1979
+ "artifacts"
1980
+ ]);
1981
+ var ChangeSchema = z3.object({
1982
+ type: ChangeTypeSchema,
1983
+ timestamp: z3.number(),
1984
+ summary: z3.string(),
1985
+ details: z3.record(z3.string(), z3.unknown()).optional()
1986
+ });
1987
+ var ChangesResponseSchema = z3.discriminatedUnion("ready", [z3.object({
1988
+ ready: z3.literal(true),
1989
+ changes: z3.string(),
1990
+ details: z3.array(ChangeSchema)
1991
+ }), z3.object({
1992
+ ready: z3.literal(false),
1993
+ pending: z3.number(),
1994
+ windowExpiresIn: z3.number()
1995
+ })]);
1996
+ var DeleteSubscriptionResponseSchema = z3.object({ success: z3.boolean() });
1997
+ var SetSessionTokenRequestSchema = z3.object({ sessionTokenHash: z3.string().min(1) });
1998
+ var GetDeliverableContextRequestSchema = z3.object({ sessionToken: z3.string().min(1) });
1999
+ var GetDeliverableContextResponseSchema = z3.object({ context: z3.string() });
2000
+ var SetSessionTokenResponseSchema = z3.object({ url: z3.string() });
2001
+ var ImportConversationRequestSchema = z3.object({
2002
+ a2aMessages: z3.array(A2AMessageSchema),
2003
+ meta: z3.object({
2004
+ planId: z3.string().optional(),
2005
+ sourcePlatform: z3.string().optional(),
2006
+ sessionId: z3.string().optional()
2007
+ }).optional()
2008
+ });
2009
+ var ImportConversationResponseSchema = z3.discriminatedUnion("success", [z3.object({
2010
+ success: z3.literal(true),
2011
+ sessionId: z3.string(),
2012
+ transcriptPath: z3.string(),
2013
+ messageCount: z3.number()
2014
+ }), z3.object({
2015
+ success: z3.literal(false),
2016
+ error: z3.string()
2017
+ })]);
2018
+ var t = initTRPC.context().create({ allowOutsideOfServer: true });
2019
+ var router = t.router;
2020
+ var publicProcedure = t.procedure;
2021
+ var middleware = t.middleware;
2022
+ var conversationRouter = router({ import: publicProcedure.input(ImportConversationRequestSchema).output(ImportConversationResponseSchema).mutation(async ({ input, ctx }) => {
2023
+ return ctx.conversationHandlers.importConversation(input, ctx);
2024
+ }) });
2025
+ var hookRouter = router({
2026
+ createSession: publicProcedure.input(CreateHookSessionRequestSchema).output(CreateHookSessionResponseSchema).mutation(async ({ input, ctx }) => {
2027
+ return ctx.hookHandlers.createSession(input, ctx);
2028
+ }),
2029
+ updateContent: publicProcedure.input(PlanIdSchema.merge(UpdatePlanContentRequestSchema)).output(UpdatePlanContentResponseSchema).mutation(async ({ input, ctx }) => {
2030
+ const { planId, ...contentInput } = input;
2031
+ return ctx.hookHandlers.updateContent(planId, contentInput, ctx);
2032
+ }),
2033
+ getReviewStatus: publicProcedure.input(PlanIdSchema).output(GetReviewStatusResponseSchema).query(async ({ input, ctx }) => {
2034
+ return ctx.hookHandlers.getReviewStatus(input.planId, ctx);
2035
+ }),
2036
+ updatePresence: publicProcedure.input(PlanIdSchema.merge(UpdatePresenceRequestSchema)).output(UpdatePresenceResponseSchema).mutation(async ({ input, ctx }) => {
2037
+ const { planId, ...presenceInput } = input;
2038
+ return ctx.hookHandlers.updatePresence(planId, presenceInput, ctx);
2039
+ }),
2040
+ setSessionToken: publicProcedure.input(PlanIdSchema.merge(SetSessionTokenRequestSchema)).output(SetSessionTokenResponseSchema).mutation(async ({ input, ctx }) => {
2041
+ const { planId, sessionTokenHash } = input;
2042
+ return ctx.hookHandlers.setSessionToken(planId, sessionTokenHash, ctx);
2043
+ }),
2044
+ waitForApproval: publicProcedure.input(z3.object({
2045
+ planId: z3.string(),
2046
+ reviewRequestId: z3.string()
2047
+ })).output(z3.object({
2048
+ approved: z3.boolean(),
2049
+ feedback: z3.string().optional(),
2050
+ deliverables: z3.array(z3.any()).optional(),
2051
+ reviewComment: z3.string().optional(),
2052
+ reviewedBy: z3.string().optional(),
2053
+ status: z3.string().optional()
2054
+ })).mutation(async ({ input, ctx }) => {
2055
+ const { planId, reviewRequestId } = input;
2056
+ return ctx.hookHandlers.waitForApproval(planId, reviewRequestId, ctx);
2057
+ }),
2058
+ getDeliverableContext: publicProcedure.input(PlanIdSchema.merge(GetDeliverableContextRequestSchema)).output(GetDeliverableContextResponseSchema).query(async ({ input, ctx }) => {
2059
+ const { planId, sessionToken } = input;
2060
+ return ctx.hookHandlers.getDeliverableContext(planId, sessionToken, ctx);
2061
+ }),
2062
+ getSessionContext: publicProcedure.input(z3.object({ sessionId: z3.string() })).output(z3.discriminatedUnion("found", [z3.object({
2063
+ found: z3.literal(true),
2064
+ planId: z3.string(),
2065
+ sessionToken: z3.string(),
2066
+ url: z3.string(),
2067
+ deliverables: z3.array(z3.object({
2068
+ id: z3.string(),
2069
+ text: z3.string()
2070
+ })),
2071
+ reviewComment: z3.string().optional(),
2072
+ reviewedBy: z3.string().optional(),
2073
+ reviewStatus: z3.string().optional()
2074
+ }), z3.object({ found: z3.literal(false) })])).query(async ({ input, ctx }) => {
2075
+ return ctx.hookHandlers.getSessionContext(input.sessionId, ctx);
2076
+ })
2077
+ });
2078
+ var planRouter = router({
2079
+ getStatus: publicProcedure.input(PlanIdSchema).output(PlanStatusResponseSchema).query(async ({ input, ctx }) => {
2080
+ const metadata = getPlanMetadata(await ctx.getOrCreateDoc(input.planId));
2081
+ if (!metadata) throw new TRPCError({
2082
+ code: "NOT_FOUND",
2083
+ message: "Plan not found"
2084
+ });
2085
+ return { status: metadata.status };
2086
+ }),
2087
+ hasConnections: publicProcedure.input(PlanIdSchema).output(HasConnectionsResponseSchema).query(async ({ input, ctx }) => {
2088
+ return { hasConnections: await ctx.getPlanStore().hasActiveConnections(input.planId) };
2089
+ })
2090
+ });
2091
+ var subscriptionRouter = router({
2092
+ create: publicProcedure.input(PlanIdSchema.merge(CreateSubscriptionRequestSchema)).output(CreateSubscriptionResponseSchema).mutation(async ({ input, ctx }) => {
2093
+ const { planId, subscribe, windowMs, maxWindowMs, threshold } = input;
2094
+ return { clientId: ctx.getPlanStore().createSubscription({
2095
+ planId,
2096
+ subscribe: subscribe || ["status"],
2097
+ windowMs: windowMs ?? 5e3,
2098
+ maxWindowMs: maxWindowMs ?? 3e4,
2099
+ threshold: threshold ?? 1
2100
+ }) };
2101
+ }),
2102
+ getChanges: publicProcedure.input(SubscriptionClientIdSchema).output(ChangesResponseSchema).query(async ({ input, ctx }) => {
2103
+ const { planId, clientId } = input;
2104
+ const result = ctx.getPlanStore().getChanges(planId, clientId);
2105
+ if (!result) throw new TRPCError({
2106
+ code: "NOT_FOUND",
2107
+ message: "Subscription not found"
2108
+ });
2109
+ return result;
2110
+ }),
2111
+ delete: publicProcedure.input(SubscriptionClientIdSchema).output(DeleteSubscriptionResponseSchema).mutation(async ({ input, ctx }) => {
2112
+ const { planId, clientId } = input;
2113
+ return { success: ctx.getPlanStore().deleteSubscription(planId, clientId) };
2114
+ })
2115
+ });
2116
+ var appRouter = router({
2117
+ hook: hookRouter,
2118
+ plan: planRouter,
2119
+ subscription: subscriptionRouter,
2120
+ conversation: conversationRouter
2121
+ });
2122
+
2123
+ // src/adapters/claude-code.ts
2124
+ import { z as z6 } from "zod";
2125
+
2126
+ // src/constants.ts
2127
+ var CLAUDE_TOOL_NAMES = {
2128
+ WRITE: "Write",
2129
+ EDIT: "Edit",
2130
+ EXIT_PLAN_MODE: "ExitPlanMode",
2131
+ ASK_USER_QUESTION: "AskUserQuestion"
2132
+ };
2133
+ var MCP_TOOL_NAMES = {
2134
+ REQUEST_USER_INPUT: "request_user_input"
2135
+ };
2136
+ var CLAUDE_PERMISSION_MODES = {
2137
+ PLAN: "plan",
2138
+ DEFAULT: "default",
2139
+ ACCEPT_EDITS: "acceptEdits",
2140
+ DONT_ASK: "dontAsk",
2141
+ BYPASS_PERMISSIONS: "bypassPermissions"
2142
+ };
2143
+ var CLAUDE_HOOK_EVENTS = {
2144
+ PRE_TOOL_USE: "PreToolUse",
2145
+ POST_TOOL_USE: "PostToolUse",
2146
+ PERMISSION_REQUEST: "PermissionRequest"
2147
+ };
2148
+ var DEFAULT_AGENT_TYPE = "claude-code";
2149
+
2150
+ // src/logger.ts
2151
+ import { homedir } from "os";
2152
+ import { join } from "path";
2153
+ import pino from "pino";
2154
+
2155
+ // src/config/env/server.ts
2156
+ import { z as z5 } from "zod";
2157
+
2158
+ // src/config/config.ts
2159
+ import { z as z4 } from "zod";
2160
+ function loadEnv(schema4) {
2161
+ try {
2162
+ return schema4.parse(process.env);
2163
+ } catch (error) {
2164
+ if (error instanceof z4.ZodError) {
2165
+ const testResult = schema4.safeParse(void 0);
2166
+ if (testResult.success) {
2167
+ return testResult.data;
2168
+ }
2169
+ if (!error.issues || !Array.isArray(error.issues)) {
2170
+ throw new Error("Environment variable validation failed (no error details available)");
2171
+ }
2172
+ const errorMessages = error.issues.map((err) => ` - ${err.path.join(".")}: ${err.message}`).join("\n");
2173
+ throw new Error(`Environment variable validation failed:
2174
+ ${errorMessages}`);
2175
+ }
2176
+ throw error;
2177
+ }
2178
+ }
2179
+
2180
+ // src/config/env/server.ts
2181
+ var schema = z5.object({
2182
+ LOG_LEVEL: z5.enum(["debug", "info", "warn", "error"]).default("info")
2183
+ });
2184
+ var serverConfig = loadEnv(schema);
2185
+
2186
+ // src/logger.ts
2187
+ var LOG_FILE = join(homedir(), ".shipyard", "hook-debug.log");
2188
+ var logger = pino(
2189
+ {
2190
+ level: serverConfig.LOG_LEVEL,
2191
+ timestamp: pino.stdTimeFunctions.isoTime
2192
+ },
2193
+ pino.multistream([{ stream: pino.destination(2) }, { stream: pino.destination(LOG_FILE) }])
2194
+ );
2195
+
2196
+ // src/adapters/claude-code.ts
2197
+ var ClaudeCodeHookBaseSchema = z6.object({
2198
+ session_id: z6.string(),
2199
+ transcript_path: z6.string().optional(),
2200
+ cwd: z6.string().optional(),
2201
+ permission_mode: z6.enum([
2202
+ CLAUDE_PERMISSION_MODES.DEFAULT,
2203
+ CLAUDE_PERMISSION_MODES.PLAN,
2204
+ CLAUDE_PERMISSION_MODES.ACCEPT_EDITS,
2205
+ CLAUDE_PERMISSION_MODES.DONT_ASK,
2206
+ CLAUDE_PERMISSION_MODES.BYPASS_PERMISSIONS
2207
+ ]),
2208
+ hook_event_name: z6.string(),
2209
+ tool_name: z6.string().optional(),
2210
+ tool_input: z6.record(z6.string(), z6.unknown()).optional()
2211
+ });
2212
+ function handlePreToolUse(input) {
2213
+ const toolName = input.tool_name;
2214
+ if (toolName === CLAUDE_TOOL_NAMES.ASK_USER_QUESTION) {
2215
+ logger.info(
2216
+ { toolName },
2217
+ "Blocking AskUserQuestion - redirecting to request_user_input MCP tool"
2218
+ );
2219
+ return {
2220
+ type: "tool_deny",
2221
+ reason: `BLOCKED: Use the ${MCP_TOOL_NAMES.REQUEST_USER_INPUT} MCP tool instead for consistent browser UI. See the tool description for available parameters.`
2222
+ };
2223
+ }
2224
+ return { type: "passthrough" };
2225
+ }
2226
+ var ExitPlanModeToolInputSchema = z6.object({
2227
+ plan: z6.string()
2228
+ });
2229
+ function handlePermissionRequest(input) {
2230
+ const sessionId = input.session_id;
2231
+ const toolName = input.tool_name;
2232
+ if (toolName === CLAUDE_TOOL_NAMES.EXIT_PLAN_MODE) {
2233
+ logger.info(
2234
+ {
2235
+ toolInput: input.tool_input,
2236
+ toolInputKeys: input.tool_input ? Object.keys(input.tool_input) : []
2237
+ },
2238
+ "ExitPlanMode tool_input received"
2239
+ );
2240
+ const parsed = ExitPlanModeToolInputSchema.safeParse(input.tool_input);
2241
+ if (!parsed.success) {
2242
+ logger.warn(
2243
+ { parseError: parsed.error?.issues, toolInput: input.tool_input },
2244
+ "ExitPlanMode tool_input parse failed - no plan content"
2245
+ );
2246
+ return { type: "plan_exit", sessionId };
2247
+ }
2248
+ return {
2249
+ type: "plan_exit",
2250
+ sessionId,
2251
+ planContent: parsed.data.plan,
2252
+ metadata: {
2253
+ originSessionId: input.session_id,
2254
+ originTranscriptPath: input.transcript_path,
2255
+ originCwd: input.cwd
2256
+ }
2257
+ };
2258
+ }
2259
+ return { type: "passthrough" };
2260
+ }
2261
+ function handlePostToolUse(input) {
2262
+ const sessionId = input.session_id;
2263
+ const toolName = input.tool_name;
2264
+ if (toolName === CLAUDE_TOOL_NAMES.EXIT_PLAN_MODE) {
2265
+ return {
2266
+ type: "post_exit",
2267
+ sessionId,
2268
+ toolName
2269
+ };
2270
+ }
2271
+ return { type: "passthrough" };
2272
+ }
2273
+ var claudeCodeAdapter = {
2274
+ name: "claude-code",
2275
+ parseInput(stdin) {
2276
+ let input;
2277
+ try {
2278
+ const parsed = JSON.parse(stdin);
2279
+ input = ClaudeCodeHookBaseSchema.parse(parsed);
2280
+ } catch {
2281
+ return { type: "passthrough" };
2282
+ }
2283
+ if (input.hook_event_name === CLAUDE_HOOK_EVENTS.PRE_TOOL_USE) {
2284
+ return handlePreToolUse(input);
2285
+ }
2286
+ if (input.permission_mode !== CLAUDE_PERMISSION_MODES.PLAN) {
2287
+ return { type: "passthrough" };
2288
+ }
2289
+ if (input.hook_event_name === CLAUDE_HOOK_EVENTS.PERMISSION_REQUEST) {
2290
+ return handlePermissionRequest(input);
2291
+ }
2292
+ if (input.hook_event_name === CLAUDE_HOOK_EVENTS.POST_TOOL_USE) {
2293
+ return handlePostToolUse(input);
2294
+ }
2295
+ return { type: "passthrough" };
2296
+ },
2297
+ formatOutput(response) {
2298
+ if (response.hookType === "tool_deny") {
2299
+ return JSON.stringify({
2300
+ hookSpecificOutput: {
2301
+ hookEventName: CLAUDE_HOOK_EVENTS.PRE_TOOL_USE,
2302
+ permissionDecision: "deny",
2303
+ permissionDecisionReason: response.denyReason || "Tool call denied by hook"
2304
+ }
2305
+ });
2306
+ }
2307
+ if (response.hookType === "post_tool_use") {
2308
+ return JSON.stringify({
2309
+ hookSpecificOutput: {
2310
+ hookEventName: CLAUDE_HOOK_EVENTS.POST_TOOL_USE,
2311
+ additionalContext: response.additionalContext || ""
2312
+ }
2313
+ });
2314
+ }
2315
+ if (response.allow) {
2316
+ return JSON.stringify({
2317
+ hookSpecificOutput: {
2318
+ hookEventName: CLAUDE_HOOK_EVENTS.PERMISSION_REQUEST,
2319
+ decision: {
2320
+ behavior: "allow",
2321
+ message: response.message
2322
+ }
2323
+ }
2324
+ });
2325
+ }
2326
+ const message = response.feedback?.length ? formatFeedback(response.feedback) : response.message || "Changes requested";
2327
+ return JSON.stringify({
2328
+ hookSpecificOutput: {
2329
+ hookEventName: CLAUDE_HOOK_EVENTS.PERMISSION_REQUEST,
2330
+ decision: {
2331
+ behavior: "deny",
2332
+ message
2333
+ }
2334
+ }
2335
+ });
2336
+ }
2337
+ };
2338
+ function formatFeedback(feedback) {
2339
+ if (!feedback.length) {
2340
+ return "Changes requested. Check the plan for reviewer comments.";
2341
+ }
2342
+ const threads = feedback.map((f) => ({
2343
+ id: f.threadId,
2344
+ comments: f.comments.map((c) => ({
2345
+ id: c.author,
2346
+ userId: c.author,
2347
+ body: c.content,
2348
+ createdAt: c.createdAt
2349
+ })),
2350
+ selectedText: f.blockId ? `Block ${f.blockId}` : void 0
2351
+ }));
2352
+ const feedbackText = formatThreadsForLLM(threads, {
2353
+ includeResolved: false,
2354
+ selectedTextMaxLength: 100
2355
+ });
2356
+ return `Changes requested:
2357
+
2358
+ ${feedbackText}`;
2359
+ }
2360
+
2361
+ // ../../packages/shared/dist/registry-config.mjs
2362
+ var DEFAULT_REGISTRY_PORTS = [32191, 32192];
2363
+
2364
+ // ../../packages/shared/dist/index.mjs
2365
+ import { createHash, randomBytes } from "crypto";
2366
+ function computeHash(content) {
2367
+ return createHash("sha256").update(content).digest("hex").slice(0, 16);
2368
+ }
2369
+ function generateSessionToken() {
2370
+ return randomBytes(32).toString("base64url");
2371
+ }
2372
+ function hashSessionToken(token) {
2373
+ return createHash("sha256").update(token).digest("hex");
2374
+ }
2375
+ var APPROVAL_LONG_POLL_TIMEOUT_MS = 1800 * 1e3;
2376
+ var DEFAULT_TRPC_TIMEOUT_MS = 10 * 1e3;
2377
+
2378
+ // src/config/env/registry.ts
2379
+ import { homedir as homedir2 } from "os";
2380
+ import { join as join2 } from "path";
2381
+ import { z as z7 } from "zod";
2382
+ var schema2 = z7.object({
2383
+ REGISTRY_PORT: z7.string().optional().transform((val) => {
2384
+ if (!val) return DEFAULT_REGISTRY_PORTS;
2385
+ const port = Number.parseInt(val, 10);
2386
+ if (Number.isNaN(port)) {
2387
+ throw new Error(`REGISTRY_PORT must be a valid number, got: ${val}`);
2388
+ }
2389
+ return [port];
2390
+ }),
2391
+ SHIPYARD_STATE_DIR: z7.string().optional().default(() => join2(homedir2(), ".shipyard"))
2392
+ });
2393
+ var registryConfig = loadEnv(schema2);
2394
+
2395
+ // src/trpc-client.ts
2396
+ import { createTRPCClient, httpBatchLink } from "@trpc/client";
2397
+ var cachedClient = null;
2398
+ var cachedBaseUrl = null;
2399
+ function getTRPCClient(baseUrl, timeoutMs = DEFAULT_TRPC_TIMEOUT_MS) {
2400
+ if (timeoutMs !== DEFAULT_TRPC_TIMEOUT_MS) {
2401
+ return createTRPCClient({
2402
+ links: [
2403
+ httpBatchLink({
2404
+ url: `${baseUrl}/trpc`,
2405
+ fetch: (url, options) => {
2406
+ return fetch(url, {
2407
+ ...options,
2408
+ signal: AbortSignal.timeout(timeoutMs)
2409
+ });
2410
+ }
2411
+ })
2412
+ ]
2413
+ });
2414
+ }
2415
+ if (cachedClient && cachedBaseUrl === baseUrl) {
2416
+ return cachedClient;
2417
+ }
2418
+ cachedClient = createTRPCClient({
2419
+ links: [
2420
+ httpBatchLink({
2421
+ url: `${baseUrl}/trpc`,
2422
+ fetch: (url, options) => {
2423
+ return fetch(url, {
2424
+ ...options,
2425
+ signal: AbortSignal.timeout(timeoutMs)
2426
+ });
2427
+ }
2428
+ })
2429
+ ]
2430
+ });
2431
+ cachedBaseUrl = baseUrl;
2432
+ return cachedClient;
2433
+ }
2434
+
2435
+ // src/http-client.ts
2436
+ async function retryWithBackoff(fn, maxAttempts = 3, baseDelay = 1e3) {
2437
+ let lastError = null;
2438
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
2439
+ try {
2440
+ return await fn();
2441
+ } catch (err) {
2442
+ lastError = err;
2443
+ if (attempt < maxAttempts - 1) {
2444
+ const delay = attempt === 0 ? 0 : baseDelay * 2 ** (attempt - 1);
2445
+ logger.debug(
2446
+ { attempt: attempt + 1, maxAttempts, delay },
2447
+ "Registry health check failed, retrying..."
2448
+ );
2449
+ await new Promise((resolve) => setTimeout(resolve, delay));
2450
+ }
2451
+ }
2452
+ }
2453
+ throw lastError || new Error("Retry failed");
2454
+ }
2455
+ async function getRegistryUrl() {
2456
+ const ports = registryConfig.REGISTRY_PORT;
2457
+ for (const port of ports) {
2458
+ try {
2459
+ const url = `http://localhost:${port}`;
2460
+ await retryWithBackoff(
2461
+ async () => {
2462
+ const res = await fetch(`${url}/registry`, {
2463
+ signal: AbortSignal.timeout(5e3)
2464
+ });
2465
+ if (!res.ok) {
2466
+ throw new Error(`Registry responded with status ${res.status}`);
2467
+ }
2468
+ },
2469
+ 3,
2470
+ 1e3
2471
+ );
2472
+ logger.debug({ port }, "Found registry server (with retry)");
2473
+ return url;
2474
+ } catch (err) {
2475
+ const error = err;
2476
+ logger.debug(
2477
+ { port, error: error.message },
2478
+ "Failed to connect to registry port after retries"
2479
+ );
2480
+ }
2481
+ }
2482
+ logger.error(
2483
+ {
2484
+ ports,
2485
+ attemptsPerPort: 3,
2486
+ totalTimeout: "15s (5s per attempt * 3 attempts)"
2487
+ },
2488
+ "Registry server not reachable - check if `pnpm dev` is running"
2489
+ );
2490
+ return null;
2491
+ }
2492
+ async function createSession(request) {
2493
+ const baseUrl = await getRegistryUrl();
2494
+ if (!baseUrl) {
2495
+ throw new Error("Registry server not available");
2496
+ }
2497
+ const trpc = getTRPCClient(baseUrl);
2498
+ return trpc.hook.createSession.mutate(request);
2499
+ }
2500
+ async function updatePlanContent(planId, request) {
2501
+ const baseUrl = await getRegistryUrl();
2502
+ if (!baseUrl) {
2503
+ throw new Error("Registry server not available");
2504
+ }
2505
+ const trpc = getTRPCClient(baseUrl);
2506
+ return trpc.hook.updateContent.mutate({ planId, ...request });
2507
+ }
2508
+ async function getReviewStatus(planId) {
2509
+ const baseUrl = await getRegistryUrl();
2510
+ if (!baseUrl) {
2511
+ throw new Error("Registry server not available");
2512
+ }
2513
+ const trpc = getTRPCClient(baseUrl);
2514
+ return trpc.hook.getReviewStatus.query({ planId });
2515
+ }
2516
+ async function updatePresence(planId, request) {
2517
+ const baseUrl = await getRegistryUrl();
2518
+ if (!baseUrl) {
2519
+ throw new Error("Registry server not available");
2520
+ }
2521
+ const trpc = getTRPCClient(baseUrl);
2522
+ return trpc.hook.updatePresence.mutate({ planId, ...request });
2523
+ }
2524
+ async function setSessionToken(planId, sessionTokenHash) {
2525
+ const baseUrl = await getRegistryUrl();
2526
+ if (!baseUrl) {
2527
+ throw new Error("Registry server not available");
2528
+ }
2529
+ const trpc = getTRPCClient(baseUrl);
2530
+ return trpc.hook.setSessionToken.mutate({ planId, sessionTokenHash });
2531
+ }
2532
+ async function waitForApproval(planId, reviewRequestId) {
2533
+ const baseUrl = await getRegistryUrl();
2534
+ if (!baseUrl) {
2535
+ throw new Error("Registry server not available");
2536
+ }
2537
+ const trpc = getTRPCClient(baseUrl, APPROVAL_LONG_POLL_TIMEOUT_MS);
2538
+ return trpc.hook.waitForApproval.mutate({ planId, reviewRequestId });
2539
+ }
2540
+ async function getSessionContext(sessionId) {
2541
+ const baseUrl = await getRegistryUrl();
2542
+ if (!baseUrl) {
2543
+ throw new Error("Registry server not available");
2544
+ }
2545
+ const trpc = getTRPCClient(baseUrl);
2546
+ return trpc.hook.getSessionContext.query({ sessionId });
2547
+ }
2548
+ async function getDeliverableContext(planId, sessionToken) {
2549
+ const baseUrl = await getRegistryUrl();
2550
+ if (!baseUrl) {
2551
+ throw new Error("Registry server not available");
2552
+ }
2553
+ const trpc = getTRPCClient(baseUrl);
2554
+ return trpc.hook.getDeliverableContext.query({ planId, sessionToken });
2555
+ }
2556
+
2557
+ // src/core/plan-manager.ts
2558
+ var sessionToPlan = /* @__PURE__ */ new Map();
2559
+ async function createPlan(options) {
2560
+ const { sessionId, agentType, metadata } = options;
2561
+ logger.info({ sessionId, agentType }, "Creating plan for session");
2562
+ const response = await createSession({
2563
+ sessionId,
2564
+ agentType,
2565
+ metadata
2566
+ });
2567
+ sessionToPlan.set(sessionId, {
2568
+ planId: response.planId
2569
+ });
2570
+ await updatePresence(response.planId, {
2571
+ agentType,
2572
+ sessionId
2573
+ });
2574
+ logger.info({ sessionId, planId: response.planId, url: response.url }, "Plan created by server");
2575
+ return response;
2576
+ }
2577
+ async function updateContent(options) {
2578
+ const { sessionId, filePath, content, agentType } = options;
2579
+ let session = sessionToPlan.get(sessionId);
2580
+ if (!session) {
2581
+ try {
2582
+ const serverSession = await getSessionContext(sessionId);
2583
+ if (serverSession.found && serverSession.planId) {
2584
+ logger.info(
2585
+ { sessionId, planId: serverSession.planId },
2586
+ "Found existing session on server"
2587
+ );
2588
+ session = { planId: serverSession.planId };
2589
+ sessionToPlan.set(sessionId, session);
2590
+ }
2591
+ } catch (err) {
2592
+ logger.debug({ sessionId, err }, "Could not fetch session from server");
2593
+ }
2594
+ }
2595
+ if (!session) {
2596
+ logger.info({ sessionId, filePath }, "First write detected, creating plan");
2597
+ await createPlan({
2598
+ sessionId,
2599
+ agentType: agentType ?? DEFAULT_AGENT_TYPE,
2600
+ metadata: { filePath }
2601
+ });
2602
+ session = sessionToPlan.get(sessionId);
2603
+ if (!session) {
2604
+ logger.error({ sessionId }, "Failed to track session after plan creation");
2605
+ return false;
2606
+ }
2607
+ }
2608
+ const contentHash = computeHash(content);
2609
+ if (session.lastContentHash === contentHash) {
2610
+ logger.debug({ sessionId }, "Content unchanged, skipping update");
2611
+ return true;
2612
+ }
2613
+ logger.info({ sessionId, planId: session.planId, filePath }, "Updating plan content");
2614
+ await updatePlanContent(session.planId, {
2615
+ content,
2616
+ filePath
2617
+ });
2618
+ sessionToPlan.set(sessionId, {
2619
+ ...session,
2620
+ filePath,
2621
+ lastContentHash: contentHash
2622
+ });
2623
+ if (agentType) {
2624
+ await updatePresence(session.planId, {
2625
+ agentType,
2626
+ sessionId
2627
+ });
2628
+ }
2629
+ return true;
2630
+ }
2631
+
2632
+ // src/config/env/web.ts
2633
+ import { z as z8 } from "zod";
2634
+ var schema3 = z8.object({
2635
+ SHIPYARD_WEB_URL: z8.string().url().default("http://localhost:5173")
2636
+ });
2637
+ var webConfig = loadEnv(schema3);
2638
+
2639
+ // src/core/review-status.ts
2640
+ async function waitForReviewDecision(planId, _wsUrl) {
2641
+ logger.info({ planId }, "Waiting for approval via server endpoint");
2642
+ const result = await waitForApproval(planId, planId);
2643
+ logger.info({ planId, approved: result.approved }, "Received approval decision from server");
2644
+ return {
2645
+ approved: result.approved,
2646
+ feedback: result.feedback,
2647
+ deliverables: result.deliverables,
2648
+ reviewComment: result.reviewComment,
2649
+ reviewedBy: result.reviewedBy,
2650
+ status: result.status
2651
+ };
2652
+ }
2653
+ async function handleUpdatedPlanReview(sessionId, planId, planContent, _originMetadata) {
2654
+ logger.info(
2655
+ { planId, contentLength: planContent.length },
2656
+ "Plan content changed, triggering re-review"
2657
+ );
2658
+ logger.info({ planId }, "Syncing updated plan content");
2659
+ try {
2660
+ await updatePlanContent(planId, {
2661
+ content: planContent
2662
+ });
2663
+ } catch (err) {
2664
+ const error = err;
2665
+ if (error.message?.includes("404")) {
2666
+ logger.warn(
2667
+ { planId, sessionId },
2668
+ "Plan not found (404), creating new plan with updated content"
2669
+ );
2670
+ return await checkReviewStatus(sessionId, planContent, _originMetadata);
2671
+ }
2672
+ throw err;
2673
+ }
2674
+ const baseUrl = webConfig.SHIPYARD_WEB_URL;
2675
+ logger.info(
2676
+ { planId, url: `${baseUrl}/plan/${planId}` },
2677
+ "Content synced, browser already open. Waiting for server approval..."
2678
+ );
2679
+ const decision = await waitForReviewDecision(planId, "");
2680
+ logger.info({ planId, approved: decision.approved }, "Decision received via Y.Doc");
2681
+ if (decision.approved) {
2682
+ const sessionToken = generateSessionToken();
2683
+ const sessionTokenHash = hashSessionToken(sessionToken);
2684
+ logger.info({ planId }, "Generating new session token for re-approved plan");
2685
+ try {
2686
+ const tokenResult = await setSessionToken(planId, sessionTokenHash);
2687
+ const url = tokenResult.url;
2688
+ const deliverableCount = (decision.deliverables ?? []).length;
2689
+ logger.info(
2690
+ { planId, url, deliverableCount },
2691
+ "Session token set and stored by server with updated content hash"
2692
+ );
2693
+ const reviewFeedback = decision.reviewComment ? `
2694
+
2695
+ Reviewer comment: ${decision.reviewComment}` : "";
2696
+ return {
2697
+ allow: true,
2698
+ message: `Plan re-approved with updates! You have ${deliverableCount} deliverable${deliverableCount === 1 ? "" : "s"}. Use add_artifact(filePath, deliverableId) to upload proof-of-work.${reviewFeedback}`,
2699
+ planId,
2700
+ sessionToken,
2701
+ url
2702
+ };
2703
+ } catch (err) {
2704
+ logger.error({ err, planId }, "Failed to set session token, but plan was approved");
2705
+ return {
2706
+ allow: true,
2707
+ message: "Updated plan approved (session token unavailable)",
2708
+ planId
2709
+ };
2710
+ }
2711
+ }
2712
+ logger.debug({ planId }, "Changes requested - server will manage state cleanup");
2713
+ return {
2714
+ allow: false,
2715
+ message: decision.reviewComment || "Changes requested",
2716
+ planId
2717
+ };
2718
+ }
2719
+ async function checkReviewStatus(sessionId, planContent, originMetadata) {
2720
+ const state = await getSessionContext(sessionId);
2721
+ let planId;
2722
+ if (!state.found && planContent) {
2723
+ logger.info(
2724
+ { sessionId, contentLength: planContent.length, hasState: !!state },
2725
+ "Creating plan from ExitPlanMode (blocking mode)"
2726
+ );
2727
+ const result = await createPlan({
2728
+ sessionId,
2729
+ agentType: DEFAULT_AGENT_TYPE,
2730
+ metadata: {
2731
+ source: "ExitPlanMode",
2732
+ ...originMetadata
2733
+ }
2734
+ });
2735
+ planId = result.planId;
2736
+ logger.info({ planId }, "Syncing plan content");
2737
+ await updatePlanContent(planId, {
2738
+ content: planContent
2739
+ });
2740
+ logger.info(
2741
+ { planId, url: result.url },
2742
+ "Plan created and synced, browser opened. Waiting for server approval..."
2743
+ );
2744
+ const decision = await waitForReviewDecision(planId, "");
2745
+ logger.info({ planId, approved: decision.approved }, "Decision received via Y.Doc");
2746
+ if (decision.approved) {
2747
+ const sessionToken = generateSessionToken();
2748
+ const sessionTokenHash = hashSessionToken(sessionToken);
2749
+ logger.info({ planId }, "Generating session token for approved plan");
2750
+ try {
2751
+ const tokenResult = await setSessionToken(planId, sessionTokenHash);
2752
+ const url = tokenResult.url;
2753
+ const deliverableCount = (decision.deliverables ?? []).length;
2754
+ logger.info(
2755
+ { planId, url, deliverableCount },
2756
+ "Session token set and stored by server with deliverables"
2757
+ );
2758
+ const reviewFeedback = decision.reviewComment ? `
2759
+
2760
+ Reviewer comment: ${decision.reviewComment}` : "";
2761
+ return {
2762
+ allow: true,
2763
+ message: `Plan approved! You have ${deliverableCount} deliverable${deliverableCount === 1 ? "" : "s"}. Use add_artifact(filePath, deliverableId) to upload proof-of-work.${reviewFeedback}`,
2764
+ planId,
2765
+ sessionToken,
2766
+ url
2767
+ };
2768
+ } catch (err) {
2769
+ logger.error({ err, planId }, "Failed to set session token, approving without it");
2770
+ return {
2771
+ allow: true,
2772
+ message: "Plan approved, but session token unavailable. You may need to refresh the plan in the browser. Check ~/.shipyard/server-debug.log for details.",
2773
+ planId
2774
+ };
2775
+ }
2776
+ }
2777
+ logger.debug({ sessionId }, "Changes requested - server will manage state cleanup");
2778
+ return {
2779
+ allow: false,
2780
+ message: decision.reviewComment || "Changes requested",
2781
+ planId
2782
+ };
2783
+ }
2784
+ if (!state.found) {
2785
+ logger.info({ sessionId }, "No session state or plan content, allowing exit");
2786
+ return { allow: true };
2787
+ }
2788
+ if ((!state || !state.planId) && planContent) {
2789
+ logger.error(
2790
+ { sessionId, hasPlanContent: !!planContent, hasState: !!state, statePlanId: state?.planId },
2791
+ "Unreachable state: plan content exists but no session state"
2792
+ );
2793
+ return {
2794
+ allow: false,
2795
+ message: "Internal error: Plan content found but session state missing. Check ~/.shipyard/hook-debug.log and report this issue."
2796
+ };
2797
+ }
2798
+ if (!state.planId) {
2799
+ throw new Error("Unreachable: state.planId should exist at this point");
2800
+ }
2801
+ planId = state.planId;
2802
+ if (planContent) {
2803
+ logger.info({ planId }, "Plan content provided, triggering re-review");
2804
+ return await handleUpdatedPlanReview(sessionId, planId, planContent, originMetadata);
2805
+ }
2806
+ logger.info({ sessionId, planId }, "Checking review status");
2807
+ let status;
2808
+ try {
2809
+ status = await getReviewStatus(planId);
2810
+ } catch (err) {
2811
+ logger.warn({ err, planId }, "Failed to get review status, blocking exit");
2812
+ return {
2813
+ allow: false,
2814
+ message: "Cannot verify plan approval status. Ensure the Shipyard MCP server is running. Check ~/.shipyard/server-debug.log for details.",
2815
+ planId
2816
+ };
2817
+ }
2818
+ logger.info({ sessionId, planId, status: status.status }, "Review status retrieved");
2819
+ const baseUrl = webConfig.SHIPYARD_WEB_URL;
2820
+ switch (status.status) {
2821
+ case "changes_requested":
2822
+ return {
2823
+ allow: false,
2824
+ message: formatFeedbackMessage(status.feedback),
2825
+ feedback: status.feedback,
2826
+ planId
2827
+ };
2828
+ case "pending_review":
2829
+ return {
2830
+ allow: false,
2831
+ message: `Plan is pending review.
2832
+
2833
+ Open: ${baseUrl}/plan/${planId}`,
2834
+ planId
2835
+ };
2836
+ case "draft":
2837
+ return {
2838
+ allow: false,
2839
+ message: `Plan is still in draft.
2840
+
2841
+ Submit for review at: ${baseUrl}/plan/${planId}`,
2842
+ planId
2843
+ };
2844
+ case "in_progress":
2845
+ return {
2846
+ allow: true,
2847
+ message: "Plan approved. Work is in progress. Use add_artifact(filePath, deliverableId) to upload deliverable proofs.",
2848
+ planId
2849
+ };
2850
+ case "completed":
2851
+ return {
2852
+ allow: true,
2853
+ message: `Task completed by ${status.completedBy}`,
2854
+ planId
2855
+ };
2856
+ default: {
2857
+ assertNever(status);
2858
+ }
2859
+ }
2860
+ }
2861
+ function formatFeedbackMessage(feedback) {
2862
+ if (!feedback?.length) {
2863
+ return "Changes requested. Check the plan for reviewer comments.";
2864
+ }
2865
+ const lines = feedback.map((f) => {
2866
+ const blockInfo = f.blockId ? `Block ${f.blockId}` : "General";
2867
+ const comments = f.comments.map((c) => ` - ${c.author}: ${c.content}`).join("\n");
2868
+ return `${blockInfo}:
2869
+ ${comments}`;
2870
+ });
2871
+ return `Changes requested:
2872
+
2873
+ ${lines.join("\n\n")}`;
2874
+ }
2875
+
2876
+ // src/index.ts
2877
+ function getAdapter() {
2878
+ return claudeCodeAdapter;
2879
+ }
2880
+ async function handlePlanStart(event) {
2881
+ try {
2882
+ const result = await createPlan({
2883
+ sessionId: event.sessionId,
2884
+ agentType: DEFAULT_AGENT_TYPE,
2885
+ metadata: event.metadata
2886
+ });
2887
+ return {
2888
+ allow: true,
2889
+ message: `Plan created at ${result.url}. Write your plan, mark deliverables with {#deliverable}, then exit plan mode to await approval.`,
2890
+ planId: result.planId,
2891
+ url: result.url
2892
+ };
2893
+ } catch (err) {
2894
+ logger.error({ err }, "Failed to create plan");
2895
+ return { allow: true };
2896
+ }
2897
+ }
2898
+ async function handleContentUpdate(event) {
2899
+ try {
2900
+ await updateContent({
2901
+ sessionId: event.sessionId,
2902
+ filePath: event.filePath,
2903
+ content: event.content,
2904
+ agentType: DEFAULT_AGENT_TYPE
2905
+ });
2906
+ return { allow: true };
2907
+ } catch (err) {
2908
+ logger.error({ err }, "Failed to update content");
2909
+ throw err;
2910
+ }
2911
+ }
2912
+ async function handlePlanExit(event) {
2913
+ try {
2914
+ return await checkReviewStatus(event.sessionId, event.planContent, event.metadata);
2915
+ } catch (err) {
2916
+ const error = err;
2917
+ logger.error(
2918
+ { err: error, message: error.message, code: error.code },
2919
+ "Failed to check review status"
2920
+ );
2921
+ const isConnectionError = error.code === "ECONNREFUSED" || error.code === "ECONNRESET" || error.code === "ETIMEDOUT" || error.code === "ENOTFOUND" || error.message?.includes("connect") || error.message?.includes("timeout") || error.message?.includes("WebSocket") || error.message?.includes("not available");
2922
+ const message = isConnectionError ? "Cannot connect to Shipyard server. Ensure the Shipyard MCP server is running. Check ~/.shipyard/hook-debug.log for details." : `Review system error: ${error.message}. Check ~/.shipyard/hook-debug.log for details.`;
2923
+ return {
2924
+ allow: false,
2925
+ message
2926
+ };
2927
+ }
2928
+ }
2929
+ async function handlePostExit(event) {
2930
+ try {
2931
+ const sessionContext = await getSessionContext(event.sessionId);
2932
+ if (!sessionContext.found) {
2933
+ logger.debug({ sessionId: event.sessionId }, "No session found in registry");
2934
+ return {
2935
+ allow: true,
2936
+ hookType: "post_tool_use",
2937
+ additionalContext: ""
2938
+ };
2939
+ }
2940
+ const { planId, sessionToken, url } = sessionContext;
2941
+ logger.info(
2942
+ { planId, sessionId: event.sessionId },
2943
+ "Injecting session context via PostToolUse"
2944
+ );
2945
+ const result = await getDeliverableContext(planId, sessionToken);
2946
+ return {
2947
+ allow: true,
2948
+ hookType: "post_tool_use",
2949
+ additionalContext: result.context,
2950
+ planId,
2951
+ sessionToken,
2952
+ url
2953
+ };
2954
+ } catch (err) {
2955
+ logger.error({ err, sessionId: event.sessionId }, "Failed to get session context from server");
2956
+ return {
2957
+ allow: true,
2958
+ hookType: "post_tool_use",
2959
+ additionalContext: ""
2960
+ };
2961
+ }
2962
+ }
2963
+ async function processEvent(_adapter, event) {
2964
+ switch (event.type) {
2965
+ case "plan_start":
2966
+ return handlePlanStart(event);
2967
+ case "content_update":
2968
+ return handleContentUpdate(event);
2969
+ case "plan_exit":
2970
+ return handlePlanExit(event);
2971
+ case "post_exit":
2972
+ return handlePostExit(event);
2973
+ case "disconnect":
2974
+ return { allow: true };
2975
+ case "tool_deny":
2976
+ return {
2977
+ allow: false,
2978
+ hookType: "tool_deny",
2979
+ denyReason: event.reason
2980
+ };
2981
+ case "passthrough":
2982
+ return { allow: true };
2983
+ default: {
2984
+ const _exhaustive = event;
2985
+ logger.warn({ event: _exhaustive }, "Unknown event type");
2986
+ return { allow: true };
2987
+ }
2988
+ }
2989
+ }
2990
+ async function readStdin() {
2991
+ const chunks = [];
2992
+ for await (const chunk of process.stdin) {
2993
+ chunks.push(chunk);
2994
+ }
2995
+ return Buffer.concat(chunks).toString("utf-8");
2996
+ }
2997
+ function outputSessionStartContext() {
2998
+ const context = `[SHIPYARD] Collaborative planning with human review & proof-of-work tracking.
2999
+
3000
+ IMPORTANT: Use native plan mode (Shift+Tab) to create plans. The hook handles everything automatically.
3001
+
3002
+ ## What are Deliverables?
3003
+
3004
+ Deliverables are measurable outcomes you can prove with artifacts (screenshots, videos, test results).
3005
+
3006
+ Good deliverables (provable):
3007
+ \`\`\`
3008
+ - [ ] Screenshot of working login page {#deliverable}
3009
+ - [ ] Video showing feature in action {#deliverable}
3010
+ - [ ] Test results showing all tests pass {#deliverable}
3011
+ \`\`\`
3012
+
3013
+ Bad deliverables (implementation details, not provable):
3014
+ \`\`\`
3015
+ - [ ] Implement getUserMedia API \u2190 This is a task, not a deliverable
3016
+ - [ ] Add error handling \u2190 Can't prove this with an artifact
3017
+ \`\`\`
3018
+
3019
+ ## Workflow
3020
+
3021
+ 1. Enter plan mode (Shift+Tab) \u2192 Browser opens with live plan
3022
+ 2. Write plan with {#deliverable} markers for provable outcomes
3023
+ 3. Exit plan mode \u2192 Hook BLOCKS until human approves
3024
+ 4. On approval \u2192 You receive planId, sessionToken, and deliverable IDs
3025
+ 5. Do work \u2192 Take screenshots/videos as you go
3026
+ 6. \`add_artifact(filePath, deliverableId)\` for each deliverable
3027
+ 7. When all deliverables fulfilled \u2192 Auto-completes with snapshot URL
3028
+
3029
+ ## After Approval
3030
+
3031
+ You only need ONE tool: \`add_artifact\`
3032
+
3033
+ When the last deliverable gets an artifact, the task auto-completes and returns a snapshot URL for your PR.`;
3034
+ const hookOutput = {
3035
+ hookSpecificOutput: {
3036
+ hookEventName: "SessionStart",
3037
+ additionalContext: context
3038
+ }
3039
+ };
3040
+ console.log(JSON.stringify(hookOutput));
3041
+ }
3042
+ async function main() {
3043
+ try {
3044
+ if (process.argv.includes("--context")) {
3045
+ outputSessionStartContext();
3046
+ return;
3047
+ }
3048
+ const stdin = await readStdin();
3049
+ if (!stdin.trim()) {
3050
+ logger.debug("Empty stdin, passing through");
3051
+ console.log(JSON.stringify({ continue: true }));
3052
+ return;
3053
+ }
3054
+ const adapter = getAdapter();
3055
+ const event = adapter.parseInput(stdin);
3056
+ logger.debug({ event }, "Parsed event");
3057
+ const response = await processEvent(adapter, event);
3058
+ const output = adapter.formatOutput(response);
3059
+ logger.debug({ output }, "Sending hook response");
3060
+ console.log(output);
3061
+ process.exit(0);
3062
+ } catch (err) {
3063
+ logger.error({ err }, "Hook error, failing closed");
3064
+ console.log(
3065
+ JSON.stringify({
3066
+ hookSpecificOutput: {
3067
+ hookEventName: "PermissionRequest",
3068
+ decision: {
3069
+ behavior: "deny",
3070
+ message: `Hook error: ${err.message}. Check ~/.shipyard/hook-debug.log for details.`
3071
+ }
3072
+ }
3073
+ })
3074
+ );
3075
+ process.exit(0);
3076
+ }
3077
+ }
3078
+ main();