Commit Graph

983 Commits

Author SHA1 Message Date
sanbo 7e289568a2 Keep workspace skills visible when the prompt budget truncates
The skills prompt renderer was re-sorting every discovered skill by name,
which discarded workspace/source precedence at the last mile. Under a large
global skills set, higher-priority workspace skills from directories such as
`.claude/skills` could be pushed past the prompt budget and disappear from the
model-visible skills list even though discovery had found them correctly.

This keeps stable ordering in discovery and preserves registry order during
rendering, then adds a regression test that proves a workspace-priority skill
survives when lower-priority global skills overflow the prompt budget.

Constraint: Session-time skill rendering must preserve cross-tool/workspace precedence
Rejected: Raise the prompt budget cap | would hide the ordering bug and bloat prompts
Rejected: Special-case `.claude/skills` during rendering | precedence belongs to registry order, not path-specific branches
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Do not re-sort rendered skills without re-proving precedence behavior under prompt truncation
Tested: cargo test --all-features; cargo fmt --all -- --check; cargo clippy --all-targets --all-features
Not-tested: Manual TUI interaction beyond automated skills prompt and QA PTY coverage
2026-05-10 00:25:53 -05:00
Hunter Bown 1ab5528727 docs(changelog): credit @reidliu41 for /skills spacing
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 00:25:38 -05:00
reidliu41 edb8bb0754 fix: add spacing between listed skills
Render a blank line between entries in the /skills output so long skill
  descriptions remain easier to scan. Add coverage for multi-skill list spacing.
2026-05-10 00:25:15 -05:00
Hunter Bown 21c3df1533 docs(changelog): credit @reidliu41 for base-URL override propagation
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 00:25:01 -05:00
reidliu41 dcb8cd5926 fix: forward base URL overrides to active providers
Route DEEPSEEK_BASE_URL through the active provider config instead of leaving
  self-hosted providers on their localhost defaults. This makes --base-url work
  for Ollama and vLLM while preserving provider-specific env overrides.
2026-05-10 00:24:22 -05:00
Hunter Bown fd82ef626a docs(changelog): credit @michaeltse321 for WSL2 turn-start fix
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 00:24:09 -05:00
Chun Tse 29be2b18f7 fix(tui): send TurnStarted before snapshot to prevent WSL2 timeout
On WSL2 with Windows drives mounted at /mnt/c, git snapshot operations
can take 30+ seconds due to the slow 9P filesystem bridge. The original
code sent TurnStarted *after* the snapshot, causing the UI's 30-second
dispatch watchdog to fire with 'Turn dispatch timed out; the engine may
have stopped' before the turn ever appeared to start.

This commit sends TurnStarted immediately before the snapshot, so the
UI shows progress while the snapshot runs in the background.
2026-05-10 00:23:44 -05:00
Hunter Bown 9209c3366f docs(changelog): credit @Giggitycountless for .gitignore automation
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 00:23:27 -05:00
Jiahao Ren f9004c2a3f fix: handle missing newline and slash-less variants in gitignore check
- Check for both .deepseek and .deepseek/ to prevent duplicates
- Ensure trailing newline before appending to avoid joining with unterminated line
- Add tests for both edge cases
2026-05-10 00:23:17 -05:00
Jiahao Ren afaaab1433 refactor: fix clippy single_match warning
Use if-let instead of match for single-pattern destructuring in
ensure_deepseek_gitignored(). Addresses clippy::single_match warning.
2026-05-10 00:20:56 -05:00
Jiahao Ren c4ab84e1d8 feat: auto-add .deepseek/ to .gitignore in git repos
When /init runs inside a git repository, automatically append .deepseek/
to .gitignore so that workspace-local state (instructions, snapshots,
pastes) is not accidentally committed.

The helper ensure_deepseek_gitignored() checks for an existing .git
directory, reads the current .gitignore (if any), and appends the entry
only when it is not already present. Non-fatal if the file cannot be
written (e.g. read-only filesystem).

Includes four tests covering creation, append, idempotency, and
non-git-repo skip behaviour.

