Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
53 changes: 2 additions & 51 deletions frontend/web/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions frontend/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@
"dependencies": {
"@fontsource-variable/geist": "^5.2.9",
"@fontsource-variable/geist-mono": "^5.2.8",
"@fortawesome/fontawesome-svg-core": "^7.3.0",
"@fortawesome/free-solid-svg-icons": "^7.3.0",
"@fortawesome/react-fontawesome": "^3.4.0",
"@tanstack/react-query": "^5.59.0",
"@xyflow/react": "12.11.1",
"katex": "^0.18.5",
Expand Down
14 changes: 2 additions & 12 deletions frontend/web/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -818,7 +818,7 @@ export default function App() {
const proj: PaletteItem[] = projects.map((p) => ({
id: `p-${p.id}`,
label: shownName(p, locale === 'zh-CN', t('sidebar.unnamedSession')),
hint: p.daemon_alive ? `● ${t('common.live')}` : '○',
hint: p.daemon_alive ? t('common.live') : undefined,
keywords: `${p.id} ${p.display_name ?? ''} ${p.daemon_alive ? 'live running' : 'stopped idle'}`,
group: t('palette.project'),
run: () => selectProject(p.id),
Expand Down Expand Up @@ -883,16 +883,6 @@ export default function App() {
onManage={requestManageSession}
onOpenPanel={(panel) => setOverlay(panel)}
onOpenLearning={openLearningLibrary}
onOpenResults={() => {
const selection = defaultDeliverySelection(deliveryHistory);
if (selection) openDelivery(selection.receipt, selection.path);
else {
setPreviewPathRequest(current => ({ path: FILES_PATH, token: current.token + 1 }));
openPreview();
}
setSidebarOpen(false);
}}
resultsCount={deliveryCount}
onNew={() => { startNewSession(); setSidebarOpen(false); }}
onSearch={() => setSearchOpen(true)}
// The trial portal owns sign-in; a token kept here is this browser's own.
Expand Down Expand Up @@ -932,7 +922,7 @@ export default function App() {
snapshotStale={snapQ.isError}
readOnly={kiosk}
/> : <WorkspaceHeader className="project-header">
<div className="topbar-title min-w-0 truncate font-serif text-[19px] font-medium leading-6 text-ink">
<div className="topbar-title min-w-0 truncate text-[20px] font-semibold leading-7 text-ink">
{shownName(projects.find(project => project.id === activeSid) ?? {}, locale === 'zh-CN', t('sidebar.unnamedSession'))}
</div>
</WorkspaceHeader>}
Expand Down
2 changes: 1 addition & 1 deletion frontend/web/src/components/ArtifactModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ export function ArtifactModal({
{/* On a phone the file's tools wrap onto their own rows under its name. */}
<div className={`flex shrink-0 flex-wrap items-start gap-2 border-b border-line px-4 py-3 sm:px-5 ${!path ? "hidden" : ""}`}>
<div className="min-w-0 flex-1">
<h2 className="truncate text-sm font-semibold text-ink font-mono" title={info?.path ?? path ?? ''}>
<h2 className="truncate text-[15px] font-semibold tracking-[-0.01em] text-ink" title={info?.path ?? path ?? ''}>
{info?.name ?? path ?? t('artifact.title')}
</h2>
<p className="mt-0.5 truncate text-[11px] text-ink-faint">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export function BrowserNotificationSettings({ notifications }: {
<button type="button" role="switch" aria-checked={enabled} aria-labelledby="browser-notifications-label"
aria-describedby="browser-notifications-detail" disabled={unavailable || requesting}
onClick={() => void change()}
className="shrink-0 rounded-lg border border-line px-3 py-2 text-sm text-ink disabled:opacity-40">
className="shrink-0 rounded-full border border-line px-4 py-2 text-sm text-ink disabled:opacity-40">
{requesting ? (zh ? '正在请求权限…' : 'Requesting permission…') : enabled ? (zh ? '已开启' : 'On') : (zh ? '已关闭' : 'Off')}
</button>
</section>;
Expand Down
2 changes: 1 addition & 1 deletion frontend/web/src/components/ChiefNeeds.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export function ChiefNeeds({ zh, onStart }: {
};
return (
<section className="chief-needs mx-auto max-w-2xl px-5 pb-8 pt-[8vh]">
<h2 className="font-serif text-[28px] font-medium leading-tight tracking-[-0.01em] text-ink">{zh ? '你的总负责人' : 'Your chief'}</h2>
<h2 className="text-[32px] font-bold leading-tight tracking-[-0.03em] text-ink">{zh ? '你的总负责人' : 'Your chief'}</h2>
<p className="mt-2 text-sm leading-6 text-ink-faint">{zh
? '它照看你所有的项目,盯着你关心的方向,有值得说的会主动来找你。勾选你需要的就行。'
: 'It looks after all your projects, follows your directions, and comes to you when something is worth it. Tick what you need.'}</p>
Expand Down
8 changes: 4 additions & 4 deletions frontend/web/src/components/CommandPalette.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export function CommandPalette({
aria-autocomplete="list"
aria-controls="command-palette-results"
aria-activedescendant={filtered[sel] ? `palette-${filtered[sel].id}` : undefined}
className="w-full bg-transparent font-mono text-sm text-ink outline-none placeholder:text-ink-faint"
className="w-full bg-transparent text-[15px] text-ink outline-none placeholder:text-ink-faint"
/>
</div>
<div id="command-palette-results" role="listbox" className="max-h-[52vh] overflow-y-auto scroll-thin py-1.5">
Expand All @@ -112,7 +112,7 @@ export function CommandPalette({
)}
{groups.map((g) => (
<div key={g.name} className="mb-1">
<div className="px-4 py-1 text-[10px] font-semibold uppercase tracking-wider text-ink-faint">
<div className="px-5 pb-1 pt-2 text-[11px] text-ink-faint">
{g.name}
</div>
{g.items.map((it) => {
Expand All @@ -127,8 +127,8 @@ export function CommandPalette({
aria-selected={active}
onMouseEnter={() => setSel(filtered.indexOf(it))}
onClick={() => choose(it)}
className={`flex w-full items-center justify-between px-4 py-1.5 text-left text-sm transition-colors ${
active ? 'bg-blue-deep/20 text-ink' : 'text-ink-dim hover:bg-panel/60'
className={`mx-2 flex w-[calc(100%-1rem)] items-center justify-between rounded-lg px-3 py-2 text-left text-sm transition-colors ${
active ? 'bg-sunken text-ink' : 'text-ink-dim'
}`}
>
<span className="min-w-0 truncate">{it.label}</span>
Expand Down
4 changes: 2 additions & 2 deletions frontend/web/src/components/CredentialsSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export function CredentialsSettings() {
catch (reason) { setError(requestFailureText(reason, t).text); }
finally { setBusy(false); }
};
const fieldClass = 'mt-1 w-full min-w-0 rounded border border-line bg-bg px-3 py-2 text-sm text-ink outline-none focus:border-blue';
const fieldClass = 'mt-2 w-full min-w-0 rounded-xl border border-line bg-bg px-3 py-2 text-sm text-ink outline-none focus:border-ink-faint';
return <section className="settings-section">
<h3 className="text-sm font-semibold text-ink">{zh ? '传给角色的环境变量' : 'Environment for roles'}</h3>
<p className="my-2 text-xs leading-5 text-ink-faint">{zh
Expand All @@ -51,7 +51,7 @@ export function CredentialsSettings() {
<textarea name="credential-value" rows={2} autoComplete="off" spellCheck={false} value={value}
onChange={event => { setValue(event.target.value); setSaved(false); }} className={fieldClass} />
</label>
<button type="submit" disabled={busy} className="rounded border border-blue/35 px-3 py-2 text-xs text-blue disabled:opacity-40">{zh ? '保存变量' : 'Save variable'}</button>
<button type="submit" disabled={busy} className="rounded-full bg-ink px-4 py-2 text-xs font-medium text-on-accent disabled:opacity-40">{zh ? '保存变量' : 'Save variable'}</button>
</form>
{saved && <p role="status" className="mt-2 text-xs text-ink-dim">{zh ? '已保存' : 'Saved'}</p>}
{error && <p role="alert" className="mt-2 text-xs text-err">{error}</p>}
Expand Down
13 changes: 2 additions & 11 deletions frontend/web/src/components/EventStream.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -622,15 +622,6 @@ export function latestConversationDelivery(
return undefined;
}

function fileGlyph(path: string): string {
const ext = path.split('.').pop()?.toLowerCase() ?? '';
if (['csv', 'tsv', 'xlsx', 'xls', 'parquet'].includes(ext)) return '▦';
if (modelFormat(path)) return '◇';
if (ext === 'pdf') return '◧';
if (['py', 'ts', 'tsx', 'js', 'sh', 'r', 'ipynb', 'json', 'yaml', 'yml'].includes(ext)) return '‹›';
return '▤';
}

/**
* A delivered result in the conversation, shown as itself: a picture shows the
* picture, files show as files. "Open" leads to the result; the process behind
Expand Down Expand Up @@ -683,7 +674,7 @@ function DeliveryCard({
<p className="text-xs text-ink-faint">{deliveryTimeLabel(delivery, zh)}</p>
{listed.length ? <ul className="result-card-files">
{listed.map(file => <li key={file.path} title={file.path}>
<span aria-hidden="true">{fileGlyph(file.path)}</span>{file.label || file.path.split('/').pop()}
{file.label || file.path.split('/').pop()}
</li>)}
{others.length > listed.length ? <li className="text-ink-faint">{zh ? `另有 ${others.length - listed.length} 个文件` : `${others.length - listed.length} more files`}</li> : null}
</ul> : null}
Expand Down Expand Up @@ -1038,7 +1029,7 @@ export function EventStream({
{hasOlder && <button type="button" disabled={loadingOlder} onClick={onLoadOlder} className="block w-full py-2 text-xs text-ink-faint">{locale === 'zh-CN' ? loadingOlder ? '正在加载…' : '更早的对话' : loadingOlder ? 'Loading…' : 'Earlier conversation'}</button>}
{deferredEvents.length === 0 ? (
historyStatus === 'ready' ? emptyState ?? (onCompose ? <div className="mx-auto max-w-2xl px-5 pb-8 pt-[12vh]">
<h2 className="font-serif text-[28px] font-medium leading-tight tracking-[-0.01em] text-ink">{locale === 'zh-CN' ? '从你想完成的事开始' : 'Start with what you want to accomplish'}</h2>
<h2 className="text-[32px] font-bold leading-tight tracking-[-0.03em] text-ink">{locale === 'zh-CN' ? '从你想完成的事开始' : 'Start with what you want to accomplish'}</h2>
<p className="mt-2 text-sm leading-6 text-ink-faint">{locale === 'zh-CN' ? '直接说出目标,也可以选择下面的场景,再补充你的材料和要求。' : 'Describe your goal, or choose a starting point and add your material and requirements.'}</p>
<StartPrompts onPick={onCompose} />
<p className="mt-6 text-xs text-ink-faint">{locale === 'zh-CN' ? '或者直接试一个实际跑过的任务' : 'Or try a task that was run end to end'}</p>
Expand Down
8 changes: 2 additions & 6 deletions frontend/web/src/components/Landing.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faBars } from '@fortawesome/free-solid-svg-icons';
import { Menu } from 'lucide-react';
import { BackendHandshake } from './BackendHandshake';
import { Button } from './primitives';
import { useI18n } from '../i18n';
Expand Down Expand Up @@ -55,7 +54,7 @@ export function Landing({
<div className="landing-page" style={creating ? { display: 'none' } : undefined}>
<div className="landing-navigation lg:hidden">
{/* The project list opens from the same mark as on a project's page. */}
<Button onClick={onChoose} aria-label={t('topbar.openSessions')} title={t('topbar.openSessions')}><FontAwesomeIcon icon={faBars} className="h-4 w-4" /></Button>
<Button onClick={onChoose} aria-label={t('topbar.openSessions')} title={t('topbar.openSessions')}><Menu size={18} aria-hidden="true" /></Button>
</div>
{loading ? <BackendHandshake /> : (
<>
Expand All @@ -80,9 +79,6 @@ export function Landing({
return accepted;
}} disabled={creating} pending={false} focusSignal={focusSignal}
completionSelection={completionSelection} onCompletionSelectionChange={setCompletionSelection} />
<p className="landing-caption">{locale === 'zh-CN'
? '发送后自动建立项目;团队干活时也可以随时说话。'
: 'Sending creates a project. You can write at any time while the team works.'}</p>
<label className="landing-workdir">
<span>{locale === 'zh-CN' ? '工作目录' : 'Folder'}</span>
<input value={workdir} onChange={event => { setWorkdir(event.target.value); onWorkdirChange?.(); }} list="landing-workdirs" disabled={creating}
Expand Down
8 changes: 4 additions & 4 deletions frontend/web/src/components/MarkdownContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 }) => <h1 className="mb-2 mt-3 text-base font-semibold text-ink first:mt-0">{value}</h1>,
h2: ({ children: value }) => <h2 className="mb-1.5 mt-3 text-sm font-semibold text-ink first:mt-0">{value}</h2>,
h3: ({ children: value }) => <h3 className="mb-1 mt-2 text-sm font-medium text-ink first:mt-0">{value}</h3>,
p: ({ children: value }) => <p className="my-1.5 whitespace-pre-wrap break-words leading-[1.625] first:mt-0 last:mb-0">{value}</p>,
h1: ({ children: value }) => <h1 className="mb-3 mt-6 text-[22px] font-semibold leading-snug tracking-[-0.02em] text-ink first:mt-0">{value}</h1>,
h2: ({ children: value }) => <h2 className="mb-2 mt-5 text-lg font-semibold leading-snug tracking-[-0.015em] text-ink first:mt-0">{value}</h2>,
h3: ({ children: value }) => <h3 className="mb-1.5 mt-4 text-[15px] font-semibold text-ink first:mt-0">{value}</h3>,
p: ({ children: value }) => <p className="my-2.5 whitespace-pre-wrap break-words leading-[1.75] first:mt-0 last:mb-0">{value}</p>,
ul: ({ children: value }) => <ul className="my-2 list-disc space-y-1 pl-5">{value}</ul>,
ol: ({ children: value }) => <ol className="my-2 list-decimal space-y-1 pl-5">{value}</ol>,
li: ({ children: value }) => <li className="pl-0.5">{value}</li>,
Expand Down
34 changes: 13 additions & 21 deletions frontend/web/src/components/MobileTabBar.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,4 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {
faBars,
faDiagramProject,
faFlask,
faListUl,
faWindowMaximize,
} from '@fortawesome/free-solid-svg-icons';
import type { IconDefinition } from '@fortawesome/fontawesome-svg-core';
import { FlaskConical, Menu, MessageSquare, Network, Package, type LucideIcon } from 'lucide-react';
import { useI18n } from '../i18n';

export type MobileTab = 'sessions' | 'activity' | 'workbench' | 'map' | 'preview';
Expand All @@ -24,11 +16,11 @@ export function MobileTabBar({
sidebarOpen?: boolean;
}) {
const { t, locale } = useI18n();
const tabs: { id: Exclude<MobileTab, 'sessions'>; label: string; icon: IconDefinition }[] = [
{ id: 'activity', label: t('mobile.activity'), icon: faListUl },
{ id: 'preview', label: locale === 'zh-CN' ? '成果与文件' : 'Results & files', icon: faWindowMaximize },
{ id: 'map', label: t('mobile.map'), icon: faDiagramProject },
{ id: 'workbench', label: t('mobile.workbench'), icon: faFlask },
const tabs: { id: Exclude<MobileTab, 'sessions'>; label: string; icon: LucideIcon }[] = [
{ id: 'activity', label: t('mobile.activity'), icon: MessageSquare },
{ id: 'preview', label: locale === 'zh-CN' ? '成果与文件' : 'Results & files', icon: Package },
{ id: 'map', label: t('mobile.map'), icon: Network },
{ id: 'workbench', label: t('mobile.workbench'), icon: FlaskConical },
];

return (
Expand All @@ -42,10 +34,10 @@ export function MobileTabBar({
<button
type="button"
onClick={onOpenSessions}
className="flex min-h-[3.25rem] flex-1 flex-col items-center justify-center gap-0.5 text-ink-faint active:bg-panel-raised"
className="flex min-h-[3.5rem] flex-1 flex-col items-center justify-center gap-1 text-ink-faint active:bg-panel-raised"
>
<FontAwesomeIcon icon={faBars} className="h-4 w-4" />
<span className="text-[10px] leading-none">{t('mobile.sessions')}</span>
<Menu size={20} strokeWidth={1.75} aria-hidden="true" />
<span className="text-[11px] leading-none">{t('mobile.sessions')}</span>
</button>
) : null}
{tabs.map((tab) => {
Expand All @@ -56,12 +48,12 @@ export function MobileTabBar({
type="button"
onClick={() => onSelect(tab.id)}
aria-current={selected ? 'page' : undefined}
className={`flex min-h-[3.25rem] flex-1 flex-col items-center justify-center gap-0.5 active:bg-panel-raised ${
selected ? 'text-blue' : 'text-ink-faint'
className={`flex min-h-[3.5rem] flex-1 flex-col items-center justify-center gap-1 active:bg-panel-raised ${
selected ? 'font-medium text-ink' : 'text-ink-faint'
}`}
>
<FontAwesomeIcon icon={tab.icon} className="h-4 w-4" />
<span className="text-[10px] leading-none">{tab.label}</span>
<tab.icon size={20} strokeWidth={selected ? 2 : 1.75} aria-hidden="true" />
<span className="text-[11px] leading-none">{tab.label}</span>
</button>
);
})}
Expand Down
Loading
Loading