@agent-native/core 0.195.0-nightly-20260927184127 → 0.195.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 (29) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/calendar/CHANGELOG.md +18 -0
  3. package/corpus/templates/clips/CHANGELOG.md +1 -0
  4. package/corpus/templates/content/CHANGELOG.md +10 -0
  5. package/corpus/templates/design/CHANGELOG.md +1 -0
  6. package/corpus/templates/mail/CHANGELOG.md +17 -0
  7. package/corpus/templates/mail/app/components/onboarding/AiInboxSetup.tsx +122 -13
  8. package/corpus/templates/mail/app/components/onboarding/register-first-run.tsx +25 -0
  9. package/corpus/templates/mail/app/i18n/en-US.ts +3 -0
  10. package/corpus/templates/mail/app/root.tsx +1 -0
  11. package/corpus/templates/mail/changelog/2026-09-27-add-ai-inbox-triage-to-mail-s-first-run-onboarding.md +6 -0
  12. package/corpus/templates/slides/CHANGELOG.md +17 -0
  13. package/dist/automation/index.d.ts +1 -1
  14. package/dist/client/observability/ObservabilityDashboard.js +37 -29
  15. package/dist/collab/routes.d.ts +2 -2
  16. package/dist/jobs/background-automation-runner.js +1 -0
  17. package/dist/notifications/routes.d.ts +1 -1
  18. package/dist/observability/reviews.js +104 -31
  19. package/dist/observability/routes.d.ts +5 -5
  20. package/dist/observability/store.d.ts +10 -5
  21. package/dist/observability/store.js +143 -49
  22. package/dist/observability/types.d.ts +7 -0
  23. package/dist/progress/routes.d.ts +1 -1
  24. package/dist/resources/handlers.d.ts +1 -1
  25. package/dist/secrets/routes.d.ts +9 -9
  26. package/dist/server/agent-engine-ollama-models-route.d.ts +2 -2
  27. package/dist/server/realtime-token.d.ts +1 -1
  28. package/dist/triggers/actions/manage-automation.d.ts +2 -2
  29. package/package.json +4 -4
package/corpus/README.md CHANGED
@@ -31,4 +31,4 @@ rg -n "defineAction|useActionQuery" node_modules/@agent-native/core/corpus
31
31
 
32
32
  ## Generated Counts
33
33
 
34
- - template files: 10364
34
+ - template files: 10366
@@ -3,6 +3,24 @@
3
3
  All notable user-facing changes to Agent-Native Calendar are documented here. Open it any
4
4
  time from the command menu (Cmd+K → "What's new") or from Settings.
5
5
 
6
+ ## 2026-09-27
7
+
8
+ ### Improved
9
+
10
+ - Events created by the agent now show their date and time with a direct link to Calendar.
11
+ - Calendar shows cards for event changes and lets you start an event draft from a suggested time.
12
+
13
+ ### Fixed
14
+
15
+ - Calendar cards keep your booking link title when it matches the default label
16
+ - Calendar event cards retain Meet and Zoom links, show conferencing warnings, and format event times in your selected locale.
17
+ - Calendar event cards show times in the supplied offset or Calendar timezone and keep long working-location labels readable.
18
+ - Calendar time links keep separate drafts per timezone and preserve edits when reopened
19
+
20
+ ### Security
21
+
22
+ - Meeting links from invitations now open in a new tab that cannot redirect your Calendar tab
23
+
6
24
  ## 2026-09-26
7
25
 
8
26
  ### Improved
@@ -38,6 +38,7 @@ from the command menu (Cmd+K → "What's new") or from Settings.
38
38
 
39
39
  ### Fixed
40
40
 
41
+ - Fix Google sign-in and connect popups that stayed blank and asked you to allow pop-ups
41
42
  - Clips checks storage before upload and offers Builder.io or your own S3-compatible keys when storage is missing.
42
43
  - Clips desktop sign-in now accepts authenticator codes when two-step verification is enabled.
43
44
  - Keep Builder login state after blocked popups and show feedback while retrying storage connection checks
@@ -58,6 +58,12 @@ time from the command menu (Cmd+K → "What's new").
58
58
 
59
59
  - Search now ranks exact and partial title matches above incidental matches in document bodies.
60
60
 
61
+ ## 2026-09-18
62
+
63
+ ### Improved
64
+
65
+ - Mention a connected AI model in a comment, choose how it should respond, and keep the work in that thread.
66
+
61
67
  ## 2026-09-16
62
68
 
63
69
  ### Fixed
@@ -72,6 +78,10 @@ time from the command menu (Cmd+K → "What's new").
72
78
 
73
79
  ## 2026-09-14
74
80
 
81
+ ### Added
82
+
83
+ - Ask AI conversations now stay with the comment that started them, with inline progress, replies, recovery, and an explicit option to open the full conversation.
84
+
75
85
  ### Improved
76
86
 
77
87
  - Trash now uses table-native metadata filters to find nested Pages, preview their content, and empty reviewed scopes with progress that survives navigation.
@@ -7,6 +7,7 @@ from the command menu (Cmd+K → "What's new") or from Settings.
7
7
 
8
8
  ### Improved
9
9
 
10
+ - The Connect AI setup card now has even spacing above and below the composer.
10
11
  - Chrome local access guidance clarifies how to approve live editing
11
12
 
12
13
  ### Fixed
@@ -3,6 +3,22 @@
3
3
  All notable user-facing changes to Agent-Native Mail are documented here. Open it any
4
4
  time from the command menu (Cmd+K → "What's new") or from Settings.
5
5
 
6
+ ## 2026-09-27
7
+
8
+ ### Improved
9
+
10
+ - Add AI inbox triage to Mail's first-run onboarding.
11
+ - Scheduled-send cards show the subject and local send time
12
+ - Successful draft, filter, and inbox rule changes now appear as concise action cards in chat.
13
+
14
+ ### Fixed
15
+
16
+ - Fixed the inbox crash when the sidebar is pinned
17
+ - Inbox navigation stays in a hamburger drawer, and filter tabs use available toolbar space before scrolling.
18
+ - Inbox sorting finishes reliably across larger mailboxes
19
+ - Scheduled email cards keep subjects that match the default label
20
+ - Scheduled sends reject timestamps outside the supported date range before saving.
21
+
6
22
  ## 2026-09-26
7
23
 
8
24
  ### Improved
@@ -40,6 +56,7 @@ time from the command menu (Cmd+K → "What's new") or from Settings.
40
56
 
