@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
@@ -1199,13 +1199,15 @@ export function EmailThread({
1199
1199
  <Tooltip>
1200
1200
  <TooltipTrigger asChild>
1201
1201
  <button
1202
+ type="button"
1202
1203
  onClick={goBack}
1204
+ aria-label={t("mail.thread.back")}
1203
1205
  className="mt-0.5 flex h-9 w-9 sm:h-7 sm:w-7 shrink-0 items-center justify-center rounded-full text-muted-foreground hover:text-foreground hover:bg-accent transition-colors"
1204
1206
  >
1205
1207
  <IconArrowLeft className="h-[14px] w-[14px] rtl:-scale-x-100" />
1206
1208
  </button>
1207
1209
  </TooltipTrigger>
1208
- <TooltipContent>Back (Esc)</TooltipContent>
1210
+ <TooltipContent>{t("mail.thread.back")} (Esc)</TooltipContent>
1209
1211
  </Tooltip>
1210
1212
 
1211
1213
  <div className="flex-1 min-w-0">
@@ -1288,7 +1290,9 @@ export function EmailThread({
1288
1290
  <Tooltip>
1289
1291
  <TooltipTrigger asChild>
1290
1292
  <button
1293
+ type="button"
1291
1294
  onClick={handleArchive}
1295
+ aria-label={t("mail.actions.archive")}
1292
1296
  className="flex h-7 w-7 items-center justify-center rounded text-muted-foreground hover:text-foreground hover:bg-accent transition-colors"
1293
1297
  >
1294
1298
  <IconArchive className="h-4 w-4" />
@@ -1302,7 +1306,9 @@ export function EmailThread({
1302
1306
  <Tooltip>
1303
1307
  <TooltipTrigger asChild>
1304
1308
  <button
1309
+ type="button"
1305
1310
  onClick={handleTrash}
1311
+ aria-label={t("mail.actions.moveToTrash")}
1306
1312
  className="flex h-7 w-7 items-center justify-center rounded text-muted-foreground hover:text-destructive hover:bg-destructive/10 transition-colors"
1307
1313
  >
1308
1314
  <IconTrash className="h-4 w-4" />
@@ -1314,13 +1320,17 @@ export function EmailThread({
1314
1320
  </Tooltip>
1315
1321
  )}
1316
1322
  <button
1323
+ type="button"
1317
1324
  onClick={() => goToSibling(-1)}
1325
+ aria-label={t("mail.thread.previousConversation")}
1318
1326
  className="flex h-7 w-7 items-center justify-center rounded text-muted-foreground hover:text-foreground hover:bg-accent transition-colors ms-1"
1319
1327
  >
1320
1328
  <IconChevronUp className="h-3.5 w-3.5" />
1321
1329
  </button>
1322
1330
  <button
1331
+ type="button"
1323
1332
  onClick={() => goToSibling(1)}
1333
+ aria-label={t("mail.thread.nextConversation")}
1324
1334
  className="flex h-7 w-7 items-center justify-center rounded text-muted-foreground hover:text-foreground hover:bg-accent transition-colors"
1325
1335
  >
1326
1336
  <IconChevronDown className="h-3.5 w-3.5" />
@@ -1329,9 +1339,14 @@ export function EmailThread({
1329
1339
  <Tooltip>
1330
1340
  <TooltipTrigger asChild>
1331
1341
  <button
1342
+ type="button"
1332
1343
  onClick={onToggleMaximize}
1344
+ aria-label={t(
1345
+ isMaximized
1346
+ ? "mail.thread.minimize"
1347
+ : "mail.thread.maximize",
1348
+ )}
1333
1349
  className="flex h-7 w-7 items-center justify-center rounded text-muted-foreground hover:text-foreground hover:bg-accent transition-colors ms-1"
1334
- aria-label={isMaximized ? "Minimize" : "Maximize"}
1335
1350
  aria-pressed={isMaximized}
1336
1351
  >
1337
1352
  {isMaximized ? (
@@ -1342,7 +1357,11 @@ export function EmailThread({
1342
1357
  </button>
1343
1358
  </TooltipTrigger>
1344
1359
  <TooltipContent>
1345
- {isMaximized ? "Minimize" : "Maximize"}
1360
+ {t(
1361
+ isMaximized
1362
+ ? "mail.thread.minimize"
1363
+ : "mail.thread.maximize",
1364
+ )}
1346
1365
  </TooltipContent>
1347
1366
  </Tooltip>
1348
1367
  )}
@@ -1574,6 +1593,7 @@ function ThreadLoadingState({
1574
1593
  to: { name: string; email: string }[];
1575
1594
  };
1576
1595
  }) {
1596
+ const t = useT();
1577
1597
  const threadSubject = preview?.subject?.replace(/^(Re|Fwd|Fw):\s*/i, "");
1578
1598
 
1579
1599
  return (
@@ -1583,13 +1603,15 @@ function ThreadLoadingState({
1583
1603
  <Tooltip>
1584
1604
  <TooltipTrigger asChild>
1585
1605
  <button
1606
+ type="button"
1586
1607
  onClick={onBack}
1608
+ aria-label={t("mail.thread.back")}
1587
1609
  className="mt-0.5 flex h-9 w-9 sm:h-7 sm:w-7 shrink-0 items-center justify-center rounded-full text-muted-foreground hover:text-foreground hover:bg-accent transition-colors"
1588
1610
  >
1589
1611
  <IconArrowLeft className="h-[14px] w-[14px] rtl:-scale-x-100" />
1590
1612
  </button>
1591
1613
  </TooltipTrigger>
1592
- <TooltipContent>Back (Esc)</TooltipContent>
1614
+ <TooltipContent>{t("mail.thread.back")} (Esc)</TooltipContent>
1593
1615
  </Tooltip>
1594
1616
 
1595
1617
  <div className="flex-1 min-w-0">
@@ -1811,7 +1833,7 @@ const ExpandedMessageCard = forwardRef<
1811
1833
  <div className="flex flex-col gap-1 text-[13px]">
1812
1834
  <div className="flex gap-3">
1813
1835
  <span className="w-10 shrink-0 text-muted-foreground/60">
1814
- From
1836
+ {t("mail.thread.from")}
1815
1837
  </span>
1816
1838
  <span className="text-foreground font-semibold">
1817
1839
  <button
@@ -1823,7 +1845,9 @@ const ExpandedMessageCard = forwardRef<
1823
1845
  </span>
1824
1846
  </div>
1825
1847
  <div className="flex gap-3">
1826
- <span className="w-10 shrink-0 text-muted-foreground/60">To</span>
1848
+ <span className="w-10 shrink-0 text-muted-foreground/60">
1849
+ {t("mail.thread.to")}
1850
+ </span>
1827
1851
  <span className="text-foreground">
1828
1852
  {email.to.map(renderContactLink)}
1829
1853
  </span>
@@ -1831,7 +1855,7 @@ const ExpandedMessageCard = forwardRef<
1831
1855
  {email.cc && email.cc.length > 0 && (
1832
1856
  <div className="flex gap-3">
1833
1857
  <span className="w-10 shrink-0 text-muted-foreground/60">
1834
- Cc
1858
+ {t("mail.thread.cc")}
1835
1859
  </span>
1836
1860
  <span className="text-foreground">
1837
1861
  {email.cc.map(renderContactLink)}
@@ -1847,7 +1871,7 @@ const ExpandedMessageCard = forwardRef<
1847
1871
  month: "long",
1848
1872
  day: "numeric",
1849
1873
  })}{" "}
1850
- at{" "}
1874
+ {t("mail.thread.at")}{" "}
1851
1875
  {new Date(email.date).toLocaleTimeString("en-US", {
1852
1876
  hour: "numeric",
1853
1877
  minute: "2-digit",
@@ -1855,7 +1879,9 @@ const ExpandedMessageCard = forwardRef<
1855
1879
  })}
1856
1880
  </span>
1857
1881
  <button
1882
+ type="button"
1858
1883
  onClick={() => setShowDetails(false)}
1884
+ aria-label={t("mail.thread.closeDetails")}
1859
1885
  className="text-muted-foreground/50 hover:text-foreground transition-colors"
1860
1886
  >
1861
1887
  <IconX className="h-3.5 w-3.5" />
@@ -1895,24 +1921,28 @@ const ExpandedMessageCard = forwardRef<
1895
1921
  <Tooltip>
1896
1922
  <TooltipTrigger asChild>
1897
1923
  <button
1924
+ type="button"
1898
1925
  onClick={(e) => {
1899
1926
  e.stopPropagation();
1900
1927
  onReply();
1901
1928
  }}
1929
+ aria-label={t("mail.compose.reply")}
1902
1930
  className="flex h-9 w-9 sm:h-6 sm:w-6 items-center justify-center rounded text-muted-foreground/40 hover:text-foreground transition-colors"
1903
1931
  >
1904
1932
  <IconArrowBackUp className="h-4 w-4 sm:h-[14px] sm:w-[14px] rtl:-scale-x-100" />
1905
1933
  </button>
1906
1934
  </TooltipTrigger>
1907
- <TooltipContent>Reply</TooltipContent>
1935
+ <TooltipContent>{t("mail.compose.reply")}</TooltipContent>
1908
1936
  </Tooltip>
1909
1937
  <Tooltip>
1910
1938
  <TooltipTrigger asChild>
1911
1939
  <button
1940
+ type="button"
1912
1941
  onClick={(e) => {
1913
1942
  e.stopPropagation();
1914
1943
  onReplyAll();
1915
1944
  }}
1945
+ aria-label={t("mail.mobileActions.replyAll")}
1916
1946
  className="flex h-9 w-9 sm:h-6 sm:w-6 items-center justify-center rounded text-muted-foreground/40 hover:text-foreground transition-colors"
1917
1947
  >
1918
1948
  <IconArrowBackUpDouble className="h-4 w-4 sm:h-[14px] sm:w-[14px] rtl:-scale-x-100" />
@@ -1925,16 +1955,18 @@ const ExpandedMessageCard = forwardRef<
1925
1955
  <Tooltip>
1926
1956
  <TooltipTrigger asChild>
1927
1957
  <button
1958
+ type="button"
1928
1959
  onClick={(e) => {
1929
1960
  e.stopPropagation();
1930
1961
  onForward();
1931
1962
  }}
1963
+ aria-label={t("mail.compose.forward")}
1932
1964
  className="flex h-9 w-9 sm:h-6 sm:w-6 items-center justify-center rounded text-muted-foreground/40 hover:text-foreground transition-colors"
1933
1965
  >
1934
1966
  <IconArrowForwardUp className="h-4 w-4 sm:h-[14px] sm:w-[14px] rtl:-scale-x-100" />
1935
1967
  </button>
1936
1968
  </TooltipTrigger>
1937
- <TooltipContent>Forward</TooltipContent>
1969
+ <TooltipContent>{t("mail.compose.forward")}</TooltipContent>
1938
1970
  </Tooltip>
1939
1971
  </div>
1940
1972
 
@@ -2036,6 +2068,8 @@ const ExpandedMessageCard = forwardRef<
2036
2068
  ))}
2037
2069
  {email.attachments.length > 1 && (
2038
2070
  <button
2071
+ type="button"
2072
+ aria-label={t("mail.thread.downloadAll")}
2039
2073
  onClick={() => {
2040
2074
  for (const att of email.attachments!) {
2041
2075
  const a = document.createElement("a");
@@ -3611,6 +3645,7 @@ function ThreadSearchBar({
3611
3645
  <input
3612
3646
  ref={inputRef}
3613
3647
  type="text"
3648
+ aria-label={t("mail.thread.searchConversationLabel")}
3614
3649
  value={query}
3615
3650
  onChange={(e) => onChange(e.target.value)}
3616
3651
  onKeyDown={handleKeyDown}
@@ -3630,37 +3665,45 @@ function ThreadSearchBar({
3630
3665
  <Tooltip>
3631
3666
  <TooltipTrigger asChild>
3632
3667
  <button
3668
+ type="button"
3633
3669
  onClick={onPrev}
3670
+ aria-label={t("mail.thread.previousMatch")}
3634
3671
  disabled={totalMatches === 0}
3635
3672
  className="flex h-8 w-8 sm:h-6 sm:w-6 items-center justify-center rounded text-muted-foreground hover:text-foreground hover:bg-accent transition-colors disabled:opacity-30 disabled:cursor-not-allowed"
3636
3673
  >
3637
3674
  <IconChevronUp className="h-3.5 w-3.5 sm:h-3 sm:w-3" />
3638
3675
  </button>
3639
3676
  </TooltipTrigger>
3640
- <TooltipContent>Previous match (Shift+Enter)</TooltipContent>
3677
+ <TooltipContent>
3678
+ {t("mail.thread.previousMatch")} (Shift+Enter)
3679
+ </TooltipContent>
3641
3680
  </Tooltip>
3642
3681
  <Tooltip>
3643
3682
  <TooltipTrigger asChild>
3644
3683
  <button
3684
+ type="button"
3645
3685
  onClick={onNext}
3686
+ aria-label={t("mail.thread.nextMatch")}
3646
3687
  disabled={totalMatches === 0}
3647
3688
  className="flex h-8 w-8 sm:h-6 sm:w-6 items-center justify-center rounded text-muted-foreground hover:text-foreground hover:bg-accent transition-colors disabled:opacity-30 disabled:cursor-not-allowed"
3648
3689
  >
3649
3690
  <IconChevronDown className="h-3.5 w-3.5 sm:h-3 sm:w-3" />
3650
3691
  </button>
3651
3692
  </TooltipTrigger>
3652
- <TooltipContent>Next match (Enter)</TooltipContent>
3693
+ <TooltipContent>{t("mail.thread.nextMatch")} (Enter)</TooltipContent>
3653
3694
  </Tooltip>
3654
3695
  <Tooltip>
3655
3696
  <TooltipTrigger asChild>
3656
3697
  <button
3698
+ type="button"
3657
3699
  onClick={onClose}
3700
+ aria-label={t("mail.thread.closeSearch")}
3658
3701
  className="flex h-8 w-8 sm:h-6 sm:w-6 items-center justify-center rounded text-muted-foreground hover:text-foreground hover:bg-accent transition-colors ms-1"
3659
3702
  >
3660
3703
  <IconX className="h-3.5 w-3.5 sm:h-3 sm:w-3" />
3661
3704
  </button>
3662
3705
  </TooltipTrigger>
3663
- <TooltipContent>Close (Esc)</TooltipContent>
3706
+ <TooltipContent>{t("mail.thread.closeSearch")} (Esc)</TooltipContent>
3664
3707
  </Tooltip>
3665
3708
  </div>
3666
3709
  </div>
@@ -363,18 +363,21 @@ export const InlineReplyComposer = forwardRef<
363
363
  <>
364
364
  <div className="flex items-center border-b border-border/30 px-4 pb-2">
365
365
  <span className="w-8 shrink-0 text-xs font-medium text-muted-foreground">
366
- To
366
+ {t("mail.compose.to")}
367
367
  </span>
368
368
  <RecipientInput
369
369
  value={draft.to}
370
370
  onChange={(val) => onUpdate(draft.id, { to: val })}
371
+ ariaLabel={t("mail.compose.toRecipients")}
371
372
  autoFocus={draft.mode === "forward"}
372
373
  field="to"
373
374
  onMoveRecipient={moveRecipient}
374
375
  />
375
376
  <button
376
377
  type="button"
377
- aria-label={showCcBcc ? "Hide Cc and Bcc" : "Show Cc and Bcc"}
378
+ aria-label={t(
379
+ showCcBcc ? "mail.compose.hideCcBcc" : "mail.compose.showCcBcc",
380
+ )}
378
381
  aria-expanded={showCcBcc}
379
382
  onClick={toggleCcBcc}
380
383
  className="p-1 text-muted-foreground transition-colors hover:text-foreground"
@@ -392,22 +395,24 @@ export const InlineReplyComposer = forwardRef<
392
395
  <>
393
396
  <div className="flex items-center border-b border-border/30 px-4">
394
397
  <span className="w-8 shrink-0 text-xs font-medium text-muted-foreground">
395
- Cc
398
+ {t("mail.compose.cc")}
396
399
  </span>
397
400
  <RecipientInput
398
401
  value={draft.cc ?? ""}
399
402
  onChange={(val) => onUpdate(draft.id, { cc: val })}
403
+ ariaLabel={t("mail.compose.ccRecipients")}
400
404
  field="cc"
401
405
  onMoveRecipient={moveRecipient}
402
406
  />
403
407
  </div>
404
408
  <div className="flex items-center border-b border-border/30 px-4">
405
409
  <span className="w-8 shrink-0 text-xs font-medium text-muted-foreground">
406
- Bcc
410
+ {t("mail.compose.bcc")}
407
411
  </span>
408
412
  <RecipientInput
409
413
  value={draft.bcc ?? ""}
410
414
  onChange={(val) => onUpdate(draft.id, { bcc: val })}
415
+ ariaLabel={t("mail.compose.bccRecipients")}
411
416
  field="bcc"
412
417
  onMoveRecipient={moveRecipient}
413
418
  />
@@ -499,6 +504,8 @@ export const InlineReplyComposer = forwardRef<
499
504
  <Tooltip>
500
505
  <TooltipTrigger asChild>
501
506
  <button
507
+ type="button"
508
+ aria-label={t("mail.compose.popOut")}
502
509
  onClick={() => onPopOut(draft.id)}
503
510
  className="flex h-9 w-9 sm:h-6 sm:w-6 items-center justify-center rounded text-muted-foreground/40 hover:text-foreground transition-colors"
504
511
  >
@@ -524,6 +531,8 @@ export const InlineReplyComposer = forwardRef<
524
531
  <Tooltip>
525
532
  <TooltipTrigger asChild>
526
533
  <button
534
+ type="button"
535
+ aria-label={t("mail.compose.popOut")}
527
536
  onClick={() => onPopOut(draft.id)}
528
537
  className="flex h-6 w-6 items-center justify-center rounded text-muted-foreground/40 hover:text-foreground transition-colors shrink-0"
529
538
  >
@@ -619,6 +628,8 @@ export const InlineReplyComposer = forwardRef<
619
628
  <Button
620
629
  variant="ghost"
621
630
  size="icon"
631
+ type="button"
632
+ aria-label={t("mail.compose.bold")}
622
633
  className="h-7 w-7"
623
634
  onClick={() => editorRef.current?.toggleBold()}
624
635
  >
@@ -632,6 +643,8 @@ export const InlineReplyComposer = forwardRef<
632
643
  <Button
633
644
  variant="ghost"
634
645
  size="icon"
646
+ type="button"
647
+ aria-label={t("mail.compose.italic")}
635
648
  className="h-7 w-7"
636
649
  onClick={() => editorRef.current?.toggleItalic()}
637
650
  >
@@ -645,6 +658,8 @@ export const InlineReplyComposer = forwardRef<
645
658
  <Button
646
659
  variant="ghost"
647
660
  size="icon"
661
+ type="button"
662
+ aria-label={t("mail.compose.insertLink")}
648
663
  className="h-7 w-7"
649
664
  onClick={() => editorRef.current?.setLink()}
650
665
  >
@@ -658,6 +673,8 @@ export const InlineReplyComposer = forwardRef<
658
673
  <Button
659
674
  variant="ghost"
660
675
  size="icon"
676
+ type="button"
677
+ aria-label={t("mail.compose.attachFile")}
661
678
  className="h-7 w-7"
662
679
  onClick={() => void handleAttach()}
663
680
  >
@@ -733,6 +750,8 @@ export const InlineReplyComposer = forwardRef<
733
750
  <Button
734
751
  variant="ghost"
735
752
  size="icon"
753
+ type="button"
754
+ aria-label={t("mail.compose.discardDraft")}
736
755
  className="h-7 w-7 text-muted-foreground hover:text-destructive"
737
756
  onClick={() => onDiscard(draft.id)}
738
757
  >
@@ -53,6 +53,7 @@ interface RecipientInputProps {
53
53
  value: string;
54
54
  onChange: (value: string) => void;
55
55
  placeholder?: string;
56
+ ariaLabel?: string;
56
57
  autoFocus?: boolean;
57
58
  /** Field identity; enables dragging chips between To/Cc/Bcc when paired with onMoveRecipient. */
58
59
  field?: RecipientField;
@@ -324,6 +325,7 @@ export function RecipientInput({
324
325
  value,
325
326
  onChange,
326
327
  placeholder,
328
+ ariaLabel,
327
329
  autoFocus,
328
330
  field,
329
331
  onMoveRecipient,
@@ -759,6 +761,9 @@ export function RecipientInput({
759
761
  </button>
760
762
  <button
761
763
  type="button"
764
+ aria-label={t("mail.recipients.removeRecipient", {
765
+ recipient: displayName,
766
+ })}
762
767
  onClick={() => removeRecipient(i)}
763
768
  className="ml-0.5 rounded-sm p-0.5 text-indigo-400 hover:bg-indigo-500/20 transition-colors"
764
769
  >
@@ -783,6 +788,9 @@ export function RecipientInput({
783
788
  <span className="max-w-[180px] truncate">{r}</span>
784
789
  <button
785
790
  type="button"
791
+ aria-label={t("mail.recipients.removeRecipient", {
792
+ recipient: r,
793
+ })}
786
794
  onClick={() => removeRecipient(i)}
787
795
  className="ml-0.5 rounded-sm p-0.5 hover:bg-foreground/10 transition-colors"
788
796
  >
@@ -798,6 +806,7 @@ export function RecipientInput({
798
806
  data-recipient-field={field}
799
807
  role="combobox"
800
808
  aria-autocomplete="list"
809
+ aria-label={ariaLabel ?? placeholder}
801
810
  aria-controls={
802
811
  showSuggestions && hasSuggestions ? suggestionListId : undefined
803
812
  }
@@ -1579,7 +1579,11 @@ function AppLayoutInner({ children }: AppLayoutProps) {
1579
1579
  <Tooltip>
1580
1580
  <TooltipTrigger asChild>
1581
1581
  <PopoverTrigger asChild>
1582
- <button className="flex items-center hover:opacity-90 transition-opacity ms-1">
1582
+ <button
1583
+ type="button"
1584
+ aria-label={t("mail.toolbar.accounts")}
1585
+ className="flex items-center hover:opacity-90 transition-opacity ms-1"
1586
+ >
1583
1587
  <div
1584
1588
  className="flex items-center"
1585
1589
  style={{
@@ -2914,6 +2918,9 @@ function AccountPopover({
2914
2918
  >
2915
2919
  {/* Checkbox */}
2916
2920
  <button
2921
+ type="button"
2922
+ aria-label={account.email}
2923
+ aria-pressed={isChecked}
2917
2924
  onClick={() => onToggleAccount(account.email)}
2918
2925
  className="shrink-0"
2919
2926
  >
@@ -76,6 +76,8 @@ const messages = {
76
76
  markUnread: "Mark unread",
77
77
  moveTo: "Move to",
78
78
  moveToTrash: "Move to Trash",
79
+ star: "Star",
80
+ unstar: "Unstar",
79
81
  },
80
82
  compose: {
81
83
  addImage: "Add an image",
@@ -87,6 +89,7 @@ const messages = {
87
89
  attachFile: "Attach file",
88
90
  bold: "Bold",
89
91
  cancel: "Cancel",
92
+ closeAllDrafts: "Close all drafts",
90
93
  code: "Code",
91
94
  deleteDraft: "Delete draft",
92
95
  deleteDrafts: "Delete drafts",
@@ -94,6 +97,7 @@ const messages = {
94
97
  discardDraft: "Discard draft",
95
98
  enterLinkUrl: "Enter the URL for the link.",
96
99
  forward: "Forward",
100
+ from: "From",
97
101
  fullScreen: "Full screen",
98
102
  fullScreenCompose: "Full screen compose",
99
103
  generate: "Generate",
@@ -105,19 +109,29 @@ const messages = {
105
109
  minimize: "Minimize",
106
110
  minimizeCompose: "Minimize compose",
107
111
  newDraft: "New draft",
112
+ newMessage: "New Message",
108
113
  pasteLink: "Paste link...",
109
114
  plainText: "Plain text",
110
115
  popOut: "Pop out to compose window",
111
116
  reply: "Reply",
112
117
  replyTo: "to {{recipient}}",
118
+ queuedDraft: "Queued draft",
113
119
  restore: "Restore",
114
120
  restoreCompose: "Restore compose",
115
121
  restoreComposeSize: "Restore compose size",
116
122
  restoreSize: "Restore size",
117
123
  send: "Send",
118
124
  sending: "Sending...",
125
+ hideCcBcc: "Hide Cc and Bcc",
126
+ showCcBcc: "Show Cc and Bcc",
119
127
  strikethrough: "Strikethrough",
120
128
  subject: "Subject",
129
+ to: "To",
130
+ toRecipients: "To recipients",
131
+ cc: "Cc",
132
+ ccRecipients: "Cc recipients",
133
+ bcc: "Bcc",
134
+ bccRecipients: "Bcc recipients",
121
135
  toSubmit: "to submit",
122
136
  uploading: "Uploading...",
123
137
  writeMessagePlaceholder: "Write your message...",
@@ -195,6 +209,7 @@ const messages = {
195
209
  expandToIndividualEmails: "Expand to individual emails",
196
210
  peopleCount: "{{count}} people",
197
211
  recipientCount: "{{count}} recipients",
212
+ removeRecipient: "Remove recipient {{recipient}}",
198
213
  saveAsAlias: "Save as alias",
199
214
  saving: "Saving...",
200
215
  },
@@ -230,15 +245,29 @@ const messages = {
230
245
  },
231
246
  thread: {
232
247
  alwaysFrom: "Always from {{domain}}",
248
+ at: "at",
249
+ back: "Back",
250
+ cc: "Cc",
251
+ closeDetails: "Close details",
252
+ closeSearch: "Close search",
233
253
  downloadAll: "Download all",
234
254
  emailContent: "Email content",
255
+ from: "From",
235
256
  hideQuotedText: "Hide quoted text",
236
257
  imagesBlocked: "Images blocked.",
258
+ maximize: "Maximize",
259
+ minimize: "Minimize",
260
+ nextConversation: "Next conversation",
261
+ nextMatch: "Next match",
262
+ previousConversation: "Previous conversation",
263
+ previousMatch: "Previous match",
237
264
  remoteImagesHidden: "Remote images hidden in this embed.",
238
265
  searchConversation: "Search in conversation...",
266
+ searchConversationLabel: "Search in conversation",
239
267
  showImages: "Show images",
240
268
  showQuotedText: "Show quoted text",
241
269
  showSignature: "Show signature",
270
+ to: "To",
242
271
  unsubscribe: "Unsubscribe",
243
272
  unsubscribeTooltip: "Unsubscribe from this mailing list",
244
273
  unsubscribing: "Unsubscribing...",
@@ -249,6 +278,8 @@ const messages = {
249
278
  actions: "Selection actions",
250
279
  selected: "{{count}} selected",
251
280
  select: "Select",
281
+ selectEmail: "Select email",
282
+ deselectEmail: "Deselect email",
252
283
  all: "All",
253
284
  none: "None",
254
285
  read: "Read",
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-09-15
4
+ ---
5
+
6
+ Mail labels recipient and account controls for keyboard and assistive-technology parity.
@@ -3,6 +3,38 @@
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-14
7
+
8
+ ### Improved
9
+
10
+ - Deck filter button now shows when the list is limited to your own decks.
11
+ - Slides comments can now target slide objects and positions with full thread actions, reactions, and Google-style shortcut behavior.
12
+
13
+ ### Fixed
14
+
15
+ - An attached PDF, PowerPoint, or Word reference is now read before a new deck is generated, and its typography, palette, and page proportions steer the design instead of being silently dropped
16
+ - Creating a design system no longer fails silently when Builder indexing is unavailable.
17
+ - Design system creation from onboarding now opens inline instead of a new tab, so onboarding progress is no longer lost
18
+ - Every icon in the collapsed left sidebar now shows its name on hover
19
+ - Sending a selection, drawing, or pending update to the agent now opens the agent panel instead of appearing to do nothing.
20
+ - Style requests like matching one slide's background across the deck now succeed instead of failing after repeated rejected edits.
21
+ - Switching organizations now shows only decks from the current organization
22
+
23
+ ### Changed
24
+
25
+ - Creative Context is now in Labs and off by default
26
+
27
+ ## 2026-09-13
28
+
29
+ ### Improved
30
+
31
+ - Control+M adds a slide with the current slide's layout.
32
+
33
+ ### Fixed
34
+
35
+ - Slides support keyboard navigation, selection, and reordering in the slide rail.
36
+ - Slides route navigation, selection, clipboard, and reorder shortcuts through the focused editor surface.
37
+
6
38
  ## 2026-09-12
7
39
 
8
40
  ### Fixed
@@ -16,7 +16,7 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
16
16
  * </CommandMenu>
17
17
  */
18
18
  import { Command as CommandPrimitive, CommandGroup as CommandGroupPrimitive, CommandInput as CommandInputPrimitive, CommandItem as CommandItemPrimitive, CommandList as CommandListPrimitive, CommandSeparator as CommandSeparatorPrimitive, CommandShortcut as CommandShortcutPrimitive, } from "@agent-native/toolkit/ui/command";
19
- import { IconBook2, IconExternalLink, IconInfoCircle, IconMessage, IconHistory, } from "@tabler/icons-react";
19
+ import { IconBook2, IconExternalLink, IconInfoCircle, IconMessage, IconHistory, IconLogout, } from "@tabler/icons-react";
20
20
  import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, } from "react";
21
21
  import { parseChangelog } from "../changelog/parse.js";
22
22
  import { AboutAgentNativeDialog } from "./AboutAgentNativeDialog.js";
@@ -24,6 +24,7 @@ import { sendToAgentChat } from "./agent-chat.js";
24
24
  import { ChangelogDialog, useChangelogSeen } from "./changelog/Changelog.js";
25
25
  import { Dialog, DialogContent, DialogTitle } from "./components/ui/dialog.js";
26
26
  import { useT } from "./i18n.js";
27
+ import { signOut, SIGN_OUT_SEARCH_TERMS } from "./sign-out.js";
27
28
  import { cn } from "./utils.js";
28
29
  const CommandMenuContext = createContext(null);
29
30
  function useCommandMenuContext() {
@@ -235,6 +236,16 @@ export function CommandMenu({ open, onOpenChange, children, renderResults, rende
235
236
  .toLowerCase()
236
237
  .includes(search.toLowerCase());
237
238
  const showAboutRow = showAbout && aboutRowMatches;
239
+ const signOutLabel = t("agentChat.auth.logOut");
240
+ const showSignOutRow = !search ||
241
+ [signOutLabel, ...SIGN_OUT_SEARCH_TERMS]
242
+ .join(" ")
243
+ .toLowerCase()
244
+ .includes(search.toLowerCase());
245
+ const handleSignOut = useCallback(() => {
246
+ onOpenChange(false);
247
+ void signOut();
248
+ }, [onOpenChange]);
238
249
  // Filter children based on search
239
250
  const filterChildren = (nodes) => {
240
251
  return React.Children.map(nodes, (child) => {
@@ -298,9 +309,10 @@ export function CommandMenu({ open, onOpenChange, children, renderResults, rende
298
309
  const hasResults = React.Children.toArray(filteredChildren).some((child) => React.isValidElement(child) &&
299
310
  (child.type === CommandGroup || child.type === CommandDocsGroup));
300
311
  const dynamicResults = open ? renderResults?.(search) : null;
301
- const renderList = (results = dynamicResults) => (_jsxs(CommandListPrimitive, { children: [results, hasResults && filteredChildren, showChangelogRow && (_jsxs(_Fragment, { children: [hasResults && _jsx(CommandSeparator, {}), _jsx("div", { className: "p-1", children: _jsxs(CommandItemPrimitive, { className: "cursor-pointer gap-2 py-2", onSelect: openChangelog, children: [_jsx(IconHistory, { className: "h-4 w-4 text-muted-foreground" }), _jsx("span", { children: changelogLabel }), changelogUnseen && (_jsx("span", { className: "ms-auto h-2 w-2 rounded-full bg-primary", "aria-label": "New updates available" }))] }) })] })), showAboutRow && (_jsxs(_Fragment, { children: [(hasResults || showChangelogRow) && _jsx(CommandSeparator, {}), _jsx("div", { className: "p-1", children: _jsxs(CommandItemPrimitive, { className: "cursor-pointer gap-2 py-2", onSelect: openAbout, children: [_jsx(IconInfoCircle, { className: "h-4 w-4 text-muted-foreground" }), _jsx("span", { children: aboutLabel })] }) })] })), showAgentFallback && (_jsxs(_Fragment, { children: [(hasResults ||
312
+ const renderList = (results = dynamicResults) => (_jsxs(CommandListPrimitive, { children: [results, hasResults && filteredChildren, showChangelogRow && (_jsxs(_Fragment, { children: [hasResults && _jsx(CommandSeparator, {}), _jsx("div", { className: "p-1", children: _jsxs(CommandItemPrimitive, { className: "cursor-pointer gap-2 py-2", onSelect: openChangelog, children: [_jsx(IconHistory, { className: "h-4 w-4 text-muted-foreground" }), _jsx("span", { children: changelogLabel }), changelogUnseen && (_jsx("span", { className: "ms-auto h-2 w-2 rounded-full bg-primary", "aria-label": "New updates available" }))] }) })] })), showAboutRow && (_jsxs(_Fragment, { children: [(hasResults || showChangelogRow) && _jsx(CommandSeparator, {}), _jsx("div", { className: "p-1", children: _jsxs(CommandItemPrimitive, { className: "cursor-pointer gap-2 py-2", onSelect: openAbout, children: [_jsx(IconInfoCircle, { className: "h-4 w-4 text-muted-foreground" }), _jsx("span", { children: aboutLabel })] }) })] })), showSignOutRow && (_jsxs(_Fragment, { children: [(hasResults || showChangelogRow || showAboutRow) && (_jsx(CommandSeparator, {})), _jsx("div", { className: "p-1", children: _jsxs(CommandItemPrimitive, { className: "cursor-pointer gap-2 py-2", onSelect: handleSignOut, children: [_jsx(IconLogout, { className: "h-4 w-4 text-muted-foreground rtl:-scale-x-100" }), _jsx("span", { children: signOutLabel })] }) })] })), showAgentFallback && (_jsxs(_Fragment, { children: [(hasResults ||
302
313
  showChangelogRow ||
303
314
  showAboutRow ||
315
+ showSignOutRow ||
304
316
  Boolean(results)) && _jsx(CommandSeparator, {}), _jsx("div", { className: "p-1", children: _jsxs(CommandItemPrimitive, { className: "cursor-pointer gap-2 py-2", onSelect: handleSubmitToAgent, children: [_jsx(IconMessage, { className: "h-4 w-4 text-muted-foreground" }), _jsx("span", { children: search.trim() ? (_jsxs(_Fragment, { children: ["Ask AI:", " ", _jsxs("span", { className: "text-muted-foreground", children: ["\"", search, "\""] })] })) : (_jsx("span", { className: "text-muted-foreground", children: "Ask AI anything..." })) }), search.trim() && (_jsx("span", { className: "ms-auto text-xs text-muted-foreground", children: "\u21B5" }))] }) })] }))] }));
305
317
  return (_jsxs(_Fragment, { children: [_jsx(Dialog, { open: open, onOpenChange: (nextOpen) => {
306
318
  if (!nextOpen && nestedDialogsRef.current.length > 0)