mirror of
https://github.com/cline/cline.git
synced 2026-09-19 02:05:44 +08:00
The CLI's interactive TUI has been rewritten from scratch using [OpenTUI](https://github.com/anomalyco/opentui), replacing the Ink-based implementation. OpenTUI is a native terminal rendering engine written in Zig with a React reconciler, giving us capabilities that were impossible with Ink: native diff rendering, syntax-highlighted code, streaming markdown, scrollable content, mouse interaction, and clipboard support. ### Before / After The old TUI was a single 1,300-line monolith (`interactive-tui.ts`) with 30+ useState hooks, limited rendering (plain text only), and no dialog system. The new TUI is decomposed into focused components, contexts, and hooks with rich rendering throughout. ### Architecture ``` run-interactive.ts (runtime bridge) | | callbacks: onSubmit, onAbort, onModelChange, onModeChange, ... v index.tsx (OpenTUI renderer) | v root.tsx (provider tree + view router + global keyboard) | +-- DialogProvider Modal dialogs (model picker, tool approval, settings, etc.) +-- SessionProvider Chat entries, running state, mode, usage tracking +-- EventBridgeProvider Subscribes to SDK agent events, forwards to session | +-- View Router +-- HomeView Welcome screen with animated robot + centered input +-- ChatView Scrollbox message list + input bar + status bar +-- OnboardingView First-run provider/model setup wizard +-- ConfigView Settings browser (dialog) +-- HistoryView Session history with resume (dialog) ``` The TUI never talks to the SDK directly. All communication flows through callback props defined in `TuiProps`. The runtime bridge (`run-interactive.ts`) owns session lifecycle, event wiring, and state that persists across session restarts. ### What's New Core rendering: - Streaming markdown for assistant responses (`<markdown>` element) - Unified diffs with syntax highlighting for file edits (`<diff>` element) - Syntax-highlighted code for file reads (`<code>` element) - Expandable/collapsible tool output sections - Scrollable chat with auto-scroll pinning during streaming - Mouse-tracked animated robot on the home screen Dialog system (`@opentui-ui/dialog`): - Model selector with search, thinking level picker, and provider switching - Cline-specific model picker with recommended/free tiers - Tool approval dialog (approve/reject/always-approve per tool) - Ask question dialog (agent asks user for input mid-run) - Config/settings browser with interactive toggles - Session history browser with message preview and resume - Help overlay with all keyboard shortcuts and commands - Provider picker with OAuth login and API key entry - Device code auth flow for Cline provider Input and navigation: - Autocomplete dropdown for `/` slash commands and `@` file mentions - Input history (up/down arrow through previous prompts) - Message queuing (Enter during a running turn queues the message) - Steer messages (Ctrl+S sends guidance to a running turn) - Text selection with copy-to-clipboard (OSC52) Session management: - `/history` to browse and resume past sessions - `/compact` for manual context window compaction - `/clear` to reset conversation - `/model` to switch models mid-conversation (preserves chat history) - `/help` with full keyboard shortcut and command reference - `/settings` for interactive config browser Plan/Act mode: - Tab toggles between plan and act mode with accent color change (yellow/cyan) - `switch_to_act_mode` tool lets the agent transition from plan to act mid-session - System prompt and tools are rebuilt on mode switch, conversation history preserved Onboarding: - First-run wizard detects if no provider is configured - Step-by-step provider selection, authentication (OAuth or API key), model selection - Thinking level configuration for supported models - Results applied to runtime config immediately ### Interactive Setup Wizards Three new top-level CLI commands that walk users through complex setup flows interactively, so they don't have to construct long flag-heavy commands by hand: `clite connect` - Connector setup for messaging platforms (Telegram, Slack, Discord, Google Chat, WhatsApp, Linear). Walks through bot token entry, platform-specific options, and launches the bridge. `clite schedule` - Scheduled run creation. Walks through cron expression (with presets like "weekdays at 9am"), prompt, workspace, provider/model selection, iteration limits, and timeout. `clite mcp` - MCP server management. Lists configured servers, add new ones (stdio or SSE), edit existing config, remove servers, and test connectivity. ### What Got Removed - `interactive-tui.ts` (1,314 lines) and all old Ink components (ChatMessage, ConfigView, InputBox, MentionMenu, SlashMenu, StatusBar, WelcomeView) - `run-interactive-opentui.ts` (merged into `run-interactive.ts`) The old Ink `HistoryListView` component is preserved at `commands/history-list-view.ts` because the standalone `clite history` command still uses Ink for its interactive picker. This is separate from the main TUI. ### Runtime Changes - Shebang changed from `#!/usr/bin/env node` to `#!/usr/bin/env bun` (required because OpenTUI uses `bun:ffi`) - `package.json` bin entry changed from `dist/index.js` to `src/index.ts` for `bun link` dev workflow - Minor SDK changes: `hookPath` added to `RpcSessionRow`, `toolTimeouts` config support, `resolveSystemPrompt` export ### Documentation - `DEVELOPMENT.md`: Full development guide covering prerequisites (Bun, Zig, Node), first-time setup, monorepo structure, tech stack, TUI architecture walkthrough, and common dev tasks - `DISTRIBUTION.md`: Plan for publishing compiled binaries to npm (platform-specific packages, binary resolver, postinstall caching, CI pipeline). Uses OpenCode's distribution model as reference. ### Testing Locally ```bash # Install prerequisites curl -fsSL https://bun.sh/install | bash brew install zig # macOS. For Linux: snap install zig --classic # Clone and checkout git clone <repo-url> cd cline-sdk-wip git checkout saoudrizwan/cli-tui-opentui bun install # Build SDK packages (required for workspace package resolution) bun run build:sdk # Link globally cd apps/cli bun link # Run from anywhere clite ``` Or skip the build/link and run directly from source: ```bash cd apps/cli bun run dev ``` To test onboarding flow with a fresh config: `clite --config /tmp/cline-test` --------- Co-authored-by: abeatrix <beatrix@cline.bot>
50 lines
1.3 KiB
TypeScript
50 lines
1.3 KiB
TypeScript
export interface BuildOptions {
|
|
single: boolean;
|
|
skipInstall: boolean;
|
|
skipSdkBuild: boolean;
|
|
installNativeVariants: boolean;
|
|
}
|
|
|
|
export function parseBuildOptions(args: readonly string[]): BuildOptions {
|
|
return {
|
|
single: args.includes("--single"),
|
|
skipInstall: args.includes("--skip-install"),
|
|
skipSdkBuild: args.includes("--skip-sdk-build"),
|
|
installNativeVariants: args.includes("--install-native-variants"),
|
|
};
|
|
}
|
|
|
|
export function shouldInstallNativeVariants(input: {
|
|
options: BuildOptions;
|
|
opentuiVersion: string | undefined;
|
|
}): boolean {
|
|
return Boolean(
|
|
input.opentuiVersion &&
|
|
input.options.installNativeVariants &&
|
|
!input.options.skipInstall,
|
|
);
|
|
}
|
|
|
|
export function validateBuildOptions(input: {
|
|
options: BuildOptions;
|
|
opentuiVersion: string | undefined;
|
|
targetCount: number;
|
|
}): string | undefined {
|
|
if (input.targetCount === 0) {
|
|
return "No matching targets for this platform.";
|
|
}
|
|
if (
|
|
input.opentuiVersion &&
|
|
!input.options.single &&
|
|
!input.options.skipInstall &&
|
|
!input.options.installNativeVariants
|
|
) {
|
|
return [
|
|
"Cross-platform OpenTUI builds require native package variants.",
|
|
"Pass --install-native-variants to allow the build script to run bun install for all OpenTUI native packages.",
|
|
"Pass --skip-install only when those packages are already installed.",
|
|
].join("\n");
|
|
}
|
|
return undefined;
|
|
}
|