feat(tasks-ui): readability pass, height-budget fix and leftover sweep

The native port is finished off with the readability work the earlier rounds
left open, plus the cleanup of everything the shadcn era or the older canvas
left behind.

- Geometry: node height is now composed from named parts (chrome, two title
  lines, meta row) and per-node extras, so a teammate card that carries a task
  line no longer gets clipped by the old fixed 68px budget; the layout spec
  follows the new model and GRAPH_ROW_STRIDE stays exported for it.
- Readability: row rhythm (28-32px), three ink levels for title/meta/owner,
  truncation with title hints, current-row and hover expressed as an accent bar
  plus a hover fill (no shadows), phase frames and edges back on the l1/l2
  hairlines, control cluster uniformly 28px, drawer durations on tabular
  figures, kill action revealed on hover/focus without shifting the row, no
  horizontal overflow at 360px.
- Task window: the markdown body is pulled onto the page scale (12px body,
  12/13px headings, tightened list indent and paragraph spacing) while the
  shared MarkdownText/markdownTextProps contract is untouched.
- Cleanup: dead stylesheet rules, unused TSX exports and helpers, stale
  comments that still described the retired Variant-D canvas, zero-reference
  i18n keys across the dictionaries, and the Tailwind/shadcn/Variant-D
  narrative in the design doc, AGENTS.md and the plugin guide (kept as one
  short "why it was rolled back" section).

