* docs(cli): release the SDK before the CLI in the publish-cli skill
Add a Step 0 to the publish-cli skill that gates a CLI release on an SDK
release when the SDK changed since its last release, and relocate the
publish-cli skill to the repo root.
Why release the SDK alongside the CLI: the CLI bundles the SDK source via
workspace:*, so the CLI always ships the latest SDK code, but the hub
daemon stamps a buildId that defaults to the @cline/core version and a
running hub is only respawned when that buildId changes. Bumping the SDK
version forces a stale hub to be retired and respawned with the new code.
It also keeps SDK releases on a regular cadence in step with the CLI.
Step 0 covers detecting unreleased sdk/packages changes, bumping the
shared SDK version + llms CHANGELOG, committing to main, kicking off
sdk-publish.yml on the latest channel, and waiting for it before cutting
the CLI release. Also fixes the now-stale working-directory note (commands
run from the repo root, not sdk/) and updates the DEVELOPMENT.md path.
* chore: move opentui skill to repo root
Relocate the opentui TUI skill from apps/cli to the repo root, matching
the real-dir + symlink convention used by the other root skills (real dir
in .agents/skills, symlink from .claude/skills).
* docs(sdk): reformat the SDK changelog and move it to sdk/CHANGELOG.md
The changelog covers all SDK packages (they share one version and release
together), so move it from sdk/packages/llms/ to the SDK root, parallel to
apps/cli/CHANGELOG.md. Reformat to match the CLI changelog: a titled
header with flat, version-only sections, newest on top, no dates, and no
Next Release bucket. The unreleased entry that bucket held is captured
from commits when the next SDK release is drafted. Update the publish-cli
skill to draft SDK notes from commits and prepend a ## <version> section
at sdk/CHANGELOG.md.
* feat: update Fireworks model registry to improve Cline UX for Fireworks API users
The VS Code extension's Fireworks model list was significantly out of
date compared to the current active models available on the Fireworks
platform. This commit updates the registry to match the current model
lineup, ensuring users can select from the latest available models.
Changes:
- Default model: accounts/fireworks/models/kimi-k2p6 (was kimi-k2p5)
- SDK default: accounts/fireworks/models/kimi-k2p6 (was minimax-m2p5)
Removed 6 stale/phantom models no longer available:
- qwen3-vl-30b-a3b-thinking
- qwen3-vl-30b-a3b-instruct
- deepseek-v3p2
- glm-4p7
- glm-5
- minimax-m2p1
Added 9 missing models:
- accounts/fireworks/models/kimi-k2p6
- accounts/fireworks/routers/kimi-k2p6-turbo
- accounts/fireworks/models/deepseek-v4-flash
- accounts/fireworks/models/deepseek-v4-pro
- accounts/fireworks/models/glm-5p1
- accounts/fireworks/routers/glm-5p1-fast
- accounts/fireworks/models/minimax-m2p7
- accounts/fireworks/models/qwen3p6-plus
- accounts/fireworks/models/gpt-oss-20b
Fixed metadata for 3 overlapping models:
- kimi-k2p5: contextWindow 262144 → 256000, maxTokens 16384 → 256000
- minimax-m2p5: maxTokens 16384 → 196608
- gpt-oss-120b: maxTokens 16384 → 32768, cacheReadsPrice 0.01 → 0.015
All models now have cacheWritesPrice: 0 because Fireworks does not
charge a separate rate for prompt cache writes (cache writes are
billed at the standard input rate, matching the SDK catalog).
Three models remain in the UI but are scheduled for deprecation on
June 17 and will be removed then:
- accounts/fireworks/models/kimi-k2p5
- accounts/fireworks/models/minimax-m2p5
- accounts/fireworks/models/qwen3p6-plus
Files:
- apps/vscode/src/shared/api.ts
- apps/vscode/webview-ui/src/components/settings/__tests__/APIOptions.spec.tsx
- sdk/packages/llms/src/providers/builtins.ts
* fix: update qwen3p6-plus context window and maxTokens
* fix(cli): recover stale interactive sessions and suppress shutdown hook races
This fixes the CLI/TUI regression introduced between `3.0.14` and `3.0.15` where the interactive CLI could enter a broken state after stopping and restarting Cline Hub, then attempting to cancel a request with Escape.
The affected release window was:
- `49e8c1b32` / `v3.0.14`: known-good baseline
- `c33c3176e` / `v3.0.15`: release containing the regression
- `fad8271f4 feat: Cline Hub web app (#10969)`: relevant behavior change in the window
The Hub web app change introduced new Hub-backed runtime/session lifecycle behavior. After Ctrl+C or Hub shutdown, the CLI could still retain an `activeSessionId` that no longer existed in the Hub/runtime process. On the next interactive send, the CLI attempted to reuse that stale session and received `session not found`. Because cancellation also targeted the stale session, Escape stopped working and OpenTUI ended up receiving failures during input handling, which made the TUI look corrupted.
The same lifecycle issue also explains the Ctrl+C errors:
```text
error: hook dispatch failed: Hub connection closed (code=1006, reason=Connection ended)
error: WebSocket connection to 'ws://127.0.0.1:50168/hub' failed: Failed to connect
```
Those were caused by late hook dispatches racing against Hub shutdown. The CLI was still trying to send hook events over a Hub WebSocket that had already closed.
**What changed**
- Added missing-session recovery in the interactive runtime.
- Detects `session not found` / stale session errors.
- Reads any recoverable messages from the missing session.
- Clears the stale active session state.
- Starts a new interactive runtime session.
- Retries the current turn once against the fresh session.
- Made hook dispatch shutdown-aware.
- Runtime hooks now mark themselves as shutting down before session disposal.
- Hook dispatches are skipped once shutdown begins.
- Dispatch failures during shutdown are suppressed, since the Hub transport closing is expected at that point.
- Reordered CLI cleanup.
- Hooks are shut down before stopping/disposing runtime sessions.
- This prevents abort/stop lifecycle events from trying to dispatch over a closing Hub connection.
**Regression coverage**
Added tests for:
- Recovering from a disappeared active interactive session and retrying against a new session.
- Ensuring hook events are not dispatched after shutdown begins.
**Verification**
Passed:
```text
bunx vitest run apps/cli/src/utils/hooks.test.ts apps/cli/src/runtime/interactive/session-runtime.test.ts
bun -F @cline/cli typecheck
bun -F @cline/cli test:unit
bun -F @cline/cli test:e2e:cli:tui
git diff --check
```
* SessionNotFoundError
* fix(core): preserve stale session errors in hub runs
* clean up
---------
Co-authored-by: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com>
* feat(cli): add Slack socket mode support
Add socket mode as an alternative to webhook mode for Slack
connector, allowing connections without a public URL.
- Introduce `--connection` flag to select webhook or socket mode
- Add `--app-token` option for socket mode authentication
- Make signing secret and base URL conditional on webhook mode
- Add `parseSlackConnectionMode` with validation and tests
- Update CLI platform definition to support hybrid connection type
- Update README docs with socket mode usage examples
* use base-url and remove connection flag
* isSocketMode
* fix(core): use union schema for read files tool input validation
Move the normalizeReadFileRequests helper logic directly into the
read_files tool executor, replacing the legacy helper with inline
validation against ReadFilesInputUnionSchema. This ensures invalid
union inputs are rejected before reaching the executor.
Update tests to reflect validation behavior and add coverage for
rejecting invalid union inputs.
* add new schema support
* feat(llms,core): route custom registered handlers through the agent runtime
Expose the handler-registry helpers (hasRegisteredHandler, getRegisteredHandler,
getRegisteredHandlerAsync, isRegisteredHandlerAsync) from @cline/llms, and have
core's createAgentModelFromConfig consult the registry: when a handler is
registered for a provider, build it via createHandler and adapt its ApiHandler
surface onto the AgentModel contract (the inverse of the gateway's
toApiStreamChunk).
This lets hosts register provider handlers that need host-only dependencies
(e.g. a vscode.lm-backed handler) and have them used by the main agent loop,
not just standalone createHandler callers.
* fix(core): resolve registered handlers lazily and avoid double finish
Address review feedback:
- createAgentModelFromConfig built the handler eagerly with the sync
createHandler, which throws for providers registered via registerAsyncHandler.
The adapter now accepts a handler factory and resolves it on the first stream
via createHandlerAsync, supporting both sync- and async-registered handlers.
- Guard the adapter's catch-block finish with sawFinish so a handler that emits
an explicit done chunk and then throws does not produce two finish events.
* fix(core): preserve thought signatures and finish-reason semantics in adapter
Further review feedback on the ApiHandler -> AgentModel adapter:
- Reasoning and tool-call thought signatures are now surfaced under
metadata.thoughtSignature (the key downstream adapters read), instead of being
stored as metadata.signature / dropped.
- A done chunk whose incompleteReason indicates max output tokens now maps to
finish{reason:"max-tokens"} rather than "stop".
- A turn that ends with tool calls (no explicit done) now terminates as
finish{reason:"tool-calls"}, matching the gateway/AI-SDK adapters.
* Apply remaining changes
* fix(core): report lazy handler-factory rejection as a finish(error) event
The lazy handler resolution (await source()) ran outside the adapter's
try/catch, so a rejecting factory (e.g. when the host API is unavailable at
stream time) escaped as a raw generator exception instead of a terminal
finish{reason:"error"} event. Move the resolution inside the try block so all
failure paths converge on the same terminal finish.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
- user's who are signed in with oauth in old extension were not properly
migrating their token. this commit handles that
Co-authored-by: Max Paulus 🥪 <max@cline.bot>
* docs(sdk): add custom model provider plugin example
Add an OpenRouter-backed example plugin demonstrating the providers
capability and registerProvider. It registers an OpenAI-compatible
provider plus its model catalog with the gateway so the agent can run
inference against an endpoint Cline does not bundle.
Registers under a distinct id (openrouter-plugin) to avoid colliding
with the built-in openrouter provider.
* docs(sdk): drop redundant provider section from plugin examples readme
* docs(sdk): drop provider demo line from plugin examples readme
* fix: support plugin model providers
* docs: remove provider plugin demo
* docs: address provider example review
* Move the apps to the root dir
* Update all references from sdk/apps/ to apps/
* Update dependencies
* Install bun types
* Fix types
* Fix types
* Fix linter
* Ingore apps from vscode
* Fix security warning
* Fix windows install
* Enable windows dev mode
* Revert "Enable windows dev mode"
This reverts commit a46c99282e.
* Revert "Ingore apps from vscode"
This reverts commit 47f7b265d2.
* Revert "Fix windows install"
This reverts commit 1dabba1556.
* update the repo root
* fix root dir
* fix path
* fix other path
* Fix unrelated changes
* fix: address apps move follow-up blockers (#11228)
* fix: update root app command paths
* fix: include moved apps in root checks
* fix: clean up moved app path references
---------
Co-authored-by: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com>
* feat(cli): bundle and serve Cline Hub dashboard with cline dashboard
Add the @cline/cline-hub workspace dependency to the CLI and build the
Hub webview as part of CLI packaging. Copy the generated dashboard assets
into platform-specific CLI distributions so the dashboard is available in
built artifacts.
Refactor the Cline Hub server startup into an exported function so the CLI
can start and stop the dashboard server programmatically.
* fix(cli): resolve dashboard webview in wrapper installs
Detect the platform-specific CLI package from the published wrapper layout
and use its bundled cline-hub webview assets when no explicit dist path is
set. Add test coverage for resolving assets via CLINE_WRAPPER_PATH.
* patches
* patch
* fix server detachHub on stop
Imported detachHub.
Changed ClineHubDashboardServer.stop to () => Promise<void>.
Made stop() idempotent with a stopped guard.
Clears the health interval.
Calls server.stop(true).
Always calls await detachHub(ctx) in a finally, so hub client teardown still happens if the HTTP server stop throws.
---------
Co-authored-by: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com>
* fix(plugin-sandbox): expose CLINE_PLUGIN_IMPORT_TIMEOUT_MS env override
The hardcoded 4000 ms importTimeoutMs default is too tight on Windows
cold-start; the plugin-sandbox tests already use 30_000 ms for the same
reason. This patch lets hosts raise the ceiling via env var without
touching code or adding a CLI flag, with explicit options.importTimeoutMs
still taking precedence.
Precedence: options.importTimeoutMs > env var > 4000.
Refs: #11065
* fix(plugin-sandbox): tighten env parsing + use vi.stubEnv (PR feedback)
- Number.parseInt accepts trailing garbage ("4000ms" -> 4000); switch
to Number() + Number.isInteger() so malformed env values fall back
to the default instead of silently consuming the numeric prefix.
- Replace manual process.env save/restore in the regression test with
the idiomatic vi.stubEnv() / vi.unstubAllEnvs() pattern.
Per Greptile review on #11084.
* docs(sdk): add env-blocker plugin example
Adds a beforeTool hook plugin that deterministically blocks the agent
from reading .env secret files via read_files, editor, or run_commands
(e.g. cat .env), while leaving .env.example/.sample/.template readable.
Demonstrates moving a security policy out of an AGENTS.md rule (a
suggestion the model can ignore) and into the execution path.
* docs(sdk): install env-blocker globally in usage examples
A secret-protection guard is most useful applied to every project, so
drop the --cwd . project-scoped install in favor of the global default.
* docs(sdk): trim env-blocker usage docs
* docs(sdk): limit env-blocker to read paths only
It is a read blocker, so only guard read_files and run_commands.
Drop the editor case (and with it the symmetric apply_patch concern),
keeping the example focused and simple.
* docs(sdk): rename env-blocker helpers for readability
collectPaths -> extractFilePaths, collectCommands -> extractShellCommands
so the beforeTool call sites read clearly at a glance.
* docs(sdk): rename commandTouchesEnv to commandReadsEnv
* docs(sdk): drop console.error from env-blocker hook
* feat(plugin): support rule contributions in sandbox
Add plugin rule registration to the sandbox descriptor and handler state so
plugins can contribute static or dynamic rule content.
Update plugin installation to omit peer dependencies and use
legacy-peer-deps to avoid peer resolution failures during isolated installs.
* feat(cli): support participant mute targets in Discord
Resolve /mute and /unmute targets from Discord user mentions and raw
user IDs so a specific participant can be muted within a thread.
Update Discord system rules to guide agents toward thread-level and
participant-level mute commands, and add tests for target parsing.
* Update sdk/apps/cli/src/utils/chat-commands.ts
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* fix(cli): normalize addressed bot command suffixes
---------
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com>
* fix(cli): clear connector sessions on hub shutdown
* fix: stop Discord connector after repeated errors
Added error tracking to Discord connector to prevent spam:
- Tracks errors by message within a 1-minute window
- After 3 identical errors, shuts down connector instead of posting
- Prevents repeated error messages flooding Discord channels
- Logs shutdown reason for debugging
* fix: address Greptile feedback
1. Error tracker now per-thread (includes thread.id in key)
- Prevents cross-thread error aggregation
- One thread having errors will not kill the whole connector
2. Use fixed time window instead of sliding window
- Track firstSeen timestamp, not just lastSeen
- Prevents indefinite spam from errors every 61s
- Window properly resets after ERROR_WINDOW_MS from first error
3. Remove redundant delete in clearBindingSessionIds
- binding.state.sessionId already deleted in earlier block
- Cleanup was misleading/unnecessary
* feat: Cline Hub web app
Add a Cline Hub app for monitoring connected clients, viewing and driving sessions, streaming assistant output, and restarting the local hub. Document local, LAN, and tunnel usage with room-secret gating, ignore generated Cline cache/config data, and update lockfile entries.
* feat: Cline Hub UI
* feat: provider config schema
* run command update
* Use Workspace versions
* fix: rename routines to schedules
* feat(schedule): add routine summary and update support
Include last execution data in routine schedule overviews and cache the
summary state in the UI to reduce unnecessary reloads.
Add support for updating routine schedules from the hub server, validate
required fields, and trigger schedules asynchronously after confirming they
exist.
* UI for Connectors
* Fix UI switch for telemetryOptOut
* Expands Recent Sessions UI - allow title update
* feat: Cline Hub routes
* Add "health" and "version" routes
* Refactor server.ts nto 17 focused modules
* Provider Model list search box
* Extensions -> Customizations
* fix: restore discord connector catalog
* fix
---------
Co-authored-by: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com>
* feat(cli): support participant mute targets in Discord
Resolve /mute and /unmute targets from Discord user mentions and raw
user IDs so a specific participant can be muted within a thread.
Update Discord system rules to guide agents toward thread-level and
participant-level mute commands, and add tests for target parsing.
* patches
* update prompt
* fix(cli): stabilize core tests on Windows
Avoid several Windows-specific failure modes in the core CLI test suite.
Vitest already runs test files inside worker pools. The workspace file indexer was lazily spawning a nested worker from a transformed TypeScript module via import.meta.url, which is fragile on Windows and can cause Vitest to report only a generic worker fork crash. Disable that worker path under VITEST and use the deterministic fallback indexer for tests.
Quote process.execPath in bash executor shell-string tests. Windows Node/Bun paths commonly contain spaces, so unquoted command strings can fail under PowerShell or cmd even though they work on Unix paths.
Make detached hub probing defensive by routing probeHubServer calls through a safe wrapper, so rejected or malformed probe results are treated as unreachable instead of destabilizing startup/prewarm flows.
Also clear CLINE_RUN_AS_HUB_DAEMON in daemon test setup so tests do not inherit daemon-mode state from the surrounding CLI environment except where explicitly set.
Validation: bunx vitest run --config vitest.config.ts src/hub/daemon/index.test.ts src/services/workspace/file-indexer.test.ts src/services/workspace/mention-enricher.test.ts src/extensions/tools/executors/bash.test.ts --reporter=dot
Validation: bun run typecheck
Validation: bun run test:unit
* patch
* fix(cli): bind discord sessions to individual message authors
Resolve Discord participants from normalized message author data and persist
participant-specific thread state in bindings. Restore or create sessions per
participant so different Discord users do not accidentally share chat state.
Also add coverage for bot author handling and owner user configuration.
* patches
* fix(cli): steer active connector sessions across turn keys
Detect active connector turns by session ID when the current turn key
does not match, so replies steer the existing runtime session instead of
starting a duplicate session.
Also treat queued runtime turns as a non-error completion and log the
queued state for connector transports.
* fix(cli): steer active connector sessions across turn keys
Detect active connector turns by session ID when the current turn key
does not match, so replies steer the existing runtime session instead of
starting a duplicate session.
Also treat queued runtime turns as a non-error completion and log the
queued state for connector transports.
* add /idel
* fix(cli): bind discord sessions to individual message authors
Resolve Discord participants from normalized message author data and persist
participant-specific thread state in bindings. Restore or create sessions per
participant so different Discord users do not accidentally share chat state.
Also add coverage for bot author handling and owner user configuration.
* patches