Shift existing dark palette tokens up one tier for less harsh contrast while keeping the same color system; sync settings preview swatches and accent-on colors.
1. Removed the two floating arrow buttons (.sb-toggle / .rp-toggle) that
used to sit at the side seams between sidebar/main/rightpanel.
2. Each page section now owns its own .page-top bar with:
- left: .pt-sb-toggle (caretLeft, borderless icon button) — collapses
left sidebar; svg rotates 180° when sidebar is collapsed.
- right: .pt-rp-toggle (caretRight) — same logic for right panel.
- chat/collab keep run-state centered between the two icons.
- services/token use a .pt-spacer to fill the middle gap.
3. .pt-icon style is borderless / transparent / opacity-0.7 (no boxy
bordered button look); page-top padding tightened to 4px so the
carets hug the screen edges. Bump styles.css?v=95→97.
4. Wiring: app.js queries .pt-sb-toggle/.pt-rp-toggle by class (4 of
each, one per page) and binds them to the existing
.body.classList.toggle('sb-collapsed') / .toggle('rp-collapsed')
handlers. Behavior identical to the old single buttons.
5. Dropped the DEV annotation scaffold: removed annot.css link in head,
annot.js script at end of body, and deleted both files.
1. Sidebar nav: move 后台服务 (services) to AFTER 指挥家 (collab).
New order: 聊天 → 指挥家 → 后台服务 → Token 统计.
2. Token trend chart: was flat (container 160px tall, viewBox 600×140).
Now container 280px + max-width 760px to stop it stretching on wide
screens; viewBox bumped to 600×260 with a bit more padding so text
does not get distorted under preserveAspectRatio="none".
3. Token stats tabs (聊天 / Conductor) reuse the .svc-tabs underline
look from the services page — same visual language. CSS-only;
.tok-tabs/.tok-tab classes and the JS click handler are unchanged.
4. Bump app.js?v=81→82 (app.js really changed this time, and the bump
also flushes stale i18n cache for previously-untranslated keys).
Resolved one conflict in app.js: kept the new token trend chart code from
main and adopted PR's services-tab nav handler (replaces the old
channels/status separate handlers, which the PR consolidates anyway).
index.html and styles.css auto-merged cleanly.
Closesdd3xp/GenericAgent_Desktop#7
Pure SVG line chart showing daily spending (¥) over time. Respects
date filter, fills zero-cost gaps, uses local timezone for grouping.
Hidden on Conductor tab.
- Two tabs: 聊天 (chat sessions) and Conductor (cumulative/current)
- Conductor tab hides date filter and stat-row summary
- Remove green background and expand triangle from conductor rows
- Bump app.js and styles.css cache versions
- conductor.py: install cost_tracker + expose /token-stats endpoint (5 lines)
- app.js: fetch conductor token totals and display as a single summary row at top of token table (not expandable, with tooltip noting it's excluded from cumulative totals)
- styles.css: conductor row styling
UI restructure (frontend static):
- PLAN moved from sticky toggle chip to a preset card (BUILTIN_PRESETS) that
one-shot-sends `presetPrompt.plan`, now pointing at the real
memory/plan_sop.md (Auto was considered too but dropped — it semantically
overlaps with the existing "自主探索" preset). All plan/auto toggle
plumbing removed: state, chip listeners, applyToggleClass, ga_plan/ga_auto
localStorage, planPrefix/autoPrefix injection.
- Chat composer: model chip moved out of the joined .cb-left pill group to
sit next to the send button (composer-bot is now right-aligned model+send).
- Conductor composer: gained its own #collab-model-chip + #collab-model-menu;
openModelMenu/renderModelMenu/updateModelChip refactored to be ctx-aware
(both chips share the model list; each pops its menu into its own
composer; updateModelChip syncs both names).
- Topbar dissolved into per-page headers: the global .topbar was removed
from <main>; the run-state moved into a .page-top inside the chat page,
so the "topbar" now switches with the page instead of persisting.
- Removed the conductor "{n} 个任务进行中" sticky banner (#collab-sticky);
the same info is already in the progress panel and the sidebar badge.
Conductor persistence (conductor.py + frontend wiring):
- conductor.py: add_chat() carries files/images on each chat item; WS
receive passes data.files/data.images through; hello includes a
running flag (any subagent with status="running"). 5 net edits.
- app.js: ws.send now posts {msg, files, images} (was msg only); onWsData
hello/chat branches map files/images and set S.conductorTyping from
data.running so attachments + run animation survive a page refresh.
Session naming (mirror TUI continue_cmd._preview_text):
- New helper displayTitle(sess): if user manually renamed, use sess.title;
otherwise scan messages — prefer the last <summary>…</summary> in any
assistant reply, fall back to the first user message text (≤40 chars,
attachment placeholders stripped), final fallback t('conv.defaultTitle').
- newSession() now defaults sess.title to '' instead of '新对话'; the
earlier "first message → title" auto-rename block in submitInput is
gone — titles only get written when the user renames explicitly.
- isAutoTitle() recognises '新对话'/'New chat'/'agent-N' as placeholder so
legacy sessions and the brief agent-N experiment get re-derived live
in the sidebar without losing user renames.
- Sidebar render + search filter now go through displayTitle.
Note: requires a one-time restart of conductor.py for its part to take
effect; the static frontend changes are just a refresh.
- Replace SVG icon with ⧉ character (same as code block)
- Match font-size, padding, border-radius, background
- Remove border and flex layout, use simple text button
- Both buttons now visually identical (~16.5x14.7px)
Re-skin the desktop frontend in ethan su's "rectilinear workspace" visual
language (PR#3) without dropping any feature, plus two UX fixes. Done as a
content-overlay, NOT a git merge of PR#3 — PR#3's app.js reverts ask_user /
conductor / composer / timing, so only its visual layer is adopted.
Design (PR#3):
- Bundle brand fonts (Azonix wordmark / Lexend / Noto Sans / JetBrains Mono)
+ phosphor-icons.js (auto-hydrates [data-ga-icon]).
- styles.css: adopt ethan's full design-token system (accent #1f6f53,
--radius 4px/2px squared corners, brand fonts) via 3-way merge; keep all
feature CSS (composer chips, ask_user notice, conductor, flatpickr, timing
badge); normalize leftover --blue -> --accent.
- index.html: ethan's phosphor chrome; keep contenteditable composers, the
real conductor UI, flatpickr links, and collab-badge.
- app.js: add GA_ICON() helper; swap dynamic chrome icons (pin, more, model
edit/delete, add-preset, channel, ctx-delete, drawer-close) to Phosphor.
Flags, copy/check, file-chip and preset-card icons left inline by design.
Fixes:
- PLAN/AUTO toggles now show an unmistakable on-state (solid accent fill);
the .cb-left .chip.sm rule was overriding .chip.on by specificity, so the
on/off difference was nearly invisible.
- On refresh, restore the session you were actually viewing (persist
ga_active) instead of the bridge's roaming most-recently-updated session;
show the empty new-session state when none is selected.
Unify the single-question and multi-question ask_user rendering instead of
having two divergent paths:
- Single-question options (from `candidates`) are now folded into the question
body as inline A./B./C. lines via foldAskCandidates(), rendered exactly like
multi-question inline options (.ask-option-line). The separate numbered <ul>
candidate list is gone, which also removes the "1. A." double-numbering.
- Fold with a single newline so question + options render as one <p>; every
option (including the first) follows a <br>, so all get consistent indent.
- Placeholder is unified to the free-form ask.placeholderOpen for both; the
per-single-question "type 1/2/3 to pick" placeholder is removed.
- Drop now-dead code: ask.placeholderOpts i18n (zh+en) and the
.ask-candidates / .ask-candidate-key / .ask-candidate-label CSS.
- Resolve styles.css: keep session-rename's .ci-rename-input + my .ci-pin, both on --accent.
- Adapt ask_user dynamic placeholder: inputEl.setAttribute('placeholder',...) ->
'data-ph' so it shows on the contenteditable composer (no placeholder attr on a div).
- session-rename uses its own rename <input> (.value) — untouched, no composer conflict.
- Bump asset cache-bust (styles.css v74 / app.js v45).
WIP checkpoint: both composers (chat + collab) to contenteditable+atomic chips on top
of lyx/017's ctx multi-composer; conductor send uses gaComposerText('collab'); --blue
-> --accent; flatpickr (PR#2). Re-merging latest main next.
- Rename the misleadingly-named --blue theme accent var to --accent (incl.
--blue-bg/-soft -> --accent-bg/-soft) across styles.css + the applyTheme
setter in app.js. Keep --blue* as back-compat aliases of --accent* so
unmerged branches (e.g. PR#1) still render until they migrate.
- Sidebar / right-panel toggles: plain icon button when expanded (no bg/border);
restore the edge-tab look (bg + border) only when collapsed.
- Bump asset cache-bust (styles.css v23 / app.js v30).
Replace the card/button wizard with a lightweight notice block: users reply in the main composer with dynamic placeholders. Add formatAskUserQuestion to merge numbered lines and break between questions only. Update tool schemas to guide multi-question Markdown in question and single-question candidates. Hide redundant candidates lists by default (preview flag on).
Replace the plain <textarea> composer with a contenteditable div so attachment
placeholders render as atomic, non-editable chips (QQ @-mention style): the caret
can't enter them and Backspace deletes the whole chip + its file. Stays a plain-text
box otherwise — no rich formatting, paste is forced to plain text.
- index.html: <textarea class="input"> -> <div class="input" contenteditable>.
- composerText() serializes content back to plain text (chips -> [Image #N]/[File #N],
<br>/<div> -> newline) so all downstream send/expand/collect logic is unchanged.
- insert/remove placeholder now create/remove <span.ph-chip contenteditable=false>
nodes; reconcile compares pendingFiles against chips present in the DOM.
- Drop the textarea-only atomicPlaceholderDelete (contenteditable=false is native).
- Enter-to-send + IME guard kept; paste forced to plain text (+ image/file paste).
- setComposerLocked toggles contentEditable (readOnly is a no-op on a div).
- i18n placeholder hint via :empty::before + data-ph; .ph-chip pill styling.
- Add !important to all Flatpickr CSS overrides to beat CDN specificity
- Change dateFormat from ISO 'Y-m-d\TH:i' to 'Y-m-d H:i' (double space)
- Update tokGetFiltered to use .replace(/\s+/,'T') for Safari compat
- Add Flatpickr CDN (CSS + JS + zh locale) to index.html
- Change input type to text with .tok-date class
- Add Flatpickr theme override using CSS variables (light + dark)
- Initialize Flatpickr instances with ISO dateFormat for Safari compat
- Update reset button to use fp.clear() API
Replace single question/candidates params with a required questions array
({question, options?}, 1–5 items) in ga.py and tool schemas. Add desktop
wizard rendering with per-question options, inline custom input, and
batch submit after all answers.
Replace hardcoded max-width (760px/560px) with CSS variable
--chat-max-w: clamp(600px, 75%, 1000px) so the chat area
scales naturally on wider displays.
- Remove colored borders and backgrounds from fold components
- Use 2px left border line for visual hierarchy
- Keep subtle color coding (blue=tool, green=result, gold=thinking)
- Fix .bubble.md pre specificity override for fold pre elements