Commit Graph

1218 Commits

Author SHA1 Message Date
Uğur Murat Altıntas 6c811dcef5 fix(i18n): address Turkish locale review feedback
Fix Copilot review issues in the tr locale: Korean string leaks,
placeholder order, stray quotes, broken {provider} tags, duplicate
English voice keys overriding translations, and remaining TODO strings.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-24 17:13:34 +00:00
Uğur Murat Altıntas c77936ff81 feat(i18n): add Turkish (tr) locale support
Add a complete Turkish locale to the WebUI and login page so users can
select Türkçe in Settings, with speech recognition via tr-TR.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-24 17:13:34 +00:00
Rory Ford 7be9a26018 feat: PATCH /api/mcp/servers/{name} — enable/disable toggle
Add `PATCH /api/mcp/servers/{name}` endpoint that accepts `{"enabled": bool}`,
updates `mcp_servers.<name>.enabled` in config.yaml, and calls `reload_config()`.
Mirrors the existing DELETE pattern.

Also wire the previously-defined-but-unrouted `_handle_mcp_server_delete` into
`handle_delete`, and `_handle_mcp_server_update` into a new `handle_put` +
`do_PUT` in server.py — fixing a pre-existing bug where those handlers existed
but were never reachable over HTTP.

UI: add a toggle button in each MCP server row in the system settings panel
(panels.js). Clicking it calls PATCH and reloads the list. Toggle button is
styled with `.mcp-toggle-enabled` / `.mcp-toggle-disabled` CSS classes. The
`toggle_supported` flag in the list response is now `True`.

i18n: add 5 new keys (`mcp_enable_server`, `mcp_disable_server`,
`mcp_enabled_toast`, `mcp_disabled_toast`, `mcp_toggle_failed`) to all 9
non-English locales (English values as placeholder translations).

Tests: add `TestMcpToggle` class with 7 tests covering disable, enable,
404-not-found, empty name, missing field, response payload, and URL-encoded name.
Update `test_empty_config` and visibility panel assertions to reflect
`toggle_supported: True` and the new toggle button in panels.js.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 17:13:32 +00:00
Dustin 029d95ada9 style(composer): address Copilot review on PR #2812
Three small fixes from Copilot's review:

1. static/style.css:1354 - removed spaces inside `clamp(...)` args to
   match the file's existing compact style (no spaces after commas in
   neighboring declarations like `transition:border-color .2s,box-shadow .2s`).

2. CHANGELOG.md - wrapped the long single-line entry across multiple lines
   with standard Markdown continuation indentation for cleaner diffs.

3. CHANGELOG.md - normalized `~1300 px` to `~1300px` for unit-formatting
   consistency.

No behavior change. Same one-line CSS rule, just tightened formatting.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 17:13:30 +00:00
Dustin 2c9fc4cfc0 style(composer): responsive composer-box max-width via clamp()
`.composer-box` had a hardcoded `max-width: 780px` since the early
v0.50.x layout pass. On wide displays (1440p+, 2880px ultrawides)
this leaves significant unused horizontal space AND squeezes the
composer-footer chips (workspace, model, reasoning, context %)
against each other inside the 780px box.

When the context-percentage ring appears (active token usage), the
workspace chip truncates to "Fou..." instead of showing the full
workspace name. Model + reasoning chips also lose room. The chip
strip horizontally-scrolls inside .composer-left, so the rightmost
chips effectively hide behind context %.

The constraint isn't "Reading flow looks better at 780px" — the
textarea is min-height:64px, max-height:200px and wraps naturally,
so users on wide displays get the SAME readable text wrap regardless
of box width. Only the footer chips suffer.

Fix: clamp(780px, 60vw, 1100px). Preserves the 780px floor (no
regression on viewports < 780px since clamp's first arg is the
minimum) while letting wider viewports use up to 1100px (60% of
viewport width, capped). 1100px gives ~40% more horizontal room for
the footer chips without filling the entire screen at extreme widths.

Per-viewport behavior:
  <= 780 px → 780 px (hard floor) — zero change vs current
  1280  px  → 60vw = 768 → floored to 780 — zero change
  1440  px  → 60vw = 864 — +84 px room
  1920  px  → 60vw = 1152 → capped at 1100 — +320 px room
  2880  px  → 60vw = 1728 → capped at 1100 — +320 px room

