Skip to content

Releases: clawterm/ClawTerm

ClawTerm v1.7.0

Choose a tag to compare

@github-actions github-actions released this 23 May 11:33

Changed

  • System notification surface narrowed — agent attention (OSC 9;2) is now the only producer. Before, a single agent turn could fire two banners (the generic "command finished in: X" matcher fired alongside the agent's own OSC), and server-started / server-crashed / generic error matchers piled up in Notification Center for events users could already see in-tab. The notifyCommandComplete() path, the EVENT_TO_CONFIG_KEY map, and the entire notifications.types config subtree are gone. Server-detection matchers still feed the in-tab "Open localhost:X in Browser" context menu and the per-tab lastError display — only the system-banner surface is removed. As part of the same pass, the muted flag now gates Tab.handleOscNotification once at the top so a muted tab silences the sidebar dot and the banner together (previously each surface was checked separately, and a dead onNeedsAttention callback was still wired up post-#547 phase 1 producing duplicate banners). Config schema bumped to v3 with a migration that strips the legacy notifications.types subtree (#547).
  • Pane-scoped active-tab suppression in multi-pane tabs. Before: a 4-pane tab where you're focused on pane A wouldn't fire a banner for pane B's agent because the tab was "visible." After: the banner fires unless you're actually looking at that specific pane. Single-pane tabs are unaffected (focused pane equals only pane) (#549).
  • Per-tab 4-second cooldown on agent-attention banners. A misbehaving agent or runaway Claude Code Notification hook can emit OSC 9;2 in a tight loop — without throttling that's 10 banners in a second, replacing each other on platforms with tag-coalescing and burning through Notification Center retention. The sidebar dot still updates every time (idempotent); only the system banner is throttled. Per-tab rather than global so a noisy agent in tab A can't penalize tab B. Cooldown records are dropped on tab close so the map stays bounded across long sessions (#551).

Removed

  • Web Audio chime. The in-app two-tone AudioContext chime bypassed macOS Focus / Do Not Disturb because it was app audio, not OS-notification audio. Banners alone are signal enough; users who want a notification sound can configure one through System Settings → Notifications. Notifications now post with silent: true so the OS default chime doesn't sneak back in alongside the live banner. Config schema bumped to v4 with a migration that strips the legacy notifications.sound field.

Fixed

  • Cmd+Shift+D now actually splits vertically. The split container in tab.ts is built as split-container split-${direction}, but #518 deleted the .split-horizontal / .split-vertical CSS thinking it was dead — the commit conflated the container's class template with the divider's split-divider-${direction} template on the next line. Without these rules the container fell back to the default flex-direction: row, so a vertical split rendered side-by-side and was visually indistinguishable from a horizontal split. Horizontal splits worked by coincidence. This is the second regression of the same rules — c11f046 already restored them once after #472 — so a DO NOT REMOVE comment now points at the consumer in tab.ts so a third cleanup pass doesn't repeat the mistake (#557).
  • Notification permission denied now surfaces a one-shot toast explaining how to enable (System Settings → Notifications → Clawterm), instead of silently no-op'ing on every OSC. Latched with a per-session flag so it doesn't spam. On window-focus the OS permission is re-queried so a user who flips permission on externally gets working banners without an app restart; a re-grant resets the latch so the toast fires again on a future revoke. A public isOperational getter is exposed for the upcoming settings UI (#553) to render the disabled state (#550).

See CHANGELOG for full history.

ClawTerm v1.6.4

Choose a tag to compare

@github-actions github-actions released this 19 May 18:50

Fixed

  • Cmd+V now actually pastes again. #531 (shipped in 1.6.2) dropped the CmdOrCtrl+V accelerator from the custom Edit → Paste MenuItemBuilder on the theory that Cmd+V would fall through to WebKit and dispatch a DOM paste event. It doesn't — WKWebView's Cmd+V handling needs an NSMenuItem with the paste: action selector seeded onto the responder chain, which a custom-action menu item never installs. After #531, no item registered paste:, so Cmd+V was swallowed and no paste event fired; paste only worked via the Edit-menu click and right-click paths (both of which kept triggering the consent UI #531 was meant to remove). The Edit → Paste item is now PredefinedMenuItem::paste, which builds an NSMenuItem with action: paste: and the standard Cmd+V key equivalent. Cmd+V now routes through WebKit's native paste — NSText reads NSPasteboard, dispatches a real DOM paste event on the focused element, and the pane listener handles agent-trust gating and image-clipboard detection (the latter moved into the pane listener from terminal-manager.ts::dispatchPaste, which is no longer on the keyboard path). The pasteboard-consent UI does not appear on Cmd+V because the native paste action does not go through navigator.clipboard.readText() (#546)

See CHANGELOG for full history.

ClawTerm v1.6.3

Choose a tag to compare

@github-actions github-actions released this 16 May 16:01

Fixed

  • Pane text no longer stays stuck at the old column count after a window resize while terminals are streaming output. pane.fit() defers fitAddon.fit() for 300ms whenever the PTY wrote in the last 300ms — that exists to stop a write/fit race from corrupting the saved scroll position (#177). The deferral rescheduled on every new fit request with no upper bound, so a pane streaming continuous output (an agent running, tail -f, a busy build) could defer its fit forever. Window resize goes through this deferred path; divider drag uses forceFit and bypasses it — which is exactly why "some terminals stay stuck and others don't" mid-stream. Two changes: (1) the deferral chain is now capped at 1000ms total wait, so a resize is always reflected within ~1s; (2) the window-resize ResizeObserver adds a 150ms settled-timer that force-fits every pane in the active tab once the resize gesture quiets down, mirroring divider-drag's mouseup semantics. The 300ms quiet-output check still wins when it can, preserving the scroll-jump guard for bursty output (#532)
  • macOS Dock icon now refreshes after an in-app update. The Dock and IconServices cache the icon per-bundle-path; replacing Contents/Resources/icon.icns in place (what tauri-plugin-updater does on macOS) doesn't invalidate either cache. Users who self-updated saw the OLD icon in the Dock until they killall Dock or restarted — most visibly when updating across the v1.6.0 brand refresh. A new macOS-gated Tauri command bumps the .app bundle directory's mtime via std::fs (no extra crates), which is what makes IconServices re-read the .icns on the next Dock query. The updater calls it right before relaunch(); failure is non-fatal. If you're already on a stale-iconed 1.6.x, killall Dock is the one-shot manual fix (#533)

See CHANGELOG for full history.

ClawTerm v1.6.2

Choose a tag to compare

@github-actions github-actions released this 16 May 14:30

Fixed

  • Cmd+V no longer triggers the macOS pasteboard-consent UI (the floating "Paste" pill on macOS 15+, or the "Allow Paste from [App]?" alert on 14). The Edit → Paste menu item used to register Cmd+V as an AppKit accelerator, which consumed the keystroke before WebKit saw it; the menu callback then read the clipboard via navigator.clipboard.readText(), a programmatic NSPasteboard read from JS that macOS gates behind the consent UI. The accelerator is gone — Cmd+V now flows to WebKit, which dispatches a real DOM paste event with clipboardData populated and the user-gesture context intact, and the existing pane paste listener handles it with no system prompt. The Edit menu still has a Paste item (clicking it manually goes through the old readText path and still surfaces the OS UI — rare path). Cut, Copy, and Select All keep their accelerators since they don't read the pasteboard (#531)

See CHANGELOG for full history.

ClawTerm v1.6.1

Choose a tag to compare

@github-actions github-actions released this 15 May 22:01

Removed

  • Plausible analytics — purged from both the in-app shell and the landing page. The deferred script-injection in src/main.ts, the <script> block in docs/index.html, and the https://plausible.io allowances in the Tauri CSP are all gone. ClawTerm no longer makes any third-party analytics requests.

See CHANGELOG for full history.

ClawTerm v1.6.0

Choose a tag to compare

@github-actions github-actions released this 15 May 21:29

Changed

  • Brand refresh — new mark, color system, and typography. ClawTerm now ships with a 2×2 command-grid icon (active tile in Command Green #7CFF4F), a unified all-mono UI (JetBrains Mono everywhere from sidebar labels to wordmark — Inter is retired), and a calmer Mac-utility palette. Active state is the only thing rendered in green: focused tab, focused pane border, primary CTA, terminal cursor, focus ring, status indicators. Decoration uses neutral tokens. Borders are dimmed throughout and the terminal interior is now #07080A, one notch darker than the surrounding chrome, so the terminal reads as a deliberate well. Inactive terminal panes no longer render a cursor, reinforcing which pane is receiving input. App icon, favicons, web manifest, and the landing page (docs/index.html) are all regenerated against the new system. See docs/brand.md for the full guidelines (#523, #524, #525, #526, #527).
  • Brand renamed Clawterm → ClawTerm (capital T). Documentation, in-app strings, menus, window titles, and Tauri bundle metadata all use the new casing. The macOS bundle is now ClawTerm.app for fresh installs; the bundle identifier stays com.clawterm.terminal so the in-app updater rewrites your existing Clawterm.app in place and all user data and config persist across the rename. If you'd like a consistent filename you can quit ClawTerm, drag the old bundle to the Trash, and reinstall — but you don't have to (#524).
  • Branch colors in the sidebar now use brand-tuned hues — the same bright ANSI palette the terminal already renders (soft red, green, yellow, blue, magenta, cyan), replacing the louder saturated iOS palette that didn't fit the Mac-utility direction. Per-branch color stability is preserved (deterministic hash → palette index).

Fixed

  • Docs referenced stale Clawterm_<version>_* bundle filenames in installation and development guides. Updated to match the new ClawTerm_<version>_* naming produced by fresh Tauri builds. The scripts/lint-name.sh guard now catches the Clawterm_<version> pattern too — the previous word-bounded match treated the underscore as a word character and skipped these.
  • Windows and Linux references removed from user-visible docs. ClawTerm has been macOS-only since v1.4.3, but the installation guide, development guide, keybindings reference, configuration reference, architecture overview, RELEASING.md, and install.sh still described the old multi-platform install paths and per-OS keybindings. All scrubbed to a single macOS path.

See CHANGELOG for full history.

Clawterm v1.5.0

Choose a tag to compare

@github-actions github-actions released this 15 May 20:12

Added

  • Multiple Clawterm windows — drag a terminal to a second monitor and watch it while you work on the primary. Click the + button at the right of the titlebar (or Cmd+N, or File → New Window in the menu bar) to spawn an additional window. Each window has its own tabs, panes, and PTYs; PTY ownership stays scoped to the window that created the pane, so closing one window can't kill terminals running in the other. Only the main window owns session.json — secondary windows are ephemeral by design, so on next launch you get back exactly what you had in the main window (plus a fresh empty secondary if you want one). Process-wide startup (PTY session cleanup, the auto-updater, analytics) runs only in the main window so opening a second window can't double-fire or nuke the main window's PTYs (#522)

Changed

  • Closing the last tab now closes the window instead of spawning a fresh tab. Matches Warp / iTerm2 / Wezterm / Terminal.app convention, and is the obvious behavior once multi-window exists — a secondary window's last-tab-close should disappear the window, not leave you stuck on an empty one. For the main window this quits the app, same as Cmd+Q. Uses WebviewWindow::destroy() rather than close() because the onCloseRequested hook calls manager.dispose() and re-entering teardown while already mid-cleanup left the window frozen-but-alive (#522)

Fixed

  • macOS menu shortcuts no longer fire in every open window — the menu is process-level on macOS, but on_menu_event was broadcasting menu-action to every webview via app.emit. With two windows open, pressing Cmd+W in one would close a tab in both; same for every menu-bound action. The frontend now tracks per-window focus via onFocusChanged and the menu-action listener early-returns unless that window is the focused one — only the window the user's actually looking at acts on the keystroke (#522)
  • macOS menu state no longer flickers between windowsapplyMenuAccelerators and updateMenuDisabled push state to the (process-level) menu, so a background window's render could clobber whatever the focused window had just installed. Both now gate on the local isWindowFocused flag, and a focus swap force-refreshes the menu so the dim/accel state always reflects the window you're actually looking at (#522)

See CHANGELOG for full history.

Clawterm v1.4.3

Choose a tag to compare

@github-actions github-actions released this 15 May 16:53

Added

  • Cmd+V now pastes images into Claude Code's prompt — Claude Code already pulls clipboard images from NSPasteboard via osascript when it receives Ctrl+V (\x16), but Cmd+V was just calling readText(), which returns "" for image-only clipboards so nothing reached the TUI. The Edit-menu paste handler now inspects the clipboard for image/* types; if it finds one and the focused pane's foreground is a trusted agent, it sends Ctrl+V to the pty and lets Claude Code handle the rest. Text clipboards and shell panes are unaffected (#520)

Fixed

  • Claude Code statusLine row no longer disappears after 30 seconds of idle — the row (model name + context bar + effort + thinking dot + >200k tag) was hidden on both the pane footer and the sidebar tab entry whenever the on-disk per-turn JSON went "stale", because the Rust reader treated any file older than 30s as untrustworthy. But the writer only fires on assistant turns, so simply reading a long response was enough to nuke the indicator. The stale gate is now gated on whether the keyed PID is still alive (via kill(pid, 0)) instead of mtime, and a startup sweep removes orphan files left by dead Claude sessions so /tmp/clawterm-status/ stays bounded across runs (#521)
  • Paste-confirm dialog no longer fires for Claude Code during tool calls — the trust gate added in #508 only inspected the immediate foreground PID, which briefly becomes a tool subshell (zsh / bash / node) whenever Claude runs a Bash tool. The dialog then fired even though claude was still the session driver. The gate now walks up the parent chain back to the pane's shell and trusts the paste if any ancestor matches the trusted-agent allowlist, capped at 8 hops via a new proc_ppid lookup. Also skips the dialog when the pty isn't initialized yet, which removed a confusing modal race during pane startup. Extracted the pure trust decision so it has real test coverage (#519)

See CHANGELOG for full history.

Clawterm v1.4.2

Choose a tag to compare

@github-actions github-actions released this 14 May 14:07

Removed

  • Dead-code sweep across three removal-wave leftovers — code paths that grep+verify proved unreachable were trimmed: the entire Windows titlebar branch in terminal-manager.ts and its .win-ctrl / .titlebar-win / --win-close-* CSS (residual from the v1.4.0 platform drop — isMac has been a constant true); the empty no-op stubs updateStatusBar(), setupStatusBarClicks(), and showPaneNumberOverlay() along with the five call sites and stale doc-comments that kept invoking them (residual from #348 and #333 in v1.2.0); the unused get_process_cwd Tauri command (the frontend only calls get_process_cwd_full); the dead sidebar.groupByState and sidebar.expandActiveTab config knobs that the renderer ignored (signature took them with underscore prefixes), the duplicate _tabIndex parameter on renderTabEntry, and the matching docs row; the two non-divider .split-horizontal / .split-vertical CSS rules left over from before the split-divider split-divider-${direction} template existed. No visible change; ~140 lines net (#518)

See CHANGELOG for full history.

Clawterm v1.4.1

Choose a tag to compare

@github-actions github-actions released this 14 May 11:51

Added

  • Sidebar tabs now show a Claude Code context-window bar + N% per tab — previously you had to click into a tab to find out how much context a Claude session had used. The bar now lives on every tab header whose pane has a Claude statusLine, using the same ok / warn / crit color thresholds (60% / 85%) as the pane footer so the two surfaces never diverge. Multi-pane tabs show the max % across panes on the header AND a per-pane % column inside the sub-list, so you can also see which pane is burning context. Plain shells render no bar and reserve no space — the indicator is opt-in by the presence of Claude data. CSS extracted to a shared .context-bar / .context-bar-fill family so the sidebar and footer can't drift on width, color, or fill behaviour. Snapshot diffing buckets to nearest 5% so typing in Claude doesn't repaint sidebar DOM on every assistant turn (#507)

Changed

  • The context-near-limit attention dot is gone — the new sidebar bar already paints the same threshold (≥85% → crit red), so the orange dot was redundant. The rate-limit-near and compaction-imminent dots stay; they encode signals the bar can't express on its own (#507)
  • Brand assets now derive from a single source SVGdocs/brand/clawterm.svg is the canonical mark; the app icon (src-tauri/icons/*.png + .icns), the favicon (docs/favicon.svg + .png), and the new GitHub social-preview image (docs/brand/og-image.png) all regenerate from it via documented sips / iconutil commands in docs/brand/README.md. Geometry preserved — the chevron mark is unchanged. Hand-edited bitmaps are now a bug; re-run the regeneration commands after any edit (#501)

See CHANGELOG for full history.