Skip to content

Follow up Cline upstream updates: required agent description, global modular rules, plugin-based hooks, deprecated .clinerules/.clineignore #2405

Description

@dyoshikawa

Summary

Cline's SDK/CLI config contract has moved: configured agents now require description (rulesync can emit files Cline refuses to load), global modular rules exist at ~/.cline/rules/ but rulesync drops them, hooks have converged on the documented plugin surface (which invalidates the rationale for closing #1847), .clinerules is literally named DEPRECATED_CONFIG_DIR upstream, and .clineignore is now documented as "deprecate soon".

Upstream baselines at time of research: Cline (VS Code) v4.0.11 (2026-07-24), Cline CLI v3.0.46 (2026-07-19), SDK v0.0.65 (2026-07-19).

Recent Releases

  • v4.0.0 (2026-06-26) — release — SDK-backed extension runtime, Cline Plugins, Customize marketplace, MCP file/format migration into shared settings.
  • v4.0.1 (2026-06-28) — release — the VS Code extension was rolled back to the pre-SDK (3.89.2) codebase; the SDK migration continues on main. This is why the shipping extension still resolves only the legacy .clinerules paths.
  • v4.0.11 (2026-07-24) — release — model additions only.
  • cli-v3.0.23 (2026-06-10) — "Added support for configured agents as subagent tools".
  • cli-v3.0.25 / v3.0.27 (2026-06-17) — MCP servers inside plugins; cline skill install/manage command.
  • Docs 0b0ca9b1 (2026-05-12, PR #10350) — deleted the 514-line file-hooks reference, leaving docs/customization/hooks a stub pointing at /sdk/plugins.
  • Docs b919a7e8 (2026-07-21, PR #12410) — .clineignore marked "deprecate soon".
  • Docs 9466fcc0 (2026-07-26, PR #12154) — hooks stub retitled "See details under SDK Plugins page".

Upstream path surface at v4.0.11

From resolve*ConfigSearchPaths() in sdk/packages/shared/src/storage/paths.ts (where .clinerules is literally the constant DEPRECATED_CONFIG_DIR) and apps/vscode/src/core/storage/disk.ts:

Surface SDK / CLI search paths VS Code (disk.ts)
rules AGENTS.md, .clinerules/, .cline/rules/, ~/.agents/AGENTS.md, ~/.cline/rules/, ~/Documents/Cline/Rules .clinerules, AGENTS.md, ~/Documents/Cline/Rules
workflows .clinerules/workflows, ~/Documents/Cline/Workflows, ~/.cline/workflows, .cline/workflows .clinerules/workflows, ~/Documents/Cline/Workflows
skills .clinerules/skills, .cline/skills, .agents/skills, ~/.cline/skills, ~/.agents/skills same + .claude/skills
agents .cline/agents, ~/.cline/agents (none — configured agents are SDK/CLI only)
hooks (files) ~/Documents/Cline/Hooks, ~/.cline/hooks, .clinerules/hooks, .cline/hooks .clinerules/hooks
plugins .cline/plugins, ~/.cline/plugins (not supported)
mcp ~/.cline/data/settings/cline_mcp_settings.json only extension settings file
permissions CLINE_COMMAND_PERMISSIONS env var only env var only

Gaps

1. subagents — Cline's agent frontmatter contract has moved past rulesync's

  • Upstream (sdk/packages/core/src/extensions/tools/team/configured-agent-config.ts, v4.0.11; feature landed cli-v3.0.23, 2026-06-10):

    const ConfiguredAgentFrontmatterSchema = z.object({
      name:        z.string().trim().min(1),
      description: z.string().trim().min(1),   // REQUIRED
      tools:       z.union([z.string(), z.array(z.string())]).optional(),
      skills:      z.union([z.string(), z.array(z.string())]).optional(),
      providerId:  z.string().trim().min(1).optional(),
      modelId:     z.string().trim().min(1).optional(),
      maxIterations: z.number().int().positive().optional(),
    })

    isYamlFile() accepts .yml and .yaml. A missing or empty description, or an empty body, makes parseConfiguredAgentConfig throw and the agent is skipped.

  • rulesync: project + global. ClineSubagentFrontmatterSchema (src/features/subagents/cline-subagent.ts) declares only name (required) and description (optional), and fromRulesyncSubagent emits whatever came in. Because canonical RulesyncSubagentFrontmatter (src/features/subagents/rulesync-subagent.ts) also has description optional, rulesync will happily write .cline/agents/<name>.yaml with no description — a file Cline refuses to load, with no warning from either side. tools / skills / providerId / modelId / maxIterations are reachable only through the untyped cline: escape section.

2. rules — global modular rules are silently dropped

  • Upstream: resolveRulesConfigSearchPaths() (v4.0.11) reads global rules from ~/.cline/rules/ and ~/Documents/Cline/Rules/ in addition to ~/.agents/AGENTS.md; the VS Code extension creates and reads ~/Documents/Cline/Rules (ensureRulesDirectoryExists in disk.ts). Docs: config ("~/.cline/rules/ — Global rules") and cline-rules.
  • rulesync: global returns only a root path — ~/.agents/AGENTS.md — and fromRulesyncRule throws for non-root rules in global mode (src/features/rules/cline-rule.ts). The --global dry-run emits one file and drops the four non-root rules that project mode emits, making Cline the only tool in the matrix with a 🌏 rules marker that cannot carry modular global rules.

3. hooks — upstream converged on the plugin surface, which invalidates #1847's close rationale

#1847 was closed not planned on 2026-07-24 because "the two active runtimes still expose incompatible discovery contracts" for file-based hook scripts. That remains true of the file-hook loaders, but the documented surface has moved:

  • docs/customization/hooks.mdx lost its entire 514-line file-hook reference on 2026-05-12 (commit 0b0ca9b1) and is now a two-line stub pointing at /sdk/plugins. The docs.cline.bot/features/hooks/hook-reference page cited in Add Cline hooks adapter (executable per-event scripts; needs multi-file output + executable-bit plumbing) #1847's triage no longer exists.
  • v4.0.0 (2026-06-26) shipped Cline Plugins as the supported extension mechanism, and the plugins docs document a single unambiguous discovery contract: .cline/plugins/ (project) and ~/.cline/plugins/ (global), .ts/.js modules exporting an AgentPlugin, with an explicit scope warning ("Cline SDK, CLI, and Kanban… not applicable on VSCode and JetBrains Extension for now").
  • Hook stages are enumerated at /sdk/plugins: input, runtime_event, session_start, run_start, iteration_start, turn_start, before_agent_start, tool_call_before, tool_call_after, turn_end, stop_error, iteration_end, run_end, session_shutdown, error; plugin objects expose beforeRun / afterRun / beforeModel / afterModel / beforeTool / afterTool / onEvent plus per-hook policies (mode, timeoutMs, retries, failureMode, …).
  • rulesync: unsupported — there is no src/features/hooks/cline-hooks.ts (the directory has 20+ other adapters), and the project dry-run emits no hook artifact.
  • rulesync already has the exact primitive needed: src/features/hooks/amp-plugin-generator.ts generates a JS/TS plugin module that shells out to the user's canonical hook commands, and src/features/hooks/pi-extension-generator.ts does the same for Pi.

4. rules / commands — the new .cline/* roots are not emitted (forward-looking)

  • Upstream: .cline/rules/ (project rules) and .cline/workflows/ (project workflows) are both in the v4.0.11 SDK/CLI search paths, and .cline/rules/ is documented at config. In the SDK path resolver .clinerules is the constant DEPRECATED_CONFIG_DIR.
  • rulesync: rules project → .clinerules/ only; commands project → .clinerules/workflows, global → ~/Documents/Cline/Workflows (src/constants/cline-paths.ts, src/features/commands/cline-command.ts).
  • Severity note: this is not currently broken. The rolled-back VS Code extension (v4.0.1 shipped the 3.89.2 extension code) reads only .clinerules and .clinerules/workflows, and the SDK/CLI reads both old and new roots — so rulesync's current output is the maximally compatible choice today. The gap is forward-looking.

5. ignore — .clineignore is officially on the way out

  • Upstream: the clineignore docs are now titled ".clineignore (deprecate soon)" (docs commit b919a7e8, 2026-07-21) with a warning that it "is not a security or access-control boundary… We're moving away from it as a supported feature." The documented replacement is not a config file but a plugin (sdk/examples/plugins/gitignore-read-files-guard.ts) that enforces via a beforeTool hook and reads .gitignore.
  • rulesync: project, straight .clineignore passthrough (src/features/ignore/cline-ignore.ts).

Proposed Follow-up

  1. Make description required in ClineSubagentFrontmatterSchema (or fail validation with an explicit message naming Cline's requirement), add typed optional tools / skills / providerId / modelId / maxIterations fields, and accept .yml alongside .yaml on import.
  2. Add a global nonRoot path for Cline rules writing ~/.cline/rules/*.md (read by CLI/SDK) and/or ~/Documents/Cline/Rules/*.md (read by both runtimes), keeping ~/.agents/AGENTS.md as the root file.
  3. Reopen the hooks question scoped to the plugin surface: add a cline-plugin-generator.ts emitting .cline/plugins/<name>.ts (project) and ~/.cline/plugins/<name>.ts (global), mapping rulesync events onto beforeTool / afterTool / beforeRun / afterRun. This targets one documented contract, needs no executable-bit or multi-file plumbing, and carries no duplicate-execution risk (the file-hook loaders never look at plugins/). Document the VS Code/JetBrains limitation that upstream itself documents.
  4. Track the .cline/rules + .cline/workflows migration and switch (or dual-emit with import from both) once the SDK-backed VS Code extension ships as stable. Also consider ~/.cline/workflows for global commands.
  5. No code change is forced for .clineignore yet, but the matrix should be qualified as a deprecated surface. The eventual replacement is the plugin surface from gap 3 — another reason to build the Cline plugin generator.

Minor / not gaps

  • mcp scope is correctsdk/packages/core/src/extensions/mcp/config-loader.ts resolves exclusively through resolveMcpSettingsPath()~/.cline/data/settings/cline_mcp_settings.json. docs/cli/cli-reference lists a project .cline/mcp.json and docs/mcp/mcp-overview lists ~/.cline/mcp.json, but neither appears in any v4.0.11 loader, so those doc lines look stale. rulesync's global-only mapping matches the code.
  • mcp entry shape — the canonical registration is now nested ({ transport: { type, command|url, … }, disabled, metadata, oauth }); the flat form rulesync writes is explicitly kept as legacy*RegistrationSchema and still parses. isMcpServers (src/types/mcp.ts) is permissive enough that nested entries round-trip untouched.
  • rules frontmatterpaths is the only evaluated conditional (rule-conditionals.ts: conditionalEvaluators = { paths }, unknown keys ignored). The alwaysApply / description keys rulesync writes are inert but harmless.
  • skills frontmatter — upstream requires exactly name + description (≤1024 chars); ClineSkillFrontmatterSchema matches.
  • permissions is an inert artifact — pre-existing design, not an upstream change. CommandPermissionController reads CLINE_COMMAND_PERMISSIONS from the environment and nothing else; no Cline code path loads .cline/command-permissions.json. rulesync knows this (src/features/permissions/cline-permissions.ts tells the user to export CLINE_COMMAND_PERMISSIONS=$(cat .cline/command-permissions.json)), but the README matrix's plain overstates it. Worth a doc qualification rather than a code change.
  • New surfaces with no rulesync feature dimension: cron/scheduled agents (.cline/cron/, ~/.cline/cron/) and agent teams (~/.cline/data/teams/).

Open questions / unconfirmed

  • Whether .cline/mcp.json (project) or ~/.cline/mcp.json ever functions: listed in docs/cli/cli-reference and docs/mcp/mcp-overview but absent from every v4.0.11 loader read. Treated as stale documentation.
  • Global workflows path: docs say ~/.cline/data/workflows/, paths.ts says ~/.cline/workflows. Code was preferred; the discrepancy is unconfirmed.
  • Whether the SDK-backed VS Code extension (reverted in v4.0.1) will re-land with the .cline/rules + .cline/workflows roots — no upstream statement of timing found. This gates gap 4.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    consideringenhancementNew feature or requestmaintainer-scrapRough notes for AI implementation. Not for human eyes.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions