Skip to content
Open
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
1fcf779
refactor: update session and topic display modes in AgentPage and Hom…
kangfenmao Jul 3, 2026
0cc96e8
refactor: replace legacy layout preferences with new display mode set…
kangfenmao Jul 3, 2026
c331e25
refactor: update right pane dimensions and adjust group header behavi…
kangfenmao Jul 3, 2026
eeb74c9
refactor: add manage agents and assistants functionality to resource …
kangfenmao Jul 3, 2026
a8b5d6d
refactor: enhance shell actions and minimize functionality across com…
kangfenmao Jul 3, 2026
9997b27
refactor: enhance SectionHeader styling and add collapse affordance t…
kangfenmao Jul 3, 2026
db31187
refactor: remove onSelectItem prop from various components and update…
kangfenmao Jul 3, 2026
b6ca368
refactor: add onSelectedClick handlers to ResourceEntityRail, AgentRe…
kangfenmao Jul 3, 2026
f41a5bc
refactor: update styling and class names in ConversationPickerDialog …
kangfenmao Jul 3, 2026
988cb1f
refactor: update drag-and-drop capabilities in ResourceEntityRail and…
kangfenmao Jul 3, 2026
4983a41
refactor: update default visible count for session and topic groups i…
kangfenmao Jul 3, 2026
a595dfe
refactor: simplify NavbarHeader class names in AgentChatNavbar and He…
kangfenmao Jul 3, 2026
adb9e85
refactor: enhance skill management integration in agent resources and…
kangfenmao Jul 4, 2026
f87a9e3
refactor: implement icon type selection for assistants and agents, en…
kangfenmao Jul 4, 2026
7ef2260
refactor: add clear topics functionality for assistants and update re…
kangfenmao Jul 4, 2026
efd8375
refactor: update assistant topic clearing success modal and related t…
kangfenmao Jul 4, 2026
5e45378
refactor(chat-resources): flatten edit dialog tool tabs
kangfenmao Jul 4, 2026
3b5d834
refactor: prevent duplicate empty session creation from rapid classic…
kangfenmao Jul 5, 2026
3a6b494
refactor: ensure assistant selector is available in classic layout wh…
kangfenmao Jul 5, 2026
d96a4a5
refactor: implement onCreateTopicAfterClear callback for topic manage…
kangfenmao Jul 5, 2026
d0d45bd
refactor(i18n): update sidebar icon key for assistants and add chat t…
kangfenmao Jul 5, 2026
6089e18
feat: add assistant grouping and topic position management
kangfenmao Jul 5, 2026
2284e36
feat: enhance resource entity handling and improve session pane behavior
kangfenmao Jul 6, 2026
3ab7505
Merge remote-tracking branch 'origin/main' into kangfenmao/remove-vie…
kangfenmao Jul 6, 2026
6569aba
feat: add assistant tag handling and update tests for topic sections
kangfenmao Jul 6, 2026
7ff6dd7
fix(assistant-resource-list): re-validate topics after clear confirm
zhangjiadi225 Jul 6, 2026
7c2b9cf
fix(assistant-resource-list): disable rail reorder under tag grouping
zhangjiadi225 Jul 6, 2026
967b322
fix(topics): delete assistant via shared useAssistantMutations hook
zhangjiadi225 Jul 6, 2026
d72647c
refactor(agent-session): give the session pane its own position prefe…
zhangjiadi225 Jul 6, 2026
53ae8c9
chore(sync): merge main
kangfenmao Jul 6, 2026
22f4fa1
fix(resource-entity-rail): make entity selection keyboard-accessible
zhangjiadi225 Jul 6, 2026
15dc6f5
refactor(agent-icon): give the agent rail its own icon-type preference
zhangjiadi225 Jul 6, 2026
7c93108
test(resource-entity-rail): type the virtual-list mock scrollToIndex …
zhangjiadi225 Jul 6, 2026
3805348
refactor(resource-selection): centralize post-delete active-row selec…
zhangjiadi225 Jul 6, 2026
98d4935
chore(sync): merge main
zhangjiadi225 Jul 6, 2026
072f545
fix(classic-layout): preserve resource and pane state
zhangjiadi225 Jul 6, 2026
e7bab3e
fix(resource-list): use base barrel imports
zhangjiadi225 Jul 6, 2026
03742fa
test(file): avoid watcher event race
kangfenmao Jul 6, 2026
0adc437
fix(Topics): hide add assistant header when topics are on the right
kangfenmao Jul 6, 2026
4ce34ff
chore(sync): merge main
kangfenmao Jul 6, 2026
d34ac66
feat(agent-resource-list): update selection logic and enhance test co…
kangfenmao Jul 6, 2026
b86588e
feat: implement default collapsed group resolution for topics and ses…
kangfenmao Jul 6, 2026
f05c553
Merge branch 'main' into kangfenmao/remove-view-switching
kangfenmao Jul 6, 2026
9f59dd9
feat(assistant-resource-list): update selection logic to handle activ…
kangfenmao Jul 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/references/file/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ The **same physical external file** can therefore be reached by either handle va

