Batch of small UX fixes: permission stream, compact mode, settings, CLI session list, keybindings, export, copy - #220
Open
leonidasbarkas98-cpu wants to merge 12 commits into
Conversation
Root cause (regression from a156881, MCP-file -> stdio migration): the 'result' event closed the Claude process stdin immediately, tearing down the stdio control channel while can_use_tool requests could still be in flight -> every permission prompt aborted instantly. - Defer stdin.end via _maybeEndClaudeStdin: close only once 'result' was seen AND no permission request is pending (500ms grace window), retried after each answered prompt so the process still exits cleanly. - Re-entrancy guard in _sendMessageToClaude: reject a second send while a process is running (overlapping --resume spawns fought over the session lock; queueing stays fork-issue-16). - [perm] diagnostic logging on spawn/result/can_use_tool/response/kill to prove the failing path at runtime if it ever reoccurs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
New setting claudeCodeChat.ui.compactMode (default off): reduces paddings, margins, font sizes and line heights of chat messages, tool blocks and code blocks for a denser layout. Nothing is hidden or restructured - density only; the normal layout is untouched. - Reuses the existing settingsData transport (_sendCurrentSettings) to push the flag into the webview, which toggles a body-level compact-mode class; all overrides live in one scoped CSS block. - onDidChangeConfiguration listener extended so changing the setting in the native VS Code settings UI applies live without a reload. Also ships temporary file-based [perm] diagnostics for fork-issue-15: console.error of an installed extension is not persisted anywhere readable, so _permLog() mirrors all permission-channel events (stdin close/error, stdin.end stack, can_use_tool stdin state, process close) to os.tmpdir()/claude-code-chat-perm.log. To be removed once fork-issue-15 is root-caused. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds three checkboxes to the webview settings modal (gear icon) so the recently introduced options are discoverable in-app, not only in the native VS Code settings UI: - notifications.completionPopup (default on) - notifications.completionSound (default off) - ui.compactMode (default off) New 'Notifications' and 'Appearance' sections follow the existing settings-group markup; values ride the existing settingsData / updateSettings transport (_sendCurrentSettings now also carries the two notification keys; _updateSettings is generic already). compactMode keeps its single effect path (config change -> settingsData -> body class). Also updates the _maybeEndClaudeStdin doc comment with the fork-issue-15 perm-log findings; behavior unchanged — the reviewed close logic stays until the lifecycle rework lands. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ue-31)
Replace the Plan and Ultrathink input toggles with a single Modes popup
matching the standard Claude Code UI: four permission modes (Manual,
Edit automatically, Plan, Auto) with descriptions and a checkmark on
the active one, plus an effort slider (Low/Medium/High/Extra high/Max)
and a shift+tab cycle hint.
- mode and effort are provider state persisted in workspaceState
('claude.selectedMode'/'claude.selectedEffort', same pattern as the
model selection), pushed to the webview on init (modeSelected/
effortSelected) and applied on every process spawn: --permission-mode
for acceptEdits/plan/auto (Manual sends no flag, byte-identical to
the previous default spawn) and --effort once explicitly chosen
(no flag before first interaction, CLI default stays in charge),
- selection therefore now also applies to queued messages, slash
commands and plan-file sends, and survives panel reloads,
- the ULTRATHINK prompt-prefix block is removed; --effort is the
native replacement (the thinking.intensity setting and its modal
stay dormant, cleanup is a follow-up),
- _sendMessageToClaude loses the per-message planMode/thinkingMode
parameters; the message queue carries only id/message/images,
- popup follows the existing connect-menu pattern; effort slider
labels get scoped flex rules so five labels fit the popup width,
- shift+tab in the input cycles through the four modes.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The headless CLI does not interpret /compact as a command (verified on the target system: the text is passed verbatim to the model), so a real compaction is emulated: the toolbar button sends a summarize turn to the running session (full context, no user echo, no backup commit), captures the result as a seed, and arms a forced fresh session — the next user message starts without --resume, prefixed by the summary. A failed summarize (e.g. an API 400 after context overflow) still arms the fresh session, just without a seed, giving a one-click way out of an otherwise dead conversation that would re-resume into the same overflow forever. A saved separator message marks the boundary in the chat and on reload; the conversation filename is pinned so the fresh session keeps writing the same history file. The slash modal's /compact entry now uses the same flow instead of the dead verbatim send, and the context indicator highlights the button from 85% usage. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ssue-37) The history panel now shows a separate "CLI Sessions" section with the 25 most recent Claude Code CLI sessions of the current workspace, read from ~/.claude/projects/<slug>/*.jsonl (slug matched case-insensitively, CLAUDE_CONFIG_DIR respected). Titles come from a bounded 64 KB head read (first real user line), entries already known to the extension's own history are deduplicated away, and the JSONL files are never written to. Clicking an entry resets the conversation state, adopts the CLI session id and renders a display-only preview of the last ~20 messages from a bounded 512 KB tail read; the next message then continues that session through the regular --resume path and is saved as a normal extension conversation. The line parser is strictly defensive since the JSONL format is CLI-internal and may change between versions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…sue-41) Three confirmed paths let an old session bleed into the visible chat: loading a conversation from history never adopted its sessionId, so the next turn resumed whichever session was active before and the following save poisoned the file on disk with the foreign id - the load path now adopts the stored id when its CLI transcript still exists (fresh start otherwise) and drops pin/checkpoints only when switching files. Stdout of a superseded process had no stale guard (close did), so a late result line could reinstate a killed session - the handler now ignores non-current processes. The compact pin (fork-issue-36) lived only in RAM and a reload split the conversation in two files - it now rides along in the persisted panel state. The spawn log records the effective resume/fresh decision for future field diagnosis. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…inding (fork-issue-45) Ctrl+Shift+C collided with terminal copy; the binding now carries when !terminalFocus and the README explains how to rebind or disable it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit a4e41f5ad9a45412c20198fd1c304d601a37fbf0)
Adds a download button next to the delete button on each history entry. The host validates the filename exactly like the delete path, reads the stored JSON untouched and writes it wherever the save dialog points (Downloads, then workspace, then home as the default location). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit d970e21dbcf9f866222a97a8c7b6c4a341d2c1d0)
…sue-46) The message copy button read innerText, so ordered lists lost or renumbered their markers (parseSimpleMarkdown strips the literal digits and interrupted lists restart at 1). addMessage now records the raw markdown in a WeakMap and the copy handler prefers it, falling back to the old DOM read when no raw text exists. Side effect worth noting: messages with code fences now copy as markdown source including the fence lines, instead of flattened rendered text. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 1b406605a13f3162c623aeb0b4bfa387800321f5)
completionPopup/completionSound were read/written by fork-issue-29 but their package.json configuration entries come from the fork-issue-17 notification feature, which is intentionally not part of this batch. Since VS Code rejects config.update() for unregistered keys, every settings save would throw mid-loop and silently drop all other settings changes. Remove the two orphaned checkboxes and their read/write wiring instead of registering the keys (that would pull fork-issue-17 scope in unannounced).
Bare #NN comment references pointed at our private tracker, not this repo's issues; requalify as fork-issue-NN so GitHub doesn't auto-link them to an unrelated issue here. Genuine "upstream andrepimenta#98" references are left untouched.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A batch of unrelated small UX fixes and additions, grouped into one PR because each is small on its own. In commit order:
resultclosed the Claude process stdin immediately, tearing down the stdio control channel while acan_use_toolrequest could still be in flight.stdin.endis now deferred untilresultwas seen and no permission request is pending, retried after each answered prompt; a re-entrancy guard also rejects a second send while a process is still running.claudeCodeChat.ui.compactMode): reduces padding/margins/font size/line height of messages, tool blocks and code blocks for a denser layout. Density only, nothing hidden or restructured; applies live via the existing settings transport.--permission-mode/--efforton every spawn (Manual sends no flag, byte-identical to the previous default spawn), and survives queued messages, slash commands, plan-file sends and panel reloads./compactas a command, compaction is emulated by sending a summarize turn to the running session, capturing the result as a seed, and arming a forced fresh (non---resume) session for the next message, prefixed by the summary. A failed summarize still arms the fresh session (without a seed) so an overflowed conversation isn't stuck re-resuming into the same overflow.~/.claude/projects/<slug>/*.jsonl, deduplicated against sessions the extension already knows. Clicking one adopts the session id and renders a bounded preview; the next message continues it through the normal--resumepath.Ctrl+Shift+Ckeybinding for the new Compact button conflicting with the VS Code terminal's copy shortcut (scoped to!terminalFocusnow); README documents how to rebind or disable it.innerText, so ordered lists keep their original numbers instead of being renumbered/flattened by the rendered DOM. Falls back to the old DOM read when no raw markdown was recorded for a message. Side effect: messages with code fences now copy as markdown source (including fence lines) instead of flattened rendered text.package.jsonconfig keys (belonging to a notification feature intentionally out of scope for this batch —config.update()on an unregistered key throws and was silently dropping every other settings change in the same save), and requalified internal-tracker issue references in code comments so they don't auto-link to unrelated issues on this repo.This is one of several PRs from our fork submitted together as part of a broader, thematically grouped series (permission/session handling, settings/UI, security hardening, rendering, etc. split across separate branches/PRs). This particular branch is based directly on current
main(ab6e307) and does not stack on any other PR in the series.tsc --noEmitclean, no new dependencies.🤖 Generated with Claude Code