Commit Graph

142 Commits

Author SHA1 Message Date
m4 e8f09f240e fix(webui): reject malformed JSON body in system config PUT
An unparseable request body was silently converted to null, merged over
defaults, and saved — wiping the admin's config while returning 200.
Throw SystemConfigError on JSON parse failure so the route returns 400
INVALID_REQUEST without touching the saved config file.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-11 09:06:11 +08:00
m4 3ddd953e1b feat(webui): admin + public system config API routes 2026-08-11 08:51:46 +08:00
m4 b75de8b5e6 Revert "feat(webui): pin sidebar collapse button to the resize divider"
This reverts commit adc59ba. The divider-mounted tab broke the header's
visual consistency; the collapse toggle stays in the top header.
2026-08-11 07:22:20 +08:00
m4 adc59ba9a9 feat(webui): pin sidebar collapse button to the resize divider
The collapse control now hangs off the top of the ResizableHandle so it
tracks the divider as the sidebar is resized, instead of sitting in the
header far from the boundary it controls. The header toggle remains for
the collapsed and mobile-overlay states. ResizableHandle now renders
passed children (previously shadowed by the withHandle element).
2026-08-10 23:44:28 +08:00
m4 17271d6ebd style(webui): show title only in thread list rows 2026-08-10 22:44:55 +08:00
m4 39e126beab style(webui): gradient brand mark and larger welcome title 2026-08-10 22:35:23 +08:00
m4 62005109a4 style(webui): pastel-tinted stat cards on welcome screen
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-10 22:32:34 +08:00
m4 e0d38afa0c fix(webui): composer shadow and single cyan focus ring 2026-08-10 21:34:29 +08:00
m4 535d1b4955 fix(webui): deepen light brand to cyan-700 for WCAG AA contrast
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-10 21:00:37 +08:00
m4 c388fa4838 fix(webui): register layered shadows in theme, use ring-ring/20 for focus rings
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-10 21:00:22 +08:00
m4 11aa88d4f9 style(webui): cyan active states in sidebar, premium login card 2026-08-10 20:02:13 +08:00
m4 7b6bac0c53 style(webui): polish composer, user bubble, and tool-call box 2026-08-10 19:58:47 +08:00
m4 50e5871184 style(webui): bright zinc+cyan design tokens and Inter font 2026-08-10 14:13:12 +08:00
m4 10904c13fb fix(webui): prefix zip include paths with ./ to defeat option injection 2026-08-10 12:25:48 +08:00
m4 9984c6bdc4 feat(webui): checkbox multi-select download in workspace tree 2026-08-10 12:14:46 +08:00
m4 1d813c18d6 feat(webui): selective include/exclude download for workspace zips 2026-08-10 12:06:39 +08:00
m4 0e34383aed fix(webui): maximize the DialogContent itself; fixed children are trapped by its translate 2026-08-08 22:53:45 +08:00
m4 cd87138a82 fix(webui): maximize preview to browser window instead of OS fullscreen 2026-08-08 22:48:58 +08:00
m4 bbea13b68a feat(webui): fullscreen toggle for html preview panel 2026-08-08 22:37:24 +08:00
m4 918cf741ac feat(webui): redirect render=1 html to path-embedded token URL 2026-08-08 14:15:34 +08:00
m4 046129197a feat(webui): token-gated render route for sandboxed html preview 2026-08-08 14:05:48 +08:00
m4 0e9334d4cd fix(webui): use Code icon for Source toggle to distinguish from Edit
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-08 12:00:57 +08:00
m4 9a4141b05e feat(webui): preview/source toggle for html files in workspace dialog
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-08 11:46:15 +08:00
m4 666a82ebb0 feat(webui): image zoom/pan and prev-next navigation in file dialog
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-08 11:44:15 +08:00
m4 66781a7012 feat(webui): serve html as text/html with allow-scripts sandbox under render=1
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-08 11:31:21 +08:00
m4 2db00b5157 feat(webui): captcha input on login page after repeated failures
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-08 09:35:44 +08:00
m4 9a1775c17d feat(webui): require math captcha after 3 failed logins per IP
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-08 09:32:52 +08:00
m4 f91b26670b feat(webui): GET /api/auth/captcha issues math captchas
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-08 09:29:29 +08:00
m4 4a652fd67f feat(webui): redirect to /login on any API 401 response
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-08 09:17:06 +08:00
m4 b53d58fa35 fix(webui): preserve remaining session TTL on password change
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-08 08:30:43 +08:00
m4 a7625fc38f feat(webui): remember-me checkbox on the login page
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-08 08:19:23 +08:00
m4 a047129622 feat(webui): rememberMe login flag with 30-day persistent cookie
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-08 08:12:10 +08:00
m4 8a59ec59d8 feat(webui): parameterize session TTL and cookie maxAge
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-08 08:06:51 +08:00
m4 0953e403e5 feat(webui): mount error-log bell in the header
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-31 20:10:09 +08:00
m4 47420514bd feat(webui): error-log bell with unread badge and clear-all
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-31 19:32:57 +08:00
m4 a67f16651d feat(webui): useErrorLogs hook with unread cursor and clear-all
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-31 19:31:59 +08:00
m4 09d9f49e9f feat(webui): record BFF route errors in the acting user's error log
routeErrorResponse gains an optional actor; every route that resolves an
actor now passes it, so API failures survive the toast. Unauthenticated
failures and the error-logs route itself are never logged.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-31 11:01:31 +08:00
m4 dd4b63a0ee feat(webui): report user-visible errors to the per-user error log
Add errorReporter (errorToast = toast.error + fire-and-forget POST to
/api/error-logs) and wire it into the operational error toasts across
chat, threads, tasks, agents, models, files and clipboard. Pure form
validation hints stay on toast.error.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-31 10:46:07 +08:00
m4 a4e47e1b5d style(webui): render the idle status dot as a hollow ring
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-31 10:43:40 +08:00
m4 8d455a08e2 feat(webui): add /api/error-logs GET/POST/DELETE for per-user error logs
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-31 10:25:37 +08:00
m4 cbc343963c feat(webui): show a running indicator on busy threads in the list
Three mechanisms, merged in ThreadList: a 10s heartbeat polling the new
?status=busy filter (out-of-band runs: scheduled tasks, other clients),
a module-level running store fed by useChat's own run lifecycle (zero
latency for this client's runs), and a spinner replacing the status dot
while either source marks the thread busy. The BFF list route now
validates and forwards the status filter, which also unbreaks the
previously ignored status dropdown.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-31 09:57:08 +08:00
m4 bd1ef8abf5 perf(webui): slim the conversation list payload to derived summaries
The list route forwarded each thread's full values.messages to the
browser (~47MB for 20 threads), blocking the main thread on JSON.parse
and making the list appear suddenly after a long wait. The BFF now
derives title/description/pinned/needsUserInput server-side via the
shared conversationSummary module and never sends values or interrupts;
useThreads consumes the slim shape directly.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-31 08:23:39 +08:00
m4 c8e8305107 fix(webui): read usage deployment id from EVOSCIENTIST_USAGE_DEPLOYMENT_ID
Matches the backend split: usage attribution no longer shares
EVOSCIENTIST_DEPLOYMENT_ID with workspace scope partitioning.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-30 22:11:31 +08:00
m4 fbf88fbf8a fix(webui): stop probing the scope registry for unscoped threads in the list
Every conversation-list load fanned out getByThread per visible thread;
legacy threads without a scope each logged a 404 warning and added a
round-trip. A thread whose metadata claims no workspace_scope_id can
never pass the scope assertion, so skip the probe and filter it directly.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-30 11:43:50 +08:00
m4 7c121ce019 feat(webui): thinking timer at the bottom of the message area while a run is active
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-30 11:21:58 +08:00
m4 cfaf704652 feat(webui): segmented default/temperature/top_p sampling picker in the chat bar
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-30 10:41:32 +08:00
m4 a4202e149a feat(webui): mutually-exclusive sampling_override in thread model selection
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-30 10:25:36 +08:00
m4 f83cd431c7 feat(webui): exact-value keyboard input on generation sliders
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-29 08:44:21 +08:00
m4 7b14ab5251 fix(webui): correct reset-affordance tooltip copy
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-29 08:17:23 +08:00
m4 8f1ba6ad6f feat(webui): inline temperature/top_p sliders in the chat bar
Adds a GenerationParamSlider next to the reasoning-effort slider so a
per-thread temperature/top_p override can be set from the chat bar.
Unset sliders rest at the registry-catalog default in a muted style;
dragging commits an override, and clicking the value resets to the
default. Hidden below the sm breakpoint, and disabled while the
thread inherits the registry model.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-29 08:03:10 +08:00