One line in static/style.css. CHANGELOG entry. No JS. No new deps.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 17:13:30 +00:00
ai-ag2026 a34d5e26c2 fix(chat): settle stream_end without done 2026-05-24 17:10:01 +00:00
AJV20 237bab753a feat: surface live activity timeline (#2847)
Squashed from 2 author commits:
- d2237e23 feat: surface live activity timeline
- eee57ec0 fix: satisfy activity timeline CI guards

Frontend-only telemetry from existing stream events. Replaces empty
Thinking… placeholder with observable run status (Waiting on model /
Waiting on tool result / Working for …). New CSS, new test file.
2026-05-24 16:13:00 +00:00
humayunak 7983e025c4 kanban: full markdown rendering for task description and comments
- Rewrote _kanbanRenderMarkdown() from basic paragraph wrapper to a
  line-by-line block processor supporting headings, code blocks, lists,
  task lists, tables, blockquotes, horizontal rules, and strikethrough.
- Added CSS for all new elements (table borders, code blocks, checkboxes,
  blockquote accent, heading sizing, etc.).
- Dropped white-space: pre-wrap from .kanban-task-preview-body and
  .kanban-detail-row-main since markdown now handles layout.
- Applied _kanbanRenderMarkdown() to task description (was esc()) and
  comment body (was esc()) in the task detail view.
2026-05-24 16:12:34 +00:00
Frank Song 70402f96f1 fix(workspace): fall back for large markdown previews 2026-05-24 15:52:54 +00:00
Frank Song 99c886c199 fix(workspace): open rendered preview links correctly 2026-05-24 15:52:35 +00:00
Frank Song f1586daa3b fix(cron): surface gateway scheduling guidance 2026-05-24 15:52:35 +00:00
AJV20 b6f7412b53 Add option to ignore agent updates 2026-05-24 15:52:34 +00:00
Koraji95-coder 7a3ceacffe fix(composer): stop chip wraps from compressing past their content (#2740)
Squashed from 2 author commits:
- a1017d02 initial fix: flex:0 0 auto on all 5 chip wraps
- bf54ba50 Copilot review fix-up: consolidate into single rule

Closes #2740. CSS-only, no JS changes. Default-width layout unchanged,
only affects narrow-viewport overflow regime via composer-left's existing
overflow-x:auto.
2026-05-24 15:52:26 +00:00
tangerine-fan 9a5973a6b5 feat: echo clarify user choice as visible message in conversation
After the user responds to a clarify prompt, insert a synthetic user
message into the conversation showing their choice. This makes the
clarify interaction visible in the chat history, which was previously
only shown in the transient clarify dialog card.

The message is marked with _clarify_response: true so downstream
consumers can distinguish it from regular user messages if needed.
2026-05-24 15:52:00 +00:00
humayunak 32df5546b4 fix(webui): prevent approval and clarify cards stealing focus from composer textarea
When tool approval or clarification cards appear during streaming,
they unconditionally call focus() on their input elements via setTimeout,
stealing focus from the composer (#msg) if the user is actively typing.
This silently drops keystrokes mid-type.

Add a guard: only move focus to the card if the composer textarea does
not already have focus. The document.activeElement check matches the
pattern already used upstream in other focus-sensitive components.

Fixes: #
2026-05-24 15:52:00 +00:00
tn801534 2e876ea229 fix: kanban worker log URL double query param on non-default boards 2026-05-24 15:52:00 +00:00
Abdul Munim 7999d1c75a feat(workspace): add Open in VS Code action for files and folders (#2735)
Right-click any workspace file, folder, or root now shows
'Open in VS Code' alongside the existing Reveal in File Manager action.

- POST /api/file/open-vscode: resolves path via safe_resolve, finds VS
  Code via shutil.which() with fallbacks for macOS (/usr/local/bin/code,
  app bundle CLI), Linux (/usr/bin/code, /snap/bin/code), and Windows
  (%LOCALAPPDATA% and %PROGRAMFILES% user/system installs). Returns a
  descriptive error if not found rather than a bare OS error.
- Optional vscode block in config.yaml: command (default: code),
  host_path_prefix + container_path_prefix for Docker path mapping.
- i18n: open_in_vscode and open_in_vscode_failed translated in all 10
  locales (it, ja, ru, es, de, zh-CN, zh-TW, pt, ko).
- 26 tests in tests/test_2735_open_in_vscode.py covering source wiring,
  command resolution, i18n completeness, and live endpoint error paths.
2026-05-24 04:26:46 +00:00
b3nw 160cd03c18 fix(chat): reset reasoning accumulator per turn and prefer reasoning_content (closes #2565)
Two confirmed bugs in the thinking/reasoning display:

1. reasoningText was initialized once when the SSE stream opened and never
   reset between turns. On the done event, the last assistant message
   received the union of every turn's reasoning. Now reset at both turn
   boundaries: tool (alongside existing liveReasoningText reset) and
   interim_assistant (the other turn boundary where prior reasoning closes).

2. ui.js renderMessages preferred m.reasoning (which could be corrupted by
   bug 1) over m.reasoning_content (the clean per-turn value from the
   backend). The fallback now reads m.reasoning_content || m.reasoning.

Both fixes are needed: bug 2 alone cannot cover providers that stream
reasoning events without populating reasoning_content on the final API
message.

Updated test_streaming_race_fix.py to scope its reconnect-accumulator
guard to the _wireSSE preamble only, since turn-boundary resets inside
event listeners are intentional and correct.

9 new regression tests in test_issue2565_reasoning_accumulation.py.
2026-05-24 04:08:40 +00:00
b3nw 1f56fad73f fix(chat): flush pending render before segment reset at tool/interim boundaries
Fixes #2713 — live assistant text can truncate at tool-call segment
boundaries during streaming.

Before _resetAssistantSegment() in the tool and interim_assistant SSE
handlers, synchronously flush any pending rAF render work so tokens that
arrived during the 66ms throttle window are written to the DOM before
assistantBody is cleared. Without this flush, the pending _doRender
callback fires after assistantBody is null and skips the write silently,
causing the tail of the pre-tool segment to disappear from the live view.

Implementation:
- Extract _flushPendingSegmentRender() helper (guarded by assistantBody
  && _renderPending) that cancels the pending rAF and synchronously
  writes via smd/renderMd/esc — same cascade as _doRender.
- Call the helper from both the tool and interim_assistant handlers
  before their respective _resetAssistantSegment() calls.
- Normal cases where the rAF has already fired are unaffected (guard
  skips immediately).

Completed transcripts were never affected (renderMessages rebuilds from
the full assistantText accumulator on done).

Adds tests/test_issue2713_streaming_segment_flush.py with 11 static
analysis regression tests pinning the helper shape and call-site
ordering.
2026-05-24 04:08:33 +00:00
ai-ag2026 39242c586c fix: clear stale inflight UI state (closes #2795, squashed from 5 commits)
Cherry-pick of PR #2796 by @ai-ag2026, squashed from 5 author commits onto current master:
- dcee0563 fix: drop stale optimistic sidebar rows
- 3a73400d fix: clear stale busy state before send
- 46c3b902 fix: preserve server idle rows during optimistic merge
- de51d271 fix: let chat start survive pre-start UI errors
- d2f5c906 fix: hide nonfatal pre-start send warnings

Authorship preserved via --author. Code-only squash (no CHANGELOG).
2026-05-24 04:08:25 +00:00
gavinssr 75fdadd477 feat: add Hepburn skin (magenta-rose palette)
Add Hepburn skin with full light/dark palette derived from the
Hepburn TUI theme. Brand color #c6246a with pink-magenta accents.

- Light: soft pink surfaces (#fff3f7 / #fbe4ed)
- Dark: deep aubergine (#110a0f / #1e0f19)
- Accent: #d44a7a (light) / #f278ad (dark)
- Styled: send button, new chat button, tool cards, session indicator

Also fix settings panel skin picker to prioritize localStorage
over server defaults, so newly selected skins reflect correctly
in the dropdown.
2026-05-24 03:03:32 +00:00
Harlan Zhou 21481e85fd fix(ui): recover from stale /session/{id} on boot-time 404 2026-05-24 03:03:31 +00:00
ai-ag2026 1e5f20f56d fix: preserve settled tool cards after stream completion 2026-05-24 03:03:31 +00:00
nesquena-hermes 12becd1f4b fix(chat): rename _inflightStateLimits() to _getInflightStateLimits() to fix v0.51.117 collision
Closes #2771.

v0.51.117 (PR #2766) introduced a top-level function _inflightStateLimits()
in static/ui.js that collided with the window._inflightStateLimits config
object set in static/boot.js. Because top-level function declarations in
classic (non-module) scripts attach to window, boot.js's assignment
overwrote the function reference, and every later _inflightStateLimits()
call threw TypeError. _compactInflightState() runs on every send(), so
no new chat session could be created — v0.51.117 is effectively unusable.

Reported by @jahilldev, with multiple users (@isma3iloiso, @theDanielJLewis,
@JHVenn) confirming the bug or reverting to v0.51.116.

Fix: rename the function to _getInflightStateLimits() — the window-attached
config key stays under its original name (unchanged for any downstream
code that reads it). Updates all 4 call sites in static/ui.js.

Tests:

  - Update tests/test_inflight_storage_quota.py — the existing test
    asserted 'function _inflightStateLimits()' in UI_JS as a positive
    presence check, which certified the bug. Now asserts the renamed
    function name is present AND the old colliding name is absent AND
    no stale call sites remain.
  - Add tests/test_window_function_collision.py — generalized regression
    that scans every static JS file for top-level function declarations
    whose name also appears as the target of 'window.X = {...}' or
    'window.X = <number>'. This is the exact shape that broke #2715
    (_pinnedSessionsLimit in v0.51.106) and #2771. Test fails with a
    precise diagnostic naming the file and symbol if the bug class
    returns. Confirmed test FAILS on current master (unfixed) and PASSES
    on this branch.

Verified end-to-end against the live browser before commit:
  - typeof window._inflightStateLimits === 'object' (config preserved)
  - typeof window._getInflightStateLimits === 'function'
  - _getInflightStateLimits() returns the limits object
  - saveInflightState() persists to localStorage without throwing

Full pytest suite: 6308 passed, 6 skipped, 3 xpassed, 8 subtests passed.
Opus advisor: SHIP.
2026-05-22 23:17:00 +00:00
george-andraws b2477974c5 fix: make in-flight recovery storage quota-safe 2026-05-22 19:49:20 +00:00
lucasrc 35adc3a473 feat: add per-skill enable/disable toggle in Skills panel
Original PR: #2676 by @lucasrc

Adds POST /api/skills/toggle endpoint that flips skills.disabled in
config.yaml, and a UI toggle in the Skills panel that shows all skills
(including disabled ones) with a per-skill on/off control.

- Backend: new endpoint validates skill exists in filesystem before
  toggling. Read-modify-write wrapped in _cfg_lock for thread safety.
  Writes through to platform_disabled.webui when present.
- Frontend: each skill-item now has a toggle switch; disabled skills
  appear muted but still listed (previously they were filtered out).
- i18n: new toggle keys translated across all 9 non-English locales.
- Tests: round-trip test for disabled list normalization + toggle
  endpoint behavior.

Squash-merged from contributor's branch (19 commits + 1 merge commit)
onto current master via the cherry-pick-stale-contributor-prs procedure.
2026-05-22 19:43:00 +00:00
nesquena-hermes 057ae7da53 Polish: chevron icon toggle + fix collapsed-card edge clip
- Replace text 'Collapse'/'Expand' button labels with Lucide chevron SVG
  icons (chevron-down expanded → click to collapse, chevron-up collapsed
  → click to expand). Matches the iconographic design language of the
  rest of the chrome (composer buttons, sidebar controls).
  ARIA label + title attributes carry the same semantics for assistive
  tech, so no accessibility regression vs. the text labels.

- Fix collapsed-card edge clipping at viewport bottom. Original
  .clarify-card { bottom: -24px } was sized for the expanded card
  (300-420px tall); adding a 72px collapsed variant pushed the header
  below the parent's visible region. Override bottom to 8px and reduce
  inner padding for the collapsed state so the entire header sits cleanly
  inside the viewport at both desktop and mobile sizes (verified card
  fits with ~115px margin desktop / ~125px margin mobile).

Per Nathan's 2026-05-22 UX feedback on the screenshot package.
2026-05-22 18:14:48 +00:00
Michael Lam 581da3da2b feat: make clarify prompt collapsible 2026-05-22 17:45:40 +00:00
Frank Song 53f294dc8d Fix composer model picker opening lag 2026-05-22 16:58:55 +00:00
ai-ag2026 ef9fe1dfdb fix(chat): keep model fallback guard before session option repair 2026-05-22 16:50:17 +00:00
ai-ag2026 ebcf0dabb5 fix(chat): keep restored session model visible on hard refresh 2026-05-22 16:50:17 +00:00
ai-ag2026 765e5aa091 fix(chat): hydrate restored session model on boot 2026-05-22 16:50:17 +00:00
ai-ag2026 6bcc9689aa fix(chat): keep new session model authoritative 2026-05-22 16:50:17 +00:00
ai-ag2026 af1ee81f06 fix(chat): resolve session model before activating 2026-05-22 16:50:17 +00:00
nesquena-hermes cab60bcd3b Stage 402: PR #2736 2026-05-22 15:51:12 +00:00
ai-ag2026 dabe7b0ea5 fix(session): keep conversation actions menu clickable 2026-05-22 12:21:10 +02:00
ai-ag2026 77b0ca6e02 fix(chat): preserve session actions after panel resync 2026-05-22 09:25:15 +02:00
ai-ag2026 f81d24ec4c fix(chat): resync sidebar after panel switch 2026-05-22 09:25:15 +02:00
Hermes Agent b14aae4ee5 Stage 400: PR #2717 — fix: surface update check fetch errors instead of failing silently
Co-authored-by: ai-ag2026 <ai-ag2026@users.noreply.github.com>
2026-05-21 22:59:54 +00:00
Hermes Agent d1f09a9e9b Stage 400: PR #2722 — i18n: complete French (fr) locale (+93 missing keys, 88.8% → 96.7% coverage)
Co-authored-by: victorwhale <victorwhale@users.noreply.github.com>
2026-05-21 22:59:51 +00:00
Hermes Agent 80356c3a47 Stage 400: PR #2709 — fix(model): prefer profile default model on fresh boot when localStorage has no persisted pick
Co-authored-by: starship-s <starship-s@users.noreply.github.com>
2026-05-21 22:59:48 +00:00
Hermes Agent cc36711b9f Stage 400: PR #2710 — fix: render streamed math incrementally (no flash when delta completes a KaTeX expression)
Co-authored-by: Michaelyklam <Michaelyklam@users.noreply.github.com>
2026-05-21 22:59:46 +00:00
Hermes Agent 0fae9cbdf1 Stage 400: PR #2723 — fix(chat): dedupe uploaded-file optimistic user turns
Co-authored-by: ai-ag2026 <ai-ag2026@users.noreply.github.com>
2026-05-21 22:59:40 +00:00
Hermes Agent 4f3eb9f7f8 Stage 400: PR #2718 — fix: rename _pinnedSessionsLimit() to _getPinnedSessionsLimit() (follow-up to v0.51.105 #2700, matches sessions.js getter convention)
Co-authored-by: eslicarrillo <eslicarrillo@users.noreply.github.com>
2026-05-21 22:59:37 +00:00
Hermes Agent 905b3eba5e Stage 398: PR #2700 — feat: make pinned session limit configurable (builds on shipped #2614 3-cap)
Co-authored-by: ai-ag2026 <ai-ag2026@users.noreply.github.com>
2026-05-21 17:43:56 +00:00
Hermes Agent 7d3013245a Stage 398: PR #2687 — feat: hide suggestions preference (closes #2679)
Closes #2679

Co-authored-by: Michaelyklam <Michaelyklam@users.noreply.github.com>
2026-05-21 17:43:48 +00:00
Hermes Agent 8e1ac89baa Stage 397: PR #2692 — fix(ui): invalidate transcript cache on same-count content changes
Co-authored-by: ai-ag2026 <ai-ag2026@users.noreply.github.com>
2026-05-21 17:14:37 +00:00
Hermes Agent e2338f696f Stage 397: PR #2688 — fix: resync virtualized sidebar after scroll clamp
Co-authored-by: ai-ag2026 <ai-ag2026@users.noreply.github.com>
2026-05-21 17:14:36 +00:00
Hermes Agent d5dcd60981 Stage 397: PR #2674 — fix: new-chat default model provider sync when model id matches but provider differs
Co-authored-by: AJV20 <AJV20@users.noreply.github.com>
2026-05-21 17:14:34 +00:00
Hermes Agent 3dd2ace4e1 Stage 397: PR #2689 — fix(chat): preserve inflight send state during start race
Co-authored-by: ai-ag2026 <ai-ag2026@users.noreply.github.com>
2026-05-21 17:14:33 +00:00