Skip to content

Rename JSON mode → Chat, promote it as a first-class Claude interface - #82

Merged
frenchie4111 merged 13 commits into
mainfrom
chat-mode-rename-and-promote
May 25, 2026
Merged

Rename JSON mode → Chat, promote it as a first-class Claude interface#82
frenchie4111 merged 13 commits into
mainfrom
chat-mode-rename-and-promote

Conversation

@frenchie4111

Copy link
Copy Markdown
Collaborator

Summary

Promotes the React-chat interface for Claude tabs from its experimental name. Renames user-facing strings, restructures Settings so the interface choice nests under the Default Agent, threads the picker into onboarding, and adds discoverable in-tab switch affordances. Internal identifiers (json-claude, JsonModeChat, jsonClaude/* events, defaultClaudeTabType: 'xterm' | 'json') stay unchanged. Default for new installs is still Terminal — this is promotion via visibility, not a default flip.

What's new for users

  • Vocabulary: tab labels, right-click menus, sparkles tooltips, ActivityCosts copy, and Settings labels all use "Chat mode" / "Terminal mode" instead of "JSON mode" / "xterm Claude".
  • Settings → Agent → General → Default Agent → Claude now reveals a nested Terminal/Chat radio (a new reusable InterfaceToggle component). The standalone Experimental "JSON-mode Claude tabs" sub-card is gone; Chat-specific behavior (permission mode, auto-sleep, density) moves into a Chat interface card under Agent → Claude.
  • Onboarding quest: new choose-interface step sits between hidden and spawn-second, renders the same InterfaceToggle with a Continue button. Skipping defaults to Terminal.
  • Top-left overlay on Terminal Claude tabs: a ✨ Switch to the new Chat mode chip (sibling of the existing Spectating/Take control affordance), with an X dismiss button that persistently hides the promo via settings.chatPromotionDismissed. Tooltip on both buttons points users at the right-click tab menu.
  • Top-left overlay on Chat tabs (when default is still Terminal): Switch back to Terminal mode + Make Chat mode default buttons. Both auto-hide once Chat becomes the default. Tooltips point at right-click menu and Settings respectively.
  • Empty Chat state: vertically centered hero with a brand-gradient Sparkles circle, "What are we going to build today?" headline, and "Send a message to get started." subtitle.

What's removed

  • settings.jsonModeClaudeTabs flag and all of its gates. Chat is always available now; default behavior is unchanged for users on the old false default (Terminal stays default).

Dev affordances

  • Help → Debug: Preview Onboarding (dev builds only, !app.isPackaged): toggles a renderer-local override that forces the 4-step welcome form to render even when repos are added. Shows a "Preview mode" banner with an Exit button inside the form.

Test plan

  • npm run typecheck clean
  • npx electron-vite build clean
  • npx vitest run src/shared — 582 tests passing (settings slice, onboarding slice, terminals slice tests cover the rename + new field)
  • Manual: open Settings → Agent, confirm Interface radio renders nested under Claude. Codex hides it.
  • Manual: clear userData/config.json, run through onboarding, confirm choose-interface card appears after first worktree-add.
  • Manual: on a Terminal Claude tab, click the Sparkles overlay → tab converts in place. X dismiss → promo gone everywhere across reload.
  • Manual: on a Chat tab (with Terminal default), use Switch back + Make Chat default and verify both buttons disappear after defaulting.
  • Manual (dev): Help → Debug: Preview Onboarding shows the welcome form without nuking repos; banner + Exit button work.

🤖 Generated with Claude Code

frenchie4111 and others added 13 commits May 25, 2026 12:14
…n user-facing strings

Promotes the React-chat interface from its experimental name. The
internal identifiers (`json-claude` tab type, `JsonModeChat` component,
`jsonClaude/*` events, `defaultClaudeTabType: 'xterm' | 'json'` field,
`json-mode-cards/` directory, `plans/json-mode-native-chat.md`, etc.)
all stay unchanged — only display strings shift.

User-visible changes:
- Tab labels: `Claude (JSON)` → `Chat`
- Right-click menu (desktop + mobile): `Convert to JSON-mode chat` →
  `Switch to Chat`; `Convert to terminal mode` → `Switch to Terminal`
- Sparkles tooltip: `New Claude (JSON) tab` → `New Chat tab`;
  `⇧-click for Claude (JSON, experimental)` → `⇧-click for Chat`;
  `⇧-click for Claude Code (xterm)` → `⇧-click for Terminal`
- ActivityCosts empty-state copy
- CLAUDE.md / CONTRIBUTING.md user-facing phrasing

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… + tab header

Makes the Chat-vs-Terminal interface choice well-placed and discoverable
without changing the default (Terminal stays default for new installs).

Settings restructure:
- Removes the standalone `Experimental → JSON-mode Claude tabs`
  sub-card. The Interface picker (Terminal/Chat radio) now lives
  nested under the Default Agent → Claude row in Agent → General,
  rendered with the new `InterfaceToggle` component. The picker
  only shows when Claude is the selected default agent (Codex has
  no Chat-mode equivalent).
- Chat-specific config (default permission mode for new chats,
  auto-sleep idle minutes, chat density) moves to a `Chat interface`
  card under Agent → Claude — alongside the Claude command, env
  vars, etc.

`settings.jsonModeClaudeTabs` removed entirely (11 call sites,
under the spec's 10-site threshold but functionally a pure gate
that no longer has a "behind-a-flag" reason to exist). Default
behavior is now "Chat is always available; Terminal is still the
default." Persistence and IPC handler dropped along with the field;
existing configs with the key set are harmlessly ignored.

`defaultClaudeTabType` field stays unchanged — values continue to
be `'xterm' | 'json'` (no churn) but Settings now labels them
`Terminal` and `Chat`.

Onboarding:
- New `choose-interface` QuestStep, inserted between `hidden` and
  `spawn-second`. The QuestCard renders the same `InterfaceToggle`
  the Settings panel uses (size="compact"), with a Continue button
  that advances to `spawn-second`. Skip / dismiss defaults to
  Terminal (the existing `defaultClaudeTabType` default).

Per-tab switch chip:
- Every Claude tab header (agent.claude + json-claude) gets a small
  icon button (MessageSquare for Chat-bound switch, TerminalIcon
  for Terminal-bound) right before the close button, with a
  `Switch to Chat` / `Switch to Terminal` tooltip. Wires into the
  existing `convertTabType` IPC — no new plumbing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…erminal body

The per-tab icon chip felt cramped and easy to miss. The new affordance
overlays the Terminal Claude tab itself (top-left, mirroring the
top-right Spectating/Take-control overlay): a Sparkles icon plus
"Switch to the new Chat mode" — a discoverable nudge rather than a
generic toggle.

- TerminalPanel: drop the per-tab MessageSquare/TerminalIcon chip.
- XTerminal: new optional `onSwitchToChat` prop renders the chip
  when set, the tab is a Claude agent, and the terminal isn't
  loading/exited.
- WorkspaceView: thread `onSwitchToChat` through, wired to the
  existing `convertTabType('json-claude')` IPC for Claude agent
  tabs.

The reverse direction (Chat → Terminal) is still reachable via the
tab's right-click menu and the Settings interface picker. No need
to clutter the Chat body since Chat doesn't need promotion.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There's no real cost meter UI in Chat — the description was forward-
looking and read oddly to users.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…hat tabs

The Terminal-tab Chat promo chip now ships with an X button that
persistently hides the nudge across the workspace. Once dismissed,
the user keeps Settings → Agent → Interface and right-click → Switch
to Chat as the discovery surfaces.

New `settings.chatPromotionDismissed: boolean` slice field (5-file
pattern: shared slice + test, persistence, initial-state, IPC,
backend method, type). Defaults to false.

On Chat tabs, when the user's default is still Terminal (i.e. they
transitioned from Terminal → Chat on this tab), a top-left overlay
shows two buttons:
- "Switch back" — calls `panesConvertTabType('agent')` to revert
  this tab to a Terminal Claude tab.
- "Set Chat as default" — calls `setDefaultClaudeTabType('json')`.
  Both overlay buttons auto-hide afterwards since the user is now
  at home in Chat.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- "Switch back" → "Switch back to Terminal mode"
- "Set Chat as default" → "Make Chat mode default"
- Tooltips on the Switch-to-Chat, X dismiss, and Switch-back buttons
  point users at the right-click tab menu as a permanent alternative.
- Tooltip on the Make-Chat-default button points at Settings → Agent
  → Interface for reversing the choice later.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sends `app:debugResetOnboarding` from the Help menu (gated on
`!app.isPackaged`) and the renderer flips the quest back to
'hidden'. The choose-interface card resurfaces on the next worktree
tick. Lets us re-test the onboarding flow without nuking
`userData/config.json`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Big brand-gradient "What are we going to build today?" with a
Sparkles-in-a-gradient-circle above it, vertically centered in the
scroll area when the chat has no entries / pending approvals / busy
indicator. Subtitle "Send a message to get started." in muted
text. Hidden the moment the first entry lands.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bare "Switch to Terminal" / "Switch to Chat" reads ambiguously (Terminal
what? Chat what?). Adding "mode" makes the right-click menu, the
sparkles button tooltip, and the Settings Interface radio match the
overlay copy already in place.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The empty-state hero (`min-h-full`) and the regular `px-4 py-3
space-y-3` content wrapper were both rendering when entries were
empty. The wrapper added ~24px of padding below the full-height
empty state, producing a tiny scrollable overflow. Switch to a
ternary so only one of the two trees mounts at a time.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…in place

Repurposes the dev menu entry I added earlier. Instead of resetting
the QuestCard, it toggles a renderer-local override that forces the
4-step welcome / onboarding form to render even when repos are
already added, so the layout can be inspected without wiping
userData. A warning-tinted banner inside the form makes it obvious
we're in preview mode and offers an Exit preview button (toggling
the menu item again also exits).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The 4-step welcome form's "Choose your default agent" step now
reveals the Terminal/Chat InterfaceToggle right below the Claude
button when Claude is the selected default — same nested visual
pattern as Settings → Agent. Skipping it leaves the existing
'xterm' default in place.

Drops the post-creation QuestCard 'choose-interface' step now that
the welcome form covers it. QuestStep union goes back to the
original 5 values (hidden → spawn-second → switch-between → finale
→ done). QuestCard reverts to its pre-PR shape.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Subtle "Setting"-section flourish to draw the eye to the recently-
promoted Chat interface inside the Terminal/Chat radio. Uses the
same brand-gradient-bg as the Sparkles overlay button and onboarding
finale CTA for visual consistency.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@frenchie4111
frenchie4111 merged commit 2285eb7 into main May 25, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant