@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
|
@@ -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 { DevDatabaseLink } from "@agent-native/toolkit/app/db-admin";
|
|
8
13
|
import { FeedbackButton } from "@agent-native/toolkit/app/feedback";
|
|
9
14
|
import { OrgSwitcher } from "@agent-native/toolkit/app/org";
|
|
@@ -12,12 +17,7 @@ import {
|
|
|
12
17
|
AppSidebar,
|
|
13
18
|
AppSidebarNavItem,
|
|
14
19
|
} from "@agent-native/toolkit/app/shared";
|
|
15
|
-
import {
|
|
16
|
-
ChatHistoryRail,
|
|
17
|
-
type ChatHistoryItem,
|
|
18
|
-
} from "@agent-native/toolkit/chat-history";
|
|
19
20
|
import { IconSearch } from "@tabler/icons-react";
|
|
20
|
-
import { useEffect, useMemo } from "react";
|
|
21
21
|
import { useLocation, useNavigate } from "react-router";
|
|
22
22
|
import { toast } from "sonner";
|
|
23
23
|
|
|
@@ -43,40 +43,6 @@ interface SidebarProps {
|
|
|
43
43
|
onCollapsedChange?: (collapsed: boolean) => void;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
function formatThreadAge(updatedAt: number) {
|
|
47
|
-
const diffMs = Math.max(0, Date.now() - updatedAt);
|
|
48
|
-
const minutes = Math.floor(diffMs / 60_000);
|
|
49
|
-
if (minutes < 1) return "now";
|
|
50
|
-
if (minutes < 60) return `${minutes}m`;
|
|
51
|
-
const hours = Math.floor(minutes / 60);
|
|
52
|
-
if (hours < 24) return `${hours}h`;
|
|
53
|
-
const days = Math.floor(hours / 24);
|
|
54
|
-
if (days < 7) return `${days}d`;
|
|
55
|
-
return new Date(updatedAt).toLocaleDateString([], {
|
|
56
|
-
month: "short",
|
|
57
|
-
day: "numeric",
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function threadTitle(thread: ChatThreadSummary) {
|
|
62
|
-
return thread.title || thread.preview || "Untitled chat";
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function threadUpdatedAt(thread: ChatThreadSummary) {
|
|
66
|
-
return Number.isFinite(thread.updatedAt)
|
|
67
|
-
? thread.updatedAt
|
|
68
|
-
: Number.isFinite(thread.createdAt)
|
|
69
|
-
? thread.createdAt
|
|
70
|
-
: 0;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function compareThreads(a: ChatThreadSummary, b: ChatThreadSummary) {
|
|
74
|
-
const aPinned = a.pinnedAt ?? 0;
|
|
75
|
-
const bPinned = b.pinnedAt ?? 0;
|
|
76
|
-
if (aPinned || bPinned) return bPinned - aPinned;
|
|
77
|
-
return threadUpdatedAt(b) - threadUpdatedAt(a);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
46
|
function persistedActiveThreadId() {
|
|
81
47
|
try {
|
|
82
48
|
return localStorage.getItem(BRAIN_ACTIVE_THREAD_KEY);
|
|
@@ -94,8 +60,9 @@ function BrainChatsSection({ open }: { open: boolean }) {
|
|
|
94
60
|
pinThread,
|
|
95
61
|
archiveThread,
|
|
96
62
|
renameThread,
|
|
97
|
-
|
|
63
|
+
isNewThread,
|
|
98
64
|
} = useChatThreads(undefined, BRAIN_CHAT_STORAGE_KEY, undefined, {
|
|
65
|
+
ownership: "mine",
|
|
99
66
|
autoCreate: false,
|
|
100
67
|
restoreActiveThread: false,
|
|
101
68
|
});
|
|
@@ -104,46 +71,27 @@ function BrainChatsSection({ open }: { open: boolean }) {
|
|
|
104
71
|
const location = useLocation();
|
|
105
72
|
const activeThreadId = brainAskThreadIdFromPath(location.pathname);
|
|
106
73
|
|
|
107
|
-
const
|
|
108
|
-
() =>
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
);
|
|
128
|
-
|
|
129
|
-
useEffect(() => {
|
|
130
|
-
const refresh = () => refreshThreads();
|
|
131
|
-
const handleRunning = (event: Event) => {
|
|
132
|
-
const detail = (event as CustomEvent).detail as
|
|
133
|
-
| { isRunning?: unknown }
|
|
134
|
-
| undefined;
|
|
135
|
-
if (typeof detail?.isRunning === "boolean") refreshThreads();
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
window.addEventListener("agent-chat:threads-updated", refresh);
|
|
139
|
-
window.addEventListener("agentNative.chatRunning", handleRunning);
|
|
140
|
-
window.addEventListener("focus", refresh);
|
|
141
|
-
return () => {
|
|
142
|
-
window.removeEventListener("agent-chat:threads-updated", refresh);
|
|
143
|
-
window.removeEventListener("agentNative.chatRunning", handleRunning);
|
|
144
|
-
window.removeEventListener("focus", refresh);
|
|
145
|
-
};
|
|
146
|
-
}, [refreshThreads]);
|
|
74
|
+
const history = useOwnershipChatHistory({
|
|
75
|
+
getThreadUrl: (threadId) => appPath(brainAskThreadPath(threadId)),
|
|
76
|
+
activeId: activeThreadId,
|
|
77
|
+
localMineRows: ownDraftRows({ threads, isNewThread }),
|
|
78
|
+
mutations: {
|
|
79
|
+
pin: pinThread,
|
|
80
|
+
rename: renameThread,
|
|
81
|
+
archive: archiveThread,
|
|
82
|
+
},
|
|
83
|
+
onMutationFailed: (kind) => {
|
|
84
|
+
toast.error(
|
|
85
|
+
t(
|
|
86
|
+
kind === "archive"
|
|
87
|
+
? "chat.archiveFailed"
|
|
88
|
+
: kind === "rename"
|
|
89
|
+
? "chat.renameFailed"
|
|
90
|
+
: "agentChat.common.saveFailed",
|
|
91
|
+
),
|
|
92
|
+
);
|
|
93
|
+
},
|
|
94
|
+
});
|
|
147
95
|
|
|
148
96
|
function openThread(threadId: string) {
|
|
149
97
|
switchThread(threadId);
|
|
@@ -165,20 +113,12 @@ function BrainChatsSection({ open }: { open: boolean }) {
|
|
|
165
113
|
async function handleArchiveThread(threadId: string) {
|
|
166
114
|
const wasActive =
|
|
167
115
|
threadId === activeThreadId || threadId === persistedActiveThreadId();
|
|
168
|
-
const archived = await
|
|
169
|
-
if (!archived)
|
|
170
|
-
toast.error(t("chat.archiveFailed"));
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
116
|
+
const archived = await history.listProps.onDelete!(threadId);
|
|
117
|
+
if (!archived) return false;
|
|
173
118
|
if (wasActive) {
|
|
174
119
|
handleNewChat();
|
|
175
120
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
function handleRenameThread(threadId: string, title: string) {
|
|
179
|
-
void renameThread(threadId, title).then((renamed) => {
|
|
180
|
-
if (!renamed) toast.error(t("chat.renameFailed"));
|
|
181
|
-
});
|
|
121
|
+
return true;
|
|
182
122
|
}
|
|
183
123
|
|
|
184
124
|
return (
|
|
@@ -188,8 +128,8 @@ function BrainChatsSection({ open }: { open: boolean }) {
|
|
|
188
128
|
aria-hidden={!open}
|
|
189
129
|
>
|
|
190
130
|
<div className="ms-4">
|
|
191
|
-
<
|
|
192
|
-
|
|
131
|
+
<OwnershipChatHistoryRail
|
|
132
|
+
{...history}
|
|
193
133
|
activeId={activeThreadId}
|
|
194
134
|
onSelect={openThread}
|
|
195
135
|
onNewChat={handleNewChat}
|
|
@@ -198,13 +138,6 @@ function BrainChatsSection({ open }: { open: boolean }) {
|
|
|
198
138
|
showMore: t("chat.chats"),
|
|
199
139
|
showLess: t("chat.chats"),
|
|
200
140
|
}}
|
|
201
|
-
previewCount={5}
|
|
202
|
-
expandedCount={15}
|
|
203
|
-
onTogglePin={(threadId) => {
|
|
204
|
-
const thread = visibleThreads.find((item) => item.id === threadId);
|
|
205
|
-
if (thread) void pinThread(threadId, !thread.pinnedAt);
|
|
206
|
-
}}
|
|
207
|
-
onRename={handleRenameThread}
|
|
208
141
|
renameMaxLength={160}
|
|
209
142
|
onDelete={(threadId) => void handleArchiveThread(threadId)}
|
|
210
143
|
labels={{
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "@agent-native/core/client/hooks";
|
|
5
5
|
import { useT } from "@agent-native/core/client/i18n";
|
|
6
6
|
import { ShareButton } from "@agent-native/toolkit/app/sharing";
|
|
7
|
-
import { VisibilityBadge } from "@agent-native/toolkit/sharing";
|
|
7
|
+
import { VisibilityBadge } from "@agent-native/toolkit/app/sharing/VisibilityBadge";
|
|
8
8
|
import {
|
|
9
9
|
IconAlertTriangle,
|
|
10
10
|
IconArchive,
|
|
@@ -1,9 +1,16 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
|
|
1
3
|
import baseConfig from "@agent-native/core/vitest-config";
|
|
2
4
|
import { defineConfig, mergeConfig } from "vitest/config";
|
|
3
5
|
|
|
4
6
|
export default mergeConfig(
|
|
5
7
|
baseConfig,
|
|
6
8
|
defineConfig({
|
|
9
|
+
resolve: {
|
|
10
|
+
alias: {
|
|
11
|
+
"@": path.resolve(__dirname, "./app"),
|
|
12
|
+
},
|
|
13
|
+
},
|
|
7
14
|
test: {
|
|
8
15
|
passWithNoTests: true,
|
|
9
16
|
exclude: [
|
|
@@ -15,6 +15,12 @@ time from the command menu (Cmd+K → "What's new") or from Settings.
|
|
|
15
15
|
|
|
16
16
|
- Apps no longer keep server functions and databases warm by default; set `AGENT_NATIVE_ENABLE_KEEP_WARM=1` to opt in.
|
|
17
17
|
|
|
18
|
+
## 2026-10-16
|
|
19
|
+
|
|
20
|
+
### Improved
|
|
21
|
+
|
|
22
|
+
- Booking links show localized visibility badges.
|
|
23
|
+
|
|
18
24
|
## 2026-10-08
|
|
19
25
|
|
|
20
26
|
### Added
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
SlugEditor,
|
|
7
7
|
} from "@agent-native/scheduling/react/components";
|
|
8
8
|
import { ShareButton } from "@agent-native/toolkit/app/sharing";
|
|
9
|
-
import { VisibilityBadge } from "@agent-native/toolkit/sharing";
|
|
9
|
+
import { VisibilityBadge } from "@agent-native/toolkit/app/sharing/VisibilityBadge";
|
|
10
10
|
import type {
|
|
11
11
|
AvailabilityConfig,
|
|
12
12
|
BookingHost,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { appPath } from "@agent-native/core/client/api-path";
|
|
1
2
|
import { useT } from "@agent-native/core/client/i18n";
|
|
2
3
|
import {
|
|
3
4
|
navigateWithAgentChatViewTransition,
|
|
@@ -5,14 +6,15 @@ import {
|
|
|
5
6
|
useChatThreads,
|
|
6
7
|
type ChatThreadSummary,
|
|
7
8
|
} from "@agent-native/toolkit/app/chat/agentkit-chat/rail";
|
|
9
|
+
import {
|
|
10
|
+
ownDraftRows,
|
|
11
|
+
OwnershipChatHistoryRail,
|
|
12
|
+
useOwnershipChatHistory,
|
|
13
|
+
type OwnDraftRow,
|
|
14
|
+
} from "@agent-native/toolkit/app/chat/ownership-history";
|
|
8
15
|
import { OrgSwitcher } from "@agent-native/toolkit/app/org";
|
|
9
16
|
import { openCommandMenu } from "@agent-native/toolkit/app/shared";
|
|
10
17
|
import { AgentNativeIcon } from "@agent-native/toolkit/app/shared/AgentNativeIcon";
|
|
11
|
-
import {
|
|
12
|
-
ChatHistoryList,
|
|
13
|
-
type ChatHistoryItem,
|
|
14
|
-
type ChatHistorySection,
|
|
15
|
-
} from "@agent-native/toolkit/chat-history/ChatHistoryList";
|
|
16
18
|
import {
|
|
17
19
|
IconApps,
|
|
18
20
|
IconClock,
|
|
@@ -25,7 +27,7 @@ import {
|
|
|
25
27
|
IconPin,
|
|
26
28
|
IconSearch,
|
|
27
29
|
} from "@tabler/icons-react";
|
|
28
|
-
import { useEffect,
|
|
30
|
+
import { useEffect, useRef, useState } from "react";
|
|
29
31
|
import { Link, useLocation, useNavigate } from "react-router";
|
|
30
32
|
import { toast } from "sonner";
|
|
31
33
|
|
|
@@ -41,7 +43,6 @@ import {
|
|
|
41
43
|
} from "@/components/ui/tooltip";
|
|
42
44
|
import { APP_TITLE } from "@/lib/app-config";
|
|
43
45
|
import { chatThreadPath, HOME_PATH, threadIdFromPath } from "@/lib/chat-paths";
|
|
44
|
-
import { visibleChatThreads } from "@/lib/sidebar-thread-state";
|
|
45
46
|
import { cn } from "@/lib/utils";
|
|
46
47
|
|
|
47
48
|
const CHAT_STORAGE_KEY = "chat";
|
|
@@ -53,11 +54,9 @@ interface SidebarProps {
|
|
|
53
54
|
onCollapsedChange?: (collapsed: boolean) => void;
|
|
54
55
|
}
|
|
55
56
|
|
|
56
|
-
function
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
function threadUpdatedAt(thread: ChatThreadSummary) {
|
|
57
|
+
function threadUpdatedAt(
|
|
58
|
+
thread: Pick<ChatThreadSummary, "createdAt" | "updatedAt">,
|
|
59
|
+
) {
|
|
61
60
|
return Number.isFinite(thread.updatedAt)
|
|
62
61
|
? thread.updatedAt
|
|
63
62
|
: Number.isFinite(thread.createdAt)
|
|
@@ -65,14 +64,6 @@ function threadUpdatedAt(thread: ChatThreadSummary) {
|
|
|
65
64
|
: 0;
|
|
66
65
|
}
|
|
67
66
|
|
|
68
|
-
function compareRecentThreads(a: ChatThreadSummary, b: ChatThreadSummary) {
|
|
69
|
-
return threadUpdatedAt(b) - threadUpdatedAt(a);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function comparePinnedThreads(a: ChatThreadSummary, b: ChatThreadSummary) {
|
|
73
|
-
return (b.pinnedAt ?? 0) - (a.pinnedAt ?? 0);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
67
|
function formatRelativeTime(timestamp: number) {
|
|
77
68
|
const elapsed = timestamp - Date.now();
|
|
78
69
|
const intervals = [
|
|
@@ -106,7 +97,10 @@ function ThreadHistoryTitle({
|
|
|
106
97
|
title,
|
|
107
98
|
running,
|
|
108
99
|
}: {
|
|
109
|
-
thread:
|
|
100
|
+
thread: OwnDraftRow &
|
|
101
|
+
Partial<
|
|
102
|
+
Pick<ChatThreadSummary, "preview" | "scope" | "source" | "pinnedAt">
|
|
103
|
+
>;
|
|
110
104
|
title: string;
|
|
111
105
|
running: boolean;
|
|
112
106
|
}) {
|
|
@@ -287,7 +281,7 @@ function ChatThreadsSection({ collapsed }: { collapsed: boolean }) {
|
|
|
287
281
|
pinThread,
|
|
288
282
|
archiveThread,
|
|
289
283
|
renameThread,
|
|
290
|
-
|
|
284
|
+
isNewThread,
|
|
291
285
|
} = useChatThreads(undefined, CHAT_STORAGE_KEY, undefined, {
|
|
292
286
|
autoCreate: false,
|
|
293
287
|
restoreActiveThread: false,
|
|
@@ -295,66 +289,46 @@ function ChatThreadsSection({ collapsed }: { collapsed: boolean }) {
|
|
|
295
289
|
const { workingThreadIds, observedThreadStarts } =
|
|
296
290
|
useAgentChatRunningThreads();
|
|
297
291
|
|
|
298
|
-
const
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
292
|
+
const localMineRows = ownDraftRows({
|
|
293
|
+
threads,
|
|
294
|
+
isNewThread,
|
|
295
|
+
observedThreadStarts,
|
|
296
|
+
});
|
|
297
|
+
const history = useOwnershipChatHistory({
|
|
298
|
+
getThreadUrl: (threadId) => appPath(chatThreadPath(threadId)),
|
|
299
|
+
activeId:
|
|
300
|
+
threadIdFromPath(location.pathname) ??
|
|
301
|
+
activeThreadId ??
|
|
302
|
+
persistedActiveThreadId(),
|
|
303
|
+
localMineRows,
|
|
304
|
+
pinned: { label: t("chat.pinned") },
|
|
305
|
+
mutations: {
|
|
306
|
+
pin: pinThread,
|
|
307
|
+
rename: renameThread,
|
|
308
|
+
archive: archiveThread,
|
|
309
|
+
},
|
|
310
|
+
onMutationFailed: (kind) => {
|
|
311
|
+
if (kind === "archive") toast.error(t("chat.archiveFailed"));
|
|
312
|
+
if (kind === "rename") toast.error(t("chat.renameFailed"));
|
|
313
|
+
},
|
|
314
|
+
decorateItem: (item, row) => {
|
|
315
|
+
const title = row.title || row.preview || t("chat.untitledChat");
|
|
311
316
|
return {
|
|
312
|
-
|
|
317
|
+
...item,
|
|
313
318
|
title: (
|
|
314
319
|
<ThreadHistoryTitle
|
|
315
|
-
thread={
|
|
320
|
+
thread={row}
|
|
316
321
|
title={title}
|
|
317
|
-
running={workingThreadIds.has(
|
|
322
|
+
running={workingThreadIds.has(row.id)}
|
|
318
323
|
/>
|
|
319
324
|
),
|
|
320
|
-
titleText: title,
|
|
321
|
-
pinned: Boolean(thread.pinnedAt),
|
|
322
325
|
};
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
.filter((thread) => !thread.pinnedAt)
|
|
330
|
-
.sort(compareRecentThreads)
|
|
331
|
-
.slice(0, 30)
|
|
332
|
-
.map(toItem);
|
|
333
|
-
|
|
334
|
-
return [
|
|
335
|
-
{ id: "pinned", label: t("chat.pinned"), items: pinned },
|
|
336
|
-
{ id: "recents", label: t("chat.recents"), items: recent },
|
|
337
|
-
];
|
|
338
|
-
}, [t, visibleThreads, workingThreadIds]);
|
|
339
|
-
|
|
340
|
-
useEffect(() => {
|
|
341
|
-
const refresh = () => refreshThreads();
|
|
342
|
-
const handleRunning = (event: Event) => {
|
|
343
|
-
const detail = (event as CustomEvent).detail as
|
|
344
|
-
| { isRunning?: unknown }
|
|
345
|
-
| undefined;
|
|
346
|
-
if (typeof detail?.isRunning === "boolean") refreshThreads();
|
|
347
|
-
};
|
|
348
|
-
|
|
349
|
-
window.addEventListener("agent-chat:threads-updated", refresh);
|
|
350
|
-
window.addEventListener("agentNative.chatRunning", handleRunning);
|
|
351
|
-
window.addEventListener("focus", refresh);
|
|
352
|
-
return () => {
|
|
353
|
-
window.removeEventListener("agent-chat:threads-updated", refresh);
|
|
354
|
-
window.removeEventListener("agentNative.chatRunning", handleRunning);
|
|
355
|
-
window.removeEventListener("focus", refresh);
|
|
356
|
-
};
|
|
357
|
-
}, [refreshThreads]);
|
|
326
|
+
},
|
|
327
|
+
});
|
|
328
|
+
const displayedActiveThreadId =
|
|
329
|
+
threadIdFromPath(location.pathname) ??
|
|
330
|
+
activeThreadId ??
|
|
331
|
+
persistedActiveThreadId();
|
|
358
332
|
|
|
359
333
|
function openThread(threadId: string, options?: { isNew?: boolean }) {
|
|
360
334
|
switchThread(threadId);
|
|
@@ -382,23 +356,6 @@ function ChatThreadsSection({ collapsed }: { collapsed: boolean }) {
|
|
|
382
356
|
if (threadId) openThread(threadId, { isNew: true });
|
|
383
357
|
}
|
|
384
358
|
|
|
385
|
-
async function handleArchiveThread(threadId: string) {
|
|
386
|
-
const wasActive =
|
|
387
|
-
threadId === activeThreadId || threadId === persistedActiveThreadId();
|
|
388
|
-
const archived = await archiveThread(threadId);
|
|
389
|
-
if (!archived) {
|
|
390
|
-
toast.error(t("chat.archiveFailed"));
|
|
391
|
-
return;
|
|
392
|
-
}
|
|
393
|
-
if (wasActive) await handleNewChat();
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
function handleRenameThread(threadId: string, title: string) {
|
|
397
|
-
void renameThread(threadId, title).then((renamed) => {
|
|
398
|
-
if (!renamed) toast.error(t("chat.renameFailed"));
|
|
399
|
-
});
|
|
400
|
-
}
|
|
401
|
-
|
|
402
359
|
const newChatButton = (
|
|
403
360
|
<button
|
|
404
361
|
type="button"
|
|
@@ -430,17 +387,20 @@ function ChatThreadsSection({ collapsed }: { collapsed: boolean }) {
|
|
|
430
387
|
return (
|
|
431
388
|
<div className="flex min-h-0 flex-1 flex-col">
|
|
432
389
|
<div className="px-2 pb-3">{newChatButton}</div>
|
|
433
|
-
<
|
|
434
|
-
|
|
390
|
+
<OwnershipChatHistoryRail
|
|
391
|
+
{...history}
|
|
392
|
+
onNewChat={() => void handleNewChat()}
|
|
393
|
+
showNewChat={false}
|
|
435
394
|
activeId={displayedActiveThreadId}
|
|
436
395
|
onSelect={openThread}
|
|
437
|
-
|
|
438
|
-
const
|
|
439
|
-
|
|
396
|
+
onDelete={async (threadId) => {
|
|
397
|
+
const wasActive =
|
|
398
|
+
threadId === activeThreadId ||
|
|
399
|
+
threadId === persistedActiveThreadId();
|
|
400
|
+
const archived = await history.listProps.onDelete?.(threadId);
|
|
401
|
+
if (archived && wasActive) await handleNewChat();
|
|
440
402
|
}}
|
|
441
|
-
onRename={handleRenameThread}
|
|
442
403
|
renameMaxLength={160}
|
|
443
|
-
onDelete={(threadId) => void handleArchiveThread(threadId)}
|
|
444
404
|
labels={{
|
|
445
405
|
options: (item) =>
|
|
446
406
|
t("chat.optionsFor", { title: item.titleText ?? "" }),
|
|
@@ -451,8 +411,9 @@ function ChatThreadsSection({ collapsed }: { collapsed: boolean }) {
|
|
|
451
411
|
unpin: t("chat.unpinChat"),
|
|
452
412
|
delete: t("chat.archiveChat"),
|
|
453
413
|
}}
|
|
454
|
-
|
|
455
|
-
|
|
414
|
+
railLabels={{
|
|
415
|
+
newChat: t("chat.newChat"),
|
|
416
|
+
}}
|
|
456
417
|
className="chat-sidebar-history min-h-0 flex-1"
|
|
457
418
|
listClassName="pb-4"
|
|
458
419
|
/>
|
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
All notable user-facing changes to Clips are documented here. Open it any time
|
|
4
4
|
from the command menu (Cmd+K → "What's new") or from Settings.
|
|
5
5
|
|
|
6
|
+
## 2026-10-21
|
|
7
|
+
|
|
8
|
+
### Improved
|
|
9
|
+
|
|
10
|
+
- Share panels describe general access in a sentence and no longer open an empty people list when you click into them.
|
|
11
|
+
|
|
6
12
|
## 2026-10-20
|
|
7
13
|
|
|
8
14
|
### Fixed
|
|
@@ -59,6 +65,7 @@ from the command menu (Cmd+K → "What's new") or from Settings.
|
|
|
59
65
|
|
|
60
66
|
### Improved
|
|
61
67
|
|
|
68
|
+
- Share dialogs make it easier to see who has access and manage common sharing changes.
|
|
62
69
|
- Rewind settings now show whether Rewind is remembering screen only or screen + audio.
|
|
63
70
|
- Clips detects browser meetings more reliably and keeps notes until the meeting stop and transcript save are confirmed.
|
|
64
71
|
- Clips detects browser meetings sooner, asks before starting when the active tab is unclear, and retries failed stops.
|
|
@@ -1617,24 +1624,4 @@ from the command menu (Cmd+K → "What's new") or from Settings.
|
|
|
1617
1624
|
- The agent sidebar now slides in smoothly without duplicate edge borders.
|
|
1618
1625
|
- The clip details sidebar now collapses into a slide-out panel on smaller screens.
|
|
1619
1626
|
|
|
1620
|
-
## 2026-06-25
|
|
1621
|
-
|
|
1622
|
-
### Added
|
|
1623
|
-
|
|
1624
|
-
- GitHub issue and pull request pages can now preview playable Clips links when the Chrome extension is installed.
|
|
1625
|
-
- Recording pages now offer a download action for viewers with video download access.
|
|
1626
|
-
|
|
1627
|
-
### Improved
|
|
1628
|
-
|
|
1629
|
-
- Clip titles are now edited only from a clip's detail view, not from the library grid
|
|
1630
|
-
- Console diagnostics keep more useful non-secret details when clips are shared with agents.
|
|
1631
|
-
- Recording cards now avoid duplicate rename controls in the overflow menu.
|
|
1632
|
-
|
|
1633
|
-
### Fixed
|
|
1634
|
-
|
|
1635
|
-
- Chrome extension recordings now upload large capture bursts reliably and report extension errors to Sentry.
|
|
1636
|
-
- Fixed owner recognition so Clips created from desktop and web sessions remain editable by the same signed-in user.
|
|
1637
|
-
- Fixed the Mac menu bar popover so it opens reliably after launch at login.
|
|
1638
|
-
- Localized Clips Settings changelog and extension sidebar labels in every supported interface language.
|
|
1639
|
-
|
|
1640
1627
|
For the full list of updates, see the [changelog folder](./changelog/).
|