camox 0.74.1 → 0.76.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/core/lib/artifactRuntime.js +4 -2
  2. package/dist/features/provider/AuthenticatedCamoxProvider.js +75 -63
  3. package/dist/features/renderer/RendererFrames.js +47 -41
  4. package/dist/features/routes/pageRuntime.d.ts +6 -4
  5. package/dist/features/routes/pageRuntime.js +5 -1
  6. package/dist/features/studio/components/ChatWidget.js +137 -121
  7. package/dist/features/studio/components/ClearThread.js +121 -0
  8. package/dist/features/studio/components/DeleteDraftDialog.js +67 -65
  9. package/dist/features/studio/components/DraftBar.js +60 -49
  10. package/dist/features/studio/components/DraftNotices.js +149 -0
  11. package/dist/features/studio/components/DraftsControl.js +217 -180
  12. package/dist/features/studio/components/DraftsSheet.js +387 -0
  13. package/dist/features/studio/components/PublishedTab.js +511 -0
  14. package/dist/features/studio/components/ReviewDraftDialog.js +104 -89
  15. package/dist/features/studio/components/SheetTable.js +46 -0
  16. package/dist/features/studio/components/Specialists.js +1 -1
  17. package/dist/features/studio/components/ThreadMessages.js +376 -171
  18. package/dist/features/studio/draftLabel.js +15 -1
  19. package/dist/features/studio/draftNotice.js +1 -0
  20. package/dist/features/studio/studioStore.js +5 -5
  21. package/dist/features/studio/useArchiveDraft.js +60 -0
  22. package/dist/features/studio/useRestoreDraft.js +70 -0
  23. package/dist/features/studio/viewSwitch.js +19 -11
  24. package/dist/lib/draft-scope.d.ts +1 -1
  25. package/dist/lib/draft-scope.js +6 -3
  26. package/dist/lib/queries.js +12 -1
  27. package/dist/lib/studio-reads.js +22 -0
  28. package/dist/lib/use-project-room.js +19 -13
  29. package/dist/lib/use-thread.js +1 -1
  30. package/dist/package.js +1 -1
  31. package/dist/studio.css +1 -1
  32. package/package.json +4 -4
@@ -4,6 +4,9 @@ import { ThreadMarkdown } from "./ThreadMarkdown.js";
4
4
  import { c } from "react/compiler-runtime";
5
5
  import * as React from "react";
6
6
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
+ import { Button } from "@camox/ui/button";
8
+ import { X } from "lucide-react";
9
+ import { Dialog, DialogContent, DialogTitle } from "@camox/ui/dialog";
7
10
  import { Avatar, AvatarFallback, AvatarImage } from "@camox/ui/avatar";
8
11
  import { Bubble, BubbleContent } from "@camox/ui/bubble";
9
12
  import { Message, MessageAvatar, MessageContent, MessageHeader } from "@camox/ui/message";
