Terminal: first-class workspace feature with Claude Code integration#118
Conversation
…ures/terminal/ Move TerminalViewport, terminalTheme, terminalTypes, terminalRawOutput, terminalSessionTracking, and useTerminalTabs out of features/devtools/terminal/ into features/terminal/ alongside the existing runtime store and host components. Update all imports, rename the CSS class from .devtools-terminal-surface to .terminal-surface, and expand terminalTheme to include the full 16-colour ANSI palette (mapped from the app's Catppuccin icon tokens) and font-options support. Includes the implementation plan in docs/terminal-integration.md.
Ungate the terminal from Developer Mode — New Terminal appears in every pane's + menu and the command palette without requiring developerModeEnabled. Settings → Terminal section: font family (with document.fonts.load() pre-check for correct xterm.js cell metrics), font size, and Claude Code rendering toggle (CLAUDE_CODE_NO_FLICKER=1). Right-panel layout watcher re-fits the terminal after peek overlays open/close. Rust sidecar: COLORTERM=truecolor added as default; extra_env passthrough for per-session env overrides; devtools_check_binary command for PATH-aware binary detection via login shell. TypeScript: extraEnv field threads through TerminalSessionCreateInput and both terminal session create call sites.
Registers claude-code-terminal as a pseudo-runtime injected alongside ACP providers in chatStore. Binary presence is detected via devtools_check_binary (login shell) at initialization; result drives binaryReady/authReady and the auto-default selection (Claude Code becomes the default new-chat target when found and no explicit preference is set). selectedRuntimeId persistence: saved to AI preferences so the choice survives restarts. getDefaultNewChatRuntimeId() reads prefs + binary status directly, bypassing the active-session override that would otherwise shadow the setting. Add to chat routing: handleAttachToNewChat checks getDefaultNewChatRuntimeId() and calls openClaudeCodeTerminalWithContext() when Claude Code is the target. Context (notes, files) is formatted as quoted @mentions; a cd command scopes the session to the vault root or the selected folder. AI Providers settings: Claude Code appears in the INSTALLED section with a "Ready" badge when found, and in ALL with an Install button (opens claude.ai/code) when not. A "Default agent" selector with documentation sits above the installed list. A note under the Claude Code row links to Terminal settings for model, skip-permissions, max-turns, and continue-session configuration.
7a86be0 to
c01b55c
Compare
Adds terminalPalettes.ts: hand-tuned 16-colour ANSI palettes for all 20 NeverWrite themes (catppuccin, nord, solarized, gruvbox, tokyoNight, rosePine, kanagawa, everforest, ayu, nightOwl, vesper, synthwave84, and the app-specific default, ocean, forest, rose, amber, lavender, sunset, claude, codex). Palettes are applied as --terminal-ansi-* CSS custom properties synchronously inside applyThemeColors() — same call site, same tick, no effect-ordering issue. getTerminalTheme() reads --terminal-ansi-* first, falling back to the existing --catppuccin-icon-* tokens for any theme without a custom entry. When the user switches themes, the terminal colours update live via the existing useThemeStore subscription in TerminalViewport.
c01b55c to
2f9452a
Compare
Subscription-based auth (claude-ai-login, claude-login, console-login) only works with the Claude Code CLI, not the ACP sidecar. Strip these methods from claude-acp in normalizeRuntimeSetupStatus() and mark the runtime as not-ready when the current auth is subscription-based. Adds a note in the Claude provider expanded panel directing users to configure an Anthropic API key. If only a subscription was previously configured, Claude ACP now shows as "Not configured" until a key is added.
Security: - devtools_check_binary: validate binary name against [A-Za-z0-9._-] before interpolating into sh -lc to prevent shell injection - cd command: switch from double-quote to single-quote escaping so $, backticks, and backslash in vault/folder names can't execute arbitrary shell code Bugs: - chatPaneMovement: remove the second guard clause (default-runtime check) that was silently returning null for explicit ACP runtime requests (e.g. clicking + Codex from the sidebar) when Claude Code was the default provider - ai:new-agent command/shortcut: route to openClaudeCodeTerminalWithContext() when Claude Code is the default instead of calling createNewChatInWorkspace() which would silently no-op Correctness: - buildContextArgs: strip vault root prefix from absolute note/file paths so @mentions are vault-relative rather than exposing full filesystem paths - @mention quoting: use safe-character whitelist instead of space-only check - Thread paneId through openClaudeCodeTerminalWithContext so terminals opened from a specific pane's + menu land in the right pane
De-duplicate descriptor (jsgrrchg#2): Extract CLAUDE_TERMINAL_DESCRIPTOR and buildClaudeTerminalSetupStatus into features/ai/utils/claudeTerminalRuntime.ts. chatStore and AIProvidersSettings now share one definition with consistent copy. Subscribe-based terminal ready (jsgrrchg#3): Replace setInterval+setTimeout polling in waitForTerminalRunning with a synchronous pre-check followed by useTerminalRuntimeStore.subscribe. No busy loop, no 100ms lag, logs a warning on timeout. Raise settle delay (jsgrrchg#4): CLAUDE_TUI_SETTLE_MS 2000 → 3500 with a comment explaining the limitation and what a proper fix would require. Binary check cache (#1): Module-level cache in checkClaudeCodeInstalled() so chatStore, TerminalSettings, and AIProvidersSettings share one sh spawn rather than three. Persist auto-selection (jsgrrchg#5): When Claude Code is auto-selected on first launch (binary found, no prior preference), persist it to AiPreferences so binary removal/reinstall doesn't silently change the default on next start. ACP runtime auto-selection is NOT persisted — only the Claude Code terminal selection is.
|
Hey I did a quick fix to connect the behavior in the sidebar to the new chat behavior and the cmd+shift+n shortcut. Also I found this issues, if you are busy let me know, I can take it from here, I'll add now a few tests
Let me know your thoughts, and thank you for your work |
|
Before merge, I think we should settle four remaining points:
Some of this may be intentional product direction, 2 and 3 gives me that impression. |
Closes #107.
What's in this PR
Terminal as a first-class feature
+menu and command palette for all usersfeatures/devtools/terminal/intofeatures/terminal/document.fonts.load()pre-check for correct xterm.js cell metricsCOLORTERM=truecolorandextra_envpassthrough added to the Rust PTY sidecarClaude Code as a built-in agent provider
devtools_check_binary)cds to vault or selected folder, startsclaudewith configured flags, pre-fills@mentionsfor attached notes and files--dangerously-skip-permissions), model selection, continue last session (--continue), max turns (--max-turns)