@agent-native/core 0.180.0-nightly-20260915184036 → 0.180.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 (77) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/CHANGELOG.md +10 -0
  3. package/corpus/templates/calendar/CHANGELOG.md +39 -0
  4. package/corpus/templates/calendar/INTERACTION-MATRIX.md +19 -17
  5. package/corpus/templates/calendar/actions/update-calendar-visual-preferences.ts +21 -0
  6. package/corpus/templates/calendar/actions/view-screen.ts +10 -2
  7. package/corpus/templates/calendar/app/components/calendar/CreateEventDialog.tsx +11 -0
  8. package/corpus/templates/calendar/app/components/calendar/MonthView.tsx +174 -145
  9. package/corpus/templates/calendar/app/components/calendar/WeekView.tsx +20 -16
  10. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +1 -0
  11. package/corpus/templates/calendar/app/hooks/use-events.ts +16 -0
  12. package/corpus/templates/calendar/app/hooks/use-view-preferences.ts +126 -14
  13. package/corpus/templates/calendar/app/i18n-data.ts +90 -0
  14. package/corpus/templates/calendar/app/lib/calendar-navigation.ts +29 -9
  15. package/corpus/templates/calendar/app/lib/calendar-timezone.ts +2 -0
  16. package/corpus/templates/calendar/app/lib/event-time-range.ts +34 -0
  17. package/corpus/templates/calendar/app/pages/CalendarView.tsx +245 -35
  18. package/corpus/templates/calendar/changelog/2026-09-13-calendar-sidebar-overflow-is-easier-to-discover.md +6 -0
  19. package/corpus/templates/calendar/changelog/2026-09-15-calendar-mirrors-notion-calendar-s-customizable-day-ranges-a.md +6 -0
  20. package/corpus/templates/calendar/shared/calendar-view-preferences.ts +36 -0
  21. package/corpus/templates/calendar/shared/timezone.ts +9 -2
  22. package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +2 -0
  23. package/corpus/templates/clips/CHANGELOG.md +19 -0
  24. package/corpus/templates/clips/actions/save-browser-diagnostics.ts +43 -4
  25. package/corpus/templates/clips/app/components/player/browser-diagnostics-panel.tsx +114 -1
  26. package/corpus/templates/clips/app/i18n/en-US.ts +7 -0
  27. package/corpus/templates/clips/app/lib/browser-diagnostics-capture.ts +108 -0
  28. package/corpus/templates/clips/app/routes/record.tsx +1 -0
  29. package/corpus/templates/clips/changelog/2026-09-15-recordings-include-a-structured-timeline-of-browser-interact.md +6 -0
  30. package/corpus/templates/clips/chrome-extension/public/manifest.json +7 -0
  31. package/corpus/templates/clips/chrome-extension/src/background.ts +235 -9
  32. package/corpus/templates/clips/chrome-extension/src/content-history-bridge.ts +80 -0
  33. package/corpus/templates/clips/chrome-extension/src/content-script.ts +166 -5
  34. package/corpus/templates/clips/chrome-extension/vite.config.ts +4 -0
  35. package/corpus/templates/clips/server/db/schema.ts +3 -0
  36. package/corpus/templates/clips/server/lib/public-agent-context.ts +40 -2
  37. package/corpus/templates/clips/server/plugins/db.ts +5 -0
  38. package/corpus/templates/clips/shared/browser-diagnostics.ts +171 -0
  39. package/corpus/templates/content/.agents/skills/content/SKILL.md +4 -2
  40. package/corpus/templates/content/.agents/skills/document-editing/SKILL.md +8 -1
  41. package/corpus/templates/content/AGENTS.md +5 -6
  42. package/corpus/templates/content/CHANGELOG.md +24 -0
  43. package/corpus/templates/content/actions/_content-database-row-migration.ts +67 -36
  44. package/corpus/templates/content/actions/_document-edit-mutation.ts +74 -23
  45. package/corpus/templates/content/actions/edit-document.ts +48 -8
  46. package/corpus/templates/content/actions/migrate-content-database-rows.ts +69 -28
  47. package/corpus/templates/content/server/plugins/agent-chat.ts +1 -1
  48. package/corpus/templates/design/CHANGELOG.md +22 -0
  49. package/corpus/templates/factory/CHANGELOG.md +11 -0
  50. package/corpus/templates/forms/CHANGELOG.md +6 -0
  51. package/corpus/templates/mail/.agents/skills/mail-interaction-parity/references/interaction-matrix.md +24 -4
  52. package/corpus/templates/mail/CHANGELOG.md +68 -0
  53. package/corpus/templates/mail/app/components/email/ComposeBubbleToolbar.tsx +8 -0
  54. package/corpus/templates/mail/app/components/email/ComposeModal.tsx +33 -13
  55. package/corpus/templates/mail/app/components/email/EmailListItem.tsx +23 -4
  56. package/corpus/templates/mail/app/components/email/EmailThread.tsx +56 -13
  57. package/corpus/templates/mail/app/components/email/InlineReplyComposer.tsx +23 -4
  58. package/corpus/templates/mail/app/components/email/RecipientInput.tsx +9 -0
  59. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +8 -1
  60. package/corpus/templates/mail/app/i18n/en-US.ts +31 -0
  61. package/corpus/templates/mail/changelog/2026-09-15-mail-labels-recipient-and-account-controls-for-keyboard-and-.md +6 -0
  62. package/corpus/templates/slides/CHANGELOG.md +32 -0
  63. package/dist/client/CommandMenu.js +14 -2
  64. package/dist/client/settings/AccountSettingsCard.js +3 -2
  65. package/dist/client/settings/SettingsTabsPage.js +9 -1
  66. package/dist/client/settings/agent-settings-search.js +5 -1
  67. package/dist/client/sign-out.d.ts +1 -0
  68. package/dist/client/sign-out.js +8 -0
  69. package/dist/collab/routes.d.ts +1 -1
  70. package/dist/file-upload/actions/upload-image.d.ts +2 -2
  71. package/dist/observability/routes.d.ts +3 -3
  72. package/dist/org/handlers.d.ts +1 -1
  73. package/dist/resources/handlers.d.ts +1 -1
  74. package/dist/secrets/routes.d.ts +3 -3
  75. package/dist/server/agent-engine-api-key-route.d.ts +2 -2
  76. package/dist/server/transcribe-voice.d.ts +1 -1
  77. package/package.json +4 -4
