codeburn/docs/providers/cline-cli.md
iamtoruk d64b29f64d feat(cli): rehome the cline-cli provider into the workspace layout
Upstream `main` ships a provider this branch has no counterpart for: the
Cline CLI (npm `cline`, 3.x), whose sessions live in a layout unrelated to the
VS Code extension tree `cline.ts` reads. Files added on one side only produce
no merge conflict, so a `main` merge would happily create `src/providers/
cline-cli.ts` — a path npm workspaces does not build and no registry imports.
Green build, and a whole provider quietly does not exist.

Ported from #940 (@ozymandiashh), which carried it faithfully: identical dedup
keys, all 34 upstream test cases, and the clean phase-8 split — discovery and
file I/O host-side, pure record decode in @codeburn/core, registered next to
its neighbours and deliberately separate from the shared vscode-cline tier.

Two changes on top of that port:

  - `observations.ts` follows the post-#1074 conventions: the model is routed
    through `normalizeModelIdentifier` at the observation boundary like every
    other provider, and measured cost is carried the way the sibling decoders
    carry it rather than through a cast.

  - the estimated-cost path reports zero web-search requests. Upstream prices
    that path with a hardcoded 0; letting the decoded `fetch_web_content`
    count reach the pricing pass would bill $0.01 per fetch on top of tokens,
    a billing change nobody asked for. A metered call keeps the real count —
    its dollar figure comes from the CLI, so nothing prices off it.

DAILY_CACHE_VERSION takes 27 (MIN_SUPPORTED 27): every historical Cline CLI
session contributes usage no older rollup ever contained, and usage-aggregator
serves every day before today from that cache for ten years, so without the
bump an upgrading user would keep cline-cli-less history forever while today's
numbers silently included it.
2026-08-21 13:27:57 -07:00

3.4 KiB

Cline CLI

The Cline command-line agent (npm cline, 3.x). Separate from the Cline provider, which reads the VS Code extension's task tree.

  • Source: src/providers/cline-cli.ts
  • Loading: eager (src/providers/index.ts:3)
  • Test: tests/providers/cline-cli.test.ts

Where it reads from

One root, resolved exactly as the CLI resolves it — each level independently overridable:

Level Env var Default
sessions CLINE_SESSION_DATA_DIR <data>/sessions
data CLINE_DATA_DIR <root>/data
root CLINE_DIR ~/.cline

A directory is a session only when it contains <sessionId>/<sessionId>.json. probeRoots() reports the resolved sessions dir, so codeburn doctor distinguishes "CLI not installed" from "override pointing somewhere else".

Storage format

sessions/<sessionId>/
  <sessionId>.json           metadata + rolled-up usage
  <sessionId>.messages.json  per-message metrics

<sessionId>.json carries session_id, provider, model, cwd, workspace_root, started_at / ended_at, messages_path, and a metadata.usage rollup (inputTokens, outputTokens, cacheReadTokens, cacheWriteTokens, totalCost).

<sessionId>.messages.json holds { version, updated_at, agent, sessionId, messages[], system_prompt }. Assistant messages carry Anthropic-style content blocks (thinking / text / tool_use) plus:

"modelInfo": { "id": "z-ai/glm-5.2", "provider": "cline-pass" },
"metrics": { "inputTokens": 6937, "outputTokens": 213,
             "cacheReadTokens": 0, "cacheWriteTokens": 0, "cost": 0.002108502 }

One metrics block becomes one parsed call. Dedup key: cline-cli:<sessionId>:<messageId>.

Caching

None at the provider level; the metadata file is the cached source path and the normal parser/cache layers apply.

Quirks

  • provider in the session file is the upstream LLM route (e.g. cline-pass), not the tool. The codeburn provider name is always cline-cli.
  • Model strings are not normalized by the CLI. The same model appears as z-ai/glm-5.2, cline-pass/glm-5.2, and GLM-5.2 across sessions, so pricing lookups may need a model-alias.
  • Cost is reported per message, so costIsEstimated is false on the normal path; it falls back to calculateCost only when a message omits cost.
  • Rollup fallback. A session whose messages carry no metrics (interrupted, or an older layout) emits a single call from metadata.usage. This reads usage, deliberately not aggregateUsage / aggregatedAgentsCost, which fold in spawned subagents that are themselves separate session directories and would double count.
  • messages_path is absolute and goes stale when a session directory is copied between machines, so the co-located <sessionId>.messages.json is preferred and messages_path is only the fallback.
  • Tool names differ from the extension's. run_commands, read_files, search_codebase, editor, apply_patch, fetch_web_content, skills, spawn_agent, and the team_* family. run_commands carries a JSON-encoded array of command lines in a single string field.

When fixing a bug here

  1. Reproduce with a minimal session directory: <id>.json plus <id>.messages.json.
  2. Run tests/providers/cline-cli.test.ts.
  3. This provider shares no code with vscode-cline-parser.ts — changes here cannot affect Cline, Roo Code, KiloCode, or IBM Bob.