Files
Agent-System-Frontend/src/workspaces.ts
T
weichen 204ca67dc7 Merge file preview into a Work/Files third column and rework the left rail
Why: The three-column workbench redesign converges entries and hierarchy:
project switching tops the left rail (identity shown once), sessions and
search stay centered, files/workspaces/account sink to the bottom. The
right column becomes a Work/Files third column that absorbs the preview
pane, which is no longer an independent fourth region; the artifacts
workspace overlay folds into the Files entry, and stop control
consolidates into the input area with a light fast/slow-lane status hint.

Evidence: make test-frontend NOT_RUN at commit time; the run and its
outcome are recorded in the Dev task card before integration.

Impact: App.tsx layout and divider width tiers (work 280-560, files with
open preview 420-1100); store UI state rightTab work/files plus filesView
with syncFilesEntry replacing syncPreviewRail; Workbench dual entry;
PreviewPane gains a back-to-list control; TaskSidebar project switcher;
TopBar drops project identity; Conversation drops the header stop button
and gains the input status line; workspaces.ts drops the artifacts builtin.

Refs: three-column workbench proposal (2026-10-11), DESIGN.md 6/9.3
revision follows in the Dev repo.
2026-10-11 02:40:18 +00:00

66 lines
1.9 KiB
TypeScript

// 体系工具排位:服务端声明的工作区对所有用户可见,按 shortcut 数字占位;
// 内置「代理」补进空位。文件浏览在第三栏「文件」入口(方案:入口收敛),不再占体系工具位。
// 插件管理面板不进这条清单。
export interface WorkspaceEntry {
key: string
title: string
icon: string
shortcut: string
}
export interface WorkspaceSource {
id: string
title: string
icon?: string
shortcut?: string
}
const BUILTINS: Omit<WorkspaceEntry, 'shortcut'>[] = [
{ key: 'agents', title: '代理', icon: '🤖' },
]
function shortcutNum(raw?: string): number | null {
if (!raw) return null
const m = raw.match(/(\d)/)
if (!m) return null
const n = Number(m[1])
return n >= 1 && n <= 9 ? n : null
}
export function buildWorkspaceEntries(server: WorkspaceSource[]): WorkspaceEntry[] {
const used = new Set<number>()
const ranked: { rank: number; entry: Omit<WorkspaceEntry, 'shortcut'> }[] = []
const unranked: Omit<WorkspaceEntry, 'shortcut'>[] = []
for (const w of server) {
const entry = { key: `ws:${w.id}`, title: w.title, icon: w.icon || '🗂' }
const n = shortcutNum(w.shortcut)
if (n && !used.has(n)) {
used.add(n)
ranked.push({ rank: n, entry })
} else {
unranked.push(entry)
}
}
const takeFree = (prefer: number): number => {
if (!used.has(prefer) && prefer >= 1 && prefer <= 9) {
used.add(prefer)
return prefer
}
for (let n = 1; n <= 9; n++) {
if (!used.has(n)) {
used.add(n)
return n
}
}
return 99
}
ranked.push({ rank: takeFree(1), entry: BUILTINS[0] })
for (const entry of unranked) ranked.push({ rank: takeFree(9), entry })
return ranked
.filter(item => item.rank <= 9)
.sort((a, b) => a.rank - b.rank)
.slice(0, 9)
.map((item, i) => ({ ...item.entry, shortcut: `⌘${i + 1}` }))
}