Compare commits

..
Author SHA1 Message Date
Max Paulus 🥪 11e0d45e45 remove claude bias 2026-05-04 12:30:17 -07:00
Max Paulus 🥪 f7210a4807 remove claude bias when reach mistake limit 2026-05-04 12:07:40 -07:00
Max Paulus 🥪 914527804c remove reference to restore session 2026-05-04 11:33:21 -07:00
Max Paulus 🥪 e37e91e4c5 remove references to sdk-session-factory 2026-05-04 11:33:21 -07:00
Max Paulus 🥪 823bfb1f60 fix subagent output 2026-05-04 11:33:21 -07:00
Max Paulus 🥪 41e80d236b add completion_result to last message when translating from sdk messages to cline messages 2026-05-04 11:33:21 -07:00
Max Paulus 🥪 f8cf469178 remove session-factory 2026-05-04 11:33:21 -07:00
Max Paulus 🥪 240a089e5d fix delete all and export buttons 2026-05-04 11:33:21 -07:00
Max Paulus 🥪 73c0881024 add toggle task favorite functionality 2026-05-04 11:33:21 -07:00
Max Paulus 🥪 c9206d90f1 rename sessionManager to sdkHost 2026-05-04 11:33:20 -07:00
Max Paulus 🥪 3fe42ab80d fix enable thinking toggle saving wrong model 2026-05-04 11:33:20 -07:00
Max Paulus 🥪 c5cb747bfa fix mcp auto approve settings 2026-05-04 11:33:20 -07:00
Max Paulus 🥪 4a7fb75dec update claude.md and .clinerules files
- remove stale info from .clinerules
2026-05-04 11:33:20 -07:00
Max Paulus 🥪 8ebc816489 add migration functionality so user can see old cline messages
- upon first loading an old conversation, we convert the format to new
sdk format and save it to sdk persistence layer
2026-05-04 11:33:20 -07:00
Dominic Cooney c108c5abe6 Remove Lazy Teammate Mode easter egg
Delete the April Fools' day feature including:
- Lazy teammate rules prompt (lazy-teammate-rules.ts)
- ClineLogoTired SVG component
- lazyTeammateModeEnabled setting from state keys, ExtensionMessage,
  controller state, settings update handler, webview context, and
  feature settings UI
- Proto fields marked as reserved (Settings #183, UpdateSettingsRequest #43)
2026-05-04 11:33:20 -07:00
Dominic Cooney f8ad3860c2 Set SHELL correctly in background shells. 2026-05-04 11:33:20 -07:00
Dominic Cooney ba342862a4 refactor: don't close terminals on profile switch, just key by effective shell
Instead of aggressively closing idle terminals and warning about busy
ones when the terminal profile changes, we now simply update the setting.
Existing terminals stay open and remain eligible for reuse if the user
switches back. New terminals use the new profile, and getOrCreateTerminal()
skips terminals with a different effective shell during reuse matching.

- Simplified setDefaultTerminalProfile() to void return
- Removed handleTerminalProfileChange() (dead code)
- Removed terminal close/warn notifications from updateSettings.ts
  and updateSettingsCli.ts
- Cleaned up unused imports
2026-05-04 11:33:19 -07:00
Dominic Cooney 9e640450c0 fix: compare effective shell paths for terminal reuse and profile switching
Previously, terminal matching compared raw shellPath values directly:
- 'default' profile terminals had shellPath=undefined
- 'zsh' profile terminals had shellPath='/bin/zsh'
These never matched, even though on macOS they resolve to the same shell.

Now effectiveShellPath() resolves undefined (default) to the actual
default shell via getShell(), so switching between 'zsh' and 'default'
on macOS won't needlessly close compatible terminals, and terminal reuse
correctly matches terminals running the same effective shell.
2026-05-04 11:33:19 -07:00
Dominic Cooney 6c8f9e4493 fix: set $SHELL env var to match selected terminal profile
When a non-default shell profile is selected (e.g. bash), the terminal
was spawning the correct shell binary via shellPath but inheriting
$SHELL from the parent process (VSCode extension host), which still
pointed to the user's login shell (e.g. /bin/zsh). This caused child
processes that read $SHELL (make, npm scripts, etc.) to see the wrong
shell.

Now VscodeTerminalRegistry.createTerminal() sets SHELL in the terminal's
env to match the shellPath when a specific profile is selected.
2026-05-04 11:33:19 -07:00
Dominic Cooney 42cdcc458d fix: propagate runtime terminal settings changes to live VscodeTerminalManager
When the user changes terminal settings (shell profile, timeout, reuse,
output limit) while terminals are open, the changes now propagate
immediately to the live VscodeTerminalManager instance via
controller.terminalManager (a public getter on SdkController).

Previously, updateSettings.ts and updateSettingsCli.ts tried to access
controller.task.terminalManager which doesn't exist in the SDK controller.
Now they use controller.terminalManager which is the shared instance
created lazily in SdkController.
2026-05-04 11:33:19 -07:00
Dominic Cooney 0aaf43d4cf feat: wire terminal settings (shell profile, timeout, reuse, output limit) into VscodeTerminalManager
When the lazy VscodeTerminalManager is first created, applyTerminalSettings()
reads from StateManager and configures:
- defaultTerminalProfile (shell choice: default/zsh/bash/etc.)
- shellIntegrationTimeout
- terminalReuseEnabled
- terminalOutputLineLimit

Also exposes a public terminalManager getter so updateSettings handlers
can apply runtime changes to the existing instance.
2026-05-04 11:33:19 -07:00
Dominic Cooney f51c8f6a68 feat: add custom run_commands tool with foreground/background terminal support
Introduces a VSCode-specific run_commands tool that replaces the SDK's
built-in version. This is an IDE-level feature built on top of the SDK,
not integrated into the SDK itself.

The tool supports two execution modes, switchable dynamically:
- Foreground (vscodeTerminal): Uses VscodeTerminalManager for visible
  VS Code terminals with shell integration, real-time output streaming,
  and 'Proceed While Running' support.
- Background (backgroundExec): Delegates to the SDK's createBashExecutor
  for headless child_process.spawn execution with configurable timeout.

Wiring:
- SdkController creates a lazy VscodeTerminalManager
- SdkSessionFactory passes getTerminalManager to VscodeSessionHost
- VscodeSessionHost suppresses SDK's built-in run_commands (bash: undefined)
- createVscodeExtraTools includes the custom run_commands tool

Design doc: sdk-migration/FOREGROUND-TERMINAL-DESIGN.md
2026-05-04 11:33:19 -07:00
Dominic Cooney 2176fbf1a5 fix(ENG-1885): deduplicate tool_result blocks on session resume with parallel tool calls
Root cause: initial-message-sanitizer only checked the immediately next
user message (i+1) for matching tool results. The SDK persists each
parallel tool result as a separate user message, so for N parallel tool
calls only 1/N was found and (N-1) placeholders were created. The
remaining (N-1) real results were left as separate messages. On merge,
this produced duplicate tool_result blocks causing Anthropic API errors.

Fix:
- Scan ALL consecutive user messages after the assistant to collect tool
  results, then consolidate into a single message via splice()
- Add defensive dedup in convertToOpenAiMessages as a safety net

Tests: 12 pass (5 sanitizer + 7 openai-format conversion)
2026-05-04 11:33:19 -07:00
Max Paulus 🥪 4c1706e6fa fix user message format 2026-05-04 11:33:19 -07:00
Max Paulus 🥪 9d72dc6661 fix tool rendering again 2026-05-04 11:33:18 -07:00
Max Paulus 🥪 78cdc55a02 remove lots of old task history code 2026-05-04 11:33:18 -07:00
Max Paulus 🥪 614a09807e remove acp from old cli and clineagent
- acp mode and clineagent is in sdk-wip now
- this will make it easier to clean up the sdkcontroller
2026-05-04 11:33:18 -07:00
Max Paulus 🥪 75ba27ea58 use sessionhost instead of other types 2026-05-04 11:33:18 -07:00
Max Paulus 🥪 0732118f89 fix perf issue 2026-05-04 11:33:18 -07:00
Max Paulus 🥪 1e36127ca3 fix clear task not actually updating the UI 2026-05-04 11:33:18 -07:00
Max Paulus 🥪 e1952e0698 use sdk for getTaskWithId 2026-05-04 11:33:18 -07:00
Max Paulus 🥪 9f3804ad67 listTasks uses sdk now 2026-05-04 11:33:17 -07:00
Mikołaj Kondratek 5294f2d8fd Update @clinebot modules to 0.0.37 2026-05-04 11:33:17 -07:00
Dominic Cooney 40a1e7e36e fix(ENG-1887): stuck "Thinking" after attempt_completion
The ask:"completion_result" message was emitted at content_end (when the
attempt_completion tool finished), but a usage event with
say:"api_req_started" always arrived between content_end and done,
becoming the last raw message. The webview uses the last raw message to
determine UI state, so it showed "Thinking..." instead of the completion
UI with the "Start New Task" button.

Fix: defer the ask:"completion_result" emission from content_end to the
done handler, which always runs after the usage event. The done handler
now unconditionally emits ask:"completion_result" (previously it was
conditional on !wasAttemptCompletionSeen). This ensures the ask is
always the final message regardless of whether attempt_completion was
used.
2026-05-04 11:33:17 -07:00
Dominic Cooney 7667780bc0 Add pending prompts to be compatible with SDK post cline/sdk-wip#263 2026-05-04 11:33:17 -07:00
Dominic Cooney bdcb733442 Implement preferredLanguage support. 2026-05-04 11:33:17 -07:00
Dominic Cooney b35def73fc fix: allow debug harness browser capture opt-out 2026-05-04 11:33:17 -07:00
Dominic Cooney 32ff768206 Delete a bunch of now-dead code. 2026-05-04 11:33:17 -07:00
Max Paulus 🥪 8f48efbe73 fixup! Remove Focus Chain from settings UI and state plumbing 2026-05-04 11:33:16 -07:00
Max Paulus 🥪 4c4f0079df feat: translate SDK spawn_agent events into rich subagent UI
The SDK spawn_agent tool was rendering as a generic tool row in the
webview. This translates its events into the ClineMessage types that
SubagentStatusRow already handles:

- content_start → say:"use_subagents" (prompts list with stable ts)
- content_update → say:"subagent" (running progress, partial=true)
- content_end → say:"subagent" (completed/failed) + say:"subagent_usage"

Also filters sub-agent agent_events by parentAgentId so only the root
agent produces ClineMessages. Without this, every sub-agent tool call,
text output, iteration, and usage event flooded the main chat.

No webview/CLI changes needed — existing SubagentStatusRow and
messageUtils filtering handle all the emitted message types.
2026-05-04 11:33:16 -07:00
Max Paulus 🥪 d30a4ae96e Remove strict plan mode setting
Remove the strictPlanModeEnabled feature toggle from the entire codebase.
The setting is not used by the SDK controller path and plan mode behavior
is now handled via system prompt instructions and the switch_to_act_mode
tool in the SDK layer.

Changes:
- Remove state key, ExtensionMessage field, and proto fields (reserved)
- Remove ToolExecutor plan-mode restriction logic (PLAN_MODE_RESTRICTED_TOOLS,
  isPlanModeToolRestricted, and the enforcement block)
- Remove from TaskConfig interface, validation, and TASK_CONFIG_KEYS
- Remove settings toggle from webview FeatureSettingsSection and CLI
- Remove from getStateToPostToWebview and updateSettings handlers
- Remove from ExtensionStateContext defaults and test mocks
- Regenerate proto types
2026-05-04 11:33:16 -07:00
Max Paulus 🥪 67699af03f Remove Focus Chain from settings UI and state plumbing
Remove the Focus Chain feature toggle from the settings view and
all associated state wiring:

- Settings UI: Remove Focus Chain toggle, reminder interval slider,
  and nested-key handling that was only used by focus chain
- ChatView: Remove focus chain checklist state, progress message
  memo, and placeholder memo
- TaskSection/TaskHeader: Remove focus chain props and FocusChain
  component rendering
- ExtensionStateContext: Remove focus chain settings default and
  currentFocusChainChecklist from state provider
- ExtensionMessage: Remove focusChainSettings and
  currentFocusChainChecklist from shared ExtensionState type
- getStateToPostToWebview: Stop sending focus chain state to webview
- updateSettings/updateSettingsCli: Remove focus chain settings
  update handlers and telemetry toggle tracking
2026-05-04 11:33:16 -07:00
Max Paulus 🥪 2672de7deb fix: read subagentsEnabled from StateManager so Settings toggle is respected
buildSessionConfig() only read subagentsEnabled from taskSettings (per-task
overrides), which is undefined for normal chat flow. This caused
enableSpawnAgent to always be false, making the SDK hide the spawn_agent
tool and causing the model to fall back to the skills tool.

Now reads the global subagentsEnabled setting from StateManager as the
default, with taskSettings still able to override it.
2026-05-04 11:33:16 -07:00
Max Paulus 🥪 f08b61323f add useBrowser auto approve back to support web fetch auto approve settings 2026-05-04 11:33:16 -07:00
Max Paulus 🥪 ae0b33ab2b remove browser use from cline
- we are removing browser use from cline as part of the migration to the
cline sdk. we may add it back later
2026-05-04 11:33:16 -07:00
Max Paulus 🥪 2054203791 fix: re-export AuthService from SDK so remote config gets auth tokens
The remote config system (fetch.ts, utils.ts) and other core modules
import AuthService from src/services/auth/AuthService.ts. In the SDK
migration, this was still the classic AuthService class with its own
separate singleton — completely disconnected from the SDK AuthService
that SdkController initializes with actual credentials.

This caused fetchRemoteConfig() to silently fail because:
- AuthService.getInstance().getAuthToken() returned null (no credentials)
- AuthService.getInstance().getActiveOrganizationId() returned null
- ClineAccountService.fetchUserRemoteConfig() failed silently

Fix: Replace src/services/auth/AuthService.ts with a re-export barrel
that points to src/sdk/auth-service.ts, matching the pattern used for
Controller (src/core/controller/index.ts → src/sdk/SdkController.ts).
This ensures all modules that import AuthService get the SDK singleton
which has the actual auth state.

Also stub out AuthServiceMock.ts which extended the classic AuthService
using protected members that no longer exist in the SDK version. The
mock was only used via dynamic require in E2E test mode and is not
referenced by any production code.
2026-05-04 11:33:16 -07:00
Max Paulus 🥪 9ccdc356bb feat: port remote config fetching to SdkController
The SdkController was missing all remote config support that the classic
Controller provides for enterprise customers (org-level policy enforcement,
MCP server management, provider lockdown, OpenTelemetry, etc.).

Changes:
- Add startRemoteConfigTimer() that fetches immediately then every 1 hour
- Chain timer start after auth restore in constructor
- Call fetchRemoteConfig() on login (handleAuthCallback)
- Fire-and-forget fetchRemoteConfig() at task start (initTask)
- Call clearRemoteConfig() on sign-out (handleSignOut)
- Clear interval timer in dispose() to prevent memory leaks
- Verify refreshRemoteConfig gRPC handler is already wired correctly
2026-05-04 11:33:15 -07:00
Max Paulus 🥪 c404a9d1d2 fix: handle bare array/string input in run_commands rendering (ENG-1867)
The SDK run_commands tool can pass input as a bare string[] (e.g.
["biome check --write src/"]) instead of wrapped { commands: [...] }.
parseToolInput() returns undefined for arrays, so commandText ended up
as "", rendering an empty shell fence in the command approval UI.

Extend both content_start and content_end handlers to detect bare
arrays and bare strings before falling through to parseToolInput(),
mirroring the fix already applied for search_codebase (S6-47).

Adds 6 unit tests covering bare array, multi-element array, bare
string, content_end round-trip, and wrapped-object regression.
2026-05-04 11:33:15 -07:00
Max Paulus 🥪 0bb8abb542 fix: implement exportTaskWithId and fix openDiskConversationHistory
- Replace exportTaskWithId stub in SdkController with real implementation
  that opens the task directory in the file manager (matching classic behavior)
- Fix openDiskConversationHistory to await openFileIntegration and move
  path construction inside the null check

Closes ENG-1828
2026-05-04 11:33:15 -07:00
Max Paulus 🥪 79b70f4652 fix: abort SDK session on mistake_limit_reached so UI buttons update correctly
After consecutive tool failures hitting maxConsecutiveMistakes (default 3),
the UI buttons stayed as Approve/Reject instead of updating to
"Proceed Anyways"/"Start New Task".

Root cause: In the SDK path, trackToolErrors() emitted the
mistake_limit_reached message but the SDK agent continued running,
immediately appending more messages. The mistake_limit_reached message
was never the last message, so the webview never showed correct buttons.

Fix: When the mistake limit is reached, set result.turnComplete = true
and abort the SDK session so the agent stops producing events. The
existing askResponse -> tryResumeSessionFromTask flow handles resumption
when the user clicks "Proceed Anyways".

Closes ENG-1874
2026-05-04 11:33:15 -07:00
Max Paulus 🥪 1cd9b75b09 fix: reuse timestamp for hook status messages to update in-place (ENG-1871) 2026-05-04 11:33:15 -07:00
Max Paulus 🥪 c5197a4f49 fix: emit mistake_limit_reached in SDK path after consecutive tool failures
The SDK execution path was missing consecutive tool error tracking that
the classic Task class provides via consecutiveMistakeCount. When tools
failed repeatedly, the UI buttons stayed showing "Approve"/"Reject"
instead of updating to "Proceed Anyways"/"Start New Task".

This change:
1. Adds toolError/toolSuccess flags to TranslationResult so the message
   translator signals when tool calls succeed or fail (content_end events
   with/without event.error)
2. Adds consecutiveToolErrorCount tracking to SdkSessionEventCoordinator
3. When the count reaches maxConsecutiveMistakes (default: 3), emits an
   ask="mistake_limit_reached" ClineMessage, which the webview already
   handles correctly to show the right buttons
4. Resets the counter on tool success or after emitting the limit message

Fixes ENG-1874
2026-05-04 11:33:15 -07:00
Max Paulus 🥪 6d02eacfc2 Fix SDK chat cost display for free Cline models 2026-05-04 11:33:15 -07:00
Max Paulus 🥪 1cb7cb8e76 bump sdk version 2026-05-04 11:33:14 -07:00
Max Paulus 🥪 f59768aea0 fix(sdk): poll feature flags during auth updates 2026-05-04 11:33:14 -07:00
Max Paulus 🥪 316a7f9f9e fix: sync OpenAI Codex OAuth credentials
Bridge SDK provider settings with the legacy Codex OAuth manager so ChatGPT Subscription sign-in updates settings state and inference can read the stored token. Clear both stores on sign-out and refresh incomplete SDK-stored credentials.
2026-05-04 11:33:14 -07:00
Max Paulus 🥪 157df2c482 break sdk controller down even further into smaller components 2026-05-04 11:33:14 -07:00
Max Paulus 🥪 ba7b7d984c split sdk controller even further
- made taskControl
2026-05-04 11:33:14 -07:00
Max Paulus 🥪 6719a28323 Extract SDK MCP and followup coordinators 2026-05-04 11:33:14 -07:00
Max Paulus 🥪 648b20667e Refactor SDK controller coordinators 2026-05-04 11:33:14 -07:00
cline 195554f034 fix(sdk): togglePlanActMode returns false to preserve pending input
The webview's onModeToggle handler in ChatTextArea.tsx treats the
returned boolean as 'did I consume your pending input' and calls
setInputValue('') when true. The SDK flow rebuilds the session
without consuming chatContent, so returning true incorrectly wiped
any text the user had typed before toggling.

Match the classic extension's semantic: only return true when the
chatContent was actually consumed as a plan-response message. The
SDK flow never does this, so both success branches now return false
(same-mode no-op already returned false).

ClineMessages and mode indicator continue to update correctly because:
- rebuildSessionForMode keeps this.task and its messageStateHandler
  alive across the session rebuild, so clineMessages are preserved
- getStateToPostToWebview() reads mode from stateManager which is
  updated before postStateToWebview() is called
- oldUnsubscribe() is called before old session stop/dispose, so no
  stale 'ended' events reach the gRPC bridge after rebuild

Adds 7 unit tests in src/sdk/toggle-plan-act-mode.test.ts covering
PLAN/ACT enum decode, chatContent pass-through, boolean round-trip,
invalid enum handling, and error propagation.
2026-05-04 11:33:13 -07:00
Max Paulus 🥪 354de542f0 fix(sdk): rebuild session with mode-specific provider/model on plan/act toggle
rebuildSessionForMode() now logs the resolved provider/model/apiKey from
buildSessionConfig({ cwd, mode: newMode }) so it is visible that the
mode-specific provider and model were picked up (planModeApiProvider /
actModeApiProvider, planModeApiModelId / actModeApiModelId, etc.).

Also adds an auth pre-check mirroring the one in initTask(): if the new
mode resolves to the cline provider without an auth token, emit the
standard auth error message sequence (say:task, say:api_req_started,
ask:api_req_failed) so the webview renders the "Sign in to Cline" button
via ErrorRow instead of crashing on the first SDK API call.

The pre-check runs BEFORE tearing down the old session, so the user
keeps their chat history and can retry after signing in or toggle back
to the original mode.
2026-05-04 11:33:13 -07:00
cline 23972fb4ce feat(sdk): rebuild session on plan/act mode toggle with cancel-style teardown
Replaces the old togglePlanActMode() behavior (which just cancelled the task and left the user to start over) with a full session rebuild that preserves conversation history while swapping in the new mode's system prompt and tools. Mirrors the CLI's onModeChange callback in apps/cli/src/runtime/run-interactive.ts.

Changes in src/sdk/SdkController.ts:

- Add rebuildSessionForMode(newMode): persists mode to global state, reads conversation history from the active session via loadInitialMessages(), tears down the old VscodeSessionHost (unsubscribe + stop + dispose), builds a fresh CoreSessionConfig for the new mode (new system prompt via buildSessionConfig, switch_to_act_mode re-injected for plan), preserves the task/session ID, and starts a new session with initialMessages. Task proxy stays alive so currentTaskItem and clineMessages remain stable across the rebuild.

- Implement applyPendingModeChange(): was a TODO stub; now reads pendingModeChange, clears it, and delegates to rebuildSessionForMode. This is the path the switch_to_act_mode tool uses when the model programmatically transitions plan -> act.

- Rewrite togglePlanActMode(): if activeSession exists, call rebuildSessionForMode; otherwise persist mode and refresh state. No more cancelTask() followed by the user manually restarting.

- Wire applyPendingModeChange into handleSessionEvent: when turnComplete/sessionEnded flips isRunning=false, check pendingModeChange and apply it fire-and-forget. Complements the existing check in fireAndForgetSend so we catch the mode change via either the event stream or the send promise resolution.

Cancel-style teardown on mid-turn toggle (matches classic Cline UX of "switch modes cancels the current task"):

- Reject any pendingToolApprovalResolve with { approved: false, reason: "Mode changed" } so the SDK tool executor unwinds cleanly

- Clear pendingAskResolve (no meaningful answer to give the dying session)

- Cancel the debounced save timer so it does not race with the finalization we write below

- await oldManager.abort(oldSessionId) (same call cancelTask uses) so the AbortSignal propagates through the tool executor: running shell commands get SIGTERM, in-flight LLM streams terminate

- Finalize in-memory messages via finalizeMessagesForSave() to strip partial: true flags and stamp the open api_req_started with cancelReason: "user_cancelled", re-add via messageStateHandler.addMessages() which updates by ts in-place, and persist synchronously via saveClineMessages so on-disk history reflects a cleanly cancelled turn

- Set activeSession.isRunning=false before teardown so late events from the dying session cannot flip state on the new session

Tests: npx tsc --noEmit and npx biome lint both pass clean.
2026-05-04 11:33:13 -07:00
Max Paulus 🥪 8dd91e697a feat(sdk): inject switch_to_act_mode tool in plan-mode sessions
Mirrors the CLI's plan -> act flow (apps/cli/src/runtime/run-interactive.ts)
by adding a programmatic mode-switch tool to SDK sessions started in plan
mode. When the model calls switch_to_act_mode after the user agrees to
the plan, the tool sets a pendingModeChange flag and returns a success
message so the current turn completes normally. After sessionManager.send()
returns, applyPendingModeChange() is invoked as the plumbing entry point
for the full session-rebuild flow (to be implemented in Task 4).

Changes to src/sdk/SdkController.ts:
- Import createTool and Tool type from @clinebot/shared
- Add pendingModeChange: Mode | null field
- Add createSwitchToActModeTool() private method matching the CLI's
  tool definition (name, description, success message, timeouts)
- Add injectModeExtraTools() helper and wire it into all four
  session-creation code paths: initTask, reinitExistingTaskFromId,
  resumeSessionFromTask, and restartSessionForMcpTools
- Add applyPendingModeChange() stub that reads and clears the flag
  (Task 4 will fill in the full session rebuild)
- Invoke applyPendingModeChange() from fireAndForgetSend's .then()
  after the turn completes (skipped for queue/steer deliveries)

CoreSessionConfig.mode is already set correctly in buildSessionConfig(),
so the SDK's plan preset (which disables editor tools) continues to be
selected -- our injected tool is merged with that preset.

Verification: tsc --noEmit passes with 0 errors; SDK vitest suite
shows 143 passing tests (same as baseline).
2026-05-04 11:33:13 -07:00
Max Paulus 🥪 cdc11e818b feat(sdk): append plan-mode instructions to system prompt in VSCode
Mirrors the CLI plan-mode guardrails (apps/cli/src/runtime/prompt.ts)
so plan mode in VSCode tells the model to explore/analyze/plan and NOT
implement. Previously buildClineSystemPrompt did not emit these
instructions, so plan mode in VSCode had weaker guardrails than the CLI.
2026-05-04 11:33:13 -07:00
Max Paulus 🥪 4228755175 feat: wire UserPromptSubmit and TaskCancel hooks via SDK AgentExtension plugin
Implement the remaining two feasible Cline hooks as SDK AgentExtension
plugins, since AgentHooks lacks the right hook points for these:

- UserPromptSubmit → onInput: fires before the prompt enters the agent
  loop, supports cancel and contextModification
- TaskCancel → onSessionShutdown: fires only on user-initiated
  cancellation (reason === session_stop), fire-and-forget

Changes:
- hooks-adapter.ts: add buildHookExtensions() returning AgentExtension[]
  with one inline extension (cline-lifecycle-hooks) implementing onInput
  and onSessionShutdown callbacks
- SdkController.ts: add buildExtensionsWithEmitter() method and wire
  config.extensions at all 4 session creation sites (initTask,
  reinitExistingTaskFromId, resumeSessionFromTask,
  restartSessionForMcpTools)

The existing buildAgentHooks() for the 4 AgentHooks-based hooks
(TaskStart, PreToolUse, PostToolUse, TaskComplete) is untouched.
2026-05-04 11:33:13 -07:00
Max Paulus 🥪 19822719ad fix: show 'Sign in to Cline' button instead of raw SDK error when not logged in
When using the 'cline' provider without authentication, the SDK throws a
generic 'Missing API key' error that surfaces as a raw red error message
with an infinite 'Thinking...' spinner. The classic extension shows a
friendly login prompt with a 'Sign in to Cline' button instead.

Fix by adding a pre-check in initTask() that detects the cline provider
with no auth token and emits the same message sequence the classic
extension uses (say:task -> say:api_req_started -> ask:api_req_failed
with a serialized ClineError). The webview's ErrorRow already handles
this pattern and renders the sign-in UI.

Also updates catch blocks in fireAndForgetSend(), askResponse(), and
reinitExistingTaskFromId() to detect cline auth errors and emit the
proper auth UI instead of raw say:error messages.
2026-05-04 11:33:13 -07:00
Max Paulus 🥪 b02b240331 feat: emit hook_status ClineMessages from hooks-adapter for chatview visibility
The SDK invokes AgentHooks callbacks inline (not through onEvent), so the
message-translator case "hook" handler never fires for adapter hooks. This
means hooks run silently with no UI feedback.

Fix by emitting hook_status ClineMessages directly from the hooks-adapter
callbacks via a HookMessageEmitter callback provided by SdkController.

Changes to hooks-adapter.ts:
- Add HookMessageEmitter type and buildHookStatusMessage() helper
- Add optional emitHookMessage param to buildAgentHooks()
- In all 4 callbacks, check factory.hasHook() before emitting
- Emit running/completed/cancelled/failed status messages

Changes to SdkController.ts:
- Add buildHooksWithEmitter() that wires emitter to messageStateHandler,
  pushMessageToWebview, and debouncedSaveClineMessages
- Override config.hooks at all 4 buildSessionConfig() call sites
2026-05-04 11:33:12 -07:00
Max Paulus 🥪 92646795e1 feat(sdk): bridge Cline file-based hooks into SDK AgentHooks interface
Create src/sdk/hooks-adapter.ts that maps 4 Cline hooks to SDK
lifecycle callbacks:
- TaskStart → onSessionStart
- PreToolUse → onToolCallStart
- PostToolUse → onToolCallEnd
- TaskComplete → onRunEnd (gated on finishReason === completed)

Each callback dynamically checks hooksEnabled via StateManager so
toggling mid-session takes effect immediately. All callbacks are
fail-open (errors logged, never block the SDK).

Wire buildAgentHooks() into buildSessionConfig() in
cline-session-factory.ts so every new session gets hook callbacks.
2026-05-04 11:33:12 -07:00
Max Paulus 🥪 2b90bc8239 fix(sdk): execute attempt_completion command parameter instead of ignoring it
The attempt_completion extra tool defined a command parameter in its schema
but the execute function silently discarded it, wasting tokens.

Re-use the SDK built-in bash executor (via createDefaultExecutors) to run
the command when provided, and append its output to the completion result
returned to the model.

Changes:
- vscode-runtime-builder.ts: createAttemptCompletionTool now accepts cwd,
  lazily creates a bash executor, and executes the command parameter
- vscode-session-host.ts: passes input.config.cwd to createVscodeExtraTools

Closes S6-47
2026-05-04 11:33:12 -07:00
Max Paulus 🥪 b9eaa43bb5 fix(sdk): parse mcp tool calls
- mcp tool calls weren't properly translated to the right format for
viewing in the chatview. this fixes that
2026-05-04 11:33:12 -07:00
Max Paulus 🥪 6854c80f2d fix(sdk): use delivery: "queue" for follow-up messages during active turns (S6-26C)
When the user sends a follow-up message while the agent is mid-turn,
askResponse() now detects isRunning and passes delivery: "queue" to
the SDK send() call. The SDK enqueues the message and drains it after
the current turn completes, preventing "already in progress" errors.

Changes:
- fireAndForgetSend(): accept optional delivery param, skip isRunning
  reset when message was queued (turn didnt complete)
- askResponse(): capture wasAlreadyRunning before setting isRunning,
  compute delivery accordingly, skip translator reset for queued msgs
- handleSessionEvent(): log pending_prompts/pending_prompt_submitted
  events for visibility
2026-05-04 11:33:12 -07:00
Max Paulus 🥪 16c5d966b6 fix(sdk): include MCP tools in toolPolicies for approval enforcement
MCP tools were bypassing the approval flow because buildToolPolicies()
only covered built-in SDK tools. MCP tools registered as extra tools
with serverName__toolName names had no policy entries, so the SDK
defaulted them to autoApprove:true.

- Add MCP tool iteration in buildToolPolicies() using McpHub.getServers()
- Gate MCP tool auto-approve on both the global useMcp toggle and each
  tool's individual autoApprove flag
- Use serverName__toolName format matching the SDK's default name transform
- Remove unnecessary regex sanitization helper (sdkMcpToolName)
2026-05-04 11:33:12 -07:00
Max Paulus 🥪 481a5e5304 fix(sdk): translate auto-approval settings into SDK toolPolicies
The SDK defaults all tools to autoApprove:true when no toolPolicies
are provided. The user's auto-approval settings (readFiles, editFiles,
executeSafeCommands, etc.) were not being translated into SDK
toolPolicies, so requestToolApproval was never called.

- Add buildToolPolicies() that maps AutoApprovalSettings actions to
  SDK tool names with { autoApprove: boolean } policies
- Add toolPolicies option to VscodeSessionHostOptions, pass through
  to ClineCore.create()
- Read autoApprovalSettings from StateManager in startNewSession()
  and pass the derived toolPolicies to VscodeSessionHost.create()
2026-05-04 11:33:12 -07:00
Max Paulus 🥪 6390aa7ed2 feat(sdk): wire requestToolApproval callback for non-auto-approved tools
Implement the requestToolApproval callback so the SDK can request user
approval for non-auto-approved tools (S6-26 Part A).

- Export sdkToolToClineSayTool from message-translator.ts for reuse
- Add handleRequestToolApproval() private method to SdkController that
  converts SDK ToolApprovalRequest to ClineSayTool JSON, emits a
  ClineMessage with type:ask/ask:tool, and returns a Promise resolved
  when the user clicks Approve/Reject in the webview
- Add handleAskQuestion() private method (extracted from inline callback)
- Wire both callbacks into startNewSession() via VscodeSessionHost.create()
- Add pendingToolApprovalResolve field to SdkController, resolved in
  askResponse() by reading taskState.askResponse (yesButtonClicked=approve,
  noButtonClicked=deny)
- Clean up pendingToolApprovalResolve in cancelTask() and clearTask()
  to prevent Promise leaks
- Update PROBLEMS.md to mark Part A as fixed
2026-05-04 11:33:12 -07:00
Max Paulus 🥪 21d545e70a update package-lock 2026-05-04 11:33:11 -07:00
Max Paulus 🥪 df56a80d0c feat(S6-26B): wire SDK ask_question tool for follow-up questions
The SDK built-in ask_question tool was excluded from the agent tool list
because no askQuestion executor was provided. The agent could not ask
clarifying questions when encountering ambiguity.

Changes:
- vscode-session-host.ts: Add askQuestion option, pass defaultToolExecutors
  to ClineCore.create() so the SDK includes ask_question in the tool list
- SdkController.ts: Implement askQuestion executor that emits ClineMessage
  with ask:"followup" (reusing existing webview UI), stores a pending
  Promise resolver, and resolves it when askResponse() is called.
  cancelTask()/clearTask() clear pendingAskResolve to prevent leaks.
- message-translator.ts: Update comment to reflect new handling
- PROBLEMS.md: Mark S6-26 Part B as fixed with evidence
2026-05-04 11:33:11 -07:00
Max Paulus 🥪 71af35830c fix(S6-48): file edit diffs show deletions (red) not just additions (green)
The SDK editor tool provides old_text and new_text, but the message
translator stored raw new_text in content. DiffEditRow did not recognize
it as a diff format and fell through to a fallback treating every line
as an addition (all green, no red).

Three fixes:
1. message-translator.ts editor case: when both old_text and new_text
   are present, build a SEARCH/REPLACE diff in the format DiffEditRow
   expects.
2. message-translator.ts apply_patch case: also check the input field
   (SDK format) and populate both content and diff.
3. ChatRow.tsx: prefer tool.diff over tool.content when passing to
   DiffEditRow, and check for either in the guard condition.

7 new tests, 1 updated test. All 72 message-translator tests pass.
2026-05-04 11:33:11 -07:00
Max Paulus 🥪 a6057a4488 fix(S6-47): search tool group shows empty regex and "/" path
The SDK search_codebase tool input can be a bare array or string
(per SearchCodebaseUnionInputSchema), but parseToolInput() only
handled objects. This caused empty regex in the UI. Additionally,
the SDK has no path param for search, so the webview showed "/".

Changes:
- message-translator.ts: Handle bare array and string input formats
  for search_codebase in sdkToolToClineSayTool()
- ToolGroupRenderer.tsx: Show "codebase" instead of "/" when search
  path is empty; fix getActivityText to not require path for search
- RequestStartRow.tsx: Same empty-path fixes for consistency
- 8 new unit tests covering all SDK input formats and content_end
  preservation
2026-05-04 11:33:11 -07:00
Dominic Cooney 5e540269f9 fix: resolve @mentions in SDK path before sending to agent
The SDK migration removed the classic parseMentions() call that resolved
context mentions (@/file, @problems, @git-changes, @https://url, @hash)
into inline content. The SDK's own mention enricher only handles simple
@path mentions and fails with the webview's @/path format.

Add resolveContextMentions() to SdkController that calls parseMentions()
before sending text to the SDK in all three send paths: initTask(),
askResponse(), and resumeSessionFromTask().

Fixes: Context command not returning any response in chat
2026-05-04 11:33:11 -07:00
Dominic Cooney 8733c056c5 fix: Resume Task button not displayed after cancellation
Three issues fixed in SdkController:

1. Race condition: Late-arriving SDK 'done' events after cancelTask()
   produced completion_result messages that replaced the 'Resume Task'
   button with 'Start New Task'. Added a filter in handleSessionEvent()
   that suppresses these messages when isRunning === false.

2. Dead session: After cancellation, activeSession still existed but the
   SDK session was dead (aborted). Clicking 'Resume Task' tried to send()
   to the dead session causing 'session not found' error. Changed
   askResponse() to also check isRunning, routing cancelled sessions to
   resumeSessionFromTask() which creates a fresh SDK session.

3. Idle resume: resumeSessionFromTask() only generated a [TASK RESUMPTION]
   prompt when there were no initialMessages. After cancellation there ARE
   initialMessages (conversation history), so the prompt was empty and the
   session sat idle. Changed to always send a resumption prompt when the
   user didn't type anything, matching classic extension behavior.
2026-05-04 11:33:11 -07:00
Dominic Cooney e04ddf631f Note tool impedance mistmatches in PROBLEMS. 2026-05-04 11:33:11 -07:00
Dominic Cooney 73c5528e44 Debug harness improvements for OAuth. 2026-05-04 11:33:10 -07:00
Dominic Cooney c4adbbffb6 rebase: remove vscodeTerminalExecutionMode override (main PR #10196)
Main's PR #10196 (Remove foreground terminal, commit 1862f1595) removed
the vscodeTerminalExecutionMode field from ExtensionState. The webview
now unconditionally renders commands as background-exec (ChatRow.tsx
hardcodes isBackgroundExec={true}), so the SDK-adapter override in
getStateToPostToWebview() is both a type error and dead code.

Removes the override and documents why it's no longer needed for any
future archaeology.
2026-05-04 11:33:10 -07:00
Max Paulus 🥪 d61fde394b style: lint-staged formatting fixes for S6-39/S6-40 commit 2026-05-04 11:33:10 -07:00
Max Paulus 🥪 ce5a255c0c fix: render URL and skill name in webFetch/useSkill tool calls (S6-39, S6-40)
S6-39: SDK fetch_web_content uses { requests: [{ url, prompt }] } but
sdkToolToClineSayTool() only checked for a top-level url field. Added
fallback to extract URL from requests[0].url.

S6-40: SDK skills tool uses { skill: "name" } but sdkToolToClineSayTool()
only checked skill_name and name fields. Added skill to the fallback chain.

7 new unit tests covering both SDK and classic input formats.
2026-05-04 11:33:10 -07:00
Max Paulus 🥪 f8ba599583 fix: suppress AbortError on task cancel and emit resume_task ask (S6-46, S6-34)
When the user cancels a running task, AbortController.abort() in the SDK
throws an AbortError that propagated unhandled to the VSCode developer
console. Three fixes:

1. VscodeSessionHost.abort(): wrap inner.abort() in try/catch that
   suppresses AbortError (expected) and re-throws others.

2. SdkController.cancelTask(): narrow try/catch to only the abort()
   call, suppress AbortError at debug level, and always proceed with
   cleanup. Emit ask: "resume_task" instead of say: "info" so the
   webview shows the Resume task button (fixes S6-34).

3. SdkController.fireAndForgetSend(): detect AbortError in .catch()
   and return early without emitting error events to the UI.
2026-05-04 11:33:10 -07:00
Max Paulus 🥪 0d39c35441 fix(S6-44): resolve RangeError: Invalid string length on task start
Two bugs combined to cause unbounded stdout accumulation in the SDK
file indexer when starting a new task:

1. SdkController used process.cwd() instead of getCwd() for workspace
   resolution. In VSCode extension host, process.cwd() returns the
   VSCode installation dir, not the workspace folder, causing rg to
   recurse enormous directory trees.

2. SDK file-indexer.ts rg command only excluded .git but not
   node_modules/dist/build/etc (which walkDir fallback did exclude).
   This is fixed in the linked SDK repo separately.

Fixes:
- Replace all process.cwd() calls in SdkController.ts and
  cline-session-factory.ts with getCwd() which resolves the actual
  workspace folder via HostProvider.workspace.getWorkspacePaths()
- Document fix in PROBLEMS.md as S6-44
2026-05-04 11:33:10 -07:00
Max Paulus 🥪 1fc12662c5 fix(sdk): format command output as raw text instead of JSON (S6-41)
The SDK run_commands tool returns ToolOperationResult[] with structured
output ({query, result, success, error?}). The message translator was
falling through to JSON.stringify() for non-string output, causing raw
JSON like [{"query":"ls","result":"...","success":true}] to appear in
the chat instead of formatted shell output.

Changes:
- Add extractToolOutputText() helper that extracts raw text from
  ToolOperationResult[] format, using result.result for success and
  result.error for failures
- Update command content_end handler to use extractToolOutputText()
- Override vscodeTerminalExecutionMode to backgroundExec in
  SdkController.getStateToPostToWebview() since SDK always uses
  background execution
- Add 15 unit tests covering all output extraction cases

Fixes S6-41
2026-05-04 11:33:10 -07:00
Max Paulus 🥪 13f5235f9a fix(S6-38): resolve workspace root via HostProvider instead of process.cwd()
The SdkController used process.cwd() in 4 places as the working directory
for SDK sessions. In VSCode, process.cwd() returns the extension host
directory, not the user workspace. This meant Cline could not find project
files without explicit paths.

Added SdkController.getWorkspaceRoot() which resolves the workspace root
via HostProvider.workspace.getWorkspacePaths() (delegates to
vscode.workspace.workspaceFolders[0].uri.fsPath), falling back to
process.cwd() only when no workspace folder is open.

Replaced all 4 process.cwd() calls in initTask(), reinitExistingTaskFromId(),
resumeSessionFromTask(), and restartSessionForMcpTools().

Also added a defensive warning log in buildSessionConfig() for the
process.cwd() fallback path.

Updated PROBLEMS.md: S4-3 marked fixed, S6-38 added.
2026-05-04 11:33:10 -07:00
Max Paulus 🥪 b15a2abf57 fix(S6-45): use transient prop to prevent isActive from leaking to DOM
Renamed isActive to \$isActive in StyledTabButton in ClineRulesToggleModal.tsx.
The dollar-sign prefix tells styled-components to consume the prop for
styling without forwarding it to the underlying DOM element, eliminating
the React warning "React does not recognize the isActive prop on a DOM element."

Updated PROBLEMS.md with S6-45 entry marked as verified fixed.
2026-05-04 11:33:09 -07:00
Dominic Cooney 3aef7df81b Bump ZOD version to unbreak JetBrains webview runtime bundling error. 2026-05-04 11:33:09 -07:00
Dominic Cooney 156f86f777 Update package-lock.json etc. 2026-05-04 11:33:09 -07:00
Dominic Cooney 811b489de4 Update to SDK 0.0.35. 2026-05-04 11:33:09 -07:00
Dominic Cooney 701cda0d52 Update PROBLEMS.md, cost display is fixed. 2026-05-04 11:33:09 -07:00
Bee 40ef83305a use latest sdk main (#10337)
* use latest sdk main

* update sdk auth service

* dont throw when scm not available
2026-05-04 11:33:09 -07:00
Max Paulus 🥪 000d237044 fix sdk initial messages 2026-05-04 11:33:09 -07:00
Max Paulus 🥪 2e6adc23f6 updated problems.md 2026-05-04 11:33:08 -07:00
Max Paulus 🥪 cd7781bf92 fix read_files tool call not showing all file paths. Fixed assistant message not appearing after tool call result 2026-05-04 11:33:08 -07:00
Max Paulus 🥪 5f0714ba1e cline chatview is able to show some tool calls 2026-05-04 11:33:08 -07:00
Max Paulus 🥪 67fd6fcffb fix(sdk): preserve task session id when reloading MCP tools
Keep the active task/session id stable during MCP tool-list restarts so currentTaskItem stays mapped and chat state is not lost after toggling MCP servers.
2026-05-04 11:33:08 -07:00
Max Paulus 🥪 abbe849786 refactor some sdk session code (DRY it up a bit) 2026-05-04 11:33:08 -07:00
Max Paulus 🥪 fb28011a96 fix (click new task while in mid task)
- fixes the issue where if I click new task while mid task, and navigate
back to old task, old task still shows as thinking
2026-05-04 11:33:08 -07:00
Max Paulus 🥪 2b929440ee resume session working
- new task button doesn't work thoguh
2026-05-04 11:33:08 -07:00
Max Paulus 🥪 dafd751dda todo session resume 2026-05-04 11:33:07 -07:00
Max Paulus 🥪 05855b3a6a handle hicap and requesty auth callback support 2026-05-04 11:33:07 -07:00
Max Paulus 🥪 d523af555d add openrouter auth callback support
- tested by choosing openrouter provider, clicking "get openrouter api
key", and then sending a prompt to openrouter (gpt-oss-120b:free model)
2026-05-04 11:33:07 -07:00
Max Paulus 🥪 4cb1bf1d1b fix mcp oauth callback
- tests: tested with remote notion mcp: https://mcp.notion.com/mcp
2026-05-04 11:33:07 -07:00
Dominic Cooney 5692670333 docs: add S6-35 — inference cost not displayed in task (minor) 2026-05-04 11:33:07 -07:00
Dominic Cooney 6392c1e0d4 docs: add S6-34 — cancel during generation doesn't show Resume task 2026-05-04 11:33:07 -07:00
Dominic Cooney 3d7e3a5451 docs: add S6-33 — insufficient credits shows raw error instead of buy-credits UI 2026-05-04 11:33:07 -07:00
Dominic Cooney f2b01b1c25 docs: add S6-32 — New Task button and delete disabled after MCP tool change 2026-05-04 11:33:07 -07:00
Dominic Cooney 434489cec0 docs: add S6-31 — conversation history lost after MCP tool changes 2026-05-04 11:33:06 -07:00
Dominic Cooney 2a2cafeeaf fix(sdk): update adapter for SDK sync (b2f9f62d → e99831a6)
SessionManager interface changes:
- Add update() and handleHookEvent() to VscodeSessionHost
- Remove readHooks() (no longer in SessionManager interface)
- Import HookEventPayload from @clinebot/core

Auth service fixes:
- Replace InstanceType<typeof UserInfo> with UserInfo type directly
- Fix null assignment to protobuf field (use empty create instead)
2026-05-04 11:33:06 -07:00
Dominic Cooney f99fe6e128 feat(sdk): add attempt_completion tool and fix duplicate green rectangles
In the SDK migration branch, every agent response was showing a green
'Task Completed' rectangle because the done event unconditionally emitted
completion_result messages. In the classic extension, the green rectangle
only appeared when the agent explicitly called the attempt_completion tool.

Changes:
- Register attempt_completion as a custom tool in VscodeRuntimeBuilder
  so the SDK agent can call it (the SDK has no built-in equivalent)
- Handle attempt_completion in MessageTranslator: content_start emits
  say:'completion_result' (green rectangle), content_end emits
  ask:'completion_result' with empty text (enables follow-up input
  without a second green rectangle)
- Track attempt_completion calls via MessageTranslatorState so the done
  event can skip emitting completion_result when already handled
- When attempt_completion is NOT called, done emits ask:'completion_result'
  with empty text (renders as InvisibleSpacer, no green rectangle)
- Update tests: 2 existing tests updated, 1 new test added for the
  suppression behavior (35/35 pass)
2026-05-04 11:33:06 -07:00
Dominic Cooney 107053fc84 docs: update PROBLEMS.md — S6-29 verified fixed, remove from priority list 2026-05-04 11:33:06 -07:00
Dominic Cooney efca727f5b fix(S6-29): emit completion_result after MCP tool reload
After restartSessionForMcpTools() completes, the webview was left in
a 'Thinking...' state because no ask:'completion_result' message was
emitted. The webview's handleSendMessage() requires clineAsk to be
set to enable follow-up input.

Fix: Emit ask:'completion_result' after the success info message so
the webview knows the agent is idle and enables the follow-up input.

Tested with debug harness:
1. Sent 'Say hello briefly' → completed
2. Toggled kamibiki MCP server off via UI
3. 'MCP tools changed' + 'reloaded successfully' messages appeared
4. Typed 'Say goodbye' → follow-up inference ran successfully
2026-05-04 11:33:06 -07:00
Dominic Cooney 9f673a2675 docs: update PROBLEMS.md — verify MCP tools, follow-up messages, debouncing
Mark as verified:
- S6-10: MCP tools work via VscodeRuntimeBuilder + McpHub bridge
- S6-14: VscodeRuntimeBuilder bridges all transport types
- S6-20: MCP tools available to agent (kb_status, kb_search tested)
- S6-28: MCP tool reload debouncing prevents duplicate messages
- S6-30: New — follow-up messages fixed (say→ask completion_result)
2026-05-04 11:33:06 -07:00
Dominic Cooney 92639018a7 fix: MCP tools + follow-up messages in SDK migration
Three fixes for the SDK migration:

1. Follow-up messages: Changed the 'done' event translation from
   say:'completion_result' to ask:'completion_result'. The webview's
   handleSendMessage() requires clineAsk to be set to send follow-up
   messages. Without the ask message, typing a follow-up and pressing
   Enter was silently dropped.

2. Session cleanup: Clear activeSession reference before stop/dispose
   to prevent re-entrant calls. Added 3s timeouts to stop()/dispose()
   to prevent UI blocking when sessions are in unexpected states.

3. MCP tool change debouncing: When an MCP server connects,
   notifyWebviewOfServerChanges() fires multiple times in quick
   succession. Added 300ms debounce with fingerprint quick-check
   to coalesce these into a single tool list change callback.

Tested with debug harness:
- MCP tools (kb_status, kb_search) work correctly
- Follow-up messages work via both gRPC and DOM (typing + Enter)
- MCP tools work in follow-up turns
2026-05-04 11:33:06 -07:00
Dominic Cooney d2a8e19dca feat: MCP tool list change detection and session restart
- McpHub: Added computeToolFingerprint(), setToolListChangeCallback(),
  clearToolListChangeCallback(), and checkToolListChanged() to detect
  when the set of available MCP tools changes (servers added/removed/
  reconnected). Only fires on actual tool list changes, not mere status
  updates.

- SdkController: Added handleMcpToolListChanged() which restarts the
  session immediately when idle, or defers via mcpToolRestartPending
  flag until the current turn completes. restartSessionForMcpTools()
  creates a new VscodeSessionHost with fresh tools, preserves
  conversation messages, and emits info messages to the chat.

- SdkController: Fixed MCP settings file path — was reading from
  VSCode extension storage (HostProvider.globalStorageFsPath/settings/)
  instead of ~/.cline/data/settings/ where the actual MCP settings live.

- task-proxy: Made taskId settable so session restart can update the
  proxy's session ID without recreating it.

- Tests: 16 unit tests for tool list change detection covering
  fingerprinting, callback firing, and edge cases.

Known issues: S6-28 (reload messages appear twice), S6-29 (new task
button broken after reload). See PROBLEMS.md.
2026-05-04 11:33:05 -07:00
Dominic Cooney cef09f37e6 fix(S6-27): restore conversation when opening task from history
The gRPC handler for showTaskWithId was calling controller.initTask()
which starts a NEW SDK session instead of loading the existing task's
messages from disk. Changed to call controller.showTaskWithId(id)
which correctly: (1) looks up the history item, (2) tears down any
active session, (3) creates a task proxy with loaded messages,
(4) pushes messages through both state updates and partial message
stream, (5) posts state to the webview.

Verified with debug harness: send message → new task → click history
item → conversation restored with all messages.
2026-05-04 11:33:05 -07:00
Dominic Cooney ac7e06fcab Deleting tasks is reflected immediately in history. 2026-05-04 11:33:05 -07:00
Dominic Cooney 5eee05aafe fix: S6-24 tool input preservation, S6-6 path mismatch, restore streaming state push
- S6-24: Preserve tool input from content_start for use at content_end
  (MessageTranslatorState stores streamingToolInput/streamingToolName)
- S6-6: Replace readUiMessages (legacy path) with getSavedClineMessages
  (uses HostProvider.globalStorageFsPath, matching saveClineMessages)
- Restore postStateToWebview() in handleSessionEvent (needed for streaming)
- Fix TS2352 cast in message-translator.ts (as unknown as Record)
- Add 4 new tests for tool input preservation through streaming lifecycle
- S6-26: Research SDK pending prompts/tool approval/ask_question system
- S6-27: Create focused task for history messages still not rendering
- Update PROBLEMS.md priority section
2026-05-04 11:33:05 -07:00
Dominic Cooney 9d371572cd fix: display inference messages in webview (SDK migration)
The partial message handler in ExtensionStateContext only updated
existing messages by matching timestamps — it never appended new ones.
In the classic extension, messages were first added via state updates,
then updated in-place by partial messages. In the SDK migration,
messages arrive via the partial message stream first, so they need
to be appended when no existing message matches.

Also adds debounced ClineMessage persistence in SdkController so
task history can load messages via readUiMessages().
2026-05-04 11:33:05 -07:00
Dominic Cooney 3de6eeff6b docs: update PROBLEMS.md with verification results and new issues
- S6-5: Regressed — inference works but view doesn't switch to chat
- S6-6: Failed verification, merged S6-15 into it
- S6-8: Marked as verified fixed (brown logo)
- S6-19: New — history deletion dialog confirms but doesn't delete
- S6-20: New — MCP tools panel is empty
- Added Priority & Next Steps section recommending S6-5 as top priority
2026-05-04 11:33:05 -07:00
Dominic Cooney 008a66889f fix: build system prompt for SDK sessions to enable inference
The SDK's DefaultSessionManager passes the systemPrompt from
CoreSessionConfig directly to the Agent — there is no fallback for
empty system prompts. Both the CLI and SDK's VSCode extension call
buildClineSystemPrompt() before passing config to the session manager.

Our buildSessionConfig() was setting systemPrompt: '' (empty string),
which caused the gateway to return empty responses with 0 tokens.

Changes:
- cline-session-factory.ts: Import buildWorkspaceMetadata from
  @clinebot/core and buildClineSystemPrompt from @clinebot/shared.
  Build the full Cline system prompt in buildSessionConfig() using
  workspace metadata, IDE name, mode, provider, and platform.
  Falls back to a minimal prompt on error.
- vscode-session-host.ts: Add logging around send() for debugging
  inference issues (input/output tokens, response text).
- SdkController.ts: Add logging for session events and agent turn
  completion to aid debugging.

Verified: Agent responds correctly with 2776 input tokens (system
prompt) and generates proper output ('Hello, world! 👋').
2026-05-04 11:33:05 -07:00
Dominic Cooney 992feabd21 document new problems: S6-15 through S6-18
- S6-15: History items not clickable (blocker)
- S6-16: Sending message completes immediately with no output (blocker)
- S6-17: Cancel button enabled after task completes (minor)
- S6-18: Missing API key shows error instead of login prompt (blocker)
2026-05-04 11:33:05 -07:00
Dominic Cooney ccb5095877 simplify oauth: read credentials from providers.json directly
- Rewrite restoreRefreshTokenAndRetrieveAuthInfo() to read from providers.json
  instead of injecting through StateManager secrets
- Add fetchUserInfoFromApi() to get user profile from Cline API at startup
- Delete VscodeOAuthTokenManager (~180 lines) - SDK default handles persistence
- Simplify resolveApiKey() for cline provider to read from providers.json
- Cache getProviderSettings() as singleton to avoid re-reading file
- Net reduction of 94 lines
2026-05-04 11:33:04 -07:00
Dominic Cooney 257f1824b6 Add codebase search guidance for avoiding build output
Documents which directories contain minified/generated code that
produces noisy search results (out/, dist/, src/generated/, etc.),
how to skip them with search_files and grep, and how to search
minified files when necessary (grep -oP, source maps).
2026-05-04 11:33:04 -07:00
Dominic Cooney 6932ba829b sdk: wire VscodeSessionHost into SdkController for end-to-end inference
Replace ClineCore.create() with VscodeSessionHost.create() which
constructs DefaultSessionManager directly with VSCode-specific options:

1. VscodeSessionHost (new file):
   - Implements SessionManager interface, wrapping DefaultSessionManager
   - Injects source: 'vscode' on start() for telemetry tagging
   - Writes empty MCP settings to prevent SDK's default MCP loading

2. VscodeOAuthTokenManager:
   - Reads Cline OAuth tokens from secrets.json (cline:clineAccountId)
   - Refreshes tokens via SDK's refreshClineToken()
   - Returns null on re-auth failure instead of throwing
     OAuthReauthRequiredError (prevents 'Run clite auth' error)
   - Delegates non-cline OAuth (openai-codex, oca) to SDK's
     ProviderSettingsManager

3. VscodeRuntimeBuilder (from previous commit, now wired in):
   - Bridges classic McpHub to SDK tool system
   - Supports all MCP transports (stdio, SSE, streamableHttp)

4. SdkController changes:
   - initTask() uses VscodeSessionHost.create({ mcpHub })
   - ActiveSession.core -> ActiveSession.sessionManager
   - Removed createClineCore() and MCP filtering from session factory

All 99 SDK unit tests pass. No new TypeScript errors.
2026-05-04 11:33:04 -07:00
Dominic Cooney b378b6e4a4 sdk: fix webview state, chat history, and add VscodeRuntimeBuilder
Four fixes for making inference work in the VSCode UI:

1. Webview state connection (S6-13): Wire WebviewGrpcBridge to the
   controller's getStateToPostToWebview() so state updates include
   messages, currentTaskItem, and task history. Added setGetStateFn()
   method to the bridge and called it from SdkController constructor.

2. Chat history loading (S6-6): Fix history lookup in showTaskWithId()
   and reinitExistingTaskFromId() to check StateManager's taskHistory
   first (where updateTaskHistory writes), then fall back to the legacy
   file reader. Also clear active session before viewing history.

3. Message translation (S6-12): Add sdkToolToClineSayTool() mapping
   function that converts SDK tool names (read_files, editor, etc.) to
   classic ClineSayTool format that ChatRow.tsx expects. Add usage event
   handling for api_req_started messages. Update tests to match actual
   output format.

4. VscodeRuntimeBuilder (S6-14): New custom RuntimeBuilder that bridges
   the classic McpHub to the SDK's tool system. Delegates builtin tools
   to DefaultRuntimeBuilder but replaces MCP tools with ones loaded from
   the classic McpHub, supporting all transport types (stdio, SSE,
   streamableHttp). Not yet wired into session creation — needs
   VscodeSessionHost wrapper (see S6-9).

All 99 SDK unit tests pass.
2026-05-04 11:33:04 -07:00
Dominic Cooney f4e8f89ca5 feat(sdk): fix inference pipeline — credential resolution, non-blocking start, MCP filtering
- Fix credential resolution: replace broken ProviderSettingsManager and
  buildApiHandlerSettings() paths with resolveApiKey()/resolveModelId()
  that read directly from StateManager.getApiConfiguration() (includes
  secrets). Handles all 30+ providers including cline OAuth token
  extraction (idToken from cline:clineAccountId JSON, workos: prefix).

- Fix non-blocking session start: initTask() now calls
  core.start({interactive:true}) WITHOUT a prompt (returns immediately),
  then fire-and-forgets core.send() for inference. Events stream
  in real-time via subscribe(). Same pattern for askResponse().

- Add MCP settings filtering: SDK's StdioMcpClient only supports stdio
  transport. ensureFilteredMcpSettings() writes a filtered copy of
  cline_mcp_settings.json (stdio-only) and sets CLINE_MCP_SETTINGS_PATH
  env var. Future: replace with custom RuntimeBuilder that provides a
  clientFactory delegating to classic McpHub for streamableHttp support.

- Fix debug harness gRPC message format for web.post_message.

- Update PROBLEMS.md: S6-5 and S6-11 marked 🟢 Verified Fixed.

Verified: Debug harness sends newTask → session starts, agent runs,
events stream to webview (iteration_start, usage, iteration_end, done).
2026-05-04 11:33:04 -07:00
Dominic Cooney a67ccc59d4 Add Claude analysis of the branch. 2026-05-04 11:33:04 -07:00
Dominic Cooney aefa0b3f7a Fix: empty clineEnv in updateSettings flips to local environment
Protobuf defaults empty strings to ''. The check 'request.clineEnv !== undefined'
was true for empty strings, causing ClineEnv.setEnvironment('') which defaults
to 'production' but also triggers accountLogoutClicked(). This caused the user
to be logged out and the environment to appear to flip when changing models.

Fix: Also check 'request.clineEnv !== ""' before processing.
2026-05-04 11:33:04 -07:00
Dominic Cooney ecddcef2a5 Fix critical bugs: history item saving, VSCode API exposure, logging
1. initTask() now saves history item to StateManager immediately
   after session starts. Without this, currentTaskItem was undefined
   in getStateToPostToWebview(), so the webview never switched to
   chat view after sending a message.

2. updateTaskHistory() and deleteTaskFromState() are now real
   implementations using StateManager instead of stubs.

3. Exposed window.__clineVsCodeApi in webview for debug harness
   access (platform.config.ts).

4. Added detailed logging to initTask() for debugging:
   - Session config (provider, model, apiKey presence)
   - ClineCore creation
   - Session start
   - Error details

These fixes address the user-reported issues:
- Send button clears input but doesn't switch to chat view
- Chat history appears empty
2026-05-04 11:33:04 -07:00
Dominic Cooney 001399b9a4 Update README with Step 7 & 8 progress 2026-05-04 11:33:03 -07:00
Dominic Cooney bf461f19da Step 8: Settings & Features — TaskProxy compatibility + togglePlanActMode
TaskProxy improvements for settings handler compatibility:
- api property is now settable (updateSettings replaces it on model switch)
- terminalManager returns a proper stub that safely no-ops
  (setDefaultTerminalProfile, setShellIntegrationTimeout, etc.)
- Added TaskProxyTerminalManager interface

SdkController improvements:
- togglePlanActMode() now properly implemented:
  - Saves mode to StateManager
  - Cancels active task if switching modes mid-task
  - Posts state update to webview
- toggleActModeForYoloMode() switches to act mode

These changes ensure the updateSettings gRPC handler works
without modification — it calls controller.task.api and
controller.task.terminalManager which are now properly stubbed.
2026-05-04 11:33:03 -07:00
Dominic Cooney 3f893b1040 Step 7: Wire classic McpHub into SdkController
Following the 'Thunk, Don't Replace' principle, wire the classic
McpHub into SdkController instead of building a custom SDK MCP
manager. The classic McpHub already supports all three transports
(stdio, SSE, streamableHTTP), file watching, and all gRPC handlers.

Changes:
- SdkController.mcpHub: type changed from 'any' to 'McpHub'
- Constructor initializes McpHub with same args as classic Controller
- Existing gRPC handlers (subscribeToMcpServers, restartMcpServer,
  deleteMcpServer, toggleMcpServer, etc.) work without modification
- SDK's InMemoryMcpManager will replace it in Step 10 (Cleanup)

Also includes:
- Fix S6-5: buildSessionConfig() falls back to classic StateManager
  when SDK ProviderSettingsManager has no provider configured
- Fix S6-6: showTaskWithId() loads messages from disk via
  readUiMessages() and adds them to TaskProxy's messageStateHandler
- Updated PROBLEMS.md and README.md with Step 7 progress
2026-05-04 11:33:03 -07:00
Dominic Cooney 88ae634fa1 Fix S6-5 & S6-6: provider config fallback + history message loading
S6-5: buildSessionConfig() now falls back to classic StateManager
- Try SDK ProviderSettingsManager first (providers.json)
- If no provider/apiKey found, fall back to StateManager.buildApiHandlerSettings()
- This correctly resolves provider/model/apiKey for the current mode (plan/act)
- Critical because providers.json may not exist yet for existing users

S6-6: showTaskWithId() now loads messages from disk
- Call readUiMessages(taskId) to load ui_messages.json
- Add messages to TaskProxy's messageStateHandler via addMessages()
- This populates the message state so getStateToPostToWebview() returns them

Also: remove unused Settings import from cline-session-factory.ts,
add StateManager import for the fallback path.
2026-05-04 11:33:03 -07:00
Dominic Cooney a04e204c1b Step 6: Auth & Account Flows — SDK-backed auth and account services
- Add src/sdk/auth-service.ts: SDK-backed AuthService replacing classic AuthService
  - loginClineOAuth(), loginOcaOAuth(), loginOpenAICodex() via SDK functions
  - Token persistence to secrets.json with workos: prefix
  - Cross-window auth sync via secrets change listener
  - Streaming subscriptions with immediate initial state push
- Add src/sdk/account-service.ts: SDK-backed ClineAccountService
  - Authenticated API requests using SDK-backed AuthService
  - Credit fetching, org switching, payment history
- Wire gRPC handlers to SDK-backed auth:
  - accountLoginClicked, accountLogoutClicked, subscribeToAuthStatusUpdate
  - openAiCodexSignIn, openAiCodexSignOut
- Update SdkController to initialize auth/account services
- Update extension.ts secrets listener to use new auth-service
- 20 unit tests in auth-service.test.ts
- Update sdk-migration/README.md and PROBLEMS.md for Step 6

Status: Implementation complete, awaiting E2E verification
Blockers: S6-5 (inference not starting), S6-6 (history items not loading)
2026-05-04 11:33:03 -07:00
Dominic Cooney 86aa1a68ef Step 5: gRPC thunking layer — TaskProxy + WebviewGrpcBridge
- src/sdk/task-proxy.ts: TaskProxy provides classic Task-compatible
  interface that delegates to SDK session methods. MessageStateHandler
  extends EventEmitter for CLI compatibility (on/off pattern).
  TaskProxyState mirrors classic TaskState subset.

- src/sdk/webview-grpc-bridge.ts: Bridges SDK session events to
  webview gRPC streams. Translates ClineMessages to proto format
  and pushes through sendPartialMessageEvent/sendStateUpdate.

- src/sdk/SdkController.ts: Wired TaskProxy + WebviewGrpcBridge
  into session lifecycle. Events flow: SDK → message translator →
  gRPC bridge → webview streams. Reuses getStateToPostToWebview()
  for state building.

- No 'as' casts in production code — type narrowing used instead.
  Stubs throw errors instead of returning undefined as unknown as T.

- 114 unit tests pass across 6 test files.
- 0 new TypeScript errors (3 pre-existing in unrelated files).
- Extension loads, sidebar renders, newTask routes correctly.
- initTask fails at runtime because ClineCore.create() needs SDK
  config (Step 6+).
2026-05-04 11:33:03 -07:00
Dominic Cooney a14b4c9088 Step 4: Session lifecycle — SDK adapter layer
Implement session lifecycle for the SDK migration:

- src/sdk/cline-session-factory.ts: Build CoreSessionConfig from
  legacy state via ProviderSettingsManager, create ClineCore instances,
  build StartSessionInput/resume inputs, HistoryItem CRUD helpers

- src/sdk/message-translator.ts: Translate all SDK CoreSessionEvent
  types to ClineMessage[] for webview consumption. Handles chunk,
  agent_event (content_start/update/end, done, error, notice, usage),
  ended, hook, status events. Streaming state tracking for partial
  message dedup.

- src/sdk/SdkController.ts: Session lifecycle methods (initTask,
  askResponse, cancelTask, clearTask, showTaskWithId,
  reinitExistingTaskFromId), SDK event subscription/translation
  pipeline, session event listener system.

- Tests: 91 unit tests across 4 files (27 message-translator,
  37 legacy-state-reader, 15 cline-session-factory, 12
  provider-migration). TypeScript compiles with 0 errors.

- Updated sdk-migration/README.md: Step 4 marked completed,
  improved debug harness overlay dismiss instructions.

- Updated sdk-migration/PROBLEMS.md: Step 4 verified, 3 minor
  known issues documented (S4-1, S4-2, S4-3).
2026-05-04 11:33:02 -07:00
Dominic Cooney 79a51cc5f0 Step 3: Provider Migration — SDK-backed credential migration
Implements src/sdk/provider-migration.ts with:
- migrateProviders() using SDK's ProviderSettingsManager auto-migration
- getProviderSettingsManager() for accessing provider settings
- Supports all 30+ providers (Anthropic, OpenAI, OpenRouter, Bedrock, Ollama, Cline, etc.)
- Never overwrites existing entries (idempotent)
- Tags migrated entries with tokenSource: 'migration'
- 12 unit tests passing, 0 TypeScript errors
2026-05-04 11:33:02 -07:00
Dominic Cooney 7a1be66de8 Step 2: Legacy State Reader — read all on-disk state from SDK adapter layer
Implements src/sdk/legacy-state-reader.ts with:
- readGlobalState/readGlobalStateKey for globalState.json
- readSecrets/readSecretKey for secrets.json
- readTaskHistory for state/taskHistory.json
- readApiConversationHistory, readUiMessages, readContextHistory, readTaskMetadata for per-task data
- readMcpSettings for settings/cline_mcp_settings.json
- listTaskIds for task directory listing
- readAllLegacyState composite reader
- All reads are non-throwing (missing/corrupt files return typed defaults)
- 37 unit tests passing, 0 TypeScript errors
2026-05-04 11:33:02 -07:00
Dominic Cooney ce2dcfb402 Step 1: Foundation & Cutover - SDK adapter layer
- Add @clinebot/core, @clinebot/llms, @clinebot/shared, @clinebot/agents
  as dependencies via file: protocol (linked to ../sdk-wip)
- Create src/sdk/ directory with SdkController stub and barrel export
- Replace src/core/controller/index.ts with re-export from SDK adapter
  (classic Controller accessible via origin/main)
- Extract getStateToPostToWebview() to standalone function for reuse
- Add vitest.config.sdk.ts for SDK adapter tests
- Fix implicit any types in handler modules
- Extension compiles and builds successfully (tsc + esbuild pass)
- Single entry point: no CLINE_SDK flag, SDK adapter is the only codepath

Replaces classic src/core/controller/index.ts (see origin/main)
2026-05-04 11:33:02 -07:00
Dominic Cooney e291f4067a sdk-migration-v3: single entry point, delete-and-document principle
Key changes from feedback:
- Replace 'don't delete what you haven't replaced' with 'delete and document'
  - Delete classic code immediately when replaced by SDK equivalent
  - Add 'Replaces classic src/core/... (see origin/main)' comments
  - Use kb_search/git to reference origin/main for classic implementation
- Single entry point: no CLINE_SDK env variable, no dual codepaths
  - Step 1 now modifies src/extension.ts directly
  - Rationale: dual entry points caused constant confusion in attempt 2
- Updated ARCHITECTURE.md with key architectural decisions
- Updated .clinerules/sdk-migration.md with new rules
2026-05-04 11:33:02 -07:00
Dominic Cooney 99126ce210 sdk-migration-v3: seed the third migration attempt
- Port forward debug harness (server.ts, README.md, .clinerules)
- Port forward ws.d.ts type declaration
- Create sdk-migration/ doc structure:
  - README.md: entry point, 10-step plan, operational procedure
  - ARCHITECTURE.md: features, design decisions, SDK capabilities
  - SDK-REFERENCE/OAUTH.md: SDK OAuth reference with pitfalls
  - SDK-REFERENCE/MCP.md: SDK MCP reference with gap analysis
  - PROBLEMS.md: issue tracker with verification requirements
- Add .clinerules/sdk-migration.md for agent guidance

Key changes from attempt 2:
- gRPC thunking instead of typed message replacement
- Verification gates before each step
- Never delete what you haven't replaced
- Structured problem tracking with evidence requirements
- Concise, purpose-specific docs with fan-out structure
2026-05-04 11:33:02 -07:00
1880 changed files with 39668 additions and 355292 deletions
-33
View File
@@ -1,33 +0,0 @@
# CLI Development
The CLI lives in `cli/` and uses React Ink for terminal UI.
- If needed, look at `cli/src/constants/colors.ts` for re-used terminal colors, e.g. `COLORS.primaryBlue` highlight color (selections, spinners, success states).
- Never use `dimColor` with gray (e.g. `<Text color="gray" dimColor>`) - it's too hard to read. Use `color="gray"` for secondary text and normal foreground (no color) for primary text.
- When thinking about how to handle state or messages from core, look at webview for how it communicates with the vs code extension.
- When updating the webview, consider and suggest to the user to update the CLI TUI since we want to provide a similar experience to our terminal users as we do our vs code extension users.
## Adding New API Providers
When adding a new API provider to the extension, you must also update the CLI:
1. **Update `cli/src/components/ModelPicker.tsx`**: Add the provider to the `providerModels` map so `getDefaultModelId()` returns the correct default model. Import the models and default ID from `@shared/api`:
```typescript
import { newProviderDefaultModelId, newProviderModels } from "@/shared/api"
export const providerModels = {
// ...existing providers
"new-provider": { models: newProviderModels, defaultId: newProviderDefaultModelId },
}
```
2. **Use `applyProviderConfig()` for auth flows**: When implementing OAuth or other auth flows for the provider, use the shared utility at `cli/src/utils/provider-config.ts`:
```typescript
import { applyProviderConfig } from "../utils/provider-config"
// After successful auth:
await applyProviderConfig({ providerId: "new-provider", controller })
```
This handles setting provider, default model, API key mapping, state persistence, and rebuilding the API handler.
3. **Provider-specific auth**: If the provider uses OAuth (like `openai-codex`), add handling in `SettingsPanelContent.tsx`'s `handleProviderSelect` callback. See the existing Codex OAuth flow as a reference.
+121
View File
@@ -0,0 +1,121 @@
# Debug Harness
HTTP-controlled debugger for the VSCode extension at `src/dev/debug-harness/server.ts`.
## Quick start
```bash
# Build extension first if needed (protos + esbuild):
npm run protos && IS_DEV=true node esbuild.mjs
# Launch (skip-build if already built):
npx tsx src/dev/debug-harness/server.ts --skip-build --auto-launch
# In another terminal:
curl localhost:19229/api -d '{"method":"status"}'
```
## Data Isolation
The debugee runs with `CLINE_DIR=~/.cline2` by default, separate from your real `~/.cline`.
This prevents the debugee's logout from logging out the debugger, and vice versa.
Override with `--cline-dir /tmp/test-dir`. Check with `status()``clineDir`.
## Browser Capture & OAuth
The debugee runs with `CLINE_CAPTURE_BROWSER=1`, which intercepts `openExternal()` in
`src/utils/env.ts`. URLs are captured instead of opening a real browser:
- Logged to `$CLINE_DIR/data/debug-captured-urls.jsonl`
- POSTed in real-time to `/captured-url` on the harness server
- Queryable via `oauth.captured_urls`
### OAuth API
- **`oauth.captured_urls`** `{clear?}` — URLs the debugee tried to open
- **`oauth.read_stored_token`** — Check auth token presence in secrets.json
- **`oauth.simulate_callback`** `{path, code?, state?, provider?, token?}` — Build vscode:// callback URI
- **`oauth.read_captured_urls_file`** — Read on-disk JSONL of captured URLs
### OAuth testing flow
For **Cline OAuth** (SDK local callback): The SDK starts a local HTTP server, the auth URL
is captured. To complete: open the captured URL in a real browser (it redirects back to the
SDK's callback server), OR extract the callback port and `curl http://127.0.0.1:PORT/callback?code=...`.
For **MCP/Provider OAuth** (vscode:// URI): The redirect goes to a vscode:// URI. Use
`oauth.simulate_callback` to build it, then inject via `ext.evaluate` calling the URI handler.
## Navigating Views — Use Commands, Not Clicks
Don't try to find/click small sidebar icons. Use VSCode commands via command palette.
Registered in `src/registry.ts`:
| Command | View |
|---------|------|
| `cline.accountButtonClicked` | Account / sign-in |
| `cline.historyButtonClicked` | Task history |
| `cline.settingsButtonClicked` | Settings |
| `cline.mcpButtonClicked` | MCP servers |
| `cline.plusButtonClicked` | New task (chat) |
| `cline.worktreesButtonClicked` | Worktrees |
```bash
curl localhost:19229/api -d '{"method":"ui.command_palette","params":{"command":"cline.accountButtonClicked"}}'
```
## Key commands
All via `POST localhost:19229/api` with `{"method":"...", "params":{...}}`:
- **`launch`** / **`shutdown`** — lifecycle
- **`ui.screenshot`** — screenshot to `/tmp/cline-debug/`; returns `{path}`**use `read_file` on the path to examine, do NOT `open` the file** (Preview.app covers the VSCode window)
- **`ui.open_sidebar`** — open the Cline sidebar
- **`ext.set_breakpoint`** `{file, line, condition?}` — breakpoint by source file (sourcemap-resolved)
- **`ext.evaluate`** `{expression, callFrameId?}` — eval in extension host
- **`ext.resume`** / **`ext.step_over`** / **`ext.step_into`** — stepping
- **`ext.call_stack`** — inspect when paused
- **`web.evaluate`** `{expression}` — eval in webview
- **`web.post_message`** `{message}` — send postMessage to extension host via exposed vsCodeApi
- **`wait_for_pause`** `{timeout?}` — block until breakpoint hit
- **`ui.locator`** `{role?, testId?, text?, frame?}` — Playwright locator (auto-retries on stale sidebar frame)
- **`ui.react_input`** `{text, selector?, clear?, submit?}` — set React textarea value via `execCommand('insertText')`; works reliably across multiple tasks
- **`ui.send_message`** `{text, images?, files?, responseType?}` — send chat message bypassing the textarea entirely (via gRPC postMessage)
- **`ui.command_palette`** `{command}` — run VSCode command
## Typical Session
```bash
# 1. Launch
curl localhost:19229/api -d '{"method":"launch","params":{"skipBuild":true}}'
# 2. Open sidebar + dismiss overlays (ALWAYS do this first)
curl localhost:19229/api -d '{"method":"ui.open_sidebar"}'
curl localhost:19229/api -d '{"method":"web.evaluate","params":{"expression":"document.querySelectorAll(\".sr-only\").forEach(el => el.parentElement?.click())"}}'
# 3. Navigate to view
curl localhost:19229/api -d '{"method":"ui.command_palette","params":{"command":"cline.accountButtonClicked"}}'
# 4. Check captured OAuth URLs if testing auth
curl localhost:19229/api -d '{"method":"oauth.captured_urls"}'
# 5. Verify
curl localhost:19229/api -d '{"method":"ui.screenshot"}'
```
## Caveats
- **⚠️ Dismiss promotional overlays FIRST**: On fresh launches, full-screen promo overlays block the sidebar. **Dismiss immediately after `ui.open_sidebar`**, before any other interaction or screenshot. May need to run twice:
```bash
curl localhost:19229/api -d '{"method": "ui.open_sidebar"}'
curl localhost:19229/api -d '{"method": "web.evaluate", "params": {"expression": "document.querySelectorAll(\".sr-only\").forEach(el => el.parentElement?.click())"}}'
```
- **Screenshots — don't open the file**: `ui.screenshot` and `ui.sidebar_screenshot` save PNGs to `/tmp/cline-debug/` and return the `{path}`. Use `read_file` on that path to examine screenshots. Running `open <path>` launches Preview.app on macOS which covers the VSCode window.
- **Scripts count = 0 after launch**: CDP connects after extension host starts, so scripts parsed during startup aren't tracked. Breakpoints still work via sourcemap resolution.
- **Port 9230**: Extension host inspector. If another VSCode instance uses this port, the harness will fail to connect. Kill other debug instances first.
- **macOS only** for now (Playwright Electron launch behavior).
- **Webview CDP**: `connect_webview` may fail depending on Electron version. `web.evaluate` still works via Playwright's `frame.evaluate()` fallback.
- **Sourcemap paths**: esbuild outputs relative paths like `../src/extension.ts` in the sourcemap. The resolver handles this, but if a file isn't found, use `ext.source_files` to see exact paths.
- **OAuth with fake codes**: Browser capture intercepts the URL but doesn't provide a valid auth code. For real OAuth testing, open the captured URL in a browser. For unit testing, mock the token exchange.
See `src/dev/debug-harness/README.md` for full API reference.
+43 -87
View File
@@ -18,6 +18,49 @@ This file is the secret sauce for working effectively in this codebase. It captu
- When adding new feature flags, see this PR as a reference https://github.com/cline/cline/pull/7566
- Additional instructions about making requests: @.clinerules/network.md
## Searching the Codebase — Avoiding Build Output
Several directories contain build output or generated code that produces
noisy or unusable results with `search_files` / `grep`:
| Directory | What it is | Why it's a problem |
|-----------|-----------|-------------------|
| `out/` | esbuild bundle output | Mirrors `src/` structure as minified JS — every search gets duplicate hits on single-line files |
| `dist/` | Packaged extension | Entire extension bundled into one minified `extension.js` (~1 long line) |
| `dist-standalone/` | Standalone build output | Same minification issue |
| `src/generated/` | Generated protobuf code | Auto-generated from `proto/`; not the source of truth |
| `src/shared/proto/` | Generated proto type defs | Auto-generated from `proto/`; not the source of truth |
| `node_modules/` | Dependencies | Huge, not project source |
### How to skip build output
**`search_files`** — Point at `src/` (not the project root) and use `file_pattern`:
```
search_files(path="src/core", regex="myFunction", file_pattern="*.ts")
```
The `file_pattern` parameter is the most effective filter — e.g. `"*.ts"`,
`"*.tsx"`, `"*.proto"`.
**`grep` directly** — Exclude build dirs and restrict to source extensions:
```bash
grep -rn "myFunction" src/ --include="*.ts" --exclude-dir={out,dist,node_modules,generated}
```
### When you must search minified files
Sometimes you need to verify what got bundled (e.g., checking if a change
made it into the build). Minified files are typically one long line, so
normal `grep` shows the entire file as context. Use these approaches:
- **`grep -oP`** to extract just the match with limited surrounding context:
```bash
grep -oP '.{0,40}myFunction.{0,40}' dist/extension.js
```
- **`read_file`** on files in `out/src/` — these have source maps and are
more readable than `dist/extension.js` (which is the fully bundled output).
- **Source maps** — `out/src/*.js.map` and `dist/extension.js.map` can be
used to trace minified output back to original source locations.
## gRPC/Protobuf Communication
The extension and webview communicate via gRPC-like protocol over VS Code message passing.
@@ -48,93 +91,6 @@ The extension and webview communicate via gRPC-like protocol over VS Code messag
- `src/core/controller/task/explainChanges.ts` - Handler implementation
- `webview-ui/src/components/chat/ChatRow.tsx` - UI rendering
## Adding a New API Provider
When adding a new provider (e.g., "openai-codex"), you must update the proto conversion layer in THREE places or the provider will silently reset to Anthropic:
1. `proto/cline/models.proto` - Add to the `ApiProvider` enum (e.g., `OPENAI_CODEX = 40;`)
2. `convertApiProviderToProto()` in `src/shared/proto-conversions/models/api-configuration-conversion.ts` - Add case mapping string to proto enum
3. `convertProtoToApiProvider()` in the same file - Add case mapping proto enum back to string
**Why this matters:** Without these, the provider string hits the `default` case and returns `ANTHROPIC`. The webview, provider list, and handler all work fine, but the state silently resets when it round-trips through proto serialization. No error is thrown.
**Other files to update when adding a provider:**
- `src/shared/api.ts` - Add to `ApiProvider` union type, define models
- `src/shared/providers/providers.json` - Add to provider list for dropdown
- `src/core/api/index.ts` - Register handler in `createHandlerForProvider()`
- `webview-ui/src/components/settings/utils/providerUtils.ts` - Add cases in `getModelsForProvider()` and `normalizeApiConfiguration()`
- `webview-ui/src/utils/validate.ts` - Add validation case
- `webview-ui/src/components/settings/ApiOptions.tsx` - Render provider component
## Responses API Providers (OpenAI Codex, OpenAI Native)
Providers using OpenAI's Responses API require native tool calling. XML tools don't work with the Responses API.
**Symptoms of broken native tool calling:**
- Tools get called multiple times (e.g., `ask_followup_question` asks the same question twice)
- Tool arguments get duplicated or malformed
- The model responds but tools aren't recognized
**Root causes to check:**
1. **Provider missing from `isNextGenModelProvider()`** in `src/utils/model-utils.ts`. The native variant matchers (e.g., `native-gpt-5/config.ts`) call this function. If your provider isn't in the list, the matcher returns false and falls back to XML tools.
2. **Model missing `apiFormat: ApiFormat.OPENAI_RESPONSES`** in its model info (`src/shared/api.ts`). This property signals that the model requires native tool calling. The task runner in `src/core/task/index.ts` checks this and forces `enableNativeToolCalls: true` regardless of user settings.
**When adding a new Responses API provider:**
1. Add provider to `isNextGenModelProvider()` list in `src/utils/model-utils.ts`
2. Set `apiFormat: ApiFormat.OPENAI_RESPONSES` on all models that use the Responses API
3. The variant matcher and task runner will handle the rest automatically
## Adding Tools to System Prompt
This is tricky—multiple prompt variants and configs. **Always search for existing similar tools first and follow their pattern.** Look at the full chain from prompt definition → variant configs → handler → UI before implementing.
1. **Add to `ClineDefaultTool` enum** in `src/shared/tools.ts`
2. **Tool definition** in `src/core/prompts/system-prompt/tools/` (create file like `generate_explanation.ts`)
- Define variants for each `ModelFamily` (generic, next-gen, xs, etc.)
- Export variants array (e.g., `export const my_tool_variants = [GENERIC, NATIVE_NEXT_GEN, XS]`)
- **Fallback behavior**: If a variant isn't defined for a model family, `ClineToolSet.getToolByNameWithFallback()` automatically falls back to GENERIC. So you only need to export `[GENERIC]` unless the tool needs model-specific behavior.
3. **Register in `src/core/prompts/system-prompt/tools/init.ts`** - Import and spread into `allToolVariants`
4. **Add to variant configs** - Each model family has its own config in `src/core/prompts/system-prompt/variants/*/config.ts`. Add your tool's enum to the `.tools()` list:
- `generic/config.ts`, `next-gen/config.ts`, `gpt-5/config.ts`, `native-gpt-5/config.ts`, `native-gpt-5-1/config.ts`, `native-next-gen/config.ts`, `gemini-3/config.ts`, `glm/config.ts`, `hermes/config.ts`, `xs/config.ts`
- **Important**: If you add to a variant's config, make sure the tool spec exports a variant for that ModelFamily (or relies on GENERIC fallback)
5. **Create handler** in `src/core/task/tools/handlers/`
6. **Wire up in `ToolExecutor.ts`** if needed for execution flow
7. **Add to tool parsing** in `src/core/assistant-message/index.ts` if needed
8. **If tool has UI feedback**: add `ClineSay` enum in proto, update `src/shared/ExtensionMessage.ts`, update `src/shared/proto-conversions/cline-message.ts`, update `webview-ui/src/components/chat/ChatRow.tsx`
## Modifying System Prompt
**Read these first:** `src/core/prompts/system-prompt/README.md`, `tools/README.md`, `__tests__/README.md`
System prompt is modular: **components** (reusable sections) + **variants** (model-specific configs) + **templates** (with `{{PLACEHOLDER}}` resolution).
**Key directories:**
- `components/` - Shared sections: `rules.ts`, `capabilities.ts`, `editing_files.ts`, etc.
- `variants/` - Model-specific: `generic/`, `next-gen/`, `xs/`, `gpt-5/`, `gemini-3/`, `hermes/`, `glm/`, etc.
- `templates/` - Template engine and placeholder definitions
**Variant tiers (ask user which to modify):**
- **Next-gen** (Claude 4, GPT-5, Gemini 2.5): `next-gen/`, `native-next-gen/`, `native-gpt-5/`, `native-gpt-5-1/`, `gemini-3/`, `gpt-5/`
- **Standard** (default fallback): `generic/`
- **Local/small models**: `xs/`, `hermes/`, `glm/`
**How overrides work:** Variants can override components via `componentOverrides` in their `config.ts`, or provide a custom template in `template.ts` (e.g., `next-gen/template.ts` exports `rules_template`). If no override, the shared component from `components/` is used.
**Example: Adding a rule to RULES section**
1. Check if variant overrides rules: look for `rules_template` in `variants/*/template.ts` or `componentOverrides.RULES` in `config.ts`
2. If shared: modify `components/rules.ts`
3. If overridden: modify that variant's template
4. XS variant is special—has heavily condensed inline content in `template.ts`
**After any changes, regenerate snapshots:**
```bash
UPDATE_SNAPSHOTS=true npm run test:unit
```
Snapshots live in `__tests__/__snapshots__/`. Tests validate across model families and context variations (browser, MCP, focus chain).
## Modifying Default Slash Commands
Three places need updates:
- `src/core/slash-commands/index.ts` - Command definitions
- `src/core/prompts/commands.ts` - System prompt integration
- `webview-ui/src/utils/slash-commands.ts` - Webview autocomplete
## Adding New Global State Keys
Adding a new key to global state requires updates in multiple places. Missing any step causes silent failures.
-90
View File
@@ -1,90 +0,0 @@
# Networking & Proxy Support
To ensure Cline works correctly in all environments (VSCode, JetBrains, CLI) and with various network configurations (especially corporate proxies), strictly follow these guidelines for all network activity.
In extension code, do NOT use the global `fetch` or a default `axios` instance. (Note, `shared/net.ts` is exempt from these rules because it sets up the fetch wrappers.) In Webview code, you SHOULD use global `fetch`.
Global `fetch` and default `axios` do not automatically pick up proxy configurations in all environments (specifically JetBrains and CLI). You MUST use the provided utilities in `@/shared/net` which handle proxy agent configuration. In the webview, the browser/embedder handles proxies.
## Guidelines
### 1. Using `fetch`
Instead of `fetch(...)`, import the proxy-aware wrapper:
```typescript
import { fetch } from '@/shared/net'
// Usage is identical to global fetch
const response = await fetch('https://api.example.com/data')
```
### 2. Using `axios`
When using `axios`, you must apply the settings from `getAxiosSettings()`:
```typescript
import axios from 'axios'
import { getAxiosSettings } from '@/shared/net'
const response = await axios.get('https://api.example.com/data', {
headers: { 'Authorization': '...' },
...getAxiosSettings() // <--- CRITICAL: Injects the proxy agent if needed
})
```
### 3. Third-Party Clients (OpenAI, Ollama, etc.)
Most API client libraries allow you to customize the `fetch` implementation. You **MUST** pass the proxy-aware `fetch` to these clients.
**Example (OpenAI):**
```typescript
import OpenAI from "openai"
import { fetch } from "@/shared/net"
this.client = new OpenAI({
apiKey: '...',
fetch, // <--- CRITICAL: Pass our fetch wrapper
})
```
### 4. Tests
Use `mockFetchForTesting` to mock the underlying fetch implementation.
**Example (callback):**
```
import { mockFetchForTesting } from "@/shared/net"
...
let mockFetch = ...
mockFetchForTesting(mockFetch, () => {
// This calls mockFetch
fetch('https://foo.example').then(...)
})
// Original fetch is restored immediately when the call returns.
```
**Example (Promise):**
```
import { mockFetchForTesting } from "@/shared/net"
...
let mockFetch = ...
await mockFetchForTesting(mockFetch, async () => {
await ...
// This calls mockFetch
await fetch('https://foo.example')
...
})
// Original fetch is restored when the Promise from the callback settles
```
## Verification
If you are adding a new network call or integration:
1. Check `@/shared/net.ts` is imported.
2. Ensure `fetch` or `getAxiosSettings` is being used.
3. Verify that third-party clients are configured to use the custom fetch.
+29
View File
@@ -0,0 +1,29 @@
# SDK Migration
When working on the SDK migration (branch `sdk-migration-v3`), start by
reading `sdk-migration/README.md` in full. It contains the step-by-step
plan, core principles, and operational procedure.
Key documents:
- `sdk-migration/README.md` — Entry point, plan, steps
- `sdk-migration/ARCHITECTURE.md` — Design decisions, features, SDK capabilities
- `sdk-migration/SDK-REFERENCE/OAUTH.md` — SDK OAuth reference
- `sdk-migration/SDK-REFERENCE/MCP.md` — SDK MCP reference
- `sdk-migration/PROBLEMS.md` — Issue tracker with verification status
- `src/dev/debug-harness/README.md` — Debug harness API
## Critical Rules
1. **Always use `kb_search(name="sdk", query="...")` before implementing**
SDK features. Don't guess at APIs.
2. **Never mark a problem 🟢 without evidence.** Write the test first.
3. **Delete and document.** When replacing a classic module, delete it
immediately and add `// Replaces classic src/core/... (see origin/main)`.
Use `kb_search(name="cline", commit="origin/main")` or
`git show origin/main:path` to reference the classic implementation.
4. **Single entry point.** No `CLINE_SDK` env variable. There is one
codepath — the SDK adapter.
5. **Use `{appBaseUrl}`**, never hardcode `app.cline.bot`.
6. **Avoid `as` casts.** Use explicit conversion functions with tests.
7. **Dismiss the Kanban overlay** before any debug harness interaction.
8. **Use command palette** to navigate tabs in the debug harness.
+83
View File
@@ -0,0 +1,83 @@
name: CLI TUI Tests
on:
pull_request:
branches:
- main
workflow_dispatch:
workflow_call:
permissions:
contents: read
jobs:
cli-tui-tests:
name: CLI TUI Tests
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
- name: Install dependencies
run: npm ci
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build CLI
run: npm run cli:build
- name: Run TUI Tests
id: tui_tests
run: |
npm run test:e2e:cli:tui 2>&1 | tee tui-test-output.log
exit_code=${PIPESTATUS[0]}
echo "tui_exit_code=$exit_code" >> $GITHUB_OUTPUT
exit $exit_code
- name: Write failure summary
if: always() && steps.tui_tests.outcome != 'success' && steps.tui_tests.outcome != 'skipped'
run: |
echo "## ❌ CLI TUI Tests Failed" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Step outcome:** \`${{ steps.tui_tests.outcome }}\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Test Output" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
if [ -f tui-test-output.log ]; then
cat tui-test-output.log >> $GITHUB_STEP_SUMMARY
else
echo "(no test output captured — process may have been killed before output was flushed)" >> $GITHUB_STEP_SUMMARY
fi
echo '```' >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Debugging" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **TUI traces** are attached as artifacts below — download and inspect them to see terminal state at the point of failure." >> $GITHUB_STEP_SUMMARY
echo "- **To view a trace replay/Run a TUI Trace: ** run \`npx tui-test show-trace path/to/trace/file\` in your terminal" >> $GITHUB_STEP_SUMMARY
echo "- **Full test log** is also attached as an artifact." >> $GITHUB_STEP_SUMMARY
echo "- Tests run with \`retries: 2\` so any failure shown is a consistent failure, not a flake." >> $GITHUB_STEP_SUMMARY
- name: Upload TUI traces
if: always() && steps.tui_tests.outcome != 'success' && steps.tui_tests.outcome != 'skipped'
uses: actions/upload-artifact@v4
with:
name: tui-test-traces
path: tests/e2e/cli/tui-traces/
retention-days: 14
if-no-files-found: warn
- name: Upload test log
if: always() && steps.tui_tests.outcome != 'success' && steps.tui_tests.outcome != 'skipped'
uses: actions/upload-artifact@v4
with:
name: tui-test-log
path: tui-test-output.log
retention-days: 14
if-no-files-found: warn
+15 -8
View File
@@ -1,14 +1,21 @@
name: Smoke Tests
# Temporarily disabled: this workflow built and linked the legacy CLI
# (`cd cli && npm install && npm run build && npm link`) before running the
# smoke-test scenarios. The legacy CLI publish chain has been retired in
# favor of the SDK CLI at `sdk/apps/cli/`. The scenarios under
# `evals/smoke-tests/scenarios/` are CLI-agnostic and should be re-enabled
# once the build step is repointed at the new SDK CLI. Until then, only
# manual `workflow_dispatch` runs are accepted (and will fail in their
# current form).
on:
push:
branches: [main]
paths:
- 'src/core/**'
- 'src/shared/**'
- 'proto/**'
- 'evals/**'
- '.github/workflows/cline-evals-regression.yml'
pull_request:
paths:
- 'src/core/**'
- 'src/shared/**'
- 'proto/**'
- 'evals/**'
- '.github/workflows/cline-evals-regression.yml'
workflow_dispatch:
permissions:
+111
View File
@@ -0,0 +1,111 @@
name: Publish NPM Release
on:
workflow_call:
inputs:
confirm_publish:
description: 'Type "publish" to confirm you want to publish to NPM'
required: true
type: string
permissions:
contents: write # Required for pushing tags
id-token: write # Required for npm trusted publishing (OIDC)
checks: write # Required by test workflow
pull-requests: write # Required by test workflow
jobs:
test:
uses: ./.github/workflows/test.yml
publish-npm-release:
needs: test
name: Publish Cline CLI to NPM
if: github.repository == 'cline/cline' && github.ref == 'refs/heads/main' && inputs.confirm_publish == 'publish'
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "24.x"
registry-url: "https://registry.npmjs.org"
- name: Install root dependencies and CLI dependencies
run: npm ci --include=optional # this will also install cli deps because "cli" in included in root package.json workspaces field
- name: Generate Protos
run: npm run protos
- name: Read release version
id: version
run: |
# Read version from cli/package.json
VERSION=$(node -p "require('./cli/package.json').version")
echo "Release version: $VERSION"
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Build standalone NPM package
env:
TELEMETRY_SERVICE_API_KEY: ${{ secrets.TELEMETRY_SERVICE_API_KEY }}
ERROR_SERVICE_API_KEY: ${{ secrets.ERROR_SERVICE_API_KEY }}
CLINE_ENVIRONMENT: production
OTEL_TELEMETRY_ENABLED: "1"
OTEL_METRICS_EXPORTER: otlp
OTEL_LOGS_EXPORTER: otlp
OTEL_EXPORTER_OTLP_PROTOCOL: ${{ secrets.OTEL_EXPORTER_OTLP_PROTOCOL }}
OTEL_EXPORTER_OTLP_ENDPOINT: ${{ secrets.OTEL_EXPORTER_OTLP_ENDPOINT }}
OTEL_EXPORTER_OTLP_HEADERS: ${{ secrets.OTEL_EXPORTER_OTLP_HEADERS }}
run: node scripts/package-npm.mjs
- name: Verify build output
run: |
echo "Checking dist-standalone directory..."
ls -la dist-standalone/
echo "Verifying CLI binaries..."
ls -lh cli/bin/cline-* || echo "Warning: CLI binaries not found"
echo "Checking package.json in dist-standalone..."
cat dist-standalone/package.json | grep version
- name: Publish to NPM with latest tag
run: |
echo "Publishing version ${{ steps.version.outputs.version }} to NPM with tag 'latest'..."
cd dist-standalone
npm publish --tag latest --access public
- name: Tag release
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag "v${{ steps.version.outputs.version }}-cli"
git push origin "v${{ steps.version.outputs.version }}-cli"
- name: Summary
run: |
echo "✅ Successfully published cline@${{ steps.version.outputs.version }} to NPM with tag 'latest'"
echo ""
echo "📦 Install with: npm install -g cline"
echo "🔗 NPM: https://www.npmjs.com/package/cline/v/${{ steps.version.outputs.version }}"
- name: Post release to Slack
uses: slackapi/slack-github-action@v3.0.1
with:
method: chat.postMessage
token: ${{ secrets.SLACK_RELEASE_BOT_TOKEN }}
payload: |
channel: "C0APVKGGZFC"
text: "Cline CLI v${{ steps.version.outputs.version }}"
blocks:
- type: "section"
text:
type: "mrkdwn"
text: "*Cline CLI v${{ steps.version.outputs.version }}*"
- type: "context"
elements:
- type: "mrkdwn"
text: "<https://www.npmjs.com/package/cline/v/${{ steps.version.outputs.version }}|View on npm>"
+136
View File
@@ -0,0 +1,136 @@
name: Publish NPM Nightly
on:
workflow_call:
inputs:
force_publish:
description: "Force publish even if there are no commits in the last 24 hours"
required: false
type: boolean
default: false
permissions:
contents: read
id-token: write # Required for npm trusted publishing (OIDC)
checks: write # Required by test workflow
pull-requests: write # Required by test workflow
jobs:
test:
uses: ./.github/workflows/test.yml
publish-npm-nightly:
needs: test
name: Publish Cline CLI (Nightly) to NPM
if: github.repository == 'cline/cline' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Check for recent commits
id: check_commits
env:
FORCE_PUBLISH: ${{ inputs.force_publish }}
run: |
if [ "$FORCE_PUBLISH" = "true" ]; then
echo "force_publish enabled, proceeding with publish"
echo "skip=false" >> $GITHUB_OUTPUT
exit 0
fi
if [ $(git rev-list --count HEAD --since="24 hours ago") -eq 0 ]; then
echo "No commits in last 24 hours, skipping publish"
echo "skip=true" >> $GITHUB_OUTPUT
else
echo "Found recent commits, proceeding with publish"
echo "skip=false" >> $GITHUB_OUTPUT
fi
- name: Setup Node.js
if: steps.check_commits.outputs.skip != 'true'
uses: actions/setup-node@v4
with:
node-version: "24.x"
registry-url: "https://registry.npmjs.org"
- name: Install root dependencies and CLI dependencies
if: steps.check_commits.outputs.skip != 'true'
run: npm ci --include=optional # this will also install cli deps because "cli" in included in root package.json workspaces field
- name: Generate Protos
if: steps.check_commits.outputs.skip != 'true'
run: npm run protos
- name: Generate nightly version with timestamp
if: steps.check_commits.outputs.skip != 'true'
id: version
run: |
# Read base version from cli/package.json (e.g., "2.0.0")
BASE_VERSION=$(node -p "require('./cli/package.json').version")
# Generate timestamp (Unix epoch seconds)
TIMESTAMP=$(date +%s)
# Create unique nightly version: 1.0.9-nightly.1736365200
VERSION="${BASE_VERSION}-nightly.${TIMESTAMP}"
echo "Base version: $BASE_VERSION"
echo "Generated nightly version: $VERSION"
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Update cli/package.json with nightly version
if: steps.check_commits.outputs.skip != 'true'
run: |
# Update version with timestamp-based nightly version
node -e "
const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('cli/package.json', 'utf8'));
pkg.version = '${{ steps.version.outputs.version }}';
fs.writeFileSync('cli/package.json', JSON.stringify(pkg, null, '\t'));
"
echo "Using version ${{ steps.version.outputs.version }} for build"
cat cli/package.json | grep '"version"'
- name: Build and package CLI
if: steps.check_commits.outputs.skip != 'true'
env:
TELEMETRY_SERVICE_API_KEY: ${{ secrets.TELEMETRY_SERVICE_API_KEY }}
ERROR_SERVICE_API_KEY: ${{ secrets.ERROR_SERVICE_API_KEY }}
CLINE_ENVIRONMENT: production
OTEL_TELEMETRY_ENABLED: "1"
OTEL_METRICS_EXPORTER: otlp
OTEL_LOGS_EXPORTER: otlp
OTEL_EXPORTER_OTLP_PROTOCOL: ${{ secrets.OTEL_EXPORTER_OTLP_PROTOCOL }}
OTEL_EXPORTER_OTLP_ENDPOINT: ${{ secrets.OTEL_EXPORTER_OTLP_ENDPOINT }}
OTEL_EXPORTER_OTLP_HEADERS: ${{ secrets.OTEL_EXPORTER_OTLP_HEADERS }}
run: node scripts/package-npm.mjs
- name: Verify build output
if: steps.check_commits.outputs.skip != 'true'
run: |
echo "Checking dist-standalone directory..."
ls -la dist-standalone/
echo "Verifying CLI binaries..."
ls -lh cli/bin/cline-* || echo "Warning: CLI binaries not found"
echo "Checking package.json in dist-standalone..."
cat dist-standalone/package.json | grep version
- name: Publish to NPM with nightly tag
if: steps.check_commits.outputs.skip != 'true'
run: |
echo "Publishing version ${{ steps.version.outputs.version }} to NPM with tag 'nightly'..."
cd dist-standalone
npm publish --tag nightly --access public
- name: Summary
if: steps.check_commits.outputs.skip != 'true'
run: |
echo "✅ Successfully published cline@${{ steps.version.outputs.version }} to NPM with tag 'nightly'"
echo ""
echo "📦 Install with: npm install -g cline@nightly"
echo "🔗 NPM: https://www.npmjs.com/package/cline/v/${{ steps.version.outputs.version }}"
+215
View File
@@ -0,0 +1,215 @@
# Build and Pack CLI
#
# Builds a CLI tarball from any branch/commit and publishes it as a GitHub Release.
# Requires write access to the repository (maintainers/collaborators only).
#
# Security: Split into two jobs to isolate untrusted build code from write tokens.
# The build job runs arbitrary ref code with zero permissions. The release job
# only runs trusted GitHub Actions with write scope.
#
# Usage (helper script, auto-detects current branch):
# ./scripts/build-cli-artifact.sh
# ./scripts/build-cli-artifact.sh feature/my-changes
# ./scripts/build-cli-artifact.sh feature/my-changes 1234 # comments on PR
#
# Usage (gh CLI directly):
# gh workflow run pack-cli.yml -f ref=main
# gh workflow run pack-cli.yml -f ref=abc123 -f pr_number=1234
#
# Install the built CLI (no auth required):
# npm install -g https://github.com/cline/cline/releases/download/cli-build-<sha>/cline-<ver>.tgz
#
# Find releases:
# gh release list --limit 10
name: Build and Pack CLI
permissions:
contents: read
on:
workflow_dispatch:
inputs:
ref:
description: 'Branch, tag, or commit SHA to build (leave empty for default branch)'
required: false
type: string
pr_number:
description: 'PR number to comment on with install instructions (optional)'
required: false
type: number
jobs:
# ── Build job: runs untrusted ref code with ZERO permissions ──
build:
name: Build CLI
runs-on: ubuntu-latest
permissions: {}
outputs:
commit_sha: ${{ steps.commit.outputs.sha }}
tarball: ${{ steps.pack.outputs.tarball }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ inputs.ref || github.ref }}
persist-credentials: false
- name: Get commit SHA
id: commit
run: |
COMMIT_SHA=$(git rev-parse --short HEAD)
echo "sha=$COMMIT_SHA" >> $GITHUB_OUTPUT
echo "Building from commit: $COMMIT_SHA"
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20.x"
- name: Install dependencies
run: npm ci --include=optional
- name: Generate Protos
run: npm run protos
- name: Build standalone package
run: node scripts/package-npm.mjs
- name: Create Tarball
id: pack
run: |
cd dist-standalone
TARBALL=$(npm pack)
echo "tarball=$TARBALL" >> $GITHUB_OUTPUT
echo "Created tarball: $TARBALL"
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: cli-tarball
path: dist-standalone/*.tgz
# ── Release job: only trusted Actions code, with write permissions ──
release:
name: Release CLI
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
issues: write
steps:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: cli-tarball
path: dist-standalone
- name: Create GitHub Release
id: create_release
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const path = require('path');
const commit = '${{ needs.build.outputs.commit_sha }}';
const tarball = '${{ needs.build.outputs.tarball }}';
// Delete existing release/tag if re-running for the same commit
const tagName = `cli-build-${commit}`;
try {
const existing = await github.rest.repos.getReleaseByTag({
owner: context.repo.owner,
repo: context.repo.repo,
tag: tagName
});
await github.rest.repos.deleteRelease({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: existing.data.id
});
await github.rest.git.deleteRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: `tags/${tagName}`
});
core.info(`Deleted existing release for ${tagName}`);
} catch (e) {
// Release doesn't exist yet, that's fine
}
// Create a release
const release = await github.rest.repos.createRelease({
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: tagName,
name: `CLI Build (${commit})`,
body: `Automated CLI build from commit ${commit}\n\nInstall with:\n\`\`\`bash\nnpm install -g https://github.com/${context.repo.owner}/${context.repo.repo}/releases/download/${tagName}/${tarball}\n\`\`\``,
draft: false,
prerelease: true
});
// Upload the tarball as a release asset
const tarballPath = path.join('dist-standalone', tarball);
const tarballData = fs.readFileSync(tarballPath);
await github.rest.repos.uploadReleaseAsset({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: release.data.id,
name: tarball,
data: tarballData
});
const downloadUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/releases/download/${tagName}/${tarball}`;
core.setOutput('release_url', release.data.html_url);
core.setOutput('download_url', downloadUrl);
- name: Comment on PR with download instructions
if: inputs.pr_number != ''
uses: actions/github-script@v7
with:
script: |
const commit = '${{ needs.build.outputs.commit_sha }}';
const releaseUrl = '${{ steps.create_release.outputs.release_url }}';
const downloadUrl = '${{ steps.create_release.outputs.download_url }}';
const prNumber = ${{ inputs.pr_number || 0 }};
if (!prNumber) return;
const comment = `## 📦 CLI Build Ready
A CLI build has been created for commit \`${commit}\`.
### Install Directly from URL (No Authentication Required!)
\`\`\`bash
npm install -g ${downloadUrl}
\`\`\`
### Alternative: Download and Install
\`\`\`bash
curl -L ${downloadUrl} -o cline.tgz
npm install -g ./cline.tgz
\`\`\`
📦 [View Release](${releaseUrl})
`;
await github.rest.issues.createComment({
issue_number: prNumber,
owner: context.repo.owner,
repo: context.repo.repo,
body: comment
});
- name: Summary
run: |
echo "✅ CLI build complete!"
echo ""
echo "📦 Release: ${{ steps.create_release.outputs.release_url }}"
echo "🔗 Download URL: ${{ steps.create_release.outputs.download_url }}"
echo ""
echo "Install from anywhere (no authentication required):"
echo " npm install -g ${{ steps.create_release.outputs.download_url }}"
@@ -0,0 +1,60 @@
name: Publish CLI (Trusted)
on:
schedule:
- cron: "0 12 * * *" # 4 AM PST (UTC-8) = 12 UTC
workflow_dispatch:
inputs:
publish_target:
description: "Which publish flow to run"
required: true
default: "main"
type: choice
options:
- main
- nightly
confirm_publish:
description: 'Required when publish_target=main. Type "publish" to confirm release publish.'
required: false
type: string
force_nightly_publish:
description: "Force nightly publish even with no commits in last 24h"
required: false
type: boolean
default: false
permissions:
id-token: write # Required for npm trusted publishing (OIDC)
contents: write # Required because npm-main creates/pushes git tags
checks: write # Required by nested reusable test workflow
pull-requests: write # Required by nested reusable test workflow
jobs:
cli-tui-tests:
uses: ./.github/workflows/cli-tui-tests.yml
publish-main:
needs: cli-tui-tests
if: |
github.repository == 'cline/cline' && (
github.event_name == 'workflow_dispatch' &&
github.event.inputs.publish_target == 'main' &&
github.event.inputs.confirm_publish == 'publish' &&
!endsWith(github.actor, '[bot]')
)
uses: ./.github/workflows/npm-main.yaml
secrets: inherit
with:
confirm_publish: ${{ github.event.inputs.confirm_publish }}
publish-nightly:
needs: cli-tui-tests
if: |
github.repository == 'cline/cline' && (
github.event_name == 'schedule' ||
(github.event_name == 'workflow_dispatch' && github.event.inputs.publish_target == 'nightly')
)
uses: ./.github/workflows/npm-nightly.yaml
secrets: inherit
with:
force_publish: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.force_nightly_publish == 'true' }}
-394
View File
@@ -1,394 +0,0 @@
name: Publish CLI to NPM
on:
schedule:
- cron: "0 12 * * *"
workflow_dispatch:
inputs:
publish_target:
description: "Which publish flow to run"
required: true
default: "main"
type: choice
options:
- main
- nightly
git_tag:
description: "Existing release tag to publish when publish_target=main, for example cli-v0.1.0"
required: false
type: string
confirm_publish:
description: 'Required when publish_target=main. Type "publish" to confirm release publish.'
required: false
type: string
force_nightly_publish:
description: "Force nightly publish even with no commits in last 24h"
required: false
type: boolean
default: false
permissions:
contents: read
id-token: write
defaults:
run:
working-directory: sdk
jobs:
publish-main:
name: Publish cline
permissions:
contents: write
id-token: write
if: |
github.repository == 'cline/cline' &&
github.ref == 'refs/heads/main' &&
github.event_name == 'workflow_dispatch' &&
github.event.inputs.publish_target == 'main' &&
github.event.inputs.confirm_publish == 'publish' &&
!endsWith(github.actor, '[bot]')
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.git_tag }}
fetch-depth: 0
fetch-tags: true
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: "1.3.13"
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "24.x"
registry-url: "https://registry.npmjs.org"
- name: Verify publish tooling
run: |
NPM_VERSION=$(npm --version)
echo "npm ${NPM_VERSION}"
IFS=. read -r major minor patch <<EOF
${NPM_VERSION}
EOF
if [ "$major" -lt 11 ] || { [ "$major" -eq 11 ] && [ "$minor" -lt 5 ]; } || { [ "$major" -eq 11 ] && [ "$minor" -eq 5 ] && [ "$patch" -lt 1 ]; }; then
echo "npm 11.5.1 or newer is required for trusted publishing"
exit 1
fi
- name: Install dependencies
run: bun install
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Validate release tag
id: version
run: |
TAG="${{ github.event.inputs.git_tag }}"
if [ -z "$TAG" ]; then
echo "git_tag is required when publish_target=main"
exit 1
fi
if ! printf "%s\n" "$TAG" | grep -Eq '^cli-v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$'; then
echo "git_tag must look like cli-vX.Y.Z, got: ${TAG}"
exit 1
fi
VERSION="${TAG#cli-v}"
PACKAGE_VERSION=$(node -p "require('./apps/cli/package.json').version")
if [ "$PACKAGE_VERSION" != "$VERSION" ]; then
echo "sdk/apps/cli/package.json version ${PACKAGE_VERSION} does not match ${TAG}"
exit 1
fi
if ! printf "%s\n" "$VERSION" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$'; then
echo "sdk/apps/cli/package.json has invalid version: ${VERSION}"
exit 1
fi
TAG_COMMIT=$(git rev-parse "${TAG}^{commit}")
HEAD_COMMIT=$(git rev-parse HEAD)
if [ "$TAG_COMMIT" != "$HEAD_COMMIT" ]; then
echo "${TAG} does not point at the checked out commit"
exit 1
fi
git fetch origin +main:refs/remotes/origin/main
if ! git merge-base --is-ancestor "$HEAD_COMMIT" origin/main; then
echo "${TAG} is not reachable from origin/main"
exit 1
fi
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
- name: Build SDK packages
run: bun run build:sdk
- name: Run tests
run: bun run test
- name: Build platform binaries
run: bun script/build.ts --install-native-variants --skip-sdk-build
working-directory: sdk/apps/cli
- name: Verify build output
run: |
VERSION="${{ steps.version.outputs.version }}"
EXPECTED=(
"@cline/cli-darwin-arm64"
"@cline/cli-darwin-x64"
"@cline/cli-linux-arm64"
"@cline/cli-linux-x64"
"@cline/cli-windows-arm64"
"@cline/cli-windows-x64"
)
for package_name in "${EXPECTED[@]}"; do
dir="apps/cli/dist/${package_name#@cline/}"
if [ ! -f "$dir/package.json" ]; then
echo "Missing package manifest: $dir/package.json"
exit 1
fi
actual_name=$(node -p "require('./$dir/package.json').name")
actual_version=$(node -p "require('./$dir/package.json').version")
if [ "$actual_name" != "$package_name" ]; then
echo "Expected $package_name, got $actual_name"
exit 1
fi
if [ "$actual_version" != "$VERSION" ]; then
echo "Expected $package_name@$VERSION, got $actual_version"
exit 1
fi
ls -lh "$dir/bin/"
done
- name: Publish to NPM with latest tag
env:
NPM_CONFIG_PROVENANCE: "true"
run: bun script/publish-npm.ts --tag latest
working-directory: sdk/apps/cli
- name: Get Previous CLI Tag
id: prev_tag
run: |
CURRENT_TAG="${{ steps.version.outputs.tag }}"
PREV_TAG=$(git describe --tags --abbrev=0 --match 'cli-v*' "$CURRENT_TAG^" 2>/dev/null || echo "")
echo "prev_tag=$PREV_TAG" >> $GITHUB_OUTPUT
- name: Get Changelog Entry
id: changelog
run: |
# Grab content between the first "## " header and the next one in apps/cli/CHANGELOG.md
CONTENT=$(awk '/^## [0-9]/{if(found) exit; found=1; next} found{print}' apps/cli/CHANGELOG.md)
echo "content<<EOF" >> $GITHUB_OUTPUT
echo "$CONTENT" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ steps.version.outputs.tag }}
name: "CLI v${{ steps.version.outputs.version }}"
body: |
${{ steps.changelog.outputs.content }}
${{ steps.prev_tag.outputs.prev_tag != '' && format('Full Changelog: https://github.com/{0}/compare/{1}...{2}', github.repository, steps.prev_tag.outputs.prev_tag, steps.version.outputs.tag) || '' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Summary
run: |
VERSION="${{ steps.version.outputs.version }}"
echo "Published cline@${VERSION} to npm with dist-tag 'latest'"
echo "Install with: npm install -g cline"
- name: Post release to Slack
uses: slackapi/slack-github-action@v3.0.1
with:
method: chat.postMessage
token: ${{ secrets.SLACK_RELEASE_BOT_TOKEN }}
payload: |
channel: "C0APVKGGZFC"
text: "Cline CLI v${{ steps.version.outputs.version }}"
blocks:
- type: "section"
text:
type: "mrkdwn"
text: "Cline CLI v${{ steps.version.outputs.version }}"
- type: "section"
text:
type: "mrkdwn"
text: ${{ toJSON(steps.changelog.outputs.content) }}
- type: "context"
elements:
- type: "mrkdwn"
text: "<https://www.npmjs.com/package/cline/v/${{ steps.version.outputs.version }}|View on npm>${{ steps.prev_tag.outputs.prev_tag != '' && format(' | Full Changelog: https://github.com/{0}/compare/{1}...{2}', github.repository, steps.prev_tag.outputs.prev_tag, steps.version.outputs.tag) || '' }}"
publish-nightly:
name: Publish cline nightly
permissions:
contents: read
id-token: write
if: |
github.repository == 'cline/cline' &&
github.ref == 'refs/heads/main' &&
(
github.event_name == 'schedule' ||
(
github.event_name == 'workflow_dispatch' &&
github.event.inputs.publish_target == 'nightly'
)
)
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check for recent commits
id: check_commits
env:
FORCE_PUBLISH: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.force_nightly_publish == 'true' }}
run: |
if [ "$FORCE_PUBLISH" = "true" ]; then
echo "force_nightly_publish enabled, proceeding with publish"
echo "skip=false" >> "$GITHUB_OUTPUT"
exit 0
fi
if [ "$(git rev-list --count HEAD --since='24 hours ago')" -eq 0 ]; then
echo "No commits in last 24 hours, skipping publish"
echo "skip=true" >> "$GITHUB_OUTPUT"
else
echo "Found recent commits, proceeding with publish"
echo "skip=false" >> "$GITHUB_OUTPUT"
fi
- name: Setup Bun
if: steps.check_commits.outputs.skip != 'true'
uses: oven-sh/setup-bun@v2
with:
bun-version: "1.3.13"
- name: Setup Node.js
if: steps.check_commits.outputs.skip != 'true'
uses: actions/setup-node@v4
with:
node-version: "24.x"
registry-url: "https://registry.npmjs.org"
- name: Verify publish tooling
if: steps.check_commits.outputs.skip != 'true'
run: |
NPM_VERSION=$(npm --version)
echo "npm ${NPM_VERSION}"
IFS=. read -r major minor patch <<EOF
${NPM_VERSION}
EOF
if [ "$major" -lt 11 ] || { [ "$major" -eq 11 ] && [ "$minor" -lt 5 ]; } || { [ "$major" -eq 11 ] && [ "$minor" -eq 5 ] && [ "$patch" -lt 1 ]; }; then
echo "npm 11.5.1 or newer is required for trusted publishing"
exit 1
fi
- name: Install dependencies
if: steps.check_commits.outputs.skip != 'true'
run: bun install
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build SDK packages
if: steps.check_commits.outputs.skip != 'true'
run: bun run build:sdk
- name: Run tests
if: steps.check_commits.outputs.skip != 'true'
run: bun run test
- name: Generate nightly version
if: steps.check_commits.outputs.skip != 'true'
id: version
run: |
BASE_VERSION=$(node -p "require('./apps/cli/package.json').version")
TIMESTAMP=$(date +%s)
VERSION="${BASE_VERSION}-nightly.${TIMESTAMP}"
echo "Base version: ${BASE_VERSION}"
echo "Generated nightly version: ${VERSION}"
echo "base_version=${BASE_VERSION}" >> "$GITHUB_OUTPUT"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
- name: Update nightly package version
if: steps.check_commits.outputs.skip != 'true'
run: |
VERSION="${{ steps.version.outputs.version }}"
node -e '
const fs = require("node:fs");
const path = "apps/cli/package.json";
const pkg = JSON.parse(fs.readFileSync(path, "utf8"));
pkg.version = process.env.VERSION;
fs.writeFileSync(path, `${JSON.stringify(pkg, null, "\t")}\n`);
'
cat apps/cli/package.json | grep '"version"'
env:
VERSION: ${{ steps.version.outputs.version }}
- name: Build platform binaries
if: steps.check_commits.outputs.skip != 'true'
run: bun script/build.ts --install-native-variants --skip-sdk-build
working-directory: sdk/apps/cli
- name: Verify build output
if: steps.check_commits.outputs.skip != 'true'
run: |
VERSION="${{ steps.version.outputs.version }}"
EXPECTED=(
"@cline/cli-darwin-arm64"
"@cline/cli-darwin-x64"
"@cline/cli-linux-arm64"
"@cline/cli-linux-x64"
"@cline/cli-windows-arm64"
"@cline/cli-windows-x64"
)
for package_name in "${EXPECTED[@]}"; do
dir="apps/cli/dist/${package_name#@cline/}"
if [ ! -f "$dir/package.json" ]; then
echo "Missing package manifest: $dir/package.json"
exit 1
fi
actual_name=$(node -p "require('./$dir/package.json').name")
actual_version=$(node -p "require('./$dir/package.json').version")
if [ "$actual_name" != "$package_name" ]; then
echo "Expected $package_name, got $actual_name"
exit 1
fi
if [ "$actual_version" != "$VERSION" ]; then
echo "Expected $package_name@$VERSION, got $actual_version"
exit 1
fi
ls -lh "$dir/bin/"
done
- name: Publish to NPM with nightly tag
if: steps.check_commits.outputs.skip != 'true'
env:
NPM_CONFIG_PROVENANCE: "true"
run: bun script/publish-npm.ts --tag nightly
working-directory: sdk/apps/cli
- name: Summary
if: steps.check_commits.outputs.skip != 'true'
run: |
VERSION="${{ steps.version.outputs.version }}"
echo "Published cline@${VERSION} to npm with dist-tag 'nightly'"
echo "Install with: npm install -g cline@nightly"
@@ -1,4 +1,4 @@
name: "Publish New SDK Extension Nightly"
name: "Publish SDK Nightly Release"
on:
schedule:
@@ -17,7 +17,7 @@ env:
jobs:
publish:
name: Publish Cline New SDK Extension Nightly
name: Publish Cline (Nightly SDK) Extension
if: github.repository == 'cline/cline' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: PublishNightly
+60 -90
View File
@@ -3,103 +3,73 @@ name: "Publish Nightly Release"
on:
workflow_dispatch:
run-name: "Publish Nightly from ${{ github.ref_name }} @ ${{ github.sha }}"
# Prevent concurrent publish runs on the same branch. The nightly publish script
# generates the extension version from a seconds-resolution timestamp, so parallel
# runs on the same ref can collide on the same version and cause publish failures
# or inconsistent tagging. Runs on different branches proceed independently.
concurrency:
group: publish-nightly-${{ github.ref }}
cancel-in-progress: false
permissions: {}
permissions:
contents: write
packages: write
checks: write
pull-requests: write
jobs:
test:
if: github.repository == 'cline/cline' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dpc/sdk-migration-simpler-login')
permissions:
contents: read
uses: ./.github/workflows/test.yml
test:
uses: ./.github/workflows/test.yml
publish:
needs: test
permissions:
contents: write
name: Publish Cline (Nightly) Extension
if: github.repository == 'cline/cline' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dpc/sdk-migration-simpler-login')
runs-on: ubuntu-latest
environment: PublishNightly
publish:
needs: test
name: Publish Cline (Nightly) Extension
if: github.repository == 'cline/cline'
runs-on: ubuntu-latest
environment: PublishNightly
steps:
- name: Checkout selected branch
uses: actions/checkout@v4
with:
ref: ${{ github.sha }}
lfs: true
persist-credentials: false
steps:
- uses: actions/checkout@v4
with:
lfs: true
- name: Show build source
run: |
echo "Building ref: $GITHUB_REF"
echo "Building sha: $GITHUB_SHA"
git --no-pager log -1 --oneline
- name: Check for recent commits
run: |
if [ $(git rev-list --count HEAD --since="24 hours ago") -eq 0 ]; then
echo "No commits in last 24 hours, exiting"
exit 0
fi
echo "Found recent commits, proceeding with build"
- name: Setup Node.js
uses: actions/setup-node@v4
with:
# Keep publish environment aligned with test workflow/tooling lockfile expectations.
# Newer LTS (Node 24 / npm 11) can make `npm list` fail with ELSPROBLEMS during vsce packaging.
node-version: 22
- name: Setup Node.js
uses: actions/setup-node@v4
with:
# Keep publish environment aligned with test workflow/tooling lockfile expectations.
# Newer LTS (Node 24 / npm 11) can make `npm list` fail with ELSPROBLEMS during vsce packaging.
node-version: 22
- name: Install root dependencies
run: npm ci --include=optional
- name: Install root dependencies
run: npm ci --include=optional
- name: Install webview-ui dependencies
run: cd webview-ui && npm ci --include=optional
- name: Install webview-ui dependencies
run: cd webview-ui && npm ci --include=optional
- name: Install Publishing Tools
run: npm install -g @vscode/vsce ovsx
- name: Install Publishing Tools
run: npm install -g @vscode/vsce ovsx
- name: Verify LFS media assets are resolved
run: |
for FILE in webview-ui/src/assets/cline_kanban_demo.mp4 webview-ui/src/assets/cline_kanban_demo.webm; do
if grep -q "git-lfs.github.com/spec/v1" "$FILE"; then
echo "Error: $FILE is still a Git LFS pointer in CI checkout"
exit 1
fi
done
- name: Verify LFS media assets are resolved
run: |
for FILE in webview-ui/src/assets/cline_kanban_demo.mp4 webview-ui/src/assets/cline_kanban_demo.webm; do
if grep -q "git-lfs.github.com/spec/v1" "$FILE"; then
echo "Error: $FILE is still a Git LFS pointer in CI checkout"
exit 1
fi
done
- name: Publish Nightly Extension
env:
VSCE_PAT: ${{ secrets.VSCE_PAT }}
OVSX_PAT: ${{ secrets.OVSX_PAT }}
TELEMETRY_SERVICE_API_KEY: ${{ secrets.TELEMETRY_SERVICE_API_KEY }}
ERROR_SERVICE_API_KEY: ${{ secrets.ERROR_SERVICE_API_KEY }}
CLINE_ENVIRONMENT: production
# OpenTelemetry production defaults (can be overridden at runtime)
OTEL_TELEMETRY_ENABLED: ${{ secrets.OTEL_TELEMETRY_ENABLED }}
OTEL_LOGS_EXPORTER: otlp
OTEL_METRICS_EXPORTER: otlp
OTEL_EXPORTER_OTLP_PROTOCOL: ${{ secrets.OTEL_EXPORTER_OTLP_PROTOCOL }}
OTEL_EXPORTER_OTLP_ENDPOINT: ${{ secrets.OTEL_EXPORTER_OTLP_ENDPOINT }}
OTEL_EXPORTER_OTLP_HEADERS: ${{ secrets.OTEL_EXPORTER_OTLP_HEADERS }}
run: npm run publish:marketplace:nightly
- name: Tag published commit
env:
GH_TOKEN: ${{ github.token }}
run: |
SAFE_REF=$(echo "$GITHUB_REF_NAME" | tr '/[:upper:]' '-[:lower:]' | tr -cd 'a-z0-9._-')
SHORT_SHA=$(git rev-parse --short=12 HEAD)
TIMESTAMP=$(date -u +"%Y%m%d%H%M%S")
TAG="nightly-${SAFE_REF}-${TIMESTAMP}-${SHORT_SHA}"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag -a "$TAG" -m "Cline Nightly published from ${GITHUB_REF_NAME} at ${GITHUB_SHA}"
# Use an explicit HTTPS remote with GH_TOKEN because checkout was run with
# persist-credentials: false, so actions/checkout did not persist a git credential helper.
git push "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" "refs/tags/${TAG}"
echo "Tagged published commit: $TAG"
- name: Publish Nightly Extension
env:
VSCE_PAT: ${{ secrets.VSCE_PAT }}
OVSX_PAT: ${{ secrets.OVSX_PAT }}
TELEMETRY_SERVICE_API_KEY: ${{ secrets.TELEMETRY_SERVICE_API_KEY }}
ERROR_SERVICE_API_KEY: ${{ secrets.ERROR_SERVICE_API_KEY }}
CLINE_ENVIRONMENT: production
# OpenTelemetry production defaults (can be overridden at runtime)
OTEL_TELEMETRY_ENABLED: ${{ secrets.OTEL_TELEMETRY_ENABLED }}
OTEL_LOGS_EXPORTER: otlp
OTEL_METRICS_EXPORTER: otlp
OTEL_EXPORTER_OTLP_PROTOCOL: ${{ secrets.OTEL_EXPORTER_OTLP_PROTOCOL }}
OTEL_EXPORTER_OTLP_ENDPOINT: ${{ secrets.OTEL_EXPORTER_OTLP_ENDPOINT }}
OTEL_EXPORTER_OTLP_HEADERS: ${{ secrets.OTEL_EXPORTER_OTLP_HEADERS }}
run: npm run publish:marketplace:nightly
-269
View File
@@ -1,269 +0,0 @@
name: Publish Main SDK Packages
on:
workflow_dispatch:
inputs:
channel:
description: "Publish channel"
required: true
type: choice
options:
- nightly
- latest
default: nightly
force_publish:
description: "Force publish even if there are no commits in the last 24 hours"
required: false
type: boolean
default: false
confirm_publish:
description: 'Required when channel=latest. Type "publish" to confirm release publish.'
required: false
type: string
schedule:
# Run nightly at 2:00 AM UTC
- cron: "0 2 * * *"
defaults:
run:
working-directory: sdk
jobs:
test:
permissions:
contents: read
uses: ./.github/workflows/sdk-test.yml
publish-sdk:
needs: test
name: Publish SDK Packages
permissions:
contents: write
id-token: write
if: |
github.repository == 'cline/cline' &&
github.ref == 'refs/heads/main' &&
(
github.event_name != 'workflow_dispatch' ||
inputs.channel != 'latest' ||
(
inputs.confirm_publish == 'publish' &&
!endsWith(github.actor, '[bot]')
)
)
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Determine publish channel
id: channel
run: |
# Default to nightly for scheduled runs
if [ "${{ github.event_name }}" = "schedule" ]; then
echo "channel=nightly" >> $GITHUB_OUTPUT
else
echo "channel=${{ inputs.channel }}" >> $GITHUB_OUTPUT
fi
- name: Check for recent commits
id: check_commits
run: |
CHANNEL="${{ steps.channel.outputs.channel }}"
# Always publish for latest (production) releases
if [ "$CHANNEL" = "latest" ]; then
echo "Production release requested, proceeding with publish"
echo "skip=false" >> $GITHUB_OUTPUT
exit 0
fi
if [ "${{ inputs.force_publish }}" = "true" ]; then
echo "force_publish enabled, proceeding with publish"
echo "skip=false" >> $GITHUB_OUTPUT
exit 0
fi
if [ "$(git rev-list --count HEAD --since="24 hours ago")" -eq 0 ]; then
echo "No commits in last 24 hours, skipping publish"
echo "skip=true" >> $GITHUB_OUTPUT
else
echo "Found recent commits, proceeding with publish"
echo "skip=false" >> $GITHUB_OUTPUT
fi
- name: Verify trusted publishing context
if: steps.check_commits.outputs.skip != 'true'
run: |
if [ -z "${ACTIONS_ID_TOKEN_REQUEST_TOKEN:-}" ] || [ -z "${ACTIONS_ID_TOKEN_REQUEST_URL:-}" ]; then
echo "GitHub OIDC request environment is unavailable. Ensure this job has id-token: write for npm trusted publishing."
exit 1
fi
echo "GitHub OIDC request environment is available for npm trusted publishing."
- name: Setup Bun
if: steps.check_commits.outputs.skip != 'true'
uses: oven-sh/setup-bun@v2
with:
bun-version: "1.3.13"
- name: Setup Node.js
if: steps.check_commits.outputs.skip != 'true'
uses: actions/setup-node@v4
with:
node-version: "24.x"
registry-url: "https://registry.npmjs.org"
- name: Verify publish tooling
if: steps.check_commits.outputs.skip != 'true'
run: |
NPM_VERSION=$(npm --version)
echo "npm ${NPM_VERSION}"
IFS=. read -r major minor patch <<EOF
${NPM_VERSION}
EOF
if [ "$major" -lt 11 ] || { [ "$major" -eq 11 ] && [ "$minor" -lt 5 ]; } || { [ "$major" -eq 11 ] && [ "$minor" -eq 5 ] && [ "$patch" -lt 1 ]; }; then
echo "npm 11.5.1 or newer is required for trusted publishing"
exit 1
fi
- name: Install dependencies
if: steps.check_commits.outputs.skip != 'true'
run: bun install
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build SDK
if: steps.check_commits.outputs.skip != 'true'
run: bun run build:sdk
- name: Generate shared version
if: steps.check_commits.outputs.skip != 'true'
id: version
run: |
CHANNEL="${{ steps.channel.outputs.channel }}"
BASE_VERSION=$(node -p "require('./packages/llms/package.json').version")
if [ "$CHANNEL" = "nightly" ]; then
TIMESTAMP=$(date +%s)
VERSION="${BASE_VERSION}-nightly.${TIMESTAMP}"
else
VERSION="$BASE_VERSION"
fi
echo "Base version: $BASE_VERSION"
echo "Channel: $CHANNEL"
echo "Publish version: $VERSION"
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Update all package versions and lockfile
if: steps.check_commits.outputs.skip != 'true'
run: bun scripts/version.ts "${{ steps.version.outputs.version }}"
- name: Verify publishability
if: steps.check_commits.outputs.skip != 'true'
run: bun scripts/check-publish.ts
- name: Prepare package tarball directory
if: steps.check_commits.outputs.skip != 'true'
run: mkdir -p "$RUNNER_TEMP/sdk-npm-packs"
# Pack with Bun so workspace/catalog protocols are resolved in the tarball,
# then publish that tarball with npm so npm trusted publishing can use GitHub OIDC.
# Publish sequentially in dependency order: shared → llms → agents → core → sdk
- name: Publish @cline/shared
if: steps.check_commits.outputs.skip != 'true'
env:
NPM_CONFIG_PROVENANCE: "true"
run: |
CHANNEL="${{ steps.channel.outputs.channel }}"
echo "Publishing @cline/shared@${{ steps.version.outputs.version }} with tag '${CHANNEL}'..."
cd packages/shared
TARBALL=$(bun pm pack --destination "$RUNNER_TEMP/sdk-npm-packs" --quiet)
npm publish "$RUNNER_TEMP/sdk-npm-packs/$(basename "$TARBALL")" --tag "$CHANNEL" --access public
- name: Publish @cline/llms
if: steps.check_commits.outputs.skip != 'true'
env:
NPM_CONFIG_PROVENANCE: "true"
run: |
CHANNEL="${{ steps.channel.outputs.channel }}"
echo "Publishing @cline/llms@${{ steps.version.outputs.version }} with tag '${CHANNEL}'..."
cd packages/llms
TARBALL=$(bun pm pack --destination "$RUNNER_TEMP/sdk-npm-packs" --quiet)
npm publish "$RUNNER_TEMP/sdk-npm-packs/$(basename "$TARBALL")" --tag "$CHANNEL" --access public
- name: Publish @cline/agents
if: steps.check_commits.outputs.skip != 'true'
env:
NPM_CONFIG_PROVENANCE: "true"
run: |
CHANNEL="${{ steps.channel.outputs.channel }}"
echo "Publishing @cline/agents@${{ steps.version.outputs.version }} with tag '${CHANNEL}'..."
cd packages/agents
TARBALL=$(bun pm pack --destination "$RUNNER_TEMP/sdk-npm-packs" --quiet)
npm publish "$RUNNER_TEMP/sdk-npm-packs/$(basename "$TARBALL")" --tag "$CHANNEL" --access public
- name: Publish @cline/core
if: steps.check_commits.outputs.skip != 'true'
env:
NPM_CONFIG_PROVENANCE: "true"
run: |
CHANNEL="${{ steps.channel.outputs.channel }}"
echo "Publishing @cline/core@${{ steps.version.outputs.version }} with tag '${CHANNEL}'..."
cd packages/core
TARBALL=$(bun pm pack --destination "$RUNNER_TEMP/sdk-npm-packs" --quiet)
npm publish "$RUNNER_TEMP/sdk-npm-packs/$(basename "$TARBALL")" --tag "$CHANNEL" --access public
- name: Publish @cline/sdk
if: steps.check_commits.outputs.skip != 'true'
env:
NPM_CONFIG_PROVENANCE: "true"
run: |
CHANNEL="${{ steps.channel.outputs.channel }}"
echo "Publishing @cline/sdk@${{ steps.version.outputs.version }} with tag '${CHANNEL}'..."
cd packages/sdk
TARBALL=$(bun pm pack --destination "$RUNNER_TEMP/sdk-npm-packs" --quiet)
npm publish "$RUNNER_TEMP/sdk-npm-packs/$(basename "$TARBALL")" --tag "$CHANNEL" --access public
- name: Create package tags for production publish
if: steps.check_commits.outputs.skip != 'true' && steps.channel.outputs.channel == 'latest'
run: |
VERSION="${{ steps.version.outputs.version }}"
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
for PKG in shared llms agents core sdk; do
TAG="sdk/${PKG}/v${VERSION}"
if git rev-parse -q --verify "refs/tags/${TAG}" >/dev/null; then
echo "Tag already exists locally: ${TAG}"
else
git tag -a "${TAG}" -m "@cline/${PKG}@${VERSION}"
echo "Created tag: ${TAG}"
fi
# Ensure remote has the tag; this is idempotent if tag already exists remotely.
git push origin "refs/tags/${TAG}"
done
- name: Summary
if: steps.check_commits.outputs.skip != 'true'
run: |
VERSION="${{ steps.version.outputs.version }}"
CHANNEL="${{ steps.channel.outputs.channel }}"
echo "Published SDK packages with tag '${CHANNEL}':"
echo " - @cline/shared@${VERSION}"
echo " - @cline/llms@${VERSION}"
echo " - @cline/agents@${VERSION}"
echo " - @cline/core@${VERSION}"
echo " - @cline/sdk@${VERSION}"
if [ "$CHANNEL" = "latest" ]; then
echo "Created git tags:"
echo " - sdk/shared/v${VERSION}"
echo " - sdk/llms/v${VERSION}"
echo " - sdk/agents/v${VERSION}"
echo " - sdk/core/v${VERSION}"
echo " - sdk/sdk/v${VERSION}"
fi
-7
View File
@@ -160,13 +160,6 @@ jobs:
OTEL_EXPORTER_OTLP_HEADERS: ${{ secrets.OTEL_EXPORTER_OTLP_HEADERS }}
RELEASE_TYPE: ${{ github.event.inputs.release-type }}
run: |
# Swap README.marketplace.md into README.md so both the GitHub
# release artifact (vsce package below) and the marketplace
# publish (npm run publish:marketplace below, which swaps
# internally as an idempotent no-op) ship the same README.
node scripts/marketplace-readme.mjs swap-in
trap 'node scripts/marketplace-readme.mjs restore' EXIT
# Required to generate the .vsix
vsce package --allow-package-secrets sendgrid --out "cline-${{ steps.get_version.outputs.version }}.vsix"
-112
View File
@@ -1,112 +0,0 @@
name: SDK Tests
on:
push:
branches:
- main
paths:
- "sdk/**"
- ".github/workflows/sdk-test.yml"
workflow_dispatch:
pull_request:
branches:
- main
paths:
- "sdk/**"
- ".github/workflows/sdk-test.yml"
workflow_call:
permissions:
contents: read
defaults:
run:
working-directory: sdk
jobs:
quality-checks:
runs-on: ubuntu-latest
name: Quality Checks
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: "1.3.13"
- name: Install dependencies
run: bun install
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Typecheck
run: |
bun run build:sdk
bun run -F @cline/cli build
bun run types
- name: Lint & Format
run: bun run lint
test:
needs: quality-checks
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
node-version: "24.x"
- os: windows-latest
node-version: "24.x"
runs-on: ${{ matrix.os }}
name: Test (${{ matrix.os }}, Node ${{ matrix.node-version }})
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: "1.3.13"
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
run: bun install
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build SDK
id: build_sdk_step
run: bun run build:sdk
- name: Build CLI
id: build_cli_step
if: ${{ !cancelled() && steps.build_sdk_step.outcome == 'success' }}
run: bun -F @cline/cli build
- name: Run Tests
if: ${{ !cancelled() && steps.build_sdk_step.outcome == 'success' && steps.build_cli_step.outcome == 'success' && matrix.os != 'windows-latest' }}
run: bun run test
- name: Run SDK Tests (Windows)
if: ${{ !cancelled() && steps.build_sdk_step.outcome == 'success' && steps.build_cli_step.outcome == 'success' && matrix.os == 'windows-latest' }}
run: bun -F './packages/**' test
- name: Smoke test SQLite under Node
if: ${{ !cancelled() && steps.build_sdk_step.outcome == 'success' && matrix.os != 'windows-latest' }}
timeout-minutes: 10
run: bun scripts/ci-node-smoke.ts
- name: Run TUI e2e tests
if: ${{ !cancelled() && steps.build_sdk_step.outcome == 'success' && steps.build_cli_step.outcome == 'success' && matrix.os == 'ubuntu-latest' && matrix.node-version == '24.x' }}
run: bun -F @cline/cli test:e2e:cli:tui
- name: Verify packages are publishable
if: ${{ !cancelled() && steps.build_sdk_step.outcome == 'success' && steps.build_cli_step.outcome == 'success' && matrix.os == 'ubuntu-latest' && matrix.node-version == '24.x' }}
run: bun scripts/check-publish.ts
+2
View File
@@ -13,6 +13,8 @@ on:
# Set default permissions for all jobs
permissions:
contents: read # Needed to check out code
checks: write # Needed to report test results
pull-requests: write # Needed to add comments/annotations to PRs
jobs:
quality-checks:
-4
View File
@@ -56,7 +56,3 @@ evals/smoke-tests/results/
secrets.json
tui-traces
tests/**/cache
# Backup created by scripts/marketplace-readme.mjs while publishing.
# Should never be committed: only exists if a publish aborts mid-swap.
.README.github.bak
-9
View File
@@ -25,15 +25,6 @@ eslint-rules/**
# cli
cli/**
# sdk (separate monorepo with its own build/release pipeline)
sdk/**
# Source-of-truth for the marketplace README (the .vsix only ever sees the
# README.md that scripts/marketplace-readme.mjs swaps into place). The backup
# only exists if a publish aborts mid-swap; neither should ship in the .vsix.
README.marketplace.md
.README.github.bak
# Custom
**/demo.gif
.nvmrc
-2
View File
@@ -1,3 +1 @@
@.clinerules/general.md
@.clinerules/network.md
@.clinerules/cli.md
+6 -5
View File
@@ -42,14 +42,15 @@ We also welcome contributions to our [documentation](https://github.com/cline/cl
```bash
code cline
```
3. Install [bun](https://bun.com)
4. Install the necessary dependencies for the extension and webview-gui:
3. Install the necessary dependencies for the extension and webview-gui:
```bash
npm run install:all
cd sdk && bun run build && cd ..
```
5. Generate Protocol Buffer files (required before first build):
6. Launch by pressing `F5` (or `Run`->`Start Debugging`) to open a new VSCode window with the extension loaded. (You may need to install the [esbuild problem matchers extension](https://marketplace.visualstudio.com/items?itemName=connor4312.esbuild-problem-matchers) if you run into issues building the project.)
4. Generate Protocol Buffer files (required before first build):
```bash
npm run protos
```
5. Launch by pressing `F5` (or `Run`->`Start Debugging`) to open a new VSCode window with the extension loaded. (You may need to install the [esbuild problem matchers extension](https://marketplace.visualstudio.com/items?itemName=connor4312.esbuild-problem-matchers) if you run into issues building the project.)
-146
View File
@@ -1,146 +0,0 @@
<div align="center"><sub>
English | <a href="https://github.com/cline/cline/blob/main/locales/es/README.md" target="_blank">Español</a> | <a href="https://github.com/cline/cline/blob/main/locales/de/README.md" target="_blank">Deutsch</a> | <a href="https://github.com/cline/cline/blob/main/locales/ja/README.md" target="_blank">日本語</a> | <a href="https://github.com/cline/cline/blob/main/locales/zh-cn/README.md" target="_blank">简体中文</a> | <a href="https://github.com/cline/cline/blob/main/locales/zh-tw/README.md" target="_blank">繁體中文</a> | <a href="https://github.com/cline/cline/blob/main/locales/ko/README.md" target="_blank">한국어</a>
</sub></div>
# Cline
<div align="center">
<table>
<tbody>
<td align="center">
<a href="https://marketplace.visualstudio.com/items?itemName=saoudrizwan.claude-dev" target="_blank"><strong>Download on VS Marketplace</strong></a>
</td>
<td align="center">
<a href="https://discord.gg/cline" target="_blank"><strong>Discord</strong></a>
</td>
<td align="center">
<a href="https://www.reddit.com/r/cline/" target="_blank"><strong>r/cline</strong></a>
</td>
<td align="center">
<a href="https://github.com/cline/cline/discussions/categories/feature-requests?discussions_q=is%3Aopen+category%3A%22Feature+Requests%22+sort%3Atop" target="_blank"><strong>Feature Requests</strong></a>
</td>
<td align="center">
<a href="https://docs.cline.bot/getting-started/for-new-coders" target="_blank"><strong>Getting Started</strong></a>
</td>
</tbody>
</table>
</div>
Meet Cline, an AI assistant that can use your **CLI** a**N**d **E**ditor.
Thanks to [Claude Sonnet's agentic coding capabilities](https://www.anthropic.com/claude/sonnet), Cline can handle complex software development tasks step-by-step. With tools that let him create & edit files, explore large projects, use the browser, and execute terminal commands (after you grant permission), he can assist you in ways that go beyond code completion or tech support. Cline can even use the Model Context Protocol (MCP) to create new tools and extend his own capabilities. While autonomous AI scripts traditionally run in sandboxed environments, this extension provides a human-in-the-loop GUI to approve every file change and terminal command, providing a safe and accessible way to explore the potential of agentic AI.
1. Enter your task and add images to convert mockups into functional apps or fix bugs with screenshots.
2. Cline starts by analyzing your file structure & source code ASTs, running regex searches, and reading relevant files to get up to speed in existing projects. By carefully managing what information is added to context, Cline can provide valuable assistance even for large, complex projects without overwhelming the context window.
3. Once Cline has the information he needs, he can:
- Create and edit files + monitor linter/compiler errors along the way, letting him proactively fix issues like missing imports and syntax errors on his own.
- Execute commands directly in your terminal and monitor their output as he works, letting him e.g., react to dev server issues after editing a file.
- For web development tasks, Cline can launch the site in a headless browser, click, type, scroll, and capture screenshots + console logs, allowing him to fix runtime errors and visual bugs.
4. When a task is completed, Cline will present the result to you with a terminal command like `open -a "Google Chrome" index.html`, which you run with a click of a button.
> [!TIP]
> Follow [this guide](https://docs.cline.bot/features/customization/opening-cline-in-sidebar) to open Cline on the right side of your editor. This lets you use Cline side-by-side with your file explorer, and see how he changes your workspace more clearly.
---
<img align="right" width="340" src="https://github.com/user-attachments/assets/3cf21e04-7ce9-4d22-a7b9-ba2c595e88a4">
### Use any API and Model
Cline supports API providers like OpenRouter, Anthropic, OpenAI, Google Gemini, AWS Bedrock, Azure, GCP Vertex, Cerebras and Groq. You can also configure any OpenAI compatible API, or use a local model through LM Studio/Ollama. If you're using OpenRouter, the extension fetches their latest model list, allowing you to use the newest models as soon as they're available.
The extension also keeps track of total tokens and API usage cost for the entire task loop and individual requests, keeping you informed of spend every step of the way.
<!-- Transparent pixel to create line break after floating image -->
<img width="2000" height="0" src="https://github.com/user-attachments/assets/ee14e6f7-20b8-4391-9091-8e8e25561929"><br>
<img align="left" width="370" src="https://github.com/user-attachments/assets/81be79a8-1fdb-4028-9129-5fe055e01e76">
### Run Commands in Terminal
Thanks to the new [shell integration updates in VSCode v1.93](https://code.visualstudio.com/updates/v1_93#_terminal-shell-integration-api), Cline can execute commands directly in your terminal and receive the output. This allows him to perform a wide range of tasks, from installing packages and running build scripts to deploying applications, managing databases, and executing tests, all while adapting to your dev environment & toolchain to get the job done right.
For long running processes like dev servers, use the "Proceed While Running" button to let Cline continue in the task while the command runs in the background. As Cline works hell be notified of any new terminal output along the way, letting him react to issues that may come up, such as compile-time errors when editing files.
<!-- Transparent pixel to create line break after floating image -->
<img width="2000" height="0" src="https://github.com/user-attachments/assets/ee14e6f7-20b8-4391-9091-8e8e25561929"><br>
<img align="right" width="400" src="https://github.com/user-attachments/assets/c5977833-d9b8-491e-90f9-05f9cd38c588">
### Create and Edit Files
Cline can create and edit files directly in your editor, presenting you a diff view of the changes. You can edit or revert Cline's changes directly in the diff view editor, or provide feedback in chat until you're satisfied with the result. Cline also monitors linter/compiler errors (missing imports, syntax errors, etc.) so he can fix issues that come up along the way on his own.
All changes made by Cline are recorded in your file's Timeline, providing an easy way to track and revert modifications if needed.
<!-- Transparent pixel to create line break after floating image -->
<img width="2000" height="0" src="https://github.com/user-attachments/assets/ee14e6f7-20b8-4391-9091-8e8e25561929"><br>
<img align="left" width="370" src="https://github.com/user-attachments/assets/bc2e85ba-dfeb-4fe6-9942-7cfc4703cbe5">
### Use the Browser
With Claude Sonnet's new [Computer Use](https://www.anthropic.com/news/3-5-models-and-computer-use) capability, Cline can launch a browser, click elements, type text, and scroll, capturing screenshots and console logs at each step. This allows for interactive debugging, end-to-end testing, and even general web use! This gives him autonomy to fixing visual bugs and runtime issues without you needing to handhold and copy-pasting error logs yourself.
Try asking Cline to "test the app", and watch as he runs a command like `npm run dev`, launches your locally running dev server in a browser, and performs a series of tests to confirm that everything works. [See a demo here.](https://x.com/sdrzn/status/1850880547825823989)
<!-- Transparent pixel to create line break after floating image -->
<img width="2000" height="0" src="https://github.com/user-attachments/assets/ee14e6f7-20b8-4391-9091-8e8e25561929"><br>
<img align="right" width="350" src="https://github.com/user-attachments/assets/ac0efa14-5c1f-4c26-a42d-9d7c56f5fadd">
### "add a tool that..."
Thanks to the [Model Context Protocol](https://github.com/modelcontextprotocol), Cline can extend his capabilities through custom tools. While you can use [community-made servers](https://github.com/modelcontextprotocol/servers), Cline can instead create and install tools tailored to your specific workflow. Just ask Cline to "add a tool" and he will handle everything, from creating a new MCP server to installing it into the extension. These custom tools then become part of Cline's toolkit, ready to use in future tasks.
- "add a tool that fetches Jira tickets": Retrieve ticket ACs and put Cline to work
- "add a tool that manages AWS EC2s": Check server metrics and scale instances up or down
- "add a tool that pulls the latest PagerDuty incidents": Fetch details and ask Cline to fix bugs
<!-- Transparent pixel to create line break after floating image -->
<img width="2000" height="0" src="https://github.com/user-attachments/assets/ee14e6f7-20b8-4391-9091-8e8e25561929"><br>
<img align="left" width="360" src="https://github.com/user-attachments/assets/7fdf41e6-281a-4b4b-ac19-020b838b6970">
### Add Context
**`@url`:** Paste in a URL for the extension to fetch and convert to markdown, useful when you want to give Cline the latest docs
**`@problems`:** Add workspace errors and warnings ('Problems' panel) for Cline to fix
**`@file`:** Adds a file's contents so you don't have to waste API requests approving read file (+ type to search files)
**`@folder`:** Adds folder's files all at once to speed up your workflow even more
<!-- Transparent pixel to create line break after floating image -->
<img width="2000" height="0" src="https://github.com/user-attachments/assets/ee14e6f7-20b8-4391-9091-8e8e25561929"><br>
<img align="right" width="350" src="https://github.com/user-attachments/assets/140c8606-d3bf-41b9-9a1f-4dbf0d4c90cb">
### Checkpoints: Compare and Restore
As Cline works through a task, the extension takes a snapshot of your workspace at each step. You can use the 'Compare' button to see a diff between the snapshot and your current workspace, and the 'Restore' button to roll back to that point.
For example, when working with a local web server, you can use 'Restore Workspace Only' to quickly test different versions of your app, then use 'Restore Task and Workspace' when you find the version you want to continue building from. This lets you safely explore different approaches without losing progress.
<!-- Transparent pixel to create line break after floating image -->
<img width="2000" height="0" src="https://github.com/user-attachments/assets/ee14e6f7-20b8-4391-9091-8e8e25561929"><br>
## Contributing
To contribute to the project, start with our [Contributing Guide](CONTRIBUTING.md) to learn the basics. You can also join our [Discord](https://discord.gg/cline) to chat with other contributors in the `#contributors` channel. If you're looking for full-time work, check out our open positions on our [careers page](https://cline.bot/join-us)!
## Enterprise
Get the same Cline experience with enterprise-grade controls: SSO (SAML/OIDC), global policies and configuration, observability with audit trails, private networking (VPC/private link), and self-hosted or on-prem deployments, and enterprise support. Learn more at our [enterprise page](https://cline.bot/enterprise) or [talk to us](https://cline.bot/contact-sales).
## License
[Apache 2.0 © 2026 Cline Bot Inc.](./LICENSE)
+83 -172
View File
@@ -1,20 +1,13 @@
<p align="center">
<img src="assets/icons/icon.png" width="80" alt="Cline" />
</p>
<h1 align="center">Cline</h1>
<p align="center">
The open source coding agent in your IDE and terminal.
</p>
<div align="center">
<div align="center"><sub>
English | <a href="https://github.com/cline/cline/blob/main/locales/es/README.md" target="_blank">Español</a> | <a href="https://github.com/cline/cline/blob/main/locales/de/README.md" target="_blank">Deutsch</a> | <a href="https://github.com/cline/cline/blob/main/locales/ja/README.md" target="_blank">日本語</a> | <a href="https://github.com/cline/cline/blob/main/locales/zh-cn/README.md" target="_blank">简体中文</a> | <a href="https://github.com/cline/cline/blob/main/locales/zh-tw/README.md" target="_blank">繁體中文</a> | <a href="https://github.com/cline/cline/blob/main/locales/ko/README.md" target="_blank">한국어</a>
</sub></div>
# Cline
<div align="center">
<table>
<tbody>
<td align="center">
<a href="https://docs.cline.bot" target="_blank"><strong>Docs</strong></a>
<a href="https://marketplace.visualstudio.com/items?itemName=saoudrizwan.claude-dev" target="_blank"><strong>Download on VS Marketplace</strong></a>
</td>
<td align="center">
<a href="https://discord.gg/cline" target="_blank"><strong>Discord</strong></a>
@@ -26,209 +19,127 @@ The open source coding agent in your IDE and terminal.
<a href="https://github.com/cline/cline/discussions/categories/feature-requests?discussions_q=is%3Aopen+category%3A%22Feature+Requests%22+sort%3Atop" target="_blank"><strong>Feature Requests</strong></a>
</td>
<td align="center">
<a href="https://cline.bot/join-us" target="_blank"><strong>Join us!</strong></a>
<a href="https://docs.cline.bot/getting-started/for-new-coders" target="_blank"><strong>Getting Started</strong></a>
</td>
</tbody>
</table>
</div>
</div>
Meet Cline, an AI assistant that can use your **CLI** a**N**d **E**ditor.
<br>
Thanks to [Claude Sonnet's agentic coding capabilities](https://www.anthropic.com/claude/sonnet), Cline can handle complex software development tasks step-by-step. With tools that let him create & edit files, explore large projects, use the browser, and execute terminal commands (after you grant permission), he can assist you in ways that go beyond code completion or tech support. Cline can even use the Model Context Protocol (MCP) to create new tools and extend his own capabilities. While autonomous AI scripts traditionally run in sandboxed environments, this extension provides a human-in-the-loop GUI to approve every file change and terminal command, providing a safe and accessible way to explore the potential of agentic AI.
<div align="center">
<table>
<tr>
<td align="center" width="50%">
1. Enter your task and add images to convert mockups into functional apps or fix bugs with screenshots.
2. Cline starts by analyzing your file structure & source code ASTs, running regex searches, and reading relevant files to get up to speed in existing projects. By carefully managing what information is added to context, Cline can provide valuable assistance even for large, complex projects without overwhelming the context window.
3. Once Cline has the information he needs, he can:
- Create and edit files + monitor linter/compiler errors along the way, letting him proactively fix issues like missing imports and syntax errors on his own.
- Execute commands directly in your terminal and monitor their output as he works, letting him e.g., react to dev server issues after editing a file.
- For web development tasks, Cline can launch the site in a headless browser, click, type, scroll, and capture screenshots + console logs, allowing him to fix runtime errors and visual bugs.
4. When a task is completed, Cline will present the result to you with a terminal command like `open -a "Google Chrome" index.html`, which you run with a click of a button.
### CLI
Run Cline in your terminal.
Interactive chat or fully headless
for CI/CD and scripting.
```
npm i -g cline
```
<a href="./sdk/apps/cli/README.md">Learn more</a>
<br><br>
</td>
<td align="center" width="50%">
### Kanban
Run many agents in parallel from a
web-based task board. Each card gets its own
worktree, auto-commit, and dependency chains.
```
npm i -g kanban
```
<a href="https://github.com/cline/kanban">Learn more</a>
<br><br>
</td>
</tr>
<tr>
<td align="center" width="50%">
### VS Code Extension
AI coding assistant in your editor.
Create files, run commands, browse the web,
and use tools with human-in-the-loop approval.
<a href="https://marketplace.visualstudio.com/items?itemName=saoudrizwan.claude-dev">Install from VS Marketplace</a>
<br><br>
</td>
<td align="center" width="50%">
### JetBrains Plugin
The same Cline experience in IntelliJ IDEA,
PyCharm, WebStorm, GoLand, and the rest of
the JetBrains family.
<a href="https://plugins.jetbrains.com/plugin/28247-cline">Install from JetBrains Marketplace</a>
<br><br>
</td>
</tr>
</table>
</div>
<div align="center">
<table>
<tr>
<td align="center">
### SDK
Build your own AI agents and integrations powered by the same engine that runs the CLI, Kanban, VS Code extension, and JetBrains plugin. Custom tools, multi-agent teams, connectors, scheduled automations, and more.
```
npm install @cline/sdk
```
<a href="https://docs.cline.bot/cline-sdk/overview">Documentation</a>
<br><br>
</td>
</tr>
</table>
</div>
> [!TIP]
> Follow [this guide](https://docs.cline.bot/features/customization/opening-cline-in-sidebar) to open Cline on the right side of your editor. This lets you use Cline side-by-side with your file explorer, and see how he changes your workspace more clearly.
---
## Index
<img align="right" width="340" src="https://github.com/user-attachments/assets/3cf21e04-7ce9-4d22-a7b9-ba2c595e88a4">
| Product | Description | Location |
|---------|------------|--------------|
| **SDK** | Node.js programmatic agent API and extension exports. | [`sdk/`](https://github.com/cline/cline/tree/main/sdk) |
| **CLI** | Terminal UI, headless mode, shell commands, and CLI-specific flows. | [`sdk/apps/cli/`](https://github.com/cline/cline/tree/main/sdk/apps/cli) |
| **VS Code Extension** | The Marketplace extension and extension host integration. | [`/`](https://github.com/cline/cline/tree/main) (WIP migrating) |
| **JetBrains Plugin** | JetBrains-hosted client that talks to the shared agent core. | Currently we are not open-sourcing JetBrains plugins |
| **Kanban** | Web-based multi-agent task board. | [`cline/kanban`](https://github.com/cline/kanban). |
| **Docs site** | Public documentation pages. | [`docs/`](https://docs.cline.bot/) |
### Use any API and Model
## Edits Code Across Your Project
Cline supports API providers like OpenRouter, Anthropic, OpenAI, Google Gemini, AWS Bedrock, Azure, GCP Vertex, Cerebras and Groq. You can also configure any OpenAI compatible API, or use a local model through LM Studio/Ollama. If you're using OpenRouter, the extension fetches their latest model list, allowing you to use the newest models as soon as they're available.
Cline reads your project structure, understands the relationships between files, and makes coordinated changes across your codebase. It monitors linter and compiler errors as it works, fixing issues like missing imports, type mismatches, and syntax errors before you even see them. In VS Code and JetBrains, every edit shows up as a diff you can review, modify, or revert. All changes are tracked with checkpoints, so you can easily undo the agent's work.
The extension also keeps track of total tokens and API usage cost for the entire task loop and individual requests, keeping you informed of spend every step of the way.
## Runs Bash Commands
<!-- Transparent pixel to create line break after floating image -->
Cline executes commands directly in your terminal and watches the output in real time. Install packages, run build scripts, execute tests, deploy applications, manage databases. For long-running processes like dev servers, Cline continues working in the background and reacts to new output as it appears, catching compile errors, test failures, and server crashes as they happen.
<img width="2000" height="0" src="https://github.com/user-attachments/assets/ee14e6f7-20b8-4391-9091-8e8e25561929"><br>
## Plan and Act
<img align="left" width="370" src="https://github.com/user-attachments/assets/81be79a8-1fdb-4028-9129-5fe055e01e76">
Toggle between Plan mode and Act mode. In Plan mode, Cline explores your codebase, asks clarifying questions, and lays out a strategy. Once you're aligned, switch to Act mode and Cline executes the plan. Every file edit and terminal command requires your approval, so you stay in control of what actually changes. Or toggle auto-approve and let Cline run autonomously.
### Run Commands in Terminal
## Rules and Skills
Thanks to the new [shell integration updates in VSCode v1.93](https://code.visualstudio.com/updates/v1_93#_terminal-shell-integration-api), Cline can execute commands directly in your terminal and receive the output. This allows him to perform a wide range of tasks, from installing packages and running build scripts to deploying applications, managing databases, and executing tests, all while adapting to your dev environment & toolchain to get the job done right.
Define project-specific rules in `.clinerules` files that guide how Cline works in your codebase: coding standards, architecture conventions, deployment procedures, testing requirements. Rules are picked up automatically by the CLI, VS Code extension, and JetBrains plugin. Use skills to let the model load specific rules when needed.
For long running processes like dev servers, use the "Proceed While Running" button to let Cline continue in the task while the command runs in the background. As Cline works hell be notified of any new terminal output along the way, letting him react to issues that may come up, such as compile-time errors when editing files.
## Works With Every Model
<!-- Transparent pixel to create line break after floating image -->
Cline is not locked to a single AI provider. Use whichever model fits your workflow:
<img width="2000" height="0" src="https://github.com/user-attachments/assets/ee14e6f7-20b8-4391-9091-8e8e25561929"><br>
| Provider | Models |
|----------|--------|
| Anthropic | Claude Opus, Sonnet, Haiku |
| OpenAI | GPT series model |
| Google | Gemini series model |
| OpenRouter | 200+ models from any provider |
| Vercel AI Gateway | Models through Vercel AI Gateway |
| AWS Bedrock | Claude, Llama, and more |
| Azure / GCP Vertex | All hosted models |
| Cerebras / Groq | Fast inference models |
| Ollama / LM Studio | Run local models on your machine |
| Any OpenAI-compatible API | Self-hosted or third-party endpoints |
<img align="right" width="400" src="https://github.com/user-attachments/assets/c5977833-d9b8-491e-90f9-05f9cd38c588">
## Extend With Plugins or MCP Servers
### Create and Edit Files
Extend Cline's capabilities with plugins. Using the SDK, register tools and lifecycle hooks programmatically through the plugin system for logging, auditing, policy enforcement, or adding domain-specific capabilities. Simple plugin example below.
Cline can create and edit files directly in your editor, presenting you a diff view of the changes. You can edit or revert Cline's changes directly in the diff view editor, or provide feedback in chat until you're satisfied with the result. Cline also monitors linter/compiler errors (missing imports, syntax errors, etc.) so he can fix issues that come up along the way on his own.
```typescript
import { Agent, createTool } from "@cline/sdk"
All changes made by Cline are recorded in your file's Timeline, providing an easy way to track and revert modifications if needed.
const deployTool = createTool({
name: "deploy",
description: "Deploy the current branch to staging.",
inputSchema: { type: "object", properties: { env: { type: "string" } }, required: ["env"] },
execute: async (input) => {
// your deployment logic
},
})
<!-- Transparent pixel to create line break after floating image -->
const agent = new Agent({ tools: [deployTool], /* ... */ })
```
...or use [MCP servers](https://github.com/modelcontextprotocol) to connect to databases, query APIs, manage cloud infrastructure, and interact with external systems. Use [community-built servers](https://github.com/modelcontextprotocol/servers) or ask Cline to create custom tools on the fly. In the CLI, manage servers with `cline mcp`.
<img width="2000" height="0" src="https://github.com/user-attachments/assets/ee14e6f7-20b8-4391-9091-8e8e25561929"><br>
## Multi-Agent Teams
<img align="left" width="370" src="https://github.com/user-attachments/assets/bc2e85ba-dfeb-4fe6-9942-7cfc4703cbe5">
Coordinate multiple agents working together on complex tasks. A coordinator agent breaks the work into subtasks and delegates to specialist agents, each with their own tools and context. Team state persists across sessions so you can pick up where you left off.
### Use the Browser
```bash
cline --team-name auth-sprint "Plan and implement user authentication with tests"
```
With Claude Sonnet's new [Computer Use](https://www.anthropic.com/news/3-5-models-and-computer-use) capability, Cline can launch a browser, click elements, type text, and scroll, capturing screenshots and console logs at each step. This allows for interactive debugging, end-to-end testing, and even general web use! This gives him autonomy to fixing visual bugs and runtime issues without you needing to handhold and copy-pasting error logs yourself.
## Scheduled Agents
Try asking Cline to "test the app", and watch as he runs a command like `npm run dev`, launches your locally running dev server in a browser, and performs a series of tests to confirm that everything works. [See a demo here.](https://x.com/sdrzn/status/1850880547825823989)
Run agents on cron schedules for recurring automations. Daily PR summaries, weekly dependency checks, codebase health reports. Schedules persist across restarts and run independently of any terminal session.
<!-- Transparent pixel to create line break after floating image -->
```bash
cline schedule create "PR summary" \
--cron "0 9 * * MON-FRI" \
--prompt "List all open PRs and their review status" \
--workspace /path/to/repo
```
<img width="2000" height="0" src="https://github.com/user-attachments/assets/ee14e6f7-20b8-4391-9091-8e8e25561929"><br>
## Connect to Slack, Telegram, Discord, and More
<img align="right" width="350" src="https://github.com/user-attachments/assets/ac0efa14-5c1f-4c26-a42d-9d7c56f5fadd">
Chat with your agent from any messaging platform: Telegram, Slack, Discord, Google Chat, WhatsApp, and Linear. Each conversation thread maps to an agent session with full context. Set up access control to restrict who can interact with your agent.
### "add a tool that..."
```bash
cline connect telegram -m my_bot -k $BOT_TOKEN
cline connect slack --token $SLACK_TOKEN --signing-secret $SECRET --base-url $URL
```
Thanks to the [Model Context Protocol](https://github.com/modelcontextprotocol), Cline can extend his capabilities through custom tools. While you can use [community-made servers](https://github.com/modelcontextprotocol/servers), Cline can instead create and install tools tailored to your specific workflow. Just ask Cline to "add a tool" and he will handle everything, from creating a new MCP server to installing it into the extension. These custom tools then become part of Cline's toolkit, ready to use in future tasks.
## Headless CLI for CI/CD
- "add a tool that fetches Jira tickets": Retrieve ticket ACs and put Cline to work
- "add a tool that manages AWS EC2s": Check server metrics and scale instances up or down
- "add a tool that pulls the latest PagerDuty incidents": Fetch details and ask Cline to fix bugs
Run Cline with zero interaction for scripting and automation. Pipe input, get JSON output, chain commands, integrate into CI/CD pipelines.
<!-- Transparent pixel to create line break after floating image -->
```bash
cline "Run tests and fix any failures"
git diff origin/main | cline "Review these changes for issues"
cline --json "List all TODO comments" | jq -r 'select(.type == "agent_event" and .event.text) | .event.text'
```
<img width="2000" height="0" src="https://github.com/user-attachments/assets/ee14e6f7-20b8-4391-9091-8e8e25561929"><br>
<img align="left" width="360" src="https://github.com/user-attachments/assets/7fdf41e6-281a-4b4b-ac19-020b838b6970">
### Add Context
**`@url`:** Paste in a URL for the extension to fetch and convert to markdown, useful when you want to give Cline the latest docs
**`@problems`:** Add workspace errors and warnings ('Problems' panel) for Cline to fix
**`@file`:** Adds a file's contents so you don't have to waste API requests approving read file (+ type to search files)
**`@folder`:** Adds folder's files all at once to speed up your workflow even more
<!-- Transparent pixel to create line break after floating image -->
<img width="2000" height="0" src="https://github.com/user-attachments/assets/ee14e6f7-20b8-4391-9091-8e8e25561929"><br>
<img align="right" width="350" src="https://github.com/user-attachments/assets/140c8606-d3bf-41b9-9a1f-4dbf0d4c90cb">
### Checkpoints: Compare and Restore
As Cline works through a task, the extension takes a snapshot of your workspace at each step. You can use the 'Compare' button to see a diff between the snapshot and your current workspace, and the 'Restore' button to roll back to that point.
For example, when working with a local web server, you can use 'Restore Workspace Only' to quickly test different versions of your app, then use 'Restore Task and Workspace' when you find the version you want to continue building from. This lets you safely explore different approaches without losing progress.
<!-- Transparent pixel to create line break after floating image -->
<img width="2000" height="0" src="https://github.com/user-attachments/assets/ee14e6f7-20b8-4391-9091-8e8e25561929"><br>
## Contributing
Start with the [Contributing Guide](CONTRIBUTING.md). Join our [Discord](https://discord.gg/cline) and head to the `#contributors` channel to connect with other contributors. Check our [careers page](https://cline.bot/join-us) for full-time roles.
To contribute to the project, start with our [Contributing Guide](CONTRIBUTING.md) to learn the basics. You can also join our [Discord](https://discord.gg/cline) to chat with other contributors in the `#contributors` channel. If you're looking for full-time work, check out our open positions on our [careers page](https://cline.bot/join-us)!
## Enterprise
Get the same Cline experience with enterprise-grade controls: SSO (SAML/OIDC), global policies and configuration, observability with audit trails, private networking (VPC/private link), and self-hosted or on-prem deployments, and enterprise support. Learn more at our [enterprise page](https://cline.bot/enterprise) or [talk to us](https://cline.bot/contact-sales).
## License
+1 -3
View File
@@ -179,9 +179,7 @@
"!!**/*.js",
"!!**/scripts/**",
"!!**/*.tsx",
"!!**/testing-platform/**",
// ACP mode must redirect console to stderr - this is intentional
"!!cli/src/acp/index.ts"
"!!**/testing-platform/**"
]
},
{
+1 -2
View File
@@ -32,7 +32,7 @@
"package": "npm pack --pack-destination ./dist",
"build": "npm run typecheck && npx tsx esbuild.mts && npm run build:types",
"build:production": "npm run typecheck && npx tsx esbuild.mts --production && npm run build:types",
"build:types": "(npx tsc -p tsconfig.lib.json || true) && cp dist/types/cli/src/exports.d.ts dist/lib.d.ts && mkdir -p dist/agent && cp dist/types/cli/src/agent/ClineAgent.d.ts dist/types/cli/src/agent/ClineSessionEmitter.d.ts dist/types/cli/src/agent/public-types.d.ts dist/agent/ && rm -rf dist/types",
"build:types": "(npx tsc -p tsconfig.lib.json || true) && cp dist/types/cli/src/exports.d.ts dist/lib.d.ts && rm -rf dist/types dist/agent",
"watch": "npx tsx esbuild.mts --watch",
"dev": "IS_DEV=true && npm run link && npm run watch ; npm run unlink",
"clean": "rimraf dist",
@@ -82,7 +82,6 @@
"vitest": "^4.0.17"
},
"dependencies": {
"@agentclientprotocol/sdk": "^0.13.1",
"@vscode/ripgrep": "^1.15.9",
"aws4fetch": "^1.0.20",
"chalk": "^5.3.0",
-248
View File
@@ -1,248 +0,0 @@
/**
* ACP-based implementation of DiffViewProvider that uses the ACP client's
* filesystem capabilities for reading and writing files.
*
* This provider attempts to use the ACP client's fs/read_text_file and
* fs/write_text_file methods when available, falling back to the
* FileEditProvider's local filesystem implementation otherwise.
*
* @module acp
*/
import type * as acp from "@agentclientprotocol/sdk"
import { workspaceResolver } from "@core/workspace"
import { createDirectoriesForFile } from "@utils/fs"
import { getCwd } from "@utils/path"
import * as fs from "fs/promises"
import * as iconv from "iconv-lite"
import { HostProvider } from "@/hosts/host-provider"
import { FileEditProvider } from "@/integrations/editor/FileEditProvider"
import { detectEncoding } from "@/integrations/misc/extract-text"
import type { FileDiagnostics } from "@/shared/proto/index.cline"
import { Logger } from "@/shared/services/Logger"
/**
* A function that resolves the current session ID.
* This is used by ACPDiffViewProvider to get the session ID at runtime,
* since the provider may be created before a session exists.
*/
export type SessionIdResolver = () => string | undefined
/**
* A DiffViewProvider implementation that uses the ACP client's filesystem
* capabilities when available, with fallback to local filesystem operations.
*
* This class extends FileEditProvider and overrides the file I/O methods to
* use the ACP protocol's fs/read_text_file and fs/write_text_file requests
* when the client supports these capabilities. This allows the editor (client)
* to handle file operations, which enables features like:
* - Reading unsaved editor state
* - Tracking file modifications in the editor
* - Proper integration with the client's undo/redo stack
*/
export class ACPDiffViewProvider extends FileEditProvider {
private readonly connection: acp.AgentSideConnection
private readonly clientCapabilities: acp.ClientCapabilities | undefined
private readonly sessionIdResolver: SessionIdResolver
/**
* Creates a new ACPDiffViewProvider.
*
* @param connection - The ACP agent-side connection for making requests
* @param clientCapabilities - The client's advertised capabilities
* @param sessionIdResolver - A function that returns the current session ID
*/
constructor(
connection: acp.AgentSideConnection,
clientCapabilities: acp.ClientCapabilities | undefined,
sessionIdResolver: SessionIdResolver,
) {
super()
this.connection = connection
this.clientCapabilities = clientCapabilities
this.sessionIdResolver = sessionIdResolver
}
/**
* Gets the current session ID, or throws if no session is active.
*/
private getSessionId(): string {
const sessionId = this.sessionIdResolver()
if (!sessionId) {
throw new Error("No active ACP session. Cannot perform file operation.")
}
return sessionId
}
/**
* Check if the client supports file read operations.
*/
private canReadFile(): boolean {
return this.clientCapabilities?.fs?.readTextFile === true
}
/**
* Check if the client supports file write operations.
*/
private canWriteFile(): boolean {
return this.clientCapabilities?.fs?.writeTextFile === true
}
/**
* Opens a file for editing, using ACP fs capabilities when available.
*
* If the client supports fs/read_text_file, this method will read the file
* content via the ACP connection, which may include unsaved editor state.
* Otherwise, it falls back to the FileEditProvider's local fs implementation.
*/
override async open(relPath: string, options?: { displayPath?: string }): Promise<void> {
// If we can't read files via ACP, fall back to FileEditProvider
if (!this.canReadFile()) {
Logger.debug("[ACPDiffViewProvider] Client does not support fs.readTextFile, falling back to local fs")
return super.open(relPath, options)
}
// Set up state - this replicates the DiffViewProvider.open() logic
// but uses ACP for file reading instead of local fs
this.isEditing = true
const cwd = await getCwd()
const absolutePathResolved = workspaceResolver.resolveWorkspacePath(cwd, relPath, "ACPDiffViewProvider.open.absolutePath")
this.absolutePath = typeof absolutePathResolved === "string" ? absolutePathResolved : absolutePathResolved.absolutePath
this.relPath = options?.displayPath ?? relPath
const fileExists = this.editType === "modify"
// Read file content
if (fileExists) {
// Try to save any dirty state in the editor first
try {
await HostProvider.workspace.saveOpenDocumentIfDirty({
filePath: this.absolutePath!,
})
} catch {
// Ignore errors - the host may not support this
}
// Read file content via ACP
try {
Logger.debug("[ACPDiffViewProvider] Reading file via ACP:", this.absolutePath)
const response = await this.connection.readTextFile({
sessionId: this.getSessionId(),
path: this.absolutePath!,
})
this.originalContent = response.content
// ACP always returns UTF-8 text content
this.fileEncoding = "utf8"
Logger.debug("[ACPDiffViewProvider] Read file successfully, length:", response.content.length)
} catch (error) {
// If ACP read fails, fall back to local fs
Logger.debug("[ACPDiffViewProvider] ACP read failed, falling back to local fs:", error)
const fileBuffer = await fs.readFile(this.absolutePath!)
this.fileEncoding = await detectEncoding(fileBuffer)
this.originalContent = iconv.decode(fileBuffer, this.fileEncoding)
}
} else {
this.originalContent = ""
this.fileEncoding = "utf8"
}
// Create directories for new files
const createdDirs = await createDirectoriesForFile(this.absolutePath!)
// Store for potential cleanup - access via the private field workaround
;(this as any).createdDirs = createdDirs
// Make sure the file exists before we proceed
if (!fileExists) {
// For new files, write via ACP if possible, otherwise local fs
if (this.canWriteFile()) {
try {
await this.connection.writeTextFile({
sessionId: this.getSessionId(),
path: this.absolutePath!,
content: "",
})
} catch {
// Fall back to local fs
await fs.writeFile(this.absolutePath!, "")
}
} else {
await fs.writeFile(this.absolutePath!, "")
}
}
// Get diagnostics before editing
let preDiagnostics: FileDiagnostics[] = []
try {
preDiagnostics = (await HostProvider.workspace.getDiagnostics({})).fileDiagnostics
} catch {
preDiagnostics = []
}
;(this as any).preDiagnostics = preDiagnostics
// Call the parent's openDiffEditor to set up in-memory document content
await this.openDiffEditor()
await this.scrollEditorToLine(0)
;(this as any).streamedLines = []
}
/**
* Scrolls the editor to a specific line.
* No-op for file-based providers, but needed for protected access.
*/
protected override async scrollEditorToLine(_line: number): Promise<void> {
// No-op: No visual editor to scroll
}
/**
* Opens the diff editor.
*/
protected override async openDiffEditor(): Promise<void> {
// Set up in-memory document content from the original content
// no-op: No visual editor to open
}
/**
* Saves the document content, using ACP fs capabilities when available.
*
* If the client supports fs/write_text_file, this method will write the file
* content via the ACP connection. Otherwise, it falls back to the
* FileEditProvider's local fs implementation.
*/
protected override async saveDocument(): Promise<Boolean> {
// If we can't write files via ACP, fall back to FileEditProvider
if (!this.canWriteFile()) {
Logger.debug("[ACPDiffViewProvider] Client does not support fs.writeTextFile, falling back to local fs")
return super.saveDocument()
}
const content = await this.getContent()
if (!this.absolutePath || content === undefined) {
return false
}
try {
Logger.debug("[ACPDiffViewProvider] Writing file via ACP:", {
path: this.absolutePath,
contentLength: content.length,
})
await this.connection.writeTextFile({
sessionId: this.getSessionId(),
path: this.absolutePath,
content: content,
})
Logger.debug("[ACPDiffViewProvider] Write file successfully")
return true
} catch (error) {
// If ACP write fails, fall back to local fs
Logger.debug("[ACPDiffViewProvider] ACP write failed, falling back to local fs:", error)
return super.saveDocument()
}
}
}
-414
View File
@@ -1,414 +0,0 @@
/**
* ACP Host Bridge Client Provider
*
* Implements HostBridgeClientProvider for ACP mode, providing stub implementations
* of the 4 required service clients. These clients conform to the interfaces in
* host-bridge-client-types.ts and will use ACP connection capabilities where applicable.
*
* @module acp
*/
import type * as acp from "@agentclientprotocol/sdk"
import type {
DiffServiceClientInterface,
EnvServiceClientInterface,
WindowServiceClientInterface,
WorkspaceServiceClientInterface,
} from "@generated/hosts/host-bridge-client-types"
import type { HostBridgeClientProvider, StreamingCallbacks } from "@hosts/host-provider-types"
import * as proto from "@shared/proto/index"
import { ClineClient } from "@/shared/cline"
import { Logger } from "@/shared/services/Logger"
/**
* Function type that resolves the current session ID.
* Returns undefined if no session is active.
*/
export type SessionIdResolver = () => string | undefined
/**
* Function type that resolves the current working directory.
* Returns undefined if no cwd is available (will fall back to process.cwd()).
*/
export type CwdResolver = () => string | undefined
/**
* ACP implementation of DiffService client.
*
* Handles diff operations for the ACP environment. Most operations are stubs
* that will be implemented in the next phase using ACP extension methods or
* the fs capabilities (readTextFile/writeTextFile).
*/
class ACPDiffServiceClient implements DiffServiceClientInterface {
async openDiff(_request: proto.host.OpenDiffRequest): Promise<proto.host.OpenDiffResponse> {
// Next phase: Could use ACP client capabilities to open a diff view in the editor.
// This would involve sending an ACP extension notification/request to the client
// to display a side-by-side diff of the original vs modified content.
Logger.debug("[ACPDiffServiceClient] openDiff called (stub)")
return proto.host.OpenDiffResponse.create({})
}
async getDocumentText(request: proto.host.GetDocumentTextRequest): Promise<proto.host.GetDocumentTextResponse> {
// Next phase: Use connection.readTextFile if clientCapabilities.fs.readTextFile is available.
// This would read the current document content from the editor, including any unsaved changes.
// For now, return empty content.
Logger.debug("[ACPDiffServiceClient] getDocumentText called (stub)", { diffId: request.diffId })
return proto.host.GetDocumentTextResponse.create({ content: "" })
}
async replaceText(_request: proto.host.ReplaceTextRequest): Promise<proto.host.ReplaceTextResponse> {
// Next phase: Use connection.writeTextFile if clientCapabilities.fs.writeTextFile is available.
// This would replace text in the document at the specified range.
Logger.debug("[ACPDiffServiceClient] replaceText called (stub)")
return proto.host.ReplaceTextResponse.create({})
}
async scrollDiff(_request: proto.host.ScrollDiffRequest): Promise<proto.host.ScrollDiffResponse> {
// Next phase: Send ACP extension notification to scroll the diff view to a specific line.
// No visual editor in ACP mode by default, so this is a no-op.
Logger.debug("[ACPDiffServiceClient] scrollDiff called (stub)")
return proto.host.ScrollDiffResponse.create({})
}
async truncateDocument(_request: proto.host.TruncateDocumentRequest): Promise<proto.host.TruncateDocumentResponse> {
// Next phase: Read file using readTextFile, truncate content, write back using writeTextFile.
// This is used to truncate a document to a specific line count.
Logger.debug("[ACPDiffServiceClient] truncateDocument called (stub)")
return proto.host.TruncateDocumentResponse.create({})
}
async saveDocument(_request: proto.host.SaveDocumentRequest): Promise<proto.host.SaveDocumentResponse> {
// Next phase: Use connection.writeTextFile to persist the document to disk.
// This saves the current document content to the file system.
Logger.debug("[ACPDiffServiceClient] saveDocument called (stub)")
return proto.host.SaveDocumentResponse.create({})
}
async closeAllDiffs(_request: proto.host.CloseAllDiffsRequest): Promise<proto.host.CloseAllDiffsResponse> {
// Next phase: Send ACP extension notification to close all diff views in the editor.
// No visual diff views in ACP mode by default, so this is a no-op.
Logger.debug("[ACPDiffServiceClient] closeAllDiffs called (stub)")
return proto.host.CloseAllDiffsResponse.create({})
}
async openMultiFileDiff(_request: proto.host.OpenMultiFileDiffRequest): Promise<proto.host.OpenMultiFileDiffResponse> {
// Next phase: Send ACP extension notification to open a multi-file diff view.
// This would display changes across multiple files in the editor.
Logger.debug("[ACPDiffServiceClient] openMultiFileDiff called (stub)")
return proto.host.OpenMultiFileDiffResponse.create({})
}
}
/**
* ACP implementation of EnvService client.
*
* Handles environment operations like clipboard access, version info, and telemetry.
* Most operations are stubs that will be implemented using ACP extension methods.
*/
class ACPEnvServiceClient implements EnvServiceClientInterface {
private readonly version: string
constructor(_clientCapabilities: acp.ClientCapabilities | undefined, _sessionIdResolver: SessionIdResolver, version: string) {
this.version = version
}
async debugLog(request: proto.cline.StringRequest): Promise<proto.cline.Empty> {
Logger.debug(request.value)
return proto.cline.Empty.create()
}
async clipboardWriteText(_request: proto.cline.StringRequest): Promise<proto.cline.Empty> {
Logger.debug("[ACPEnvServiceClient] clipboardWriteText called (stub)")
return proto.cline.Empty.create()
}
async clipboardReadText(_request: proto.cline.EmptyRequest): Promise<proto.cline.String> {
Logger.debug("[ACPEnvServiceClient] clipboardReadText called (stub)")
return proto.cline.String.create({ value: "" })
}
async getHostVersion(_request: proto.cline.EmptyRequest): Promise<proto.host.GetHostVersionResponse> {
// Return version info for the ACP agent.
return proto.host.GetHostVersionResponse.create({
version: this.version,
platform: "Cline ACP Agent",
clineType: ClineClient.Cli,
})
}
async getIdeRedirectUri(_request: proto.cline.EmptyRequest): Promise<proto.cline.String> {
Logger.debug("[ACPEnvServiceClient] getIdeRedirectUri called (stub)")
return proto.cline.String.create({ value: "" })
}
async getTelemetrySettings(_request: proto.cline.EmptyRequest): Promise<proto.host.GetTelemetrySettingsResponse> {
// Return telemetry as disabled by default in ACP mode.
return proto.host.GetTelemetrySettingsResponse.create({
isEnabled: proto.host.Setting.DISABLED,
})
}
subscribeToTelemetrySettings(
_request: proto.cline.EmptyRequest,
callbacks: StreamingCallbacks<proto.host.TelemetrySettingsEvent>,
): () => void {
// Send initial telemetry settings (disabled) and return unsubscribe function.
callbacks.onResponse(
proto.host.TelemetrySettingsEvent.create({
isEnabled: proto.host.Setting.DISABLED,
}),
)
// Return no-op unsubscribe function
return () => {}
}
async shutdown(_request: proto.cline.EmptyRequest): Promise<proto.cline.Empty> {
// Next phase: Graceful ACP connection shutdown.
// This would cleanly close the ACP connection and release resources.
Logger.debug("[ACPEnvServiceClient] shutdown called (stub)")
return proto.cline.Empty.create()
}
async openExternal(request: proto.cline.StringRequest): Promise<proto.cline.Empty> {
const url = request.value || ""
if (url) {
Logger.debug(`[ACPEnvServiceClient] openExternal: ${url}`)
const { openUrlInBrowser } = await import("../utils/browser")
await openUrlInBrowser(url)
}
return proto.cline.Empty.create()
}
}
/**
* ACP implementation of WindowService client.
*
* Handles window/UI operations like showing documents, dialogs, and messages.
* Most operations are stubs that will be implemented using ACP extension methods.
*/
class ACPWindowServiceClient implements WindowServiceClientInterface {
constructor(_clientCapabilities: acp.ClientCapabilities | undefined, _sessionIdResolver: SessionIdResolver) {}
async showTextDocument(request: proto.host.ShowTextDocumentRequest): Promise<proto.host.TextEditorInfo> {
// Next phase: Send ACP extension request to open document in the editor.
// This would tell the ACP client to open the specified file.
Logger.debug("[ACPWindowServiceClient] showTextDocument called (stub)", { path: request.path })
return proto.host.TextEditorInfo.create({
documentPath: request.path,
})
}
async showOpenDialogue(_request: proto.host.ShowOpenDialogueRequest): Promise<proto.host.SelectedResources> {
// Next phase: Send ACP extension request for file picker dialog.
// This would display a file open dialog in the ACP client.
Logger.debug("[ACPWindowServiceClient] showOpenDialogue called (stub)")
return proto.host.SelectedResources.create({ paths: [] })
}
async showMessage(request: proto.host.ShowMessageRequest): Promise<proto.host.SelectedResponse> {
// Next phase: Send ACP extension notification to show message in the editor.
// This would display an information/warning/error message to the user.
Logger.debug("[ACPWindowServiceClient] showMessage called (stub)", {
message: request.message,
type: request.type,
})
return proto.host.SelectedResponse.create({})
}
async showInputBox(_request: proto.host.ShowInputBoxRequest): Promise<proto.host.ShowInputBoxResponse> {
// Next phase: Send ACP extension request for input dialog.
// This would display an input box for user text entry.
Logger.debug("[ACPWindowServiceClient] showInputBox called (stub)")
return proto.host.ShowInputBoxResponse.create({ response: "" })
}
async showSaveDialog(_request: proto.host.ShowSaveDialogRequest): Promise<proto.host.ShowSaveDialogResponse> {
// Next phase: Send ACP extension request for save dialog.
// This would display a file save dialog in the ACP client.
Logger.debug("[ACPWindowServiceClient] showSaveDialog called (stub)")
return proto.host.ShowSaveDialogResponse.create({ selectedPath: "" })
}
async openFile(request: proto.host.OpenFileRequest): Promise<proto.host.OpenFileResponse> {
// Next phase: Send ACP extension request to open file in the editor.
// This would open the specified file in the ACP client's editor.
Logger.debug("[ACPWindowServiceClient] openFile called (stub)", { filePath: request.filePath })
return proto.host.OpenFileResponse.create({})
}
async openSettings(_request: proto.host.OpenSettingsRequest): Promise<proto.host.OpenSettingsResponse> {
// Next phase: Send ACP extension request to open settings panel.
// This would open the settings/preferences in the ACP client.
Logger.debug("[ACPWindowServiceClient] openSettings called (stub)")
return proto.host.OpenSettingsResponse.create({})
}
async getOpenTabs(_request: proto.host.GetOpenTabsRequest): Promise<proto.host.GetOpenTabsResponse> {
// Next phase: Send ACP extension request to list open tabs/documents.
// This would return a list of currently open files in the editor.
Logger.debug("[ACPWindowServiceClient] getOpenTabs called (stub)")
return proto.host.GetOpenTabsResponse.create({ paths: [] })
}
async getVisibleTabs(_request: proto.host.GetVisibleTabsRequest): Promise<proto.host.GetVisibleTabsResponse> {
// Next phase: Send ACP extension request to list visible tabs.
// This would return a list of visible tabs/panes in the editor.
Logger.debug("[ACPWindowServiceClient] getVisibleTabs called (stub)")
return proto.host.GetVisibleTabsResponse.create({ paths: [] })
}
async getActiveEditor(_request: proto.host.GetActiveEditorRequest): Promise<proto.host.GetActiveEditorResponse> {
// Next phase: Send ACP extension request to get active editor info.
// This would return information about the currently focused editor.
Logger.debug("[ACPWindowServiceClient] getActiveEditor called (stub)")
return proto.host.GetActiveEditorResponse.create({})
}
}
/**
* ACP implementation of WorkspaceService client.
*
* Handles workspace operations like getting paths, diagnostics, and terminal commands.
* Uses the cwdResolver to get the current working directory, falling back to process.cwd().
*/
class ACPWorkspaceServiceClient implements WorkspaceServiceClientInterface {
private readonly _clientCapabilities: acp.ClientCapabilities | undefined
private readonly cwdResolver: CwdResolver
constructor(
clientCapabilities: acp.ClientCapabilities | undefined,
_sessionIdResolver: SessionIdResolver,
cwdResolver: CwdResolver,
) {
this._clientCapabilities = clientCapabilities
this.cwdResolver = cwdResolver
}
/**
* Get the current working directory, using the resolver if available,
* otherwise falling back to process.cwd().
*/
private getCwd(): string {
return this.cwdResolver() ?? process.cwd()
}
async getWorkspacePaths(_request: proto.host.GetWorkspacePathsRequest): Promise<proto.host.GetWorkspacePathsResponse> {
// Return the current working directory from the resolver.
const cwd = this.getCwd()
Logger.debug("[ACPWorkspaceServiceClient] getWorkspacePaths called", { cwd })
return proto.host.GetWorkspacePathsResponse.create({
paths: [cwd],
})
}
async saveOpenDocumentIfDirty(
_request: proto.host.SaveOpenDocumentIfDirtyRequest,
): Promise<proto.host.SaveOpenDocumentIfDirtyResponse> {
// Next phase: Use ACP extension or fs.writeTextFile to save dirty documents.
// This would save any unsaved changes in the specified document.
Logger.debug("[ACPWorkspaceServiceClient] saveOpenDocumentIfDirty called (stub)")
return proto.host.SaveOpenDocumentIfDirtyResponse.create({})
}
async getDiagnostics(_request: proto.host.GetDiagnosticsRequest): Promise<proto.host.GetDiagnosticsResponse> {
// Next phase: Send ACP extension request for diagnostics (errors, warnings).
// This would return linting/compilation errors from the ACP client.
Logger.debug("[ACPWorkspaceServiceClient] getDiagnostics called (stub)")
return proto.host.GetDiagnosticsResponse.create({ fileDiagnostics: [] })
}
async openProblemsPanel(_request: proto.host.OpenProblemsPanelRequest): Promise<proto.host.OpenProblemsPanelResponse> {
// Next phase: Send ACP extension notification to open the problems panel.
// This would show the diagnostics/problems view in the editor.
Logger.debug("[ACPWorkspaceServiceClient] openProblemsPanel called (stub)")
return proto.host.OpenProblemsPanelResponse.create({})
}
async openInFileExplorerPanel(
request: proto.host.OpenInFileExplorerPanelRequest,
): Promise<proto.host.OpenInFileExplorerPanelResponse> {
// Next phase: Send ACP extension notification to reveal file in explorer.
// This would highlight/reveal the specified path in the file tree.
Logger.debug("[ACPWorkspaceServiceClient] openInFileExplorerPanel called (stub)", { path: request.path })
return proto.host.OpenInFileExplorerPanelResponse.create({})
}
async openClineSidebarPanel(
_request: proto.host.OpenClineSidebarPanelRequest,
): Promise<proto.host.OpenClineSidebarPanelResponse> {
// Next phase: Send ACP extension notification to open Cline sidebar.
// This would show the Cline panel/sidebar in the editor.
Logger.debug("[ACPWorkspaceServiceClient] openClineSidebarPanel called (stub)")
return proto.host.OpenClineSidebarPanelResponse.create({})
}
async openTerminalPanel(_request: proto.host.OpenTerminalRequest): Promise<proto.host.OpenTerminalResponse> {
// Next phase: Send ACP extension notification or use createTerminal capability.
// This would open/show the terminal panel in the editor.
Logger.debug("[ACPWorkspaceServiceClient] openTerminalPanel called (stub)")
return proto.host.OpenTerminalResponse.create({})
}
async executeCommandInTerminal(
request: proto.host.ExecuteCommandInTerminalRequest,
): Promise<proto.host.ExecuteCommandInTerminalResponse> {
// Next phase: Use connection.createTerminal if clientCapabilities.terminal is available.
// This would execute the specified command in a terminal via the ACP client.
// The ACP SDK provides createTerminal() which returns a TerminalHandle with
// methods like currentOutput(), waitForExit(), kill(), and release().
Logger.debug("[ACPWorkspaceServiceClient] executeCommandInTerminal called (stub)", {
command: request.command,
hasTerminalCapability: this._clientCapabilities?.terminal,
})
return proto.host.ExecuteCommandInTerminalResponse.create({})
}
async openFolder(request: proto.host.OpenFolderRequest): Promise<proto.host.OpenFolderResponse> {
// Next phase: Send ACP extension request to change workspace/folder.
// This would open a new folder/workspace in the ACP client.
Logger.debug("[ACPWorkspaceServiceClient] openFolder called (stub)", { path: request.path })
return proto.host.OpenFolderResponse.create({ success: true })
}
async searchWorkspaceItems(
_request: proto.host.SearchWorkspaceItemsRequest,
): Promise<proto.host.SearchWorkspaceItemsResponse> {
throw new Error("searchWorkspaceItems is not implemented on the ACP host")
}
}
/**
* ACP Host Bridge Client Provider
*
* Provides the 4 service clients required by HostBridgeClientProvider interface,
* implemented for the ACP environment. Uses the ACP connection and client capabilities
* to delegate operations to the ACP client where possible.
*/
export class ACPHostBridgeClientProvider implements HostBridgeClientProvider {
workspaceClient: WorkspaceServiceClientInterface
envClient: EnvServiceClientInterface
windowClient: WindowServiceClientInterface
diffClient: DiffServiceClientInterface
/**
* Creates a new ACPHostBridgeClientProvider.
*
* @param connection - The ACP agent-side connection for making requests
* @param clientCapabilities - The client's advertised capabilities
* @param sessionIdResolver - Function that returns the current session ID
* @param cwdResolver - Function that returns the current working directory
* @param debug - Whether to enable debug logging
* @param version - Version string for getHostVersion (optional)
*/
constructor(
clientCapabilities: acp.ClientCapabilities | undefined,
sessionIdResolver: SessionIdResolver,
cwdResolver: CwdResolver,
version: string,
) {
this.workspaceClient = new ACPWorkspaceServiceClient(clientCapabilities, sessionIdResolver, cwdResolver)
this.envClient = new ACPEnvServiceClient(clientCapabilities, sessionIdResolver, version)
this.windowClient = new ACPWindowServiceClient(clientCapabilities, sessionIdResolver)
this.diffClient = new ACPDiffServiceClient()
}
}
-141
View File
@@ -1,141 +0,0 @@
/**
* AcpAgent - Thin wrapper that bridges stdio connection to ClineAgent.
*
* This class wraps the ClineAgent and connects it to an ACP AgentSideConnection
* for stdio-based communication. It:
* - Wires up the permission handler to call connection.requestPermission()
* - Subscribes to ClineAgent session events and forwards them to connection.sessionUpdate()
* - Delegates all acp.Agent methods to the internal ClineAgent
*
* For programmatic usage without stdio, use ClineAgent directly.
*
* @module acp
*/
import type * as acp from "@agentclientprotocol/sdk"
import { Logger } from "@/shared/services/Logger.js"
import { ClineAgent } from "../agent/ClineAgent.js"
import { type AcpAgentOptions, type SessionUpdateType } from "../agent/types.js"
/**
* ACP Agent wrapper that bridges stdio connection to ClineAgent.
*
* This is the class used by runAcpMode() for stdio-based ACP communication.
* It creates an internal ClineAgent and wires up the connection for:
* - Permission requests (via connection.requestPermission)
* - Session updates (via connection.sessionUpdate)
*/
export class AcpAgent implements acp.Agent {
private readonly connection: acp.AgentSideConnection
private readonly clineAgent: ClineAgent
/** Track which sessions we've subscribed to for event forwarding */
private readonly subscribedSessions: Set<string> = new Set()
constructor(connection: acp.AgentSideConnection, options: AcpAgentOptions) {
this.connection = connection
// Create the internal ClineAgent
this.clineAgent = new ClineAgent(options)
// Wire up the permission handler to use the connection
this.clineAgent.setPermissionHandler(async (request) => {
try {
Logger.debug("[AcpAgent] Forwarding permission request to connection")
return await this.connection.requestPermission({
sessionId: request.sessionId,
toolCall: request.toolCall,
options: request.options,
})
} catch (error) {
Logger.debug("[AcpAgent] Error requesting permission:", error)
return { outcome: { outcome: "cancelled" } }
}
})
}
/**
* Subscribe to session events and forward them to the connection.
*/
private subscribeToSessionEvents(sessionId: string): void {
if (this.subscribedSessions.has(sessionId)) {
return
}
const emitter = this.clineAgent.emitterForSession(sessionId)
// Forward session update by adding the sessionUpdate discriminator
const forwardSessionUpdate = <K extends SessionUpdateType>(eventName: K) => {
emitter.on(eventName, (payload: Record<string, unknown>) => {
const update = {
sessionUpdate: eventName,
...payload,
} as acp.SessionUpdate
this.connection.sessionUpdate({ sessionId, update }).catch((error) => {
Logger.error(`[AcpAgent] Error forwarding ${eventName}:`, error)
})
})
}
// Forward all standard session updates
forwardSessionUpdate("agent_message_chunk")
forwardSessionUpdate("agent_thought_chunk")
forwardSessionUpdate("tool_call")
forwardSessionUpdate("tool_call_update")
forwardSessionUpdate("available_commands_update")
forwardSessionUpdate("plan")
forwardSessionUpdate("current_mode_update")
forwardSessionUpdate("user_message_chunk")
forwardSessionUpdate("config_option_update")
forwardSessionUpdate("session_info_update")
// Handle errors specially (not part of ACP SessionUpdate)
emitter.on("error", (error) => {
Logger.error("[AcpAgent] Session error:", error)
})
this.subscribedSessions.add(sessionId)
}
// ============================================================
// acp.Agent Interface Implementation - Delegate to ClineAgent
// ============================================================
async initialize(params: acp.InitializeRequest): Promise<acp.InitializeResponse> {
return await this.clineAgent.initialize(params, this.connection)
}
async newSession(params: acp.NewSessionRequest): Promise<acp.NewSessionResponse> {
const response = await this.clineAgent.newSession(params)
// Subscribe to events for this new session
this.subscribeToSessionEvents(response.sessionId)
return response
}
async prompt(params: acp.PromptRequest): Promise<acp.PromptResponse> {
// Ensure we're subscribed to this session's events
this.subscribeToSessionEvents(params.sessionId)
return this.clineAgent.prompt(params)
}
async cancel(params: acp.CancelNotification): Promise<void> {
return this.clineAgent.cancel(params)
}
async setSessionMode(params: acp.SetSessionModeRequest): Promise<acp.SetSessionModeResponse> {
return this.clineAgent.setSessionMode(params)
}
async unstable_setSessionModel(params: acp.SetSessionModelRequest): Promise<acp.SetSessionModelResponse> {
return this.clineAgent.unstable_setSessionModel(params)
}
async authenticate(params: acp.AuthenticateRequest): Promise<acp.AuthenticateResponse> {
return this.clineAgent.authenticate(params)
}
async shutdown(): Promise<void> {
this.subscribedSessions.clear()
return this.clineAgent.shutdown()
}
}
File diff suppressed because it is too large Load Diff
-141
View File
@@ -1,141 +0,0 @@
/**
* Entry point for ACP (Agent Client Protocol) mode.
*
* When the CLI is invoked with `--acp`, this module sets up the ACP connection
* and runs Cline as an ACP-compliant agent communicating over stdio.
*
* This module exports:
* - `ClineAgent` - Decoupled agent for programmatic use (no stdio dependency)
* - `AcpAgent` - Thin wrapper that bridges stdio connection to ClineAgent
* - `ClineSessionEmitter` - Typed EventEmitter for per-session events
* - `runAcpMode` - Function to run Cline in stdio-based ACP mode
*
* @module acp
*/
import { AgentSideConnection, ndJsonStream } from "@agentclientprotocol/sdk"
import { Logger } from "@/shared/services/Logger"
import { AcpAgent } from "./AcpAgent.js"
import { nodeToWebReadable, nodeToWebWritable } from "./streamUtils.js"
// Re-export classes for programmatic use
export { ClineAgent } from "../agent/ClineAgent.js"
export { ClineSessionEmitter } from "../agent/ClineSessionEmitter.js"
export type {
AcpAgentOptions,
AcpSessionState,
ClineAgentOptions,
ClineSessionEvents,
PermissionHandler,
} from "../agent/types.js"
export { AcpAgent } from "./AcpAgent.js"
/** Original console methods for restoration if needed */
const originalConsole = {
log: console.log,
info: console.info,
warn: console.warn,
debug: console.debug,
error: console.error,
}
/**
* Redirect all console output to stderr.
*
* In ACP mode, stdout is reserved exclusively for JSON-RPC communication.
* All logging must go to stderr to avoid corrupting the protocol stream.
*/
function redirectConsoleToStderr(): void {
console.log = (...args) => console.error(...args)
console.info = (...args) => console.error(...args)
console.warn = (...args) => console.error(...args)
console.debug = (...args) => console.error(...args)
// console.error already goes to stderr
}
/**
* Restore console methods to their original behavior.
*/
export function restoreConsole(): void {
console.log = originalConsole.log
console.info = originalConsole.info
console.warn = originalConsole.warn
console.debug = originalConsole.debug
console.error = originalConsole.error
}
export interface AcpModeOptions {
/** Path to Cline configuration directory */
config?: string
/** Working directory (default: process.cwd()) */
cwd?: string
/** Additional runtime hooks directory */
hooksDir?: string
/** Enable verbose/debug logging to stderr */
verbose?: boolean
}
/**
* Run Cline in ACP mode.
*
* This function:
* 1. Redirects console output to stderr (stdout reserved for JSON-RPC)
* 2. Sets up the ndJsonStream for stdio communication
* 3. Creates the AgentSideConnection with our AcpAgent factory
* 4. Initializes the CLI infrastructure (StateManager, Controller, etc.)
* 5. Keeps the process alive until the connection closes
*
* @param options - Configuration options for ACP mode
*/
export async function runAcpMode(options: AcpModeOptions = {}): Promise<void> {
redirectConsoleToStderr()
const outputStream = nodeToWebWritable(process.stdout)
const inputStream = nodeToWebReadable(process.stdin)
const stream = ndJsonStream(outputStream, inputStream)
let agent: AcpAgent | null = null
new AgentSideConnection((conn) => {
agent = new AcpAgent(conn, {
debug: Boolean(options.verbose),
hooksDir: options.hooksDir,
})
return agent
}, stream)
let isShuttingDown = false
const shutdown = async () => {
if (isShuttingDown) {
// Force exit on second signal
process.exit(1)
}
isShuttingDown = true
try {
await agent?.shutdown()
restoreConsole()
} catch (error) {
Logger.error("[ACP] Error during shutdown:", error)
}
process.exit(0)
}
process.on("SIGINT", shutdown)
process.on("SIGTERM", shutdown)
// Keep the process alive
// The ndJsonStream will handle stdin events automatically.
// We need to ensure the process doesn't exit while waiting for input.
process.stdin.resume()
// Handle stdin end (client disconnected)
process.stdin.on("end", shutdown)
// Handle stdin errors
process.stdin.on("error", async (error) => {
Logger.error("[ACP] stdin error:", error)
await shutdown()
})
Logger.info("[ACP] Process is now listening for ACP requests on stdin")
}
-54
View File
@@ -1,54 +0,0 @@
/**
* Stream conversion utilities for ACP mode.
*
* The ACP SDK's ndJsonStream function expects Web Streams (ReadableStream/WritableStream),
* but Node.js provides its own stream types. These utilities convert between them.
*
* @module acp/streamUtils
*/
import type { Readable, Writable } from "node:stream"
/**
* Convert a Node.js Writable stream to a Web WritableStream.
*
* Used to convert process.stdout for ACP output.
*
* @param nodeStream - Node.js Writable stream (e.g., process.stdout)
* @returns Web WritableStream compatible with ndJsonStream
*/
export function nodeToWebWritable(nodeStream: Writable): WritableStream<Uint8Array> {
return new WritableStream<Uint8Array>({
write(chunk) {
return new Promise<void>((resolve, reject) => {
nodeStream.write(Buffer.from(chunk), (err) => {
if (err) {
reject(err)
} else {
resolve()
}
})
})
},
})
}
/**
* Convert a Node.js Readable stream to a Web ReadableStream.
*
* Used to convert process.stdin for ACP input.
*
* @param nodeStream - Node.js Readable stream (e.g., process.stdin)
* @returns Web ReadableStream compatible with ndJsonStream
*/
export function nodeToWebReadable(nodeStream: Readable): ReadableStream<Uint8Array> {
return new ReadableStream<Uint8Array>({
start(controller) {
nodeStream.on("data", (chunk: Buffer) => {
controller.enqueue(new Uint8Array(chunk))
})
nodeStream.on("end", () => controller.close())
nodeStream.on("error", (err) => controller.error(err))
},
})
}
File diff suppressed because it is too large Load Diff
-274
View File
@@ -1,274 +0,0 @@
/**
* Tests for ClineSessionEmitter - Typed EventEmitter for per-session ACP events.
*/
import { beforeEach, describe, expect, it, vi } from "vitest"
import { ClineSessionEmitter } from "./ClineSessionEmitter.js"
import type { SessionUpdatePayload } from "./types.js"
describe("ClineSessionEmitter", () => {
let emitter: ClineSessionEmitter
beforeEach(() => {
emitter = new ClineSessionEmitter()
})
describe("on/emit", () => {
it("should emit and receive agent_message_chunk events", () => {
const listener = vi.fn()
const payload: SessionUpdatePayload<"agent_message_chunk"> = {
content: { type: "text", text: "Hello, world!" },
}
emitter.on("agent_message_chunk", listener)
emitter.emit("agent_message_chunk", payload)
expect(listener).toHaveBeenCalledTimes(1)
expect(listener).toHaveBeenCalledWith(payload)
})
it("should emit and receive agent_thought_chunk events", () => {
const listener = vi.fn()
const payload: SessionUpdatePayload<"agent_thought_chunk"> = {
content: { type: "text", text: "Thinking..." },
}
emitter.on("agent_thought_chunk", listener)
emitter.emit("agent_thought_chunk", payload)
expect(listener).toHaveBeenCalledTimes(1)
expect(listener).toHaveBeenCalledWith(payload)
})
it("should emit and receive tool_call events", () => {
const listener = vi.fn()
const payload: SessionUpdatePayload<"tool_call"> = {
toolCallId: "test-tool-call-id",
title: "Test Tool Call",
status: "in_progress",
}
emitter.on("tool_call", listener)
emitter.emit("tool_call", payload)
expect(listener).toHaveBeenCalledTimes(1)
expect(listener).toHaveBeenCalledWith(payload)
})
it("should emit and receive tool_call_update events", () => {
const listener = vi.fn()
const payload: SessionUpdatePayload<"tool_call_update"> = {
toolCallId: "test-tool-call-id",
status: "completed",
rawOutput: { result: "success" },
}
emitter.on("tool_call_update", listener)
emitter.emit("tool_call_update", payload)
expect(listener).toHaveBeenCalledTimes(1)
expect(listener).toHaveBeenCalledWith(payload)
})
it("should emit and receive available_commands_update events", () => {
const listener = vi.fn()
const payload: SessionUpdatePayload<"available_commands_update"> = {
availableCommands: [{ name: "test", description: "Test command" }],
}
emitter.on("available_commands_update", listener)
emitter.emit("available_commands_update", payload)
expect(listener).toHaveBeenCalledTimes(1)
expect(listener).toHaveBeenCalledWith(payload)
})
it("should emit and receive current_mode_update events", () => {
const listener = vi.fn()
const payload: SessionUpdatePayload<"current_mode_update"> = {
currentModeId: "act",
}
emitter.on("current_mode_update", listener)
emitter.emit("current_mode_update", payload)
expect(listener).toHaveBeenCalledTimes(1)
expect(listener).toHaveBeenCalledWith(payload)
})
it("should emit and receive plan events", () => {
const listener = vi.fn()
const payload: SessionUpdatePayload<"plan"> = {
entries: [{ content: "Step 1", status: "pending", priority: "high" }],
}
emitter.on("plan", listener)
emitter.emit("plan", payload)
expect(listener).toHaveBeenCalledTimes(1)
expect(listener).toHaveBeenCalledWith(payload)
})
it("should emit and receive error events", () => {
const listener = vi.fn()
const error = new Error("Test error")
emitter.on("error", listener)
emitter.emit("error", error)
expect(listener).toHaveBeenCalledTimes(1)
expect(listener).toHaveBeenCalledWith(error)
})
})
describe("multiple listeners", () => {
it("should support multiple listeners for the same event", () => {
const listener1 = vi.fn()
const listener2 = vi.fn()
const payload: SessionUpdatePayload<"agent_message_chunk"> = {
content: { type: "text", text: "Hello" },
}
emitter.on("agent_message_chunk", listener1)
emitter.on("agent_message_chunk", listener2)
emitter.emit("agent_message_chunk", payload)
expect(listener1).toHaveBeenCalledTimes(1)
expect(listener2).toHaveBeenCalledTimes(1)
})
it("should call listeners in order of registration", () => {
const order: number[] = []
const listener1 = vi.fn(() => order.push(1))
const listener2 = vi.fn(() => order.push(2))
const payload: SessionUpdatePayload<"agent_message_chunk"> = {
content: { type: "text", text: "Hello" },
}
emitter.on("agent_message_chunk", listener1)
emitter.on("agent_message_chunk", listener2)
emitter.emit("agent_message_chunk", payload)
expect(order).toEqual([1, 2])
})
})
describe("off", () => {
it("should remove a specific listener", () => {
const listener = vi.fn()
const payload: SessionUpdatePayload<"agent_message_chunk"> = {
content: { type: "text", text: "Hello" },
}
emitter.on("agent_message_chunk", listener)
emitter.off("agent_message_chunk", listener)
emitter.emit("agent_message_chunk", payload)
expect(listener).not.toHaveBeenCalled()
})
it("should only remove the specified listener", () => {
const listener1 = vi.fn()
const listener2 = vi.fn()
const payload: SessionUpdatePayload<"agent_message_chunk"> = {
content: { type: "text", text: "Hello" },
}
emitter.on("agent_message_chunk", listener1)
emitter.on("agent_message_chunk", listener2)
emitter.off("agent_message_chunk", listener1)
emitter.emit("agent_message_chunk", payload)
expect(listener1).not.toHaveBeenCalled()
expect(listener2).toHaveBeenCalledTimes(1)
})
})
describe("once", () => {
it("should only call the listener once", () => {
const listener = vi.fn()
const payload: SessionUpdatePayload<"agent_message_chunk"> = {
content: { type: "text", text: "Hello" },
}
emitter.once("agent_message_chunk", listener)
emitter.emit("agent_message_chunk", payload)
emitter.emit("agent_message_chunk", payload)
expect(listener).toHaveBeenCalledTimes(1)
})
})
describe("removeAllListeners", () => {
it("should remove all listeners for a specific event", () => {
const listener1 = vi.fn()
const listener2 = vi.fn()
const payload: SessionUpdatePayload<"agent_message_chunk"> = {
content: { type: "text", text: "Hello" },
}
emitter.on("agent_message_chunk", listener1)
emitter.on("agent_message_chunk", listener2)
emitter.removeAllListeners("agent_message_chunk")
emitter.emit("agent_message_chunk", payload)
expect(listener1).not.toHaveBeenCalled()
expect(listener2).not.toHaveBeenCalled()
})
it("should remove all listeners when no event is specified", () => {
const listener1 = vi.fn()
const listener2 = vi.fn()
emitter.on("agent_message_chunk", listener1)
emitter.on("tool_call", listener2)
emitter.removeAllListeners()
emitter.emit("agent_message_chunk", { content: { type: "text", text: "Hello" } })
emitter.emit("tool_call", { toolCallId: "test", title: "Test" })
expect(listener1).not.toHaveBeenCalled()
expect(listener2).not.toHaveBeenCalled()
})
})
describe("listenerCount", () => {
it("should return the correct number of listeners", () => {
const listener1 = vi.fn()
const listener2 = vi.fn()
expect(emitter.listenerCount("agent_message_chunk")).toBe(0)
emitter.on("agent_message_chunk", listener1)
expect(emitter.listenerCount("agent_message_chunk")).toBe(1)
emitter.on("agent_message_chunk", listener2)
expect(emitter.listenerCount("agent_message_chunk")).toBe(2)
emitter.off("agent_message_chunk", listener1)
expect(emitter.listenerCount("agent_message_chunk")).toBe(1)
})
})
describe("chaining", () => {
it("should support method chaining", () => {
const listener = vi.fn()
const result = emitter.on("agent_message_chunk", listener).on("error", vi.fn()).off("error", vi.fn())
expect(result).toBe(emitter)
})
})
describe("emit return value", () => {
it("should return true when there are listeners", () => {
emitter.on("agent_message_chunk", vi.fn())
const result = emitter.emit("agent_message_chunk", { content: { type: "text", text: "Hello" } })
expect(result).toBe(true)
})
it("should return false when there are no listeners", () => {
const result = emitter.emit("agent_message_chunk", { content: { type: "text", text: "Hello" } })
expect(result).toBe(false)
})
})
})
-114
View File
@@ -1,114 +0,0 @@
/**
* Typed EventEmitter for per-session ACP events.
*
* This class provides a type-safe wrapper around Node's EventEmitter
* for emitting and subscribing to session-specific ACP events.
*
* @module acp
*/
import { EventEmitter } from "events"
import type { ClineSessionEvents } from "./public-types.js"
/**
* Type-safe EventEmitter for ClineAgent session events.
*
* Each session has its own emitter instance, allowing consumers to
* subscribe to events for specific sessions without filtering.
*
* @example
* ```typescript
* const agent = new ClineAgent({ version: "1.0.0" })
* const session = await agent.newSession({ cwd: "/path/to/project" })
*
* // Subscribe to session events
* agent.session(session.sessionId).on("agent_message_chunk", (content) => {
* console.log("Agent says:", content.text)
* })
*
* agent.session(session.sessionId).on("tool_call", (toolCall) => {
* console.log("Tool called:", toolCall.toolName)
* })
* ```
*/
export class ClineSessionEmitter {
private readonly emitter: EventEmitter
constructor() {
this.emitter = new EventEmitter()
// Increase max listeners since we may have many event types
this.emitter.setMaxListeners(20)
}
/**
* Subscribe to a session event.
*
* @param event - The event name to subscribe to
* @param listener - The callback function to invoke when the event is emitted
* @returns This emitter instance for chaining
*/
on<K extends keyof ClineSessionEvents>(event: K, listener: ClineSessionEvents[K]): this {
this.emitter.on(event, listener as (...args: unknown[]) => void)
return this
}
/**
* Subscribe to a session event for a single invocation.
*
* @param event - The event name to subscribe to
* @param listener - The callback function to invoke when the event is emitted
* @returns This emitter instance for chaining
*/
once<K extends keyof ClineSessionEvents>(event: K, listener: ClineSessionEvents[K]): this {
this.emitter.once(event, listener as (...args: unknown[]) => void)
return this
}
/**
* Unsubscribe from a session event.
*
* @param event - The event name to unsubscribe from
* @param listener - The callback function to remove
* @returns This emitter instance for chaining
*/
off<K extends keyof ClineSessionEvents>(event: K, listener: ClineSessionEvents[K]): this {
this.emitter.off(event, listener as (...args: unknown[]) => void)
return this
}
/**
* Emit a session event.
*
* @param event - The event name to emit
* @param args - The arguments to pass to the event listeners
* @returns True if the event had listeners, false otherwise
*/
emit<K extends keyof ClineSessionEvents>(event: K, ...args: Parameters<ClineSessionEvents[K]>): boolean {
return this.emitter.emit(event, ...args)
}
/**
* Remove all listeners for a specific event or all events.
*
* @param event - Optional event name to remove listeners for
* @returns This emitter instance for chaining
*/
removeAllListeners<K extends keyof ClineSessionEvents>(event?: K): this {
if (event) {
this.emitter.removeAllListeners(event)
} else {
this.emitter.removeAllListeners()
}
return this
}
/**
* Get the number of listeners for a specific event.
*
* @param event - The event name to count listeners for
* @returns The number of listeners
*/
listenerCount<K extends keyof ClineSessionEvents>(event: K): number {
return this.emitter.listenerCount(event)
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-356
View File
@@ -1,356 +0,0 @@
/**
* Permission handling for ACP integration.
*
* This module handles the translation between ACP permission requests/responses
* and Cline's internal permission system. It maps ClineAsk types to appropriate
* ACP permission options and translates user responses back to Cline's format.
*
* @module acp/permissionHandler
*/
import type * as acp from "@agentclientprotocol/sdk"
import type { ClineAsk } from "@shared/ExtensionMessage"
import type { ClineAskResponse } from "@shared/WebviewMessage"
import { Logger } from "@/shared/services/Logger.js"
import type { AcpSessionState, ClinePermissionOption } from "./types.js"
/**
* Standard permission options for operations that support "always allow".
* Used for commands, tools, and MCP server operations.
*/
const STANDARD_PERMISSION_OPTIONS: ClinePermissionOption[] = [
{ kind: "allow_once", optionId: "allow_once", name: "Allow Once" },
{ kind: "allow_always", optionId: "allow_always", name: "Always Allow" },
{ kind: "reject_once", optionId: "reject_once", name: "Reject" },
]
/**
* Permission options for operations that don't support "always allow".
* Used for browser actions and other one-time operations.
*/
const RESTRICTED_PERMISSION_OPTIONS: ClinePermissionOption[] = [
{ kind: "allow_once", optionId: "allow_once", name: "Allow Once" },
{ kind: "reject_once", optionId: "reject_once", name: "Reject" },
]
/**
* Mapping of ClineAsk types to their permission option sets.
*/
const ASK_TYPE_PERMISSION_MAP: Partial<Record<ClineAsk, ClinePermissionOption[]>> = {
// Commands support "always allow" for auto-approval
command: STANDARD_PERMISSION_OPTIONS,
// Tool operations support "always allow"
tool: STANDARD_PERMISSION_OPTIONS,
// MCP server operations support "always allow"
use_mcp_server: STANDARD_PERMISSION_OPTIONS,
// Browser actions are one-time, no "always allow"
browser_action_launch: RESTRICTED_PERMISSION_OPTIONS,
// Command output continuation - simple allow/reject
command_output: RESTRICTED_PERMISSION_OPTIONS,
}
/**
* ClineAsk types that require permission handling.
* Other ask types (like followup, plan_mode_respond) don't need permission UI.
*/
const PERMISSION_REQUIRING_ASK_TYPES: Set<ClineAsk> = new Set([
"command",
"tool",
"browser_action_launch",
"use_mcp_server",
"command_output",
])
/**
* Result of handling a permission response.
*/
export interface PermissionHandlerResult {
/** Cline's internal response type */
response: ClineAskResponse
/** Optional text to pass with the response */
text?: string
/** Whether "always allow" was selected (for auto-approval tracking) */
alwaysAllow?: boolean
/** Whether the request was cancelled */
cancelled?: boolean
}
/**
* Check if a ClineAsk type requires permission handling.
*
* @param askType - The ClineAsk type to check
* @returns True if the ask type requires permission UI
*/
export function requiresPermission(askType: ClineAsk): boolean {
return PERMISSION_REQUIRING_ASK_TYPES.has(askType)
}
/**
* Get the appropriate permission options for a ClineAsk type.
*
* @param askType - The ClineAsk type
* @returns Array of permission options, or undefined if the ask type doesn't require permission
*/
export function getPermissionOptionsForAskType(askType: ClineAsk): acp.PermissionOption[] | undefined {
const options = ASK_TYPE_PERMISSION_MAP[askType]
if (!options) {
return undefined
}
// Convert to ACP PermissionOption format
return options.map((opt) => ({
kind: opt.kind,
optionId: opt.optionId,
name: opt.name,
}))
}
/**
* Handle an ACP permission response and translate it to Cline's format.
*
* @param response - The ACP permission response from the client
* @param askType - The original ClineAsk type that triggered the permission request
* @returns The translated result for Cline's handleWebviewAskResponse
*/
export function handlePermissionResponse(response: acp.RequestPermissionResponse, askType: ClineAsk): PermissionHandlerResult {
// Check if cancelled
if (response.outcome.outcome === "cancelled") {
return {
response: "noButtonClicked",
cancelled: true,
}
}
// Get the selected option ID
const optionId = response.outcome.optionId
// Translate the option to Cline's response format
switch (optionId) {
case "allow_once":
return {
response: "yesButtonClicked",
alwaysAllow: false,
}
case "allow_always":
return {
response: "yesButtonClicked",
alwaysAllow: true,
}
case "reject_once":
case "reject_always":
return {
response: "noButtonClicked",
alwaysAllow: false,
}
default:
// Unknown option ID - treat as rejection for safety
Logger.error(`[permissionHandler] Unknown permission option: ${optionId}`)
return {
response: "noButtonClicked",
}
}
}
/**
* Create a permission request for an ACP tool call.
*
* @param toolCall - The ACP tool call that needs permission
* @param askType - The Cline ask type
* @returns The permission request options, or null if no permission needed
*/
export function createPermissionRequest(
toolCall: acp.ToolCall,
askType: ClineAsk,
): { toolCall: acp.ToolCall; options: acp.PermissionOption[] } | null {
const options = getPermissionOptionsForAskType(askType)
if (!options) {
return null
}
return {
toolCall,
options,
}
}
/**
* Track "always allow" decisions for auto-approval.
* This maintains a set of tool/command patterns that have been auto-approved.
*/
export class AutoApprovalTracker {
/** Set of auto-approved command prefixes */
private autoApprovedCommands: Set<string> = new Set()
/** Set of auto-approved tool names */
private autoApprovedTools: Set<string> = new Set()
/** Set of auto-approved MCP servers */
private autoApprovedMcpServers: Set<string> = new Set()
/**
* Record an "always allow" decision for a permission request.
*
* @param askType - The Cline ask type that was auto-approved
* @param identifier - The identifier for the operation (command, tool name, etc.)
*/
recordAlwaysAllow(askType: ClineAsk, identifier: string): void {
switch (askType) {
case "command":
// Store the first word of the command as the key
const commandPrefix = identifier.split(" ")[0]
this.autoApprovedCommands.add(commandPrefix)
break
case "tool":
this.autoApprovedTools.add(identifier)
break
case "use_mcp_server":
this.autoApprovedMcpServers.add(identifier)
break
}
}
/**
* Check if an operation has been auto-approved.
*
* @param askType - The Cline ask type
* @param identifier - The identifier for the operation
* @returns True if the operation was previously auto-approved
*/
isAutoApproved(askType: ClineAsk, identifier: string): boolean {
switch (askType) {
case "command":
const commandPrefix = identifier.split(" ")[0]
return this.autoApprovedCommands.has(commandPrefix)
case "tool":
return this.autoApprovedTools.has(identifier)
case "use_mcp_server":
return this.autoApprovedMcpServers.has(identifier)
default:
return false
}
}
/**
* Clear all auto-approval records.
*/
clear(): void {
this.autoApprovedCommands.clear()
this.autoApprovedTools.clear()
this.autoApprovedMcpServers.clear()
}
}
/**
* Process a pending permission request for a session.
*
* This function coordinates the permission flow:
* 1. Checks if the operation is already auto-approved
* 2. If not, requests permission from the ACP client
* 3. Tracks "always allow" decisions
* 4. Returns the translated result for Cline
*
* @param requestPermission - Function to request permission from the ACP client
* @param sessionId - The session ID
* @param toolCall - The tool call requiring permission
* @param askType - The Cline ask type
* @param identifier - Identifier for auto-approval tracking
* @param autoApprovalTracker - The auto-approval tracker
* @returns The permission handler result
*/
export async function processPermissionRequest(
requestPermission: (
sessionId: string,
toolCall: acp.ToolCall,
options: acp.PermissionOption[],
) => Promise<acp.RequestPermissionResponse>,
sessionId: string,
toolCall: acp.ToolCall,
askType: ClineAsk,
identifier: string,
autoApprovalTracker?: AutoApprovalTracker,
): Promise<PermissionHandlerResult> {
// Check if already auto-approved
if (autoApprovalTracker?.isAutoApproved(askType, identifier)) {
return {
response: "yesButtonClicked",
alwaysAllow: true,
}
}
// Get permission options for this ask type
const options = getPermissionOptionsForAskType(askType)
if (!options) {
// No permission options defined - allow by default
return {
response: "yesButtonClicked",
}
}
// Request permission from the ACP client
const response = await requestPermission(sessionId, toolCall, options)
// Handle the response
const result = handlePermissionResponse(response, askType)
// Track "always allow" decisions
if (result.alwaysAllow && autoApprovalTracker) {
autoApprovalTracker.recordAlwaysAllow(askType, identifier)
}
return result
}
/**
* Get the identifier for auto-approval tracking from a tool call.
*
* @param toolCall - The ACP tool call
* @param askType - The Cline ask type
* @returns The identifier string for auto-approval tracking
*/
export function getAutoApprovalIdentifier(toolCall: acp.ToolCall, askType: ClineAsk): string {
const rawInput = toolCall.rawInput as Record<string, unknown> | undefined
switch (askType) {
case "command":
return (rawInput?.command as string) || toolCall.title
case "tool":
// Try to get tool name from raw input or title
return (rawInput?.tool as string) || toolCall.title
case "use_mcp_server":
return (rawInput?.serverName as string) || toolCall.title
default:
return toolCall.toolCallId
}
}
/**
* Update the session state's pending tool call after permission is handled.
*
* @param sessionState - The session state to update
* @param toolCallId - The tool call ID that was handled
* @param approved - Whether the permission was approved
*/
export function updateSessionStateAfterPermission(sessionState: AcpSessionState, toolCallId: string, approved: boolean): void {
// Remove from pending tool calls
sessionState.pendingToolCalls.delete(toolCallId)
// Clear current tool call ID if it matches
if (sessionState.currentToolCallId === toolCallId && !approved) {
sessionState.currentToolCallId = undefined
}
}
-258
View File
@@ -1,258 +0,0 @@
/**
* Public types for the Cline library API.
*
* This file contains types that are safe to export to library consumers.
* It must NOT import any internal types (Controller, StateManager, etc.)
* to keep the generated declaration files clean.
*
* Internal-only extensions of these types live in ./types.ts.
*/
import type * as acp from "@agentclientprotocol/sdk"
// ============================================================
// Session Update Type Utilities
// ============================================================
/**
* Different types of updates that can be sent during session processing.
*
* These updates provide real-time feedback about the agent's progress.
*
* See protocol docs: [Agent Reports Output](https://agentclientprotocol.com/protocol/prompt-turn#3-agent-reports-output)
*/
export type SessionUpdateType = acp.SessionUpdate["sessionUpdate"]
/**
* Different types of update payloads that can be sent during session processing.
*
* Each update type has a corresponding payload structure defined in the ACP SessionUpdate union.
*/
export type SessionUpdatePayload<T extends SessionUpdateType> = Omit<
Extract<acp.SessionUpdate, { sessionUpdate: T }>,
"sessionUpdate"
>
// ============================================================
// Permission Handler Callback Types
// ============================================================
/**
* Handler function for permission requests.
* Called when the agent needs permission for a tool call.
* The handler should present the request to the user and call resolve() with their response.
*/
export type PermissionHandler = (request: acp.RequestPermissionRequest) => Promise<acp.RequestPermissionResponse>
// ============================================================
// Session Event Emitter Types
// ============================================================
/**
* Maps ACP SessionUpdate types to their event listener signatures.
* Uses the sessionUpdate discriminator to derive event names and payload types.
*/
export type ClineSessionEvents = {
[K in SessionUpdateType]: (payload: SessionUpdatePayload<K>) => void
} & {
/** Error event for session-level errors (not part of ACP SessionUpdate) */
error: (error: Error) => void
}
// ============================================================
// ClineAgent Options
// ============================================================
/**
* Options for creating a ClineAgent instance.
*/
export interface ClineAgentOptions {
/** Whether debug logging is enabled */
debug?: boolean
/** Cline Config Directory (defaults to ~/.cline) */
clineDir?: string
/** Additional runtime hooks directory */
hooksDir?: string
}
/**
* Options for creating an ACP agent instance.
*/
export interface AcpAgentOptions {
/** Whether debug logging is enabled */
debug?: boolean
/** Additional runtime hooks directory */
hooksDir?: string
}
// ============================================================
// Session Types
// ============================================================
export type SessionID = string
/**
* Extended session data stored by Cline for ACP sessions.
*/
export interface ClineAcpSession {
/** Unique session ID */
sessionId: SessionID
/** Working directory for the session */
cwd: string
/** Current mode (plan/act) */
mode: "plan" | "act"
/** MCP servers passed from the client */
mcpServers: acp.McpServer[]
/** Timestamp when session was created */
createdAt: number
/** Timestamp of last activity */
lastActivityAt: number
/** Whether this session was loaded from history (needs resume on first prompt) */
isLoadedFromHistory?: boolean
/** Model ID override for plan mode (format: "provider/modelId") */
planModeModelId?: string
/** Model ID override for act mode (format: "provider/modelId") */
actModeModelId?: string
}
/**
* Lifecycle status of an ACP session.
*
* Represents the state machine:
* Idle → Processing → Idle (normal completion)
* Idle → Processing → Cancelled (cancellation, then back to Idle on next prompt)
*/
export enum AcpSessionStatus {
/** Session is idle, waiting for a prompt */
Idle = "idle",
/** Session is actively processing a prompt */
Processing = "processing",
/** Session processing was cancelled */
Cancelled = "cancelled",
}
/**
* State tracking for an active ACP session within Cline.
*/
export interface AcpSessionState {
/** Session ID */
sessionId: SessionID
/** Current lifecycle status of the session */
status: AcpSessionStatus
/** Current tool call ID being executed (if any) */
currentToolCallId?: string
/** Accumulated tool calls for permission batching */
pendingToolCalls: Map<string, acp.ToolCall>
}
// ============================================================
// Agent Capabilities
// ============================================================
/**
* Cline-specific agent capabilities extending the ACP base capabilities.
*/
export interface ClineAgentCapabilities {
/** Support for loading sessions from disk */
loadSession: boolean
/** Prompt capabilities for the agent */
promptCapabilities: {
/** Support for image inputs */
image: boolean
/** Support for audio inputs */
audio: boolean
/** Support for embedded context (file resources) */
embeddedContext: boolean
}
/** MCP server passthrough capabilities */
mcpCapabilities: {
/** Support for HTTP MCP servers */
http: boolean
/** Support for SSE MCP servers */
sse: boolean
}
}
/**
* Cline agent info for ACP initialization response.
*/
export interface ClineAgentInfo {
name: "cline"
title: "Cline"
version: string
}
// ============================================================
// Permission Options
// ============================================================
/**
* Permission option as presented to the ACP client.
*/
export interface ClinePermissionOption {
kind: acp.PermissionOptionKind
name: string
optionId: string
}
// ============================================================
// Message Translation
// ============================================================
/**
* Result of translating a Cline message to ACP session update(s).
* A single Cline message may produce multiple ACP updates.
*/
export interface TranslatedMessage {
/** The session updates to send */
updates: acp.SessionUpdate[]
/** Whether this message requires a permission request */
requiresPermission?: boolean
/** Permission request details if required */
permissionRequest?: Omit<acp.RequestPermissionRequest, "sessionId">
/** The toolCallId that was created/used (for tracking across streaming updates) */
toolCallId?: string
}
// ============================================================
// Re-exported ACP Types
// ============================================================
export type {
Agent,
AgentSideConnection,
AudioContent,
CancelNotification,
ClientCapabilities,
ContentBlock,
ImageContent,
InitializeRequest,
InitializeResponse,
LoadSessionRequest,
LoadSessionResponse,
McpServer,
ModelInfo,
NewSessionRequest,
NewSessionResponse,
PermissionOption,
PermissionOptionKind,
PromptRequest,
PromptResponse,
RequestPermissionRequest,
RequestPermissionResponse,
SessionConfigOption,
SessionModelState,
SessionNotification,
SessionUpdate,
SetSessionConfigOptionRequest,
SetSessionConfigOptionResponse,
SetSessionModelRequest,
SetSessionModelResponse,
SetSessionModeRequest,
SetSessionModeResponse,
StopReason,
TextContent,
ToolCall,
ToolCallStatus,
ToolCallUpdate,
ToolKind,
} from "@agentclientprotocol/sdk"
-68
View File
@@ -1,68 +0,0 @@
/**
* Internal types for ACP integration with Cline CLI.
*
* This file re-exports all public types from ./public-types.ts and adds
* internal-only Types that reference core modules (Controller, etc.).
*
* Library consumers should never import from this file directly — they
* get the public types via the library entrypoint (exports.ts).
*/
export type {
Agent,
AgentSideConnection,
AudioContent,
CancelNotification,
ContentBlock,
ImageContent,
InitializeRequest,
InitializeResponse,
LoadSessionRequest,
LoadSessionResponse,
McpServer,
ModelInfo,
NewSessionRequest,
NewSessionResponse,
PermissionOption,
PermissionOptionKind,
PromptRequest,
PromptResponse,
ReadTextFileRequest,
ReadTextFileResponse,
RequestPermissionRequest,
RequestPermissionResponse,
SessionConfigOption,
SessionModelState,
SessionNotification,
SessionUpdate,
SetSessionConfigOptionRequest,
SetSessionConfigOptionResponse,
SetSessionModelRequest,
SetSessionModelResponse,
SetSessionModeRequest,
SetSessionModeResponse,
StopReason,
TextContent,
ToolCall,
ToolCallStatus,
ToolCallUpdate,
ToolKind,
WriteTextFileRequest,
WriteTextFileResponse,
} from "@agentclientprotocol/sdk"
export type {
AcpAgentOptions,
AcpSessionState,
ClineAgentCapabilities,
ClineAgentInfo,
ClineAgentOptions,
ClinePermissionOption,
ClineSessionEvents,
PermissionHandler,
SessionUpdatePayload,
SessionUpdateType,
TranslatedMessage,
} from "./public-types.js"
export { AcpSessionStatus } from "./public-types.js"
+4 -4
View File
@@ -194,7 +194,7 @@ const errorTypes = ["api_req_failed", "mistake_limit_reached"]
/**
* Get button configuration based on message type and state
*/
export function getButtonConfig(message: ClineMessage | undefined, isStreaming: boolean = false): ButtonConfig {
export function getButtonConfig(message: ClineMessage | undefined, isStreaming = false): ButtonConfig {
if (!message) {
return BUTTON_CONFIGS.default
}
@@ -295,6 +295,7 @@ export function getVisibleButtons(config: ButtonConfig) {
* Does not show cancel-only buttons (ThinkingIndicator handles that with esc)
*/
export const ActionButtons: React.FC<ActionButtonsProps> = ({ config, mode = "act" }) => {
const { columns: terminalWidth } = useTerminalSize()
if (!config.enableButtons) {
return null
}
@@ -306,7 +307,6 @@ export const ActionButtons: React.FC<ActionButtonsProps> = ({ config, mode = "ac
}
// Calculate button widths based on terminal width
const { columns: terminalWidth } = useTerminalSize()
const buttonCount = (hasPrimary ? 1 : 0) + (hasSecondary ? 1 : 0)
const gapWidth = buttonCount > 1 ? 1 : 0 // 1 char gap between buttons
const availableWidth = terminalWidth - 2 - gapWidth // 1 space padding on each side
@@ -330,8 +330,8 @@ export const ActionButtons: React.FC<ActionButtonsProps> = ({ config, mode = "ac
return (
<Box flexDirection="row" gap={1} marginLeft={1} width="100%">
{hasPrimary && renderButton(config.primaryText!, "1")}
{hasSecondary && renderButton(config.secondaryText!, hasPrimary ? "2" : "1")}
{hasPrimary && config.primaryText && renderButton(config.primaryText, "1")}
{hasSecondary && config.secondaryText && renderButton(config.secondaryText, hasPrimary ? "2" : "1")}
</Box>
)
}
-1
View File
@@ -183,7 +183,6 @@ vi.mock("@shared/getApiMetrics", () => ({
vi.mock("child_process", () => ({
exec: vi.fn(),
execFile: vi.fn(),
execSync: vi.fn(() => "main"),
}))
@@ -105,12 +105,6 @@ const FEATURE_SETTINGS = {
label: "Web tools",
description: "Enable web search and fetch tools",
},
strictPlanMode: {
stateKey: "strictPlanModeEnabled",
default: true,
label: "Strict plan mode",
description: "Require explicit mode switching",
},
nativeToolCall: {
stateKey: "nativeToolCallEnabled",
default: true,
-6
View File
@@ -296,12 +296,6 @@ export class CliWorkspaceServiceClient implements WorkspaceServiceClientInterfac
printInfo(`📂 Opening folder: ${path}`)
return proto.host.OpenFolderResponse.create({ success: true })
}
async searchWorkspaceItems(
_request: proto.host.SearchWorkspaceItemsRequest,
): Promise<proto.host.SearchWorkspaceItemsResponse> {
throw new Error("searchWorkspaceItems is not implemented on the CLI host")
}
}
/**
+3 -64
View File
@@ -1,71 +1,10 @@
/**
* Cline Library Exports
*
* This file exports the public API for programmatic use of Cline.
* Use these classes and types to embed Cline into your applications.
* The previous programmatic agent API has been removed.
* This module is intentionally empty for package compatibility.
*
* @example
* ```typescript
* import { ClineAgent } from "cline"
*
* const agent = new ClineAgent()
* await agent.initialize({ clientCapabilities: {} })
* const session = await agent.newSession({ cwd: process.cwd() })
* ```
* @module cline
*/
export { ClineAgent } from "./agent/ClineAgent.js"
export { ClineSessionEmitter } from "./agent/ClineSessionEmitter.js"
export type {
AcpAgentOptions,
AcpSessionState,
AcpSessionStatus,
Agent,
AgentSideConnection,
AudioContent,
CancelNotification,
ClientCapabilities,
ClineAcpSession,
ClineAgentCapabilities,
ClineAgentInfo,
ClineAgentOptions,
ClinePermissionOption,
ClineSessionEvents,
ContentBlock,
ImageContent,
InitializeRequest,
InitializeResponse,
LoadSessionRequest,
LoadSessionResponse,
McpServer,
ModelInfo,
NewSessionRequest,
NewSessionResponse,
PermissionHandler,
PermissionOption,
PermissionOptionKind,
PromptRequest,
PromptResponse,
RequestPermissionRequest,
RequestPermissionResponse,
SessionConfigOption,
SessionModelState,
SessionNotification,
SessionUpdate,
SessionUpdatePayload,
SessionUpdateType,
SetSessionConfigOptionRequest,
SetSessionConfigOptionResponse,
SetSessionModelRequest,
SetSessionModelResponse,
SetSessionModeRequest,
SetSessionModeResponse,
StopReason,
TextContent,
ToolCall,
ToolCallStatus,
ToolCallUpdate,
ToolKind,
TranslatedMessage,
} from "./agent/public-types.js"
export {}
+1 -14
View File
@@ -26,7 +26,6 @@ import { Session } from "@/shared/services/Session"
import { getProviderModelIdKey } from "@/shared/storage"
import { isOpenaiReasoningEffort, OPENAI_REASONING_EFFORT_OPTIONS, type OpenaiReasoningEffort } from "@/shared/storage/types"
import { version as CLI_VERSION } from "../package.json"
import { runAcpMode } from "./acp/index.js"
import { App } from "./components/App"
import { KanbanMigrationView } from "./components/KanbanMigrationView"
import { checkRawModeSupport } from "./context/StdinContext"
@@ -1182,7 +1181,6 @@ program
.option("--double-check-completion", "Reject first completion attempt to force re-verification")
.option("--auto-condense", "Enable AI-powered context compaction instead of mechanical truncation")
.option("--hooks-dir <path>", "Path to additional hooks directory for runtime hook injection")
.option("--acp", "Run in ACP (Agent Client Protocol) mode for editor integration")
.option("--update", "Check for updates and install if available")
.option("--kanban", `Run ${KANBAN_LAUNCH_COMMAND}`)
.option("--tui", "Open the legacy terminal UI instead of the kanban experience")
@@ -1195,7 +1193,7 @@ program
}
if (options.update) {
if (prompt || options.taskId || options.continue || options.kanban || options.tui || options.acp) {
if (prompt || options.taskId || options.continue || options.kanban || options.tui) {
printWarning("Use --update without a prompt or task flags.")
exit(1)
}
@@ -1214,17 +1212,6 @@ program
return
}
// Check for ACP mode first - this takes precedence over everything else
if (options.acp) {
await runAcpMode({
config: options.config,
cwd: options.cwd,
hooksDir: options.hooksDir,
verbose: options.verbose,
})
return
}
// Always check for piped stdin content
const stdinInput = await readStdinIfPiped()
+1 -7
View File
@@ -9,12 +9,6 @@
"outDir": "dist/types"
},
"include": [
"src/exports.ts",
"src/agent/public-types.ts",
"src/agent/ClineAgent.ts",
"src/agent/ClineSessionEmitter.ts",
"src/agent/types.ts",
"src/agent/messageTranslator.ts",
"src/agent/permissionHandler.ts"
"src/exports.ts"
]
}
+1 -1
View File
@@ -69,7 +69,7 @@ cline auth
cline auth -p cline -k "YOUR_API_KEY" -m anthropic/claude-sonnet-4-6
```
See the [CLI Reference](/cli/cli-reference#cline-auth) for all auth options.
See the [CLI Reference](/cline-cli/cli-reference#cline-auth) for all auth options.
## Security Best Practices
+3 -3
View File
@@ -54,7 +54,7 @@ Models with reasoning support include most Claude, Gemini 2.5, and Grok 3 models
| Multi-modal (text + images) | `openai/gpt-4o` or `anthropic/claude-sonnet-4-6` |
| Complex reasoning | Any model with reasoning support |
For setup and account flow details, see the [Cline provider guide](/getting-started/cline-provider).
For a deeper comparison of model capabilities and pricing, see the [Model Selection Guide](/core-features/model-selection-guide).
## Image Support
@@ -83,7 +83,7 @@ Not all models support images. Check the model's `supportsImages` capability bef
<Card title="Chat Completions" icon="message" href="/api/chat-completions">
Use these models in your API requests.
</Card>
<Card title="Cline provider" icon="scale-balanced" href="/getting-started/cline-provider">
Fastest setup path with built-in authentication and billing.
<Card title="Model Selection Guide" icon="scale-balanced" href="/core-features/model-selection-guide">
In-depth comparison for choosing the right model.
</Card>
</CardGroup>
+257
View File
@@ -0,0 +1,257 @@
---
title: "Cline API Reference"
sidebarTitle: "API Reference"
description: "Reference for the Cline Chat Completions API, an OpenAI-compatible endpoint for programmatic access."
---
The Cline API provides an OpenAI-compatible Chat Completions endpoint. You can use it from the Cline extension, the CLI, or any HTTP client that speaks the OpenAI format.
## Base URL
```
https://api.cline.bot/api/v1
```
## Authentication
All requests require a Bearer token in the `Authorization` header. You can use either:
- **API key** created at [app.cline.bot](https://app.cline.bot) (Settings > API Keys)
- **Account auth token** (used automatically by the Cline extension and CLI when you sign in)
```bash
Authorization: Bearer YOUR_API_KEY
```
### Getting an API Key
<Steps>
<Step title="Go to app.cline.bot">
Open [app.cline.bot](https://app.cline.bot) and sign in.
</Step>
<Step title="Open Settings > API Keys">
Navigate to **Settings**, then **API Keys**.
</Step>
<Step title="Create and copy your key">
Create a new key and copy it. Store it securely. You will not be able to see it again.
</Step>
</Steps>
## Chat Completions
Create a chat completion with streaming support. This endpoint follows the [OpenAI Chat Completions](https://platform.openai.com/docs/api-reference/chat/create) format.
### Request
```
POST /chat/completions
```
**Headers:**
| Header | Required | Description |
|--------|----------|-------------|
| `Authorization` | Yes | `Bearer YOUR_API_KEY` |
| `Content-Type` | Yes | `application/json` |
| `HTTP-Referer` | No | Your application URL |
| `X-Title` | No | Your application name |
**Body parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `model` | string | Yes | Model ID in `provider/model` format (e.g., `anthropic/claude-sonnet-4-6`) |
| `messages` | array | Yes | Array of message objects with `role` and `content` |
| `stream` | boolean | No | Enable SSE streaming (default: `true`) |
| `tools` | array | No | Tool definitions in OpenAI function calling format |
| `temperature` | number | No | Sampling temperature |
### Example Request
```bash
curl -X POST https://api.cline.bot/api/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-sonnet-4-6",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Explain what a context window is in 2 sentences."}
],
"stream": true
}'
```
### Response (Streaming)
When `stream: true`, the response is a series of [Server-Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-Sent_Events). Each event contains a JSON chunk:
```json
data: {"id":"gen-abc123","choices":[{"delta":{"content":"A context"},"index":0}],"model":"anthropic/claude-sonnet-4-6"}
data: {"id":"gen-abc123","choices":[{"delta":{"content":" window is"},"index":0}],"model":"anthropic/claude-sonnet-4-6"}
data: [DONE]
```
The final chunk includes a `usage` object with token counts and cost:
```json
{
"usage": {
"prompt_tokens": 25,
"completion_tokens": 42,
"prompt_tokens_details": {
"cached_tokens": 0
},
"cost": 0.000315
}
}
```
### Response (Non-Streaming)
When `stream: false`, the response is a single JSON object:
```json
{
"id": "gen-abc123",
"model": "anthropic/claude-sonnet-4-6",
"choices": [
{
"message": {
"role": "assistant",
"content": "A context window is the maximum amount of text..."
},
"finish_reason": "stop",
"index": 0
}
],
"usage": {
"prompt_tokens": 25,
"completion_tokens": 42
}
}
```
## Models
Model IDs use the `provider/model-name` format, the same format used by [OpenRouter](https://openrouter.ai). Some examples:
| Model ID | Description |
|----------|-------------|
| `anthropic/claude-sonnet-4-6` | Claude Sonnet 4.6 |
| `anthropic/claude-sonnet-4-5` | Claude Sonnet 4.5 |
| `google/gemini-2.5-pro` | Gemini 2.5 Pro |
| `openai/gpt-4o` | GPT-4o |
### Free Models
The following models are available at no cost:
| Model ID | Provider |
|----------|----------|
| `minimax/minimax-m2.5` | MiniMax |
| `kwaipilot/kat-coder-pro` | Kwaipilot |
| `z-ai/glm-5` | Z-AI |
<Note>
Model availability and pricing may change. Check [app.cline.bot](https://app.cline.bot) for the latest list.
</Note>
## Error Handling
Errors follow the OpenAI error format:
```json
{
"error": {
"code": 401,
"message": "Invalid API key",
"metadata": {}
}
}
```
Common error codes:
| Code | Meaning |
|------|---------|
| `401` | Invalid or missing API key |
| `402` | Insufficient credits |
| `429` | Rate limit exceeded |
| `500` | Server error |
| `error` (finish_reason) | Mid-stream error from the upstream model provider |
## Using with Cline
The easiest way to use the Cline API is through the Cline extension or CLI, which handle authentication and streaming for you.
### VS Code / JetBrains
Select **Cline** as your provider in the model picker dropdown. Sign in with your Cline account and your API key is managed automatically.
### Cline CLI
Configure the CLI with your API key in one command:
```bash
cline auth -p cline -k "YOUR_API_KEY" -m anthropic/claude-sonnet-4-6
```
Then run tasks normally:
```bash
cline "Write a one-line hello world in Python."
```
See the [CLI Reference](/cline-cli/cli-reference) for all available commands and options.
## Using with Other Tools
Because the Cline API is OpenAI-compatible, you can use it with any library or tool that supports custom OpenAI endpoints.
### Python (OpenAI SDK)
```python
from openai import OpenAI
client = OpenAI(
base_url="https://api.cline.bot/api/v1",
api_key="YOUR_API_KEY",
)
response = client.chat.completions.create(
model="anthropic/claude-sonnet-4-6",
messages=[{"role": "user", "content": "Hello!"}],
)
print(response.choices[0].message.content)
```
### Node.js (OpenAI SDK)
```typescript
import OpenAI from "openai"
const client = new OpenAI({
baseURL: "https://api.cline.bot/api/v1",
apiKey: "YOUR_API_KEY",
})
const response = await client.chat.completions.create({
model: "anthropic/claude-sonnet-4-6",
messages: [{ role: "user", content: "Hello!" }],
})
console.log(response.choices[0].message.content)
```
## Related
<CardGroup cols={2}>
<Card title="CLI Reference" icon="terminal" href="/cline-cli/cli-reference">
Full command reference for the Cline CLI, including auth setup.
</Card>
<Card title="Enterprise API" icon="building" href="/enterprise-solutions/api-reference">
Admin endpoints for user management, organizations, billing, and API keys.
</Card>
</CardGroup>
+3 -3
View File
@@ -214,7 +214,7 @@ console.log(data.choices[0].message.content)
## Cline CLI
The [Cline CLI](/cli/cli-reference) is the fastest way to use the Cline API from your terminal. It handles authentication, streaming, and tool execution for you.
The [Cline CLI](/cline-cli/cli-reference) is the fastest way to use the Cline API from your terminal. It handles authentication, streaming, and tool execution for you.
### Setup
@@ -242,7 +242,7 @@ cline -m google/gemini-2.5-pro "Analyze this codebase."
cline -y "Run tests and fix failures."
```
See the [CLI Reference](/cli/cli-reference) for all commands and options.
See the [CLI Reference](/cline-cli/cli-reference) for all commands and options.
## VS Code / JetBrains
@@ -269,7 +269,7 @@ For setup instructions, see [Installing Cline](/getting-started/installing-cline
<Card title="Models" icon="brain" href="/api/models">
Browse available models.
</Card>
<Card title="CLI Reference" icon="terminal" href="/cli/cli-reference">
<Card title="CLI Reference" icon="terminal" href="/cline-cli/cli-reference">
Complete Cline CLI command reference.
</Card>
</CardGroup>
-216
View File
@@ -1,216 +0,0 @@
---
title: "ACP: Editor Integrations"
description: "Use Cline in JetBrains, Neovim, Zed, and other editors via the Agent Client Protocol"
---
Cline CLI supports the [Agent Client Protocol (ACP)](https://agentclientprotocol.com/), an open standard that enables AI coding agents to work across different editors and IDEs. This means you can use the full Cline agent—with all its capabilities including Skills, Hooks, and MCP integrations—in your preferred development environment.
## Why ACP?
- **Editor flexibility**: Use Cline in JetBrains, Neovim, Zed, or any ACP-compatible editor
- **No feature compromises**: Full access to Cline's capabilities regardless of editor
- **Team consistency**: Same AI assistant across different developer workflows
- **Open standard**: Built on Zed's open Agent Client Protocol specification
## JetBrains IDEs
[JetBrains](https://www.jetbrains.com) IDEs include IntelliJ IDEA, PyCharm, WebStorm, and more. They offer built-in AI Assistant with ACP support.
<Note>
**Recommended: Native JetBrains Plugin**
For the best JetBrains experience, install the [native Cline plugin](/getting-started/installing-cline#jetbrains-ides) from the JetBrains Marketplace. It provides full IDE integration and the complete Cline experience.
The ACP setup below is an alternative way to use Cline CLI features in JetBrains IDEs.
</Note>
Alternatively, you can run Cline CLI in IntelliJ IDEA, PyCharm, WebStorm, and all other JetBrains IDEs through their built-in AI Assistant with ACP support.
<video
src="https://storage.googleapis.com/cline_public_images/cline-acp-jetbrains.mp4"
autoPlay
loop
muted
playsInline
style={{ width: "100%", borderRadius: "8px", marginTop: "16px", marginBottom: "16px" }}
/>
### Setup
1. **Install Cline CLI** (if not already installed):
```bash
npm i -g cline
```
2. **Authenticate with Cline**:
```bash
cline auth
```
3. **Configure JetBrains AI Assistant**:
- Open your JetBrains IDE
- Navigate to `Settings | Tools | AI Assistant | Agents`
- Click "Add Custom Agent"
- This opens/creates `~/.jetbrains/acp.json`
4. **Add Cline to `acp.json`**:
```json
{
"agent_servers": {
"Cline": {
"command": "cline",
"args": ["--acp"],
"env": {}
}
}
}
```
5. **Use Cline**:
- Open the AI Chat tool window
- Select "Cline" from the agent dropdown
- Start coding with Cline in your JetBrains IDE!
<Tip>
JetBrains AI Assistant can expose its built-in MCP server to Cline, giving Cline access to IDE-specific tools and context.
</Tip>
## Neovim
[Neovim](https://neovim.io) is a hyperextensible Vim-based text editor loved by developers for its speed and flexibility. Use Cline in Neovim through the [agentic.nvim](https://github.com/carlos-algms/agentic.nvim) or [avante.nvim](https://github.com/yetone/avante.nvim) plugins, which provide ACP integration.
<video
src="https://storage.googleapis.com/cline_public_images/cline-acp-neovim-avante.mp4"
autoPlay
loop
muted
playsInline
style={{ width: "100%", borderRadius: "8px", marginTop: "16px", marginBottom: "16px" }}
/>
### Setup with agentic.nvim
1. **Install Cline CLI** (if not already installed):
```bash
npm i -g cline
```
2. **Authenticate with Cline**:
```bash
cline auth
```
3. **Install agentic.nvim** using lazy.nvim:
```lua
{
"carlos-algms/agentic.nvim",
opts = {
provider = "cline-acp",
acp_providers = {
["cline-acp"] = {
command = "cline",
args = {"--acp"},
},
},
},
keys = {
{"<C-\\>", function() require("agentic").toggle() end, mode={"n","v","i"}, desc="Toggle Cline Chat"},
},
}
```
4. **Use Cline**:
- Press `<C-\>` to toggle Cline chat
- Start coding with Cline in Neovim!
### Setup with avante.nvim
Follow the [avante.nvim documentation](https://github.com/yetone/avante.nvim) for configuring external ACP agents and point it to `cline --acp`.
## Zed
[Zed](https://zed.dev) is a high-performance, multiplayer code editor built from the ground up for speed and collaboration. Zed's team created the Agent Client Protocol, making Cline a natural fit for this editor.
### Setup
1. **Install Cline CLI** (if not already installed):
```bash
npm i -g cline
```
2. **Authenticate with Cline**:
```bash
cline auth
```
3. **Configure Zed**:
- Open Zed settings (`Cmd/Ctrl + ,`)
- Add Cline to your `settings.json`:
```json
{
"agent_servers": {
"Cline": {
"type": "custom",
"command": "cline",
"args": ["--acp"],
"env": {}
}
}
}
```
4. **Use Cline**:
- Open the AI assistant panel
- Select "Cline" from the agent dropdown
- Start coding with Cline in Zed!
## Other Editors
Any editor that supports the Agent Client Protocol can run Cline. Check your editor's documentation for ACP configuration instructions, then point it to:
```bash
cline --acp
```
## Troubleshooting
### Agent not appearing
- Ensure Cline CLI is installed globally: `npm i -g cline`
- Verify authentication: `cline auth`
- Check that `cline --acp` runs without errors
- Restart your editor after configuration changes
### Permission errors
If Cline can't access files or run commands:
- Check that your editor's ACP integration passes the correct working directory
- Verify file permissions in your project
- Ensure Cline has approval settings configured correctly
### Connection issues
- Make sure no other Cline instance is using the same configuration directory
- Check editor logs for ACP-related errors
- Try running `cline --acp` manually to test the connection
## Learn More
<Columns cols={2}>
<Card title="CLI Overview" icon="terminal" href="/usage/cli-overview">
Learn about Cline CLI's core capabilities and use cases.
</Card>
<Card title="Headless Mode" icon="robot" href="/usage/cli-overview#headless-mode">
Run Cline autonomously in scripts, CI/CD pipelines, and automated workflows.
</Card>
<Card title="Skills" icon="graduation-cap" href="/customization/skills">
Understand how Cline's Skills work across all editors via ACP.
</Card>
<Card title="Hooks" icon="link" href="/customization/hooks">
Learn how to enforce policies with Hooks in any editor.
</Card>
</Columns>
-57
View File
@@ -1,57 +0,0 @@
---
title: "Agent Teams"
sidebarTitle: "Agent Teams"
description: "Coordinate multiple agents working together on complex tasks from the CLI."
---
<Warning>
This feature currently only applies to Cline SDK, CLI, and Kanban. This feature is not applicable on VSCode and JetBrains Extension for now.
</Warning>
Agent teams let you break complex work across multiple agents that coordinate through a shared task board. One agent acts as the coordinator, delegating subtasks to specialist agents.
## Starting a Team
```bash
cline --team-name auth-sprint "Plan and implement user authentication with tests"
```
The `--team-name` flag enables team mode. The coordinator agent gets additional tools for spawning teammates and delegating tasks.
## Resuming Team Work
Team state persists across sessions. Resume where you left off:
```bash
cline --team-name auth-sprint "Continue with incomplete tasks"
```
## Interactive Mode
In interactive mode, use the `/team` slash command:
```
/team Plan and implement a REST API with tests
```
## Team State
Team state is stored at `~/.cline/data/teams/[team-name]/` and includes:
- Task board with current tasks and status
- Inter-agent mailbox
- Mission log with activity history
## Disabling Teams
Teams are enabled by default. Disable them with:
```bash
cline --no-teams "your prompt"
```
## Sub-Agents
For simpler delegation within a single session (no persistent state), use [sub-agents](/features/subagents). Sub-agents run in parallel for read-only research and return focused reports to the main agent.
See the [SDK Multi-Agent Teams guide](/sdk/guides/multi-agent-teams) for the programmatic API.
-305
View File
@@ -1,305 +0,0 @@
---
title: "CLI Reference"
description: "Complete command reference for Cline CLI including all commands, flags, and configuration options."
---
```bash
cline --help # Show all commands
cline <command> --help # Show help for a specific command
```
## Synopsis
```bash
cline [options] [command] [prompt]
```
## Help Menu (Source of Truth)
```text
Usage: cline [options] [command] [prompt]
Cline CLI - AI coding assistant in your terminal
Arguments:
prompt Your prompt. Default to start in act mode with auto-approve enabled.
Options:
-V, --version Output the version number
-p, --plan Run in plan mode
--json Output messages as JSON instead of styled text
--auto-approve <boolean> Set tool auto-approval for all tools (default: true)
-t, --timeout <seconds> Optional timeout in seconds (default: 0 for no timeout)
-m, --model <model-id> Model to use for the session with the selected provider
-v, --verbose Show verbose output
-c, --cwd <path> Working directory
--config <path> Configuration directory (default: ~/.cline/data/settings)
--data-dir <path> Use isolated local state at this directory path (default: ~/.cline)
--thinking <level> Set reasoning effort level between none|low|medium|high|xhigh (default: medium)
--retries <count> Maximum consecutive mistakes (retries) before halting
--hooks-dir <path> Directory path to additional hooks for runtime hook injection (default: ~/.cline/hooks)
--acp Run in Agent Client Protocol (ACP) mode for editor integration
-i, --tui Open the terminal user interface (TUI) for interactive sessions
--id <session-id> Resume an existing session by ID
-k, --key <api-key> API key override for this run
-P, --provider <id> Provider id (default: cline)
-s, --system <system-prompt> Override the default system prompt
-z, --zen Start a session that runs in the background hub
-h, --help display help for command
Commands:
auth [options] [provider] Authenticate a provider and configure what model is used
config [options] Show current configuration
connect [options] [adapter] Connect to an editor or IDE adapter
mcp Manage MCP servers
dev Developer tools and utilities
doctor Diagnose and fix configuration issues
history|h [options] List session history or manage saved sessions
hook Handle a hook payload from stdin
plugin Manage Cline Plugins
schedule Manage scheduled tasks
hub Manage the local hub daemon
update [options] Check for updates and install if available
version Show Cline CLI version number
kanban Launch the kanban app and exit
```
## Global Options
| Option | Description |
|--------|-------------|
| `-V, --version` | Output the version number |
| `-p, --plan` | Run in plan mode |
| `--json` | Output messages as JSON instead of styled text |
| `--auto-approve <boolean>` | Set tool auto-approval for all tools (default: `true`) |
| `-t, --timeout <seconds>` | Optional timeout in seconds (default: `0` for no timeout) |
| `-m, --model <model-id>` | Model to use for the session with the selected provider |
| `-v, --verbose` | Show verbose output |
| `-c, --cwd <path>` | Working directory |
| `--config <path>` | Configuration directory (default: `~/.cline/data/settings`) |
| `--data-dir <path>` | Use isolated local state at this directory path (default: `~/.cline`) |
| `--thinking <level>` | Set reasoning effort: `none\|low\|medium\|high\|xhigh` (default `medium`) |
| `--retries <count>` | Maximum consecutive mistakes (retries) before halting |
| `--hooks-dir <path>` | Directory path to additional hooks for runtime hook injection (default: `~/.cline/hooks`) |
| `--acp` | Run in Agent Client Protocol (ACP) mode for editor integration |
| `-i, --tui` | Open the terminal user interface (TUI) for interactive sessions |
| `--id <session-id>` | Resume an existing session by ID |
| `-k, --key <api-key>` | API key override for this run |
| `-P, --provider <id>` | Provider id (default: `cline`) |
| `-s, --system <system-prompt>` | Override the default system prompt |
| `-z, --zen` | Start a session that runs in the background hub |
| `-h, --help` | Display help for command |
## Commands
### `cline` (default)
Start a task or enter interactive mode.
```bash
cline
cline "your prompt here"
cline "Run tests and fix failures"
echo "prompt" | cline
```
### `auth [options] [provider]`
Configure authentication with an AI provider.
```bash
cline auth
```
### `config [options]`
Show current configuration.
```bash
cline config
```
### `connect [options] [adapter]`
Connect to messaging platforms. See [Connectors](/cli/connectors).
```bash
cline connect
cline connect [adapter]
```
### `mcp`
Manage MCP servers. See [MCP](/mcp/mcp-overview).
```bash
cline mcp
```
### `dev`
Developer tools and utilities.
```bash
cline dev
```
### `doctor`
Diagnose and fix configuration issues.
```bash
cline doctor
```
### `history|h [options]`
List session history or manage saved sessions.
```bash
cline history
cline h
```
### `hook`
Handle a hook payload from stdin.
```bash
cat payload.json | cline hook
```
### `plugin`
Manage Cline plugins. Install plugins from npm, git repositories, or local paths. See [Plugins](/customization/plugins) for full details and the plugin manifest format.
```bash
cline plugin install <source> # Install a plugin
cline plugin i <source> # Shorthand alias
```
| Option | Description |
|--------|-------------|
| `--npm` | Treat source as an npm package |
| `--git` | Treat source as a git repository |
| `--force` | Replace an existing install for the same source |
| `--json` | Output result as JSON |
| `--cwd <path>` | Install to `<path>/.cline/plugins` instead of the global directory |
Try it with the [TypeScript Navigation Plugin](https://github.com/cline/typescript-lsp-plugin):
```bash
cline plugin install https://github.com/cline/typescript-lsp-plugin.git
```
### `schedule`
Manage scheduled agents. See [Scheduling](/cli/scheduling).
```bash
cline schedule
```
### `hub`
Manage the local hub daemon.
```bash
cline hub
```
### `update [options]`
Check for updates and install if available.
```bash
cline update
```
### `version`
Show Cline CLI version number.
```bash
cline version
cline -V
```
### `kanban`
Launch the kanban app and exit.
```bash
cline kanban
```
## Environment Variables
| Variable | Description |
|----------|-------------|
| `CLINE_DATA_DIR` | Custom configuration directory (replaces `~/.cline/data/`) |
| `CLINE_HUB_ADDRESS` | Override hub address (default: `127.0.0.1:25463`) |
| `CLINE_SESSION_BACKEND_MODE` | Force backend mode (`local`, `hub`, `remote`, `auto`) |
| `CLINE_SANDBOX_DATA_DIR` | Sandbox session storage directory |
| `CLINE_SANDBOX` | Enable sandbox mode |
| `CLINE_HOOKS_DIR` | Additional hooks directory |
| `CLINE_BUILD_ENV` | Set to `development` for debug features |
| `CLINE_DEBUG_PORT_BASE` | Base port for Node.js inspector |
| `CLINE_COMMAND_PERMISSIONS` | JSON policy restricting shell commands (see below) |
### CLINE_COMMAND_PERMISSIONS
Restrict which shell commands the agent can execute:
```bash
export CLINE_COMMAND_PERMISSIONS='{"allow": ["npm *", "git *"], "deny": ["rm -rf *", "sudo *"]}'
```
| Field | Type | Description |
|-------|------|-------------|
| `allow` | `string[]` | Glob patterns for allowed commands. If set, only matching commands are permitted. |
| `deny` | `string[]` | Glob patterns for denied commands. Deny rules always take precedence. |
| `allowRedirects` | `boolean` | Whether to allow shell redirects (`>`, `>>`, `<`). Default: `false`. |
## JSON Output Format
When using `--json`, each message is a JSON object on its own line:
```json
{"type": "say", "text": "I'll create the file now.", "ts": 1760501486669, "say": "text"}
```
| Field | Type | Description |
|-------|------|-------------|
| `type` | `"ask"` or `"say"` | Message category |
| `text` | `string` | Message content |
| `ts` | `number` | Unix timestamp in milliseconds |
| `say` | `string` | Subtype when `type` is `"say"` |
| `ask` | `string` | Subtype when `type` is `"ask"` |
| `reasoning` | `string` | Model reasoning (if available) |
| `partial` | `boolean` | `true` while streaming |
## Configuration Files
```
~/.cline/
data/
settings/
providers.json # API keys and provider config
rules/ # Global rules
skills/ # Global skills
teams/ # Team state
sessions/ # Session database (SQLite)
logs/
hub-daemon.log # Hub logs
plugins/ # Global plugins
_installed/ # Managed by `cline plugin install`
.cline/ # Project root
rules/ # Project rules
skills/ # Project skills
hooks/ # Lifecycle hooks
plugins/ # Project plugins
mcp.json # MCP server config
agents.yaml # Agent definitions
```
-156
View File
@@ -1,156 +0,0 @@
---
title: "Connectors"
sidebarTitle: "Connectors"
description: "Connect the CLI to Telegram, Slack, Discord, Google Chat, WhatsApp, etc."
---
<Warning>
This feature currently only applies to Cline CLI.
</Warning>
Connectors let you chat with your agent from messaging platforms. Each incoming message creates or continues an agent session, and the agent's response is sent back to the conversation.
## Setup Wizard
Run `cline connect` to open an interactive wizard that guides you through platform selection, credential entry, security configuration, and advanced options (provider, model, system prompt, agent mode).
```bash
cline connect
```
## Supported Platforms
| Platform | Direct Command | Required Credentials |
|----------|---------------|---------------------|
| Telegram | `cline connect telegram` | Bot username, bot token |
| Slack | `cline connect slack` | Bot token, signing secret, base URL |
| Discord | `cline connect discord` | Application ID, bot token, public key, base URL |
| Google Chat | `cline connect gchat` | Service account credentials JSON, base URL |
| WhatsApp | `cline connect whatsapp` | Phone number ID, access token, app secret, verify token, base URL |
| Linear | `cline connect linear` | API key, webhook signing secret, base URL |
## Telegram
<Steps>
<Step title="Create a Telegram bot">
Open Telegram and start a chat with [@BotFather](https://t.me/BotFather). Send `/newbot` and follow the prompts:
1. Enter a display name (e.g., "Cline")
2. Enter a username ending in `bot` (e.g., `cline_myname_bot`). Must be unique across Telegram.
3. BotFather responds with your bot token (looks like `7123456789:AAH...`)
</Step>
<Step title="Start the connector">
```bash
cline connect telegram -m <BOT-USERNAME> -k <BOT-TOKEN>
```
</Step>
<Step title="Chat with your bot">
Open Telegram, search for your bot's username, and send a message. The agent processes it and replies in the chat.
</Step>
</Steps>
### Security
By default, anyone who finds your bot can message it and it will execute tasks on your machine. Lock it down with the `--hook-command` flag.
<Steps>
<Step title="Get your Telegram user ID">
Message [@userinfobot](https://t.me/userinfobot) on Telegram. It replies with your user ID immediately.
</Step>
<Step title="Start with access control">
Replace `12345` with your actual Telegram user ID:
```bash
cline connect telegram -m <BOT-USERNAME> -k <BOT-TOKEN> \
--hook-command 'jq -r ".payload.actor.participantKey" | grep -q "telegram:id:12345" && echo "{\"action\":\"allow\"}" || echo "{\"action\":\"deny\",\"message\":\"unauthorized\"}"'
```
</Step>
</Steps>
The `--hook-command` receives each incoming message with sender info via stdin. Your script returns `{"action": "allow"}` or `{"action": "deny", "message": "reason"}`. Without `--hook-command`, everything is auto-approved.
## Slack
Requires a bot token, signing secret, and public base URL.
```bash
cline connect slack --token <BOT-TOKEN> --signing-secret <SECRET> --base-url <URL>
```
Each Slack thread maps to an agent session, so the agent maintains conversation context within a thread.
## Discord
Requires an application ID, bot token, public key, and public base URL.
```bash
cline connect discord --app-id <ID> --token <TOKEN> --public-key <KEY> --base-url <URL>
```
## Google Chat
Requires a service account credentials JSON file and public base URL.
```bash
cline connect gchat --credentials <JSON> --base-url <URL>
```
## WhatsApp
Requires a phone number ID, access token, app secret, webhook verify token, and public base URL.
```bash
cline connect whatsapp --phone-id <ID> --token <TOKEN> --app-secret <SECRET> --base-url <URL>
```
## Linear
Requires an API key, webhook signing secret, and public base URL.
```bash
cline connect linear --api-key <KEY> --signing-secret <SECRET> --base-url <URL>
```
## Managing Connectors
```bash
# Stop all connectors
cline connect --stop
# Stop a specific connector
cline connect telegram --stop
```
## Hook Command Protocol
The `--hook-command` pattern works across all connectors. The script receives a JSON payload via stdin:
```json
{
"payload": {
"actor": {
"participantKey": "telegram:id:12345",
"displayName": "User Name"
},
"message": "The incoming message text"
}
}
```
Return `{"action": "allow"}` or `{"action": "deny", "message": "reason"}`.
## Running Multiple Connectors
Multiple connectors can run simultaneously. They all share the same hub:
```bash
# Terminal 1
cline connect telegram -m my_bot -k $TELEGRAM_TOKEN
# Terminal 2
cline connect slack --token $SLACK_TOKEN --signing-secret $SECRET --base-url $URL
```
Connectors require the hub. Start it with `cline hub start` if it doesn't auto-start.
-110
View File
@@ -1,110 +0,0 @@
---
title: "Scheduling"
sidebarTitle: "Scheduling"
description: "Run agents on cron schedules for recurring automations like daily summaries and code reviews."
---
<Warning>
This feature currently only applies to Cline SDK, CLI, and Kanban. This feature is not applicable on VSCode and JetBrains Extension for now.
</Warning>
The CLI supports running agents on cron schedules through the hub. Scheduled agents persist across process restarts and run independently of any terminal session.
## Schedule Wizard
Run `cline schedule` to open an interactive menu for creating and managing schedules, browsing execution history, and viewing performance statistics.
```bash
cline schedule
```
The wizard provides:
| Action | Description |
|--------|-------------|
| Create new schedule | Set up a recurring task with cron timing and prompt |
| List schedules | View all schedules with status and next run time |
| Upcoming runs | Preview the next 10 scheduled executions |
| Active executions | Show currently running tasks |
| Trigger now | Immediately run a selected schedule |
| Pause / Resume | Suspend or restart a schedule |
| Execution history | View past runs with status, duration, tokens, and cost |
| Statistics | Success rate, average duration, last failure |
| Delete | Remove a schedule |
## Creating Schedules with Flags
```bash
cline schedule create "PR summary" \
--cron "0 9 * * MON-FRI" \
--prompt "List all open PRs and their review status" \
--workspace /path/to/repo \
--model anthropic/claude-sonnet-4-6
```
## Managing Schedules
```bash
cline schedule list
cline schedule trigger <schedule-id>
cline schedule pause <schedule-id>
cline schedule resume <schedule-id>
cline schedule delete <schedule-id>
cline schedule executions <schedule-id>
```
## Cron Expression Reference
| Expression | Schedule |
|-----------|----------|
| `*/5 * * * *` | Every 5 minutes |
| `*/15 * * * *` | Every 15 minutes |
| `0 * * * *` | Every hour |
| `0 */6 * * *` | Every 6 hours |
| `0 0 * * *` | Daily at midnight |
| `0 9 * * *` | Daily at 9am |
| `0 9 * * 1-5` | Every weekday at 9am |
| `0 9 * * 1` | Every Monday at 9am |
| `0 0 1 * *` | First of every month |
## Examples
### Daily Standup Summary
```bash
cline schedule create "Standup prep" \
--cron "0 8 * * MON-FRI" \
--prompt "Summarize: (1) PRs merged yesterday, (2) PRs currently in review, (3) open issues assigned to team members." \
--workspace /path/to/repo
```
### Weekly Dependency Check
```bash
cline schedule create "Dependency check" \
--cron "0 10 * * MON" \
--prompt "Check for outdated npm dependencies. For any with security vulnerabilities, create a branch with the update and open a PR." \
--workspace /path/to/project
```
### Codebase Health Report
```bash
cline schedule create "Code health" \
--cron "0 6 * * MON" \
--prompt "Analyze the codebase for: (1) files with no test coverage, (2) TODO/FIXME comments older than 30 days, (3) functions longer than 100 lines." \
--workspace /path/to/project
```
## Routing Results
Combine schedules with [connectors](/cli/connectors) to send results to messaging platforms:
```bash
cline connect telegram -m my_bot -k $BOT_TOKEN
cline schedule create "Morning briefing" \
--cron "0 8 * * *" \
--prompt "Summarize overnight activity in the repo"
```
Scheduling requires the hub. It starts automatically when you create a schedule.
+428
View File
@@ -0,0 +1,428 @@
---
title: "CLI Reference"
description: "Complete command reference for Cline CLI including all commands, flags, and configuration options"
---
This page documents all available commands, flags, and configuration options for Cline CLI. For quick help in your terminal, use:
```bash
cline --help # Show all commands
cline task --help # Show task command options
cline auth --help # Show auth command options
man cline # View the full manual page (if installed)
```
## Synopsis
```bash
cline [prompt] [options]
cline <command> [options] [arguments]
```
## Global Options
These options work with any command:
| Option | Description |
|--------|-------------|
| `--config <path>` | Use a custom configuration directory instead of `~/.cline/data/` |
| `-c, --cwd <path>` | Set the working directory for the task |
| `-v, --verbose` | Show detailed output including model reasoning |
| `--help` | Show help for the command |
## Modes of Operation
Cline CLI automatically detects the best output mode based on how you invoke it:
| Mode | When Activated | Description |
|------|----------------|-------------|
| **Interactive** | `cline` with no args, TTY connected | Rich terminal UI with real-time streaming, keyboard shortcuts, and visual feedback. |
| **Task** | `cline "prompt"` with TTY connected | Interactive UI starts immediately with your task. |
| **Plain Text** | stdin piped, stdout redirected, or `--yolo`/`--json` flags | Clean text output without UI, suitable for scripting and CI/CD. |
## Agent Behavior
Cline operates in two primary modes that control how it approaches tasks:
| Mode | Description |
|------|-------------|
| **Act Mode** (default) | Cline actively uses tools to accomplish tasks. It can read files, write code, execute commands, use a headless browser, and more. |
| **Plan Mode** | Cline gathers information and creates a detailed plan before implementation. It explores the codebase, asks clarifying questions, and presents a strategy for your approval before switching to Act Mode. |
Use `-a, --act` or `-p, --plan` flags to explicitly set the mode.
## Commands
### cline (default)
Run Cline without a subcommand to start a task or enter interactive mode.
```bash
# Interactive mode (no arguments)
cline
# Start a task directly
cline "your prompt here"
# Resume the latest task for the current directory
cline --continue
```
**Options:**
| Option | Description |
|--------|-------------|
| `-a, --act` | Start in Act mode (default). Cline executes actions directly. |
| `-p, --plan` | Start in Plan mode. Cline analyzes and creates a strategy before acting. |
| `-y, --yolo` | YOLO mode: auto-approve all actions, use plain text output, exit when complete. Ideal for CI/CD. |
| `-m, --model <id>` | Use a specific model (e.g., `claude-sonnet-4-5-20250929`, `gpt-4o`). |
| `-i, --images <paths...>` | Include image files with the prompt. |
| `--thinking` | Enable extended thinking with a 1024 token budget. |
| `--json` | Output messages as JSON (one object per line). Forces plain text mode. |
| `--timeout <seconds>` | Maximum execution time before the task is stopped. |
| `--continue` | Resume the most recent task from the current working directory. |
**Mode Behavior:**
| Invocation | Output Mode | Why |
|------------|-------------|-----|
| `cline` | Interactive UI | No arguments, TTY connected |
| `cline "prompt"` | Interactive UI | TTY connected |
| `cline -y "prompt"` | Plain text | YOLO flag forces plain text |
| `cline --json "prompt"` | JSON | JSON flag forces plain text |
| `cat file \| cline "prompt"` | Plain text | stdin is piped |
| `cline "prompt" > out.txt` | Plain text | stdout is redirected |
---
### cline task (alias: t)
Run a task with a prompt. This is equivalent to `cline "prompt"`.
```bash
cline task "Create a REST API endpoint"
cline t "Fix the bug in utils.js"
```
**Options:** Same as the default command above.
---
### cline auth
Configure authentication with an AI provider.
```bash
# Interactive wizard
cline auth
# Quick setup with flags
cline auth -p anthropic -k sk-ant-api-xxxxx -m claude-sonnet-4-5-20250929
```
**Options:**
| Option | Description |
|--------|-------------|
| `-p, --provider <id>` | Provider ID. See [Supported Providers](#supported-providers) below. |
| `-k, --apikey <key>` | API key for the provider. |
| `-m, --modelid <id>` | Model ID to use (e.g., `claude-sonnet-4-5-20250929`, `gpt-4o`). |
| `-b, --baseurl <url>` | Base URL for OpenAI-compatible providers. |
**Supported Providers:**
| Provider ID | Description |
|-------------|-------------|
| `anthropic` | Anthropic Claude (direct API) |
| `openai-native` | OpenAI GPT models |
| `openai-codex` | ChatGPT subscription via OAuth |
| `openrouter` | OpenRouter (access multiple providers) |
| `bedrock` | AWS Bedrock |
| `gemini` | Google Gemini |
| `xai` | X AI (Grok) |
| `cerebras` | Cerebras (fast inference) |
| `deepseek` | DeepSeek |
| `ollama` | Ollama (local models) |
| `lmstudio` | LM Studio (local models) |
| `openai` | OpenAI-compatible API (custom base URL) |
---
### cline history (alias: h)
Browse task history with pagination.
```bash
# Show recent tasks (default: 10)
cline history
# Show more tasks
cline history -n 20
# Paginate through history
cline history -n 10 -p 2
```
**Options:**
| Option | Description |
|--------|-------------|
| `-n, --limit <number>` | Number of tasks to show (default: 10) |
| `-p, --page <number>` | Page number, 1-based (default: 1) |
---
### cline config
View and manage configuration settings.
```bash
cline config
```
Opens an interactive configuration view with tabs for:
- **Settings** - Global and workspace-specific settings
- **Rules** - `.clinerules` files and imported rules
- **Workflows** - Available workflows (appear as slash commands)
- **Hooks** - Configured hook scripts
- **Skills** - Enabled skills
---
### cline update
Check for updates and install the latest version.
```bash
cline update
```
---
### cline version
Show the installed CLI version.
```bash
cline version
```
---
### cline dev
Developer tools for debugging.
```bash
# Open the log file
cline dev log
```
## Environment Variables
### CLINE_DIR
Override the default configuration directory:
```bash
export CLINE_DIR=/path/to/custom/config
cline "your task"
```
When set, all Cline data (settings, secrets, task history) is stored in this directory instead of `~/.cline/data/`.
**Use cases:**
- Running isolated Cline instances with different settings
- CI/CD environments with custom state directories
- Testing configuration changes without affecting your main setup
### CLINE_COMMAND_PERMISSIONS
Restrict which shell commands Cline can execute:
```bash
export CLINE_COMMAND_PERMISSIONS='{"allow": ["npm *", "git *"], "deny": ["rm -rf *"]}'
```
**Format:**
```json
{
"allow": ["pattern1", "pattern2"],
"deny": ["pattern3"],
"allowRedirects": true
}
```
| Field | Type | Description |
|-------|------|-------------|
| `allow` | `string[]` | Glob patterns for allowed commands. If set, **only** matching commands are permitted. |
| `deny` | `string[]` | Glob patterns for denied commands. Deny rules **always take precedence** over allow rules. |
| `allowRedirects` | `boolean` | Whether to allow shell redirects (`>`, `>>`, `<`). Default: `false`. |
**Examples:**
```bash
# Allow only npm and git commands (deny everything else)
export CLINE_COMMAND_PERMISSIONS='{"allow": ["npm *", "git *"]}'
# Allow dev commands but explicitly deny dangerous ones
export CLINE_COMMAND_PERMISSIONS='{"allow": ["npm *", "git *", "node *"], "deny": ["rm -rf *", "sudo *"]}'
# Allow file reading with redirects
export CLINE_COMMAND_PERMISSIONS='{"allow": ["cat *", "echo *"], "allowRedirects": true}'
```
**How commands are evaluated:**
1. Check for dangerous characters (backticks outside single quotes, unquoted newlines)
2. Parse command into segments split by operators (`&&`, `||`, `|`, `;`)
3. If redirects are detected and `allowRedirects` is not true, command is denied
4. Each segment is validated against deny rules first, then allow rules
5. Subshell contents (`$(...)` and `(...)`) are recursively validated
6. All segments must pass for the command to be allowed
## JSON Output Format
When using `--json`, each message is output as a JSON object (one per line):
```json
{
"type": "say",
"text": "I'll create the file now.",
"ts": 1760501486669,
"say": "text"
}
```
**Required fields:**
| Field | Type | Description |
|-------|------|-------------|
| `type` | `"ask"` \| `"say"` | Message category |
| `text` | `string` | Human-readable message content |
| `ts` | `number` | Unix timestamp in milliseconds |
**Optional fields:**
| Field | Type | Description |
|-------|------|-------------|
| `say` | `string` | Subtype when `type` is `"say"` (e.g., `"text"`, `"tool"`) |
| `ask` | `string` | Subtype when `type` is `"ask"` (e.g., `"tool"`, `"followup"`) |
| `reasoning` | `string` | Model reasoning (omitted when empty) |
| `partial` | `boolean` | `true` while streaming (omitted when complete) |
| `images` | `string[]` | Image URIs (omitted when empty) |
| `files` | `string[]` | File paths (omitted when empty) |
## Configuration Files
Cline stores all data in `~/.cline/` by default:
```text
~/.cline/
├── data/ # Configuration directory
│ ├── globalState.json # Global settings
│ ├── secrets.json # API keys (stored securely)
│ ├── workspace/ # Workspace-specific state
│ └── tasks/ # Task history and conversations
└── log/ # Debug logs (view with cline dev log)
```
## Examples
### Interactive Development
```bash
# Start interactive mode
cline
# Start with a task and use interactive UI
cline "Help me refactor this codebase"
```
### Direct Task Execution
```bash
# Run a task directly
cline "Add error handling to utils.js"
# Start in Plan mode to review strategy first
cline -p "Design a caching layer for the API"
# Use a specific model
cline -m gpt-4o "Explain this code"
```
### Piped Input
```bash
# Pipe file contents
cat README.md | cline "Summarize this document"
# Review git changes
git diff | cline "Review these changes"
# Analyze test output
npm test 2>&1 | cline "Fix any failing tests"
```
### Automation and CI/CD
```bash
# YOLO mode for automated workflows
cline -y "Run tests and fix failures"
# JSON output for scripting
cline --json "List all TODO comments" | jq '.text'
# With timeout
cline -y --timeout 600 "Run the full test suite"
# Chain commands
git diff | cline -y "explain" | cline -y "write a commit message"
```
### Authentication
```bash
# Interactive wizard
cline auth
# Quick setup: Anthropic
cline auth -p anthropic -k sk-ant-api-xxxxx -m claude-sonnet-4-5-20250929
# Quick setup: OpenAI
cline auth -p openai-native -k sk-xxxxx -m gpt-4o
# Quick setup: OpenRouter
cline auth -p openrouter -k sk-or-xxxxx
# OpenAI-compatible with custom URL
cline auth -p openai -k your-key -b https://api.example.com/v1
```
## Support
- **Report bugs:** https://github.com/cline/cline/issues
- **Discord community:** https://discord.gg/cline
- **Documentation:** https://docs.cline.bot
## See Also
<Columns cols={2}>
<Card title="Installation & Setup" icon="download" href="/cline-cli/installation">
Install Cline CLI and configure authentication.
</Card>
<Card title="Interactive Mode" icon="terminal" href="/cline-cli/interactive-mode">
Keyboard shortcuts, slash commands, and file mentions.
</Card>
<Card title="Headless Mode" icon="robot" href="/cline-cli/three-core-flows">
Run Cline autonomously in scripts, CI/CD pipelines, and automated workflows.
</Card>
<Card title="Configuration" icon="gear" href="/cline-cli/configuration">
Environment variables and advanced settings.
</Card>
</Columns>
+330
View File
@@ -0,0 +1,330 @@
---
title: "Configuration"
description: "Manage Cline CLI settings with cline config, environment variables, and configuration files"
---
Cline CLI provides multiple ways to configure settings, from the interactive `cline config` command to environment variables for automation.
## The Config Command
Launch the configuration interface:
```bash
cline config
```
This opens an interactive view with tabs for different configuration categories.
## Configuration Tabs
Navigate between tabs using arrow keys.
### Settings Tab
View and edit global and workspace-specific settings:
- **Global State**: Settings that apply across all workspaces
- **Workspace State**: Settings specific to the current directory
### Rules Tab
Manage Cline rules that guide AI behavior:
- **`.clinerules` files**: Project-specific rules in your workspace
- **Cursor rules**: Import rules from Cursor editor format
- **Windsurf rules**: Import rules from Windsurf editor format
Rules help Cline understand your project's conventions, coding standards, and preferences.
### Workflows Tab
View and manage [workflows](/customization/workflows):
- List available workflows
- View workflow definitions
- Workflows appear as slash commands in interactive mode
### Hooks Tab
Configure [hooks](/customization/hooks) for custom logic integration:
- Enable/disable hooks globally
- View configured hook scripts
- Hooks run at key points in Cline's workflow
<Note>
Hooks must be enabled via settings. Use `cline config` to toggle `hooks-enabled`.
</Note>
### Skills Tab
Manage [skills](/customization/skills) that extend Cline's capabilities:
- View available skills
- Enable/disable specific skills
- Skills provide specialized instructions for specific tasks
## Configuration Directory
Cline stores configuration in `~/.cline/data/`:
```text
~/.cline/
├── data/ # Configuration directory
│ ├── globalState.json # Global settings
│ ├── secrets.json # API keys (encrypted)
│ ├── settings/ # Settings files
│ │ └── cline_mcp_settings.json # MCP server configuration
│ ├── workspace/ # Workspace-specific state
│ └── tasks/ # Task history and data
└── log/ # Log files
```
### Viewing Logs
For debugging, view the log file:
```bash
cline dev log
```
This opens the log file in your default editor.
## Environment Variables
### CLINE_DIR
Override the default configuration directory:
```bash
export CLINE_DIR=/custom/path/to/cline
cline "your task"
```
When set, all Cline data is stored in this directory instead of `~/.cline/data/`.
**Use cases:**
- Running multiple isolated Cline configurations
- Team-shared configurations
- CI/CD with custom state directories
### CLINE_COMMAND_PERMISSIONS
Restrict which shell commands Cline can execute:
```bash
export CLINE_COMMAND_PERMISSIONS='{"allow": ["npm *", "git *"], "deny": ["rm -rf *"]}'
```
**Format:**
```json
{
"allow": ["pattern1", "pattern2"],
"deny": ["pattern3"],
"allowRedirects": true
}
```
**Fields:**
| Field | Type | Description |
|-------|------|-------------|
| `allow` | `string[]` | Glob patterns for allowed commands. If set, only matching commands are permitted. |
| `deny` | `string[]` | Glob patterns for denied commands. Deny rules take precedence over allow. |
| `allowRedirects` | `boolean` | Whether to allow shell redirects (`>`, `>>`, `<`). Default: `false` |
**Examples:**
```bash
# Allow only npm and git commands
export CLINE_COMMAND_PERMISSIONS='{"allow": ["npm *", "git *"]}'
# Allow dev commands but deny dangerous ones
export CLINE_COMMAND_PERMISSIONS='{"allow": ["npm *", "git *", "node *"], "deny": ["rm -rf *", "sudo *"]}'
# Allow file operations with redirects
export CLINE_COMMAND_PERMISSIONS='{"allow": ["cat *", "echo *"], "allowRedirects": true}'
```
<Warning>
When `allow` is set, all commands not matching the allow patterns are denied. Use this for security-sensitive environments.
</Warning>
## Using --config Flag
Run Cline with a custom configuration directory:
```bash
cline --config /path/to/custom/config "your task"
```
This is useful for:
- Running isolated Cline instances
- Testing different configurations
- Separating work and personal setups
**Example: Multiple configurations**
```bash
# Work configuration
cline --config ~/.cline-work "review this PR"
# Personal projects
cline --config ~/.cline-personal "help me with this side project"
```
## MCP Server Configuration
Cline CLI supports [MCP (Model Context Protocol)](/mcp/mcp-overview) servers, giving you access to external tools and data sources directly from the terminal. The CLI uses the same MCP configuration format as the VS Code extension.
### Setting Up MCP Servers
You can add MCP servers from the CLI:
```bash
# STDIO server
cline mcp add kanban -- kanban mcp
# Remote HTTP server
cline mcp add linear https://mcp.linear.app/mcp --type http
```
These commands update:
```
~/.cline/data/settings/cline_mcp_settings.json
```
You can still edit this file directly. It uses the same JSON format as the VS Code extension:
```json
{
"mcpServers": {
"my-server": {
"command": "node",
"args": ["/path/to/server.js"],
"env": {
"API_KEY": "your_api_key"
},
"alwaysAllow": ["tool1", "tool2"],
"disabled": false
}
}
}
```
For the full configuration reference including STDIO and SSE transport types, see [Adding and Configuring MCP Servers](/mcp/adding-and-configuring-servers).
<Note>
The CLI does not yet have a `/mcp` slash command for interactive management inside the terminal UI. Use `cline mcp add` or edit `cline_mcp_settings.json` directly.
</Note>
### Custom Config Directory
If you use the `CLINE_DIR` environment variable or `--config` flag, the MCP settings file will be located at `<your-config-dir>/data/settings/cline_mcp_settings.json` instead.
## Configuration for Local Providers
### Ollama
Configure context window size for Ollama:
```bash
# In settings or via config
cline config
# Navigate to Settings tab, find ollama-api-options-ctx-num
```
Or set via environment:
```bash
# Set context window to 32K tokens
cline -m ollama/llama3 "your task"
```
### LM Studio
Configure max tokens for LM Studio:
```bash
cline config
# Navigate to Settings tab, find lm-studio-max-tokens
```
## Importing Configuration
### From VS Code Extension
If you use the Cline VS Code extension, the CLI automatically detects and can share some settings. However, the CLI maintains its own configuration for terminal-specific features.
### From Other CLI Tools
See [Installation & Setup](/cline-cli/installation#option-3-import-from-existing-tools) for importing configurations from:
- Codex CLI
- OpenCode
## Configuration Best Practices
### For Development
Use the default configuration with workspace-specific rules:
```bash
# Add project-specific rules
echo "Use TypeScript strict mode" > .clinerules/typescript.md
```
### For CI/CD
Use environment variables and `--yolo` mode:
```bash
export CLINE_COMMAND_PERMISSIONS='{"allow": ["npm test", "npm run build"]}'
cline -y "run tests and fix any failures"
```
### For Teams
Share configuration via version control:
```bash
# Commit .clinerules/ to your repo
git add .clinerules/
git commit -m "Add Cline rules for team"
```
## Troubleshooting
### Configuration Not Persisting
1. Check write permissions on `~/.cline/data/`
2. Ensure `CLINE_DIR` isn't set to a read-only location
3. Verify the config directory exists
### Environment Variables Not Working
1. Ensure variables are exported: `export CLINE_DIR=/path`
2. Check for typos in variable names
3. Verify JSON syntax for `CLINE_COMMAND_PERMISSIONS`
### Reset Configuration
To start fresh, remove the configuration directory:
```bash
rm -rf ~/.cline/data/
cline auth # Re-authenticate
```
## Next Steps
<Columns cols={2}>
<Card title="Headless Mode" icon="robot" href="/cline-cli/three-core-flows">
Run Cline autonomously in scripts, CI/CD pipelines, and automated workflows.
</Card>
<Card title="CLI Reference" icon="terminal" href="/cline-cli/cli-reference">
Complete command documentation with all flags and options.
</Card>
</Columns>
+457
View File
@@ -0,0 +1,457 @@
---
title: "Getting Started"
description: "Run Cline AI coding agents directly in your terminal with an interactive CLI or automated workflows"
---
## What is Cline CLI?
Cline CLI brings the full power of Cline to your terminal. Whether you prefer an interactive experience or automated workflows for CI/CD pipelines, the CLI adapts to your needs.
The CLI supports macOS, Linux, and Windows, and works with all the same AI providers as the VS Code extension.
## Two Ways to Use Cline CLI
The CLI operates in two distinct modes, automatically selecting the appropriate one based on how you invoke it:
### Interactive Mode
Interactive mode is designed for **hands-on development sessions** where you want to collaborate with Cline in real-time. It provides a rich terminal interface that feels like chatting with an AI assistant.
**When it activates:** Running `cline` without arguments, or when stdin is a TTY (terminal).
```bash
cline
```
Key features:
- **Real-time conversation** - Type messages, see Cline's responses, and iterate on tasks
- **Visual feedback** - Animated welcome screen, syntax-highlighted code, and progress indicators
- **File mentions** with `@` - Reference workspace files with fuzzy search autocomplete
- **Slash commands** with `/` - Quick access to `/settings`, `/history`, `/models`, and workflows
- **Keyboard shortcuts** - `Tab` to toggle Plan/Act, `Shift+Tab` for auto-approve all
- **Session summaries** - See tasks completed, files modified, and token usage on exit
- **Settings panel** - Configure providers, models, and features without leaving the CLI
Interactive mode keeps you in control. You review Cline's plan, approve or modify actions, and guide the conversation.
[Learn more about interactive mode →](/cline-cli/interactive-mode)
### Headless Mode (Non-Interactive)
Headless mode is designed for **automation, scripting, and CI/CD pipelines** where human interaction isn't possible or desired.
**When it activates:** Using the `-y`/`--yolo` flag, `--json` flag, piping input/output, or when stdin is not a TTY.
```bash
# Headless with auto-approval (YOLO mode)
cline -y "Run tests and fix any failures"
# Headless with JSON output for parsing
cline --json "List all TODO comments" | jq '.text'
# Headless via piped input
cat README.md | cline "Summarize this document"
# Chain multiple headless commands
git diff | cline -y "explain these changes" | cline -y "write a commit message"
```
Key features:
- **No visual interface** - Clean text or JSON output suitable for scripting
- **Automatic execution** - With `-y`, Cline approves all actions and runs autonomously
- **Process control** - Exits automatically when the task completes
- **Piped workflows** - Read from stdin, write to stdout, chain with other commands
- **Machine-readable output** - Use `--json` to get structured output for parsing
<Warning>
Headless mode with `-y` gives Cline full autonomy. Run on a clean git branch so you can easily revert changes if needed.
</Warning>
### Mode Detection Summary
Cline automatically detects which mode to use based on your invocation. This table shows how different command patterns trigger each mode, helping you predict behavior in scripts and interactive sessions.
| Invocation | Mode | Reason |
|------------|------|--------|
| `cline` | Interactive | No arguments, TTY connected |
| `cline "task"` | Interactive | TTY connected |
| `cline -y "task"` | Headless | YOLO flag forces headless |
| `cline --json "task"` | Headless | JSON flag forces headless |
| `cat file \| cline "task"` | Headless | stdin is piped |
| `cline "task" > output.txt` | Headless | stdout is redirected |
[Learn more about headless mode →](/cline-cli/three-core-flows)
## Supported Model Providers
Cline CLI supports all providers available in the VS Code extension:
- **Anthropic** (Claude)
- **OpenAI** (GPT-4o, GPT-4)
- **OpenAI Codex** (ChatGPT subscription)
- **OpenRouter**
- **AWS Bedrock**
- **Google Gemini**
- **X AI (Grok)**
- **Cerebras**
- **DeepSeek**
- **Ollama** (local models)
- **LM Studio** (local models)
- **OpenAI Compatible** (any compatible API)
During setup, authenticate with `cline auth` to configure your preferred provider. [See authentication →](#authenticate)
## What You Can Build
### Automated Code Maintenance
Keep your codebase healthy with automated fixes. Cline scans for issues and applies corrections across multiple files.
```bash
cline -y "Fix all ESLint errors in src/"
```
Finds and fixes linting violations throughout your source directory.
```bash
cline -y "Update all deprecated React lifecycle methods"
```
Migrates legacy code patterns to modern equivalents (e.g., `componentWillMount` → `useEffect`).
```bash
cline -y "Update dependencies with known vulnerabilities"
```
Identifies outdated packages with security issues and updates them to safe versions.
### CI/CD Integration
Integrate Cline into your continuous integration pipelines for automated code review and documentation.
```bash
git diff origin/main | cline -y "Review these changes for issues"
```
Pipes your PR diff to Cline for automated code review, catching bugs and style issues before merge.
```bash
git log --oneline v1.0..v1.1 | cline -y "Write release notes"
```
Generates human-readable release notes from your commit history between two tags.
```bash
cline -y "Run tests and fix failures" --timeout 600
```
Executes your test suite, analyzes failures, and attempts fixes with a 10-minute timeout.
### Development Workflows
From quick edits to complex refactors, Cline adapts to your workflow.
```bash
cline
```
Launches interactive mode for exploratory development and back-and-forth collaboration.
```bash
cline "Refactor this function to use async/await"
```
Executes a focused task directly from the command line with approval prompts at key steps.
```bash
cline "Based on @src/api.ts, add error handling to all endpoints"
```
Uses file mentions (`@`) to give Cline context about specific files in your workspace.
### Custom Shell Pipelines
Chain Cline with other CLI tools to build powerful automation workflows.
```bash
gh pr diff 123 | cline -y "Review this PR"
```
Fetches a GitHub PR diff and pipes it directly to Cline for review.
```bash
cline --json "List all TODO comments" | jq '.text'
```
Outputs structured JSON that you can process with tools like `jq` for scripting.
```bash
git diff | cline -y "explain" | cline -y "write a haiku about these changes"
```
Chains multiple Cline invocations together for creative multi-step workflows.
## Features at a Glance
| Feature | Interactive Mode | Non-Interactive Mode |
|---------|------------------|----------------------|
| Interactive chat | ✓ | - |
| File mentions (@) | ✓ | ✓ (inline) |
| Slash commands (/) | ✓ | - |
| Settings panel | ✓ | `cline config` |
| Plan/Act toggle | ✓ (Tab) | `-p` / `-a` flags |
| Auto-approve | ✓ (Shift+Tab) | `-y` flag |
| Session summary | ✓ | - |
| JSON output | - | `--json` |
| Piped input | - | ✓ |
---
## Installation & Setup
In just a few minutes, you can install the CLI, authenticate with your preferred AI provider, and start running tasks from any directory on your machine.
### Prerequisites
Cline CLI requires **Node.js version 20 or higher**. We recommend Node.js 22 for the best experience.
Check your Node.js version:
```bash
node --version
```
If you need to install or update Node.js, visit [nodejs.org](https://nodejs.org) or use a version manager like [nvm](https://github.com/nvm-sh/nvm).
### Install Cline CLI
Install globally via npm:
```bash
npm install -g cline
```
Verify the installation:
```bash
cline version
```
<Tip>
To install a specific version, use `npm install -g cline@2.0.0`. Check [npm](https://www.npmjs.com/package/cline) for available versions.
</Tip>
### Authenticate
After installation, run the authentication wizard:
```bash
cline auth
```
This launches an interactive wizard with multiple options. Choose the method that works best for your workflow.
#### Option 1: Sign in with Cline (Recommended)
Select **"Sign in with Cline"** to authenticate with your Cline account via OAuth. Your browser opens automatically to complete sign-in.
#### Option 2: Sign in with ChatGPT Subscription
If you have a ChatGPT Plus or Pro subscription, select **"Sign in with ChatGPT Subscription"**. This uses OpenAI's Codex OAuth to authenticate with your existing subscription.
#### Option 3: Import from Existing Tools
Already using another AI coding CLI? Cline can import your existing configuration:
- **Import from Codex CLI** - Imports credentials from `~/.codex/auth.json`
- **Import from OpenCode** - Imports configuration from `~/.local/share/opencode/auth.json`
#### Option 4: Bring Your Own API Key
Select **"Bring your own API key"** to manually configure any supported provider. Or skip the wizard entirely with flags:
```bash
# Anthropic (Claude)
cline auth -p anthropic -k sk-ant-api-xxxxx -m claude-sonnet-4-5-20250929
# OpenAI
cline auth -p openai-native -k sk-xxxxx -m gpt-4o
# OpenRouter
cline auth -p openrouter -k sk-or-xxxxx -m anthropic/claude-sonnet-4-5-20250929
# OpenAI-compatible provider with custom base URL
cline auth -p openai -k your-api-key -b https://api.example.com/v1
```
**Quick Setup Flags:**
| Flag | Description |
|------|-------------|
| `-p, --provider <id>` | Provider ID (e.g., `anthropic`, `openai-native`, `openrouter`) |
| `-k, --apikey <key>` | Your API key |
| `-m, --modelid <id>` | Model ID (e.g., `claude-sonnet-4-5-20250929`, `gpt-4o`) |
| `-b, --baseurl <url>` | Base URL for OpenAI-compatible providers |
<Tip>
Flags are especially useful for scripting, CI/CD environments, or setting up multiple machines.
</Tip>
#### Supported Providers
| Provider | Provider ID | Notes |
|----------|-------------|-------|
| Anthropic | `anthropic` | Direct Claude API access |
| OpenAI | `openai-native` | GPT-4o, GPT-4, etc. |
| OpenAI Codex | `openai-codex` | ChatGPT subscription OAuth |
| OpenRouter | `openrouter` | Access multiple providers |
| AWS Bedrock | `bedrock` | Claude via AWS |
| Google Gemini | `gemini` | Gemini Pro, etc. |
| X AI (Grok) | `xai` | Grok models |
| Cerebras | `cerebras` | Fast inference |
| DeepSeek | `deepseek` | DeepSeek models |
| Ollama | `ollama` | Local models |
| LM Studio | `lmstudio` | Local models |
| OpenAI Compatible | `openai` | Any OpenAI-compatible API |
### Verify Your Setup
Confirm everything is working with a simple test:
```bash
cline "What is 2 + 2?"
```
If Cline responds with an answer, your installation and authentication are complete.
Check your current configuration:
```bash
cline config
```
### Quick Start
Now you're ready to use Cline. Choose how you want to work:
#### Interactive Mode
Launch the interactive CLI for development:
```bash
cline
```
You'll see the Cline welcome screen. Type your task and press Enter. Use:
- `Tab` to toggle between Plan and Act modes
- `Shift+Tab` to enable auto-approve
- `/help` for available commands
[Learn more about interactive mode →](/cline-cli/interactive-mode)
#### Direct Task Execution
Run a task directly from your shell:
```bash
cline "Add error handling to utils.js"
```
For non-interactive execution (perfect for scripts and CI/CD):
```bash
cline -y "Run tests and fix any failures"
```
[Learn more about headless mode →](/cline-cli/three-core-flows)
### Switching Providers
To change your configured provider at any time:
```bash
cline auth
```
You can also use the settings panel in interactive mode:
```bash
cline
# Then type: /settings
# Navigate to the API tab
```
### Updating
Check for updates and install the latest version:
```bash
cline update
```
Or update manually via npm:
```bash
npm update -g cline
```
### Troubleshooting
#### Command Not Found
If `cline` is not found after installation:
1. Ensure npm global bin is in your PATH:
```bash
npm bin -g
```
2. Add the path to your shell configuration (`.bashrc`, `.zshrc`, etc.):
```bash
export PATH="$PATH:$(npm bin -g)"
```
3. Restart your terminal or source your shell config.
#### Permission Errors
If you get permission errors during installation:
```bash
# Option 1: Use a Node version manager (recommended)
# nvm, fnm, or volta handle permissions automatically
# Option 2: Fix npm permissions
# See: https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally
```
#### OAuth Flow Issues
If the browser doesn't open automatically during OAuth:
1. Copy the URL from the terminal
2. Paste it in your browser manually
3. Complete the sign-in flow
4. Return to the terminal
#### API Key Validation
If your API key is rejected:
1. Verify the key is correct and hasn't expired
2. Check that you've selected the correct provider
3. Ensure your API account has the necessary permissions
**Provider-specific tips:**
- **Anthropic**: Keys start with `sk-ant-`
- **OpenAI**: Keys start with `sk-`
- **AWS Bedrock**: Requires AWS credentials configured separately. See [AWS Bedrock documentation](/provider-config/aws-bedrock/api-key).
### Uninstallation
To remove Cline CLI:
```bash
npm uninstall -g cline
```
To also remove configuration data:
```bash
rm -rf ~/.cline
```
## Next Steps
- **[Interactive Mode](/cline-cli/interactive-mode)** - Master the interactive CLI with shortcuts and slash commands
- **[Headless Mode](/cline-cli/three-core-flows)** - Run Cline autonomously in scripts, CI/CD pipelines, and automated workflows
- **[Configuration](/cline-cli/configuration)** - Configure settings, rules, workflows, and environment variables
- **[CLI Reference](/cline-cli/cli-reference)** - Complete command documentation with all flags and options
+278
View File
@@ -0,0 +1,278 @@
---
title: "Installation & Setup"
description: "Install Cline CLI on macOS, Linux, or Windows and configure your AI provider"
---
Cline CLI brings the full power of Cline to your terminal. In just a few minutes, you can install the CLI, authenticate with your preferred AI provider, and start running tasks from any directory on your machine.
## Prerequisites
Cline CLI requires **Node.js version 20 or higher**. We recommend Node.js 22 for the best experience.
Check your Node.js version:
```bash
node --version
```
If you need to install or update Node.js, visit [nodejs.org](https://nodejs.org) or use a version manager like [nvm](https://github.com/nvm-sh/nvm).
## Install Cline CLI
Install globally via npm:
```bash
npm install -g cline
```
Verify the installation:
```bash
cline version
```
<Tip>
To install a specific version, use `npm install -g cline@2.0.0`. Check [npm](https://www.npmjs.com/package/cline) for available versions.
</Tip>
## Authenticate
After installation, run the authentication wizard:
```bash
cline auth
```
This launches an interactive wizard with multiple options. Choose the method that works best for your workflow.
### Option 1: Sign in with Cline (Recommended)
Select **"Sign in with Cline"** to authenticate with your Cline account via OAuth. Your browser opens automatically to complete sign-in.
### Option 2: Sign in with ChatGPT Subscription
If you have a ChatGPT Plus or Pro subscription, select **"Sign in with ChatGPT Subscription"**. This uses OpenAI's Codex OAuth to authenticate with your existing subscription.
### Option 3: Import from Existing Tools
Already using another AI coding CLI? Cline can import your existing configuration:
- **Import from Codex CLI** - Imports credentials from `~/.codex/auth.json`
- **Import from OpenCode** - Imports configuration from `~/.local/share/opencode/auth.json`
### Option 4: Bring Your Own API Key
Select **"Bring your own API key"** to manually configure any supported provider. Or skip the wizard entirely with flags:
```bash
# Anthropic (Claude)
cline auth -p anthropic -k sk-ant-api-xxxxx -m claude-sonnet-4-5-20250929
# OpenAI
cline auth -p openai-native -k sk-xxxxx -m gpt-4o
# OpenRouter
cline auth -p openrouter -k sk-or-xxxxx -m anthropic/claude-sonnet-4-5-20250929
# Moonshot
cline auth -p moonshot -k sk-xxxxx -m kimi-k2.5
# OpenAI-compatible provider with custom base URL
cline auth -p openai -k your-api-key -b https://api.example.com/v1
```
**Quick Setup Flags:**
| Flag | Description |
|------|-------------|
| `-p, --provider <id>` | Provider ID (e.g., `anthropic`, `openai-native`, `openrouter`, `moonshot`) |
| `-k, --apikey <key>` | Your API key |
| `-m, --modelid <id>` | Model ID (e.g., `claude-sonnet-4-5-20250929`, `gpt-4o`) |
| `-b, --baseurl <url>` | Base URL for OpenAI-compatible providers |
<Tip>
Flags are especially useful for scripting, CI/CD environments, or setting up multiple machines.
</Tip>
### Supported Providers
| Provider | Provider ID | Notes |
|----------|-------------|-------|
| Anthropic | `anthropic` | Direct Claude API access |
| OpenAI | `openai-native` | GPT-4o, GPT-4, etc. |
| OpenAI Codex | `openai-codex` | ChatGPT subscription OAuth |
| OpenRouter | `openrouter` | Access multiple providers |
| AWS Bedrock | `bedrock` | Claude via AWS |
| Google Gemini | `gemini` | Gemini Pro, etc. |
| X AI (Grok) | `xai` | Grok models |
| Cerebras | `cerebras` | Fast inference |
| DeepSeek | `deepseek` | DeepSeek models |
| Moonshot | `moonshot` | Kimi models via Moonshot AI |
| Ollama | `ollama` | Local models |
| LM Studio | `lmstudio` | Local models |
| OpenAI Compatible | `openai` | Any OpenAI-compatible API |
## Verify Your Setup
Confirm everything is working with a simple test:
```bash
cline "What is 2 + 2?"
```
If Cline responds with an answer, your installation and authentication are complete.
Check your current configuration:
```bash
cline config
```
## Quick Start
Now you're ready to use Cline. Choose how you want to work:
### Interactive Mode
Launch the interactive CLI for development:
```bash
cline
```
You'll see the Cline welcome screen. Type your task and press Enter. Use:
- `Tab` to toggle between Plan and Act modes
- `Shift+Tab` to enable auto-approve
- `/help` for available commands
[Learn more about interactive mode →](/cline-cli/interactive-mode)
### Direct Task Execution
Run a task directly from your shell:
```bash
cline "Add error handling to utils.js"
```
For non-interactive execution (perfect for scripts and CI/CD):
```bash
cline -y "Run tests and fix any failures"
```
[Learn more about headless mode →](/cline-cli/three-core-flows)
## Switching Providers
To change your configured provider at any time:
```bash
cline auth
```
You can also use the settings panel in interactive mode:
```bash
cline
# Then type: /settings
# Navigate to the API tab
```
## Updating
Check for updates and install the latest version:
```bash
cline update
```
Or update manually via npm:
```bash
npm update -g cline
```
## Troubleshooting
### Command Not Found
If `cline` is not found after installation:
1. Ensure npm global bin is in your PATH:
```bash
npm bin -g
```
2. Add the path to your shell configuration (`.bashrc`, `.zshrc`, etc.):
```bash
export PATH="$PATH:$(npm bin -g)"
```
3. Restart your terminal or source your shell config.
### Permission Errors
If you get permission errors during installation:
```bash
# Option 1: Use a Node version manager (recommended)
# nvm, fnm, or volta handle permissions automatically
# Option 2: Fix npm permissions
# See: https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally
```
### OAuth Flow Issues
If the browser doesn't open automatically during OAuth:
1. Copy the URL from the terminal
2. Paste it in your browser manually
3. Complete the sign-in flow
4. Return to the terminal
### API Key Validation
If your API key is rejected:
1. Verify the key is correct and hasn't expired
2. Check that you've selected the correct provider
3. Ensure your API account has the necessary permissions
**Provider-specific tips:**
- **Anthropic**: Keys start with `sk-ant-`
- **OpenAI**: Keys start with `sk-`
- **AWS Bedrock**: Requires AWS credentials configured separately. See [AWS Bedrock documentation](/provider-config/aws-bedrock/api-key).
## Uninstallation
To remove Cline CLI:
```bash
npm uninstall -g cline
```
To also remove configuration data:
```bash
rm -rf ~/.cline
```
## Next Steps
<Columns cols={2}>
<Card title="Interactive Mode" icon="terminal" href="/cline-cli/interactive-mode">
Master the interactive CLI with shortcuts and slash commands.
</Card>
<Card title="Headless Mode" icon="robot" href="/cline-cli/three-core-flows">
Run Cline autonomously in scripts, CI/CD pipelines, and automated workflows.
</Card>
<Card title="Configuration" icon="gear" href="/cline-cli/configuration">
Configure settings, rules, workflows, and environment variables.
</Card>
<Card title="CLI Reference" icon="book" href="/cline-cli/cli-reference">
Complete command documentation with all flags and options.
</Card>
</Columns>
+252
View File
@@ -0,0 +1,252 @@
---
title: "Interactive Mode"
description: "Master the interactive CLI with keyboard shortcuts, slash commands, and file mentions"
---
Interactive mode is the primary way to work with Cline CLI when you want a collaborative, conversational experience. Unlike headless mode (which runs a single task and exits), interactive mode keeps a session open where you can have back-and-forth conversations with Cline, refine your requests, and guide the AI as it works.
## Why Use Interactive Mode?
Interactive mode is ideal when you:
- **Don't know exactly what you need yet** - Explore a codebase, ask questions, and let Cline help you understand the architecture before making changes
- **Want to review before acting** - Toggle Plan mode to see Cline's strategy, then switch to Act mode when you're ready
- **Need iterative refinement** - Build on previous responses, ask follow-up questions, and guide Cline to the right solution
- **Prefer human oversight** - Review each action, approve file changes, and maintain control over what Cline does
- **Working on complex tasks** - Multi-step refactoring, debugging sessions, or feature development that requires judgment calls
For automated workflows, scripts, or CI/CD pipelines, see [headless mode](/cline-cli/overview#headless-mode-non-interactive) instead.
## Prerequisites
Before using interactive mode, you need to have Cline CLI installed and authenticated. If you haven't done this yet, follow the [Installation & Setup guide](/cline-cli/installation) first.
## Launching Interactive Mode
Start interactive mode by running `cline` without any arguments:
```bash
cline
```
You'll see an animated welcome screen with the Cline robot. Start typing your task in the input field at the bottom of the screen.
## Keyboard Shortcuts
Keyboard shortcuts are the primary way to navigate and control the interactive CLI. Since there's no mouse interaction in the terminal, learning these shortcuts will help you work efficiently and switch between modes, manage input, and control your session without breaking your flow.
### Mode Controls
| Shortcut | Action |
|----------|--------|
| `Tab` | Toggle between Plan and Act mode |
| `Shift+Tab` | Toggle auto-approve all actions |
| `Esc` | Exit or cancel current operation |
### Input Controls
| Shortcut | Action |
|----------|--------|
| `Enter` | Submit your message |
| `↑` / `↓` | Navigate message history |
| `Home` / `End` | Move cursor to start/end of line |
| `Ctrl+A` | Move cursor to beginning |
| `Ctrl+E` | Move cursor to end |
| `Ctrl+W` | Delete word before cursor |
| `Ctrl+U` | Delete entire line |
### Session Controls
| Shortcut | Action |
|----------|--------|
| `Ctrl+C` | Exit with session summary |
## File Mentions with @
Reference files from your workspace by typing `@` followed by the filename:
```text
@src/utils.ts can you add error handling to this file?
```
As you type after `@`, Cline shows a fuzzy search dropdown of matching files. Use arrow keys to navigate and `Enter` to select.
<Tip>
File search uses ripgrep for fast, fuzzy matching. You can type partial paths like `@utils` to find `src/utils/helpers.ts`.
</Tip>
### Multiple File Mentions
Include multiple files in a single message:
```text
Compare @src/old-api.ts with @src/new-api.ts and list the breaking changes
```
## Slash Commands
Type `/` to see available commands. Slash commands provide quick access to settings, history, and workflows.
### Built-in Commands
| Command | Description |
|---------|-------------|
| `/settings` | Open the settings panel |
| `/models` | Quick model switching |
| `/history` | Browse and resume previous tasks |
| `/clear` | Start a fresh task (clears current conversation) |
| `/help` | Show help and available commands |
| `/exit` | Exit the CLI |
### Workflow Commands
If you have [workflows](/customization/workflows) configured, they appear as additional slash commands. For example, if you have a workflow named `code-review`, you can invoke it with:
```text
/code-review
```
## Settings Panel
Access the settings panel with `/settings`. Navigate between tabs using arrow keys.
| Tab | Description | Settings |
|-----|-------------|----------|
| **API** | Configure your AI provider and model | Provider selection, model choice, extended thinking toggle, thinking budget |
| **Auto-approve** | Control which actions Cline can perform without prompting | Read files, write files, execute commands, browser actions, MCP tools |
| **Features** | Toggle Cline capabilities | Hooks, skills, auto-compact, sound notifications |
| **Account** | Manage your Cline account | View account status, sign in/out, manage subscription |
| **Other** | Additional preferences | Theme preferences, debug options |
## Plan and Act Modes
Cline operates in two modes, toggled with `Tab`. These modes work the same way in the CLI as they do in the VS Code extension. For a deeper explanation of how Plan and Act modes work, see the [Plan and Act documentation](/core-workflows/plan-and-act).
### Plan Mode
In Plan mode, Cline analyzes your request and creates a strategy before making changes. Use this when:
- Exploring a new codebase
- Working on complex refactoring
- You want to review the approach first
### Act Mode
In Act mode, Cline executes tasks directly. Use this when:
- You're confident in the task
- Making straightforward changes
- Running quick operations
<Tip>
Press `Tab` anytime to switch modes. Starting in Plan mode and switching to Act after reviewing is a common workflow.
</Tip>
## Auto-approve Toggle
Press `Shift+Tab` to toggle auto-approve for all actions. This removes the approval prompts that appear before each action, letting Cline work continuously without interruption.
### When to Enable Auto-approve
Auto-approve is useful when:
- **You trust the task** - Well-defined tasks where you're confident in the outcome
- **Speed matters** - Long-running tasks where constant approvals slow you down
- **You're watching anyway** - You can see Cline's work in real-time and can interrupt if needed
- **Iterating quickly** - Rapid prototyping where you want to see results fast
### What Gets Auto-approved
When enabled, these actions happen without prompting:
- File reads
- File writes
- Command execution
- Browser actions
- MCP tool calls
You can also configure granular auto-approve settings (e.g., auto-approve reads but not writes) via `/settings` → Auto-approve tab, or see the [Auto-approve documentation](/features/auto-approve) for more details.
<Warning>
Auto-approve gives Cline full autonomy. Use on a clean git branch so you can easily revert changes if needed. You can always press `Ctrl+C` to stop Cline immediately.
</Warning>
## Session Summary
When you exit with `Ctrl+C`, Cline displays a session summary showing:
- Tasks completed
- Files modified
- Commands executed
- Token usage
This helps you track what was accomplished during your session.
## Running Multiple Instances
By default, all CLI instances share the same settings and state. However, you may want to run isolated instances with separate configurations for scenarios like:
- **Different models for different tasks** - Use a fast, cheap model for quick questions in one terminal and a more capable model for complex refactoring in another
- **Separate work and personal projects** - Keep API keys, rules, and task history isolated between contexts
- **Testing configuration changes** - Experiment with new settings without affecting your main setup
- **Team vs. individual settings** - Use shared team configuration for work projects and personal preferences for side projects
To run isolated instances, use the `--config` flag with different directories:
```bash
# Work instance with team configuration
cline --config ~/.cline-work
# Personal instance with different model/provider
cline --config ~/.cline-personal
# Experimental instance for testing new settings
cline --config ~/.cline-test
```
Each config directory maintains its own provider settings, API keys, task history, and preferences.
<Tip>
Use terminal multiplexers like tmux or split terminals to run multiple Cline instances in parallel, each working on different parts of your project with different models or settings.
</Tip>
## Tips for Effective Usage
### Start with Context
Give Cline context about what you're working on:
```text
I'm building a REST API with Express. The routes are in @src/routes/ and models in @src/models/. Help me add user authentication.
```
### Use Plan Mode for Exploration
When you're unsure about the best approach:
```text
[Tab to Plan mode]
How should I structure the database schema for a multi-tenant SaaS app?
```
### Iterate with Follow-ups
The interactive CLI maintains conversation context. Build on previous messages:
```text
> Add a login endpoint
[Cline creates the endpoint]
> Now add rate limiting to it
[Cline modifies the same endpoint]
> Add tests for both features
[Cline creates test files]
```
## Next Steps
<Columns cols={2}>
<Card title="Headless Mode" icon="robot" href="/cline-cli/three-core-flows">
Run Cline autonomously in scripts, CI/CD pipelines, and automated workflows.
</Card>
<Card title="Configuration" icon="gear" href="/cline-cli/configuration">
Explore `cline config` and advanced configuration options.
</Card>
</Columns>
+242
View File
@@ -0,0 +1,242 @@
---
title: "Overview"
description: "Run Cline AI coding agents directly in your terminal with an interactive CLI or automated workflows"
---
## What is Cline CLI?
Cline CLI brings the full power of Cline to your terminal. Whether you prefer an interactive experience or automated workflows for CI/CD pipelines, the CLI adapts to your needs.
The CLI supports macOS, Linux, and Windows, and works with all the same AI providers as the VS Code extension.
<Tip>
Ready to get started? Check out the [installation guide](/cline-cli/installation) to install Cline CLI and run your first task.
</Tip>
## Two Ways to Use Cline CLI
<Columns cols={2}>
<Card title="Interactive Mode" icon="terminal" href="/cline-cli/interactive-mode">
**For hands-on development.** Launch `cline` in your terminal and collaborate with Cline in real-time — chat, review plans, approve actions, and iterate on tasks with a rich visual interface.
</Card>
<Card title="Headless Mode" icon="robot" href="/cline-cli/three-core-flows">
**For automation & CI/CD.** Run `cline -y "task"` to let Cline work autonomously — no interaction needed. Pipe input/output, get JSON results, and chain commands in scripts and pipelines.
</Card>
</Columns>
The CLI operates in two distinct modes, automatically selecting the appropriate one based on how you invoke it:
### Interactive Mode
Interactive mode is designed for **hands-on development sessions** where you want to collaborate with Cline in real-time. It provides a rich terminal interface that feels like chatting with an AI assistant.
**When it activates:** Running `cline` without arguments, or when stdin is a TTY (terminal).
```bash
cline
```
Key features:
- **Real-time conversation** - Type messages, see Cline's responses, and iterate on tasks
- **Visual feedback** - Animated welcome screen, syntax-highlighted code, and progress indicators
- **File mentions** with `@` - Reference workspace files with fuzzy search autocomplete
- **Slash commands** with `/` - Quick access to `/settings`, `/history`, `/models`, and workflows
- **Keyboard shortcuts** - `Tab` to toggle Plan/Act, `Shift+Tab` for auto-approve all
- **Session summaries** - See tasks completed, files modified, and token usage on exit
- **Settings panel** - Configure providers, models, and features without leaving the CLI
Interactive mode keeps you in control. You review Cline's plan, approve or modify actions, and guide the conversation.
[Learn more about interactive mode →](/cline-cli/interactive-mode)
### Headless Mode (Non-Interactive)
Headless mode is designed for **automation, scripting, and CI/CD pipelines** where human interaction isn't possible or desired.
**When it activates:** Using the `-y`/`--yolo` flag, `--json` flag, piping input/output, or when stdin is not a TTY.
```bash
# Headless with auto-approval (YOLO mode)
cline -y "Run tests and fix any failures"
# Headless with JSON output for parsing
cline --json "List all TODO comments" | jq '.text'
# Headless via piped input
cat README.md | cline "Summarize this document"
# Chain multiple headless commands
git diff | cline -y "explain these changes" | cline -y "write a commit message"
```
Key features:
- **No visual interface** - Clean text or JSON output suitable for scripting
- **Automatic execution** - With `-y`, Cline approves all actions and runs autonomously
- **Process control** - Exits automatically when the task completes
- **Piped workflows** - Read from stdin, write to stdout, chain with other commands
- **Machine-readable output** - Use `--json` to get structured output for parsing
<Warning>
Headless mode with `-y` gives Cline full autonomy. Run on a clean git branch so you can easily revert changes if needed.
</Warning>
### Mode Detection Summary
Cline automatically detects which mode to use based on your invocation. This table shows how different command patterns trigger each mode, helping you predict behavior in scripts and interactive sessions.
| Invocation | Mode | Reason |
|------------|------|--------|
| `cline` | Interactive | No arguments, TTY connected |
| `cline "task"` | Interactive | TTY connected |
| `cline -y "task"` | Headless | YOLO flag forces headless |
| `cline --json "task"` | Headless | JSON flag forces headless |
| `cat file \| cline "task"` | Headless | stdin is piped |
| `cline "task" > output.txt` | Headless | stdout is redirected |
[Learn more about headless mode →](/cline-cli/three-core-flows)
## Supported Model Providers
Cline CLI supports all providers available in the VS Code extension:
- **Anthropic** (Claude)
- **OpenAI** (GPT-4o, GPT-4)
- **OpenAI Codex** (ChatGPT subscription)
- **OpenRouter**
- **AWS Bedrock**
- **Google Gemini**
- **X AI (Grok)**
- **Cerebras**
- **DeepSeek**
- **Ollama** (local models)
- **LM Studio** (local models)
- **OpenAI Compatible** (any compatible API)
During setup, authenticate with `cline auth` to configure your preferred provider. [See setup guide →](/cline-cli/installation#authenticate)
## What You Can Build
### Automated Code Maintenance
Keep your codebase healthy with automated fixes. Cline scans for issues and applies corrections across multiple files.
```bash
cline -y "Fix all ESLint errors in src/"
```
Finds and fixes linting violations throughout your source directory.
```bash
cline -y "Update all deprecated React lifecycle methods"
```
Migrates legacy code patterns to modern equivalents (e.g., `componentWillMount` → `useEffect`).
```bash
cline -y "Update dependencies with known vulnerabilities"
```
Identifies outdated packages with security issues and updates them to safe versions.
### CI/CD Integration
Integrate Cline into your continuous integration pipelines for automated code review and documentation.
```bash
git diff origin/main | cline -y "Review these changes for issues"
```
Pipes your PR diff to Cline for automated code review, catching bugs and style issues before merge.
```bash
git log --oneline v1.0..v1.1 | cline -y "Write release notes"
```
Generates human-readable release notes from your commit history between two tags.
```bash
cline -y "Run tests and fix failures" --timeout 600
```
Executes your test suite, analyzes failures, and attempts fixes with a 10-minute timeout.
### Development Workflows
From quick edits to complex refactors, Cline adapts to your workflow.
```bash
cline
```
Launches interactive mode for exploratory development and back-and-forth collaboration.
```bash
cline "Refactor this function to use async/await"
```
Executes a focused task directly from the command line with approval prompts at key steps.
```bash
cline "Based on @src/api.ts, add error handling to all endpoints"
```
Uses file mentions (`@`) to give Cline context about specific files in your workspace.
### Custom Shell Pipelines
Chain Cline with other CLI tools to build powerful automation workflows.
```bash
gh pr diff 123 | cline -y "Review this PR"
```
Fetches a GitHub PR diff and pipes it directly to Cline for review.
```bash
cline --json "List all TODO comments" | jq '.text'
```
Outputs structured JSON that you can process with tools like `jq` for scripting.
```bash
git diff | cline -y "explain" | cline -y "write a haiku about these changes"
```
Chains multiple Cline invocations together for creative multi-step workflows.
## Features at a Glance
| Feature | Interactive Mode | Non-Interactive Mode |
|---------|------------------|----------------------|
| Interactive chat | ✓ | - |
| File mentions (@) | ✓ | ✓ (inline) |
| Slash commands (/) | ✓ | - |
| Settings panel | ✓ | `cline config` |
| Plan/Act toggle | ✓ (Tab) | `-p` / `-a` flags |
| Auto-approve | ✓ (Shift+Tab) | `-y` flag |
| Session summary | ✓ | - |
| JSON output | - | `--json` |
| Piped input | - | ✓ |
| [MCP servers](/cline-cli/configuration#mcp-server-configuration) | ✓ | ✓ |
## MCP Server Support
Cline CLI supports [MCP (Model Context Protocol)](/mcp/mcp-overview) servers, the same extensibility system available in the VS Code extension. MCP servers give Cline access to external tools and data sources, from databases and APIs to browser automation and project management.
To use MCP servers with the CLI, add your server configuration to `~/.cline/data/settings/cline_mcp_settings.json`. The format is identical to the VS Code extension.
[Configure MCP servers for the CLI →](/cline-cli/configuration#mcp-server-configuration)
## Learn More
<Columns cols={2}>
<Card title="Installation & Setup" icon="download" href="/cline-cli/installation">
Install Cline CLI and authenticate with your preferred provider.
</Card>
<Card title="Interactive Mode" icon="terminal" href="/cline-cli/interactive-mode">
Master the interactive CLI with keyboard shortcuts and slash commands.
</Card>
<Card title="Headless Mode" icon="robot" href="/cline-cli/three-core-flows">
Run Cline autonomously in scripts, CI/CD pipelines, and automated workflows.
</Card>
<Card title="Configuration" icon="gear" href="/cline-cli/configuration">
Configure settings, rules, workflows, and environment variables.
</Card>
<Card title="CLI Samples" icon="flask" href="/cline-cli/samples/overview">
Real-world examples of headless workflows and automation patterns.
</Card>
</Columns>
@@ -7,7 +7,7 @@ Automate GitHub issue analysis with AI. Mention `@cline` in any issue comment to
<Note>
**New to Cline CLI?** This sample assumes you understand Cline CLI basics and have completed the [Installation Guide](https://docs.cline.bot/getting-started/installing-cline). If you're new to Cline CLI, we recommend starting with the [GitHub RCA sample](./github-issue-rca) first, as it's simpler and will help you understand the fundamentals before setting up GitHub Actions.
**New to Cline CLI?** This sample assumes you understand Cline CLI basics and have completed the [Installation Guide](https://docs.cline.bot/cline-cli/installation). If you're new to Cline CLI, we recommend starting with the [GitHub RCA sample](./github-issue-rca) first, as it's simpler and will help you understand the fundamentals before setting up GitHub Actions.
</Note>
## The Workflow
@@ -32,7 +32,7 @@ Let's configure your repository.
Before you begin, you'll need:
- **Cline CLI knowledge** - Completed the [Installation Guide](https://docs.cline.bot/getting-started/installing-cline) and understand basic usage
- **Cline CLI knowledge** - Completed the [Installation Guide](https://docs.cline.bot/cline-cli/installation) and understand basic usage
- **GitHub repository** - With admin access to configure Actions and secrets
- **GitHub Actions familiarity** - Basic understanding of workflows and CI/CD
- **API provider account** - OpenRouter, Anthropic, or similar with API key
@@ -95,7 +95,7 @@ jobs:
- name: Install Cline CLI
if: steps.detect.outputs.hit == 'true'
run: npm install -g @cline/cli
run: npm install -g cline
- name: Configure Cline Authentication
if: steps.detect.outputs.hit == 'true'
@@ -120,6 +120,7 @@ jobs:
env:
ISSUE_URL: ${{ steps.detect.outputs.issue_url }}
COMMENT: ${{ steps.detect.outputs.comment_body }}
CLINE_ADDRESS: ${{ env.CLINE_ADDRESS }}
run: |
set -euo pipefail
@@ -230,9 +231,10 @@ nano git-scripts/analyze-issue.sh # or use vim, code, etc.
# Analyze a GitHub issue using Cline CLI
if [ -z "$1" ]; then
echo "Usage: $0 <github-issue-url> [prompt]"
echo "Usage: $0 <github-issue-url> [prompt] [address]"
echo "Example: $0 https://github.com/owner/repo/issues/123"
echo "Example: $0 https://github.com/owner/repo/issues/123 'What is the root cause of this issue?'"
echo "Example: $0 https://github.com/owner/repo/issues/123 'What is the root cause of this issue?'"
exit 1
fi
@@ -241,8 +243,9 @@ ISSUE_URL="$1"
PROMPT="${2:-What is the root cause of this issue?}"
# Ask Cline for its analysis, showing only the summary
cline --auto-approve true --json "$PROMPT: $ISSUE_URL" | \
jq -r 'select(.type == "agent_event" and .event.type == "done") | .event.text' | \
cline -y "$PROMPT: $ISSUE_URL" --mode act -F json | \
sed -n '/^{/,$p' | \
jq -r 'select(.say == "completion_result") | .text' | \
sed 's/\\n/\n/g'
```
@@ -280,7 +283,7 @@ GitHub Actions will:
1. Detect the `@cline` mention
2. Start a Cline CLI instance
3. Download the analysis script
4. Analyze the issue using Act mode with auto-approval enabled
4. Analyze the issue using act mode with yolo (fully autonomous)
5. Post Cline's analysis as a new comment
**Note**: The workflow only triggers on issue comments, not pull request
@@ -293,7 +296,7 @@ The workflow (`cline-responder.yml`):
1. **Triggers** on issue comments (created or edited)
2. **Detects** `@cline` mentions (case-insensitive)
3. **Installs** Cline CLI globally using npm
4. **Configures** authentication using `cline auth --provider openrouter --apikey ...`
4. **Configures** authentication using `cline config set open-router-api-key=...`
6. **Downloads** the reusable `analyze-issue.sh` script from the
`github-issue-rca` sample
7. **Runs** analysis in Cline CLI
@@ -6,7 +6,7 @@ description: "Automated GitHub issue analysis using Cline CLI to identify root c
Automated GitHub issue analysis using Cline CLI. This script uses Cline's autonomous AI capabilities to fetch, analyze, and identify root causes of GitHub issues, outputting clean, parseable results that can be easily integrated into your development workflows.
<Note>
**New to Cline CLI?** This sample assumes you have already completed the [Installation Guide](https://docs.cline.bot/getting-started/installing-cline) and authenticated with `cline auth`. If you haven't set up Cline CLI yet, please start there first.
**New to Cline CLI?** This sample assumes you have already completed the [Installation Guide](https://docs.cline.bot/cline-cli/installation) and authenticated with `cline auth`. If you haven't set up Cline CLI yet, please start there first.
</Note>
<Frame>
@@ -17,7 +17,7 @@ Automated GitHub issue analysis using Cline CLI. This script uses Cline's autono
This sample assumes you have already:
- **Cline CLI** installed and authenticated ([Installation Guide](https://docs.cline.bot/getting-started/installing-cline))
- **Cline CLI** installed and authenticated ([Installation Guide](https://docs.cline.bot/cline-cli/installation))
- **At least one AI model provider** configured (e.g., OpenRouter, Anthropic, OpenAI)
- **Basic familiarity** with Cline CLI commands
@@ -80,18 +80,24 @@ curl -O https://raw.githubusercontent.com/cline/cline/main/src/samples/cli/githu
# Analyze a GitHub issue using Cline CLI
if [ -z "$1" ]; then
echo "Usage: $0 <github-issue-url> [prompt]"
echo "Usage: $0 <github-issue-url> [prompt] [address]"
echo "Example: $0 https://github.com/owner/repo/issues/123"
echo "Example: $0 https://github.com/owner/repo/issues/123 'What is the root cause of this issue?'"
echo "Example: $0 https://github.com/owner/repo/issues/123 'What is the root cause of this issue?' 127.0.0.1:46529"
exit 1
fi
# Gather the args
ISSUE_URL="$1"
PROMPT="${2:-What is the root cause of this issue?}"
if [ -n "$3" ]; then
ADDRESS="--address $3"
fi
# Ask Cline for its analysis, showing only the summary
cline --auto-approve true --json "$PROMPT: $ISSUE_URL" | \
jq -r 'select(.type == "agent_event" and .event.type == "done") | .event.text' | \
cline -y "$PROMPT: $ISSUE_URL" --mode act $ADDRESS -F json | \
sed -n '/^{/,$p' | \
jq -r 'select(.say == "completion_result") | .text' | \
sed 's/\\n/\n/g'
```
@@ -127,6 +133,23 @@ Ask specific questions about the issue:
./analyze-issue.sh https://github.com/owner/repo/issues/456 "What is the security impact?"
```
### Using Specific Cline Instance
Target a particular Cline instance by address:
```bash
./analyze-issue.sh https://github.com/owner/repo/issues/123 \
"What is the root cause of this issue?" \
127.0.0.1:46529
```
<Warning>
This is useful when:
- Running multiple Cline instances
- Using a remote Cline server
- Testing with specific configurations
</Warning>
<Note>
The script will automatically handle everything: fetching the issue, analyzing it with Cline, and displaying the results. The analysis typically takes 30-60 seconds depending on the issue complexity.
</Note>
@@ -141,9 +164,10 @@ The script validates input and provides usage instructions:
```bash
if [ -z "$1" ]; then
echo "Usage: $0 <github-issue-url> [prompt]"
echo "Usage: $0 <github-issue-url> [prompt] [address]"
echo "Example: $0 https://github.com/owner/repo/issues/123"
echo "Example: $0 https://github.com/owner/repo/issues/123 'What is the root cause?'"
echo "Example: $0 https://github.com/owner/repo/issues/123 'Analyze security impact' 127.0.0.1:46529"
exit 1
fi
```
@@ -152,6 +176,7 @@ fi
- Validates required GitHub issue URL
- Shows clear usage examples
- Supports optional custom prompt
- Supports optional Cline instance address
### Argument Parsing
@@ -161,12 +186,15 @@ The script extracts and sets up the arguments:
# Gather the args
ISSUE_URL="$1"
PROMPT="${2:-What is the root cause of this issue?}"
if [ -n "$3" ]; then
ADDRESS="--address $3"
fi
```
**Explanation:**
- `ISSUE_URL="$1"` - First argument is always the issue URL
- `PROMPT="${2:-...}"` - Second argument is optional, defaults to root cause analysis
- The SDK CLI runs the task directly, so no address flag is required.
- `ADDRESS` - Third argument is optional, only set if provided
### The Core Analysis Pipeline
@@ -174,26 +202,39 @@ This is where the magic happens:
```bash
# Ask Cline for its analysis, showing only the summary
cline --auto-approve true --json "$PROMPT: $ISSUE_URL" | \
jq -r 'select(.type == "agent_event" and .event.type == "done") | .event.text' | \
cline -y "$PROMPT: $ISSUE_URL" --mode act $ADDRESS -F json | \
sed -n '/^{/,$p' | \
jq -r 'select(.say == "completion_result") | .text' | \
sed 's/\\n/\n/g'
```
<Accordion title="Pipeline Breakdown: Understanding Each Component">
**1. `cline --auto-approve true --json "$PROMPT: $ISSUE_URL"`**
- `cline` is the Cline CLI binary
- Act mode is the default for prompt runs
- `--auto-approve true` allows tool use without interactive prompts
- `--json` emits newline-delimited JSON for parsing
**1. `cline -y "$PROMPT: $ISSUE_URL"`**
- `-y` enables yolo mode (no user interaction)
- Constructs prompt with issue URL
**2. `jq -r 'select(.type == "agent_event" and .event.type == "done") | .event.text'`**
- Filters for the final agent `done` event
- Extracts the final text field
**2. `--mode act`**
- Enables act mode for active investigation
- Allows Cline to use tools (read files, run commands, etc.)
**3. `$ADDRESS`**
- Optional address flag for specific instance
- Expands to `--address <ip:port>` if set
**4. `-F json`**
- Outputs in JSON format for parsing
**5. `sed -n '/^{/,$p'`**
- Extracts JSON from output
- Skips any non-JSON prefix lines
**6. `jq -r 'select(.say == "completion_result") | .text'`**
- Filters for completion result messages
- Extracts the text field
- `-r` outputs raw strings (no JSON quotes)
**3. `sed 's/\\n/\n/g'`**
**7. `sed 's/\\n/\n/g'`**
- Converts escaped newlines to actual newlines
- Makes output readable
@@ -335,6 +376,6 @@ This pattern can be adapted for many other automation scenarios, from pull reque
## Related Resources
- [CLI Installation Guide](https://docs.cline.bot/getting-started/installing-cline)
- [CLI Reference Documentation](https://docs.cline.bot/cli/cli-reference)
- [Headless Mode](https://docs.cline.bot/usage/cli-overview#headless-mode)
- [CLI Installation Guide](https://docs.cline.bot/cline-cli/installation)
- [CLI Reference Documentation](https://docs.cline.bot/cline-cli/cli-reference)
- [Headless Mode](https://docs.cline.bot/cline-cli/three-core-flows)
@@ -69,7 +69,7 @@ jobs:
cache: "npm"
- name: Install Cline CLI
run: npm install -g @cline/cli
run: npm install -g cline
- name: Configure Cline Authentication
# Replace 'anthropic' with your provider of choice (openai, openrouter, etc.)
@@ -110,7 +110,7 @@ jobs:
]
}
run: |
cline --auto-approve true 'You are a GitHub PR reviewer for this repository. Your goal is to give the PR author helpful feedback and give maintainers the context they need to review efficiently.
cline --yolo 'You are a GitHub PR reviewer for this repository. Your goal is to give the PR author helpful feedback and give maintainers the context they need to review efficiently.
PR: #'"${PR_NUMBER}"'
@@ -175,11 +175,11 @@ cline auth --provider anthropic --apikey "..."
```
The `auth` command configures Cline in the CI environment without interactive prompts. You can switch providers (e.g., `openai`, `openrouter`) by changing the flags.
### Autonomous Mode (`--auto-approve true`)
### Autonomous Mode (`--yolo`)
```bash
cline --auto-approve true '...'
cline --yolo '...'
```
The `--auto-approve true` flag tells Cline to run autonomously, executing approved tools without waiting for interactive confirmation. Prompt runs start in Act mode by default, so CI/CD workflows can perform the requested work immediately.
The `--yolo` flag tells Cline to run autonomously, executing commands without waiting for user approval. This is essential for CI/CD workflows.
### Command Permissions
We explicitly restrict what commands Cline can run using `CLINE_COMMAND_PERMISSIONS`. This ensures Cline can only use `gh` and `git` commands relevant to reviewing, preventing any accidental or malicious system modifications.
@@ -43,20 +43,20 @@ Use different models for different phases of work. Route simple tasks to cheap m
ISSUE_CONTENT=$(gh issue view $(gh issue list -L 1 | awk '{print $1}'))
# Phase 1: Quick summary with cheap model
SUMMARY=$(echo "$ISSUE_CONTENT" | cline --auto-approve true --config ~/.cline-haiku \
SUMMARY=$(echo "$ISSUE_CONTENT" | cline -y --config ~/.cline-haiku \
"summarize this issue in 2-3 sentences")
# Phase 2: Detailed plan with expensive model + thinking
PLAN=$(echo "$SUMMARY" | cline --auto-approve true --thinking high --config ~/.cline-opus \
PLAN=$(echo "$SUMMARY" | cline -y --thinking --config ~/.cline-opus \
"create detailed implementation plan with edge cases")
# Phase 3: Execute with mid-tier model
echo "$PLAN" | cline --auto-approve true --config ~/.cline-sonnet \
echo "$PLAN" | cline -y --config ~/.cline-sonnet \
"implement the plan from above"
```
<Note>
Each `cline` invocation needs to complete before passing output to the next phase. Use shell variables to store intermediate results rather than piping `cline` commands directly.
Each cline invocation needs to complete before passing output to the next phase. Use shell variables to store intermediate results rather than piping cline commands directly.
</Note>
**Cost impact:**
@@ -102,19 +102,19 @@ Get multiple AI perspectives on the same change, then synthesize their feedback.
DIFF=$(git show)
# Review 1: Gemini's perspective
echo "$DIFF" | cline --auto-approve true --config ~/.cline-gemini \
echo "$DIFF" | cline -y --config ~/.cline-gemini \
"review this diff and write your analysis to gemini-review.md"
# Review 2: Codex's perspective
echo "$DIFF" | cline --auto-approve true --config ~/.cline-codex \
echo "$DIFF" | cline -y --config ~/.cline-codex \
"review this diff and write your analysis to codex-review.md"
# Review 3: Opus's perspective
echo "$DIFF" | cline --auto-approve true --config ~/.cline-opus \
echo "$DIFF" | cline -y --config ~/.cline-opus \
"review this diff and write your analysis to opus-review.md"
# Synthesize all reviews into a consensus
cat gemini-review.md codex-review.md opus-review.md | cline --auto-approve true \
cat gemini-review.md codex-review.md opus-review.md | cline -y \
"summarize these 3 reviews and identify: 1) issues all models agree on, 2) issues only one model caught, 3) your final recommendation"
```
@@ -130,19 +130,19 @@ Run reviews in parallel for faster feedback:
```bash
# Run all reviews simultaneously
git show | cline --auto-approve true --config ~/.cline-gemini "review and save to gemini-review.md" &
git show | cline --auto-approve true --config ~/.cline-codex "review and save to codex-review.md" &
git show | cline --auto-approve true --config ~/.cline-opus "review and save to opus-review.md" &
git show | cline -y --config ~/.cline-gemini "review and save to gemini-review.md" &
git show | cline -y --config ~/.cline-codex "review and save to codex-review.md" &
git show | cline -y --config ~/.cline-opus "review and save to opus-review.md" &
# Wait for all to complete
wait
# Synthesize
cat *-review.md | cline --auto-approve true "create consensus review"
cat *-review.md | cline -y "create consensus review"
```
<Note>
Parallel execution requires managing multiple Cline instances. See [Multi-instance workflows](/usage/cli-overview#automation-patterns) for details.
Parallel execution requires managing multiple Cline instances. See [Multi-instance workflows](/cline-cli/three-core-flows#3-multi-instance-run-parallel-agents) for details.
</Note>
## Extended Thinking for Complex Tasks
@@ -151,14 +151,14 @@ Use the `--thinking` flag when Cline needs to analyze multiple approaches:
```bash
# Without thinking: Fast but may miss nuances
cline --auto-approve true "refactor this codebase"
cline -y "refactor this codebase"
# With thinking: Slower but more thorough
cline --auto-approve true --thinking high \
cline -y --thinking \
"refactor this codebase - consider: performance, maintainability, backward compatibility"
```
The `--thinking <level>` flag sets reasoning effort. Use `--thinking high` or `--thinking xhigh` when you want the model to spend more effort on complex tradeoffs. Best for:
The `--thinking` flag allocates 1024 tokens for internal reasoning before Cline responds. Best for:
- Architectural decisions
- Security analysis
- Complex refactoring
@@ -178,12 +178,12 @@ The `--thinking <level>` flag sets reasoning effort. Use `--thinking high` or `-
```bash
# Haiku: Quick summary and issue identification
gh pr view $PR | cline --auto-approve true --config ~/.cline-haiku \
gh pr view $PR | cline -y --config ~/.cline-haiku \
"list all issues to fix, output as JSON"
# Opus with thinking: Deep analysis only if issues found
if [ -s issues.json ]; then
cline --auto-approve true --thinking high --config ~/.cline-opus \
cline -y --thinking --config ~/.cline-opus \
"analyze these issues and recommend fixes"
fi
```
@@ -192,31 +192,31 @@ fi
```bash
# Different models have different security perspectives
git diff main | cline --auto-approve true --config ~/.cline-gemini "security review" > gemini-sec.md &
git diff main | cline --auto-approve true --config ~/.cline-opus "security review" > opus-sec.md &
git diff main | cline --auto-approve true --config ~/.cline-codex "security review" > codex-sec.md &
git diff main | cline -y --config ~/.cline-gemini "security review" > gemini-sec.md &
git diff main | cline -y --config ~/.cline-opus "security review" > opus-sec.md &
git diff main | cline -y --config ~/.cline-codex "security review" > codex-sec.md &
wait
# High-priority: Issues all 3 models found
cat *-sec.md | cline --auto-approve true "find security issues all 3 reviews mentioned"
cat *-sec.md | cline -y "find security issues all 3 reviews mentioned"
```
## Related Documentation
<Columns cols={2}>
<Card title="CLI Reference" icon="terminal" href="/cli/cli-reference">
<Card title="CLI Reference" icon="terminal" href="/cline-cli/cli-reference">
Complete documentation for --config and --thinking flags
</Card>
<Card title="Headless Mode" icon="robot" href="/usage/cli-overview#headless-mode">
<Card title="Headless Mode" icon="robot" href="/cline-cli/three-core-flows">
Run Cline autonomously in scripts, CI/CD pipelines, and automated workflows.
</Card>
<Card title="Cline provider" icon="brain" href="/getting-started/cline-provider">
Fastest built-in model access setup and account workflow
<Card title="Model Selection Guide" icon="brain" href="/core-features/model-selection-guide">
Compare models and choose the right one for your needs
</Card>
<Card title="CI/CD Integration" icon="github" href="/cli/samples/github-integration">
<Card title="CI/CD Integration" icon="github" href="/cline-cli/samples/github-integration">
Automate GitHub workflows with Cline CLI
</Card>
</Columns>
+56
View File
@@ -0,0 +1,56 @@
---
title: "Samples Overview"
description: Example implementations demonstrating Cline CLI capabilities
---
This section provides sample implementations that demonstrate various Cline CLI features and capabilities. Each sample includes complete code, detailed explanations, and real-world usage examples.
## Available Samples
<CardGroup cols={1}>
<Card
title="Model Orchestration"
icon="layer-group"
href="/cline-cli/samples/model-orchestration"
>
Use multiple AI models strategically with --config and --thinking flags. Optimize costs by routing simple tasks to cheap models and complex reasoning to premium models. Includes patterns for CI/CD code review, task phase optimization, and multi-model consensus.
</Card>
<Card
title="Worktree Workflows"
icon="code-branch"
href="/cline-cli/samples/worktree-workflows"
>
Use Git worktrees with the --cwd flag to run parallel tasks, test different approaches, and pipe context between isolated environments. Includes patterns for parallel execution, cross-worktree piping, and combining with model orchestration.
</Card>
<Card
title="GitHub Root Cause Analysis"
icon="magnifying-glass-chart"
href="/cline-cli/samples/github-issue-rca"
>
A command-line script that uses Cline's autonomous AI capabilities to fetch, analyze, and identify root causes of GitHub issues. Features JSON output parsing and non-interactive execution.
</Card>
<Card
title="GitHub Integration (Actions)"
icon="github"
href="/cline-cli/samples/github-integration"
>
Automatically respond to GitHub issues by mentioning @cline in comments. Uses Cline CLI in GitHub Actions to create an AI-powered issue assistant that analyzes and responds autonomously.
</Card>
<Card
title="GitHub PR Review (Actions)"
icon="code-pull-request"
href="/cline-cli/samples/github-pr-review"
>
Automatically review Pull Requests with AI. Configures Cline in GitHub Actions to analyze diffs, check for security issues, and post detailed reviews with inline code suggestions.
</Card>
</CardGroup>
## Additional Resources
- [CLI Installation Guide](/cline-cli/installation)
- [CLI Reference Documentation](/cline-cli/cli-reference)
- [Headless Mode](/cline-cli/three-core-flows)
@@ -0,0 +1,273 @@
---
title: "Worktree Workflows"
description: "Use Git worktrees with Cline CLI to run parallel tasks, test different approaches, and pipe context between isolated environments"
---
Git worktrees let you have multiple branches checked out simultaneously in different folders. Combined with Cline CLI's `--cwd` flag, this enables powerful parallel development workflows and isolated experimentation.
<Tip>
New to Git worktrees? See our comprehensive [Worktrees guide](/features/worktrees) for the full concept explanation, VS Code integration, and best practices.
</Tip>
## Quick Worktree Setup
If you haven't used Git worktrees before, here's the essentials:
```bash
# Create a new worktree in ~/worktree-a on branch feature-a
git worktree add ~/worktree-a -b feature-a
# Create another worktree for a different feature
git worktree add ~/worktree-b -b feature-b
# List all worktrees
git worktree list
# Remove a worktree when done
git worktree remove ~/worktree-a
```
Each worktree is a separate folder with its own branch checked out. They all share the same Git history and `.git` directory, but have independent working directories.
## The `--cwd` Flag
The `-c, --cwd <path>` flag tells Cline to run in a specific directory without changing your current location:
```bash
# Run Cline in a different directory
cline --cwd ~/worktree-a -y "refactor the authentication code"
# Short form
cline -c ~/worktree-b -y "add unit tests"
```
This is the key to worktree workflows—you can run multiple Cline instances in different worktrees simultaneously from a single terminal.
## Pattern 1: Parallel Task Execution
Run different tasks in parallel across multiple worktrees. Each task works on a separate branch in complete isolation.
### Example: Parallel Feature Development
```bash
# Terminal 1: Update docs in worktree-a
cline --cwd ~/worktree-a -y "read the last 10 changes using git show and update our README with them" &
# Terminal 2: TypeScript migration in worktree-b
cline --cwd ~/worktree-b -y "update the index.js to use typescript" &
# Terminal 3: Refactoring in worktree-c
cline --cwd ~/worktree-c -y "refactor the cli/ folder to be more modular" &
# Wait for all to complete
wait
```
The `&` runs each command in the background, allowing all three to execute simultaneously.
### When to Use Parallel Execution
**Perfect for:**
- Multiple independent features
- Bulk refactoring across different modules
- Running tests in one worktree while developing in another
- Trying multiple approaches to the same problem
**Not ideal for:**
- Tasks that modify the same files (merge conflicts likely)
- Tasks that depend on each other's results
- When you need to monitor progress closely
## Pattern 2: Cross-Worktree Context Piping
Pipe output from one worktree as input to another. Use when a task in one worktree needs context from attempts in another worktree.
### Example: Learning from Failures
```bash
# Try approach A in worktree-a, capture only the failure summary
cline --cwd ~/worktree-a -y \
"edit the index.ts to be better and then npm run. if it fails, output ONLY the failure summary. nothing else but the failure summary" \
| cline --cwd ~/worktree-b -y \
"i've tried to edit the index.ts in a different worktree but it failed. use a different approach for this work tree"
```
**How it works:**
1. First Cline instance runs in `worktree-a`, attempts a change, tests it
2. If it fails, outputs just the failure summary
3. That summary is piped to a second Cline instance in `worktree-b`
4. Second instance sees the failure and tries a different approach
### When to Use Context Piping
**Perfect for:**
- A/B testing different solutions
- Learning from failed attempts
- Iterative refinement (try → analyze → try differently)
- Comparing outputs across approaches
**Not ideal for:**
- Simple tasks that don't need cross-context
- When both worktrees would succeed independently
- Real-time collaboration (use parallel execution instead)
## Combining with Other CLI Features
### Different Models Per Worktree
Use `--config` to run different models in different worktrees:
```bash
# Cheap model for simple docs update
cline --cwd ~/worktree-docs --config ~/.cline-haiku -y \
"update README with latest changes"
# Expensive model for complex refactoring
cline --cwd ~/worktree-refactor --config ~/.cline-opus --thinking -y \
"refactor authentication system for better security"
```
This optimizes costs while maintaining quality where it matters.
### Task Isolation
Keep long-running worktree sessions isolated by running each task against a different worktree path:
```bash
# Run tasks in dedicated worktrees
cline --cwd ~/worktree-a -y "long-running task"
cline --cwd ~/worktree-b -y "another task"
```
Each worktree has its own Git branch and working directory, so task history and changes stay separated without needing instance management.
### With YOLO Mode
The `-y` (YOLO) flag is essential for worktree workflows:
```bash
# Without -y: Opens interactive chat (blocks other tasks)
cline --cwd ~/worktree-a "refactor code"
# With -y: Runs autonomously (doesn't block)
cline --cwd ~/worktree-a -y "refactor code" &
```
For parallel execution, always use `-y` to avoid blocking on user approval.
## Real-World Workflow Example
Here's a complete workflow showing how these patterns work together:
```bash
# Setup: Create three worktrees
git worktree add ~/cline-worktrees/feature-auth -b feature/authentication
git worktree add ~/cline-worktrees/feature-api -b feature/api-endpoints
git worktree add ~/cline-worktrees/fix-tests -b fix/failing-tests
# Pattern 1: Run parallel independent tasks
cline -c ~/cline-worktrees/feature-auth -y --config ~/.cline-sonnet \
"implement JWT authentication" &
cline -c ~/cline-worktrees/feature-api -y --config ~/.cline-sonnet \
"create REST API endpoints for user management" &
cline -c ~/cline-worktrees/fix-tests -y --config ~/.cline-haiku \
"fix all failing unit tests" &
wait
echo "All parallel tasks complete!"
# Pattern 2: Use piping for iterative refinement
cline -c ~/cline-worktrees/feature-auth -y \
"test the authentication with curl. output only errors if any" \
| cline -c ~/cline-worktrees/feature-auth -y \
"fix the authentication issues described in the input"
# Merge successful changes back
cd ~/cline-worktrees/feature-auth
git checkout main
git merge feature/authentication
# Cleanup
git worktree remove ~/cline-worktrees/feature-auth
```
## Best Practices
<AccordionGroup>
<Accordion title="Worktree Organization">
- **Use a dedicated folder**: Create `~/cline-worktrees/` for all worktrees
- **Meaningful branch names**: Use `feature/`, `fix/`, `refactor/` prefixes
- **Clean up regularly**: Remove worktrees after merging branches
</Accordion>
<Accordion title="Task Isolation">
- **Independent features only**: Don't parallelize tasks that touch the same files
- **Test in isolation**: Each worktree should have its own test run
- **Separate configs**: Use `.worktreeinclude` to copy `node_modules` and build artifacts
</Accordion>
<Accordion title="Resource Management">
- **Monitor disk space**: Each worktree is a full checkout
- **Limit parallel tasks**: Running too many simultaneously can slow your system
- **Use background jobs wisely**: Track with `jobs` command, kill with `kill %1`, etc.
</Accordion>
<Accordion title="Error Handling">
- **Check exit codes**: Use `|| echo "Task failed"` to catch errors
- **Log outputs**: Redirect to files for debugging: `> worktree-a.log 2>&1`
- **Graceful cleanup**: Always remove worktrees after tasks complete
</Accordion>
</AccordionGroup>
## Troubleshooting
<AccordionGroup>
<Accordion title="&quot;Branch already checked out&quot; error">
Git doesn't allow the same branch in multiple worktrees. Solutions:
- Use different branch names for each worktree
- Remove the existing worktree first: `git worktree remove <path>`
</Accordion>
<Accordion title="Tasks not running in parallel">
Make sure you're using:
- `&` at the end of each command to background it
- `-y` flag so Cline doesn't wait for approval
- Different worktrees (not the same path)
</Accordion>
<Accordion title="Pipe not working as expected">
Verify:
- First command outputs to stdout (not stderr)
- Second command reads from stdin (use `--` separator if needed)
- Both commands use correct `--cwd` paths
</Accordion>
<Accordion title="Changes not appearing in worktree">
Check:
- You're in the right worktree: `git worktree list`
- Files aren't gitignored
- You committed/staged changes if needed
</Accordion>
</AccordionGroup>
## Related Documentation
<Columns cols={2}>
<Card title="Worktrees Overview" icon="code-branch" href="/features/worktrees">
Complete guide to Git worktrees, VS Code integration, and .worktreeinclude
</Card>
<Card title="Model Orchestration" icon="layer-group" href="/cline-cli/samples/model-orchestration">
Use different models strategically with --config and --thinking flags
</Card>
<Card title="CLI Reference" icon="terminal" href="/cline-cli/cli-reference">
Complete documentation for --cwd and all other CLI flags
</Card>
<Card title="Headless Mode" icon="robot" href="/cline-cli/three-core-flows">
Run Cline autonomously in scripts, CI/CD pipelines, and automated workflows.
</Card>
</Columns>
+244
View File
@@ -0,0 +1,244 @@
---
title: "Headless Mode"
description: "Run Cline autonomously in scripts, CI/CD pipelines, and automated workflows"
---
Headless mode runs Cline without an interactive interface — perfect for automation, scripting, and CI/CD pipelines where human interaction isn't possible or desired. Cline executes tasks, produces clean text or JSON output, and exits when complete.
For collaborative, conversational development, see [Interactive Mode](/cline-cli/interactive-mode) instead.
<Note>
**Migrating from an older CLI version?** Instance commands (`cline instance new/list/kill`) have been removed in Cline CLI 2.0. The new architecture is simpler — just use `cline -y "task"` for headless execution.
</Note>
## When Headless Mode Activates
Cline automatically enters headless mode when any of these conditions are met:
| Invocation | Reason |
|------------|--------|
| `cline -y "task"` | `-y`/`--yolo` flag forces headless |
| `cline --json "task"` | `--json` flag forces headless |
| `cat file \| cline "task"` | stdin is piped |
| `cline "task" > output.txt` | stdout is redirected |
If none of these apply (e.g., running `cline` or `cline "task"` in a terminal), Cline launches in [interactive mode](/cline-cli/interactive-mode).
## YOLO Mode (Fully Autonomous)
The `-y` or `--yolo` flag enables fully autonomous operation — Cline approves all actions and runs without prompts:
```bash
cline -y "Run the test suite and fix any failures"
```
In YOLO mode:
- All actions are auto-approved
- Output is plain text (non-interactive)
- Process exits automatically when complete
- Perfect for CI/CD and scripts
<Warning>
YOLO mode gives Cline full autonomy. Run on a clean git branch so you can easily revert changes if needed.
</Warning>
### Mode Selection
Control whether Cline plans first or acts immediately:
```bash
# Start in Plan mode (analyze before acting)
cline -y -p "Design a REST API for user management"
# Start in Act mode (default)
cline -y -a "Fix the typo in README.md"
```
## Piping Context
Pipe file contents or command output into Cline to provide context:
```bash
# Explain a file
cat README.md | cline "Summarize this document"
# Review git changes
git diff | cline "Review these changes and suggest improvements"
# Analyze command output
npm test 2>&1 | cline "Analyze these test failures and fix them"
# Pipe a GitHub PR diff
gh pr diff 123 | cline -y "Review this PR"
```
When stdin is piped, Cline automatically enters headless mode — the piped content becomes part of the task context.
## Chaining Commands
Pipe Cline's output into another Cline instance for multi-step workflows:
```bash
# Explain changes, then write a commit message
git diff | cline -y "explain these changes" | cline -y "write a commit message for this"
# Generate code, then write tests
cline -y "create a fibonacci function" | cline -y "write unit tests for this code"
# Fun: Generate a poem about your code
git diff | cline -y "explain" | cline -y "write a haiku about this"
```
## JSON Output
Use `--json` for machine-readable output that's easy to parse in scripts:
```bash
cline --json "List all TODO comments in the codebase" | jq '.text'
```
JSON output follows the same format as task files in `~/.cline/data/tasks/<id>/ui_messages.json`.
**JSON Message Schema:**
| Field | Type | Description |
|-------|------|-------------|
| `type` | `"ask"` or `"say"` | Message category |
| `text` | `string` | Message content |
| `ts` | `number` | Unix timestamp (ms) |
| `reasoning` | `string` | (Optional) Model reasoning |
| `partial` | `boolean` | (Optional) Streaming flag |
## Including Images
Attach images to your headless task:
```bash
cline -y -i screenshot.png "Fix the layout issue shown in this screenshot"
# Or reference inline
cline -y "Fix the UI shown in @./design-mockup.png"
```
## Timeout Control
Set a maximum execution time to prevent runaway tasks:
```bash
cline -y --timeout 600 "Run full test suite"
```
## Environment Variables
Control Cline behavior via environment variables — useful for CI/CD where you can't use interactive configuration.
**CLINE_DIR** — Custom configuration directory:
```bash
export CLINE_DIR=/path/to/config
cline -y "your task"
```
**CLINE_COMMAND_PERMISSIONS** — Restrict allowed commands:
```bash
export CLINE_COMMAND_PERMISSIONS='{"allow": ["npm *", "git *"], "deny": ["rm -rf *"]}'
cline -y "your task"
```
See [Configuration](/cline-cli/configuration#environment-variables) for full documentation.
## CI/CD Integration
### GitHub Actions Example
Automate PR reviews with Cline:
```yaml
name: AI Code Review
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: '22'
- name: Install Cline
run: npm install -g cline
- name: Configure Cline
run: cline auth -p anthropic -k ${{ secrets.ANTHROPIC_API_KEY }}
- name: Review PR
run: |
git diff origin/main...HEAD | cline -y "Review this PR for:
- Potential bugs
- Security issues
- Performance concerns
- Code style violations
Provide a summary of findings."
```
### Shell Script Example
Create a reusable code review script:
```bash
#!/bin/bash
# review.sh - AI-powered code review
set -e
# Get the diff
DIFF=$(git diff HEAD~1)
if [ -z "$DIFF" ]; then
echo "No changes to review"
exit 0
fi
# Run Cline review
echo "$DIFF" | cline -y --json "Review this code diff for issues" | jq -r '.text'
```
## Common Use Cases
| Use Case | Example |
|----------|---------|
| Code review | `git diff \| cline -y "Review these changes"` |
| Fix test failures | `cline -y "Run tests and fix any failures"` |
| Generate release notes | `git log --oneline v1.0..v1.1 \| cline -y "Write release notes"` |
| Fix lint errors | `cline -y "Fix all ESLint errors in src/"` |
| Update dependencies | `cline -y "Update dependencies with known vulnerabilities"` |
| Migrate code patterns | `cline -y "Update all deprecated React lifecycle methods"` |
| PR automation | `gh pr diff 123 \| cline -y "Review this PR"` |
| Batch processing | `cline -y --json "List all TODO comments" \| jq '.text'` |
## Next Steps
<Columns cols={2}>
<Card title="Interactive Mode" icon="terminal" href="/cline-cli/interactive-mode">
For hands-on development with keyboard shortcuts, slash commands, and file mentions.
</Card>
<Card title="CLI Reference" icon="book" href="/cline-cli/cli-reference">
Complete command documentation with all flags and options.
</Card>
<Card title="Configuration" icon="gear" href="/cline-cli/configuration">
Environment variables, rules, and advanced settings.
</Card>
<Card title="CLI Samples" icon="flask" href="/cline-cli/samples/overview">
Real-world examples of headless workflows and automation patterns.
</Card>
</Columns>
-68
View File
@@ -1,68 +0,0 @@
---
title: "Cline Overview"
sidebarTitle: "Cline Overview"
description: "Your AI-powered coding agent for complex work. Read files, write code, run commands, all with your approval."
---
Welcome to the Cline documentation. Whether you're just getting started or looking to unlock advanced capabilities, you'll find everything you need here.
## What is Cline?
Cline is an AI coding agent that lives in your editor and your terminal. It can read and write files, run terminal commands, use a browser, and help you build features through natural conversation. Every action requires your explicit approval. You're always in control.
### Agent Core (SDK)
The SDK is Cline's agent core—use it to build your own applications, automations, and integrations. See SDK section for detailed functionality and architectural design of the Cline Agent.
<CardGroup cols={1}>
<Card title="SDK" icon="cube" href="https://docs.cline.bot/sdk/overview">
Build AI agents and integrations powered by the same core engine behind the CLI, Kanban, VS Code extension, and JetBrains plugin.
`npm install @cline/sdk`
</Card>
</CardGroup>
### Applications
These are end-user applications built on top of Cline's agent core:
<CardGroup cols={2}>
<Card title="CLI" icon="terminal" href="/usage/cli-overview">
Run Cline in your terminal with interactive chat or fully headless automation for CI/CD and scripting.
`npm i -g cline`
</Card>
<Card title="Kanban" icon="table-columns" href="https://github.com/cline/kanban">
Run many agents in parallel from a web-based task board with per-card worktrees, auto-commit, and dependency chains.
`npx kanban`
</Card>
<Card title="VS Code Extension" icon="code" href="https://marketplace.visualstudio.com/items?itemName=saoudrizwan.claude-dev">
AI coding assistant in your editor. Create files, run commands, browse the web, and use tools with human-in-the-loop approval.
</Card>
<Card title="JetBrains Plugin" icon="brain" href="https://plugins.jetbrains.com/plugin/27189-cline">
The same Cline experience in IntelliJ IDEA, PyCharm, WebStorm, GoLand, and the rest of the JetBrains family.
</Card>
</CardGroup>
## Other IDE Supports
Cline works across all major editors: **VS Code**, **Cursor**, **Windsurf**, **JetBrains** (IntelliJ, PyCharm, WebStorm), **Antigravity**, and **Zed**, **Neovim** via ACP mode.
## Enterprise Solutions
<CardGroup cols={2}>
<Card title="Security & Governance" icon="shield-halved" href="/enterprise-solutions/overview">
SSO, role-based access control, model and tool controls per team, and remote configuration.
</Card>
<Card title="Observability" icon="chart-line" href="/enterprise-solutions/monitoring/overview">
OpenTelemetry, Datadog, Grafana, Splunk integrations with real-time analytics.
</Card>
<Card title="Team Management" icon="users-gear" href="/enterprise-solutions/team-management/managing-members">
Manage members, roles, and permissions across your organization.
</Card>
<Card title="API Reference" icon="code" href="/enterprise-solutions/api-reference">
Programmatic access to Cline's enterprise features.
</Card>
</CardGroup>
+316
View File
@@ -0,0 +1,316 @@
---
title: "Documentation Templates"
sidebarTitle: "Templates"
description: "Templates for different types of Cline documentation"
---
Use these templates as starting points for new documentation. Each template is designed for a specific purpose. Choose the one that best fits what you're documenting.
## Choosing a Template
| If you're documenting... | Use this template |
|--------------------------|-------------------|
| What a feature does and how to use it | Feature Doc |
| How to accomplish a specific task | How-To Guide |
| Technical specifications or API details | Reference Doc |
| A complete project walkthrough | Tutorial |
## Feature Doc
Use this template when explaining a Cline feature. Focus on what it does, how to use it, and real examples.
````text
---
title: "Feature Name"
sidebarTitle: "Feature Name"
---
[One sentence explaining what this feature does.]
<Frame>
<img src="..." alt="Feature in action" />
</Frame>
[1-2 paragraphs explaining the feature in plain terms. What problem does it
solve? Why would someone use it?]
## How It Works
[Explain the mechanics without jargon. What happens when you use this feature?]
## Using [Feature Name]
[Show how to access and use it. Include the exact UI path.]
### [Option or Variation 1]
[Details with examples]
### [Option or Variation 2]
[Details with examples]
## Inspiration
[Share how you personally use this feature. Use "I" voice. Give 2-3 real
examples that spark imagination about what's possible.]
<Note>
[Important caveat, limitation, or requirement]
</Note>
````
### Example: Checkpoints Feature
Here's how the [Checkpoints](/core-workflows/checkpoints) doc follows this pattern:
- Opens with one clear sentence about what checkpoints do
- Shows a screenshot of the feature in action
- Explains how checkpoints work under the hood
- Shows exact steps to create and restore checkpoints
- Includes real examples of when checkpoints save the day
## How-To Guide
Use this template when showing how to accomplish a specific task. Focus on clear steps and troubleshooting.
````text
---
title: "How to [Accomplish Task]"
sidebarTitle: "[Short Title]"
description: "[One sentence describing what the reader will learn]"
---
[Brief intro explaining what problem this guide solves and what you'll end up
with after following it.]
## Prerequisites
[What the reader needs before starting. Keep it short. Link to other docs
rather than explaining setup here.]
- Cline installed and configured
- [Other requirement]
## Steps
<Steps>
<Step title="[First Action]">
[Clear instructions. Show exactly what to click or type.]
```bash
example command if needed
```
</Step>
<Step title="[Second Action]">
[Next step. Include screenshots for complex UI interactions.]
<Frame>
<img src="..." alt="What you should see" />
</Frame>
</Step>
<Step title="[Final Action]">
[Complete the task. Show the expected result.]
</Step>
</Steps>
## Troubleshooting
Common issues and how to fix them:
- **Problem description**: Solution in one or two sentences.
- **Another problem**: Another solution.
## Next Steps
<Card title="Related Feature" icon="arrow-right" href="/path/to/related">
Continue learning with this related guide.
</Card>
````
### Example: Your First Project
The [Your First Project](/getting-started/your-first-project) guide follows this pattern:
- Clear goal stated upfront
- Prerequisites listed briefly
- Step-by-step instructions with the Steps component
- Troubleshooting section for common issues
## Reference Doc
Use this template for technical specifications, API documentation, or detailed configuration options.
````text
---
title: "[Component/API] Reference"
sidebarTitle: "[Short Title]"
description: "[What this reference covers]"
---
[Brief description of what this reference documents and when you'd need it.]
## Overview
[High-level explanation. What is this component? What role does it play?]
## [Category 1]
### [Item Name]
[What it does in one sentence.]
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `propertyName` | `string` | `"default"` | What this property controls |
| `anotherProp` | `boolean` | `false` | What this does |
**Example:**
```typescript
// Show practical usage
const example = {
propertyName: "custom value",
anotherProp: true
}
```
### [Another Item]
[Continue for each item in this category.]
## [Category 2]
[Continue with other categories as needed.]
## Examples
[Show 2-3 complete, practical examples that combine multiple concepts.]
### [Example 1 Title]
```typescript
// Complete working example
```
### [Example 2 Title]
```typescript
// Another complete example
```
## Related
- [Related Doc 1](/path/to/doc) - Brief description
- [Related Doc 2](/path/to/doc) - Brief description
````
### Example: Cline Tools Guide
The [Cline Tools Guide](/tools-reference/all-cline-tools) follows this pattern:
- Overview of the tool system
- Each tool documented with parameters and examples
- Practical examples showing tools in context
## Tutorial
Use this template for comprehensive project walkthroughs where users build something from start to finish.
````text
---
title: "[Build/Create X] Tutorial"
sidebarTitle: "[Short Title]"
description: "[What the reader will build]"
---
In this tutorial, you'll build [specific outcome]. By the end, you'll have
[tangible result you can see/use].
<Frame>
<img src="..." alt="Preview of what you'll build" />
</Frame>
## What You'll Learn
- [Skill or concept 1]
- [Skill or concept 2]
- [Skill or concept 3]
## Prerequisites
[Required setup. Link to installation guides rather than repeating them.]
- [Prerequisite 1]
- [Prerequisite 2]
## Part 1: [First Major Section]
[Introduction to this section. What are we doing and why?]
### [Subsection]
[Detailed walkthrough with code blocks and explanations.]
```typescript
// Code that the reader should write or understand
```
[Explain what the code does and why.]
## Part 2: [Second Major Section]
[Continue building on Part 1.]
### [Subsection]
[More detailed walkthrough.]
## Part 3: [Final Section]
[Complete the project.]
## Summary
You built [what they built]. Along the way, you learned:
- [Key takeaway 1]
- [Key takeaway 2]
- [Key takeaway 3]
## Next Steps
<CardGroup cols={2}>
<Card title="Go Deeper" icon="book" href="/path/to/advanced">
Learn more advanced techniques.
</Card>
<Card title="Related Tutorial" icon="code" href="/path/to/related">
Build something else with similar concepts.
</Card>
</CardGroup>
````
### Example Structure
A good tutorial:
- Shows the end result upfront so readers know what they're building
- Breaks the work into logical parts
- Explains the "why" alongside the "how"
- Ends with clear next steps
## Quick Tips
When using these templates:
1. **Delete sections you don't need.** Templates are starting points, not rigid structures.
2. **Add sections that make sense.** If your doc needs something not in the template, add it.
3. **Keep the reader moving forward.** Every section should lead naturally to the next.
4. **Test your own instructions.** Follow your guide from scratch to catch missing steps.
<Tip>
Use the `/write-docs` workflow to generate documentation from these templates automatically.
Cline helps you fill in each section based on your project.
</Tip>
+200
View File
@@ -0,0 +1,200 @@
---
title: "Documentation Guide"
sidebarTitle: "Documentation Guide"
description: "How to write and contribute to Cline documentation"
---
Cline's documentation lives in the `docs/` directory and uses [Mintlify](https://mintlify.com) for rendering. This guide covers how to write docs that match Cline's established style.
## Using the Documentation Workflow
The fastest way to create documentation is using the `/write-docs` workflow. Type `/write-docs` in Cline and describe what you want to document. Cline guides you through a 4-step process:
1. **Research**: Examine existing docs structure and patterns
2. **Scope**: Clarify audience, doc type, and key use cases
3. **Outline**: Select a template and create structure
4. **Write**: Generate documentation following style guidelines
The workflow file lives at `.clinerules/workflows/write-docs.md` and contains templates, style rules, and examples.
## Documentation Principles
### Write for Developers
Your audience is developers who value their time. Get to the point. Every sentence should either help them understand something or help them do something.
```markdown
# Good
Switch to bash in Cline Settings → Terminal → Default Terminal Profile.
# Bad
Users who are experiencing issues may find it helpful to navigate to the
Cline settings menu where they can locate the terminal configuration
options and subsequently modify the default terminal profile setting.
```
### Show Real Examples
Abstract descriptions don't help anyone. Show actual code, real file paths, and concrete implementations.
```markdown
# Good
I use `/deep-planning` whenever I'm building features that touch multiple
parts of the codebase. For example, when adding authentication, Cline
mapped every endpoint and created a migration plan that avoided breaking changes.
# Bad
The deep planning feature can be utilized for various complex tasks
that may require careful consideration and planning.
```
### Use Active Voice
Cline does things. Files don't get created by Cline, Cline creates files.
```markdown
# Good
Cline reads your project files and builds context automatically.
# Bad
Project files are read and context is built automatically.
```
### Use Neutral Pronouns for Cline
Refer to Cline as "it" not "he". Cline is software, not a person.
```markdown
# Good
When Cline encounters an error, it suggests fixes.
# Bad
When Cline encounters an error, he suggests fixes.
```
## File Format
All documentation uses MDX format with YAML frontmatter:
```yaml
---
title: "Full Page Title"
sidebarTitle: "Shorter Nav Title" # optional
description: "One sentence for SEO" # optional but recommended
---
```
### Adding New Pages
After creating a new `.mdx` file, add it to `docs/docs.json` in the appropriate navigation group:
```json
{
"group": "Features",
"pages": [
"features/existing-page",
"features/your-new-page"
]
}
```
## Mintlify Components
Use these components appropriately throughout your docs.
### Frame
Wrap all images and videos:
```jsx
<Frame>
<img
src="https://storage.googleapis.com/cline_public_images/docs/assets/filename.png"
alt="Descriptive alt text"
/>
</Frame>
```
### Callouts
Use sparingly and purposefully:
```jsx
<Tip>Helpful suggestions that improve the experience.</Tip>
<Note>Important information the reader needs to know.</Note>
<Warning>Something that could cause problems if ignored.</Warning>
```
### Steps
For sequential procedures:
```jsx
<Steps>
<Step title="Install the Extension">
Search for "Cline" in the VS Code marketplace.
</Step>
<Step title="Configure Your Model">
Open settings and add your API key.
</Step>
</Steps>
```
### Cards
For navigation and feature overviews:
```jsx
<CardGroup cols={2}>
<Card title="Getting Started" icon="rocket" href="/getting-started/installing-cline">
Install Cline and set up your first project.
</Card>
<Card title="Features" icon="wand-magic-sparkles" href="/core-workflows/plan-and-act">
Explore what Cline can do.
</Card>
</CardGroup>
```
## Style Rules
Quick reference for consistent documentation:
| Do | Don't |
|---|---|
| Use "use" | Use "utilize" |
| Keep sentences under 25 words | Write run-on sentences |
| Use bullet points for lists | Write walls of text |
| Show where things are in the UI | Assume users can find features |
| Cross-link related docs | Leave readers stranded |
| Use code blocks with language tags | Use inline code for long snippets |
### Avoid These Patterns
- Em dashes and emojis
- Starting with "This document explains..."
- The **Bold Text**: description pattern
- Explaining obvious things
- Passive voice
## Previewing Changes
Run the docs locally to preview your changes:
```bash
cd docs
npm install # first time only
npm run dev
```
Open `http://localhost:3000` to see your changes in real time.
## Related Resources
<CardGroup cols={2}>
<Card title="Documentation Templates" icon="file-lines" href="/contributing/doc-templates">
Templates for different documentation types.
</Card>
<Card title="Workflows" icon="diagram-project" href="/customization/workflows">
Learn about Cline's workflow system.
</Card>
</CardGroup>
@@ -0,0 +1,220 @@
---
title: "Model Selection Guide"
description: "Choose the right AI model for your workflow based on reliability, speed, cost, and context window size."
---
New models drop constantly, so this guide focuses on what's working well with Cline right now. We'll keep it updated as the landscape shifts.
<Callout type="tip">
**New to model selection?** Start with [Module 2 of Cline's Learning Path](https://cline.bot/learn) for a comprehensive guide to choosing and configuring models.
</Callout>
## What is an AI Model?
Think of an AI model as the "brain" that powers Cline. When you ask Cline to write code, fix bugs, or refactor your project, it's the model that actually understands your request and generates the response.
**Key points:**
- **Models are trained AI systems** that understand natural language and code
- **Different models have different strengths** some excel at complex reasoning, others prioritize speed or cost
- **You choose which model Cline uses** like picking between different experts for different tasks
- **Models are accessed via API providers** - companies like Anthropic, OpenAI, and OpenRouter host these models
**Why it matters:** The model you choose directly impacts Cline's capabilities, response quality, speed, and cost. A premium model might handle complex refactoring beautifully but cost more, while a budget model works great for routine tasks at a fraction of the price.
## How to Select a Model in Cline
Follow these 5 simple steps to get Cline up and running with your preferred AI model:
### Step 1: Open Cline Settings
First, you need to access Cline's configuration panel.
**Two ways to open settings:**
- **Quick method**: Click the **gear icon (⚙️)** in the top-right corner of Cline's chat interface
- **Command palette**: Press **Cmd/Ctrl + Shift + P** → type "Cline: Open Settings"
<Frame>
<img src="https://storage.googleapis.com/cline_public_images/step1-config.png" alt="Cline Settings Panel" />
</Frame>
The settings panel will open, showing configuration options with "API Provider" at the top.
<Note>
The settings panel remembers your last configuration, so you'll only need to set this up once.
</Note>
### Step 2: Select an API Provider
Choose your preferred AI provider from the dropdown menu.
<Frame>
<img src="https://storage.googleapis.com/cline_public_images/step2-provider.png" alt="Cline Settings Panel" />
</Frame>
**Popular providers at a glance:**
| Provider | Best For | Notes |
|----------|----------|-------|
| **Cline** | Easiest setup | No API keys needed, access to multiple models including stealth models |
| **OpenRouter** | Value seekers | Multiple models, competitive pricing |
| **Anthropic** | Reliability | Claude models, most dependable tool usage |
| **OpenAI** | Latest tech | GPT-5, o3, o4-mini models |
| **OpenAI Codex** | ChatGPT subscribers | Use your ChatGPT subscription — no API key needed |
| **Google Gemini** | Large context | Gemini 3/2.5 with up to 2M context |
| **DeepSeek** | Budget reasoning | V3.2, R1 models at low cost |
| **Alibaba Qwen** | Open source coding | Qwen3 Coder with 1M context |
| **Moonshot** | Agentic coding | Kimi K2.5 with 262K context |
| **Cerebras** | Speed | Up to 2,600 tokens/sec |
| **AWS Bedrock** | Enterprise | Advanced features |
| **Ollama** | Privacy | Run models locally |
See the [full provider list](/getting-started/authorizing-with-cline) for all 30+ supported providers including xAI Grok, Mistral, Groq, Fireworks, Together, Baseten, SambaNova, Nebius, Hugging Face, and more.
<Info>
**Recommended for beginners:** Start with **Cline** as your provider - no API key management needed, instant access to multiple models, and occasional free inferencing through partner providers.
</Info>
### Step 3: Add Your API Key (or Sign In)
The next step depends on which provider you selected.
#### If you selected **Cline** as your provider:
- **No API key needed!** Simply sign in with your Cline account
- Click the **Sign In** button when prompted
- You'll be redirected to [app.cline.bot](https://app.cline.bot) to authenticate
- After signing in, return to your IDE
<Note>
For detailed information about the Cline authentication flow, OAuth tokens, and troubleshooting, see [Authorizing with Cline](/getting-started/authorizing-with-cline).
</Note>
#### If you selected **OpenAI Codex** as your provider:
- **No API key needed!** If you have a ChatGPT subscription (Plus, Pro, or Team), you can use it directly in Cline
- Click **"Sign in with OpenAI"** to authenticate via your browser
- Once authorized, all models available on your OpenAI plan will appear automatically
- Usage is governed by your ChatGPT subscription — no separate API billing
See the full [OpenAI Codex setup guide](/provider-config/openai-codex) for details.
#### If you selected any other provider:
You'll need to get an API key from your chosen provider:
1. **Visit your provider's website to get an API key:**
- **Anthropic**: [console.anthropic.com](https://console.anthropic.com/)
- **OpenRouter**: [openrouter.ai/keys](https://openrouter.ai/keys)
- **OpenAI**: [platform.openai.com/api-keys](https://platform.openai.com/api-keys)
- **Google**: [aistudio.google.com/apikey](https://aistudio.google.com/apikey)
- **Others**: See [Provider Setup Guide](/getting-started/authorizing-with-cline)
2. **Generate a new API key** on the provider's website
3. **Copy the API key** to your clipboard
4. **Paste your key** in the **"API Key"** field in Cline settings
5. **Save automatically** - Your key is stored securely in your editor's secrets storage
<Frame>
<img src="https://storage.googleapis.com/cline_public_images/step3-API.png" alt="Cline API Selection" />
</Frame>
<Warning>
**Payment required for most providers**: Most providers need payment information before generating keys. You only pay for what you use (typically $0.01-$0.10 per coding task).
</Warning>
### Step 4: Choose Your Model
Once your API key is added (or you've signed in), the **"Model"** dropdown becomes available.
<Frame>
<img src="https://storage.googleapis.com/cline_public_images/step4-model.png" alt="Cline Model Selection" />
</Frame>
**Quick model selection guide:**
| Your Priority | Choose This Model | Why |
|---------------|-------------------|-----|
| **Maximum reliability** | Claude Sonnet 4.5 | Most reliable tool usage, excellent at complex tasks |
| **Best value** | DeepSeek V3 or Qwen3 Coder | Great performance at budget prices |
| **Fastest speed** | Qwen3 Coder on Cerebras | Lightning-fast responses |
| **Run locally** | Any Ollama model | Complete privacy, no internet needed |
| **Latest features** | GPT-5 | OpenAI's newest capabilities |
Not sure which to pick? Start with **Claude Sonnet 4.5** for reliability or **DeepSeek V3** for value.
<Tip>
You can switch models at any time without losing your conversation. Try different models to find what works best for your specific tasks.
</Tip>
See the [model comparison tables](#current-top-models) below for detailed specifications and pricing.
### Step 5: Start Using Cline
**Congratulations! You're all set up.** Here's how to start coding with Cline:
1. **Type your request** in the Cline chat box
- Example: "Create a React component for a login form"
- Example: "Debug this TypeScript error"
- Example: "Refactor this function to be more efficient"
2. **Press Enter** or click the send icon to submit
## Choosing the Right Model
Selecting the right model involves balancing several factors. Use this framework to find your ideal match:
<Note>
**Pro tips**: Configure separate models for Plan Mode and Act Mode. Make the most out the each model's strengths. For example, use a budget model for planning discussions and a premium model for implementation.
</Note>
### Key Selection Factors
| Factor | What to Consider | Recommendation |
|--------|------------------|----------------|
| **Task Complexity** | Simple fixes vs complex refactoring | Budget models for routine tasks; Premium models for complex work |
| **Budget** | Monthly spending capacity | \$10-\$30: Budget, \$30-\$100: Mid-tier, \$100+: Premium |
| **Context Window** | Project size and file count | Small: 32K-128K, Medium: 128K-200K, Large: 400K+ |
| **Speed** | Response time requirements | Interactive: Fast models, Background: Reasoning models OK |
| **Tool Reliability** | Complex operations | Claude excels at tool usage; Test others with your workflow |
| **Provider** | Access and pricing needs | OpenRouter: Many options, Direct: Faster/reliable, Local: Privacy |
## Model Comparison Resources
For detailed model comparisons and performance metrics, see:
- [**Context Window Guide**](/model-config/context-windows) - Understanding and optimizing context usage
## Open Source vs Closed Source
### Open Source Advantages
- **Multiple providers** compete to host them
- **Cheaper pricing** due to competition
- **Provider choice** - switch if one goes down
- **Faster innovation** cycles
### Open Source Models Available
- **Qwen3 Coder** (Apache 2.0)
- **Z AI GLM 4.5** (MIT)
- **Kimi K2** (Open source)
- **DeepSeek series** (Various licenses)
## Quick Decision Matrix
| If you want... | Use this |
|----------------|----------|
| Something that just works | Claude Sonnet 4.5 |
| To save money | DeepSeek V3 or Qwen3 variants |
| Huge context windows | Gemini 2.5 Pro or Claude Sonnet 4.5 |
| Open source | Qwen3 Coder, Z AI GLM 4.5, or Kimi K2 |
| Latest tech | GPT-5 |
| To use your ChatGPT subscription | [OpenAI Codex](/provider-config/openai-codex) — sign in with your OpenAI account, no API key needed |
| Speed | Qwen3 Coder on Cerebras (fastest available) |
## What Others Are Using
Check [Vercel's leaderboard](https://vercel.com/ai-gateway/leaderboards) to see real usage patterns from the community.
+1 -1
View File
@@ -89,7 +89,7 @@ For complex tasks that need thorough analysis, use the `/deep-planning` slash co
3. Creates a detailed implementation plan
4. Asks clarifying questions before proceeding
The deep planning prompt is optimized for each model family, so it adapts to the strengths of whatever model you're using. See [/deep-planning](/core-workflows/using-commands#deep-planning) for more details.
The deep planning prompt is optimized for each model family, so it adapts to the strengths of whatever model you're using. See the [Deep Planning docs](/features/deep-planning) for more details.
## Choosing the Right Approach by Task Size
+6 -12
View File
@@ -1,7 +1,7 @@
---
title: "Using Commands"
sidebarTitle: "Using Commands"
description: "Built-in slash commands to manage context, plan implementations, and trigger reusable skills."
description: "Built-in slash commands to manage context, plan implementations, and create reusable workflows."
---
Cline provides slash commands in chat that help you manage your conversation and plan complex implementations.
@@ -37,7 +37,7 @@ Use `/smol` when you're deep into a debugging session or brainstorming and need
### /newrule
`/newrule` creates a rule file that teaches Cline your preferences. Cline will guide you through setting up guidelines for communication style, coding standards, project context, and reusable practices. The rule is saved to your `.clinerules` directory and automatically loaded for future conversations.
`/newrule` creates a rule file that teaches Cline your preferences. Cline will guide you through setting up guidelines for communication style, coding standards, project context, and workflows. The rule is saved to your `.clinerules` directory and automatically loaded for future conversations.
Use `/newrule` when you find yourself repeating the same instructions across tasks. For more about rules, see [Cline Rules](/customization/cline-rules).
@@ -50,7 +50,7 @@ Transform Cline into a meticulous architect who investigates your codebase, asks
3. **Plan Creation** - Generates `implementation_plan.md` with detailed specifications
4. **Task Creation** - Creates a new task with trackable implementation steps
Use `/deep-planning` for features touching multiple parts of your codebase, architectural changes, or complex integrations.
Use `/deep-planning` for features touching multiple parts of your codebase, architectural changes, or complex integrations. For detailed documentation, see [Deep Planning](/features/deep-planning).
### /explain-changes
@@ -68,14 +68,8 @@ Use `/explain-changes` when reviewing code, onboarding to a new codebase, or und
Use `/reportbug` when you encounter unexpected behavior, crashes, or bugs you want to report.
## Skills via Slash Commands
## Custom Workflows
In addition to built-in commands, you can trigger enabled skills directly from chat using slash commands.
Beyond the built-in slash commands, you can create your own workflow files that work the same way. Store Markdown files in `.clinerules/workflows/` and invoke them with `/your-workflow.md`.
- Type `/` to open command suggestions.
- Select a skill command (for example, `/aws-deploy`).
- Cline loads that skill and applies its `SKILL.md` instructions for the task.
Any enabled skill can be triggered this way, which gives you a fast path to skill-specific guidance without rewriting the same instructions each time.
For setup and management details, see [Skills](/customization/skills#triggering-skills-with-slash-commands).
For a complete guide on creating and managing custom workflows, see [Workflows](/customization/workflows).
+66 -6
View File
@@ -1,14 +1,18 @@
---
title: "Adding Context"
sidebarTitle: "Adding Context"
description: "Use @ mentions and drag & drop to bring files into your conversations."
description: "Use @ mentions and drag & drop to bring files, terminal output, errors, git changes, and web content into your conversations."
---
Cline works best when it has the right context, not just more context. `@` mentions let you pull in the files and folders that matter for your task — no copying, no pasting, no context switching.
Cline works best when it has the right context, not just more context. @ mentions let you pull in exactly the files, errors, terminal output, or documentation that matter for your task. No copying, no pasting, no context switching.
You can add context two ways:
- Type `@` in the chat input and select a file or folder
- Click the **+** button in the bottom left to browse files or images
- Type `@` in the chat input and select what you want
- Click the **+** button in the bottom left to browse files, images, or mentions
<Tip>
**Want to learn more about managing context?** Watch [Adding Context with @ Mentions](https://youtu.be/7j6R75Dvj1Y) to see it in action.
</Tip>
## Quick Reference
@@ -16,8 +20,11 @@ You can add context two ways:
|---------------|--------|---------|
| File content | `@/path/to/file` | `@/src/index.ts` |
| Folder contents | `@/path/to/folder/` | `@/src/components/` |
For other context — git history, web pages, terminal errors — just describe it. Cline will run `git log`, fetch the URL, or read the output itself.
| Workspace errors | `@problems` | `@problems` |
| Terminal output | `@terminal` | `@terminal` |
| Uncommitted changes | `@git-changes` | `@git-changes` |
| Specific commit | `@<commit-hash>` | `@a1b2c3d` |
| Web page | `@<url>` | `@https://react.dev/learn` |
## File Mentions
@@ -39,6 +46,59 @@ Explain how the components in @/src/components/auth/ work together.
In multi-root workspaces, prefix paths with the workspace name: `@workspace-name:/path/to/file`
</Note>
## Problem Mentions
Use `@problems` to share all errors and warnings from your workspace's Problems panel.
```text
@problems Can you fix these TypeScript errors?
```
## Terminal Mentions
Use `@terminal` to share recent terminal output. Perfect for debugging build errors or test failures.
```text
@terminal The build is failing. What's wrong?
```
## Git Mentions
Reference uncommitted changes with `@git-changes`:
```text
@git-changes Review my changes before I commit.
```
Reference specific commits with `@<commit-hash>` (7-40 character hex):
```text
What did @a1b2c3d change?
```
## URL Mentions
Reference web content with `@https://example.com`. Cline fetches the page content.
```text
Implement the pattern described in @https://react.dev/learn/scaling-up-with-reducer-and-context
```
## Combining Mentions
Combine multiple @ mentions for comprehensive context:
```text
I'm getting these errors: @problems
Here's my component: @/src/components/Form.jsx
And the API endpoint: @/src/api/users.js
The error happens when I submit: @terminal
I think this commit might have caused it: @a1b2c3d
```
## Drag & Drop
Drag files directly into the chat input to add them to your conversation.
+1 -1
View File
@@ -51,7 +51,7 @@ your-project/
Cline processes all `.md` and `.txt` files inside `.clinerules/`, combining them into a unified set of rules. Numeric prefixes (like `01-coding.md`) help organize files but are optional.
When both workspace and global rules exist, Cline combines them. Workspace rules take precedence when they conflict with global rules. See [Storage Locations](/getting-started/config#storage-locations) for more guidance.
When both workspace and global rules exist, Cline combines them. Workspace rules take precedence when they conflict with global rules. See [Storage Locations](/customization/overview#storage-locations) for more guidance.
### Global Rules Directory
+1
View File
@@ -107,3 +107,4 @@ You can still reference ignored files explicitly using [@ mentions](/core-workfl
- [Cline Rules](/customization/cline-rules) - Define persistent instructions for Cline
- [Task Management](/core-workflows/task-management#context-window) - Understand how context windows work
- [Auto-Compact](/features/auto-compact) - Automatic context compression during long tasks
- [Memory Bank](/features/memory-bank) - Structured documentation for cross-session context
+514 -2
View File
@@ -1,7 +1,519 @@
---
title: "Hooks"
sidebarTitle: "Hooks"
description: "See details under SDK Hooks page."
description: "Inject custom logic into Cline's workflow to validate operations and shape Cline's decisions."
---
See details under [SDK Plugins](/sdk/plugins).
Hooks are scripts that run at key moments in Cline's workflow. Because they execute at known points with consistent inputs and outputs, hooks bring determinism to the non-deterministic nature of AI models by enforcing guardrails, validations, and context injection. You can validate operations before they execute, monitor tool usage, and shape how Cline makes decisions.
## What You Can Build
- Stop operations before they cause problems (like creating `.js` files in a TypeScript project)
- Run linters or custom validators before files get saved
- Prevent operations that violate security policies
- Track everything for analytics or compliance
- Trigger external tools or services at the right moments
- Add context to the conversation based on what Cline is doing
## Hook Types
Cline supports 8 hook types that run at different points in the task lifecycle:
| Hook Type | When It Runs |
|-----------|--------------|
| TaskStart | When you start a new task |
| TaskResume | When you resume an interrupted task |
| TaskCancel | When you cancel a running task |
| TaskComplete | When a task finishes successfully |
| PreToolUse | Before Cline executes a tool (read_file, write_to_file, etc.) |
| PostToolUse | After a tool execution completes |
| UserPromptSubmit | When you submit a message to Cline |
| PreCompact | Before Cline truncates conversation history to free up context |
## Hook Lifecycle
```mermaid
flowchart TD
%% Styling
classDef hook fill:#FFB74D,stroke:#E65100,stroke-width:2px,color:black,rx:5,ry:5;
classDef state fill:#E1F5FE,stroke:#0277BD,stroke-width:2px,color:black;
classDef action fill:#FFFFFF,stroke:#333,stroke-width:1px,color:black,stroke-dasharray: 5 5;
%% Entry Points
Start((Start)) --> CheckType{New or<br/>Resume?}
%% Initialization Hooks
CheckType -- New Task --> H_Start[TaskStart]:::hook
CheckType -- Resume --> H_Resume[TaskResume]:::hook
%% Main Loop
H_Start --> Loop(Task Active Loop):::state
H_Resume --> Loop
subgraph Conversation Cycle
direction TB
Loop -- User sends message --> H_Submit[UserPromptSubmit]:::hook
H_Submit --> Thinking[Cline Processes Context]:::state
%% Context Compaction Path
Thinking -. Context Limit Reached .-> H_Compact[PreCompact]:::hook
H_Compact -.-> Thinking
%% Tool Execution Path
Thinking -- Decides to use tool --> H_PreTool[PreToolUse]:::hook
H_PreTool -- Allowed --> ToolExec[Tool Executes]:::action
H_PreTool -- Cancelled --> Thinking
ToolExec --> H_PostTool[PostToolUse]:::hook
H_PostTool --> Thinking
end
%% Termination Paths
Thinking -- Task Successfully Finished --> H_Complete[TaskComplete]:::hook
Loop -- User Cancels Task --> H_Cancel[TaskCancel]:::hook
%% End
H_Complete --> End((End))
H_Cancel --> End
```
The diagram shows the complete hook lifecycle:
1. **Entry**: When you start a task, either **TaskStart** (new task) or **TaskResume** (interrupted task) runs first
2. **Conversation Cycle**: Each time you send a message, **UserPromptSubmit** runs, then Cline processes your request
3. **Tool Execution**: When Cline decides to use a tool, **PreToolUse** runs first-if allowed, the tool executes, then **PostToolUse** runs
4. **Context Management**: If the conversation approaches context limits, **PreCompact** runs before truncation
5. **Exit**: The task ends with either **TaskComplete** (success) or **TaskCancel** (user cancellation)
Orange nodes represent hooks where you can inject custom logic. The cycle repeats as you continue the conversation.
## Hook Locations
Hooks can be stored globally or in a project workspace. See [Storage Locations](/customization/overview#storage-locations) for guidance on when to use each.
- **Global hooks**: `~/Documents/Cline/Hooks/`
- **Project hooks**: `.clinerules/hooks/` in your repo (can be committed to version control)
When both global and workspace hooks exist for the same hook type, both run. Global hooks execute first, then workspace hooks. If either returns `cancel: true`, the operation stops.
## Creating a Hook
<Steps>
<Step title="Open the Hooks tab">
Click the scale icon at the bottom of the Cline panel, to the left of the model selector. Switch to the Hooks tab.
</Step>
<Step title="Create a new hook">
Click **"New hook..."** dropdown and select a hook type (e.g., PreToolUse, TaskStart).
</Step>
<Step title="Review the hook's code">
Click the pencil icon to open and edit the hook script. Cline generates a template with examples.
</Step>
<Step title="Enable the hook">
Toggle the switch to activate the hook once you understand what it does.
</Step>
</Steps>
<Warning>
Always review a hook's code before enabling it. Hooks execute automatically during your workflow and can block operations or run shell commands.
</Warning>
## Quick Start: Your First Hook
Let's create a simple hook that logs every file Cline reads or writes. You'll see results in seconds.
### The Hook
Create a file called `file-logger` in your hooks directory with this content:
```bash
#!/bin/bash
# Logs all file operations to ~/cline-activity.log
INPUT=$(cat)
TOOL=$(echo "$INPUT" | jq -r '.preToolUse.toolName')
FILE_PATH=$(echo "$INPUT" | jq -r '.preToolUse.parameters.path // "N/A"')
# Log to file
echo "$(date '+%H:%M:%S') - $TOOL: $FILE_PATH" >> ~/cline-activity.log
# Always allow the operation
echo '{"cancel":false}'
```
### Setup
<Steps>
<Step title="Create the hook file">
Save the script above as `~/Documents/Cline/Hooks/file-logger` or create it through the Hooks UI.
</Step>
<Step title="Make it executable">
On macOS/Linux, run `chmod +x ~/Documents/Cline/Hooks/file-logger`.
</Step>
<Step title="Enable it (macOS/Linux only)">
In Cline's Hooks tab, find "file-logger" under PreToolUse hooks and toggle it on.
</Step>
</Steps>
<Note>
On Windows, hooks are executed with PowerShell and run whenever the hook file exists. In this
foundation PR, hook enable/disable toggling is not yet supported on Windows.
</Note>
<Note>
Coming next: JSON-backed hook enabled/disabled state across platforms, so toggle behavior is
consistent on Windows, macOS, and Linux.
</Note>
<Note>
Hook filenames are platform-specific:
- **Windows**: only `HookName.ps1` is supported (PowerShell script files)
- **macOS/Linux**: only extensionless `HookName` is supported (executable files like bash scripts or binaries)
Wrong-platform naming is ignored by hook discovery.
</Note>
### Test It
Ask Cline to read any file in your project: "What's in package.json?"
Then check the log:
```bash
cat ~/cline-activity.log
```
You'll see entries like:
```text
14:23:45 - read_file: /path/to/package.json
14:23:47 - search_files: /path/to/src
```
### Customize It
Try modifying the hook to:
- Filter specific file types (only log `.ts` files)
- Add the task ID to each log entry
- Send notifications for write operations
- Block operations on certain paths
The sections below explain how hooks receive input and return output, plus more examples.
## How Hooks Work
Hooks are executable scripts that receive JSON input via stdin and return JSON output via stdout.
### Input Structure
Every hook receives a JSON object with common fields plus hook-specific data:
```json
{
"taskId": "abc123",
"hookName": "PreToolUse",
"clineVersion": "3.17.0",
"timestamp": "1736654400000",
"workspaceRoots": ["/path/to/project"],
"userId": "user_123",
"model": {
"provider": "openrouter",
"slug": "anthropic/claude-sonnet-4.5"
},
// Hook-specific field (name matches hook type in camelCase)
"taskStart": {
"taskMetadata": {
"taskId": "abc123",
"ulid": "01J...",
"initialTask": "Add authentication to the API"
}
}
}
```
`model.provider` and `model.slug` are machine-stable identifiers for the active provider/model at hook execution time. If unavailable, Cline sends deterministic fallback values: `"unknown"`.
<Note>
Migration note for existing hook scripts:
- `timestamp` is a string (milliseconds since epoch), not a number
- `workspaceRoots` is an array of workspace root paths and replaces the old singular `workspacePath`
If your scripts previously read `.workspacePath`, switch to `.workspaceRoots[0]` (or iterate all roots).
</Note>
The hook-specific field name matches the hook type:
- `taskStart`, `taskResume`, `taskCancel`, `taskComplete` contain `{ taskMetadata: { taskId, ulid, ... } }`
- `preToolUse` contains `{ toolName: string, parameters: object }`
- `postToolUse` contains `{ toolName: string, parameters: object, result: string, success: boolean, executionTimeMs: number }`
- `userPromptSubmit` contains `{ prompt: string, attachments: string[] }`
- `preCompact` contains `{ taskId, ulid, contextSize, compactionStrategy, tokensIn, tokensOut, ... }`
### Output Structure
Hooks return a JSON object to stdout:
```json
{
"cancel": false,
"contextModification": "Optional text to add to the conversation",
"errorMessage": ""
}
```
| Field | Type | Description |
|-------|------|-------------|
| `cancel` | boolean | If `true`, stops the operation (blocks the tool, cancels the task start, etc.) |
| `contextModification` | string | Optional text that gets injected into the conversation as context for Cline |
| `errorMessage` | string | Shown to the user if `cancel` is `true` |
### Context Modification
The `contextModification` field lets hooks inject information into the conversation. This is useful for:
- Adding project-specific context when a task starts
- Providing validation results that Cline should consider
- Injecting environment information before tool execution
For example, a PreToolUse hook could add: `"Note: This file is auto-generated. Edits may be overwritten."`
## Hook Reference
### Task Lifecycle Hooks
#### TaskStart
Runs when you start a new task. Use it to:
- Log task start time for analytics
- Add project context to the conversation
- Check prerequisites before work begins
- Notify external systems (Slack, issue trackers)
```bash
#!/bin/bash
INPUT=$(cat)
TASK=$(echo "$INPUT" | jq -r '.taskStart.taskMetadata.initialTask')
echo "[TaskStart] Starting: $TASK" >&2
echo '{"cancel":false,"contextModification":"","errorMessage":""}'
```
#### TaskResume
Runs when you resume an interrupted task (instead of TaskStart). Use it to:
- Check for changes since the task was paused
- Refresh context with latest project state
- Notify that work is resuming
#### TaskCancel
Runs when you cancel a running task. Use it to:
- Clean up temporary files or resources
- Notify external systems about cancellation
- Log cancellation for analytics
#### TaskComplete
Runs when a task completes successfully. Use it to:
- Run tests or validation after changes
- Generate reports or summaries
- Notify stakeholders
- Trigger CI/CD pipelines
### Tool Hooks
#### PreToolUse
Runs before any tool executes. This is the most powerful hook for validation and safety. Use it to:
- Block dangerous operations
- Validate parameters before execution
- Add context about the file or resource being accessed
- Log tool usage
The input includes the tool name and its parameters:
```json
{
"preToolUse": {
"toolName": "write_to_file",
"parameters": {
"path": "src/config.ts",
"content": "..."
}
}
}
```
Example that blocks `.js` files in a TypeScript project:
```bash
#!/bin/bash
INPUT=$(cat)
TOOL=$(echo "$INPUT" | jq -r '.preToolUse.toolName')
FILE_PATH=$(echo "$INPUT" | jq -r '.preToolUse.parameters.path // empty')
if [[ "$TOOL" == "write_to_file" && "$FILE_PATH" == *.js ]]; then
echo '{"cancel":true,"errorMessage":"Use .ts files instead of .js in this TypeScript project"}'
exit 0
fi
echo '{"cancel":false}'
```
#### PostToolUse
Runs after a tool completes (success or failure). Use it to:
- Audit tool usage
- Validate results
- Trigger follow-up actions
- Monitor performance
The input includes execution results:
```json
{
"postToolUse": {
"toolName": "execute_command",
"parameters": { "command": "npm test" },
"result": "All tests passed",
"success": true,
"executionTimeMs": 3450
}
}
```
<Note>
PostToolUse hooks can return `cancel: true` to stop the task, but they cannot undo the tool execution that already happened.
</Note>
### Other Hooks
#### UserPromptSubmit
Runs when you send a message to Cline. Use it to:
- Log prompts for analytics
- Add context based on prompt content
- Validate or sanitize prompts
#### PreCompact
Runs before Cline truncates conversation history to stay within context limits. Use it to:
- Archive important conversation parts before they're removed
- Log compaction events
- Add a summary of what's being removed
The input includes context metrics:
```json
{
"preCompact": {
"taskId": "abc123",
"ulid": "01J...",
"contextSize": 45,
"compactionStrategy": "auto-condense",
"tokensIn": 125000,
"tokensOut": 8500,
"tokensInCache": 0,
"tokensOutCache": 0
}
}
```
## Examples
### TypeScript Enforcement
Block creation of `.js` files in a TypeScript project:
```bash
#!/bin/bash
# PreToolUse hook
INPUT=$(cat)
TOOL=$(echo "$INPUT" | jq -r '.preToolUse.toolName')
FILE_PATH=$(echo "$INPUT" | jq -r '.preToolUse.parameters.path // empty')
if [[ "$TOOL" == "write_to_file" && "$FILE_PATH" == *.js ]]; then
echo '{"cancel":true,"errorMessage":"Use .ts files instead of .js in this TypeScript project"}'
exit 0
fi
echo '{"cancel":false}'
```
### Tool Usage Logging
Log all tool executions to a file:
```bash
#!/bin/bash
# PostToolUse hook
INPUT=$(cat)
TOOL=$(echo "$INPUT" | jq -r '.postToolUse.toolName')
SUCCESS=$(echo "$INPUT" | jq -r '.postToolUse.success')
DURATION=$(echo "$INPUT" | jq -r '.postToolUse.executionTimeMs')
echo "$(date -Iseconds) | $TOOL | success=$SUCCESS | ${DURATION}ms" >> ~/.cline-tool-log.txt
echo '{"cancel":false}'
```
### Add Project Context on Task Start
Inject project-specific information when a task begins:
```bash
#!/bin/bash
# TaskStart hook
INPUT=$(cat)
WORKSPACE=$(echo "$INPUT" | jq -r '.workspaceRoots[0] // empty')
# Read project info if available
if [[ -f "$WORKSPACE/.project-context" ]]; then
CONTEXT=$(cat "$WORKSPACE/.project-context")
echo "{\"cancel\":false,\"contextModification\":\"Project context: $CONTEXT\"}"
else
echo '{"cancel":false}'
fi
```
## CLI Support
Hooks are available in the [Cline CLI](/cline-cli/getting-started):
```bash
# Enable hooks for a task
cline "What does this repo do?" -s hooks_enabled=true
# Configure hooks globally
cline config set hooks-enabled=true
```
<Note>
Windows hooks require PowerShell (`powershell.exe`) available on your PATH.
</Note>
## Troubleshooting
**Hook not running?**
- On macOS/Linux, check that the file is executable (`chmod +x hookname`)
- On Windows, ensure PowerShell is available (`powershell -NoProfile -Command "$PSVersionTable.PSVersion"`)
- On Windows, ensure the hook file is named `<HookName>.ps1` (for example `PreToolUse.ps1`)
- On macOS/Linux, ensure the hook file uses extensionless `<HookName>` naming (for example `PreToolUse`)
- On macOS/Linux, verify the hook is enabled (toggle is on in the Hooks tab)
- Check that Hooks are enabled globally in Settings
**Hook output not parsed?**
- Ensure output is valid JSON on a single line to stdout
- Use stderr (`>&2`) for debug logging, not stdout
- Check for trailing characters or newlines before the JSON
**Hook blocking unexpectedly?**
- Review the hook's logic and test with sample input
- Check both global and workspace hooks (both run if they exist)
## Related Features
- [Rules](/customization/cline-rules) define high-level guidance that hooks can enforce programmatically
- [Checkpoints](/core-workflows/checkpoints) let you roll back if a hook didn't catch an issue
- [Auto-Approve](/features/auto-approve) works well with hooks as safety nets
+86
View File
@@ -0,0 +1,86 @@
---
title: "Overview"
sidebarTitle: "Overview"
description: "Understand how Rules, Skills, Workflows, Hooks, and .clineignore work together to customize Cline."
---
Out of the box, Cline is a general-purpose AI assistant. Customizations transform it into an expert on your codebase, your team's conventions, and your workflows. Instead of repeating the same instructions every task, you define them once and Cline follows them automatically.
Cline offers five systems for this: Rules, Skills, Workflows, Hooks, and .clineignore. Each serves a different purpose and activates at different times.
## Quick Comparison
| Feature | Purpose | When Active | Best For |
|---------|---------|-------------|----------|
| **[Rules](/customization/cline-rules)** | Define how Cline behaves | Always (or contextually) | Coding standards, project constraints, team conventions |
| **[Skills](/customization/skills)** | Domain expertise loaded on-demand | Triggered by matching requests | Specialized knowledge, complex procedures, institutional expertise |
| **[Workflows](/customization/workflows)** | Step-by-step task automation | Invoked with `/workflow.md` | Repetitive processes, release procedures, setup scripts |
| **[Hooks](/customization/hooks)** | Inject custom logic at key moments | Automatically on specific events | Validation, enforcement, monitoring, automation triggers |
| **[.clineignore](/customization/clineignore)** | Control file access | Always | Excluding dependencies, build artifacts, large data files |
## Understanding Each Tool
**[Rules](/customization/cline-rules)** are always-on guidance. Use them when you want Cline to consistently follow certain patterns: coding standards, naming conventions, architectural constraints, or project-specific context. Rules shape *how* Cline works across all tasks. For example, a rule might say "always use TypeScript" or "follow the repository pattern for data access."
**[Skills](/customization/skills)** are domain expertise that loads only when relevant. Use them when you have extensive knowledge that would waste context if always active. Cline sees skill descriptions at startup and activates the full instructions only when your request matches. A data analysis skill might include pandas patterns, visualization preferences, and output formats that Cline only loads when you're working with data files.
**[Workflows](/customization/workflows)** are explicit task scripts you invoke on demand. Use them when you have a repeatable multi-step process that should run the same way every time. Type `/release.md` and Cline executes your release sequence: bump version, run tests, update changelog, commit, tag, push. Workflows define *what* to do, step by step.
**[Hooks](/customization/hooks)** are programmatic guardrails that run automatically at key moments. Use them when you need to validate, enforce, or extend Cline's behavior with custom code. A hook might block `.js` file creation in a TypeScript project, run linters before saves, or notify external services after deployments.
**[.clineignore](/customization/clineignore)** controls which files and directories Cline can access. Use it to exclude dependencies, build artifacts, generated files, and large data files from Cline's context. This reduces token usage, lowers costs, and keeps Cline focused on the code that matters. It works like `.gitignore`: add patterns to a `.clineignore` file in your project root and matching files are automatically excluded.
### Example: A Release Process
Consider how all five work together for releasing a new version:
1. **Rules** ensure Cline follows your team's commit message format and versioning policy
2. **Skills** offer deep knowledge about your CI/CD system that Cline loads when deployment questions arise
3. **Workflows** provide the explicit `/release.md` sequence: bump version, update changelog, tag, push
4. **Hooks** validate that tests pass before allowing any commit or that the changelog was actually updated
5. **.clineignore** keeps build artifacts, `node_modules/`, and generated files out of Cline's context so it stays focused
## Storage Locations
All five systems support both global and project-specific configurations:
| System | Global Location | Project Location |
|--------|-----------------|------------------|
| Rules | `~/Documents/Cline/Rules/` | `.clinerules/` |
| Skills | `~/.cline/skills/` | `.cline/skills/` |
| Workflows | `~/Documents/Cline/Workflows/` | `.clinerules/workflows/` |
| Hooks | `~/Documents/Cline/Hooks/` | `.clinerules/hooks/` |
| .clineignore | N/A | `.clineignore` |
### When to Use Each
**Start with project storage.** Most customizations belong in your project's directory because they're tied to that specific codebase. Team coding standards, deployment workflows, and architectural constraints all live with the code they describe. This also means your customizations travel with the repository, so collaborators get them automatically and changes can be reviewed in pull requests.
**Use global storage for personal preferences.** If you find yourself adding the same customization to every project, move it to global storage. Your preferred communication style, personal productivity workflows, and tools you use everywhere belong here. Global customizations apply to all projects but stay out of version control, so they won't affect your teammates.
When names conflict, project-specific configurations take precedence (except for Skills, where global takes precedence). This lets you override global defaults for specific projects when needed.
## Security Considerations
<Warning>
Always review customizations before adding them to your projects. Only use customizations from sources you trust.
</Warning>
Customizations are powerful. They shape how Cline writes code, execute commands automatically, and influence every interaction. Treat customization files with the same scrutiny you'd give any code running in your environment.
### Best Practices
Review any customization file before adding it to your project or global configuration. Understand what it does and why.
When downloading customizations from GitHub repositories, community shares, or other external sources, verify the source:
- Is the author reputable?
- Has the community reviewed it?
- Does the code do what it claims?
Look for dangerous commands:
- Shell commands that delete files (`rm`, `del`)
- Commands that transmit data (`curl`, `wget` with POST)
- File operations outside your project directory
- Commands that modify system configuration
Keep your customizations in version control so you can track changes, review diffs, and roll back if something goes wrong. When creating hooks, use the most restrictive event triggers necessary. Don't run hooks on every file save if you only need them before commits.
-138
View File
@@ -1,138 +0,0 @@
---
title: "Plugins"
sidebarTitle: "Plugins"
description: "Install and manage plugins that extend Cline with custom tools, hooks, and capabilities."
---
<Warning>
This feature currently only applies to Cline SDK, CLI, and Kanban. This feature is not applicable on VSCode and JetBrains Extension for now.
</Warning>
Plugins extend Cline with custom tools, lifecycle hooks, slash commands, and more. They can be installed globally (available in all sessions) or per-project.
## Installing Plugins via CLI
The `cline plugin install` command installs plugins from three source types:
<Tabs>
<Tab title="Git Repository">
```bash
cline plugin install https://github.com/owner/repo.git
cline plugin install git@github.com:owner/repo.git
```
The installer clones the repository, installs production dependencies, and registers the plugin entry files.
To install a specific branch or tag, append `@ref`:
```bash
cline plugin install https://github.com/owner/repo.git@v1.2.0
cline plugin install https://github.com/owner/repo.git@main
```
</Tab>
<Tab title="npm Package">
```bash
cline plugin install npm:@scope/my-plugin
cline plugin install --npm my-plugin
```
</Tab>
<Tab title="Local Path">
```bash
cline plugin install ./my-plugin
cline plugin install ~/plugins/my-tool
cline plugin install /absolute/path/to/plugin.ts
```
Local installs copy the file or directory into the plugin store. Both single `.ts`/`.js` files and directories with a `package.json` are supported.
</Tab>
</Tabs>
Additional flags:
| Flag | Description |
|------|-------------|
| `--force` | Replace an existing install for the same source |
| `--json` | Output the result as JSON (useful for scripting) |
| `--cwd <path>` | Install to `<path>/.cline/plugins` instead of the global directory |
After installation, confirm the plugin is loaded by running `cline config` and checking the plugin tab.
### Example: TypeScript Navigation Plugin
The [typescript-lsp-plugin](https://github.com/cline/typescript-lsp-plugin) is a good reference for how plugins work. It adds a `goto_definition` tool that uses the TypeScript Language Service API to resolve symbol definitions through imports, re-exports, and type aliases.
Install it with:
```bash
cline plugin install https://github.com/cline/typescript-lsp-plugin.git
```
Once installed, Cline can call `goto_definition` with a file path and line number to find where symbols are defined, which is much more precise than text search.
## Plugin Manifest Format
For a repository or npm package to be installable as a Cline plugin, its `package.json` should include a `cline` field that declares plugin entry points:
```json
{
"name": "my-cline-plugin",
"version": "1.0.0",
"cline": {
"plugins": [
{
"paths": ["./index.ts"],
"capabilities": ["tools", "hooks"]
}
]
}
}
```
The `cline.plugins` array accepts:
| Format | Example |
|--------|---------|
| Object with `paths` array | `{ "paths": ["./src/plugin.ts"], "capabilities": ["tools"] }` |
| Plain string | `"./index.ts"` |
Each path should point to a `.ts` or `.js` file that exports an `AgentPlugin` (either as the default export or a named export).
If no `cline.plugins` field is present, the installer falls back to auto-discovery: it looks for standard entry points, then recursively scans for `.ts` and `.js` files (skipping `node_modules` and `.git`).
### Host-Provided Dependencies
Dependencies under the `@cline/` scope (like `@cline/core`, `@cline/shared`) are provided by the host runtime. The installer automatically strips these from the plugin's dependency list before running `npm install`, so you should declare them as `peerDependencies`:
```json
{
"peerDependencies": {
"@cline/core": "*"
},
"peerDependenciesMeta": {
"@cline/core": {
"optional": true
}
}
}
```
## Plugin Directory Structure
Plugins are stored in the `plugins` directory at two levels:
```
~/.cline/
plugins/ # Global plugins
_installed/ # Managed by `cline plugin install`
npm/ # npm-sourced plugins
git/ # git-sourced plugins
local/ # local-sourced plugins
.cline/ # Project root
plugins/ # Project-scoped plugins
```
Global plugins (`~/.cline/plugins/`) are available across all sessions. Project plugins (`.cline/plugins/` in your repo) are available only when working in that project.
## Writing Plugins
For a guide on building plugins with the SDK, see [Writing Plugins](/sdk/guides/writing-plugins). For the plugin API reference, see [SDK Plugins](/sdk/plugins).
+4 -14
View File
@@ -4,7 +4,7 @@ sidebarTitle: "Skills"
description: "Modular instruction sets that extend Cline's capabilities for specific tasks."
---
Skills are modular instruction sets that extend Cline's capabilities for specific tasks. Each skill packages detailed guidance, processes, and optional resources that Cline loads only when relevant to your request.
Skills are modular instruction sets that extend Cline's capabilities for specific tasks. Each skill packages detailed guidance, workflows, and optional resources that Cline loads only when relevant to your request.
Install multiple skills and Cline only loads what it needs. A deployment skill stays dormant until you ask about deploying. Unlike [rules](/customization/cline-rules) (which are always active), skills load on-demand so they don't consume context when you're working on something unrelated.
@@ -24,16 +24,6 @@ Skills use progressive loading to maximize efficiency:
When you send a message, Cline sees a list of available skills with their descriptions. If your request matches a skill's description, Cline activates it using the `use_skill` tool, which loads the full instructions from SKILL.md.
## Triggering Skills with Slash Commands
You can also invoke enabled skills explicitly from the chat input using slash commands.
1. Type `/` in chat to open command suggestions.
2. Select the skill command you want to run (for example, `/aws-deploy`).
3. Cline triggers that skill and loads its `SKILL.md` instructions.
This is useful when you want to force a specific skill immediately instead of waiting for auto-matching based on description.
## Skill Structure
Every skill is a directory containing a `SKILL.md` file with YAML frontmatter.
@@ -148,7 +138,7 @@ Include real examples. Show what commands to run, what output to expect, and wha
## Where Skills Live
Skills can be stored globally or in a project workspace. See [Storage Locations](/getting-started/config#storage-locations) for guidance on when to use each.
Skills can be stored globally or in a project workspace. See [Storage Locations](/customization/overview#storage-locations) for guidance on when to use each.
Project skills:
- `.cline/skills/` (recommended)
@@ -225,7 +215,7 @@ Cline reads documentation files using `read_file` when the instructions referenc
| Use Scripts For | Use Instructions For |
|-----------------|---------------------|
| Deterministic operations (validation, formatting) | Flexible guidance that adapts to context |
| Complex computations | Decision-making processes |
| Complex computations | Decision-making workflows |
| Operations that need reliability | Steps that might vary by situation |
| Anything you'd rather not consume tokens explaining | Best practices and patterns |
@@ -241,7 +231,7 @@ description: Analyze data files and generate insights. Use when working with CSV
# Data Analysis
When analyzing data files, follow this process:
When analyzing data files, follow this workflow:
## 1. Understand the Data
- Read a sample of the file to understand its structure
+221
View File
@@ -0,0 +1,221 @@
---
title: "Workflows"
sidebarTitle: "Workflows"
description: "Automate repetitive tasks with Markdown-based workflow files."
---
Workflows are Markdown files that define a series of steps to guide Cline through repetitive or complex tasks. Type `/` followed by the workflow's filename to invoke it (e.g., `/deploy.md`).
Deploying, setting up a new project, running through a release checklist: these tasks often require remembering a dozen steps, running commands in the right order, and updating files manually. Mess up one step and you're debugging for an hour. Workflows turn those multi-step processes into one command. Type `/release.md` and Cline handles the version bump, runs tests, updates the changelog, commits, tags, and pushes. You just review and approve.
## Workflow Structure
A workflow is a markdown file with a title and steps. The filename becomes the command: `demo-workflow.md` is invoked with `/demo-workflow.md`.
````markdown title="demo-workflow.md"
# Demo Workflow
Brief description of what this workflow accomplishes.
## Step 1: Check prerequisites
Verify the environment is ready. Look for required tools and dependencies.
## Step 2: Run the build
Execute the build command:
```bash
npm run build
```
## Step 3: Verify results
Check that the build completed successfully and report any issues.
````
Steps can be written at different levels of detail:
- **High-level**: "Run the test suite and fix any failures" lets Cline decide how to accomplish the goal
- **Specific**: Use XML tool syntax or exact commands when you need precise control
## Creating Workflows
<Steps>
<Step title="Open the Workflows menu">
Click the scale icon at the bottom of the Cline panel, to the left of the model selector. Switch to the Workflows tab.
</Step>
<Step title="Create a new workflow file">
Click "New workflow file..." and enter a filename (e.g., `deploy`). The file will be created with a `.md` extension.
</Step>
<Step title="Write your workflow">
Add a title and numbered steps in markdown format. Describe what each step should accomplish.
</Step>
</Steps>
<Tip>
**Create workflows from completed tasks.** After finishing something you'll need to repeat, tell Cline: "Create a workflow for the process I just completed." Cline analyzes the conversation, identifies the steps, and generates the workflow file. Your accumulated context becomes reusable automation.
</Tip>
### Invoking Workflows
Type `/` in the chat input to see available workflows. Cline shows autocomplete suggestions as you type, so `/rel` would match `release-prep.md`. Select a workflow and press Enter to start it.
Cline executes each step in sequence, pausing for your approval when needed. You can stop a workflow at any point by rejecting a step.
### Toggling Workflows
Every workflow has a toggle to enable or disable it. This lets you control which workflows appear in the `/` menu without deleting the file.
## Where Workflows Live
Workflows can be stored in two locations: your project workspace or globally on your system.
**Workspace workflows** go in `.clinerules/workflows/` at your project root. Use these for project-specific automation like deployment scripts, release processes, or setup procedures that your team shares.
**Global workflows** go in your system's Cline Workflows directory. Use these for personal productivity workflows you use across all projects.
### Global Workflows Directory
| Operating System | Default Location |
|------------------|------------------|
| Windows | `Documents\Cline\Workflows` |
| macOS | `~/Documents/Cline/Workflows` |
| Linux/WSL | `~/Documents/Cline/Workflows` |
Workspace workflows take precedence when names match global workflows. See [Storage Locations](/customization/overview#storage-locations) for more guidance.
## What Workflows Can Use
Workflows can combine natural language instructions with specific tool calls. This flexibility lets you write workflows that are as simple or as precise as your task requires.
### Natural Language
Write steps as plain instructions. Cline interprets them and figures out which tools to use:
```markdown
## Step 1: Check for uncommitted changes
Look at the git status. If there are uncommitted changes, ask whether to continue or abort.
## Step 2: Run the test suite
Execute all tests. If any fail, show the failures and stop.
```
This approach works well when you want Cline to adapt to the situation rather than follow rigid steps.
### Cline Tools
For precise control, use Cline's built-in tools with XML syntax. This guarantees specific actions:
```xml
<execute_command>
<command>npm run test</command>
<requires_approval>false</requires_approval>
</execute_command>
```
```xml
<read_file>
<path>src/config.json</path>
</read_file>
```
```xml
<ask_followup_question>
<question>Deploy to production or staging?</question>
<options>["Production", "Staging", "Cancel"]</options>
</ask_followup_question>
```
See the full list in the [Cline Tools Reference](/tools-reference/all-cline-tools).
### CLI Tools
Reference any command-line tool installed on your machine. Git, npm, docker, gh, make, curl: whatever you have available.
```bash
git log --author="$(git config user.name)" --since="yesterday" --oneline
```
### MCP Tools
If you have [MCP servers](/mcp/mcp-overview) connected, use them in your workflows with the `use_mcp_tool` syntax. This lets you integrate with external services like GitHub, Slack, databases, or custom internal tools.
```xml
<use_mcp_tool>
<server_name>github-server</server_name>
<tool_name>create_release</tool_name>
<arguments>{"tag": "v1.2.0", "name": "Release v1.2.0", "body": "Changelog content here"}</arguments>
</use_mcp_tool>
```
Or describe the intent in natural language and let Cline figure out the tool call:
```markdown
## Step 3: Create GitHub release
Use the GitHub MCP server to create a release tagged with the version from package.json.
Include the changelog as the release body.
```
## Writing Effective Workflows
**Start simple.** Write natural language steps first. Only add XML tool calls when you need guaranteed behavior.
**Be specific about decisions.** If a step requires user input, make that explicit: "Ask whether to deploy to production or staging."
**Include failure handling.** Tell Cline what to do when something goes wrong: "If tests fail, show the failures and stop the workflow."
**Keep workflows focused.** A `deploy.md` should deploy. A `setup-db.md` should set up the database. Split complex processes into multiple workflows that can be run independently.
**Version control your workflows.** Store workflows in `.clinerules/workflows/` and commit them. Your team can share, review, and improve them together.
<Warning>
Workflows execute with your permissions. Review workflows before running them, especially those from external sources.
</Warning>
## Example: Release Preparation
This workflow automates the tedious pre-release checklist. It verifies your working directory is clean, runs tests and builds, prompts you for the version bump, and generates a changelog from recent commits.
The workflow demonstrates both approaches: XML tool syntax (`<execute_command>`, `<ask_followup_question>`) for steps that need precise control, and natural language for steps where Cline should adapt to the situation.
````markdown title="release-prep.md"
# Release Preparation
Prepare a new release by running tests, building, and updating version info.
## Step 1: Check for clean working directory
<execute_command>
<command>git status --porcelain</command>
</execute_command>
If there are uncommitted changes, ask whether to continue or stash them first.
## Step 2: Run the test suite
<execute_command>
<command>npm run test</command>
</execute_command>
If any tests fail, stop the workflow and report the failures.
## Step 3: Build the project
<execute_command>
<command>npm run build</command>
</execute_command>
Verify the build completes without errors.
## Step 4: Ask for new version
<ask_followup_question>
<question>What should the new version be?</question>
<options>["Patch (x.x.X)", "Minor (x.X.0)", "Major (X.0.0)", "Custom"]</options>
</ask_followup_question>
## Step 5: Update version
Update the version in `package.json` to the new version specified by the user.
## Step 6: Generate changelog entry
<execute_command>
<command>git log --oneline $(git describe --tags --abbrev=0)..HEAD</command>
</execute_command>
Use these commits to write a changelog entry for the new version.
````
Invoke it with `/release-prep.md` and Cline walks through each step.
+210 -641
View File
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -4,7 +4,7 @@ sidebarTitle: "API Reference"
description: "REST API endpoints for managing users, organizations, billing, plans, and API keys."
---
The Enterprise API provides REST endpoints for account management, organization administration, billing, and API key management. These are separate from the [Chat Completions API](/api/overview), which handles model inference.
The Enterprise API provides REST endpoints for account management, organization administration, billing, and API key management. These are separate from the [Chat Completions API](/api/reference), which handles model inference.
## Base URL
@@ -20,7 +20,7 @@ All endpoints require a Bearer token in the `Authorization` header:
Authorization: Bearer YOUR_AUTH_TOKEN
```
Use the same API key or account auth token described in the [public API reference](/api/overview#authentication).
Use the same API key or account auth token described in the [public API reference](/api/reference#authentication).
## Quick Example
@@ -180,7 +180,7 @@ Track token consumption and costs across your organization.
## API Keys
Create and manage API keys for programmatic access. Keys created here work with both the [Chat Completions API](/api/overview) and the endpoints on this page.
Create and manage API keys for programmatic access. Keys created here work with both the [Chat Completions API](/api/reference) and the endpoints on this page.
| Method | Endpoint | Description |
|--------|----------|-------------|
@@ -193,7 +193,7 @@ Create and manage API keys for programmatic access. Keys created here work with
## Related
<CardGroup cols={2}>
<Card title="Chat Completions API" icon="code" href="/api/overview">
<Card title="Chat Completions API" icon="code" href="/api/reference">
The public inference API for sending prompts and receiving completions.
</Card>
<Card title="SSO Setup" icon="key" href="/enterprise-solutions/sso-setup">
@@ -107,8 +107,6 @@ Select your provider below to begin the configuration process:
</Card>
<Card title="Anthropic" icon="robot" href="/enterprise-solutions/configuration/remote-configuration/anthropic/admin-configuration">
Direct Anthropic API access with optional custom base URL configuration.
</Card>
<Card title="LiteLLM" icon="layer-group" href="/enterprise-solutions/configuration/remote-configuration/litellm/admin-configuration">
Unified proxy for accessing 100+ AI models through a single interface.
@@ -150,7 +150,7 @@ Core events tracking task lifecycle, conversation turns, tool usage, and executi
| `task.checkpoint_used` | Checkpoint action used | action (create/restore/compare), task_id |
| `task.option_selected` | User selected one of AI-provided options | option_index, total_options |
| `task.options_ignored` | User ignored AI options and entered custom input | options_count |
| `task.slash_command_used` | Slash command or MCP prompt command used | command_name |
| `task.slash_command_used` | Slash command/workflow/MCP prompt command used | command_name, is_workflow |
| `task.mention_used` | Mention resolution succeeded | mention_type (file/url/folder/terminal/problems/git) |
| `task.mention_failed` | Mention resolution failed | mention_type, error_reason |
| `task.mention_search_results` | Mention search query result telemetry | query, results_count |
@@ -232,7 +232,7 @@ Events tracking user interface interactions.
| `ui.model_selected` | Model selected in UI | model, provider, previous_model |
| `ui.model_favorite_toggled` | Model favorite toggled | model_id, is_favorited |
| `ui.button_clicked` | UI button click event | button_id, context |
| `ui.rules_menu_opened` | Rules/skills menu/modal opened | menu_type |
| `ui.rules_menu_opened` | Rules/workflows menu/modal opened | menu_type |
### Example: ui.model_selected
@@ -10,7 +10,7 @@ Cline includes telemetry to help understand usage patterns and improve the produ
Telemetry captures anonymous usage events such as:
- Features used (which tools and commands)
- Features used (which tools, commands, workflows)
- Task completion rates
- Error occurrences
- Performance metrics
@@ -39,7 +39,7 @@ When telemetry is enabled, Cline captures:
<Accordion title="Feature Usage" icon="cursor-click">
- Tools executed (e.g., read_file, execute_command)
- Slash commands used
- Skills triggered
- Workflows triggered
- Settings changed
</Accordion>
@@ -297,7 +297,7 @@ Now that you understand member management, proceed with configuring your organiz
<Card
title="Configure Providers"
icon="plug"
href="/enterprise-solutions/configuration/remote-configuration/overview"
href="/enterprise-solutions/configuration/choosing-your-deployment"
>
Set up API providers for your team to use
</Card>
+10 -1
View File
@@ -35,7 +35,7 @@ Now with summarization:
- You can work on much larger projects without interruption
<Tip>
Auto Compact works especially well for long-running tasks. Structured task lists can help maintain progress across summarizations so Cline can stay on track across multiple context windows.
Auto Compact works beautifully with [Focus Chain](/features/focus-chain). When Focus Chain is enabled, todo lists persist across summarizations. Cline can work on long-horizon tasks spanning multiple context windows while staying on track.
</Tip>
## Cost Considerations
@@ -44,6 +44,15 @@ Summarization leverages your existing prompt cache from the conversation, so it
Since most input tokens are already cached, you're primarily paying for summary generation (output tokens), making it cost-effective.
## Supported Models
Auto Compact uses advanced LLM-based summarization for these models:
- Claude 4 series
- Gemini 2.5 series
- GPT-5
- Grok 4
<Note>
With other models, Cline falls back to standard rule-based context truncation, even if Auto Compact is enabled.
</Note>
+51
View File
@@ -0,0 +1,51 @@
---
title: "Background Edit"
sidebarTitle: "Background Edit"
---
Background Edit lets Cline make file changes without opening the diff editor, so you can keep writing code while Cline works on other files in the background.
<Note>
This feature is marked as experimental.
</Note>
## How It Works
By default, Cline opens a side-by-side diff editor tab for each file it modifies. With Background Edit enabled:
- Edits write directly to your files without opening new tabs
- Changes appear as collapsible diff blocks in the chat panel
- Your editor focus stays on whatever file you had open
## Enabling Background Edit
1. Click the settings icon (gear) in the top-right corner of the Cline panel
2. Go to "**Feature Settings**"
3. Toggle "**Enable Background Edit**" on
## Viewing Changes
File changes display directly in the chat panel with:
- **File action icons** showing whether the file was added, updated, or deleted
- **Stats** showing additions (+) and deletions (-) at a glance
- **Collapsible diffs** you can expand or collapse by clicking the file header
- **Real-time streaming** as changes appear line-by-line
Green highlights additions, red highlights deletions.
## When to Use It
This feature works well when you:
- Use [auto-approve mode](/features/auto-approve) and prefer reviewing changes after the fact
- Work on tasks with many small file changes
- Want to stay focused on your current file
Stick with the default diff editor if you prefer reviewing each change before it saves, or need to make inline edits to Cline's proposed changes.
## Relationship with Other Features
- **Checkpoints**: Still created after each file operation
- **Auto-approve**: Pairs well for uninterrupted workflows
- **Message editing**: Restoring from a previous message works as expected
+129
View File
@@ -0,0 +1,129 @@
---
title: "Deep Planning"
sidebarTitle: "Deep Planning"
description: "Transform Cline into a meticulous architect who investigates your codebase and creates comprehensive implementation plans."
---
Deep Planning (`/deep-planning`) turns Cline into an architect before it becomes a builder. Instead of jumping straight into code, Cline systematically explores your codebase, asks targeted questions, and produces a detailed implementation plan — all before writing a single line.
<Tip>
**When should you use this?** Use `/deep-planning` for features that touch multiple files, architectural changes, complex integrations, or any task where "just start coding" would lead to rework.
</Tip>
## How It Works
Deep Planning follows a four-step process:
<Steps>
<Step title="Silent Investigation">
Cline explores your codebase without asking you anything. It reads relevant files, traces dependencies, examines patterns, and builds a mental model of how your project is structured. You'll see Cline reading files and running searches during this phase.
This step is intentionally silent — Cline gathers context first so it can ask better questions next.
</Step>
<Step title="Discussion">
Based on what it learned, Cline asks you targeted, specific questions about your requirements and preferences. These aren't generic questions — they're informed by what Cline found in your code.
For example, instead of asking "how should authentication work?", Cline might ask "I see you're using JWT tokens in `auth/middleware.ts` with refresh token rotation. Should the new endpoint follow the same pattern, or do you want session-based auth for this feature?"
Answer these questions to shape the plan. The more specific you are, the better the implementation plan will be.
</Step>
<Step title="Plan Creation">
Cline generates a comprehensive `implementation_plan.md` file in your project. This plan typically includes:
- **Overview** of the feature and its scope
- **File-by-file changes** with specific descriptions of what to add, modify, or remove
- **Dependencies** between changes (what needs to happen first)
- **Edge cases** and error handling considerations
- **Testing strategy** for the implementation
The plan is saved as a markdown file you can review, edit, and share with your team before any code is written.
</Step>
<Step title="Task Creation">
After you approve the plan, Cline creates a new task with the implementation steps loaded as trackable items. This gives you a clean context window focused entirely on execution, with the plan serving as the roadmap.
</Step>
</Steps>
## Using Deep Planning
### Invoking It
Type `/deep-planning` in the Cline chat input, followed by a description of what you want to build:
```
/deep-planning Add a notification system that sends email and in-app
notifications when users receive comments on their posts
```
The more context you provide upfront, the more focused the investigation phase will be. Include:
- What you want to build
- Any constraints or preferences
- Which parts of the codebase are relevant (if you know)
### Reviewing the Plan
Once Cline generates `implementation_plan.md`, review it carefully:
1. **Check the scope** — Does it cover everything you need? Is anything missing?
2. **Verify the approach** — Does the technical approach match your preferences?
3. **Review the order** — Are dependencies handled correctly?
4. **Edit if needed** — It's a markdown file. Change anything that doesn't look right.
Tell Cline about any adjustments before proceeding to implementation.
## Model-Specific Optimization
The deep planning prompt is optimized for each model family. Cline adapts its investigation and planning approach based on the strengths of whatever model you're using — whether that's Claude, GPT, Gemini, DeepSeek, or others.
This means you get effective deep planning regardless of your model choice, though stronger reasoning models will generally produce more thorough plans.
<Tip>
Consider using a stronger reasoning model for the planning phase and a faster model for implementation. You can configure separate models for Plan and Act modes in Cline Settings. See [Plan & Act Mode](/core-workflows/plan-and-act#using-different-models-for-each-mode) for details.
</Tip>
## Pairing with Other Features
Deep Planning works well with several other Cline features:
| Feature | How It Helps |
|---------|-------------|
| [Focus Chain](/features/focus-chain) | Tracks implementation progress against the plan with a visible todo list |
| [Memory Bank](/features/memory-bank) | Preserves project context across sessions so deep planning has richer input |
| [Plan & Act Mode](/core-workflows/plan-and-act) | Use Plan mode for quick exploration, deep planning for thorough architecture |
| [Checkpoints](/core-workflows/checkpoints) | Roll back implementation steps if something goes wrong during execution |
<Tip>
A powerful workflow: run `/deep-planning` to create the plan, enable [Focus Chain](/features/focus-chain) to track progress, then let Cline implement step by step. You get architecture-level thinking with granular progress visibility.
</Tip>
## Deep Planning vs Plan Mode
Both involve thinking before doing, but they serve different purposes:
| | Plan Mode | Deep Planning |
|---|-----------|---------------|
| **Scope** | Quick exploration and discussion | Thorough codebase investigation |
| **Output** | Conversation context | `implementation_plan.md` file |
| **Best for** | Medium tasks, understanding code | Large tasks, multi-file features |
| **Duration** | Minutes | Longer — depends on codebase size |
| **Persistence** | Lives in conversation history | Saved as a file you can reference later |
For most development work, starting in Plan mode is sufficient. Reserve `/deep-planning` for tasks where you'd normally spend significant time planning on a whiteboard before coding.
## Tips
- **Be specific in your initial prompt.** "Add authentication" gives a vague plan. "Add OAuth2 authentication with Google and GitHub providers, using our existing user model in `models/user.ts`" gives a focused one.
- **Point Cline at relevant files.** Use `@` mentions to highlight key files in your prompt so the investigation phase starts in the right place.
- **Edit the plan before implementing.** The generated plan is a starting point. Adjust priorities, remove unnecessary steps, or add details before Cline starts coding.
- **Save plans for reference.** The `implementation_plan.md` file is useful documentation even after the feature is built. Consider committing it or moving it to a docs folder.
- **Use for onboarding.** Run `/deep-planning` on a feature you're unfamiliar with to get Cline to map out the codebase and explain how things connect.
## Related
- [Plan & Act Mode](/core-workflows/plan-and-act) — Cline's dual-mode system for structured development
- [Focus Chain](/features/focus-chain) — Automatic todo list tracking for long-running tasks
- [Memory Bank](/features/memory-bank) — Structured documentation for cross-session context
- [Using Commands](/core-workflows/using-commands) — All available slash commands
+65
View File
@@ -0,0 +1,65 @@
---
title: "Focus Chain"
sidebarTitle: "Focus Chain"
description: "Automatic todo list management with real-time progress tracking for long-running tasks."
---
Focus Chain is automatic todo list management with real-time progress tracking. It helps Cline work on longer tasks by maintaining a visible checklist that persists across context window resets.
<Frame>
<img
src="https://storage.googleapis.com/cline_public_images/docs/assets/2dos.gif"
alt="Focus Chain todo list management with real-time progress tracking"
/>
</Frame>
## When to Use It
Focus Chain works best for:
- Multi-step implementations (building a feature end-to-end)
- Tasks that might span multiple context windows
- Work where you want visibility into Cline's plan
For quick, single-step requests, Focus Chain adds overhead without much benefit.
<Tip>
Focus Chain pairs well with [Deep Planning](/features/deep-planning). Use `/deep-planning` to create a detailed implementation plan, then let Focus Chain track progress as you execute it.
</Tip>
## Enabling Focus Chain
1. Click the gear icon in the Cline sidebar
2. Navigate to "Features"
3. Check "Enable Focus Chain"
4. Optionally adjust "Remind Cline Interval" (default: 6 messages)
| Setting | Default | Description |
|---------|---------|-------------|
| Enable Focus Chain | Disabled | Enables enhanced task progress tracking |
| Remind Cline Interval | 6 | How often Cline updates the todo list (1-100 messages) |
## How It Works
When you start a task with Focus Chain enabled, Cline:
1. Analyzes your request and creates a comprehensive todo list
2. Stores it as an editable markdown file
3. Updates progress in real-time as work progresses
4. Shows a progress indicator in the task header (e.g., "3/8")
The todo list uses standard markdown checklist syntax:
```markdown
- [x] Set up project structure
- [x] Install authentication dependencies
- [ ] Create user registration component
- [ ] Implement login functionality ← Currently working
- [ ] Add password validation
- [ ] Write authentication tests
```
## Editing Todo Lists
Need to adjust the plan? Click the edit button in the expanded todo view. A markdown file opens in your editor where you can add, remove, or reorder items. Save the file and Cline automatically detects your updates.
For complex projects, start with [Plan Mode](/core-workflows/plan-and-act) to discuss the approach before committing to a todo list.
+1 -1
View File
@@ -112,4 +112,4 @@ You can bind any of these commands to keyboard shortcuts for faster access:
## Related
- [All Cline Tools](/tools-reference/all-cline-tools) - Overview of all Cline tools
- [Cline provider](/getting-started/cline-provider) - Fastest way to get started with built-in provider setup
- [Model Selection Guide](/core-features/model-selection-guide) - Choosing the right model for your workflow
+222
View File
@@ -0,0 +1,222 @@
---
title: "Memory Bank"
sidebarTitle: "Memory Bank"
description: "A structured documentation system that helps Cline maintain context across sessions."
---
Memory Bank is a documentation methodology that transforms Cline from a stateless assistant into a persistent development partner. Through structured markdown files, Cline can "remember" your project details across sessions.
## Quick Setup
1. Copy the [custom instructions below](#memory-bank-custom-instructions)
2. Add to custom instructions or a [`.clinerules` file](/customization/cline-rules)
3. Ask Cline to "initialize memory bank"
## How It Works
Memory Bank files are regular markdown files in your project that both you and Cline can access. They're organized hierarchically to build a complete picture of your project:
```text
memory-bank/
├── projectbrief.md # Foundation document
├── productContext.md # Why this project exists
├── activeContext.md # Current work focus
├── systemPatterns.md # Architecture & patterns
├── techContext.md # Tech stack & setup
└── progress.md # Status & milestones
```
<Frame>
<img src="https://storage.googleapis.com/cline_public_images/docs/assets/image%20(16).png" alt="Memory Bank file hierarchy showing projectbrief.md at the top flowing into productContext, systemPatterns, and techContext, which feed into activeContext and progress" />
</Frame>
## Core Files
| File | Purpose |
|------|---------|
| `projectbrief.md` | Foundation document with core requirements and goals |
| `productContext.md` | Why the project exists, problems it solves, UX goals |
| `activeContext.md` | Current focus, recent changes, next steps (updates most frequently) |
| `systemPatterns.md` | Architecture, design patterns, component relationships |
| `techContext.md` | Tech stack, setup, constraints, dependencies |
| `progress.md` | What works, what's left, known issues |
## Key Commands
- **"follow your custom instructions"** - Tells Cline to read Memory Bank and continue where you left off
- **"initialize memory bank"** - Creates the initial structure for a new project
- **"update memory bank"** - Triggers a full documentation review and update
These work alongside Cline's built-in [slash commands](/core-workflows/using-commands). In particular, [`/newtask`](/core-workflows/using-commands#newtask) and [`/smol`](/core-workflows/using-commands#smol) help you manage context windows without losing progress.
## Working with Plan & Act Modes
Memory Bank pairs naturally with [Plan & Act mode](/core-workflows/plan-and-act):
- **Plan mode**: Start here when resuming a project. Ask Cline to read the Memory Bank, review the current state, and discuss strategy before making changes.
- **Act mode**: Switch to Act mode once you have a plan. Cline retains everything from the planning session and can implement changes.
For complex features, use [`/deep-planning`](/core-workflows/using-commands#deep-planning) to have Cline investigate your codebase and create a detailed implementation plan. The Memory Bank gives Cline the project context it needs to plan effectively.
## Managing Context Windows
Every AI model has a [context window](/core-workflows/task-management#context-window) that limits how much information it can process at once. As you work, this window fills with conversation history, file contents, and tool results. Memory Bank helps you preserve important knowledge when you need to free up space.
### Manual approach
When your context window fills up:
1. Ask Cline to "update memory bank" to document the current state
2. Start a new conversation
3. Ask Cline to "follow your custom instructions"
This preserves important context in your Memory Bank files before the window clears, letting you continue seamlessly in a fresh conversation.
### Using slash commands
Cline's built-in commands offer more targeted options:
- **[`/smol`](/core-workflows/using-commands#smol)** compresses your conversation history while keeping you in the same task. Use this when you want to free up space without starting over.
- **[`/newtask`](/core-workflows/using-commands#newtask)** distills key decisions, file changes, and progress into a fresh task with a clean context window. This is like a developer handoff that preserves what matters.
### Automatic context management
Enable [Auto-Compact](/features/auto-compact) to let Cline automatically compress context as you work. This reduces how often you need to manually manage the context window, though you should still update the Memory Bank after significant milestones.
<Frame>
<img src="https://storage.googleapis.com/cline_public_images/docs/assets/image%20(18).png" alt="Context window progress bar showing usage approaching the limit" />
</Frame>
## Memory Bank and Checkpoints
Memory Bank and [Checkpoints](/core-workflows/checkpoints) solve different sides of the same problem:
- **Memory Bank** preserves *knowledge*: project context, decisions, patterns, and progress across sessions.
- **Checkpoints** preserve *code state*: file snapshots you can restore if something goes wrong.
Together, they let you experiment freely. Checkpoints protect your code, and Memory Bank protects your understanding of the project. If you need to roll back code changes, your Memory Bank still has the context of what you were trying to do and why.
## Reducing Your Context Footprint
Memory Bank works best when your starting context is lean. If Cline loads your entire project into context, including dependencies, build artifacts, and generated files, you burn through tokens before the real work starts.
**Add a [`.clineignore`](/customization/clineignore) file.** This is the single biggest improvement most users can make. It tells Cline which files to skip when scanning your project. Adding one can drop your starting context from 200k+ tokens to under 50k, which means faster responses, lower costs, and the ability to use smaller models effectively.
**Keep Memory Bank files concise.** Each file adds to your context when Cline reads it at the start of a session. Keep `projectbrief.md` to one page, `activeContext.md` to current state only (not a running log), and `progress.md` to a summary rather than a detailed changelog. If a file grows beyond a page or two, split the detail into a separate doc and link to it. Cline can read linked files on demand.
**Use [Cline Rules](/customization/cline-rules) strategically.** Rules load into every request. Use [conditional rules](/customization/cline-rules#conditional-rules) to activate rules only when working with matching files, so frontend rules don't load when you're editing backend code.
## Best Practices
- Start with a basic project brief and let structure evolve
- Let Cline help create the initial structure
- `activeContext.md` changes most frequently; update it after each session
- `progress.md` tracks milestones; review it when resuming work
- Update after significant milestones or direction changes
- Use [Cline Rules](/customization/cline-rules) to store the Memory Bank instructions per-project
- Add a [`.clineignore`](/customization/clineignore) early to keep your starting context small
---
## Memory Bank Custom Instructions
Copy this into custom instructions or a `.clinerules` file:
```markdown
# Cline's Memory Bank
I am Cline, an expert software engineer with a unique characteristic: my memory resets completely between sessions. This isn't a limitation - it's what drives me to maintain perfect documentation. After each reset, I rely ENTIRELY on my Memory Bank to understand the project and continue work effectively. I MUST read ALL memory bank files at the start of EVERY task - this is not optional.
## Memory Bank Structure
The Memory Bank consists of core files and optional context files, all in Markdown format. Files build upon each other in a clear hierarchy:
### Core Files (Required)
1. `projectbrief.md`
- Foundation document that shapes all other files
- Created at project start if it doesn't exist
- Defines core requirements and goals
- Source of truth for project scope
2. `productContext.md`
- Why this project exists
- Problems it solves
- How it should work
- User experience goals
3. `activeContext.md`
- Current work focus
- Recent changes
- Next steps
- Active decisions and considerations
- Important patterns and preferences
- Learnings and project insights
4. `systemPatterns.md`
- System architecture
- Key technical decisions
- Design patterns in use
- Component relationships
- Critical implementation paths
5. `techContext.md`
- Technologies used
- Development setup
- Technical constraints
- Dependencies
- Tool usage patterns
6. `progress.md`
- What works
- What's left to build
- Current status
- Known issues
- Evolution of project decisions
### Additional Context
Create additional files/folders within memory-bank/ when they help organize:
- Complex feature documentation
- Integration specifications
- API documentation
- Testing strategies
- Deployment procedures
## Documentation Updates
Memory Bank updates occur when:
1. Discovering new project patterns
2. After implementing significant changes
3. When user requests with **update memory bank** (MUST review ALL files)
4. When context needs clarification
REMEMBER: After every memory reset, I begin completely fresh. The Memory Bank is my only link to previous work. It must be maintained with precision and clarity, as my effectiveness depends entirely on its accuracy.
```
## FAQ
**Custom instructions or .clinerules?**
Either works. Custom instructions apply globally across all projects. A [`.clinerules` file](/customization/cline-rules) is project-specific and stored in your repo, which makes it easy to share with collaborators. You can also use [conditional rules](/customization/cline-rules#conditional-rules) to activate Memory Bank instructions only when working with `memory-bank/` files.
**How often should I update?**
After significant milestones or direction changes. For active development, every few sessions. You can also let [Auto-Compact](/features/auto-compact) handle routine context management and reserve manual "update memory bank" for important checkpoints.
**How does Memory Bank relate to checkpoints?**
[Checkpoints](/core-workflows/checkpoints) save your code state (file snapshots). Memory Bank saves your project knowledge (context, decisions, progress). They complement each other: checkpoints let you roll back code, Memory Bank lets you pick up where you left off intellectually.
**How does Memory Bank relate to context window limitations?**
Memory Bank stores important information in structured files that Cline can load efficiently at the start of each session. This prevents context bloat while keeping critical information available. For more on how context windows work, see [Task Management](/core-workflows/task-management#context-window).
**Does this work with other AI tools?**
Yes. Memory Bank is a documentation methodology that works with any AI that can read docs. Commands may differ but the approach works across tools.
**Different from README files?**
Memory Bank provides structured, comprehensive documentation designed for AI context management, going beyond what a single README covers. It includes files for active context and progress tracking that change frequently, unlike a typical README.
For more information, see the [Memory Bank blog post](https://cline.bot/blog/memory-bank-how-to-make-cline-an-ai-agent-that-never-forgets).
## Related
- [Plan & Act Mode](/core-workflows/plan-and-act) - Separate thinking from doing with structured planning sessions
- [Checkpoints](/core-workflows/checkpoints) - Roll back code changes while keeping your conversation context
- [Cline Rules](/customization/cline-rules) - Define persistent instructions including Memory Bank setup
- [Task Management](/core-workflows/task-management) - Understand tasks, context windows, and when to start fresh
+1 -1
View File
@@ -111,7 +111,7 @@ For each workspace folder, Cline detects:
This means Cline understands that your frontend and backend might be at different commits, on different branches, or even use different version control systems.
<Note>
While Cline detects VCS information for all workspace folders, certain features only use the **primary workspace** (the first folder): [Cline rules](/customization/cline-rules), [skills](/customization/skills#triggering-skills-with-slash-commands), and [Git-related features](/core-workflows/working-with-files) like `@git` mentions.
While Cline detects VCS information for all workspace folders, certain features only use the **primary workspace** (the first folder): [Cline rules](/customization/cline-rules), [workflows](/customization/workflows), and [Git-related features](/core-workflows/working-with-files) like `@git` mentions.
</Note>
## Referencing Files Across Workspaces
+8 -2
View File
@@ -24,13 +24,17 @@ Subagent costs (tokens and API spend) are tracked separately per subagent and ro
## Enabling Subagents
Subagents are enabled by default. Cline decides when parallel research is worth the overhead — you don't need to opt in or call them out in your prompt. To turn subagents off, disable the `use_subagents` tool in Settings → Features → Agent.
Subagents are disabled by default. To turn them on:
1. Open Cline Settings (click the gear icon in the Cline panel)
2. Go to **Features**
3. Under the **Agent** section, toggle **Subagents** on
This setting applies across all editors (VS Code, JetBrains, CLI).
## Using Subagents
When subagents are enabled, Cline picks them up on its own when a task benefits from parallel exploration. You can also nudge it explicitly by asking for parallel research in your prompt.
Cline does not automatically decide to use subagents. You need to ask for them in your prompt. When the feature is enabled and you mention subagents (or describe a task that benefits from parallel exploration), Cline will use the `use_subagents` tool.
Example prompts:
@@ -45,6 +49,8 @@ You can also run only one subagent when the task is small enough that parallel d
Subagents follow the **Read project files** auto-approve permission. If you have "Read project files" enabled in [Auto Approve](/features/auto-approve), subagent launches will be auto-approved.
In [YOLO mode](/features/auto-approve#yolo-mode), subagents are always auto-approved.
If auto-approve is off, Cline will ask for your approval before launching subagents, showing you the prompts it plans to send.
## What Subagents Can Do
+55
View File
@@ -0,0 +1,55 @@
---
title: "Web Tools"
sidebarTitle: "Web Tools"
description: "Search the web and fetch content from URLs directly within Cline"
---
Web Tools give Cline the ability to search the internet and fetch content from specific URLs during your tasks. This is useful when you need up-to-date information, documentation lookups, or research that goes beyond your local codebase and the LLM's internal knowledge.
<Warning>
Web Tools require the **Cline provider**. They are not available when using other providers like OpenRouter, Anthropic, AWS Bedrock, etc.
</Warning>
## How Web Tools Work
Cline has two web tools:
- **web_search**: Searches the web and returns a list of relevant webpages based on your query
- **web_fetch**: Fetches and analyzes content from a specific URL
When Cline determines that web information would help complete your task, it will use these tools automatically. The tools call Cline's backend API, which handles the search or fetch operation and returns the results.
## Enabling Web Tools
Web Tools are available when using the Cline provider. To use them:
1. Make sure you're signed in to Cline
2. Ensure you're using the Cline provider
3. Enable the Web Tools toggle in the Feature Settings menu
<Note>
Web tools can be auto-approved using the "Use the browser" setting in [Auto Approve](/features/auto-approve).
</Note>
## Use Cases
### Looking Up Documentation
When working with unfamiliar libraries or APIs:
- Search for official documentation
- Fetch specific API reference pages
- Get examples and usage patterns
### Research Before Implementation
Before implementing a feature:
- Search for best practices and common patterns
- Find recent discussions about approaches
- Look up known issues or limitations
### Checking Latest Information
For time-sensitive information:
- Latest release notes and changelogs
- Recent bug fixes or security updates
- Current recommended versions
+274
View File
@@ -0,0 +1,274 @@
---
title: "Worktrees"
sidebarTitle: "Worktrees"
---
Worktrees let you work on multiple branches simultaneously, each in its own folder. This enables Cline to work on tasks in parallel across separate VS Code windows, or lets Cline work independently while you continue coding in your main workspace.
## What Are Git Worktrees?
A Git worktree is a linked copy of your repository in a separate folder, checked out to a specific branch. All worktrees share the same Git history and `.git` directory, but each has its own working directory with different code checked out.
Key concepts:
- **Main worktree**: Your original repository folder where the `.git` directory lives
- **Linked worktrees**: Additional folders you create, each checked out to a different branch
- **Shared history**: All worktrees share commits, branches, and Git configuration
<Tip>
Unlike regular branch switching, worktrees let you have multiple branches checked out at the same time in different folders. This means you can have VS Code windows open for different features simultaneously.
</Tip>
## Why Use Worktrees with Cline?
Worktrees solve a common problem: **Cline takes over your VS Code window while working on a task**. With worktrees, you can:
1. **Run Cline in parallel** - Have Cline work on multiple tasks simultaneously, each in its own worktree and VS Code window
2. **Keep working while Cline works** - Let Cline handle a task in a separate worktree while you continue coding in your main workspace
3. **Isolate experimental changes** - Test risky changes in a worktree without affecting your main branch
4. **Quick context switching** - Jump between features without stashing or committing incomplete work
## Getting Started
### Quick Launch (Recommended)
The fastest way to start using worktrees is the **New Worktree Window** button on Cline's home screen:
1. Click **New Worktree Window** on the home screen
2. Enter a branch name and folder path (defaults are auto-filled)
3. Click **Create & Open**
A new VS Code window opens with your worktree, and Cline automatically opens ready to work.
<Tip>
The home screen also shows your current branch and worktree path. Click it to open the full Worktrees view.
</Tip>
### Full Worktrees View
For more control, open the full Worktrees view by clicking the **Worktrees** button in the Cline sidebar header, or by clicking your current branch info on the home screen:
<Steps>
<Step title="Create a New Worktree">
Click **New Worktree** at the bottom of the view. Enter a branch name and path (defaults are auto-filled).
</Step>
<Step title="Open in New Window">
Once created, click the **Open in new window** button to open the worktree in a separate VS Code window. Cline will automatically open in the new window.
</Step>
</Steps>
## Typical Workflow
Here's how a typical worktree session looks:
<Steps>
<Step title="Create a new worktree">
Click **New Worktree Window** on the home screen or use the Worktrees view. A new VS Code window opens with Cline ready to go.
</Step>
<Step title="Do your work">
Work on your feature or let Cline handle a task. Make commits as you go.
</Step>
<Step title="Close the worktree window">
When you're done, close the worktree's VS Code window.
</Step>
<Step title="Merge from your primary worktree">
Back in your main VS Code window, open the Worktrees view and click the **merge button** on the worktree you just worked in. This merges the branch and optionally deletes the worktree.
</Step>
</Steps>
## Managing Worktrees
### Viewing Worktrees
The Worktrees view shows all worktrees for your repository:
- **Current**: The worktree you're currently in (highlighted)
- **Main**: The primary worktree where your `.git` directory lives (cannot be deleted)
- **Locked**: Worktrees that are locked to prevent accidental deletion
### Opening Worktrees
Each worktree has two open options:
- **Open in current window**: Replace your current workspace with the worktree
- **Open in new window**: Open the worktree in a separate VS Code window (recommended for parallel Cline sessions)
Either way, Cline automatically opens in the new workspace, ready to start a task.
### Deleting Worktrees
Click the trash icon on any linked worktree to delete it. A confirmation dialog will show you exactly what will be deleted:
- The branch itself
- All project files in the worktree folder
<Warning>
Deleting a worktree permanently removes the branch and all files in that folder. Make sure any important changes are committed and pushed first.
</Warning>
<Note>
You cannot delete the main worktree. It's the primary repository where your `.git` directory lives.
</Note>
### Merging Worktrees
When you're done working in a worktree and ready to merge your changes back to the main branch:
1. Click the **merge icon** (git merge symbol) on any linked worktree
2. Review the merge details in the confirmation modal
3. Choose whether to delete the worktree after merging
4. Click **Merge**
#### Handling Merge Conflicts
If your branch has conflicts with the main branch, Cline will detect them and show you the conflicting files. You have two options:
1. **Ask Cline to Resolve & Merge** - Creates a new Cline task with a prompt asking Cline to resolve the conflicts, complete the merge, and clean up the worktree
2. **Resolve Manually** - Close the modal and resolve conflicts yourself using your preferred Git tools
<Tip>
The "Ask Cline to Resolve" option is particularly useful for complex conflicts. Cline will analyze the conflicting files and attempt to merge them intelligently based on the intent of both branches.
</Tip>
## .worktreeinclude: Automatic File Copying
When you create a new worktree, it starts with a fresh checkout—no `node_modules`, no build artifacts, no IDE settings. This means you'd normally need to run `npm install` or similar setup commands.
The `.worktreeinclude` file solves this by automatically copying specified files to new worktrees.
### How It Works
1. Create a `.worktreeinclude` file in your repository root
2. Add glob patterns for files you want copied (using `.gitignore` syntax)
3. When Cline creates a new worktree, files matching **both** `.worktreeinclude` **and** `.gitignore` are copied automatically
<Note>
Only files that are both matched by `.worktreeinclude` AND listed in `.gitignore` are copied. This prevents accidentally duplicating tracked files.
</Note>
### Example `.worktreeinclude`
```gitignore
# Copy node_modules to avoid npm install
node_modules/
# Copy IDE settings
.vscode/
# Copy build cache
.next/
dist/
# Copy environment files (if gitignored)
.env.local
```
### Creating a `.worktreeinclude` File
The Worktrees view will show a tip if you don't have a `.worktreeinclude` file. If you have a `.gitignore`, you can click **Create from .gitignore** to create one pre-filled with your gitignore contents. Then edit it to keep only the patterns you want copied.
<Tip>
For most JavaScript/TypeScript projects, just including `node_modules/` in your `.worktreeinclude` saves significant setup time for each new worktree.
</Tip>
### Pro Tip: Symlink to .gitignore
Since `.gitignore` usually contains most of the files you'd want copied to new worktrees (dependencies, environment files, build caches, etc.), you can create a symlink so they stay in sync automatically:
```bash
# In your repository root
ln -s .gitignore .worktreeinclude
```
Now whenever you update your `.gitignore`, your `.worktreeinclude` will have the same patterns. This is especially useful for projects where gitignored files are exactly what you want copied—no need to maintain two separate files.
<Note>
If you need different patterns than your `.gitignore`, create a regular `.worktreeinclude` file instead of a symlink.
</Note>
## Best Practices
<AccordionGroup>
<Accordion title="For Parallel Cline Sessions">
1. **Create purpose-specific worktrees** - Name branches clearly (e.g., `cline/refactor-auth`, `cline/add-tests`)
2. **Open in new windows** - Always use "Open in new window" for true parallelism
3. **Use .worktreeinclude** - Set up automatic file copying to reduce setup time
</Accordion>
<Accordion title="For Solo Development">
1. **Keep your main branch clean** - Use worktrees for experimental or risky changes
2. **Quick feature switches** - Instead of stashing, create a worktree for interruptions
3. **Review in isolation** - Create worktrees to review PRs without disrupting your work
</Accordion>
<Accordion title="Worktree Hygiene">
1. **Delete unused worktrees** - Remove worktrees when their branches are merged
2. **Use meaningful names** - Branch names should indicate the worktree's purpose
3. **Check for stale worktrees** - Periodically review and clean up old worktrees
</Accordion>
</AccordionGroup>
## Limitations
Worktrees are not available in certain workspace configurations:
- **Multi-root workspaces**: If you have multiple folders open in VS Code, worktrees are disabled. Open a single repository folder instead.
- **Subfolder of a repository**: If you've opened a subfolder within a Git repository (not the root), worktrees are disabled. Open the repository root folder instead.
The Worktrees view will display a message explaining the limitation if either of these applies to your workspace.
## Using Worktrees with Cline CLI
Cline CLI's `--cwd` flag unlocks powerful command-line worktree workflows:
- **Parallel execution**: Run multiple Cline instances simultaneously in different worktrees
- **Context piping**: Pipe output from one worktree as input to another for iterative refinement
- **Combined with other features**: Use with `--config` for different models per worktree, or `--thinking` for deep analysis
Example:
```bash
# Run parallel tasks in different worktrees
cline --cwd ~/worktree-a -y "refactor authentication" &
cline --cwd ~/worktree-b -y "add unit tests" &
wait
```
For complete CLI worktree patterns and examples, see [Worktree Workflows](/cline-cli/samples/worktree-workflows).
## Troubleshooting
<AccordionGroup>
<Accordion title="Branch already exists error">
Git doesn't allow the same branch to be checked out in multiple worktrees. Either:
- Use a different branch name
- Delete the existing worktree using that branch
</Accordion>
<Accordion title="Worktree folder already exists">
The path you specified already contains files. Choose a different path or delete the existing folder first.
</Accordion>
<Accordion title="Can't delete worktree">
If a worktree is locked, you'll need to unlock it first using `git worktree unlock <path>` in the terminal. If the worktree has uncommitted changes, you may need to use force delete.
</Accordion>
<Accordion title=".worktreeinclude files not copying">
Make sure the files you want copied are:
1. Listed in your `.worktreeinclude` file
2. Also listed in your `.gitignore` (only gitignored files are copied)
3. Actually exist in your current worktree
</Accordion>
</AccordionGroup>
## Technical Details
<AccordionGroup>
<Accordion title="How Worktrees Work Internally">
- Worktrees are a native Git feature (`git worktree` command)
- All worktrees share the same `.git` directory and object database
- Each worktree has its own index, working directory, and HEAD
- Worktree list is stored in `.git/worktrees/`
</Accordion>
<Accordion title="Storage Considerations">
- Each worktree contains a full checkout of the repository
- `.worktreeinclude` can significantly increase worktree size (e.g., copying `node_modules`)
- Consider your disk space when creating many worktrees
</Accordion>
<Accordion title="Relationship with Checkpoints">
Worktrees are separate from Cline's [checkpoint system](/core-workflows/checkpoints). Each worktree has its own checkpoint history. Checkpoints track changes within a single worktree, while worktrees let you work across multiple branches simultaneously.
</Accordion>
</AccordionGroup>
Worktrees unlock true parallel development with Cline. Create a worktree, open it in a new window, and let Cline work independently while you continue coding!
+103 -29
View File
@@ -1,51 +1,100 @@
---
title: "Authorization"
title: "Authorization & Model Selection"
description: "Authenticate with Cline and choose your first AI model"
---
Cline connects to AI models through a **provider**. You have two paths:
- **Cline Provider** (recommended): sign in with Google/GitHub/email, no API key setup.
- **Bring Your Own Key (BYOK)**: use your own provider credentials (cloud or local runtimes).
<CardGroup cols={2}>
<Card title="Cline Provider" icon="bolt">
Sign in with Google, GitHub, or email. No API keys to manage — access multiple models with built-in billing, free options, and early access to new releases.
## Menu
**Best for:** Most users, fastest setup
</Card>
<Card title="Bring Your Own Key (BYOK)" icon="key">
Use 3rd party provider or API keys from Anthropic, OpenAI, OpenRouter, or any supported provider. Run models locally with Ollama or LM Studio for complete privacy.
- [IDE Setup](#ide-setup)
- [CLI Setup](#cli-setup)
**Best for:** Enterprise, custom billing, local models
</Card>
</CardGroup>
## IDE Setup
<Tip>
**Watch:** [Selecting Your Model](https://youtu.be/GuPmu5TVtfA) walks through choosing and configuring your first model.
</Tip>
## Setup Steps
<Steps>
<Step title="Open Cline Settings">
Click the settings icon (⚙️) in the Cline panel.
<Step title="Open Settings">
Click the settings icon in the top-right of the Cline panel.
</Step>
<Step title="Select Provider">
Choose your desired provider from the **API Provider** dropdown.
<Step title="Select a Provider">
Choose from the **API Provider** dropdown:
- **Cline** — simplest setup, no API key needed
- **OpenRouter** — many models, one API key
- **Anthropic** — direct Claude access
- **Ollama / LM Studio** — run models locally
</Step>
<Step title="Authenticate">
- **Cline Provider:** Click **Sign In** and complete OAuth.
- **BYOK cloud provider:** Paste your API key into the **API Key** field.
- **Local runtime (Ollama/LM Studio):** no key needed; ensure runtime is running.
**Cline Provider:** Click **Sign In** and authenticate via Google, GitHub, or email. See [OAuth details](#how-oauth-works) below.
**BYOK:** Paste your API key from your provider's dashboard.
**Local:** No key needed — just ensure your local server is running.
<Note>
API keys are stored in your system's credential manager and sent only to your selected provider. They are never logged or transmitted to Cline's servers.
</Note>
</Step>
<Step title="Select Model">
Choose your desired Claude model from the **Model** dropdown.
<Step title="Choose a Model">
Select a model from the **Model** dropdown. Consider:
- **Context window** — how much code the model can process at once
- **Speed** — smaller models respond faster
- **Cost** — varies by model; local models are free
</Step>
<Step title="Verify">
Send any message. If Cline responds, you're ready.
</Step>
</Steps>
## Provider Options
## Cline Provider
### Cline Provider
The Cline Provider gives you one account, one billing relationship, and access to models from Anthropic, OpenAI, Google, and more.
- One sign-in, no key management
- Built-in billing and free model options
- Access to multiple providers from one account
- **No API key juggling** — one sign-in, multiple models
- **Built-in billing** — add credits once, use across all models
- **Free models** — search "free" in the model selector to find no-cost options tagged **FREE**
- **Stealth models** — early access to new releases before they're widely available
- **Always current** — new models added as they launch
Add credits in Cline settings or at [app.cline.bot/dashboard](https://app.cline.bot/dashboard).
### Adding Credits
### BYOK (cloud + local)
Click **Add Credits** in Cline settings or visit your [account dashboard](https://app.cline.bot/dashboard). Credits work across all available models.
### How OAuth Works
<Steps>
<Step title="Sign In">
Click **Sign In** in Cline settings. Your browser opens to `app.cline.bot`.
</Step>
<Step title="Authenticate">
Choose Google, GitHub, or email.
</Step>
<Step title="Return to IDE">
After authentication, you're redirected back with an authorization code.
</Step>
<Step title="Secure Storage">
Tokens are stored in your IDE's native secret storage (VS Code Secrets, JetBrains Credential Store, etc.).
</Step>
</Steps>
## Bring Your Own Key (BYOK)
Use your own API keys when you need specific billing arrangements, higher rate limits, access to beta models, or local privacy.
### Cloud Providers
@@ -53,9 +102,9 @@ Add credits in Cline settings or at [app.cline.bot/dashboard](https://app.cline.
|----------|----------|-------------|
| **OpenRouter** | Multiple models, competitive pricing | [Setup](/provider-config/openrouter) |
| **Anthropic** | Direct Claude access | [Setup](/provider-config/anthropic) |
| **Claude Code** | Claude Max/Pro subscription | [Setup](/provider-config/anthropic) |
| **Claude Code** | Claude Max/Pro subscription | [Setup](/provider-config/claude-code) |
| **OpenAI** | GPT models | [Setup](/provider-config/openai) |
| **Google Gemini** | Gemini models | [Setup](/provider-config/google-gemini) |
| **Google Gemini** | Large context windows | [Setup](/provider-config/gcp-vertex-ai) |
| **AWS Bedrock** | Enterprise | [Setup](/provider-config/aws-bedrock/api-key) |
| **DeepSeek** | Great value | [Setup](/provider-config/deepseek) |
@@ -65,12 +114,26 @@ Run models on your own hardware for complete privacy and zero per-request costs.
| Provider | Best For | Setup Guide |
|----------|----------|-------------|
| **Ollama** | CLI-based local runtime | [Setup](/running-models-locally/overview#runtime-options) |
| **LM Studio** | GUI-based local runtime | [Setup](/running-models-locally/overview#runtime-options) |
| **Ollama** | Easy setup, wide model selection | [Setup](/running-models-locally/ollama) |
| **LM Studio** | GUI-based model management | [Setup](/running-models-locally/lm-studio) |
Local models require sufficient hardware (especially GPU memory). See [Running Models Locally](/running-models-locally/overview) for requirements.
## CLI Setup
## Which Model Should I Choose?
| Priority | Recommended Model |
|----------|-------------------|
| **Reliability** | Claude Sonnet 4 |
| **Value** | Qwen3 Coder |
| **Speed** | Cerebras GLm 4.6 |
| **Privacy** | Any Ollama/LM Studio model |
| **Existing subscription** | Claude Code with Max/Pro |
<Note>
Learn more about LLMs and models in [Chapter 2 of AI Coding University](https://cline.bot/learn).
</Note>
## CLI Authentication
```bash
# Authenticate from the terminal
@@ -80,7 +143,12 @@ cline auth
cline a
```
Runs the same auth flow as IDE setup.
Opens a browser for OAuth, same as the IDE extension. Your session persists until you sign out.
## Account Management
- **Balance & usage:** Open Cline settings — your credit balance is at the top. Click **View Usage** for transaction history.
- **Switch organization:** Go to Cline settings → **Switch Organization** to change which billing account is charged.
## Troubleshooting
@@ -90,3 +158,9 @@ Runs the same auth flow as IDE setup.
| Browser doesn't open | Check default browser settings. Copy the URL from the Cline output panel manually. |
| Frequent re-authentication | Check org security policies. Ensure you're not clearing IDE secrets. Try a full sign-out/sign-in. |
| Can't access organization | Verify membership at [app.cline.bot](https://app.cline.bot). Ask your admin about permissions. Sign out and back in. |
## Next Steps
- [Your First Project](/getting-started/your-first-project) — build something with Cline
- [Core Workflows](/core-workflows/task-management) — patterns you'll use daily
- [Customization](/customization/overview) — tailor Cline to your workflow

Some files were not shown because too many files have changed in this diff Show More