From 894ca2e71bf73fab36ed531106e8ed89bf33d659 Mon Sep 17 00:00:00 2001 From: lbx154 <145820328+lbx154@users.noreply.github.com> Date: Tue, 3 Nov 2026 06:06:21 -0800 Subject: [PATCH 1/6] =?UTF-8?q?=E7=BD=91=E9=A1=B5=E7=95=8C=E9=9D=A2?= =?UTF-8?q?=E5=8E=BB=E6=8E=89=20AI=20=E5=91=B3=EF=BC=9A=E9=BB=91=E7=99=BD?= =?UTF-8?q?=E7=81=B0=E3=80=81=E7=B3=BB=E7=BB=9F=E5=AD=97=E4=BD=93=E3=80=81?= =?UTF-8?q?=E8=83=B6=E5=9B=8A=E6=8E=A7=E4=BB=B6=EF=BC=8C=E5=88=A0=E5=A4=9A?= =?UTF-8?q?=E4=BD=99=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 配色只剩黑白灰;深色用纯黑。金色/蓝色 token 改为 ink 的别名,状态点保留绿(运行)和红(失败) - 字体优先 SF Pro / 苹方,去掉衬线标题 - 按钮和输入框改成胶囊形,复选框随主题黑白 - 侧栏:删“全部项目合计 · 不含进行中的调用”和每个项目的花费;回收站并进筛选行;新建改成胶囊按钮 - 顶部:花费只显示 ≈$0.40,说明放在悬停提示;“已工作”时长只留在用量明细里 - 总负责人勾选项去掉卡片框,改为分隔线列表 Co-Authored-By: Claude Opus 5.5 --- frontend/web/src/App.tsx | 2 +- frontend/web/src/components/ChiefNeeds.tsx | 2 +- frontend/web/src/components/EventStream.tsx | 2 +- frontend/web/src/components/Sidebar.tsx | 14 +- frontend/web/src/components/TopBar.tsx | 17 +-- .../web/src/components/customerExperience.css | 25 +-- frontend/web/src/components/delivery.css | 2 +- frontend/web/src/index.css | 144 ++++++++---------- frontend/web/src/test/core.test.ts | 4 +- .../web/src/test/customerExperience.test.tsx | 1 - frontend/web/src/test/sidebar.test.ts | 9 +- .../web/src/test/statusPresentation.test.tsx | 27 ---- .../web/src/test/workspaceContext.test.tsx | 6 +- frontend/web/tailwind.config.ts | 7 +- 14 files changed, 102 insertions(+), 160 deletions(-) diff --git a/frontend/web/src/App.tsx b/frontend/web/src/App.tsx index 0aa133587..379a89282 100644 --- a/frontend/web/src/App.tsx +++ b/frontend/web/src/App.tsx @@ -932,7 +932,7 @@ export default function App() { snapshotStale={snapQ.isError} readOnly={kiosk} /> : -
+
{shownName(projects.find(project => project.id === activeSid) ?? {}, locale === 'zh-CN', t('sidebar.unnamedSession'))}
} diff --git a/frontend/web/src/components/ChiefNeeds.tsx b/frontend/web/src/components/ChiefNeeds.tsx index 40d8e7aed..66a639988 100644 --- a/frontend/web/src/components/ChiefNeeds.tsx +++ b/frontend/web/src/components/ChiefNeeds.tsx @@ -21,7 +21,7 @@ export function ChiefNeeds({ zh, onStart }: { }; return (
-

{zh ? '你的总负责人' : 'Your chief'}

+

{zh ? '你的总负责人' : 'Your chief'}

{zh ? '它照看你所有的项目,盯着你关心的方向,有值得说的会主动来找你。勾选你需要的就行。' : 'It looks after all your projects, follows your directions, and comes to you when something is worth it. Tick what you need.'}

diff --git a/frontend/web/src/components/EventStream.tsx b/frontend/web/src/components/EventStream.tsx index c2697cd38..b5a42c9b7 100644 --- a/frontend/web/src/components/EventStream.tsx +++ b/frontend/web/src/components/EventStream.tsx @@ -1038,7 +1038,7 @@ export function EventStream({ {hasOlder && } {deferredEvents.length === 0 ? ( historyStatus === 'ready' ? emptyState ?? (onCompose ?
-

{locale === 'zh-CN' ? '从你想完成的事开始' : 'Start with what you want to accomplish'}

+

{locale === 'zh-CN' ? '从你想完成的事开始' : 'Start with what you want to accomplish'}

{locale === 'zh-CN' ? '直接说出目标,也可以选择下面的场景,再补充你的材料和要求。' : 'Describe your goal, or choose a starting point and add your material and requirements.'}

{locale === 'zh-CN' ? '或者直接试一个实际跑过的任务' : 'Or try a task that was run end to end'}

diff --git a/frontend/web/src/components/Sidebar.tsx b/frontend/web/src/components/Sidebar.tsx index 206d93a1c..389cfca74 100644 --- a/frontend/web/src/components/Sidebar.tsx +++ b/frontend/web/src/components/Sidebar.tsx @@ -318,12 +318,11 @@ export function Sidebar({ onClick={onNew} disabled={creating} title={t('sidebar.create')} - className="ml-auto flex h-8 items-center justify-center rounded-md px-2 text-xs text-ink-dim hover:bg-bg disabled:opacity-40" + className="sidebar-new ml-auto" > - {creating ? '…' : locale === 'zh-CN' ? '+ 新建' : '+ New'} + {creating ? '…' : locale === 'zh-CN' ? '新建' : 'New'}
-

{zh ? '全部项目合计 · 不含进行中的调用' : 'All projects · excludes calls in progress'}

@@ -341,20 +340,17 @@ export function Sidebar({ ) : null}
- {onOpenTrash && }
{(['active', 'followup', 'archived'] as const).map(filter => )} + {onOpenTrash && }
{organization.error &&

{zh ? '浏览器无法读取或保存项目标记。' : 'This browser cannot read or save project markers.'}

} {organizationNotice &&

{organizationNotice}

} - {projectFilter === 'followup' &&

{zh ? '你标记为待跟进的项目。' : 'Projects you marked to follow up.'}

}
{loading && projects.length === 0 ?
{t('common.loading')}
: null} @@ -402,7 +398,6 @@ export function Sidebar({ const work = project.work_status; const workLabel = work?.label[locale === 'zh-CN' ? 'zh-CN' : 'en']; const message = project.last_message || workLabel; - const spend = spendEstimateLabel({ spendUsd: project.spend_usd ?? null, spendStatus: project.spend_status }, zh, true) || '—'; const name = shownName(project, zh, t('sidebar.unnamedSession')); return (
}
- {message} - {spend}
) : null} - {slim && onOpenResults ? : null} {slim && openKnowledge ? : null} {!slim ? ( <> - - {onSearch && }
{locale === 'zh-CN' ? '项目' : 'Projects'} 0 && localProjects.length < projects.length ? : null} + {onSearch && } @@ -470,6 +436,9 @@ export function Sidebar({ {settings && } + {openKnowledge && }
diff --git a/frontend/web/src/components/customerExperience.css b/frontend/web/src/components/customerExperience.css index a097a0275..6b3253e28 100644 --- a/frontend/web/src/components/customerExperience.css +++ b/frontend/web/src/components/customerExperience.css @@ -3,7 +3,6 @@ .landing-intro h1 { color: rgb(var(--ink)); font-size: 36px; font-weight: 700; letter-spacing: -.03em; line-height: 1.3; } .landing-composer { width: 100%; max-width: 680px; margin-top: 12px; text-align: left; } .landing-navigation { position: absolute; top: 12px; right: 16px; } -.landing-caption { margin-top: 12px; color: rgb(var(--ink-faint)); font-size: 12px; line-height: 20px; text-align: center; } /* Where the project works: a new folder unless the operator names one on the server. */ .landing-workdir { display: flex; align-items: center; justify-content: center; gap: 8px; margin-top: 4px; color: rgb(var(--ink-faint)); font-size: 12px; line-height: 20px; } .landing-workdir span { flex: none; } @@ -22,7 +21,7 @@ .landing-starters { width: 100%; max-width: 680px; margin-top: 16px; text-align: left; } .landing-starters h2 { padding: 0 12px; color: rgb(var(--ink-faint)); font-size: 12px; font-weight: 500; } .starter-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 4px 16px; margin-top: 8px; } -.starter-card { display: flex; align-items: flex-start; gap: 12px; padding: 12px; border: 0; border-radius: var(--radius-control); background: transparent; text-align: left; color: rgb(var(--ink-dim)); transition: background-color 150ms; } +.starter-card { display: flex; align-items: flex-start; gap: 12px; padding: 14px; border: 0; border-radius: var(--radius-panel); background: transparent; text-align: left; color: rgb(var(--ink-dim)); transition: background-color 150ms; } .starter-card:hover { background: rgb(var(--surface-2)); } .starter-card:focus-visible { outline: 2px solid rgb(var(--accent)); outline-offset: 3px; } .starter-card:disabled { opacity: .5; cursor: wait; } @@ -39,8 +38,6 @@ .file-browser button:hover { background: rgb(var(--surface-2)); } .file-browser strong { display: block; overflow-wrap: anywhere; color: rgb(var(--ink)); font-size: 14px; } .file-browser small { display: block; overflow-wrap: anywhere; color: rgb(var(--ink-faint)); margin-top: 4px; font-size: 12px; } -.sidebar-global-search { display: flex; flex: none; align-items: center; gap: 10px; min-height: var(--control-height); margin: 12px 12px 0; padding: 8px 12px; border-radius: var(--radius-control); color: rgb(var(--ink-dim)); font-size: 14px; text-align: left; } -.sidebar-global-search:hover { background: rgb(var(--surface-2)); color: rgb(var(--ink)); } .sidebar-project-search { display: flex; align-items: center; gap: 8px; border: 1px solid rgb(var(--line)); border-radius: var(--radius-control); padding: 0 8px; background: rgb(var(--surface)); transition: border-color 160ms ease; } .sidebar-project-search:focus-within { border-color: rgb(var(--accent)); } .sidebar-project-filters { display: flex; gap: 16px; margin: 2px 16px 10px; padding: 0; border-bottom: 1px solid rgb(var(--line)); } @@ -51,6 +48,8 @@ .sidebar-new { display: inline-flex; height: 26px; align-items: center; padding: 0 12px; border: 1px solid rgb(var(--line)); border-radius: 999px; color: rgb(var(--ink)); font-size: 12px; transition: border-color 140ms ease; } .sidebar-new:hover { border-color: rgb(var(--ink-faint)); } .sidebar-new:disabled { opacity: .4; } +.sidebar-search { display: inline-flex; width: 28px; height: 26px; align-items: center; justify-content: center; border-radius: 999px; color: rgb(var(--ink-dim)); } +.sidebar-search:hover { background: rgb(var(--surface-2)); color: rgb(var(--ink)); } .project-organization-menu { display: flex; flex-direction: column; gap: 2px; margin: 0 8px 8px; padding-top: 4px; border-top: 1px solid rgb(var(--line)); font-size: 13px; } .project-organization-menu button { min-height: var(--control-height); } .sidebar-footer { display: flex; flex-wrap: wrap; flex: none; align-items: center; justify-content: space-between; gap: 4px; min-height: 52px; padding: 8px 12px; border-top: 1px solid rgb(var(--line)); color: rgb(var(--ink-faint)); } diff --git a/frontend/web/src/components/experience.css b/frontend/web/src/components/experience.css index a73aaea66..99d713792 100644 --- a/frontend/web/src/components/experience.css +++ b/frontend/web/src/components/experience.css @@ -3,7 +3,7 @@ .experience-panel label { display: flex; flex-direction: column; gap: 8px; } .experience-panel .brand-button { align-self: flex-start; } .experience-input, .experience-select { - min-width: 0; border: 1px solid rgb(var(--field-line)); border-radius: var(--radius-control); + min-width: 0; border: 1px solid rgb(var(--field-line)); border-radius: 12px; background: rgb(var(--surface)); color: rgb(var(--ink)); font-size: 14px; line-height: 22px; } .experience-input { width: 100%; padding: 10px 12px; } @@ -45,7 +45,7 @@ .edition-pane { display: flex; flex-shrink: 0; min-width: 0; flex-direction: column; } .edition-pane textarea, .edition-pane pre, .edition-preview, .edition-note { width: 100%; height: clamp(280px, 42dvh, 440px); min-height: 280px; overflow: auto; padding: 16px; - border: 1px solid rgb(var(--field-line)); border-radius: var(--radius-control); + border: 1px solid rgb(var(--field-line)); border-radius: var(--radius-panel); background: rgb(var(--surface)); color: rgb(var(--ink)); overflow-wrap: anywhere; } .edition-pane textarea, .edition-pane pre { font: 13px/1.75 'Geist Mono Variable', ui-monospace, monospace; white-space: pre-wrap; } diff --git a/frontend/web/src/index.css b/frontend/web/src/index.css index ab1e48a32..f0845b289 100644 --- a/frontend/web/src/index.css +++ b/frontend/web/src/index.css @@ -969,35 +969,34 @@ button { background: rgb(var(--surface)); transition: box-shadow 180ms ease, border-color 180ms ease; } -.result-card:hover { border-color: rgb(var(--silver)); box-shadow: var(--shadow-lift); } +.result-card:hover { border-color: rgb(var(--silver)); } .result-card-preview { display: flex; justify-content: center; padding: 16px; - border-bottom: 1px solid rgb(var(--line)); - background: rgb(var(--surface-2) / 55%); + background: rgb(var(--surface-2)); } .result-card-preview[data-delivery-thumbnail] { aspect-ratio: 16 / 9; align-items: center; } .result-card-preview[data-delivery-thumbnail] > button { width: 100%; height: 100%; } .result-card-preview[data-delivery-thumbnail] img { width: 100%; height: 100%; max-height: 100%; object-fit: contain; } .result-card-preview img { border-radius: var(--radius-sm); cursor: zoom-in; } .result-card-model { display: block; padding: 10px; } -.result-card-body { padding: 14px 18px 12px; } +.result-card-body { padding: 20px 24px 22px; } .result-card-kind { display: flex; align-items: center; gap: 8px; color: rgb(var(--ink-faint)); font-size: 12px; } .result-card-title { - margin-top: 4px; + margin-top: 6px; overflow: hidden; color: rgb(var(--ink)); - font-size: 18px; - font-weight: 500; - line-height: 1.4; + font-size: 22px; + font-weight: 600; + letter-spacing: -.02em; + line-height: 1.3; text-overflow: ellipsis; white-space: nowrap; } .result-card-files { display: flex; flex-wrap: wrap; gap: 4px 16px; margin-top: 8px; color: rgb(var(--ink-dim)); font-size: 13px; } .result-card-files li { display: flex; min-width: 0; align-items: center; gap: 6px; } -.result-card-files li > span { color: rgb(var(--ink-faint)); font-size: 11px; } -.result-card-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; margin: 12px 0 0; } +.result-card-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; margin: 16px 0 0; } .result-card-actions button { min-height: 30px; border-radius: var(--radius-control); @@ -1008,7 +1007,8 @@ button { } .result-card-actions button:hover { background: rgb(var(--surface-2)); color: rgb(var(--ink)); } /* Opening the result is the card's one action, and looks like a button. */ -.result-card-actions .result-card-open { border: 1px solid rgb(var(--line)); background: rgb(var(--surface)); color: rgb(var(--ink)); font-weight: 500; padding-inline: 16px; } +.result-card-actions .result-card-open { min-height: 34px; background: rgb(var(--ink)); color: rgb(var(--on-accent)); font-weight: 500; padding-inline: 20px; } +.result-card-actions .result-card-open:hover { background: rgb(var(--accent-hover)); color: rgb(var(--on-accent)); } @media (max-width: 640px), (pointer: coarse) { .result-card-actions button, .chat-context-tools button, .task-line-action { min-height: 44px; } .chat-context { padding: 8px 16px 6px; align-items: center; } diff --git a/frontend/web/src/test/sessionContextApp.test.tsx b/frontend/web/src/test/sessionContextApp.test.tsx index 5f1e07b05..1ef6c4e54 100644 --- a/frontend/web/src/test/sessionContextApp.test.tsx +++ b/frontend/web/src/test/sessionContextApp.test.tsx @@ -342,7 +342,7 @@ describe('App session composer ownership', () => { act(() => renderer.root.findByType(Sidebar).props.onNew()); expect(document.title).toBe('Argus'); }); - it('counts deliveries once for the sidebar and map, keeping the latest delivery as the sidebar target', () => { + it('counts deliveries once for the map and keeps files reachable from the results entry', () => { fixture.artifacts = [{ path: 'report.md', name: 'report.md', kind: 'markdown', source: 'delivery' }, { path: 'data.csv', name: 'data.csv', kind: 'table', source: 'delivery' }] as never[]; fixture.turns = [1, 2, 3].map(n => ({ type: 'ui.argus', ts: n, event_id: n, delivery: { @@ -351,24 +351,16 @@ describe('App session composer ownership', () => { targets: fixture.artifacts.map((file: { path: string }) => ({ path: file.path, label: file.path, source: 'manager' })), primary_target: null, } })); refresh(); - expect(renderer.root.findByType(Sidebar).props.resultsCount).toBe(3); act(() => renderer.root.findAll(node => node.props.className === 'workspace-tab')[1].props.onClick()); expect(renderer.root.findByType(MapPanel).props.deliveryCount).toBe(3); act(() => renderer.root.findAll(node => node.props.className === 'workspace-tab')[0].props.onClick()); - act(() => renderer.root.findByType(Sidebar).props.onOpenResults()); - const deliveryModal = renderer.root.findAllByType(ArtifactModal).find(node => node.props.delivery)!; - expect(deliveryModal.props.delivery.delivery_id).toBe('d3'); - act(() => deliveryModal.props.onClose()); act(() => renderer.root.find(node => node.type === 'button' && node.children.includes('Results & files')).props.onClick()); expect(renderer.root.findByType(ResearchCanvas).props.artifacts).toHaveLength(2); }); - it('counts zero before any delivery exists and keeps files accessible from the file entry', () => { + it('keeps files accessible from the file entry before any delivery exists', () => { fixture.artifacts = [{ path: 'draft.md', name: 'draft.md', kind: 'markdown' }] as never[]; refresh(); - const sidebar = renderer.root.findByType(Sidebar); - expect(sidebar.props.resultsCount).toBe(0); expect(renderer.root.findAllByType(ResearchCanvas)).toHaveLength(0); - expect(renderer.root.findAll(node => node.type === 'button' && node.props['data-sidebar-results'] !== undefined).every(node => node.props.disabled)).toBe(true); act(() => renderer.root.find(node => node.type === 'button' && node.children.includes('Results & files')).props.onClick()); const canvas = renderer.root.findByType(ResearchCanvas); expect(canvas.props.requestedPath).toBe('__argus_files__'); diff --git a/frontend/web/src/test/sidebarResources.test.tsx b/frontend/web/src/test/sidebarResources.test.tsx index 1826dd27e..75c39acbc 100644 --- a/frontend/web/src/test/sidebarResources.test.tsx +++ b/frontend/web/src/test/sidebarResources.test.tsx @@ -9,7 +9,7 @@ const props = { projects: [{ id: 's-A', label: 'Synthetic session A', display_name: 'Synthetic session A', last_active: 1, daemon_alive: false, daemon_pid: null, workdir: '/synthetic' }], activeId: 's-A', localCwd: '/synthetic', onSelect: vi.fn(), onManage: vi.fn(), onOpenPanel: vi.fn(), - onOpenLearning: vi.fn(), onOpenResults: vi.fn(), resultsCount: 2, onNew: vi.fn(), loading: false, + onOpenLearning: vi.fn(), onSearch: vi.fn(), onNew: vi.fn(), loading: false, onToggleCollapse: vi.fn(), themeMode: 'light' as const, onCycleTheme: vi.fn(), }; function markup(collapsed = false) { @@ -18,40 +18,20 @@ function markup(collapsed = false) { finally { client.clear(); } } describe('top resource navigation', () => { - it('puts Results first and folds skills under Advanced', () => { + it('starts with the projects: search and new on one row, skills and settings at the bottom', () => { const html = markup(); - expect(html.indexOf('data-sidebar-resources')).toBeGreaterThan(0); - expect(html).toContain('data-sidebar-results'); - expect(html).toContain('This project’s results'); - expect(html).not.toContain('>2'); - expect(html.indexOf('data-sidebar-results')).toBeLessThan(html.indexOf('id="daemon-search"')); - expect(html).toContain('aria-expanded="false"'); - for (const label of ['aria-label="Plugins"', 'aria-label="Skill library"']) { - expect(html).not.toContain(label); - } + expect(html).not.toContain('data-sidebar-results'); + expect(html).not.toContain('data-sidebar-advanced'); + expect(html.indexOf('aria-label="Search history and results"')).toBeLessThan(html.indexOf('id="daemon-search"')); + expect(html.split('aria-label="Skill library"')).toHaveLength(2); + expect(html.indexOf('aria-label="Skill library"')).toBeGreaterThan(html.indexOf('Synthetic session A')); expect(html.indexOf('aria-label="Open settings"')).toBeGreaterThan(html.indexOf('Synthetic session A')); + expect(html).not.toContain('aria-label="Plugins"'); }); - it('shows the advanced entries above project search once opened', () => { - vi.stubGlobal('localStorage', { getItem: (key: string) => key === 'argus.sidebar.advanced.v1' ? 'open' : null, setItem: vi.fn(), removeItem: vi.fn() }); - try { - const html = markup(); - const labels = ['aria-label="Skill library"']; - for (const label of labels) { - expect(html).toContain(label); - expect(html.indexOf(label)).toBeLessThan(html.indexOf('id="daemon-search"')); - expect(html.split(label)).toHaveLength(2); - } - expect(labels.map(label => html.indexOf(label))).toEqual(labels.map(label => html.indexOf(label)).sort((a, b) => a - b)); - expect(html).not.toContain('aria-label="Learning feed"'); - expect(html).not.toContain('aria-label="Plugins"'); - } finally { vi.unstubAllGlobals(); } - }); - it('keeps a compact entry rail with Results and skills', () => { + it('keeps a compact entry rail with skills', () => { const html = markup(true); expect(html).toContain('aria-label="Expand projects"'); - const labels = ['aria-label="This project’s results"', 'aria-label="Skill library"']; - for (const label of labels) expect(html).toContain(label); - expect(labels.map(label => html.indexOf(label))).toEqual(labels.map(label => html.indexOf(label)).sort((a, b) => a - b)); + expect(html).toContain('aria-label="Skill library"'); expect(html).not.toContain('id="daemon-search"'); }); it.each([false, true])('opens the learning feed from the sidebar entry (compact=%s)', (compact) => { diff --git a/frontend/web/src/test/uxRound3.test.tsx b/frontend/web/src/test/uxRound3.test.tsx index 714538f58..55c79a1c7 100644 --- a/frontend/web/src/test/uxRound3.test.tsx +++ b/frontend/web/src/test/uxRound3.test.tsx @@ -21,7 +21,6 @@ describe('attachments a researcher actually has', () => { describe('sidebar skill entry', () => { it('opens everything the library holds instead of the raw learning feed', async () => { - vi.stubGlobal('localStorage', { getItem: (key: string) => key === 'argus.sidebar.advanced.v1' ? 'open' : null, setItem: vi.fn(), removeItem: vi.fn() }); vi.stubGlobal('window', new EventTarget()); vi.spyOn(api, 'organization').mockResolvedValue({ value: {}, revision: 0 }); const onOpenLearning = vi.fn(); From d82bf4fcbc6d7da587d5d50e9006ad135ae4df19 Mon Sep 17 00:00:00 2001 From: lbx154 <145820328+lbx154@users.noreply.github.com> Date: Tue, 3 Nov 2026 06:23:38 -0800 Subject: [PATCH 3/6] =?UTF-8?q?=E9=A1=B6=E9=83=A8=E6=A0=87=E9=A2=98?= =?UTF-8?q?=E5=8C=BA=E7=95=99=E7=99=BD=E3=80=81=E5=9B=9E=E5=A4=8D=E6=AD=A3?= =?UTF-8?q?=E6=96=87=E5=B1=82=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 顶部更高(72px),标题 20px,状态行与标签间距加大;标签选中线 2px 黑 - 右上角和侧栏底部的 ··· 改为图标,不再靠字间距拼点 - 回复里的标题 22/18/15px 半粗,段落行高 1.75,列表圆点改灰 Co-Authored-By: Claude Opus 5.5 --- frontend/web/src/App.tsx | 2 +- frontend/web/src/components/MarkdownContent.tsx | 8 ++++---- frontend/web/src/components/Sidebar.tsx | 2 +- frontend/web/src/components/TopBar.tsx | 7 ++++--- frontend/web/src/index.css | 13 +++++++------ 5 files changed, 17 insertions(+), 15 deletions(-) diff --git a/frontend/web/src/App.tsx b/frontend/web/src/App.tsx index 608fcdd4e..6e8273d19 100644 --- a/frontend/web/src/App.tsx +++ b/frontend/web/src/App.tsx @@ -922,7 +922,7 @@ export default function App() { snapshotStale={snapQ.isError} readOnly={kiosk} /> : -
+
{shownName(projects.find(project => project.id === activeSid) ?? {}, locale === 'zh-CN', t('sidebar.unnamedSession'))}
} diff --git a/frontend/web/src/components/MarkdownContent.tsx b/frontend/web/src/components/MarkdownContent.tsx index b234d3f1b..fa99a97ef 100644 --- a/frontend/web/src/components/MarkdownContent.tsx +++ b/frontend/web/src/components/MarkdownContent.tsx @@ -154,10 +154,10 @@ export function MarkdownContent({ live.current = { artifacts, onOpenArtifact, basePath, sid, delivery, locale, t }; const rehypePlugins = useMemo(() => markdownRehypePlugins(locale === 'zh-CN'), [locale]); const components = useMemo((): Components => ({ - h1: ({ children: value }) =>

{value}

, - h2: ({ children: value }) =>

{value}

, - h3: ({ children: value }) =>

{value}

, - p: ({ children: value }) =>

{value}

, + h1: ({ children: value }) =>

{value}

, + h2: ({ children: value }) =>

{value}

, + h3: ({ children: value }) =>

{value}

, + p: ({ children: value }) =>

{value}

, ul: ({ children: value }) =>
    {value}
, ol: ({ children: value }) =>
    {value}
, li: ({ children: value }) =>
  • {value}
  • , diff --git a/frontend/web/src/components/Sidebar.tsx b/frontend/web/src/components/Sidebar.tsx index e92921af2..fb90a3164 100644 --- a/frontend/web/src/components/Sidebar.tsx +++ b/frontend/web/src/components/Sidebar.tsx @@ -441,7 +441,7 @@ export function Sidebar({ }
    - +
    {onSignOut && } diff --git a/frontend/web/src/components/TopBar.tsx b/frontend/web/src/components/TopBar.tsx index 27f533835..3093168ce 100644 --- a/frontend/web/src/components/TopBar.tsx +++ b/frontend/web/src/components/TopBar.tsx @@ -1,3 +1,4 @@ +import { MoreHorizontal } from 'lucide-react'; import { WorkspaceHeader } from './WorkspaceShell'; import { SessionWorkdir } from './SessionWorkdir'; import type { Snapshot } from '../api'; @@ -75,7 +76,7 @@ export function TopBar({ return ( -

    +

    {title}

    @@ -130,9 +131,9 @@ export function TopBar({ aria-label={t('topbar.manageSession')} title={t('topbar.manageSession')} onClick={onManage} - className="icon-control flex h-8 w-8 shrink-0 items-center justify-center text-base leading-none tracking-[0.12em] text-ink-dim" + className="icon-control flex h-8 w-8 shrink-0 items-center justify-center text-ink-dim" > - ··· +