41
57
  ### Fixed
42
58
 
59
+ - Fix Google sign-in and connect popups that stayed blank and asked you to allow pop-ups
43
60
  - Slack conversations can now use all available Mail actions
44
61
  - Editing importance rules preserves disabled instructions and recovers from duplicate-rule deletion failures
45
62
  - Handle astral Unicode letters in autocomplete word boundaries
@@ -20,6 +20,7 @@ import {
20
20
  import { useEffect, useMemo, useRef, useState } from "react";
21
21
  import { toast } from "sonner";
22
22
 
23
+ import { GoogleConnectBanner } from "@/components/GoogleConnectBanner";
23
24
  import { AiRulePromptField } from "@/components/settings/AiRulePromptField";
24
25
  import {
25
26
  JevAvailabilityError,
@@ -34,6 +35,7 @@ import {
34
35
  } from "@/components/ui/dialog";
35
36
  import { Input } from "@/components/ui/input";
36
37
  import { Progress } from "@/components/ui/progress";
38
+ import { Skeleton } from "@/components/ui/skeleton";
37
39
  import { Switch } from "@/components/ui/switch";
38
40
  import {
39
41
  useAiFilterBackfillStatus,
@@ -46,6 +48,7 @@ import {
46
48
  } from "@/hooks/use-automations";
47
49
  import { useSettings, useUpdateSettings } from "@/hooks/use-emails";
48
50
  import { useGoogleAuthStatus } from "@/hooks/use-google-auth";
51
+ import { shouldOfferGoogleOAuthSetup } from "@/lib/google-oauth-setup";
49
52
  import { labelTabHref } from "@/lib/inbox-tabs";
50
53
  import { getLabelStyle } from "@/lib/label-colors";
51
54
  import { cn } from "@/lib/utils";
@@ -131,6 +134,31 @@ function SetupRuleRow({
131
134
  );
132
135
  }
133
136
 
137
+ function SetupSurface({
138
+ embedded,
139
+ visible,
140
+ onClose,
141
+ children,
142
+ }: {
143
+ embedded: boolean;
144
+ visible: boolean;
145
+ onClose: () => void;
146
+ children: React.ReactNode;
147
+ }) {
148
+ if (!visible) return null;
149
+ if (embedded) return children;
150
+ return (
151
+ <Dialog
152
+ open={visible}
153
+ onOpenChange={(open) => {
154
+ if (!open) onClose();
155
+ }}
156
+ >
157
+ <DialogContent className="max-w-3xl">{children}</DialogContent>
158
+ </Dialog>
159
+ );
160
+ }
161
+
134
162
  function SetupResults({
135
163
  status,
136
164
  loading,
@@ -362,16 +390,26 @@ function SetupResults({
362
390
 
363
391
  export function AiInboxSetup({
364
392
  forceOpen = false,
393
+ embedded = false,
365
394
  onOpenChange,
395
+ onComplete,
396
+ onSkipSetup,
366
397
  }: {
367
398
  forceOpen?: boolean;
399
+ embedded?: boolean;
368
400
  onOpenChange?: (open: boolean) => void;
401
+ onComplete?: () => void;
402
+ onSkipSetup?: () => void;
369
403
  }) {
370
404
  const t = useT();
371
405
  const { data: settings } = useSettings();
372
406
  const { data: rules = [], isLoading: rulesLoading } = useAutomations();
373
407
  const googleStatus = useGoogleAuthStatus();
374
408
  const connected = (googleStatus.data?.accounts.length ?? 0) > 0;
409
+ const canOfferGoogleOAuthSetup = useMemo(
410
+ () => shouldOfferGoogleOAuthSetup(),
411
+ [],
412
+ );
375
413
  const jevAvailability = useActionQuery(
376
414
  "get-jev-availability",
377
415
  {},
@@ -455,6 +493,17 @@ export function AiInboxSetup({
455
493
  try {
456
494
  await updateSettings.mutateAsync({ aiSetupCompleted: true });
457
495
  onOpenChange?.(false);
496
+ onComplete?.();
497
+ } catch {
498
+ toast.error(t("mail.aiFilter.settingsFailed"));
499
+ }
500
+ };
501
+
502
+ const skipSetup = async () => {
503
+ if (saving || updateSettings.isPending) return;
504
+ try {
505
+ await updateSettings.mutateAsync({ aiSetupCompleted: true });
506
+ onSkipSetup?.();
458
507
  } catch {
459
508
  toast.error(t("mail.aiFilter.settingsFailed"));
460
509
  }
@@ -601,21 +650,81 @@ export function AiInboxSetup({
601
650
  customTagSelected &&
602
651
  (!customTagName.trim() || !customTagPrompt.trim());
603
652
 
653
+ if (
654
+ embedded &&
655
+ forceOpen &&
656
+ (googleStatus.isLoading || (connected && jevAvailability.isLoading))
657
+ ) {
658
+ return (
659
+ <div className="mx-auto w-full max-w-2xl space-y-6" aria-busy="true">
660
+ <Skeleton className="h-7 w-48" />
661
+ <Skeleton className="h-14 w-full" />
662
+ <Skeleton className="h-10 w-28" />
663
+ </div>
664
+ );
665
+ }
666
+
667
+ if (embedded && forceOpen && !connected) {
668
+ return (
669
+ <div className="mx-auto w-full max-w-2xl">
670
+ {googleStatus.data?.configured === true ||
671
+ canOfferGoogleOAuthSetup ||
672
+ googleStatus.isError ? (
673
+ <GoogleConnectBanner variant="hero" />
674
+ ) : (
675
+ <div className="py-6">
676
+ <h1 className="text-lg font-semibold">
677
+ {t("mail.googleConnect.connectTitle")}
678
+ </h1>
679
+ <p className="mt-2 text-sm text-muted-foreground">
680
+ {t("mail.googleConnect.connectionNotConfigured")}
681
+ </p>
682
+ </div>
683
+ )}
684
+ <div className="mt-6 flex justify-end">
685
+ <Button
686
+ variant="ghost"
687
+ size="sm"
688
+ onClick={() => void skipSetup()}
689
+ disabled={saving || updateSettings.isPending}
690
+ >
691
+ {t("mail.sort.aiSetupSkipSetup")}
692
+ </Button>
693
+ </div>
694
+ </div>
695
+ );
696
+ }
697
+
604
698
  return (
605
- <Dialog
606
- open={visible}
607
- onOpenChange={(open) => {
608
- if (!open) {
609
- onOpenChange?.(false);
610
- void complete();
611
- }
699
+ <SetupSurface
700
+ embedded={embedded}
701
+ visible={visible}
702
+ onClose={() => {
703
+ onOpenChange?.(false);
704
+ void complete();
612
705
  }}
613
706
  >
614
- <DialogContent className="max-w-3xl">
707
+ <>
615
708
  <div className="mx-auto flex w-full max-w-2xl flex-1 flex-col justify-center overflow-y-auto">
616
- <DialogHeader className="mb-6">
617
- <DialogTitle>{headline}</DialogTitle>
618
- </DialogHeader>
709
+ <div className="mb-6 flex items-center justify-between gap-3">
710
+ {embedded ? (
711
+ <h1 className="text-lg font-semibold">{headline}</h1>
712
+ ) : (
713
+ <DialogHeader>
714
+ <DialogTitle>{headline}</DialogTitle>
715
+ </DialogHeader>
716
+ )}
717
+ {embedded && step < 3 && onSkipSetup ? (
718
+ <Button
719
+ variant="ghost"
720
+ size="sm"
721
+ onClick={() => void skipSetup()}
722
+ disabled={saving || updateSettings.isPending}
723
+ >
724
+ {t("mail.sort.aiSetupSkipSetup")}
725
+ </Button>
726
+ ) : null}
727
+ </div>
619
728
  <div
620
729
  className="mb-8 flex items-center gap-2"
621
730
  role="progressbar"
@@ -866,7 +975,7 @@ export function AiInboxSetup({
866
975
  </Button>
867
976
  </div>
868
977
  </div>
869
- </DialogContent>
870
- </Dialog>
978
+ </>
979
+ </SetupSurface>
871
980
  );
872
981
  }
@@ -0,0 +1,25 @@
1
+ import {
2
+ registerFirstRunOnboardingExtension,
3
+ type FirstRunOnboardingExtensionProps,
4
+ } from "@agent-native/core/client/onboarding";
5
+
6
+ import { AiInboxSetup } from "./AiInboxSetup";
7
+
8
+ export function MailTriageFirstRun({
9
+ onComplete,
10
+ onSkip,
11
+ }: FirstRunOnboardingExtensionProps) {
12
+ return (
13
+ <AiInboxSetup
14
+ embedded
15
+ forceOpen
16
+ onComplete={onComplete}
17
+ onSkipSetup={onSkip}
18
+ />
19
+ );
20
+ }
21
+
22
+ registerFirstRunOnboardingExtension({
23
+ id: "mail-triage",
24
+ component: MailTriageFirstRun,
25
+ });
@@ -45,6 +45,7 @@ const messages = {
45
45
  aiSetupArchiveLabel: "Skip inbox",
46
46
  aiSetupSave: "Save setup",
47
47
  aiSetupSkip: "Skip for now",
48
+ aiSetupSkipSetup: "Skip inbox setup",
48
49
  aiSetupImportantHeadline: "What’s important",
49
50
  aiSetupSkipInboxHeadline: "What can skip your inbox",
50
51
  aiSetupTagsHeadline: "Pick your tabs",
@@ -446,6 +447,8 @@ const messages = {
446
447
  },
447
448
  googleConnect: {
448
449
  connectTitle: "Connect your Google account",
450
+ connectionNotConfigured:
451
+ "Gmail connection isn't configured for this app. Ask your administrator to enable it, or skip this step for now.",
449
452
  heroDescription:
450
453
  "Send and receive real email. Connect your Gmail account to get started.",
451
454
  setupIntro:
@@ -37,6 +37,7 @@ import {
37
37
  import type { LinksFunction } from "react-router";
38
38
 
39
39
  import { AppLayout } from "@/components/layout/AppLayout";
40
+ import "@/components/onboarding/register-first-run";
40
41
  import { Button } from "@/components/ui/button";
41
42
  import { Toaster } from "@/components/ui/sonner";
42
43
  import { AppToolkitProvider } from "@/components/ui/toolkit-provider";
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-09-27
4
+ ---
5
+
6
+ Add AI inbox triage to Mail's first-run onboarding.
@@ -3,6 +3,20 @@
3
3
  All notable user-facing changes to Agent-Native Slides are documented here. Open it any
4
4
  time from the command menu (Cmd+K → "What's new").
5
5
 
6
+ ## 2026-09-27
7
+
8
+ ### Improved
9
+
10
+ - The Connect AI setup card now has even spacing above and below the composer.
11
+
12
+ ### Fixed
13
+
14
+ - Fixed deck edits that could be overwritten during unload
15
+ - Pagehide saves include queued edits and stay within the keepalive budget
16
+ - Text edits are preserved when leaving or reloading a deck, and link drops no longer navigate away.
17
+ - Text selection and bullet edits stay in their intended line and row
18
+ - The deck list stays available when a deck preview cannot be generated.
19
+
6
20
  ## 2026-09-26
7
21
 
8
22
  ### Added
@@ -25,6 +39,9 @@ time from the command menu (Cmd+K → "What's new").
25
39
 
26
40
  ### Fixed
27
41
 
42
+ - Clicking or double-clicking slide text near a box's edge now puts the caret or selection where you clicked, and pressing Enter in a styled bullet keeps its color and weight on the new bullet
43
+ - Reverted text edits no longer change slide spacing
44
+ - Slides keep their fit while text is edited and avoid saving changes that are erased.
28
45
  - Exports and Present are disabled when a deck has no slides
29
46
  - File uploads ask for storage only when requested, and chat stays disabled until an AI provider is connected.
30
47
  - Home suggestions and file imports handle provider failures more clearly.
@@ -139,8 +139,8 @@ export declare function createAutomationCallbackHandler(runtime: AutomationRunti
139
139
  duplicate?: undefined;
140
140
  eventId?: undefined;
141
141
  } | {
142
+ error?: undefined;
142
143
  accepted: boolean;
143
144
  duplicate: boolean;
144
145
  eventId: string;
145
- error?: undefined;
146
146
  }>;
@@ -70,6 +70,9 @@ function reviewThreadHref(threadId) {
70
70
  url.searchParams.set(AGENT_SIDEBAR_QUERY_PARAM, AGENT_SIDEBAR_QUERY_VALUE_OPEN);
71
71
  return isBrowser ? url.toString() : `${url.pathname}${url.search}${url.hash}`;
72
72
  }
73
+ function ReviewTooltip({ label, children, }) {
74
+ return (_jsx(TooltipProvider, { delayDuration: 200, children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: children }), _jsx(TooltipContent, { children: label })] }) }));
75
+ }
73
76
  const REVIEW_ARTIFACT_APPS = {
74
77
  design: { host: "design.agent-native.com", port: 8099 },
75
78
  slides: { host: "slides.agent-native.com", port: 8086 },
@@ -495,6 +498,8 @@ function ReviewTab({ days, renderArtifactPreview, }) {
495
498
  latestReviewVote(review, review.runId)?.feedbackType;
496
499
  const search = reviewSearch.trim().toLocaleLowerCase();
497
500
  const searchable = [
501
+ review.ask,
502
+ review.answer,
498
503
  review.summary?.ask,
499
504
  review.summary?.outcome,
500
505
  review.threadTitle,
@@ -523,6 +528,7 @@ function ReviewTab({ days, renderArtifactPreview, }) {
523
528
  const activeRunId = selectedRun?.runId ??
524
529
  selectedReview?.runs?.[0]?.runId ??
525
530
  selectedReview?.runId;
531
+ const activeThreadId = selectedRun?.threadId ?? selectedReview?.threadId;
526
532
  const reviewDetailQuery = useOutputReviewDetail(activeRunId ?? null, selectedReview?.orgId);
527
533
  const activeDetail = reviewDetailQuery.data?.runId === activeRunId
528
534
  ? reviewDetailQuery.data
@@ -549,7 +555,7 @@ function ReviewTab({ days, renderArtifactPreview, }) {
549
555
  const selectedArtifactHref = selectedArtifactChoice?.href;
550
556
  const selectedArtifactOpenHref = selectedArtifact
551
557
  ? resolveReviewArtifactOpenHref(selectedArtifact.appId, selectedArtifact.artifactId, selectedArtifact.path, {
552
- threadId: selectedReview?.threadId,
558
+ threadId: activeThreadId,
553
559
  readOnly: selectedReview?.readOnly,
554
560
  })
555
561
  : undefined;
@@ -928,15 +934,17 @@ function ReviewTab({ days, renderArtifactPreview, }) {
928
934
  ? "bg-emerald-500"
929
935
  : voteType === "thumbs_down"
930
936
  ? "bg-rose-500"
931
- : "bg-muted-foreground/40") }), !review.readOnly && (_jsxs(_Fragment, { children: [pendingVotes[review.runId] && (_jsxs("span", { role: "status", "aria-live": "polite", className: "inline-flex items-center gap-1 text-xs text-muted-foreground", children: [_jsx(IconLoader2, { size: 13, className: "animate-spin" }), t("agentChat.common.saving")] })), voteErrors[review.runId] && (_jsx("span", { role: "status", "aria-live": "polite", className: "text-xs text-destructive", children: t("agentChat.common.saveFailed") })), _jsx("button", { type: "button", "aria-label": t("observability.thumbsUp"), "aria-pressed": voteType === "thumbs_up", title: t("observability.thumbsUp"), "data-review-vote": "up", onClick: () => rateFromList(review, "thumbs_up"), disabled: pendingVotes[review.runId] === true, className: cn("rounded-md p-1.5 text-muted-foreground opacity-100 transition-[opacity,color,background-color] hover:bg-muted hover:text-emerald-600 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring group-hover:opacity-100 group-focus-within:opacity-100 [@media(hover:hover)_and_(pointer:fine)]:opacity-0 disabled:opacity-50", voteType === "thumbs_up" &&
932
- "bg-emerald-500/10 text-emerald-600 opacity-100"), children: _jsx(IconThumbUp, { size: 15 }) }), _jsx("button", { type: "button", "aria-label": t("observability.thumbsDown"), "aria-pressed": voteType === "thumbs_down", title: t("observability.thumbsDown"), "data-review-vote": "down", onClick: () => rateFromList(review, "thumbs_down"), disabled: pendingVotes[review.runId] === true, className: cn("rounded-md p-1.5 text-muted-foreground opacity-100 transition-[opacity,color,background-color] hover:bg-muted hover:text-rose-600 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring group-hover:opacity-100 group-focus-within:opacity-100 [@media(hover:hover)_and_(pointer:fine)]:opacity-0 disabled:opacity-50", voteType === "thumbs_down" &&
933
- "bg-rose-500/10 text-rose-600 opacity-100"), children: _jsx(IconThumbDown, { size: 15 }) })] })), !review.summary && !review.readOnly && (_jsx("span", { className: "opacity-100 [@media(hover:hover)_and_(pointer:fine)]:opacity-0 group-hover:opacity-100 group-focus-within:opacity-100", children: _jsx(ObservabilityReviewSummaryButton, { runId: review.runId, orgId: review.orgId, status: getSummaryStatus(review.runId), onStatusChange: (status) => updateSummaryRequests([review.runId], status), compact: true, background: true }) })), _jsx("button", { type: "button", "data-review-chevron": true, "aria-label": t(expanded
934
- ? "observability.hideReviewDetails"
935
- : "observability.showReviewDetails"), title: t(expanded
937
+ : "bg-muted-foreground/40") }), !review.readOnly && (_jsxs(_Fragment, { children: [pendingVotes[review.runId] && (_jsxs("span", { role: "status", "aria-live": "polite", className: "inline-flex items-center gap-1 text-xs text-muted-foreground", children: [_jsx(IconLoader2, { size: 13, className: "animate-spin" }), t("agentChat.common.saving")] })), voteErrors[review.runId] && (_jsx("span", { role: "status", "aria-live": "polite", className: "text-xs text-destructive", children: t("agentChat.common.saveFailed") })), _jsx(ReviewTooltip, { label: t("observability.thumbsUp"), children: _jsx("button", { type: "button", "aria-label": t("observability.thumbsUp"), "aria-pressed": voteType === "thumbs_up", title: t("observability.thumbsUp"), "data-review-vote": "up", onClick: () => rateFromList(review, "thumbs_up"), disabled: pendingVotes[review.runId] === true, className: cn("rounded-md p-1.5 text-muted-foreground opacity-100 transition-[opacity,color,background-color] hover:bg-muted hover:text-emerald-600 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring group-hover:opacity-100 group-focus-within:opacity-100 [@media(hover:hover)_and_(pointer:fine)]:opacity-0 disabled:opacity-50", voteType === "thumbs_up" &&
938
+ "bg-emerald-500/10 text-emerald-600 opacity-100"), children: _jsx(IconThumbUp, { size: 15 }) }) }), _jsx(ReviewTooltip, { label: t("observability.thumbsDown"), children: _jsx("button", { type: "button", "aria-label": t("observability.thumbsDown"), "aria-pressed": voteType === "thumbs_down", title: t("observability.thumbsDown"), "data-review-vote": "down", onClick: () => rateFromList(review, "thumbs_down"), disabled: pendingVotes[review.runId] === true, className: cn("rounded-md p-1.5 text-muted-foreground opacity-100 transition-[opacity,color,background-color] hover:bg-muted hover:text-rose-600 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring group-hover:opacity-100 group-focus-within:opacity-100 [@media(hover:hover)_and_(pointer:fine)]:opacity-0 disabled:opacity-50", voteType === "thumbs_down" &&
939
+ "bg-rose-500/10 text-rose-600 opacity-100"), children: _jsx(IconThumbDown, { size: 15 }) }) })] })), !review.summary && !review.readOnly && (_jsx("span", { className: "opacity-100 [@media(hover:hover)_and_(pointer:fine)]:opacity-0 group-hover:opacity-100 group-focus-within:opacity-100", children: _jsx(ObservabilityReviewSummaryButton, { runId: review.runId, orgId: review.orgId, status: getSummaryStatus(review.runId), onStatusChange: (status) => updateSummaryRequests([review.runId], status), compact: true, background: true }) })), _jsx(ReviewTooltip, { label: t(expanded
936
940
  ? "observability.hideReviewDetails"
937
- : "observability.showReviewDetails"), "aria-expanded": expanded, "aria-controls": detailId, onClick: () => toggleReview(review.runId), className: "rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: _jsx(IconChevronRight, { size: 16, className: cn("shrink-0 transition-transform", expanded
938
- ? "rotate-90"
939
- : "group-hover:translate-x-0.5") }) })] })] }), _jsx("div", { id: detailId, role: "region", "aria-labelledby": triggerId, "data-review-detail-for": review.runId, hidden: !expanded, className: "border-t border-border bg-muted/20", children: expanded && selectedReview && (_jsxs("div", { children: [_jsxs("div", { "data-review-summary": true, className: "flex items-start justify-between gap-3 px-3 py-3 text-sm sm:px-4", children: [_jsxs("div", { className: "min-w-0 space-y-1", children: [_jsx("p", { className: "break-words font-medium text-foreground", children: selectedSummary?.ask || selectedReview.threadTitle }), selectedSummary?.outcome && (_jsx("p", { className: "whitespace-pre-wrap break-words text-muted-foreground", children: selectedSummary.outcome })), selectedNote?.value && (_jsxs("p", { className: "flex items-start gap-1.5 whitespace-pre-wrap break-words pt-1 text-xs text-muted-foreground", children: [_jsx(IconMessageCircle, { size: 14, className: "mt-0.5 shrink-0" }), selectedNote.value] }))] }), _jsx("span", { className: "shrink-0 text-xs text-muted-foreground", children: selectedRun?.model ?? selectedReview.model })] }), _jsxs("div", { className: cn("grid min-w-0 gap-0 border-t border-border", selectedHasPreview
941
+ : "observability.showReviewDetails"), children: _jsx("button", { type: "button", "data-review-chevron": true, "aria-label": t(expanded
942
+ ? "observability.hideReviewDetails"
943
+ : "observability.showReviewDetails"), title: t(expanded
944
+ ? "observability.hideReviewDetails"
945
+ : "observability.showReviewDetails"), "aria-expanded": expanded, "aria-controls": detailId, onClick: () => toggleReview(review.runId), className: "rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: _jsx(IconChevronRight, { size: 16, className: cn("shrink-0 transition-transform", expanded
946
+ ? "rotate-90"
947
+ : "group-hover:translate-x-0.5") }) }) })] })] }), _jsx("div", { id: detailId, role: "region", "aria-labelledby": triggerId, "data-review-detail-for": review.runId, hidden: !expanded, className: "border-t border-border bg-muted/20", children: expanded && selectedReview && (_jsxs("div", { children: [_jsxs("div", { "data-review-summary": true, className: "flex items-start justify-between gap-3 px-3 py-3 text-sm sm:px-4", children: [_jsxs("div", { className: "min-w-0 space-y-1", children: [_jsx("p", { className: "break-words font-medium text-foreground", children: selectedSummary?.ask || selectedReview.threadTitle }), selectedSummary?.outcome && (_jsx("p", { className: "whitespace-pre-wrap break-words text-muted-foreground", children: selectedSummary.outcome })), selectedNote?.value && (_jsxs("p", { className: "flex items-start gap-1.5 whitespace-pre-wrap break-words pt-1 text-xs text-muted-foreground", children: [_jsx(IconMessageCircle, { size: 14, className: "mt-0.5 shrink-0" }), selectedNote.value] }))] }), _jsx("span", { className: "shrink-0 text-xs text-muted-foreground", children: selectedRun?.model ?? selectedReview.model })] }), _jsxs("div", { className: cn("grid min-w-0 gap-0 border-t border-border", selectedHasPreview
940
948
  ? "lg:grid-cols-[minmax(0,3fr)_minmax(0,2fr)]"
941
949
  : ""), children: [selectedArtifactChoices.length > 1 && (_jsx("div", { className: "col-span-full flex min-w-0 gap-2 overflow-x-auto border-b border-border px-3 py-2 sm:px-4", children: selectedArtifactChoices.map((choice) => (_jsx("button", { type: "button", "aria-pressed": choice.key === selectedArtifactChoice?.key, title: choice.artifact.title, onClick: () => setSelectedArtifactKey(choice.key), className: cn("max-w-48 shrink-0 truncate rounded-md px-2.5 py-1.5 text-xs transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", choice.key === selectedArtifactChoice?.key
942
950
  ? "bg-muted text-foreground"
@@ -952,35 +960,35 @@ function ReviewTab({ days, renderArtifactPreview, }) {
952
960
  selectedArtifact.path?.startsWith("/api/media/")), artifactPreviewAppId: selectedArtifact?.appId === "design" ||
953
961
  selectedArtifact?.appId === "slides"
954
962
  ? selectedArtifact.appId
955
- : undefined, artifactPreviewId: selectedArtifact?.artifactId, reviewOrgId: selectedReview.orgId, artifactOnly: true, inlineApp: activeDetail?.app ?? undefined, maxAppHeight: 420, previewLabel: t("observability.reviewPreview") }), _jsx("button", { type: "button", "data-review-lightbox-trigger": true, "aria-label": t("observability.reviewPreview"), title: t("observability.reviewPreview"), onClick: () => setPreviewExpanded(true), className: "absolute right-2 top-2 rounded-md border border-border bg-background/95 p-2 text-muted-foreground shadow-sm transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: _jsx(IconArrowsMaximize, { size: 16 }) })] }) })), _jsxs("section", { "data-review-transcript": true, className: cn("flex min-w-0 flex-col", selectedHasPreview &&
963
+ : undefined, artifactPreviewId: selectedArtifact?.artifactId, reviewOrgId: selectedReview.orgId, artifactOnly: true, inlineApp: activeDetail?.app ?? undefined, maxAppHeight: 420, previewLabel: t("observability.reviewPreview") }), _jsx(ReviewTooltip, { label: t("observability.reviewPreview"), children: _jsx("button", { type: "button", "data-review-lightbox-trigger": true, "aria-label": t("observability.reviewPreview"), title: t("observability.reviewPreview"), onClick: () => setPreviewExpanded(true), className: "absolute right-2 top-2 rounded-md border border-border bg-background/95 p-2 text-muted-foreground shadow-sm transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: _jsx(IconArrowsMaximize, { size: 16 }) }) })] }) })), _jsxs("section", { "data-review-transcript": true, className: cn("flex min-w-0 flex-col", selectedHasPreview &&
956
964
  "border-t border-border lg:border-l lg:border-t-0"), children: [_jsxs("div", { className: "flex shrink-0 items-center justify-between gap-2 px-3 pt-3 sm:px-4", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx("span", { className: "text-xs text-muted-foreground", children: selectedRun?.model ?? selectedReview.model }), (selectedReview.runs?.length ?? 0) > 1 && (_jsx("select", { "aria-label": t("observability.totalRuns"), title: t("observability.totalRuns"), value: activeRunId ?? selectedReview.runId, onChange: (event) => {
957
965
  setSelectedArtifactKey(null);
958
966
  setSelectedDetailRunId(event.target.value);
959
- }, className: "max-w-40 rounded-md border-0 bg-transparent py-1 text-xs text-muted-foreground outline-none focus-visible:ring-2 focus-visible:ring-ring", children: selectedReview.runs.map((run, index) => (_jsxs("option", { value: run.runId, children: [run.model, " \u00B7 ", timeAgo(run.createdAt), " \u00B7", " ", index + 1] }, run.runId))) }))] }), (selectedArtifactOpenHref ||
960
- selectedReview.threadId) && (_jsxs("div", { className: "flex items-center gap-1", children: [selectedArtifactOpenHref &&
961
- selectedArtifact && (_jsx(TooltipProvider, { delayDuration: 200, children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("a", { href: selectedArtifactOpenHref, target: "_blank", rel: "noreferrer", "aria-label": `${t("runsTray.open")} ${selectedArtifact.title}`, className: "rounded-md p-1.5 text-muted-foreground hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: _jsx(IconExternalLink, { size: 15 }) }) }), _jsxs(TooltipContent, { children: [t("runsTray.open"), " ", selectedArtifact.title] })] }) })), selectedReview.threadId &&
962
- selectedReview.orgId === activeOrg?.orgId && (_jsx(TooltipProvider, { delayDuration: 200, children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("a", { href: reviewThreadHref(selectedReview.threadId), target: "_blank", rel: "noreferrer", "aria-label": t("agentTask.openThread"), className: "rounded-md p-1.5 text-muted-foreground hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: _jsx(IconMessageCircle, { size: 15 }) }) }), _jsx(TooltipContent, { children: t("agentTask.openThread") })] }) }))] }))] }), _jsx("div", { className: "flex max-h-[min(38rem,65dvh)] min-h-64 flex-1 flex-col gap-3 overflow-y-auto overscroll-contain p-3 sm:p-4", children: reviewDetailQuery.isLoading ? (_jsxs("div", { role: "status", "aria-label": t("agentChat.common.loading"), className: "space-y-4", children: [_jsx(Skeleton, { className: "ml-auto h-14 w-3/4 rounded-xl" }), _jsx(Skeleton, { className: "h-20 w-5/6 rounded-xl" }), _jsx(Skeleton, { className: "ml-auto h-12 w-2/3 rounded-xl" })] })) : reviewDetailQuery.isError ? (_jsx("p", { role: "alert", className: "text-sm text-muted-foreground", children: t("agentChat.common.chunkLoadFailed") })) : reviewMessages.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: t("observability.notCaptured") })) : (reviewMessages.map((message, index) => {
967
+ }, className: "max-w-40 rounded-md border-0 bg-transparent py-1 text-xs text-muted-foreground outline-none focus-visible:ring-2 focus-visible:ring-ring", children: selectedReview.runs.map((run, index) => (_jsxs("option", { value: run.runId, children: [run.model, " \u00B7 ", timeAgo(run.createdAt), " \u00B7", " ", index + 1] }, run.runId))) }))] }), (selectedArtifactOpenHref || activeThreadId) && (_jsxs("div", { className: "flex items-center gap-1", children: [selectedArtifactOpenHref &&
968
+ selectedArtifact && (_jsx(TooltipProvider, { delayDuration: 200, children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("a", { href: selectedArtifactOpenHref, target: "_blank", rel: "noreferrer", "aria-label": `${t("runsTray.open")} ${selectedArtifact.title}`, className: "rounded-md p-1.5 text-muted-foreground hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: _jsx(IconExternalLink, { size: 15 }) }) }), _jsxs(TooltipContent, { children: [t("runsTray.open"), " ", selectedArtifact.title] })] }) })), activeThreadId &&
969
+ selectedReview.orgId === activeOrg?.orgId && (_jsx(TooltipProvider, { delayDuration: 200, children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("a", { href: reviewThreadHref(activeThreadId), target: "_blank", rel: "noreferrer", "aria-label": t("agentTask.openThread"), className: "rounded-md p-1.5 text-muted-foreground hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: _jsx(IconMessageCircle, { size: 15 }) }) }), _jsx(TooltipContent, { children: t("agentTask.openThread") })] }) }))] }))] }), _jsx("div", { className: "flex max-h-[min(38rem,65dvh)] min-h-64 flex-1 flex-col gap-3 overflow-y-auto overscroll-contain p-3 sm:p-4", children: reviewDetailQuery.isLoading ? (_jsxs("div", { role: "status", "aria-label": t("agentChat.common.loading"), className: "space-y-4", children: [_jsx(Skeleton, { className: "ml-auto h-14 w-3/4 rounded-xl" }), _jsx(Skeleton, { className: "h-20 w-5/6 rounded-xl" }), _jsx(Skeleton, { className: "ml-auto h-12 w-2/3 rounded-xl" })] })) : reviewDetailQuery.isError ? (_jsx("p", { role: "alert", className: "text-sm text-muted-foreground", children: t("agentChat.common.chunkLoadFailed") })) : reviewMessages.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: t("observability.notCaptured") })) : (reviewMessages.map((message, index) => {
963
970
  const isLongAssistant = message.role === "assistant" &&
964
971
  message.text.length > 320;
965
972
  return (_jsxs("div", { className: cn("max-w-[92%] break-words rounded-xl px-3 py-2 text-sm", message.role === "user"
966
973
  ? "ml-auto whitespace-pre-wrap bg-primary/10 text-foreground"
967
974
  : "mr-auto bg-muted text-foreground"), children: [message.role === "assistant" && (_jsx("span", { className: "mb-1 block text-[10px] font-medium text-muted-foreground", children: t("agentChat.common.agent") })), isLongAssistant ? (_jsxs("details", { children: [_jsxs("summary", { className: "cursor-pointer list-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: [_jsx("span", { className: "line-clamp-3 whitespace-pre-wrap", children: message.text }), _jsx("span", { className: "mt-1 block text-xs text-muted-foreground", children: t("agentChat.common.expand") })] }), _jsx("p", { className: "mt-2 whitespace-pre-wrap", children: message.text })] })) : (_jsx("p", { className: "whitespace-pre-wrap", children: message.text })), message.toolCalls?.map((toolCall, toolIndex) => (_jsxs("span", { className: "mt-2 inline-flex max-w-full items-center gap-1 rounded-full bg-background/70 px-2 py-1 text-[10px] text-muted-foreground", title: toolCall, children: [_jsx(IconTool, { size: 11 }), _jsx("span", { className: "truncate", children: toolCall })] }, `${toolCall}-${toolIndex}`)))] }, `${message.role}-${index}`));
968
- })) })] })] }), _jsxs("div", { className: "col-span-full flex shrink-0 items-center gap-1 border-t border-border px-3 py-2 sm:px-4", children: [selectedReview.readOnly ? (_jsx("span", { role: "note", title: t("observability.readOnlyTenant"), className: "text-xs text-muted-foreground", children: t("observability.readOnlyTenant") })) : (_jsxs(_Fragment, { children: [_jsx(ObservabilityReviewSummaryButton, { runId: activeRunId ?? selectedReview.runId, orgId: selectedReview.orgId, status: getSummaryStatus(activeRunId ?? selectedReview.runId), onStatusChange: (status) => updateSummaryRequests([activeRunId ?? selectedReview.runId], status), refresh: Boolean(selectedSummary) }), _jsxs("div", { role: "group", "aria-label": t("observability.reviewFeedback"), className: "flex items-center gap-1", children: [activeRunId && pendingVotes[activeRunId] && (_jsxs("span", { role: "status", "aria-live": "polite", className: "inline-flex items-center gap-1 text-xs text-muted-foreground", children: [_jsx(IconLoader2, { size: 13, className: "animate-spin" }), t("agentChat.common.saving")] })), activeRunId && voteErrors[activeRunId] && (_jsx("span", { role: "status", "aria-live": "polite", className: "text-xs text-destructive", children: t("agentChat.common.saveFailed") })), _jsx("button", { type: "button", "aria-label": t("observability.thumbsUp"), "aria-pressed": selectedVoteType === "thumbs_up", title: t("observability.thumbsUp"), disabled: Boolean(activeRunId && pendingVotes[activeRunId]), onClick: () => saveFeedback(activeRunId ?? selectedReview.runId, "thumbs_up"), className: cn("rounded-md p-2 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:opacity-50", selectedVoteType === "thumbs_up" &&
969
- "bg-emerald-500/10 text-emerald-600 dark:text-emerald-400"), children: _jsx(IconThumbUp, { size: 16 }) }), _jsx("button", { type: "button", "aria-label": t("observability.thumbsDown"), "aria-pressed": selectedVoteType === "thumbs_down", title: t("observability.thumbsDown"), disabled: Boolean(activeRunId && pendingVotes[activeRunId]), onClick: () => {
970
- saveFeedback(activeRunId ?? selectedReview.runId, "thumbs_down");
971
- setFeedbackNote((current) => current?.runId ===
972
- (activeRunId ?? selectedReview.runId)
973
- ? current
974
- : {
975
+ })) })] })] }), _jsxs("div", { className: "col-span-full flex shrink-0 items-center gap-1 border-t border-border px-3 py-2 sm:px-4", children: [selectedReview.readOnly ? (_jsx("span", { role: "note", title: t("observability.readOnlyTenant"), className: "text-xs text-muted-foreground", children: t("observability.readOnlyTenant") })) : (_jsxs(_Fragment, { children: [_jsx(ObservabilityReviewSummaryButton, { runId: activeRunId ?? selectedReview.runId, orgId: selectedReview.orgId, status: getSummaryStatus(activeRunId ?? selectedReview.runId), onStatusChange: (status) => updateSummaryRequests([activeRunId ?? selectedReview.runId], status), refresh: Boolean(selectedSummary) }), _jsxs("div", { role: "group", "aria-label": t("observability.reviewFeedback"), className: "flex items-center gap-1", children: [activeRunId && pendingVotes[activeRunId] && (_jsxs("span", { role: "status", "aria-live": "polite", className: "inline-flex items-center gap-1 text-xs text-muted-foreground", children: [_jsx(IconLoader2, { size: 13, className: "animate-spin" }), t("agentChat.common.saving")] })), activeRunId && voteErrors[activeRunId] && (_jsx("span", { role: "status", "aria-live": "polite", className: "text-xs text-destructive", children: t("agentChat.common.saveFailed") })), _jsx(ReviewTooltip, { label: t("observability.thumbsUp"), children: _jsx("button", { type: "button", "aria-label": t("observability.thumbsUp"), "aria-pressed": selectedVoteType === "thumbs_up", title: t("observability.thumbsUp"), disabled: Boolean(activeRunId && pendingVotes[activeRunId]), onClick: () => saveFeedback(activeRunId ?? selectedReview.runId, "thumbs_up"), className: cn("rounded-md p-2 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:opacity-50", selectedVoteType === "thumbs_up" &&
976
+ "bg-emerald-500/10 text-emerald-600 dark:text-emerald-400"), children: _jsx(IconThumbUp, { size: 16 }) }) }), _jsx(ReviewTooltip, { label: t("observability.thumbsDown"), children: _jsx("button", { type: "button", "aria-label": t("observability.thumbsDown"), "aria-pressed": selectedVoteType === "thumbs_down", title: t("observability.thumbsDown"), disabled: Boolean(activeRunId && pendingVotes[activeRunId]), onClick: () => {
977
+ saveFeedback(activeRunId ?? selectedReview.runId, "thumbs_down");
978
+ setFeedbackNote((current) => current?.runId ===
979
+ (activeRunId ?? selectedReview.runId)
980
+ ? current
981
+ : {
982
+ runId: activeRunId ??
983
+ selectedReview.runId,
984
+ value: "",
985
+ });
986
+ setOpenPopover({
975
987
  runId: activeRunId ?? selectedReview.runId,
976
- value: "",
988
+ kind: "feedback",
977
989
  });
978
- setOpenPopover({
979
- runId: activeRunId ?? selectedReview.runId,
980
- kind: "feedback",
981
- });
982
- }, className: cn("rounded-md p-2 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:opacity-50", selectedVoteType === "thumbs_down" &&
983
- "bg-rose-500/10 text-rose-600 dark:text-rose-400"), children: _jsx(IconThumbDown, { size: 16 }) })] }), _jsxs(Popover, { open: feedbackOpen, onOpenChange: (open) => {
990
+ }, className: cn("rounded-md p-2 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:opacity-50", selectedVoteType === "thumbs_down" &&
991
+ "bg-rose-500/10 text-rose-600 dark:text-rose-400"), children: _jsx(IconThumbDown, { size: 16 }) }) })] }), _jsxs(Popover, { open: feedbackOpen, onOpenChange: (open) => {
984
992
  if (open) {
985
993
  setFeedbackNote((current) => current?.runId ===
986
994
  (activeRunId ?? selectedReview.runId)
@@ -1059,7 +1067,7 @@ function ReviewTab({ days, renderArtifactPreview, }) {
1059
1067
  }), className: "w-full rounded-md border border-border bg-background px-2 py-1.5 text-xs text-foreground", "aria-label": t("observability.instructionTarget"), children: [_jsx("option", { value: "agent", children: t("observability.agentTarget") }), _jsx("option", { value: "developer", children: t("observability.developerTarget") }), _jsx("option", { value: "skill", children: t("observability.skillTarget") })] }), _jsx("textarea", { value: activeInstructionDraft.value, onChange: (event) => setInstructionDraft({
1060
1068
  ...activeInstructionDraft,
1061
1069
  value: event.target.value,
1062
- }), rows: 4, className: "mt-2 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground outline-none focus:ring-2 focus:ring-ring", placeholder: t("observability.instructionPlaceholder") }), _jsx("button", { type: "button", onClick: () => saveInstruction(activeRunId ?? selectedReview.runId, selectedReview.threadId), title: t("observability.saveUpdate"), disabled: !activeInstructionDraft.value.trim() ||
1070
+ }), rows: 4, className: "mt-2 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground outline-none focus:ring-2 focus:ring-ring", placeholder: t("observability.instructionPlaceholder") }), _jsx("button", { type: "button", onClick: () => saveInstruction(activeRunId ?? selectedReview.runId, activeThreadId ?? null), title: t("observability.saveUpdate"), disabled: !activeInstructionDraft.value.trim() ||
1063
1071
  instructionMutation.isPending, className: "mt-2 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium text-foreground hover:bg-muted disabled:opacity-50", children: t("observability.saveUpdate") })] })] })] })), selectedReview.authorEmail && (_jsx("span", { "data-review-author-email": true, dir: "ltr", title: selectedReview.authorEmail, className: "ml-auto min-w-0 max-w-[40%] shrink truncate whitespace-nowrap pl-2 text-right text-xs text-muted-foreground", children: selectedReview.authorEmail }))] })] })) })] }, review.runId));
1064
1072
  })) }), _jsx(Dialog, { open: Boolean(selectedReview && previewExpanded), onOpenChange: setPreviewExpanded, children: selectedReview && (_jsxs(DialogContent, { "aria-describedby": undefined, "data-review-lightbox": true, className: "flex h-dvh max-h-dvh w-screen max-w-none flex-col gap-0 overflow-hidden rounded-none p-0", children: [_jsx(DialogHeader, { className: "shrink-0 border-b border-border px-4 py-3", children: _jsx(DialogTitle, { className: "line-clamp-2 break-words text-left", children: selectedSummary?.ask ||
1065
1073
  selectedReview.threadTitle ||
@@ -8,15 +8,15 @@ export declare const getCollabState: import("h3").EventHandlerWithFetch<import("
8
8
  state: string;
9
9
  }>>;
10
10
  export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
11
- error: string;
12
11
  ok?: undefined;
12
+ error: string;
13
13
  } | {
14
14
  error?: undefined;
15
15
  ok: boolean;
16
16
  }>>;
17
17
  export declare const postCollabText: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
18
- text?: undefined;
19
18
  ok?: undefined;
19
+ text?: undefined;
20
20
  error: string;
21
21
  } | {
22
22
  error?: undefined;
@@ -400,6 +400,7 @@ async function executeBackgroundAutomation(options, deps, historyId, runIdRef) {
400
400
  spanName: `background_automation_run:${automation.name}`,
401
401
  metadata: {
402
402
  automation: automation.name,
403
+ automationId: automation.resource.id,
403
404
  trigger: "background_automation",
404
405
  label: usageLabel,
405
406
  scope: orgId ? "organization" : "personal",
@@ -16,6 +16,6 @@ export declare function createNotificationsHandler(): import("h3").EventHandlerW
16
16
  } | {
17
17
  count?: undefined;
18
18
  updated?: undefined;
19
- ok: boolean;
20
19
  error?: undefined;
20
+ ok: boolean;
21
21
  }>>;