Verified here: typecheck and lint clean; 133 files / 1413 tests; build with no
radix-ui or --tw- strings in lib/client.js (988.9 KiB); the 70-assertion
real-browser contract at 70/70 with the 20 reference screenshots regenerated;
mount e2e 7/7.
This commit is contained in:
Menghuan1918
2026-09-27 22:18:19 +08:00
parent ae4280c70e
commit b554665bde
35 changed files with 856 additions and 1388 deletions
-72
View File
@@ -90,29 +90,16 @@ export const zh = {
openWithSettingsRemove: '删除',
openWithSettingsInvalidHint: '名称或模板(需含 {path} 且以 scheme:// 开头)未填写的编辑器不会出现在菜单中',
newTab: '新建标签页',
openExplorer: '资源管理器',
brokenSymlink: '失效的软链接',
openGit: 'Git 面板',
newTerminal: '新终端',
terminalLimit: '终端数量已达上限 (3)',
close: '关闭',
closeOtherTabs: '关闭其他页签',
closeLeftTabs: '关闭左侧页签',
closeRightTabs: '关闭右侧页签',
floatDropHint: '松开以在自由窗口中打开',
dockToSidebar: '回到侧边栏',
pinTerminal: '固定终端',
pinAgentTerminal: '固定 Agent 终端',
pinToWorkspace: '固定到工作区',
pinToGlobal: '固定到全局',
unpinTerminal: '取消固定',
pinnedTerminalTooltip: '{kind} · {scope} · {cwd}',
pinnedTerminalKindUi: 'UI 终端',
pinnedTerminalKindAgent: 'Agent 终端',
pinnedTerminalScopeWorkspace: '固定到工作区',
pinnedTerminalScopeGlobal: '固定到全局',
pinnedRailLabel: '固定终端',
closePinnedTerminal: '关闭终端',
collapseBottomPanel: '折叠底部面板',
expandBottomPanel: '展开底部面板',
terminalError: '终端连接失败',
@@ -143,10 +130,6 @@ export const zh = {
loading: '加载中…',
error: '加载失败',
retry: '重试',
splitLeft: '向左分栏',
splitRight: '向右分栏',
splitUp: '向上分栏',
splitDown: '向下分栏',
notRepo: '当前目录不是 git 仓库',
noChanges: '没有变更',
statusTruncated: '变更过多,仅显示前 2000 条',
@@ -156,7 +139,6 @@ export const zh = {
unstageAll: '全部取消暂存',
commitPlaceholder: '提交信息 (Ctrl+Enter)',
commit: '提交',
commitError: '提交失败',
branch: '分支',
worktree: '工作树',
checkoutError: '切换分支失败',
@@ -180,7 +162,6 @@ export const zh = {
diffDeleted: '删除',
diffRenamed: '重命名',
diffExpand: '展开其余 {count} 行',
diffCollapse: '收起',
discard: '放弃更改',
discardTitle: '放弃更改',
discardDesc: '将丢弃「{path}」的工作区修改(不可恢复)。',
@@ -201,19 +182,15 @@ export const zh = {
loadMore: '加载更多',
historyLoadError: '加载更多历史失败',
produced: '本次产出',
producedOpen: '在侧边栏中打开',
showInFolder: '在文件夹中显示',
disconnected: '终端连接断开,重连中…',
exited: '终端进程已退出',
noSession: '选择一个会话以使用侧边栏',
pluginNotLoaded: '插件未加载,标签页暂不可用:',
hiddenFiles: '隐藏文件',
parent: '上级目录',
copied: '已复制',
copy: '复制',
newFile: '新文件',
openEditor: '打开编辑器',
gitDetail: '查看变更详情',
referenceFile: '@文件',
addToConversation: '添加到对话',
copyRelative: '复制相对地址',
@@ -257,7 +234,6 @@ export const zh = {
settingsSchemeCustomDesc: '完全由你控制:注入自定义 CSS(可覆盖内置样式),并指定标题栏下移距离',
settingsSchemeDetectedSuffix: '已检测',
settingsCustomCssTitle: '自定义 CSS',
settingsCustomCssDesc: '追加到页面末尾的样式(同优先级下后写胜出;覆盖 JS 内联变量需用 !important)',
settingsCustomCssPlaceholder: '/* 例:为自绘标题栏的壳预留 36px */\nhtml[data-dsh-title-bar-height="36"] {\n --dsh-title-bar-strip: 36px !important;\n}',
settingsSaveFailed: '保存失败',
settingsConflict: '设置已被其他窗口修改,请重试',
@@ -280,7 +256,6 @@ export const zh = {
settingsFontFamilyPlaceholder: '"JetBrains Mono", monospace',
settingsFontSizeTitle: '终端字号',
settingsFontSizeDesc: '终端字号(9–32,默认 13)',
settingsFontSizeSuffix: 'px',
settingsShellTitle: 'Shell 路径',
settingsShellDesc: 'UI 与模型终端启动的 shell(绝对路径或可执行名)。留空按既有顺序解析:yaml 的 config.shell → $SHELL / 登录 shell / Windows 的 powershell.exe。对之后打开的终端生效',
settingsShellPlaceholder: '如 /bin/zsh(留空自动解析)',
@@ -322,19 +297,14 @@ export const zh = {
browserEmbedBlockedDesc: '该站点通过 X-Frame-Options / frame-ancestors 禁止在其它页面中显示,无法在侧边栏内加载。可在浏览器中直接打开',
browserEmbedAnyway: '仍然加载',
subagent: '任务管理',
openSubagent: '任务管理',
subagentMainAgent: '主代理',
subagentEmpty: '暂无子代理',
subagentEmptyDesc: '当前主代理派生的子代理将显示在这里',
subagentRunning: '运行中',
subagentInactive: '空闲',
subagentModeOneShot: '一次性',
subagentModeContinuable: '可续接',
subagentCount: '{count} 个子代理',
subagentCountRunning: '{count} 个子代理 · {running} 运行中',
subagentDiagCorrupt: '目录损坏',
subagentDiagUnsupported: '不支持的条目',
subagentDiagUnavailable: '不可用',
subagentThinking: '思考中…',
sideChat: '侧边对话(beta)',
sideChatNew: '新建对话',
@@ -355,10 +325,7 @@ export const zh = {
sideChatThink: '思考过程',
sideChatInjection: '已注入上下文',
sideChatSend: '发送',
sideChatCancel: '停止',
sideChatCancelTitle: '中止当前回合(保留队列)',
sideChatClose: '关闭线程',
sideChatCloseTitle: '释放线程的 agent(历史保留)',
sideChatError: '侧边对话出错:{message}',
sideChatTurnUsage: '输入 {input} tok · 输出 {output} tok',
sideChatBlockCollapse: '收起',
@@ -394,7 +361,6 @@ export const zh = {
jobDurationMinutes: '{minutes} 分 {seconds} 秒',
jobDurationHours: '{hours} 小时 {minutes} 分',
jobViewOutput: '查看输出',
jobHideOutput: '收起输出',
jobNoOutput: '暂无输出',
jobNotReadYet: '等待模型读取该任务的输出(模型执行 job_output 后,输出会显示在这里)',
jobOutputTruncated: '输出过长,已截断显示',
@@ -412,7 +378,6 @@ export const zh = {
settingsViewModeGraphDesc: '分层节点图,可缩放平移',
settingsViewModeTree: '树状图',
settingsViewModeTreeDesc: '经典缩进树,键盘可导航',
tasksWorkflowMember: '工作流成员',
tasksFoldCompleted: '✓ {count} 已完成',
tasksFoldExpand: '展开已完成的节点',
tasksFoldCollapse: '折叠已完成的节点',
@@ -433,7 +398,6 @@ export const zh = {
tasksStateError: '出错',
teamBoard: '团队任务板',
teamChip: '团队 {members} 成员 · {tasks} 任务',
teamMembers: '成员',
teamTasksEmpty: '暂无共享任务',
teamTaskCreate: '新建任务',
teamTaskSubject: '标题',
@@ -597,29 +561,16 @@ export const en: Record<keyof typeof zh, string> = {
openWithSettingsRemove: 'Remove',
openWithSettingsInvalidHint: 'Editors with a missing name or a template without {path} / scheme:// are not shown in the menu',
newTab: 'New tab',
openExplorer: 'Explorer',
brokenSymlink: 'Broken symlink',
openGit: 'Git panel',
newTerminal: 'New terminal',
terminalLimit: 'Terminal limit reached (3)',
close: 'Close',
closeOtherTabs: 'Close Other Tabs',
closeLeftTabs: 'Close Tabs to the Left',
closeRightTabs: 'Close Tabs to the Right',
floatDropHint: 'Release to open in a free window',
dockToSidebar: 'Dock Back to Sidebar',
pinTerminal: 'Pin Terminal',
pinAgentTerminal: 'Pin Agent Terminal',
pinToWorkspace: 'Pin to Workspace',
pinToGlobal: 'Pin Globally',
unpinTerminal: 'Unpin',
pinnedTerminalTooltip: '{kind} · {scope} · {cwd}',
pinnedTerminalKindUi: 'UI Terminal',
pinnedTerminalKindAgent: 'Agent Terminal',
pinnedTerminalScopeWorkspace: 'Pinned to workspace',
pinnedTerminalScopeGlobal: 'Pinned globally',
pinnedRailLabel: 'Pinned Terminals',
closePinnedTerminal: 'Close Terminal',
collapseBottomPanel: 'Collapse bottom panel',
expandBottomPanel: 'Expand bottom panel',
terminalError: 'Terminal connection failed',
@@ -650,10 +601,6 @@ export const en: Record<keyof typeof zh, string> = {
loading: 'Loading…',
error: 'Failed to load',
retry: 'Retry',
splitLeft: 'Split left',
splitRight: 'Split right',
splitUp: 'Split up',
splitDown: 'Split down',
notRepo: 'This directory is not a git repository',
noChanges: 'No changes',
statusTruncated: 'Too many changes; showing the first 2,000 entries',
@@ -663,7 +610,6 @@ export const en: Record<keyof typeof zh, string> = {
unstageAll: 'Unstage all',
commitPlaceholder: 'Commit message (Ctrl+Enter)',
commit: 'Commit',
commitError: 'Commit failed',
branch: 'Branch',
worktree: 'Worktree',
checkoutError: 'Branch switch failed',
@@ -687,7 +633,6 @@ export const en: Record<keyof typeof zh, string> = {
diffDeleted: 'Deleted',
diffRenamed: 'Renamed',
diffExpand: 'Expand {count} more rows',
diffCollapse: 'Collapse',
discard: 'Discard changes',
discardTitle: 'Discard changes',
discardDesc: 'This discards the worktree changes of "{path}" (not recoverable).',
@@ -708,19 +653,15 @@ export const en: Record<keyof typeof zh, string> = {
loadMore: 'Load more',
historyLoadError: 'Failed to load more history',
produced: 'Produced',
producedOpen: 'Open in sidebar',
showInFolder: 'Show in folder',
disconnected: 'Terminal disconnected, reconnecting…',
exited: 'Terminal process exited',
noSession: 'Select a conversation to use the sidebar',
pluginNotLoaded: 'Plugin not loaded; tab unavailable:',
hiddenFiles: 'Hidden files',
parent: 'Parent directory',
copied: 'Copied',
copy: 'Copy',
newFile: 'New file',
openEditor: 'Open editor',
gitDetail: 'View change details',
referenceFile: '@file',
addToConversation: 'Add to conversation',
copyRelative: 'Copy relative path',
@@ -764,7 +705,6 @@ export const en: Record<keyof typeof zh, string> = {
settingsSchemeCustomDesc: 'Full control: inject custom CSS (can override built-in styles) and set the title-bar shift distance',
settingsSchemeDetectedSuffix: 'detected',
settingsCustomCssTitle: 'Custom CSS',
settingsCustomCssDesc: 'Styles appended at the end of the page (later in the cascade wins ties; use !important to override JS-written inline variables)',
settingsCustomCssPlaceholder: '/* e.g. reserve 36px for a shell with a custom-drawn title bar */\nhtml[data-dsh-title-bar-height="36"] {\n --dsh-title-bar-strip: 36px !important;\n}',
settingsSaveFailed: 'Failed to save',
settingsConflict: 'The setting changed in another window — please retry',
@@ -793,7 +733,6 @@ export const en: Record<keyof typeof zh, string> = {
settingsShellArgsDesc: 'Explicit shell arguments, space-separated; when non-empty they fully replace the defaults (same contract as the yaml shellArgs)',
settingsShellArgsPlaceholder: 'e.g. -l (empty = defaults)',
settingsFontSizeDesc: 'Terminal font size in px (9–32, default 13)',
settingsFontSizeSuffix: 'px',
settingsTabsTitle: 'Sidebar content',
settingsViewersTitle: 'File viewers',
settingsGeneralTitle: 'General',
@@ -829,19 +768,14 @@ export const en: Record<keyof typeof zh, string> = {
browserEmbedBlockedDesc: 'The site forbids being displayed inside other pages (X-Frame-Options / frame-ancestors), so it cannot load in the sidebar. Open it directly in your browser instead.',
browserEmbedAnyway: 'Load anyway',
subagent: 'Tasks',
openSubagent: 'Tasks',
subagentMainAgent: 'Main agent',
subagentEmpty: 'No subagents',
subagentEmptyDesc: 'Subagents spawned under the main agent will appear here',
subagentRunning: 'Running',
subagentInactive: 'Inactive',
subagentModeOneShot: 'One-shot',
subagentModeContinuable: 'Continuable',
subagentCount: '{count} subagents',
subagentCountRunning: '{count} subagents · {running} running',
subagentDiagCorrupt: 'Corrupt',
subagentDiagUnsupported: 'Unsupported',
subagentDiagUnavailable: 'Unavailable',
subagentThinking: 'Thinking…',
sideChat: 'Side Chat (beta)',
sideChatNew: 'New thread',
@@ -862,10 +796,7 @@ export const en: Record<keyof typeof zh, string> = {
sideChatThink: 'Thinking',
sideChatInjection: 'Context injected',
sideChatSend: 'Send',
sideChatCancel: 'Stop',
sideChatCancelTitle: 'Abort the running turn (queued work is kept)',
sideChatClose: 'Close thread',
sideChatCloseTitle: 'Release the thread\'s agent (history is kept)',
sideChatError: 'Side Chat error: {message}',
sideChatTurnUsage: 'Input {input} tok · Output {output} tok',
sideChatBlockCollapse: 'Collapse',
@@ -901,7 +832,6 @@ export const en: Record<keyof typeof zh, string> = {
jobDurationMinutes: '{minutes}m {seconds}s',
jobDurationHours: '{hours}h {minutes}m',
jobViewOutput: 'View output',
jobHideOutput: 'Hide output',
jobNoOutput: 'No output yet',
jobNotReadYet: 'Waiting for the model to read this job; its output appears here once the model runs job_output',
jobOutputTruncated: 'Output truncated',
@@ -919,7 +849,6 @@ export const en: Record<keyof typeof zh, string> = {
settingsViewModeGraphDesc: 'Layered node graph with zoom and pan',
settingsViewModeTree: 'Tree',
settingsViewModeTreeDesc: 'Classic indentation tree, keyboard navigable',
tasksWorkflowMember: 'Workflow member',
tasksFoldCompleted: '✓ {count} completed',
tasksFoldExpand: 'Expand the completed nodes',
tasksFoldCollapse: 'Collapse the completed nodes',
@@ -940,7 +869,6 @@ export const en: Record<keyof typeof zh, string> = {
tasksStateError: 'Error',
teamBoard: 'Team task board',
teamChip: 'Team {members} members · {tasks} tasks',
teamMembers: 'Members',
teamTasksEmpty: 'No shared tasks yet',
teamTaskCreate: 'New task',
teamTaskSubject: 'Subject',