⚡ Claude Terminal v1.3.3
The things you touch every day: finding a setting, opening a long conversation, starting the app. All three got faster.
The headline
🧩 Third-party project types
|
🔍 Ctrl+P reaches the whole appThe palette searched projects, commands and quick actions. It now searches settings, knowledge entries, workspace docs, kanban cards and past sessions too: nine sources, grouped, each one debounced and cancellable. |
⚡ A conversation opens from its endOpening a stored conversation streamed and parsed the whole file to keep the last 400 messages: 244 ms on this project's own 28.3 MB transcript, to produce 0.29 MB. Reading the tail backwards costs 78 ms, and tool output is no longer clipped. |
🔑 A token was on your dashboardThe project overview renders the remote URL with the scheme stripped. A remote written with a token in it, which is what git stores when the URL was pasted that way, therefore rendered that token in full, permanently. |
⚡ Less to parse before the window opens
About 1.6 MB of what every launch used to parse was for features most launches never reach.
| What was happening | |
|---|---|
| The heavy panels | Every panel was required at the top of renderer.js, so a single 3.6 MB script was parsed and evaluated at every start, including the panels most people never open. The five heaviest (550 KB) now load on first tab open. Code splitting rather than one standalone bundle each: a standalone bundle would carry its own copy of the observable state modules, and a subscription would fire on one copy while the UI read the other
|
| The terminal emulator | 719 KB of xterm sat in the startup bundle because five files required it at the top level, so it was parsed even when the app opened on the dashboard and no terminal was ever shown. One memoised loader now fetches it when a terminal is first mounted, and skips the WebGL addon entirely on a machine with no WebGL2 context, since the addon has a DOM-renderer fallback and the core does not |
| The project types | All seven were loaded for everyone, 362 KB, though a machine usually has projects of one or two kinds. Each type is now split in two: its identity stays eager, because the wizard and the sidebar draw from it at boot, and its behaviour loads when a project of that type is opened |
| Opening a conversation | It read the whole transcript to keep the tail. It now reads the tail: 3x faster on a large file, with the same message count and the same context figure, and tool output is no longer cut short |
| A hidden window | Chromium suspends animation frames and throttles timers to one a second in a hidden window (one a minute past five minutes). The renderer is not just a view here: it owns the MCP tab orchestration loop, so minimising to the tray stalled a running orchestration |
Everything else
- A search field in Settings, because nine groups in one 2700-line panel were reachable only by scrolling. It matches each row's rendered label and help text rather than a parallel keyword table, so it works in all five locales with nothing extra to keep in sync, and it ignores case and accents
- Terminal font size, settable between 10 and 24px and applied live to every terminal already open (#181)
- The tab close confirmation can remember your answer. Only on confirm: a remembered cancel would be a close button that never closes anything. Reversible from Settings → Claude → Terminal
- Project types are opt-in twice: the feature is off by default, and each extension is enabled one at a time on top of that. Ids are namespaced so an extension cannot shadow a built-in or reword a first-party string
- The database connection picker is themed instead of drawn by the OS. The
<select>opened a white, system-blue list in the middle of a dark modal, and no CSS can reach that. It also buys a colour dot per driver and keyboard navigation - Desktop notifications match the in-app toasts, same shape, radius, icon disc and accent stripe, instead of two objects that had drifted apart
- The dashboard's first load draws the page greyed out instead of spinning, so nothing moves when the real content arrives
- Every copy button in the app had silently stopped working. The permission allowlist added with voice capture granted only
media, so Chromium denied the clipboard check insidenavigator.clipboard.writeText(). Copies now go through a helper that prefers Electron's clipboard, which answers to neither a permission nor a focus rule - A tab asked to wait could report finished before the turn had started.
tab_waitmatched on a status rather than on a transition, andhandleSend()only flips the tab to working a few ticks later, so atab_sendfollowed by atab_waitresolved on the idle that precedes the work. Silent, and it looks exactly like success - A locked worktree could never be removed. Git wants a second
--forcefor that, and the panel only ever passed one. The lock is often git's own:worktree addholds one while it sets up, so an interrupted add left a worktree the UI could only refuse to delete - Clicking an image in a tool card collapsed the card instead of opening the lightbox: the delegated handler tested the card before the two lightbox branches, so they were unreachable from there
- The collapsed sidebar painted its icons over the footer. The rail kept
overflow: visibleso its tooltips could escape its 56px width; with every tab pinned it is ~750px tall, so the overflow was never clipped, it was drawn, over the bell, the gear and the version string - A notification's close button sat next to the text instead of at the right edge, and what a notification looked like depended on which module raised it
- A diagram that fails to parse no longer leaves mermaid's error graphic floating over the window: it throws the parse exception one line before it removes its own temporary element
- Nothing measured coverage, so nothing noticed it drifting. Thresholds are pinned at the values measured today rather than aspirational ones, the floor that matters being
src/main/services/where the privileged, networked and credential-handling code lives. It runs as its own job so it cannot make the blocking test job flaky ChatView.jsandTerminalManager.jsare pinned by characterization tests before anyone splits them: 9.5k and 4.8k lines, and the split is not safe to start blind- The README now ships in the app's five locales, and
check:docscompares the four translations against the English one: identical heading structure, a switcher reaching every file, anchors that resolve. Only the shape is checked, never the prose
🙏 Thanks
| @kenmeeus | First contribution: configurable terminal font size, applied live to open terminals through the same path the theme already used (#181) |
📜 Full changelog - 31 commits
feat(project-types) load declarative third-party project types
feat(palette) search settings, knowledge, docs, cards and sessions
feat(settings) add a search field to the settings panel
feat(settings) add configurable terminal font size (#181)
feat(chat) read a conversation from its end and unclip tool output
feat(tabs) let the close confirmation remember the choice
feat(notification) match the desktop notification to the in-app toast
feat(database) replace the native type select with a themed picker
feat(dashboard) replace the first-load spinner with a skeleton
fix(dashboard) stop printing credentials embedded in a git remote
fix(clipboard) restore the copy buttons broken by the permission gate
fix(window) keep the renderer awake while the window is hidden
fix(mcp-tabs) wait for the turn to start before reporting idle
fix(git) allow removing a locked worktree
fix(chat) stop a failed mermaid diagram leaking into the page
fix(chat) open the lightbox instead of collapsing the tool card
fix(settings) make the terminal font size row follow the panel conventions
fix(sidebar) stop the collapsed rail painting its icons over the footer
fix(toast) pin the close button to the right edge of the notification
perf(renderer) defer the heavy panels to first open
perf(terminal) load xterm when a terminal is first mounted
perf(project-types) load a type's behaviour only when it is used
test report coverage and pin it with ratcheted thresholds
test(chat) pin ChatView and TerminalManager behaviour before splitting
chore(check-docs) guard the README translations against drift
docs(readme) add translations for the four other app locales
docs(readme) document the features shipped since 1.2.x
docs resync CLAUDE.md and the READMEs with the tree
docs resync CLAUDE.md with the tree
docs resync CLAUDE.md with the tree after the 1.3.2 batch
chore(release) 1.3.3
Note
macOS users: if the app is reported as damaged on first launch, it is unsigned rather than broken. Run xattr -cr "/Applications/Claude Terminal.app", or right-click the app and choose Open.