@agent-native/core-corpus 0.217.0 → 0.218.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.
- package/corpus/README.md +1 -1
- package/corpus/templates/analytics/CHANGELOG.md +2 -0
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +38 -167
- package/corpus/templates/analytics/changelog/2026-10-16-owned-and-shared-chats-appear-in-separate-history-sections.md +6 -0
- package/corpus/templates/assets/CHANGELOG.md +6 -0
- package/corpus/templates/assets/app/components/layout/Sidebar.tsx +51 -117
- package/corpus/templates/assets/changelog/2026-10-16-owned-and-shared-chats-appear-in-separate-history-sections.md +6 -0
- package/corpus/templates/brain/app/components/layout/Sidebar.tsx +34 -101
- package/corpus/templates/brain/app/routes/sources.tsx +1 -1
- package/corpus/templates/brain/vitest.config.ts +7 -0
- package/corpus/templates/calendar/CHANGELOG.md +6 -0
- package/corpus/templates/calendar/app/pages/BookingLinksPage.tsx +1 -1
- package/corpus/templates/calendar/changelog/2026-10-16-booking-links-show-localized-visibility-badges.md +6 -0
- package/corpus/templates/chat/app/components/layout/Sidebar.tsx +62 -101
- package/corpus/templates/clips/CHANGELOG.md +7 -20
- package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +20 -77
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +63 -90
- package/corpus/templates/clips/app/components/sharing/share-test-support.tsx +180 -0
- package/corpus/templates/clips/app/components/sharing/share-ui.tsx +5 -584
- package/corpus/templates/clips/changelog/2026-10-16-share-dialogs-make-it-easier-to-see-who-has-access-and-manag.md +6 -0
- package/corpus/templates/clips/changelog/2026-10-21-share-panels-describe-general-access-in-a-sentence.md +6 -0
- package/corpus/templates/community/qr/package.json +1 -1
- package/corpus/templates/content/CHANGELOG.md +2 -0
- package/corpus/templates/content/app/components/editor/CommentsSidebar.tsx +119 -30
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +56 -13
- package/corpus/templates/content/app/components/editor/SuggestionText.tsx +18 -3
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +89 -22
- package/corpus/templates/content/app/components/editor/extensions/SuggestionHighlight.ts +383 -34
- package/corpus/templates/content/app/components/editor/suggestions/draft-session.ts +31 -0
- package/corpus/templates/content/app/components/editor/suggestions/presentation-rebase.ts +82 -4
- package/corpus/templates/content/app/global.css +31 -0
- package/corpus/templates/content/changelog/2026-10-16-accepting-a-suggestion-on-a-page-that-changed-since-it-was-s.md +6 -0
- package/corpus/templates/content/changelog/2026-10-20-suggested-edits-that-add-remove-split-or-merge-paragraphs-li.md +6 -0
- package/corpus/templates/content/shared/suggestion-diff.ts +23 -6
- package/corpus/templates/content/shared/suggestion-formatting.ts +44 -14
- package/corpus/templates/content/shared/suggestion-text.ts +20 -5
- package/corpus/templates/design/CHANGELOG.md +3 -0
- package/corpus/templates/design/app/pages/DesignSystems.tsx +1 -1
- package/corpus/templates/design/app/pages/Index.tsx +18 -64
- package/corpus/templates/design/changelog/2026-10-16-design-pages-use-localized-visibility-badges-and-a-shared-ow.md +6 -0
- package/corpus/templates/dispatch/CHANGELOG.md +4 -0
- package/corpus/templates/dispatch/app/i18n-data.ts +75 -0
- package/corpus/templates/dispatch/changelog/2026-10-21-owned-and-shared-chats-appear-in-separate-history-sections.md +6 -0
- package/corpus/templates/factory/app/components/layout/Sidebar.tsx +34 -100
- package/corpus/templates/forms/app/pages/FormsListPage.tsx +1 -1
- package/corpus/templates/plan/CHANGELOG.md +6 -0
- package/corpus/templates/plan/app/components/layout/Sidebar.tsx +34 -109
- package/corpus/templates/plan/changelog/2026-10-16-owned-and-shared-chats-appear-in-separate-history-sections.md +6 -0
- package/corpus/templates/slides/CHANGELOG.md +1 -0
- package/corpus/templates/slides/app/components/deck/DeckCard.tsx +1 -1
- package/corpus/templates/slides/app/components/design-system/DesignSystemCard.tsx +1 -1
- package/corpus/templates/slides/app/pages/Index.tsx +7 -2
- package/corpus/templates/slides/changelog/2026-10-16-deck-lists-use-the-shared-ownership-filter-and-visibility-ba.md +6 -0
- package/package.json +1 -1
- package/corpus/templates/chat/app/lib/sidebar-thread-state.ts +0 -29
- package/corpus/templates/slides/app/components/deck/DeckFilterMenu.tsx +0 -83
|
@@ -312,6 +312,10 @@ const enUS = {
|
|
|
312
312
|
},
|
|
313
313
|
},
|
|
314
314
|
dispatch: {
|
|
315
|
+
sidebar: {
|
|
316
|
+
showLocalChats: "Show local chats",
|
|
317
|
+
showAllChats: "Show all chats",
|
|
318
|
+
},
|
|
315
319
|
nav: {
|
|
316
320
|
admin: "Admin",
|
|
317
321
|
automations: "Automations",
|
|
@@ -324,6 +328,9 @@ const enUS = {
|
|
|
324
328
|
agent: "Agent",
|
|
325
329
|
},
|
|
326
330
|
pages: {
|
|
331
|
+
chatFirstCopySessionId: "Copy session ID",
|
|
332
|
+
chatFirstSessionIdCopied: "Session ID copied",
|
|
333
|
+
chatFirstWatchSession: "Watch",
|
|
327
334
|
adminDescription: "Workspace controls and operations",
|
|
328
335
|
simpleAgentsDescription:
|
|
329
336
|
"Create reusable agents in minutes, or import a setup you already made in Claude or another agent tool.",
|
|
@@ -595,6 +602,7 @@ type PartialMessages = {
|
|
|
595
602
|
} & Record<string, unknown>
|
|
596
603
|
: K extends "dispatch"
|
|
597
604
|
? {
|
|
605
|
+
sidebar?: Partial<Messages["dispatch"]["sidebar"]>;
|
|
598
606
|
nav?: Partial<Messages["dispatch"]["nav"]> & Record<string, unknown>;
|
|
599
607
|
pages?: Partial<Messages["dispatch"]["pages"]> &
|
|
600
608
|
Record<string, unknown>;
|
|
@@ -1251,6 +1259,10 @@ function mergeMessages(
|
|
|
1251
1259
|
dispatch: {
|
|
1252
1260
|
...enUS.dispatch,
|
|
1253
1261
|
...overrides.dispatch,
|
|
1262
|
+
sidebar: {
|
|
1263
|
+
...enUS.dispatch.sidebar,
|
|
1264
|
+
...overrides.dispatch?.sidebar,
|
|
1265
|
+
},
|
|
1254
1266
|
nav: {
|
|
1255
1267
|
...enUS.dispatch.nav,
|
|
1256
1268
|
...(overrides.dispatch as { nav?: Record<string, string> } | undefined)
|
|
@@ -1537,6 +1549,10 @@ export const messagesByLocale = {
|
|
|
1537
1549
|
},
|
|
1538
1550
|
|
|
1539
1551
|
dispatch: {
|
|
1552
|
+
sidebar: {
|
|
1553
|
+
showLocalChats: "显示本地聊天",
|
|
1554
|
+
showAllChats: "显示所有聊天",
|
|
1555
|
+
},
|
|
1540
1556
|
nav: {
|
|
1541
1557
|
admin: "管理",
|
|
1542
1558
|
automations: "自动化",
|
|
@@ -1549,6 +1565,9 @@ export const messagesByLocale = {
|
|
|
1549
1565
|
agent: "代理",
|
|
1550
1566
|
},
|
|
1551
1567
|
pages: {
|
|
1568
|
+
chatFirstCopySessionId: "复制会话 ID",
|
|
1569
|
+
chatFirstSessionIdCopied: "会话 ID 已复制",
|
|
1570
|
+
chatFirstWatchSession: "观看",
|
|
1552
1571
|
...chatFirstPageTranslations["zh-CN"],
|
|
1553
1572
|
adminDescription: "工作区控制与运营",
|
|
1554
1573
|
connectApps: "连接应用",
|
|
@@ -1989,6 +2008,10 @@ export const messagesByLocale = {
|
|
|
1989
2008
|
},
|
|
1990
2009
|
|
|
1991
2010
|
dispatch: {
|
|
2011
|
+
sidebar: {
|
|
2012
|
+
showLocalChats: "Mostrar chats locales",
|
|
2013
|
+
showAllChats: "Mostrar todos los chats",
|
|
2014
|
+
},
|
|
1992
2015
|
nav: {
|
|
1993
2016
|
admin: "Administración",
|
|
1994
2017
|
automations: "Automatizaciones",
|
|
@@ -2001,6 +2024,9 @@ export const messagesByLocale = {
|
|
|
2001
2024
|
agent: "Agente",
|
|
2002
2025
|
},
|
|
2003
2026
|
pages: {
|
|
2027
|
+
chatFirstCopySessionId: "Copiar ID de sesión",
|
|
2028
|
+
chatFirstSessionIdCopied: "ID de sesión copiado",
|
|
2029
|
+
chatFirstWatchSession: "Observar",
|
|
2004
2030
|
...chatFirstPageTranslations["es-ES"],
|
|
2005
2031
|
adminDescription: "Controles y operaciones del espacio de trabajo",
|
|
2006
2032
|
connectApps: "Conectar apps",
|
|
@@ -2455,6 +2481,10 @@ export const messagesByLocale = {
|
|
|
2455
2481
|
},
|
|
2456
2482
|
|
|
2457
2483
|
dispatch: {
|
|
2484
|
+
sidebar: {
|
|
2485
|
+
showLocalChats: "Afficher les conversations locales",
|
|
2486
|
+
showAllChats: "Afficher toutes les conversations",
|
|
2487
|
+
},
|
|
2458
2488
|
nav: {
|
|
2459
2489
|
admin: "Administration",
|
|
2460
2490
|
automations: "Automatisations",
|
|
@@ -2467,6 +2497,9 @@ export const messagesByLocale = {
|
|
|
2467
2497
|
agent: "Agent",
|
|
2468
2498
|
},
|
|
2469
2499
|
pages: {
|
|
2500
|
+
chatFirstCopySessionId: "Copier l’identifiant de session",
|
|
2501
|
+
chatFirstSessionIdCopied: "Identifiant de session copié",
|
|
2502
|
+
chatFirstWatchSession: "Observer",
|
|
2470
2503
|
...chatFirstPageTranslations["fr-FR"],
|
|
2471
2504
|
adminDescription: "Contrôles et opérations de l’espace de travail",
|
|
2472
2505
|
connectApps: "Connecter des apps",
|
|
@@ -2912,6 +2945,10 @@ export const messagesByLocale = {
|
|
|
2912
2945
|
},
|
|
2913
2946
|
|
|
2914
2947
|
dispatch: {
|
|
2948
|
+
sidebar: {
|
|
2949
|
+
showLocalChats: "Lokale Chats anzeigen",
|
|
2950
|
+
showAllChats: "Alle Chats anzeigen",
|
|
2951
|
+
},
|
|
2915
2952
|
nav: {
|
|
2916
2953
|
admin: "Administration",
|
|
2917
2954
|
automations: "Automatisierungen",
|
|
@@ -2924,6 +2961,9 @@ export const messagesByLocale = {
|
|
|
2924
2961
|
agent: "Agent",
|
|
2925
2962
|
},
|
|
2926
2963
|
pages: {
|
|
2964
|
+
chatFirstCopySessionId: "Sitzungs-ID kopieren",
|
|
2965
|
+
chatFirstSessionIdCopied: "Sitzungs-ID kopiert",
|
|
2966
|
+
chatFirstWatchSession: "Beobachten",
|
|
2927
2967
|
...chatFirstPageTranslations["de-DE"],
|
|
2928
2968
|
adminDescription: "Arbeitsbereichssteuerung und -betrieb",
|
|
2929
2969
|
connectApps: "Apps verbinden",
|
|
@@ -3363,6 +3403,10 @@ export const messagesByLocale = {
|
|
|
3363
3403
|
},
|
|
3364
3404
|
|
|
3365
3405
|
dispatch: {
|
|
3406
|
+
sidebar: {
|
|
3407
|
+
showLocalChats: "ローカルのチャットを表示",
|
|
3408
|
+
showAllChats: "すべてのチャットを表示",
|
|
3409
|
+
},
|
|
3366
3410
|
nav: {
|
|
3367
3411
|
admin: "管理",
|
|
3368
3412
|
automations: "自動化",
|
|
@@ -3375,6 +3419,9 @@ export const messagesByLocale = {
|
|
|
3375
3419
|
agent: "エージェント",
|
|
3376
3420
|
},
|
|
3377
3421
|
pages: {
|
|
3422
|
+
chatFirstCopySessionId: "セッション ID をコピー",
|
|
3423
|
+
chatFirstSessionIdCopied: "セッション ID をコピーしました",
|
|
3424
|
+
chatFirstWatchSession: "ウォッチ",
|
|
3378
3425
|
...chatFirstPageTranslations["ja-JP"],
|
|
3379
3426
|
adminDescription: "ワークスペースの管理と運用",
|
|
3380
3427
|
connectApps: "アプリを接続",
|
|
@@ -3808,6 +3855,10 @@ export const messagesByLocale = {
|
|
|
3808
3855
|
},
|
|
3809
3856
|
|
|
3810
3857
|
dispatch: {
|
|
3858
|
+
sidebar: {
|
|
3859
|
+
showLocalChats: "로컬 채팅 표시",
|
|
3860
|
+
showAllChats: "모든 채팅 표시",
|
|
3861
|
+
},
|
|
3811
3862
|
nav: {
|
|
3812
3863
|
admin: "관리",
|
|
3813
3864
|
automations: "자동화",
|
|
@@ -3820,6 +3871,9 @@ export const messagesByLocale = {
|
|
|
3820
3871
|
agent: "에이전트",
|
|
3821
3872
|
},
|
|
3822
3873
|
pages: {
|
|
3874
|
+
chatFirstCopySessionId: "세션 ID 복사",
|
|
3875
|
+
chatFirstSessionIdCopied: "세션 ID가 복사되었습니다",
|
|
3876
|
+
chatFirstWatchSession: "지켜보기",
|
|
3823
3877
|
...chatFirstPageTranslations["ko-KR"],
|
|
3824
3878
|
adminDescription: "워크스페이스 제어 및 운영",
|
|
3825
3879
|
connectApps: "앱 연결",
|
|
@@ -4261,6 +4315,10 @@ export const messagesByLocale = {
|
|
|
4261
4315
|
},
|
|
4262
4316
|
|
|
4263
4317
|
dispatch: {
|
|
4318
|
+
sidebar: {
|
|
4319
|
+
showLocalChats: "Mostrar conversas locais",
|
|
4320
|
+
showAllChats: "Mostrar todas as conversas",
|
|
4321
|
+
},
|
|
4264
4322
|
nav: {
|
|
4265
4323
|
admin: "Administração",
|
|
4266
4324
|
automations: "Automações",
|
|
@@ -4273,6 +4331,9 @@ export const messagesByLocale = {
|
|
|
4273
4331
|
agent: "Agente",
|
|
4274
4332
|
},
|
|
4275
4333
|
pages: {
|
|
4334
|
+
chatFirstCopySessionId: "Copiar ID da sessão",
|
|
4335
|
+
chatFirstSessionIdCopied: "ID da sessão copiado",
|
|
4336
|
+
chatFirstWatchSession: "Observar",
|
|
4276
4337
|
...chatFirstPageTranslations["pt-BR"],
|
|
4277
4338
|
adminDescription: "Controles e operações do espaço de trabalho",
|
|
4278
4339
|
connectApps: "Conectar apps",
|
|
@@ -4707,6 +4768,10 @@ export const messagesByLocale = {
|
|
|
4707
4768
|
},
|
|
4708
4769
|
|
|
4709
4770
|
dispatch: {
|
|
4771
|
+
sidebar: {
|
|
4772
|
+
showLocalChats: "स्थानीय चैट दिखाएँ",
|
|
4773
|
+
showAllChats: "सभी चैट दिखाएँ",
|
|
4774
|
+
},
|
|
4710
4775
|
nav: {
|
|
4711
4776
|
admin: "व्यवस्थापक",
|
|
4712
4777
|
automations: "ऑटोमेशन",
|
|
@@ -4719,6 +4784,9 @@ export const messagesByLocale = {
|
|
|
4719
4784
|
agent: "एजेंट",
|
|
4720
4785
|
},
|
|
4721
4786
|
pages: {
|
|
4787
|
+
chatFirstCopySessionId: "सत्र ID कॉपी करें",
|
|
4788
|
+
chatFirstSessionIdCopied: "सत्र ID कॉपी किया गया",
|
|
4789
|
+
chatFirstWatchSession: "देखें",
|
|
4722
4790
|
...chatFirstPageTranslations["hi-IN"],
|
|
4723
4791
|
adminDescription: "वर्कस्पेस नियंत्रण और संचालन",
|
|
4724
4792
|
connectApps: "ऐप कनेक्ट करें",
|
|
@@ -5181,6 +5249,10 @@ export const messagesByLocale = {
|
|
|
5181
5249
|
},
|
|
5182
5250
|
|
|
5183
5251
|
dispatch: {
|
|
5252
|
+
sidebar: {
|
|
5253
|
+
showLocalChats: "إظهار المحادثات المحلية",
|
|
5254
|
+
showAllChats: "إظهار جميع المحادثات",
|
|
5255
|
+
},
|
|
5184
5256
|
nav: {
|
|
5185
5257
|
admin: "الإدارة",
|
|
5186
5258
|
automations: "الأتمتة",
|
|
@@ -5193,6 +5265,9 @@ export const messagesByLocale = {
|
|
|
5193
5265
|
agent: "الوكيل",
|
|
5194
5266
|
},
|
|
5195
5267
|
pages: {
|
|
5268
|
+
chatFirstCopySessionId: "نسخ معرّف الجلسة",
|
|
5269
|
+
chatFirstSessionIdCopied: "تم نسخ معرّف الجلسة",
|
|
5270
|
+
chatFirstWatchSession: "مشاهدة",
|
|
5196
5271
|
...chatFirstPageTranslations["ar-SA"],
|
|
5197
5272
|
adminDescription: "عناصر التحكم في مساحة العمل وعملياتها",
|
|
5198
5273
|
connectApps: "توصيل التطبيقات",
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
navigateWithAgentChatViewTransition,
|
|
3
3
|
useChatThreads,
|
|
4
|
-
type ChatThreadSummary,
|
|
5
4
|
} from "@agent-native/core/client/agent-chat";
|
|
5
|
+
import { appPath } from "@agent-native/core/client/api-path";
|
|
6
6
|
import { useT } from "@agent-native/core/client/i18n";
|
|
7
|
+
import {
|
|
8
|
+
OwnershipChatHistoryRail,
|
|
9
|
+
useOwnershipChatHistory,
|
|
10
|
+
ownDraftRows,
|
|
11
|
+
} from "@agent-native/toolkit/app/chat/ownership-history";
|
|
7
12
|
import { FeedbackButton } from "@agent-native/toolkit/app/feedback";
|
|
8
13
|
import { OrgSwitcher } from "@agent-native/toolkit/app/org";
|
|
9
14
|
import { openCommandMenu } from "@agent-native/toolkit/app/shared";
|
|
@@ -11,17 +16,12 @@ import {
|
|
|
11
16
|
AppSidebar,
|
|
12
17
|
AppSidebarNavItem,
|
|
13
18
|
} from "@agent-native/toolkit/app/shared";
|
|
14
|
-
import {
|
|
15
|
-
ChatHistoryRail,
|
|
16
|
-
type ChatHistoryItem,
|
|
17
|
-
} from "@agent-native/toolkit/chat-history";
|
|
18
19
|
import {
|
|
19
20
|
IconGitPullRequest,
|
|
20
21
|
IconHierarchy2,
|
|
21
22
|
IconMessageCircle,
|
|
22
23
|
IconSearch,
|
|
23
24
|
} from "@tabler/icons-react";
|
|
24
|
-
import { useEffect, useMemo } from "react";
|
|
25
25
|
import { useLocation, useNavigate } from "react-router";
|
|
26
26
|
import { toast } from "sonner";
|
|
27
27
|
|
|
@@ -42,40 +42,6 @@ interface SidebarProps {
|
|
|
42
42
|
onCollapsedChange?: (collapsed: boolean) => void;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
function formatThreadAge(updatedAt: number) {
|
|
46
|
-
const diffMs = Math.max(0, Date.now() - updatedAt);
|
|
47
|
-
const minutes = Math.floor(diffMs / 60_000);
|
|
48
|
-
if (minutes < 1) return "now";
|
|
49
|
-
if (minutes < 60) return `${minutes}m`;
|
|
50
|
-
const hours = Math.floor(minutes / 60);
|
|
51
|
-
if (hours < 24) return `${hours}h`;
|
|
52
|
-
const days = Math.floor(hours / 24);
|
|
53
|
-
if (days < 7) return `${days}d`;
|
|
54
|
-
return new Date(updatedAt).toLocaleDateString([], {
|
|
55
|
-
month: "short",
|
|
56
|
-
day: "numeric",
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function threadTitle(thread: ChatThreadSummary) {
|
|
61
|
-
return thread.title || thread.preview || "Untitled chat";
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function threadUpdatedAt(thread: ChatThreadSummary) {
|
|
65
|
-
return Number.isFinite(thread.updatedAt)
|
|
66
|
-
? thread.updatedAt
|
|
67
|
-
: Number.isFinite(thread.createdAt)
|
|
68
|
-
? thread.createdAt
|
|
69
|
-
: 0;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function compareThreads(a: ChatThreadSummary, b: ChatThreadSummary) {
|
|
73
|
-
const aPinned = a.pinnedAt ?? 0;
|
|
74
|
-
const bPinned = b.pinnedAt ?? 0;
|
|
75
|
-
if (aPinned || bPinned) return bPinned - aPinned;
|
|
76
|
-
return threadUpdatedAt(b) - threadUpdatedAt(a);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
45
|
function persistedActiveThreadId() {
|
|
80
46
|
try {
|
|
81
47
|
return localStorage.getItem(CHAT_ACTIVE_THREAD_KEY);
|
|
@@ -120,56 +86,37 @@ function ChatThreadsSection({ open }: { open: boolean }) {
|
|
|
120
86
|
pinThread,
|
|
121
87
|
archiveThread,
|
|
122
88
|
renameThread,
|
|
123
|
-
|
|
89
|
+
isNewThread,
|
|
124
90
|
} = useChatThreads(undefined, CHAT_STORAGE_KEY, undefined, {
|
|
91
|
+
ownership: "mine",
|
|
125
92
|
autoCreate: false,
|
|
126
93
|
restoreActiveThread: false,
|
|
127
94
|
});
|
|
128
95
|
|
|
129
|
-
const visibleThreads = useMemo(
|
|
130
|
-
() =>
|
|
131
|
-
threads
|
|
132
|
-
.filter((thread) => thread.messageCount > 0 && !thread.archivedAt)
|
|
133
|
-
.sort(compareThreads)
|
|
134
|
-
.slice(0, 15),
|
|
135
|
-
[threads],
|
|
136
|
-
);
|
|
137
96
|
const displayedActiveThreadId =
|
|
138
97
|
threadIdFromPath(location.pathname) ??
|
|
139
98
|
(location.pathname === "/chat" ? null : activeThreadId);
|
|
140
|
-
const
|
|
141
|
-
() =>
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
if (typeof detail?.isRunning === "boolean") refreshThreads();
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
window.addEventListener("agent-chat:threads-updated", refresh);
|
|
165
|
-
window.addEventListener("agentNative.chatRunning", handleRunning);
|
|
166
|
-
window.addEventListener("focus", refresh);
|
|
167
|
-
return () => {
|
|
168
|
-
window.removeEventListener("agent-chat:threads-updated", refresh);
|
|
169
|
-
window.removeEventListener("agentNative.chatRunning", handleRunning);
|
|
170
|
-
window.removeEventListener("focus", refresh);
|
|
171
|
-
};
|
|
172
|
-
}, [refreshThreads]);
|
|
99
|
+
const history = useOwnershipChatHistory({
|
|
100
|
+
getThreadUrl: (threadId) => appPath(chatThreadPath(threadId)),
|
|
101
|
+
activeId: displayedActiveThreadId,
|
|
102
|
+
localMineRows: ownDraftRows({ threads, isNewThread }),
|
|
103
|
+
mutations: {
|
|
104
|
+
pin: pinThread,
|
|
105
|
+
rename: renameThread,
|
|
106
|
+
archive: archiveThread,
|
|
107
|
+
},
|
|
108
|
+
onMutationFailed: (kind) => {
|
|
109
|
+
toast.error(
|
|
110
|
+
t(
|
|
111
|
+
kind === "archive"
|
|
112
|
+
? "chat.archiveFailed"
|
|
113
|
+
: kind === "rename"
|
|
114
|
+
? "chat.renameFailed"
|
|
115
|
+
: "agentChat.common.saveFailed",
|
|
116
|
+
),
|
|
117
|
+
);
|
|
118
|
+
},
|
|
119
|
+
});
|
|
173
120
|
|
|
174
121
|
function openThread(threadId: string, options?: { isNew?: boolean }) {
|
|
175
122
|
switchThread(threadId);
|
|
@@ -195,20 +142,12 @@ function ChatThreadsSection({ open }: { open: boolean }) {
|
|
|
195
142
|
async function handleArchiveThread(threadId: string) {
|
|
196
143
|
const wasActive =
|
|
197
144
|
threadId === activeThreadId || threadId === persistedActiveThreadId();
|
|
198
|
-
const archived = await
|
|
199
|
-
if (!archived)
|
|
200
|
-
toast.error(t("chat.archiveFailed"));
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
145
|
+
const archived = await history.listProps.onDelete!(threadId);
|
|
146
|
+
if (!archived) return false;
|
|
203
147
|
if (wasActive) {
|
|
204
148
|
await handleNewChat();
|
|
205
149
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
function handleRenameThread(threadId: string, title: string) {
|
|
209
|
-
void renameThread(threadId, title).then((renamed) => {
|
|
210
|
-
if (!renamed) toast.error(t("chat.renameFailed"));
|
|
211
|
-
});
|
|
150
|
+
return true;
|
|
212
151
|
}
|
|
213
152
|
|
|
214
153
|
return (
|
|
@@ -218,8 +157,8 @@ function ChatThreadsSection({ open }: { open: boolean }) {
|
|
|
218
157
|
aria-hidden={!open}
|
|
219
158
|
>
|
|
220
159
|
<div className="ms-4">
|
|
221
|
-
<
|
|
222
|
-
|
|
160
|
+
<OwnershipChatHistoryRail
|
|
161
|
+
{...history}
|
|
223
162
|
activeId={displayedActiveThreadId}
|
|
224
163
|
onSelect={(threadId) => openThread(threadId)}
|
|
225
164
|
onNewChat={() => void handleNewChat()}
|
|
@@ -229,11 +168,6 @@ function ChatThreadsSection({ open }: { open: boolean }) {
|
|
|
229
168
|
showLess: t("chat.chats"),
|
|
230
169
|
}}
|
|
231
170
|
renameMaxLength={160}
|
|
232
|
-
onTogglePin={(threadId) => {
|
|
233
|
-
const thread = visibleThreads.find((item) => item.id === threadId);
|
|
234
|
-
if (thread) void pinThread(threadId, !thread.pinnedAt);
|
|
235
|
-
}}
|
|
236
|
-
onRename={handleRenameThread}
|
|
237
171
|
onDelete={(threadId) => void handleArchiveThread(threadId)}
|
|
238
172
|
labels={{
|
|
239
173
|
options: (item) =>
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
useSetHeaderActions,
|
|
6
6
|
useSetPageTitle,
|
|
7
7
|
} from "@agent-native/toolkit/app-shell";
|
|
8
|
-
import { VisibilityBadge } from "@agent-native/toolkit/sharing";
|
|
8
|
+
import { VisibilityBadge } from "@agent-native/toolkit/app/sharing/VisibilityBadge";
|
|
9
9
|
import {
|
|
10
10
|
IconPlus,
|
|
11
11
|
IconLoader2,
|
|
@@ -13,6 +13,12 @@ time from the command menu (Cmd+K → "What's new").
|
|
|
13
13
|
|
|
14
14
|
- Apps no longer keep server functions and databases warm by default; set `AGENT_NATIVE_ENABLE_KEEP_WARM=1` to opt in.
|
|
15
15
|
|
|
16
|
+
## 2026-10-16
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- Owned and shared chats appear in separate history sections, with each shared chat's owner shown as an avatar and a Copy link action on every chat.
|
|
21
|
+
|
|
16
22
|
## 2026-10-13
|
|
17
23
|
|
|
18
24
|
### Fixed
|
|
@@ -2,7 +2,6 @@ import {
|
|
|
2
2
|
navigateWithAgentChatViewTransition,
|
|
3
3
|
sendToAgentChat,
|
|
4
4
|
useChatThreads,
|
|
5
|
-
type ChatThreadSummary,
|
|
6
5
|
} from "@agent-native/core/client/agent-chat";
|
|
7
6
|
import { useCodeMode } from "@agent-native/core/client/agent-chat";
|
|
8
7
|
import { appPath } from "@agent-native/core/client/api-path";
|
|
@@ -10,6 +9,11 @@ import { useSession } from "@agent-native/core/client/hooks";
|
|
|
10
9
|
import { useT } from "@agent-native/core/client/i18n";
|
|
11
10
|
import { buildSignInReturnHref } from "@agent-native/core/client/sign-in-return";
|
|
12
11
|
import { useSendToAgentChat } from "@agent-native/toolkit/app/chat/composer";
|
|
12
|
+
import {
|
|
13
|
+
OwnershipChatHistoryRail,
|
|
14
|
+
useOwnershipChatHistory,
|
|
15
|
+
ownDraftRows,
|
|
16
|
+
} from "@agent-native/toolkit/app/chat/ownership-history";
|
|
13
17
|
import { DevDatabaseLink } from "@agent-native/toolkit/app/db-admin";
|
|
14
18
|
import { FeedbackButton } from "@agent-native/toolkit/app/feedback";
|
|
15
19
|
import { OrgSwitcher } from "@agent-native/toolkit/app/org";
|
|
@@ -21,10 +25,6 @@ import {
|
|
|
21
25
|
} from "@agent-native/toolkit/app/shared";
|
|
22
26
|
import { LazyChunkErrorBoundary } from "@agent-native/toolkit/app/shared";
|
|
23
27
|
import { LazyChunkRetryFallback } from "@agent-native/toolkit/app/shared";
|
|
24
|
-
import {
|
|
25
|
-
ChatHistoryRail,
|
|
26
|
-
type ChatHistoryItem,
|
|
27
|
-
} from "@agent-native/toolkit/chat-history";
|
|
28
28
|
import { planPathForKind } from "@shared/plan-routes";
|
|
29
29
|
import {
|
|
30
30
|
IconClipboardCheck,
|
|
@@ -34,14 +34,7 @@ import {
|
|
|
34
34
|
IconRefresh,
|
|
35
35
|
IconNews,
|
|
36
36
|
} from "@tabler/icons-react";
|
|
37
|
-
import {
|
|
38
|
-
lazy,
|
|
39
|
-
Suspense,
|
|
40
|
-
useEffect,
|
|
41
|
-
useMemo,
|
|
42
|
-
useState,
|
|
43
|
-
type MouseEvent,
|
|
44
|
-
} from "react";
|
|
37
|
+
import { lazy, Suspense, useMemo, useState, type MouseEvent } from "react";
|
|
45
38
|
import { Link, useLocation, useNavigate } from "react-router";
|
|
46
39
|
import { toast } from "sonner";
|
|
47
40
|
|
|
@@ -121,40 +114,6 @@ function formatPlanAge(value: string) {
|
|
|
121
114
|
});
|
|
122
115
|
}
|
|
123
116
|
|
|
124
|
-
function formatThreadAge(updatedAt: number) {
|
|
125
|
-
const diffMs = Math.max(0, Date.now() - updatedAt);
|
|
126
|
-
const minutes = Math.floor(diffMs / 60_000);
|
|
127
|
-
if (minutes < 1) return "now";
|
|
128
|
-
if (minutes < 60) return `${minutes}m`;
|
|
129
|
-
const hours = Math.floor(minutes / 60);
|
|
130
|
-
if (hours < 24) return `${hours}h`;
|
|
131
|
-
const days = Math.floor(hours / 24);
|
|
132
|
-
if (days < 7) return `${days}d`;
|
|
133
|
-
return new Date(updatedAt).toLocaleDateString([], {
|
|
134
|
-
month: "short",
|
|
135
|
-
day: "numeric",
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function threadTitle(thread: ChatThreadSummary) {
|
|
140
|
-
return thread.title || thread.preview || "Untitled chat";
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
function threadUpdatedAt(thread: ChatThreadSummary) {
|
|
144
|
-
return Number.isFinite(thread.updatedAt)
|
|
145
|
-
? thread.updatedAt
|
|
146
|
-
: Number.isFinite(thread.createdAt)
|
|
147
|
-
? thread.createdAt
|
|
148
|
-
: 0;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
function compareThreads(a: ChatThreadSummary, b: ChatThreadSummary) {
|
|
152
|
-
const aPinned = a.pinnedAt ?? 0;
|
|
153
|
-
const bPinned = b.pinnedAt ?? 0;
|
|
154
|
-
if (aPinned || bPinned) return bPinned - aPinned;
|
|
155
|
-
return threadUpdatedAt(b) - threadUpdatedAt(a);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
117
|
function persistedActiveThreadId() {
|
|
159
118
|
try {
|
|
160
119
|
return localStorage.getItem(
|
|
@@ -182,53 +141,34 @@ function PlanChatsSection({
|
|
|
182
141
|
pinThread,
|
|
183
142
|
archiveThread,
|
|
184
143
|
renameThread,
|
|
185
|
-
|
|
144
|
+
isNewThread,
|
|
186
145
|
} = useChatThreads(undefined, PLAN_CHAT_STORAGE_KEY, undefined, {
|
|
146
|
+
ownership: "mine",
|
|
187
147
|
autoCreate: false,
|
|
188
148
|
restoreActiveThread: false,
|
|
189
149
|
});
|
|
190
150
|
|
|
191
|
-
const
|
|
192
|
-
() =>
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
() =>
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
);
|
|
213
|
-
|
|
214
|
-
useEffect(() => {
|
|
215
|
-
const refresh = () => refreshThreads();
|
|
216
|
-
const handleRunning = (event: Event) => {
|
|
217
|
-
const detail = (event as CustomEvent).detail as
|
|
218
|
-
| { isRunning?: unknown }
|
|
219
|
-
| undefined;
|
|
220
|
-
if (typeof detail?.isRunning === "boolean") refreshThreads();
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
window.addEventListener("agent-chat:threads-updated", refresh);
|
|
224
|
-
window.addEventListener("agentNative.chatRunning", handleRunning);
|
|
225
|
-
window.addEventListener("focus", refresh);
|
|
226
|
-
return () => {
|
|
227
|
-
window.removeEventListener("agent-chat:threads-updated", refresh);
|
|
228
|
-
window.removeEventListener("agentNative.chatRunning", handleRunning);
|
|
229
|
-
window.removeEventListener("focus", refresh);
|
|
230
|
-
};
|
|
231
|
-
}, [refreshThreads]);
|
|
151
|
+
const history = useOwnershipChatHistory({
|
|
152
|
+
getThreadUrl: (threadId) => appPath(planChatThreadPath(threadId)),
|
|
153
|
+
activeId: activeThreadId,
|
|
154
|
+
localMineRows: ownDraftRows({ threads, isNewThread }),
|
|
155
|
+
mutations: {
|
|
156
|
+
pin: pinThread,
|
|
157
|
+
rename: renameThread,
|
|
158
|
+
archive: archiveThread,
|
|
159
|
+
},
|
|
160
|
+
onMutationFailed: (kind) => {
|
|
161
|
+
toast.error(
|
|
162
|
+
t(
|
|
163
|
+
kind === "archive"
|
|
164
|
+
? "raw.sidebar.archiveChatFailed"
|
|
165
|
+
: kind === "rename"
|
|
166
|
+
? "raw.sidebar.renameChatFailed"
|
|
167
|
+
: "agentChat.common.saveFailed",
|
|
168
|
+
),
|
|
169
|
+
);
|
|
170
|
+
},
|
|
171
|
+
});
|
|
232
172
|
|
|
233
173
|
if (collapsed) return null;
|
|
234
174
|
|
|
@@ -252,20 +192,12 @@ function PlanChatsSection({
|
|
|
252
192
|
async function handleArchiveThread(threadId: string) {
|
|
253
193
|
const wasActive =
|
|
254
194
|
threadId === activeThreadId || threadId === persistedActiveThreadId();
|
|
255
|
-
const archived = await
|
|
256
|
-
if (!archived)
|
|
257
|
-
toast.error(t("raw.sidebar.archiveChatFailed"));
|
|
258
|
-
return;
|
|
259
|
-
}
|
|
195
|
+
const archived = await history.listProps.onDelete!(threadId);
|
|
196
|
+
if (!archived) return false;
|
|
260
197
|
if (wasActive) {
|
|
261
198
|
await handleNewChat();
|
|
262
199
|
}
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
function handleRenameThread(threadId: string, title: string) {
|
|
266
|
-
void renameThread(threadId, title).then((renamed) => {
|
|
267
|
-
if (!renamed) toast.error(t("raw.sidebar.renameChatFailed"));
|
|
268
|
-
});
|
|
200
|
+
return true;
|
|
269
201
|
}
|
|
270
202
|
|
|
271
203
|
return (
|
|
@@ -275,22 +207,15 @@ function PlanChatsSection({
|
|
|
275
207
|
aria-hidden={!open}
|
|
276
208
|
>
|
|
277
209
|
<div className="ms-4">
|
|
278
|
-
<
|
|
279
|
-
|
|
210
|
+
<OwnershipChatHistoryRail
|
|
211
|
+
{...history}
|
|
280
212
|
activeId={activeThreadId}
|
|
281
213
|
onSelect={(threadId) => openThread(threadId)}
|
|
282
214
|
onNewChat={() => void handleNewChat()}
|
|
283
215
|
railLabels={{
|
|
284
216
|
newChat: t("sidebar.newChat"),
|
|
285
|
-
showMore: t("sidebar.chats"),
|
|
286
|
-
showLess: t("sidebar.chats"),
|
|
287
217
|
}}
|
|
288
218
|
renameMaxLength={160}
|
|
289
|
-
onTogglePin={(threadId) => {
|
|
290
|
-
const thread = visibleThreads.find((item) => item.id === threadId);
|
|
291
|
-
if (thread) void pinThread(threadId, !thread.pinnedAt);
|
|
292
|
-
}}
|
|
293
|
-
onRename={handleRenameThread}
|
|
294
219
|
onDelete={(threadId) => void handleArchiveThread(threadId)}
|
|
295
220
|
labels={{
|
|
296
221
|
options: (item) => `${t("sidebar.chats")}: ${item.titleText ?? ""}`,
|
|
@@ -47,6 +47,7 @@ time from the command menu (Cmd+K → "What's new").
|
|
|
47
47
|
|
|
48
48
|
### Improved
|
|
49
49
|
|
|
50
|
+
- Deck lists use the shared ownership filter, and visibility badges use localized labels.
|
|
50
51
|
- Contextual toolbar: the second row now changes with what is selected (text, shape, image, video, multi-select), and every state ends with an Edit with Agent button with quick picks.
|
|
51
52
|
- The top bar shows a deck's privacy next to its name, Share has People and Agents tabs, and Present opens a menu to start in this tab, full screen, or Presenter View.
|
|
52
53
|
|