Fixes #1326
2026-05-10 00:20:56 -05:00
Hunter Bown 2576408484 fix(mcp): stabilize tool ordering for prefix-cache stability (#1319)
Sort discovered tools by name in three places so the prompt prefix
the model sees is deterministic across runs regardless of server
pagination order:

- McpConnection::discover_tools — after all pages collected
- McpPool::all_tools — after iterating connections
- McpPool::to_api_tools — final block sent to the model

Adds a regression test that exercises a 2-page paginated discovery
with reverse-ordered tools and asserts the result is sorted.

Adapts the production sort idea from @hxy91819's PR; the test
infrastructure here uses the existing ScriptedValueTransport rather
than introducing a parallel MockTransport with a different trait
signature.

Co-Authored-By: hxy91819 <hxy91819@gmail.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 00:20:41 -05:00
Hunter Bown 73adb5b41a docs(changelog): credit @douglarek for error-cell markdown fix
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 00:15:39 -05:00
Leo Douglas 2d4b0e3369 fix(ui): render error cells without markdown to preserve env-var underscores
Error messages containing environment variable names like
DEEPSEEK_ALLOW_INSECURE_HTTP were mangled by markdown rendering:
the inline _italic_ parser consumed underscored segments (e.g.
_ALLOW_ → italic ALLOW without underscores), resulting in the
illegible DEEPSEEKALLOWINSECURE_HTTP displayed to the user.

Switch HistoryCell::Error from render_message (which routes through
markdown_render::render_markdown_tagged) to wrap_plain_line, which
renders the message body verbatim while preserving the existing
severity label, bold prefix, and continuation-rail layout.

Closes #1303
2026-05-10 00:14:55 -05:00
Hunter Bown 0d0f563851 docs(changelog): credit @Giggitycountless for /clear+Todos fix
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 00:14:39 -05:00
Jiahao Ren 5436041b6e refactor: extract retry_lock helper for mutex acquisition
Extract the duplicated try_lock retry loop into a generic helper method
retry_lock<T>() that retries up to N times with 1ms pauses. This improves
readability and makes the retry pattern reusable.

Addresses review feedback from gemini-code-assist.
2026-05-10 00:14:28 -05:00
Jiahao Ren 2544896704 fix: /clear now resets the Todos sidebar panel
The /clear command was not reliably clearing the Todos sidebar because
clear_todos() used a single try_lock() attempt. When the engine held
the mutex during tool execution, the lock acquisition failed and todos
persisted across /clear commands.

Replace the non-blocking try_lock with a retry loop (up to 100 attempts,
1ms apart) so /clear waits briefly for the mutex and always clears todos.

Also add a regression test clear_todos_resets_todos_list that seeds todos
and asserts they are empty after /clear.

Fixes #1258
2026-05-10 00:13:38 -05:00
Hunter Bown 7f1b4a9bbc docs(changelog): credit @Oliver-ZPLiu for drag-select + copy-rails fix
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 00:13:19 -05:00
Zhiping 964da97b93 fix(tui): update scrollbar-gutter test for interactive scrollbar (#1163)
Replace the upstream inert-scrollbar test (transcript_scrollbar_gutter_
is_not_draggable) with one that asserts the gutter starts a scrollbar
drag rather than a text selection, matching the intended behaviour
where the visible scrollbar thumb remains interactive.

The other 17 test failures in the CI run are pre-existing Windows/local
environment issues (Python REPL / skills fixture pollution) unrelated
to this change.
2026-05-10 00:12:04 -05:00
Zhiping 540a18146f fix(tui): wire scrollbar-drag entry point; fix clippy warnings (#1163)
- Wire mouse_hits_transcript_scrollbar into the Left-Down handler so the
  scrollbar thumb remains draggable after rebase onto upstream/main.
- Fix clippy::useless_format in memory-overhead test.
2026-05-10 00:12:04 -05:00
Zhiping 36a850561b test(tui): add rail-prefix-widths memory overhead test (#1163)
Simulate a 30-turn complex session (user → thinking → assistant →
tools) and assert the rail_prefix_widths vector stays under 1 MB even
in pathological sessions. The test reports exact memory figures via
eprintln! for diagnostic visibility.
2026-05-10 00:12:04 -05:00
Zhiping 31ce5bd196 fix(tui): generalize rail-prefix detection with structural pattern matching (#1163)
Replace the hardcoded three-glyph TOOL_CARD_RAIL_PREFIXES set (only
covered tool-card rails) with iterative structural detection that
handles all TUI decoration glyphs:

- Iterates through consecutive leading decorative spans so tool headers
  with multiple prefix spans (e.g. "• ▶ run issue") are fully stripped.
- Pattern A: "<glyph>[<glyph>…]<space>" where all non-space chars are
  drawing characters — covers single-glyph (▏, ▶, ⌕) and multi-glyph
  prefixes (⋮⋮).
- Pattern B: "<glyph>" + lone space span — covers assistant/user glyphs
  (●, ▎).
- Covers Box Drawing, Block Elements, Geometric Shapes, and individual
  chars used as TUI decoration (•, …, ·, ⌕, ⋮).

Store rail-prefix widths in TranscriptViewCache so the copy path reads
metadata rather than guessing from glyphs.
2026-05-10 00:12:04 -05:00
Zhiping 25c064e43f fix(tui): drag-select past edge auto-scrolls; copy strips tool-card rail (#1163)
When the user holds the left mouse button and drags past the top or

bottom of the transcript rect, advance the viewport on a fixed cadence

so a long passage can be selected in one drag. Also strip the visual

tool-card left-rail glyph (`╭ │ ╰`) from copied text so it does not

leak into the clipboard.

Auto-scroll:

* New `SelectionAutoscroll` state on `ViewportState` records direction

  and the last in-bounds column while a drag is held outside the rect.

* Armed/disarmed by the existing `Drag(Left)` handler; cleared on

  `Up(Left)`, on a fresh `Down(Left)`, and when the cursor returns

  inside the viewport.

* A new per-loop helper `tick_selection_autoscroll` advances

  `pending_scroll_delta` by ±1 line every 30 ms (~33 lines/sec) and

  extends the selection head to the matching edge row, so the visible

  selection rect stays glued to the cursor edge.

* The main loop's `poll_timeout` is clamped to the next autoscroll

  tick so the loop wakes up on cadence even with no input events.

Copy artifact:

* `line_to_plain_for_copy` returns `(plain_text, rail_prefix_width)`,

  stripping a leading rail glyph span when present.

* `selection_to_text` shifts recorded selection columns left by the

  rail width before slicing so visible selection bounds still match.

Tests:

* `drag_above/below_viewport_arms_autoscroll_*` — verify direction

  and clamped column for vertical-out drags.

* `drag_back_inside_disarms_autoscroll` — re-entering clears state.

* `mouse_up_clears_selection_autoscroll` — release ends autoscroll.

* `tick_selection_autoscroll_advances_pending_scroll_when_due` —

  cadence advances scroll and head; `_respects_cadence` blocks early

  ticks; `_clears_when_drag_ended` self-heals if drag state is lost.

* `line_to_plain_for_copy_*` — rail glyph stripping for top/middle/

  bottom rails plus negative tests for plain spans, OSC-8 wrappers,

  and lines whose plain text legitimately starts with `│`.

* Strengthened `selection_to_text_copies_rendered_transcript_block`

  to assert no `│ ` line-prefix leaks.
2026-05-10 00:12:04 -05:00
Hunter Bown 870bc2ab20 fix(build): also rerun on commits to the current branch
The earlier build-script fix only watched .git/HEAD, which catches
branch switches and detached-HEAD moves but NOT git commit on the
current branch — the commit updates the underlying ref file
(refs/heads/<name> or packed-refs after pack-refs), and HEAD itself
stays unchanged. So the embedded short-SHA in deepseek --version went
stale on the same-branch-commit case the fix was supposed to cover.

Resolve the symbolic ref at build time and watch:
- the loose ref file (refs/heads/<branch>)
- packed-refs (Cargo treats a non-existent rerun-if-changed path as
  always-changed, which covers the loose to packed transition after
  git pack-refs)

Detached HEAD is unchanged: HEAD itself contains a SHA, no symbolic
deref happens, and HEAD-as-watched still triggers on every move.

Adds parse_symbolic_ref + 4 unit tests covering: stripped prefix,
no trailing newline, detached SHA, empty input.

Smoke verified: with the previous fix, an empty commit on the same
branch did not bust the cache. With this commit, it does.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 00:11:51 -05:00
Hunter Bown 263ff4be13 docs(changelog): note mouse-wheel scroll fix for WT users (#1298, #1331)
The Windows Terminal mouse-capture default-on change in #1169 also
restores the v0.8.14 wheel-scrolls-transcript behavior on Windows
Terminal. Before mouse capture, the terminal interpreted wheel events
as input-history navigation keys; with capture on, wheel events come
into the TUI and dispatch to the viewport scroll handler.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 23:02:29 -05:00
Hunter Bown 74760a39d3 fix(mcp): capture stderr from spawned stdio servers
The stdio MCP spawn site discarded server stderr (`Stdio::null`), so a
server that crashed after \`initialize\` left only "Stdio transport
closed" — useless for debugging.

Pipe stderr now and drain it into a bounded ring buffer
(\`StderrTail\`, capped at 64 lines) via a tokio task. When the read
side fails (EOF or IO error), the transport error includes the
captured stderr tail so callers see why the server died.

Adds a unix-only regression test that spawns
\`sh -c 'echo >&2; exit 1'\` and asserts the stderr line propagates
through the recv() error.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 22:53:23 -05:00
Hunter Bown 29e418474e fix(tui): default mouse capture on in Windows Terminal (#1169)
The application's drag-select clamps to the transcript area; selection
that appeared to cross into the right sidebar on Windows was actually
the terminal handling the drag natively because Windows defaulted
`mouse_capture = false`. That default was set to dodge the
mouse-mode-leak failure mode from #878 / #898 on legacy conhost, but
modern Windows Terminal handles mouse mode cleanly.

`default_mouse_capture_enabled` now branches on `WT_SESSION`:
- Set (Windows Terminal): default on, sidebar isolation works.
- Unset (legacy conhost / older Windows hosts): default off, same as
  before — explicit `--mouse-capture` or `[tui] mouse_capture = true`
  still opts in.

Adds two regression tests on the Windows path covering both branches.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 22:49:43 -05:00
Hunter Bown 252bf6498c test(tui): broaden code-block rail regression coverage (#1212)
Adds three additional cases to the rail-on-code-block guard:
- multi-line SQL fence after an intro paragraph (issue #1212 repro)
- fenced block with an embedded blank line (different wrap branch)
- a single source line long enough to wrap inside the fence

The existing fix in caf77949d already covers these, but the original
test only asserted on a 2-line fence with no wrap. The wider coverage
locks the current behavior so a future markdown-render rewrite can't
silently regress the visible \`▏\` rail back into code output.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 22:43:34 -05:00
Hunter Bown 3bea6b74fc docs(changelog): note bundled polish items in v0.8.26
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 22:38:30 -05:00
Hunter Bown 44fa06620d fix(test): make CHANGELOG-aware gate robust to packaged-crate runs
`changelog_entry_exists_for_current_package_version` reached for
`CARGO_MANIFEST_DIR/../../CHANGELOG.md`, which assumes a workspace
checkout. Running the test from a packaged crate (no parent workspace)
panicked instead of skipping.

Walk up from `CARGO_MANIFEST_DIR` looking for `CHANGELOG.md`. Inside
the workspace it still finds the top-level file; outside the workspace
the gate quietly skips with a printed note instead of panicking.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 22:37:51 -05:00
Hunter Bown d32cbd0b0e fix(build): rerun build script when .git/HEAD moves
`build.rs` only declared `rerun-if-env-changed` for `DEEPSEEK_BUILD_SHA`
and `GITHUB_SHA`. With no `rerun-if-changed` directives, Cargo cached
the build-script output across commits and the embedded short-SHA in
`DEEPSEEK_BUILD_VERSION` (visible in `--version`) went stale until the
next `cargo clean`.

Add a `cargo:rerun-if-changed=<workspace>/.git/HEAD` directive in both
the `cli` and `tui` build scripts. Handle both layouts: a regular
checkout (`.git` is a directory) and a worktree (`.git` is a pointer
file containing `gitdir: <path>`), so the SHA stays current in either
case.

Verified: touching `.git/HEAD` now triggers a recompile of the affected
crate; `--version` reflects the current commit on the next build.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 22:37:51 -05:00
Hunter Bown b92d3569fd chore(release): prepare v0.8.26 — security hotfix
Two responsibly-disclosed security fixes:
- GHSA-88gh-2526-gfrr (@JafarAkhondali)
- GHSA-72w5-pf8h-xfp4 (@47Cid)

Plus version bump, CHANGELOG, regression tests for both.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 22:30:16 -05:00
Hunter Bown 506343f44e Merge pull request #1325 from Hmbown/work/v0.8.25
chore(release): prepare v0.8.25
2026-05-09 21:04:05 -05:00
Hunter Bown bf582cb0f9 chore(release): prepare v0.8.25
- Bump workspace to 0.8.25 (per-crate path-dep pins, Cargo.lock,
  npm/deepseek-tui/package.json all in sync; check-versions.sh green).
- Add v0.8.25 CHANGELOG entry covering markdown table wrap,
  reqwest-based self-update with SHA-256 verification, MCP framing
  centralization, terminal-mode recovery unification, recall_archive
  parent-registry exposure, ContextConfig.per_model removal, plus
  community PRs (#1300 Reid Liu, #1297 Duducoco, #1265 jinpengxuan,
  #1290 Reid Liu, #1246 heloanc, #1282 Wenjunyun123, #1274 Liu-Vince).
- Refresh README.md and README.zh-CN.md "What's New" sections.
- Prune stale docs: V0_7_5_IMPLEMENTATION_PLAN redirect stub,
  v0.8.8-coordinator-prompt, archived v0.8.10 handoff.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 20:50:06 -05:00
Hunter Bown 25f070919c test(tui): gate ANSI-byte recover_terminal_modes asserts to non-windows
Crossterm routes the same logical commands through the WinAPI console
backend on Windows, so EnableFocusChange / Push keyboard flags /
EnableMouseCapture / EnableBracketedPaste never reach the writer as
ANSI bytes there. Gate the byte-level test with cfg(not(windows)) and
add a windows-only smoke test that just exercises the function for
panic-freedom.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 14:43:58 -05:00
Hunter Bown 8bf7bf8ba6 fix(mcp): collapse SSE message match arm to satisfy clippy
The "message" arm wrapped its work in `if !data.trim().is_empty()`,
which clippy::collapsible_match flags. Move the predicate into a
match guard so the inner branch is the only body.

No behavior change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 14:43:44 -05:00
Hunter Bown c916960b23 feat(tools): expose recall archive in parent registry 2026-05-09 13:33:49 -05:00
Hunter Bown 3d45476d4f refactor(config): drop unwired context per-model field 2026-05-09 13:31:56 -05:00
Hunter Bown d109a26f35 refactor(cycle): remove stale per-model config comment 2026-05-09 13:29:18 -05:00
Hunter Bown d67752f36a docs(codemap): soften cycle manager classification 2026-05-09 13:27:57 -05:00
Hunter Bown dcf7b66ad8 refactor(mcp): centralize json-rpc framing 2026-05-09 12:34:53 -05:00
Hunter Bown b78c2f8483 refactor(update): replace curl downloads with reqwest 2026-05-09 12:34:53 -05:00
Hunter Bown 6f963adc10 fix(update): verify release assets from checksum manifest 2026-05-09 12:34:53 -05:00
Hunter Bown a6ec43ece4 refactor(tui): unify terminal-mode recovery in recover_terminal_modes()
Extract the common "re-arm keyboard enhancement, mouse capture, bracketed
paste, and focus events" sequence used by app startup, FocusGained
recovery, and resume_terminal into a single best-effort helper.

The FocusGained handler previously only re-pushed keyboard enhancement
flags + (after v0.8.24) mouse capture, missing bracketed paste and focus
events. Each new mode added at startup was a fresh gap waiting to be
discovered when a user Cmd+Tabbed away. Co-locating the four flags in
one canonical helper means future mode additions are one edit, not three.

Adds a unit test that pins the gating (mouse + bracketed paste honor
their booleans; keyboard + focus are unconditional) by writing into an
in-memory buffer and asserting on the CSI sequences crossterm emits.

Test: cargo test -p deepseek-tui --bin deepseek-tui --locked
2026-05-09 12:34:53 -05:00
Hunter Bown 42cccee02d fix(markdown): wrap long table cells instead of truncating with
The previous render_table_row truncated cell content with `…` whenever
a cell's display width exceeded `(terminal_width - 7) / num_cols`. In
narrow terminals or with verbose English/Chinese instructional tables
(common in LLM responses), users would see only the first ~30
characters of meaningful content per cell with the rest silently lost
— not visible by scrolling, not recoverable.

Replace the truncation with a word-wrapping renderer that preserves
the full cell content across multiple visual lines while keeping the
column separators (`│`) aligned on every wrapped continuation line.
The row's visual height becomes the height of the tallest column;
shorter columns get blank-padded continuation rows so column edges
stay aligned.

Algorithm:
- wrap_cell_text splits on whitespace and packs words greedily until
  the next word wouldn't fit; words wider than col_width are
  hard-broken at character boundaries so wrapping always makes
  progress (URLs, paths).
- render_table_row pre-wraps every cell, computes the row height as
  max(cell_segments_len), then emits N visual lines with each cell's
  segment-or-empty padded to col_width and separated by `│`.

Adds two regression tests covering: long cells preserve content (no
`…`) and wrapped continuation lines retain column separators.
2026-05-09 12:34:53 -05:00
Duducoco e10e53d396 fix(client): stabilize reasoning_content replay for prompt cache (#1297)
* fix(client): stabilize reasoning_content replay for prompt cache

- stop gating assistant reasoning_content on whether a later user turn
  exists; the field now depends only on the stored message itself
- preserve historical message bytes across turns so DeepSeek's prefix
  cache stays warm on every text-reply follow-up
- add a byte-stability regression test and update the prior-non-tool
  reasoning test to assert the new contract

* style(client): rustfmt single-line let binding

- collapse a two-line `let mut has_reasoning = ...` into a single line
  so `cargo fmt --all -- --check` passes
2026-05-09 12:34:36 -05:00
jinpengxuan ebae6a07f6 fix: respect active provider credentials during onboarding (#1265) 2026-05-09 12:32:52 -05:00
heloanc 2e1cec79dd fix(tui): make Home/End keys move cursor in input box (#1246)
Previously, Home/End without modifiers scrolled the transcript
instead of moving the cursor to the start/end of the input line.
This is unexpected for most users who expect standard text editing
behavior.

Now:
- Home/End (no modifier) → move cursor to start/end of input
- Ctrl+Home/End → scroll transcript to top/bottom

Closes #1234

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-authored-by: heloanc <heloanc@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Happy <yesreply@happy.engineering>
2026-05-09 12:30:17 -05:00
Hunter Bown e50eac0ce8 feat(mcp): support Streamable HTTP MCP endpoints with SSE fallback (#1300)
Closes #1266 (DeepWiki at https://mcp.deepwiki.com/mcp). URL-based MCP servers now try the modern Streamable HTTP transport first — POST JSON-RPC to the base URL with `Accept: application/json, text/event-stream`, accept either JSON or SSE response — and fall back to the older SSE endpoint-discovery flow on incompatible status codes (404/405/406/415/501). Existing SSE servers keep working via the fallback. Single-file change in `crates/tui/src/mcp.rs` with a tokio-based end-to-end test that exercises the full handshake.

Thanks @reidliu41.
2026-05-09 08:55:21 -05:00
Hunter Bown 65a4041112 fix(web): keep docs anchor scroll-margin overrideable (#1282)
Closes #1278. The docs page sets per-section `scroll-mt-32` (8rem) on each anchor section to clear the sticky nav, but the global `[id] { scroll-margin-top: 5rem }` rule loaded later with the same specificity, so 5rem won. Wrapping the global rule in `:where(...)` drops its specificity to 0, letting the page-level Tailwind utility win while still providing a fallback for anchors elsewhere on the site.

Thanks @Wenjunyun123.
2026-05-09 08:53:33 -05:00