Skip to content

Cline SDK 0.0.83

Released · Cline

Changes skills and plugins, hooks

What the release notes say

  • Hub-managed Agent Plugins. Packages under ~/.agents/plugins/* on the hub host are discovered and validated from their root plugin.json; valid skills under skills/ are exposed through the skills tool as plugin-name:skill-name, and stdio, Streamable HTTP, and legacy SSE servers from mcp.json are started without touching cline_mcp_settings.json. Workspace .agents/plugins directories are deliberately not scanned, so opening a repo cannot implicitly start repo-controlled MCP servers; extra roots require an explicit agentPluginPaths. Enablement lives in hub settings keyed by manifest name and publishes settings.changed, so clients no longer need their own loader or enablement store. Two bugs fixed along the way: settings.toggle({type: "skills"}) wrote a disabled key into a plugin skill's SKILL.md frontmatter, which the strict Agent Skills parser then rejected so the skill silently vanished until hand-edited; and InMemoryMcpManager.dispose() aborted on the first disconnect() rejection, leaking every remaining server's process
  • A model turn that dies mid-stream with a transient provider error is now retried up to 3 times with exponential backoff instead of failing the whole run — a single forwarded 429 previously aborted the run outright. Retryability is read from the AI SDK's typed signals, and a turn is never retried once it has streamed any text, reasoning, media, or tool call, so nothing is duplicated. Model calls also now allow 5 SDK-level retries for request-start 429/5xx/network failures, up from 2
  • Streaming is no longer throttled by hook forwarding. The hub proxied every runtime event to client-contributed onEvent hooks as a capability round trip carrying the full session snapshot, with the agent loop awaiting it — so each streamed token cost a few hundred KB of serialization, a persisted row, and a blocking IPC hop. Per-chunk text, reasoning, and tool-update deltas are no longer forwarded to remote onEvent hooks; every other event still reaches hooks unchanged. The hub event log also moved to synchronous = NORMAL, dropping one fsync per appended delta
  • Checkpoints no longer re-hash unchanged untracked files on every turn. Each turn built a throwaway git index, so git re-read every untracked file before each model call — with multi-GB untracked data in the workspace this blocked every message for seconds to minutes. A persistent per-session snapshot index lets git's stat cache skip unchanged files, so from the second turn a snapshot costs about one git process. Snapshot contents are byte-identical to before. A corrupt index now heals with one rebuild-and-retry that also clears a stale index.lock, where previously a git process killed mid-add degraded that session to HEAD-only checkpoints permanently
  • run_commands no longer hangs when a command backgrounds a child. The executor settled on the child's close event, which waits for the stdio pipes to drain; a backgrounded process (cmd &, nohup) holds the inherited write-ends open, so a finished command hung until the timeout killed the whole process tree. It now also settles on exit after a one-second grace period, reporting the exit code and the output collected so far
  • apply_patch "Add File" against a path that already exists is now rejected instead of silently overwriting it. Only UPDATE and DELETE targets were pre-loaded, so the parser's "File already exists" guard never saw ADD targets and the patch destroyed the file's contents with no error and no diff of what was lost
  • Nested PowerShell invocations are now unwrapped instead of being double-parsed. Command text is fed to PowerShell through a stdin bootstrap that the outer shell parses as PowerShell source, so a command written as powershell -Command "... $_ ..." had its argument interpolated before the nested shell ran — pipelines using $_ emitted one error per enumerated item, an error flood that looked like a hang, while the child still exited 0. Unwrapping is applied only when it is semantics-preserving: same PowerShell edition, -NoProfile, and an entirely quoted -Command tail; everything else passes through byte-identical
  • The run_commands tool description now names the actual PowerShell edition in use — Windows PowerShell (powershell.exe) versus PowerShell (pwsh.exe) or PowerShell (pwsh) — quotes its guidance against the resolved executable, and tells the model to write commands directly rather than wrapping them in another -Command or /c invocation. It also no longer claims "in Windows environment" when pwsh is the configured shell on macOS or Linux
  • No file index is built when the workspace root is the home directory or a filesystem root. Running from $HOME and typing an @ mention listed every file under home and re-ranked the whole index on each keystroke, driving the process to many GB of RSS until it was OOM-killed. Paths are canonicalized first so symlinked or differently-cased spellings still hit the guard
  • Credential fields are now stripped of Unicode control and format characters and surrounding whitespace before being saved. A key pasted with an invisible character (BOM, zero-width space, bidi mark) was stored corrupted and the provider returned a 401 indistinguishable from a genuinely wrong key, while masked rendering hid the corruption
  • The editor tool's error for a null old_text now names the file, says whether the parameter was null or omitted, and spells out the recovery. Models that fill optional parameters with null hit a terse "required" message and re-sent the identical call until the loop detector hard-stopped the run
  • Provider-native web search is now enabled by default in non-yolo sessions on supported provider/model combinations, instead of requiring tools.web_search.enabled = true. An explicit false still opts out, and the settings loader fails closed: web search stays disabled when a global settings file exists but cannot be read or parsed