@@ -18,12 +21,12 @@ import { MessageScroller, MessageScrollerButton, MessageScrollerContent, Message
18
21
  * agent does, never how: thinking, looking around, making changes, building, fixing the build,
19
22
  * or starting a draft. Each editor's message shows its
20
23
  * sender's avatar, without their name. A Live turn handed off to a draft ends on the draft's
21
- * card, which `onOpenDraft` opens, and the draft's thread shows the hand-off's Brief collapsed
22
- * under the editor's messages. The thread keeps its end in view, unless the editor scrolls up.
24
+ * card, which `onOpenDraft` opens, or `onRestoreDraft` restores while the draft is archived, and
25
+ * the draft's thread shows the hand-off's Brief collapsed under the editor's messages. The thread keeps its end in view, unless the editor scrolls up.
23
26
  */
24
27
  function ThreadMessages(t0) {
25
- const $ = c(20);
26
- const { view, sending: t1, onOpenDraft } = t0;
28
+ const $ = c(21);
29
+ const { view, sending: t1, onOpenDraft, onRestoreDraft } = t0;
27
30
  const sending = t1 === void 0 ? false : t1;
28
31
  const working = view.running || sending;
29
32
  const empty = view.messages.length === 0 && !working;
@@ -57,14 +60,15 @@ function ThreadMessages(t0) {
57
60
  return t4;
58
61
  }
59
62
  let t2;
60
- if ($[5] !== onOpenDraft || $[6] !== squareling || $[7] !== view || $[8] !== working) {
63
+ if ($[5] !== onOpenDraft || $[6] !== onRestoreDraft || $[7] !== squareling || $[8] !== view || $[9] !== working) {
61
64
  t2 = view.messages.map((message, index) => /* @__PURE__ */ jsxs(MessageScrollerItem, {
62
65
  messageId: message.id,
63
66
  scrollAnchor: message.from === "editor",
64
67
  className: "flex flex-col gap-4",
65
68
  children: [/* @__PURE__ */ jsx(ThreadMessageRow, {
66
69
  message,
67
- onOpenDraft
70
+ onOpenDraft,
71
+ onRestoreDraft
68
72
  }), index === view.messages.length - 1 && /* @__PURE__ */ jsx(AgentPresence, {
69
73
  view,
70
74
  working,
@@ -72,40 +76,41 @@ function ThreadMessages(t0) {
72
76
  })]
73
77
  }, message.id));
74
78
  $[5] = onOpenDraft;
75
- $[6] = squareling;
76
- $[7] = view;
77
- $[8] = working;
78
- $[9] = t2;
79
- } else t2 = $[9];
79
+ $[6] = onRestoreDraft;
80
+ $[7] = squareling;
81
+ $[8] = view;
82
+ $[9] = working;
83
+ $[10] = t2;
84
+ } else t2 = $[10];
80
85
  let t3;
81
- if ($[10] !== squareling || $[11] !== view || $[12] !== working) {
86
+ if ($[11] !== squareling || $[12] !== view || $[13] !== working) {
82
87
  t3 = view.messages.length === 0 && /* @__PURE__ */ jsx(AgentPresence, {
83
88
  view,
84
89
  working,
85
90
  squareling
86
91
  });
87
- $[10] = squareling;
88
- $[11] = view;
89
- $[12] = working;
90
- $[13] = t3;
91
- } else t3 = $[13];
92
+ $[11] = squareling;
93
+ $[12] = view;
94
+ $[13] = working;
95
+ $[14] = t3;
96
+ } else t3 = $[14];
92
97
  let t4;
93
- if ($[14] !== t2 || $[15] !== t3) {
98
+ if ($[15] !== t2 || $[16] !== t3) {
94
99
  t4 = /* @__PURE__ */ jsx(MessageScrollerViewport, { children: /* @__PURE__ */ jsxs(MessageScrollerContent, {
95
100
  className: "flex flex-col gap-4 px-2 py-3",
96
101
  children: [t2, t3]
97
102
  }) });
98
- $[14] = t2;
99
- $[15] = t3;
100
- $[16] = t4;
101
- } else t4 = $[16];
103
+ $[15] = t2;
104
+ $[16] = t3;
105
+ $[17] = t4;
106
+ } else t4 = $[17];
102
107
  let t5;
103
- if ($[17] === Symbol.for("react.memo_cache_sentinel")) {
108
+ if ($[18] === Symbol.for("react.memo_cache_sentinel")) {
104
109
  t5 = /* @__PURE__ */ jsx(MessageScrollerButton, {});
105
- $[17] = t5;
106
- } else t5 = $[17];
110
+ $[18] = t5;
111
+ } else t5 = $[18];
107
112
  let t6;
108
- if ($[18] !== t4) {
113
+ if ($[19] !== t4) {
109
114
  t6 = /* @__PURE__ */ jsx(MessageScrollerProvider, {
110
115
  autoScroll: true,
111
116
  children: /* @__PURE__ */ jsxs(MessageScroller, {
@@ -113,9 +118,9 @@ function ThreadMessages(t0) {
113
118
  children: [t4, t5]
114
119
  })
115
120
  });
116
- $[18] = t4;
117
- $[19] = t6;
118
- } else t6 = $[19];
121
+ $[19] = t4;
122
+ $[20] = t6;
123
+ } else t6 = $[20];
119
124
  return t6;
120
125
  }
121
126
  /** How long the greeting's squareling takes to reach the end of the thread, in ms. */
@@ -298,111 +303,113 @@ const PUSH_OUTCOMES = {
298
303
  notPreviewed: "Built, but the preview can’t show it."
299
304
  };
300
305
  function ThreadMessageRow(t0) {
301
- const $ = c(50);
302
- const { message, onOpenDraft } = t0;
306
+ const $ = c(57);
307
+ const { message, onOpenDraft, onRestoreDraft } = t0;
303
308
  if (message.from === "draft") {
304
309
  let t1;
305
- if ($[0] !== message || $[1] !== onOpenDraft) {
310
+ if ($[0] !== message || $[1] !== onOpenDraft || $[2] !== onRestoreDraft) {
306
311
  t1 = /* @__PURE__ */ jsx(Message, { children: /* @__PURE__ */ jsx(MessageContent, { children: /* @__PURE__ */ jsx(DraftCard, {
307
312
  message,
308
- onOpenDraft
313
+ onOpenDraft,
314
+ onRestoreDraft
309
315
  }) }) });
310
316
  $[0] = message;
311
317
  $[1] = onOpenDraft;
312
- $[2] = t1;
313
- } else t1 = $[2];
318
+ $[2] = onRestoreDraft;
319
+ $[3] = t1;
320
+ } else t1 = $[3];
314
321
  return t1;
315
322
  }
316
323
  if (message.from === "stopped" || message.from === "failed") {
317
324
  const t1 = message.from === "stopped" ? `Stopped by ${message.sender.name}` : "Camox couldn’t finish this. Send your message again to retry.";
318
325
  let t2;
319
- if ($[3] !== t1) {
326
+ if ($[4] !== t1) {
320
327
  t2 = /* @__PURE__ */ jsx(Message, { children: /* @__PURE__ */ jsx(MessageContent, { children: /* @__PURE__ */ jsx("p", {
321
328
  className: "text-muted-foreground text-sm",
322
329
  children: t1
323
330
  }) }) });
324
- $[3] = t1;
325
- $[4] = t2;
326
- } else t2 = $[4];
331
+ $[4] = t1;
332
+ $[5] = t2;
333
+ } else t2 = $[5];
327
334
  return t2;
328
335
  }
329
336
  if (message.from === "agent") {
330
337
  let t1;
331
- if ($[5] !== message.text) {
338
+ if ($[6] !== message.text) {
332
339
  t1 = /* @__PURE__ */ jsx(Message, { children: /* @__PURE__ */ jsx(MessageContent, { children: /* @__PURE__ */ jsx(ThreadMarkdown, { text: message.text }) }) });
333
- $[5] = message.text;
334
- $[6] = t1;
335
- } else t1 = $[6];
340
+ $[6] = message.text;
341
+ $[7] = t1;
342
+ } else t1 = $[7];
336
343
  return t1;
337
344
  }
338
345
  if (message.from === "push") {
339
346
  const commits = message.subjects.length;
340
347
  let t1;
341
- if ($[7] !== message.sender) {
348
+ if ($[8] !== message.sender) {
342
349
  t1 = /* @__PURE__ */ jsx(MessageAvatar, { children: /* @__PURE__ */ jsx(SenderAvatar, { sender: message.sender }) });
343
- $[7] = message.sender;
344
- $[8] = t1;
345
- } else t1 = $[8];
350
+ $[8] = message.sender;
351
+ $[9] = t1;
352
+ } else t1 = $[9];
346
353
  const t2 = `${message.sender.name} pushed ${commits} ${commits === 1 ? "commit" : "commits"}`;
347
354
  let t3;
348
- if ($[9] !== t2) {
355
+ if ($[10] !== t2) {
349
356
  t3 = /* @__PURE__ */ jsx(MessageHeader, {
350
357
  className: "text-muted-foreground text-xs",
351
358
  children: t2
352
359
  });
353
- $[9] = t2;
354
- $[10] = t3;
355
- } else t3 = $[10];
360
+ $[10] = t2;
361
+ $[11] = t3;
362
+ } else t3 = $[11];
356
363
  let t4;
357
- if ($[11] !== message.subjects) {
364
+ if ($[12] !== message.subjects) {
358
365
  t4 = message.subjects.map(_temp);
359
- $[11] = message.subjects;
360
- $[12] = t4;
361
- } else t4 = $[12];
366
+ $[12] = message.subjects;
367
+ $[13] = t4;
368
+ } else t4 = $[13];
362
369
  let t5;
363
- if ($[13] !== t4) {
370
+ if ($[14] !== t4) {
364
371
  t5 = /* @__PURE__ */ jsx("ul", {
365
372
  className: "flex flex-col gap-0.5",
366
373
  children: t4
367
374
  });
368
- $[13] = t4;
369
- $[14] = t5;
370
- } else t5 = $[14];
375
+ $[14] = t4;
376
+ $[15] = t5;
377
+ } else t5 = $[15];
371
378
  const t6 = PUSH_OUTCOMES[message.outcome];
372
379
  let t7;
373
- if ($[15] !== t6) {
380
+ if ($[16] !== t6) {
374
381
  t7 = /* @__PURE__ */ jsx("span", {
375
382
  className: "text-muted-foreground text-xs",
376
383
  children: t6
377
384
  });
378
- $[15] = t6;
379
- $[16] = t7;
380
- } else t7 = $[16];
385
+ $[16] = t6;
386
+ $[17] = t7;
387
+ } else t7 = $[17];
381
388
  let t8;
382
- if ($[17] !== t5 || $[18] !== t7) {
389
+ if ($[18] !== t5 || $[19] !== t7) {
383
390
  t8 = /* @__PURE__ */ jsxs("div", {
384
391
  "data-thread-push": true,
385
392
  className: DRAFT_CARD_CLASSES,
386
393
  children: [t5, t7]
387
394
  });
388
- $[17] = t5;
389
- $[18] = t7;
390
- $[19] = t8;
391
- } else t8 = $[19];
395
+ $[18] = t5;
396
+ $[19] = t7;
397
+ $[20] = t8;
398
+ } else t8 = $[20];
392
399
  let t9;
393
- if ($[20] !== t3 || $[21] !== t8) {
400
+ if ($[21] !== t3 || $[22] !== t8) {
394
401
  t9 = /* @__PURE__ */ jsxs(MessageContent, { children: [t3, t8] });
395
- $[20] = t3;
396
- $[21] = t8;
397
- $[22] = t9;
398
- } else t9 = $[22];
402
+ $[21] = t3;
403
+ $[22] = t8;
404
+ $[23] = t9;
405
+ } else t9 = $[23];
399
406
  let t10;
400
- if ($[23] !== t1 || $[24] !== t9) {
407
+ if ($[24] !== t1 || $[25] !== t9) {
401
408
  t10 = /* @__PURE__ */ jsxs(Message, { children: [t1, t9] });
402
- $[23] = t1;
403
- $[24] = t9;
404
- $[25] = t10;
405
- } else t10 = $[25];
409
+ $[24] = t1;
410
+ $[25] = t9;
411
+ $[26] = t10;
412
+ } else t10 = $[26];
406
413
  return t10;
407
414
  }
408
415
  if (message.from === "connectedAgent") {
@@ -412,112 +419,131 @@ function ThreadMessageRow(t0) {
412
419
  const t1 = `${sender} added context`;
413
420
  const t2 = client.verified ? void 0 : client.name;
414
421
  let t3;
415
- if ($[26] !== message.text || $[27] !== t1 || $[28] !== t2) {
416
- t3 = /* @__PURE__ */ jsx(Message, { children: /* @__PURE__ */ jsx(MessageContent, { children: /* @__PURE__ */ jsx(CollapsedNote, {
422
+ if ($[27] !== message.attachments) {
423
+ t3 = message.attachments && /* @__PURE__ */ jsx(AttachmentThumbnails, { attachments: message.attachments });
424
+ $[27] = message.attachments;
425
+ $[28] = t3;
426
+ } else t3 = $[28];
427
+ let t4;
428
+ if ($[29] !== message.text || $[30] !== t1 || $[31] !== t2 || $[32] !== t3) {
429
+ t4 = /* @__PURE__ */ jsx(Message, { children: /* @__PURE__ */ jsx(MessageContent, { children: /* @__PURE__ */ jsx(CollapsedNote, {
417
430
  label: t1,
418
431
  hideLabel: "Hide the context",
419
432
  title: t2,
420
- text: message.text
433
+ text: message.text,
434
+ children: t3
421
435
  }) }) });
422
- $[26] = message.text;
423
- $[27] = t1;
424
- $[28] = t2;
425
- $[29] = t3;
426
- } else t3 = $[29];
427
- return t3;
436
+ $[29] = message.text;
437
+ $[30] = t1;
438
+ $[31] = t2;
439
+ $[32] = t3;
440
+ $[33] = t4;
441
+ } else t4 = $[33];
442
+ return t4;
428
443
  }
429
444
  const t1 = client.verified ? void 0 : client.name;
430
445
  let t2;
431
- if ($[30] !== sender || $[31] !== t1) {
446
+ if ($[34] !== sender || $[35] !== t1) {
432
447
  t2 = /* @__PURE__ */ jsx(MessageHeader, {
433
448
  className: "text-muted-foreground text-xs",
434
449
  title: t1,
435
450
  children: sender
436
451
  });
437
- $[30] = sender;
438
- $[31] = t1;
439
- $[32] = t2;
440
- } else t2 = $[32];
452
+ $[34] = sender;
453
+ $[35] = t1;
454
+ $[36] = t2;
455
+ } else t2 = $[36];
441
456
  let t3;
442
- if ($[33] !== message.text) {
457
+ if ($[37] !== message.text) {
443
458
  t3 = /* @__PURE__ */ jsx(Bubble, {
444
459
  variant: "muted",
445
460
  className: "max-w-full",
446
461
  children: /* @__PURE__ */ jsx(BubbleContent, { children: /* @__PURE__ */ jsx(CroppedText, { text: message.text }) })
447
462
  });
448
- $[33] = message.text;
449
- $[34] = t3;
450
- } else t3 = $[34];
463
+ $[37] = message.text;
464
+ $[38] = t3;
465
+ } else t3 = $[38];
451
466
  let t4;
452
- if ($[35] !== t2 || $[36] !== t3) {
453
- t4 = /* @__PURE__ */ jsx(Message, { children: /* @__PURE__ */ jsxs(MessageContent, { children: [t2, t3] }) });
454
- $[35] = t2;
455
- $[36] = t3;
456
- $[37] = t4;
457
- } else t4 = $[37];
458
- return t4;
467
+ if ($[39] !== message.attachments) {
468
+ t4 = message.attachments && /* @__PURE__ */ jsx(AttachmentThumbnails, { attachments: message.attachments });
469
+ $[39] = message.attachments;
470
+ $[40] = t4;
471
+ } else t4 = $[40];
472
+ let t5;
473
+ if ($[41] !== t2 || $[42] !== t3 || $[43] !== t4) {
474
+ t5 = /* @__PURE__ */ jsx(Message, { children: /* @__PURE__ */ jsxs(MessageContent, { children: [
475
+ t2,
476
+ t3,
477
+ t4
478
+ ] }) });
479
+ $[41] = t2;
480
+ $[42] = t3;
481
+ $[43] = t4;
482
+ $[44] = t5;
483
+ } else t5 = $[44];
484
+ return t5;
459
485
  }
460
486
  if (message.from === "brief") {
461
487
  let t1;
462
- if ($[38] !== message.text) {
488
+ if ($[45] !== message.text) {
463
489
  t1 = /* @__PURE__ */ jsx(Message, { children: /* @__PURE__ */ jsx(MessageContent, { children: /* @__PURE__ */ jsx(CollapsedNote, {
464
490
  label: "Camox briefed the agent",
465
491
  hideLabel: "Hide the brief",
466
492
  text: message.text
467
493
  }) }) });
468
- $[38] = message.text;
469
- $[39] = t1;
470
- } else t1 = $[39];
494
+ $[45] = message.text;
495
+ $[46] = t1;
496
+ } else t1 = $[46];
471
497
  return t1;
472
498
  }
473
499
  if (message.from === "camox") {
474
500
  let t1;
475
- if ($[40] === Symbol.for("react.memo_cache_sentinel")) {
501
+ if ($[47] === Symbol.for("react.memo_cache_sentinel")) {
476
502
  t1 = /* @__PURE__ */ jsx(MessageHeader, {
477
503
  className: "text-muted-foreground text-xs",
478
504
  children: "Camox"
479
505
  });
480
- $[40] = t1;
481
- } else t1 = $[40];
506
+ $[47] = t1;
507
+ } else t1 = $[47];
482
508
  let t2;
483
- if ($[41] !== message.text) {
509
+ if ($[48] !== message.text) {
484
510
  t2 = /* @__PURE__ */ jsx(Message, { children: /* @__PURE__ */ jsxs(MessageContent, { children: [t1, /* @__PURE__ */ jsx(Bubble, {
485
511
  variant: "muted",
486
512
  className: "max-w-full",
487
513
  children: /* @__PURE__ */ jsx(BubbleContent, { children: /* @__PURE__ */ jsx(CroppedText, { text: message.text }) })
488
514
  })] }) });
489
- $[41] = message.text;
490
- $[42] = t2;
491
- } else t2 = $[42];
515
+ $[48] = message.text;
516
+ $[49] = t2;
517
+ } else t2 = $[49];
492
518
  return t2;
493
519
  }
494
520
  let t1;
495
- if ($[43] !== message.sender) {
521
+ if ($[50] !== message.sender) {
496
522
  t1 = /* @__PURE__ */ jsx(MessageAvatar, { children: /* @__PURE__ */ jsx(SenderAvatar, { sender: message.sender }) });
497
- $[43] = message.sender;
498
- $[44] = t1;
499
- } else t1 = $[44];
523
+ $[50] = message.sender;
524
+ $[51] = t1;
525
+ } else t1 = $[51];
500
526
  let t2;
501
- if ($[45] !== message.text) {
527
+ if ($[52] !== message.text) {
502
528
  t2 = /* @__PURE__ */ jsx(MessageContent, { children: /* @__PURE__ */ jsx(Bubble, {
503
529
  align: "end",
504
530
  variant: "muted",
505
531
  className: "max-w-full",
506
532
  children: /* @__PURE__ */ jsx(BubbleContent, { children: /* @__PURE__ */ jsx(CroppedText, { text: message.text }) })
507
533
  }) });
508
- $[45] = message.text;
509
- $[46] = t2;
510
- } else t2 = $[46];
534
+ $[52] = message.text;
535
+ $[53] = t2;
536
+ } else t2 = $[53];
511
537
  let t3;
512
- if ($[47] !== t1 || $[48] !== t2) {
538
+ if ($[54] !== t1 || $[55] !== t2) {
513
539
  t3 = /* @__PURE__ */ jsxs(Message, {
514
540
  align: "end",
515
541
  children: [t1, t2]
516
542
  });
517
- $[47] = t1;
518
- $[48] = t2;
519
- $[49] = t3;
520
- } else t3 = $[49];
543
+ $[54] = t1;
544
+ $[55] = t2;
545
+ $[56] = t3;
546
+ } else t3 = $[56];
521
547
  return t3;
522
548
  }
523
549
  function _temp(subject, index) {
@@ -608,13 +634,135 @@ function CroppedText(t0) {
608
634
  return t9;
609
635
  }
610
636
  /**
637
+ * The Attachments a Connected Agent's message carries, the images Camox's agent saw with it
638
+ * (ADR 0044): a thumbnail of each, which opens it at full size.
639
+ */
640
+ function AttachmentThumbnails(t0) {
641
+ const $ = c(20);
642
+ const { attachments } = t0;
643
+ const [opened, setOpened] = React.useState();
644
+ let t1;
645
+ if ($[0] !== attachments) {
646
+ let t2;
647
+ if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
648
+ t2 = (attachment) => /* @__PURE__ */ jsx("button", {
649
+ type: "button",
650
+ title: attachment.filename,
651
+ onClick: () => setOpened(attachment),
652
+ className: "checkered focus-visible:ring-ring size-16 overflow-hidden rounded-md border focus-visible:ring-2 focus-visible:outline-none",
653
+ children: /* @__PURE__ */ jsx("img", {
654
+ src: attachment.url,
655
+ alt: attachment.filename,
656
+ className: "size-full object-cover",
657
+ draggable: false
658
+ })
659
+ }, attachment.id);
660
+ $[2] = t2;
661
+ } else t2 = $[2];
662
+ t1 = attachments.map(t2);
663
+ $[0] = attachments;
664
+ $[1] = t1;
665
+ } else t1 = $[1];
666
+ let t2;
667
+ if ($[3] !== t1) {
668
+ t2 = /* @__PURE__ */ jsx("div", {
669
+ "data-thread-attachments": true,
670
+ className: "flex flex-wrap gap-1.5",
671
+ children: t1
672
+ });
673
+ $[3] = t1;
674
+ $[4] = t2;
675
+ } else t2 = $[4];
676
+ const t3 = !!opened;
677
+ let t4;
678
+ if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
679
+ t4 = (open) => !open && setOpened(void 0);
680
+ $[5] = t4;
681
+ } else t4 = $[5];
682
+ const t5 = opened?.filename;
683
+ let t6;
684
+ if ($[6] !== t5) {
685
+ t6 = /* @__PURE__ */ jsx(DialogTitle, {
686
+ className: "sr-only",
687
+ children: t5
688
+ });
689
+ $[6] = t5;
690
+ $[7] = t6;
691
+ } else t6 = $[7];
692
+ let t7;
693
+ if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
694
+ t7 = /* @__PURE__ */ jsxs(Button, {
695
+ type: "button",
696
+ variant: "ghost",
697
+ size: "icon",
698
+ className: "absolute top-2 right-2 z-10",
699
+ onClick: () => setOpened(void 0),
700
+ children: [/* @__PURE__ */ jsx(X, {}), /* @__PURE__ */ jsx("span", {
701
+ className: "sr-only",
702
+ children: "Close"
703
+ })]
704
+ });
705
+ $[8] = t7;
706
+ } else t7 = $[8];
707
+ let t8;
708
+ if ($[9] !== opened) {
709
+ t8 = opened && /* @__PURE__ */ jsx("div", {
710
+ className: "checkered absolute inset-0 flex items-center justify-center overflow-hidden p-6",
711
+ children: /* @__PURE__ */ jsx("img", {
712
+ src: opened.url,
713
+ alt: opened.filename,
714
+ className: "max-h-full max-w-full object-contain shadow-lg",
715
+ draggable: false
716
+ })
717
+ });
718
+ $[9] = opened;
719
+ $[10] = t8;
720
+ } else t8 = $[10];
721
+ let t9;
722
+ if ($[11] !== t6 || $[12] !== t8) {
723
+ t9 = /* @__PURE__ */ jsxs(DialogContent, {
724
+ className: "h-[90vh] max-h-[90vh] w-[90vw] max-w-[90vw] gap-0 overflow-hidden p-0 sm:max-w-[90vw]",
725
+ showCloseButton: false,
726
+ forceOverlay: true,
727
+ children: [
728
+ t6,
729
+ t7,
730
+ t8
731
+ ]
732
+ });
733
+ $[11] = t6;
734
+ $[12] = t8;
735
+ $[13] = t9;
736
+ } else t9 = $[13];
737
+ let t10;
738
+ if ($[14] !== t3 || $[15] !== t9) {
739
+ t10 = /* @__PURE__ */ jsx(Dialog, {
740
+ open: t3,
741
+ onOpenChange: t4,
742
+ children: t9
743
+ });
744
+ $[14] = t3;
745
+ $[15] = t9;
746
+ $[16] = t10;
747
+ } else t10 = $[16];
748
+ let t11;
749
+ if ($[17] !== t10 || $[18] !== t2) {
750
+ t11 = /* @__PURE__ */ jsxs(Fragment, { children: [t2, t10] });
751
+ $[17] = t10;
752
+ $[18] = t2;
753
+ $[19] = t11;
754
+ } else t11 = $[19];
755
+ return t11;
756
+ }
757
+ /**
611
758
  * Context the agent was given beside the editors' requests, such as the Brief the agent on Live
612
759
  * handed the request off with, or a Connected Agent's answers to its questions: a quiet line,
613
- * `label`, so the requests read on as they were sent, which shows `text` once clicked.
760
+ * `label`, so the requests read on as they were sent, which shows `text`, then `children`, once
761
+ * clicked.
614
762
  */
615
763
  function CollapsedNote(t0) {
616
- const $ = c(11);
617
- const { label, hideLabel, title, text } = t0;
764
+ const $ = c(12);
765
+ const { label, hideLabel, title, text, children } = t0;
618
766
  const [open, setOpen] = React.useState(false);
619
767
  let t1;
620
768
  if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
@@ -651,18 +799,24 @@ function CollapsedNote(t0) {
651
799
  $[6] = text;
652
800
  $[7] = t4;
653
801
  } else t4 = $[7];
654
- let t5;
655
- if ($[8] !== t3 || $[9] !== t4) {
656
- t5 = /* @__PURE__ */ jsxs("div", {
802
+ const t5 = open && children;
803
+ let t6;
804
+ if ($[8] !== t3 || $[9] !== t4 || $[10] !== t5) {
805
+ t6 = /* @__PURE__ */ jsxs("div", {
657
806
  "data-thread-collapsed": true,
658
807
  className: "text-muted-foreground flex flex-col gap-2 text-xs",
659
- children: [t3, t4]
808
+ children: [
809
+ t3,
810
+ t4,
811
+ t5
812
+ ]
660
813
  });
661
814
  $[8] = t3;
662
815
  $[9] = t4;
663
816
  $[10] = t5;
664
- } else t5 = $[10];
665
- return t5;
817
+ $[11] = t6;
818
+ } else t6 = $[11];
819
+ return t6;
666
820
  }
667
821
  function _temp2(current) {
668
822
  return !current;
@@ -672,10 +826,11 @@ const DRAFT_CARD_CLASSES = "bg-muted/50 flex w-full flex-col items-start gap-0.5
672
826
  /**
673
827
  * The card of the draft the agent on Live handed the request off to, where its agent does the
674
828
  * work: it opens the draft. Once the draft ended, there's nothing to open: it says how it ended.
829
+ * While the draft is archived, it says so and offers to restore it (ADR 0046).
675
830
  */
676
831
  function DraftCard(t0) {
677
- const $ = c(15);
678
- const { message, onOpenDraft } = t0;
832
+ const $ = c(27);
833
+ const { message, onOpenDraft, onRestoreDraft } = t0;
679
834
  let t1;
680
835
  if ($[0] !== message.name) {
681
836
  t1 = /* @__PURE__ */ jsx("span", {
@@ -686,65 +841,115 @@ function DraftCard(t0) {
686
841
  $[1] = t1;
687
842
  } else t1 = $[1];
688
843
  const name = t1;
844
+ if (message.archived) {
845
+ let t2;
846
+ if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
847
+ t2 = cn(DRAFT_CARD_CLASSES, "flex-row items-center gap-3");
848
+ $[2] = t2;
849
+ } else t2 = $[2];
850
+ let t3;
851
+ if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
852
+ t3 = /* @__PURE__ */ jsx("span", {
853
+ className: "text-muted-foreground text-xs",
854
+ children: "Archived"
855
+ });
856
+ $[3] = t3;
857
+ } else t3 = $[3];
858
+ let t4;
859
+ if ($[4] !== name) {
860
+ t4 = /* @__PURE__ */ jsxs("div", {
861
+ className: "flex min-w-0 flex-1 flex-col gap-0.5",
862
+ children: [t3, name]
863
+ });
864
+ $[4] = name;
865
+ $[5] = t4;
866
+ } else t4 = $[5];
867
+ let t5;
868
+ if ($[6] !== message.draftId || $[7] !== onRestoreDraft) {
869
+ t5 = /* @__PURE__ */ jsx(Button, {
870
+ variant: "outline",
871
+ size: "sm",
872
+ onClick: () => onRestoreDraft?.(message.draftId),
873
+ children: "Restore"
874
+ });
875
+ $[6] = message.draftId;
876
+ $[7] = onRestoreDraft;
877
+ $[8] = t5;
878
+ } else t5 = $[8];
879
+ let t6;
880
+ if ($[9] !== t4 || $[10] !== t5) {
881
+ t6 = /* @__PURE__ */ jsxs("div", {
882
+ "data-thread-draft-card": true,
883
+ className: t2,
884
+ children: [t4, t5]
885
+ });
886
+ $[9] = t4;
887
+ $[10] = t5;
888
+ $[11] = t6;
889
+ } else t6 = $[11];
890
+ return t6;
891
+ }
689
892
  if (message.ended) {
690
893
  const t2 = message.ended === "published" ? "Published" : "Deleted";
691
894
  let t3;
692
- if ($[2] !== t2) {
895
+ if ($[12] !== t2) {
693
896
  t3 = /* @__PURE__ */ jsx("span", {
694
897
  className: "text-muted-foreground text-xs",
695
898
  children: t2
696
899
  });
697
- $[2] = t2;
698
- $[3] = t3;
699
- } else t3 = $[3];
900
+ $[12] = t2;
901
+ $[13] = t3;
902
+ } else t3 = $[13];
700
903
  let t4;
701
- if ($[4] !== name || $[5] !== t3) {
904
+ if ($[14] !== name || $[15] !== t3) {
702
905
  t4 = /* @__PURE__ */ jsxs("div", {
703
906
  "data-thread-draft-card": true,
704
907
  className: DRAFT_CARD_CLASSES,
705
908
  children: [t3, name]
706
909
  });
707
- $[4] = name;
708
- $[5] = t3;
709
- $[6] = t4;
710
- } else t4 = $[6];
910
+ $[14] = name;
911
+ $[15] = t3;
912
+ $[16] = t4;
913
+ } else t4 = $[16];
711
914
  return t4;
712
915
  }
713
916
  let t2;
714
- if ($[7] !== message.draftId || $[8] !== onOpenDraft) {
917
+ if ($[17] !== message.draftId || $[18] !== onOpenDraft) {
715
918
  t2 = () => onOpenDraft?.(message.draftId);
716
- $[7] = message.draftId;
717
- $[8] = onOpenDraft;
718
- $[9] = t2;
719
- } else t2 = $[9];
919
+ $[17] = message.draftId;
920
+ $[18] = onOpenDraft;
921
+ $[19] = t2;
922
+ } else t2 = $[19];
720
923
  let t3;
721
- let t4;
722
- if ($[10] === Symbol.for("react.memo_cache_sentinel")) {
924
+ if ($[20] === Symbol.for("react.memo_cache_sentinel")) {
723
925
  t3 = cn(DRAFT_CARD_CLASSES, "hover:bg-muted focus-visible:ring-ring transition-colors focus-visible:ring-2 focus-visible:outline-none");
724
- t4 = /* @__PURE__ */ jsx("span", {
926
+ $[20] = t3;
927
+ } else t3 = $[20];
928
+ const t4 = message.restored ? "Restored a draft" : "Started a draft";
929
+ let t5;
930
+ if ($[21] !== t4) {
931
+ t5 = /* @__PURE__ */ jsx("span", {
725
932
  className: "text-muted-foreground text-xs",
726
- children: "Started a draft"
933
+ children: t4
727
934
  });
728
- $[10] = t3;
729
- $[11] = t4;
730
- } else {
731
- t3 = $[10];
732
- t4 = $[11];
733
- }
734
- let t5;
735
- if ($[12] !== name || $[13] !== t2) {
736
- t5 = /* @__PURE__ */ jsxs("button", {
935
+ $[21] = t4;
936
+ $[22] = t5;
937
+ } else t5 = $[22];
938
+ let t6;
939
+ if ($[23] !== name || $[24] !== t2 || $[25] !== t5) {
940
+ t6 = /* @__PURE__ */ jsxs("button", {
737
941
  type: "button",
738
942
  "data-thread-draft-card": true,
739
943
  onClick: t2,
740
944
  className: t3,
741
- children: [t4, name]
945
+ children: [t5, name]
742
946
  });
743
- $[12] = name;
744
- $[13] = t2;
745
- $[14] = t5;
746
- } else t5 = $[14];
747
- return t5;
947
+ $[23] = name;
948
+ $[24] = t2;
949
+ $[25] = t5;
950
+ $[26] = t6;
951
+ } else t6 = $[26];
952
+ return t6;
748
953
  }
749
954
  function SenderAvatar(t0) {
750
955
  const $ = c(10);