@@ -2,6 +2,7 @@ import { useT } from "@agent-native/core/client/i18n";
2
2
  import type {
3
3
  BrowserDiagnosticConsoleLog,
4
4
  BrowserDiagnosticNetworkRequest,
5
+ BrowserDiagnosticTimelineEvent,
5
6
  BrowserDiagnosticsData,
6
7
  } from "@shared/browser-diagnostics";
7
8
  import {
@@ -437,6 +438,106 @@ function NetworkGroupRow({
437
438
  );
438
439
  }
439
440
 
441
+ function timelineKindLabel(
442
+ t: ReturnType<typeof useT>,
443
+ event: BrowserDiagnosticTimelineEvent,
444
+ ): string {
445
+ if (event.kind === "console") return t("browserDiagnostics.consoleSource");
446
+ if (event.kind === "network") {
447
+ return event.phase === "request"
448
+ ? t("browserDiagnostics.requestStarted")
449
+ : t("browserDiagnostics.responseReceived");
450
+ }
451
+ if (event.kind === "navigation") return t("browserDiagnostics.navigation");
452
+ if (event.kind === "click") return t("browserDiagnostics.click");
453
+ if (event.kind === "input") return t("browserDiagnostics.input");
454
+ return t("browserDiagnostics.scroll");
455
+ }
456
+
457
+ function timelineDetail(event: BrowserDiagnosticTimelineEvent): string {
458
+ if (event.kind === "console") {
459
+ return `${event.level}: ${event.message.split("\n", 1)[0]}`;
460
+ }
461
+ if (event.kind === "network") {
462
+ const status = event.status ?? (event.error ? "ERR" : "");
463
+ return `${event.method} ${shortUrl(event.url)}${status ? ` · ${status}` : ""}`;
464
+ }
465
+ return event.url ?? event.target ?? event.kind;
466
+ }
467
+
468
+ function BrowserDiagnosticsTimelineRow({
469
+ event,
470
+ durationMs,
471
+ onSeek,
472
+ }: {
473
+ event: BrowserDiagnosticTimelineEvent;
474
+ durationMs: number;
475
+ onSeek: (ms: number) => void;
476
+ }) {
477
+ const t = useT();
478
+ return (
479
+ <div
480
+ className="flex min-h-9 items-center gap-2 border-b border-border/70 px-4 py-1.5 last:border-b-0"
481
+ data-browser-diagnostic-timeline-row
482
+ >
483
+ <span className="grid size-5 shrink-0 place-items-center rounded-md border border-border text-muted-foreground">
484
+ <IconInfoCircle className="size-3" aria-hidden="true" />
485
+ </span>
486
+ <span className="flex min-w-0 flex-1 items-center gap-1.5 overflow-hidden">
487
+ <span className="shrink-0 text-[11px] font-medium text-muted-foreground">
488
+ {timelineKindLabel(t, event)}
489
+ </span>
490
+ <span className="min-w-0 truncate font-mono text-xs">
491
+ {timelineDetail(event)}
492
+ </span>
493
+ </span>
494
+ <DiagnosticTimeButton
495
+ elapsedMs={event.elapsedMs}
496
+ durationMs={durationMs}
497
+ onSeek={onSeek}
498
+ />
499
+ </div>
500
+ );
501
+ }
502
+
503
+ function BrowserDiagnosticsTimelineSection({
504
+ events,
505
+ durationMs,
506
+ onSeek,
507
+ }: {
508
+ events: BrowserDiagnosticTimelineEvent[];
509
+ durationMs: number;
510
+ onSeek: (ms: number) => void;
511
+ }) {
512
+ const t = useT();
513
+ return (
514
+ <AccordionItem
515
+ value="timeline"
516
+ className="border-border/70"
517
+ data-browser-diagnostics-section="timeline"
518
+ >
519
+ <AccordionTrigger className="min-h-10 px-4 py-2 text-xs hover:no-underline [&>svg]:size-3.5">
520
+ <span className="flex min-w-0 items-center gap-2">
521
+ <span className="truncate">{t("browserDiagnostics.timeline")}</span>
522
+ <span className="rounded-md border border-border px-1.5 py-px font-mono text-[10px] font-normal tabular-nums text-muted-foreground">
523
+ {events.length}
524
+ </span>
525
+ </span>
526
+ </AccordionTrigger>
527
+ <AccordionContent className="pb-0">
528
+ {events.map((event, index) => (
529
+ <BrowserDiagnosticsTimelineRow
530
+ key={`${event.elapsedMs}-${event.kind}-${index}`}
531
+ event={event}
532
+ durationMs={durationMs}
533
+ onSeek={onSeek}
534
+ />
535
+ ))}
536
+ </AccordionContent>
537
+ </AccordionItem>
538
+ );
539
+ }
540
+
440
541
  function BrowserDiagnosticsSection({
441
542
  view,
442
543
  label,
@@ -550,6 +651,7 @@ export function BrowserDiagnosticsPanel({
550
651
  }),
551
652
  [diagnostics],
552
653
  );
654
+ const timeline = diagnostics.timeline ?? [];
553
655
  const source = captureSource(diagnostics);
554
656
  const hasFailures =
555
657
  diagnostics.summary.consoleErrorCount > 0 ||
@@ -622,7 +724,18 @@ export function BrowserDiagnosticsPanel({
622
724
  </div>
623
725
 
624
726
  <div className="min-h-0 flex-1 overflow-y-auto">
625
- <Accordion type="single" defaultValue="issues" collapsible>
727
+ <Accordion
728
+ type="single"
729
+ defaultValue={timeline.length ? "timeline" : "issues"}
730
+ collapsible
731
+ >
732
+ {timeline.length ? (
733
+ <BrowserDiagnosticsTimelineSection
734
+ events={timeline}
735
+ durationMs={durationMs}
736
+ onSeek={onSeek}
737
+ />
738
+ ) : null}
626
739
  {sections.map((section) => (
627
740
  <BrowserDiagnosticsSection
628
741
  key={section.id}
@@ -1827,6 +1827,13 @@ const messages = {
1827
1827
  capturedFrom: "Captured from {{source}}",
1828
1828
  browserCapture: "Browser capture",
1829
1829
  views: "Diagnostic views",
1830
+ timeline: "Timeline",
1831
+ navigation: "Navigation",
1832
+ click: "Click",
1833
+ input: "Input",
1834
+ scroll: "Scroll",
1835
+ requestStarted: "Request started",
1836
+ responseReceived: "Response received",
1830
1837
  issues: "Issues",
1831
1838
  consoleSource: "Console",
1832
1839
  networkSource: "Network",
@@ -1,12 +1,18 @@
1
1
  import {
2
2
  MAX_BROWSER_DIAGNOSTIC_CONSOLE_LOGS,
3
+ MAX_BROWSER_DIAGNOSTIC_INTERACTION_EVENTS,
3
4
  MAX_BROWSER_DIAGNOSTIC_MESSAGE_LENGTH,
4
5
  MAX_BROWSER_DIAGNOSTIC_NETWORK_REQUESTS,
6
+ MAX_BROWSER_DIAGNOSTIC_TARGET_LENGTH,
5
7
  MAX_BROWSER_DIAGNOSTIC_URL_LENGTH,
8
+ buildBrowserDiagnosticTimeline,
6
9
  redactBrowserDiagnosticString,
10
+ sanitizeBrowserDiagnosticNavigationUrl,
7
11
  summarizeBrowserDiagnostics,
8
12
  type BrowserDiagnosticConsoleLevel,
9
13
  type BrowserDiagnosticConsoleLog,
14
+ type BrowserDiagnosticInteractionEvent,
15
+ type BrowserDiagnosticInteractionKind,
10
16
  type BrowserDiagnosticNetworkRequest,
11
17
  type BrowserDiagnosticsData,
12
18
  } from "@shared/browser-diagnostics";
@@ -83,12 +89,40 @@ function requestMethod(input: RequestInfo | URL, init?: RequestInit): string {
83
89
  ).toUpperCase();
84
90
  }
85
91
 
92
+ function safeTargetPart(value: string | null): string | null {
93
+ if (!value || value.length > MAX_BROWSER_DIAGNOSTIC_TARGET_LENGTH) {
94
+ return null;
95
+ }
96
+ return /^[A-Za-z0-9_.:-]+$/.test(value) ? value : null;
97
+ }
98
+
99
+ function describeTarget(target: EventTarget | null): string | null {
100
+ if (!(target instanceof Element)) return null;
101
+ const element = target.closest(
102
+ "button,a,input,textarea,select,[role=button]",
103
+ ) as Element | null;
104
+ const candidate = element ?? target;
105
+ const tag = candidate.tagName.toLowerCase();
106
+ const id = safeTargetPart(candidate.id);
107
+ const testId = safeTargetPart(candidate.getAttribute("data-testid"));
108
+ const name = safeTargetPart(candidate.getAttribute("name"));
109
+ const selector = id
110
+ ? `#${id}`
111
+ : testId
112
+ ? `[data-testid=${testId}]`
113
+ : name
114
+ ? `[name=${name}]`
115
+ : "";
116
+ return truncate(`${tag}${selector}`, MAX_BROWSER_DIAGNOSTIC_TARGET_LENGTH);
117
+ }
118
+
86
119
  export function createBrowserDiagnosticsCapture(): BrowserDiagnosticsCapture {
87
120
  const startedAt = new Date().toISOString();
88
121
  const startedAtMs = Date.now();
89
122
  const startedAtPerf = performance.now();
90
123
  const consoleLogs: BrowserDiagnosticConsoleLog[] = [];
91
124
  const networkRequests: BrowserDiagnosticNetworkRequest[] = [];
125
+ const interactionEvents: BrowserDiagnosticInteractionEvent[] = [];
92
126
  const originalConsole = {
93
127
  debug: console.debug,
94
128
  log: console.log,
@@ -115,6 +149,25 @@ export function createBrowserDiagnosticsCapture(): BrowserDiagnosticsCapture {
115
149
  Math.max(0, Math.round(performance.now() - startedAtPerf));
116
150
  const timestamp = () => startedAtMs + elapsed();
117
151
 
152
+ const pushInteraction = (
153
+ kind: BrowserDiagnosticInteractionKind,
154
+ target?: EventTarget | null,
155
+ url?: string,
156
+ ) => {
157
+ if (!active) return;
158
+ if (interactionEvents.length >= MAX_BROWSER_DIAGNOSTIC_INTERACTION_EVENTS) {
159
+ interactionEvents.shift();
160
+ }
161
+ const targetDescription = describeTarget(target ?? null);
162
+ interactionEvents.push({
163
+ timestampMs: timestamp(),
164
+ elapsedMs: elapsed(),
165
+ kind,
166
+ ...(targetDescription ? { target: targetDescription } : {}),
167
+ ...(url ? { url: sanitizeBrowserDiagnosticNavigationUrl(url) } : {}),
168
+ });
169
+ };
170
+
118
171
  const pushConsole = (
119
172
  level: BrowserDiagnosticConsoleLevel,
120
173
  args: unknown[],
@@ -305,6 +358,48 @@ export function createBrowserDiagnosticsCapture(): BrowserDiagnosticsCapture {
305
358
  window.addEventListener("error", onError);
306
359
  window.addEventListener("unhandledrejection", onUnhandledRejection);
307
360
 
361
+ const onClick = (event: MouseEvent) => pushInteraction("click", event.target);
362
+ const onInput = (event: Event) => pushInteraction("input", event.target);
363
+ let lastScrollElapsed = -Infinity;
364
+ const onScroll = (event: Event) => {
365
+ const currentElapsed = elapsed();
366
+ if (currentElapsed - lastScrollElapsed < 250) return;
367
+ lastScrollElapsed = currentElapsed;
368
+ pushInteraction("scroll", event.target);
369
+ };
370
+ const onNavigation = () =>
371
+ pushInteraction("navigation", null, window.location.href);
372
+ const originalPushState = history.pushState;
373
+ const originalReplaceState = history.replaceState;
374
+ const patchedPushState = function patchedPushState(
375
+ this: History,
376
+ state: unknown,
377
+ unused: string,
378
+ url?: string | URL | null,
379
+ ) {
380
+ const result = originalPushState.call(this, state, unused, url);
381
+ onNavigation();
382
+ return result;
383
+ };
384
+ const patchedReplaceState = function patchedReplaceState(
385
+ this: History,
386
+ state: unknown,
387
+ unused: string,
388
+ url?: string | URL | null,
389
+ ) {
390
+ const result = originalReplaceState.call(this, state, unused, url);
391
+ onNavigation();
392
+ return result;
393
+ };
394
+ history.pushState = patchedPushState;
395
+ history.replaceState = patchedReplaceState;
396
+ document.addEventListener("click", onClick, true);
397
+ document.addEventListener("input", onInput, true);
398
+ document.addEventListener("scroll", onScroll, true);
399
+ window.addEventListener("popstate", onNavigation);
400
+ window.addEventListener("hashchange", onNavigation);
401
+ pushInteraction("navigation", null, window.location.href);
402
+
308
403
  const restore = () => {
309
404
  window.fetch = originalFetch;
310
405
  for (const level of ["debug", "log", "info", "warn", "error"] as const) {
@@ -314,6 +409,17 @@ export function createBrowserDiagnosticsCapture(): BrowserDiagnosticsCapture {
314
409
  XMLHttpRequest.prototype.send = originalXhrSend;
315
410
  window.removeEventListener("error", onError);
316
411
  window.removeEventListener("unhandledrejection", onUnhandledRejection);
412
+ document.removeEventListener("click", onClick, true);
413
+ document.removeEventListener("input", onInput, true);
414
+ document.removeEventListener("scroll", onScroll, true);
415
+ window.removeEventListener("popstate", onNavigation);
416
+ window.removeEventListener("hashchange", onNavigation);
417
+ if (history.pushState === patchedPushState) {
418
+ history.pushState = originalPushState;
419
+ }
420
+ if (history.replaceState === patchedReplaceState) {
421
+ history.replaceState = originalReplaceState;
422
+ }
317
423
  };
318
424
 
319
425
  const stop = () => {
@@ -331,10 +437,12 @@ export function createBrowserDiagnosticsCapture(): BrowserDiagnosticsCapture {
331
437
  endedAt,
332
438
  consoleLogs: [...consoleLogs],
333
439
  networkRequests: [...networkRequests],
440
+ interactionEvents: [...interactionEvents],
334
441
  };
335
442
  stoppedSnapshot = {
336
443
  ...snapshot,
337
444
  summary: summarizeBrowserDiagnostics(snapshot),
445
+ timeline: buildBrowserDiagnosticTimeline(snapshot),
338
446
  };
339
447
  return stoppedSnapshot;
340
448
  };
@@ -2140,6 +2140,7 @@ export default function RecordRoute() {
2140
2140
  endedAt: snapshot.endedAt,
2141
2141
  consoleLogs: snapshot.consoleLogs,
2142
2142
  networkRequests: snapshot.networkRequests,
2143
+ interactionEvents: snapshot.interactionEvents,
2143
2144
  } as any,
2144
2145
  );
2145
2146
  } catch (err) {
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: added
3
+ date: 2026-09-15
4
+ ---
5
+
6
+ Recordings include a structured timeline of browser interactions and diagnostics
@@ -46,6 +46,13 @@
46
46
  "run_at": "document_idle",
47
47
  "all_frames": false
48
48
  },
49
+ {
50
+ "matches": ["<all_urls>"],
51
+ "js": ["assets/content-history-bridge.js"],
52
+ "run_at": "document_start",
53
+ "world": "MAIN",
54
+ "all_frames": false
55
+ },
49
56
  {
50
57
  "matches": ["<all_urls>"],
51
58
  "js": ["assets/content-script.js"],