### 2.2 `FileHandle`: the Polymorphic Reference

`FileHandle = FileEntryHandle | FilePathHandle` (see [`src/shared/types/file/handle.ts`](../../../src/shared/types/file/handle.ts)) is the first-class reference type crossing the IPC boundary. Every IPC method that makes sense regardless of which subsystem is in the loop accepts a `FileHandle`; handlers dispatch internally on `handle.kind`. See §3.3 for the full dispatch table.
`FileHandle = FileEntryHandle | FilePathHandle` (see [`src/shared/utils/file/handle.ts`](../../../src/shared/utils/file/handle.ts)) is the first-class reference type crossing the IPC boundary. Every IPC method that makes sense regardless of which subsystem is in the loop accepts a `FileHandle`; handlers dispatch internally on `handle.kind`. See §3.3 for the full dispatch table.

Use `FileHandle` whenever a signature does not *inherently* require an entry row (e.g. anything that isn't a lifecycle op on a FileEntry).

Expand Down
2 changes: 1 addition & 1 deletion docs/references/file/directory-tree.md
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ The hook handles four overlapping concerns:

| Concern | Owner | Cross-reference |
|---|---|---|
| Filesystem watching | `createDirectoryWatcher` (transport) | [`watcher/`](../../../src/main/services/file/watcher) |
| Filesystem watching | `createDirectoryWatcher` (transport) | [`watcher.ts`](../../../src/main/services/file/watcher.ts) |
| `FileEntry` rows + atomic writes | FileManager | [`file-manager-architecture.md`](./file-manager-architecture.md) |
| `noteTable` sparse-state metadata | Notes domain (renderer + DataApi) | not part of tree concerns |
| `.gitignore` parsing | `gitignore.ts` (this module) | private to the tree primitive |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* Auto-generated preference mappings from classification.json
* Generated at: 2026-06-24T07:22:09.467Z
* Generated at: 2026-07-05T13:08:15.693Z
*
* This file contains pure mapping relationships without default values.
* Default values are managed in src/shared/data/preferences.ts
Expand Down Expand Up @@ -150,6 +150,10 @@ export const REDUX_STORE_MAPPINGS = {
originalKey: 'fontSize',
targetKey: 'chat.message.font_size'
},
{
originalKey: 'topicPosition',
targetKey: 'topic.tab.position'
},
{
originalKey: 'assistantIconType',
targetKey: 'assistant.icon_type'
Expand Down Expand Up @@ -795,11 +799,11 @@ export const LOCALSTORAGE_MAPPINGS: ReadonlyArray<{ originalKey: string; targetK
/**
* 映射统计:
* - ElectronStore项: 1
* - Redux Store项: 175
* - Redux Store项: 176
* - Redux分类: settings, selectionStore, llm, nutstore, preprocess, translate, websearch, ocr, note
* - DexieSettings项: 4
* - localStorage项: 0
* - 总配置项: 180
* - 总配置项: 181
*
* 使用说明:
* 1. ElectronStore读取: configManager.get(mapping.originalKey)
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/components/chat/panes/ArtifactPane.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@ export function ArtifactPaneView({
<div
ref={artifactPaneRef}
className={cn(
'flex h-full min-h-0 flex-col overflow-hidden bg-card text-card-foreground',
'flex h-full min-h-0 flex-col overflow-hidden text-card-foreground',
maximized && 'rounded-lg border border-border-subtle shadow-sm'
)}>
<div className="flex min-h-0 flex-1 overflow-hidden">
Expand Down
33 changes: 29 additions & 4 deletions src/renderer/components/chat/panes/Shell/Shell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ export interface ShellState {
pdfLayoutRefreshKey: number
}

interface ShellActions {
export interface ShellActions {
close: (afterClose?: () => void) => void
finishClose: () => void
minimize: () => void
openTab: (tab: string) => void
toggleMaximized: () => void
refreshPdfLayout: () => void
Expand All @@ -64,6 +65,10 @@ export function useShellActions(): ShellActions {
return actions
}

export function useOptionalShellActions(): ShellActions | undefined {
return use(ShellActionsContext) ?? undefined
}

export function useShellState(): ShellState {
const state = use(ShellStateContext)
if (!state) throw new Error('useShellState must be used within <Shell>')
Expand Down Expand Up @@ -113,6 +118,22 @@ function ShellProvider({
closeCallbacksRef.current = []
for (const callback of callbacks) callback()
}, [])

useEffect(() => {
if (openRef.current === defaultOpen) return

openRef.current = defaultOpen
setOpen(defaultOpen)
if (defaultOpen) {
setActiveTab(defaultTab)
setPdfLayoutPending(true)
} else {
setMaximized(false)
setPdfLayoutPending(false)
finishClose()
}
}, [defaultOpen, defaultTab, finishClose])

const close = useCallback((afterClose?: () => void) => {
if (!openRef.current) {
afterClose?.()
Expand All @@ -136,6 +157,10 @@ function ShellProvider({
})
onOpenChangeRef.current?.(true)
}, [])
const minimize = useCallback(() => {
setPdfLayoutPending(false)
setMaximized(false)
}, [])
const toggleMaximized = useCallback(() => {
setPdfLayoutPending(false)
setMaximized((currentMaximized) => !currentMaximized)
Expand All @@ -150,8 +175,8 @@ function ShellProvider({
[activeTab, maximized, open, pdfLayoutPending, pdfLayoutRefreshKey]
)
const actions = useMemo<ShellActions>(
() => ({ close, finishClose, openTab, toggleMaximized, refreshPdfLayout }),
[close, finishClose, openTab, refreshPdfLayout, toggleMaximized]
() => ({ close, finishClose, minimize, openTab, toggleMaximized, refreshPdfLayout }),
[close, finishClose, minimize, openTab, refreshPdfLayout, toggleMaximized]
)

return (
Expand Down Expand Up @@ -352,7 +377,7 @@ function ShellTabs({ children }: { children: ReactNode }) {
value={state.activeTab}
onValueChange={actions.openTab}
variant="line"
className="h-full gap-0 overflow-hidden bg-card text-card-foreground">
className="h-full gap-0 overflow-hidden text-card-foreground">
{children}
</Tabs>
)
Expand Down
68 changes: 68 additions & 0 deletions src/renderer/components/chat/panes/Shell/__tests__/Shell.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,16 @@ function ShellStateSnapshot() {
)
}

function ShellMinimizeButton() {
const actions = useShellActions()

return (
<button type="button" onClick={actions.minimize}>
minimize shell
</button>
)
}

function triggerRightSidebarShortcut() {
const handler = shortcutHandlers.get('topic.sidebar.toggle')
if (!handler) throw new Error('Expected right sidebar shortcut to be registered')
Expand Down Expand Up @@ -326,6 +336,41 @@ describe('Shell.Toggle', () => {
expect(screen.getByRole('button', { name: 'common.close_sidebar' })).toHaveAttribute('data-state', 'open')
})

it('syncs when the owning component changes the default open state', () => {
const { rerender } = render(
<Shell defaultTab="files" defaultOpen>
<Shell.Toggle tab="files" command="topic.sidebar.toggle" />
<OpenTraceButton />
<ShellStateSnapshot />
</Shell>
)

expect(screen.getByTestId('shell-state')).toHaveTextContent('open:files:false')

fireEvent.click(screen.getByRole('button', { name: 'open trace' }))
expect(screen.getByTestId('shell-state')).toHaveTextContent('open:trace:false')

rerender(
<Shell defaultTab="files" defaultOpen={false}>
<Shell.Toggle tab="files" command="topic.sidebar.toggle" />
<OpenTraceButton />
<ShellStateSnapshot />
</Shell>
)

expect(screen.getByTestId('shell-state')).toHaveTextContent('closed:trace:false')

rerender(
<Shell defaultTab="files" defaultOpen>
<Shell.Toggle tab="files" command="topic.sidebar.toggle" />
<OpenTraceButton />
<ShellStateSnapshot />
</Shell>
)

expect(screen.getByTestId('shell-state')).toHaveTextContent('open:files:false')
})

it('does not rerender actions-only consumers when shell state changes', () => {
render(
<Shell defaultTab="files">
Expand Down Expand Up @@ -382,6 +427,29 @@ describe('Shell.Toggle', () => {
expect(screen.getByTestId('shell-state')).toHaveTextContent('closed:files:false')
})

it('minimizes from maximized mode without closing the pane', () => {
render(
<Shell defaultTab="files">
<Shell.Toggle tab="files" command="topic.sidebar.toggle" />
<Shell.Tabs>
<Shell.TabList>
<Shell.Tab value="files">Files</Shell.Tab>
</Shell.TabList>
</Shell.Tabs>
<ShellMinimizeButton />
<ShellStateSnapshot />
</Shell>
)

triggerRightSidebarShortcut()
fireEvent.click(screen.getByRole('button', { name: 'common.maximize' }))
expect(screen.getByTestId('shell-state')).toHaveTextContent('open:files:true')

fireEvent.click(screen.getByRole('button', { name: 'minimize shell' }))

expect(screen.getByTestId('shell-state')).toHaveTextContent('open:files:false')
})

it('does not respond to the right sidebar shortcut when disabled', () => {
render(
<Shell defaultTab="files">
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/components/chat/panes/Shell/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ export {
useResourcePane
} from './resourcePane'
export { ResourcePaneCountButton, type ResourcePaneCountButtonProps } from './ResourcePaneCountButton'
export { Shell, useOptionalShellState, useShellActions, useShellState } from './Shell'
export { Shell, useOptionalShellActions, useOptionalShellState, useShellActions, useShellState } from './Shell'
2 changes: 1 addition & 1 deletion src/renderer/components/chat/panes/Shell/resourcePane.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { createContext, type ReactNode, use, useEffect, useRef } from 'react'
import { Shell, useShellActions } from './Shell'

// ── Resource-list-as-right-pane wiring ──────────────────────────────────────
// In classic-layout mode (`topic.layout`/`agent.layout === 'classic'`) the topic/session list moves into the
// In classic-layout mode the topic/session list moves into the
// chat's right pane as an extra tab. The list node + its label are provided once at
// the page level via context, so the Chat/AgentChat tree and the pane surfaces don't prop-thread
// them through every layer. The tab/panel/toggle below derive everything from this context, and
Expand Down
Loading
Loading