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.
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
providerin the session file is the upstream LLM route (e.g.cline-pass), not the tool. The codeburn provider name is alwayscline-cli.- Model strings are not normalized by the CLI. The same model appears as
z-ai/glm-5.2,cline-pass/glm-5.2, andGLM-5.2across sessions, so pricing lookups may need amodel-alias. - Cost is reported per message, so
costIsEstimatedis false on the normal path; it falls back tocalculateCostonly when a message omitscost. - Rollup fallback. A session whose messages carry no metrics (interrupted, or an older layout) emits a single call from
metadata.usage. This readsusage, deliberately notaggregateUsage/aggregatedAgentsCost, which fold in spawned subagents that are themselves separate session directories and would double count. messages_pathis absolute and goes stale when a session directory is copied between machines, so the co-located<sessionId>.messages.jsonis preferred andmessages_pathis 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 theteam_*family.run_commandscarries a JSON-encoded array of command lines in a single string field.
When fixing a bug here
- Reproduce with a minimal session directory:
<id>.jsonplus<id>.messages.json. - Run
tests/providers/cline-cli.test.ts. - This provider shares no code with
vscode-cline-parser.ts— changes here cannot affect Cline, Roo Code, KiloCode, or IBM Bob.