mirror of
https://github.com/AgentSeal/codeburn.git
synced 2026-08-24 16:04:34 +00:00
The Cline CLI (npm `cline`, 3.x) stores sessions as <sessions>/<id>/<id>.json + <id>.messages.json. The existing `cline` provider only discovers tasks/<id>/ui_messages.json, so every CLI session was silently reported as $0.00 — no warning, not even under --verbose. Adds `cline-cli` as its own provider rather than a third root on `cline`, leaving the shared Cline-family parser (Roo Code, KiloCode, IBM Bob) untouched. It mirrors the CLI's own root resolution (CLINE_SESSION_DATA_DIR -> CLINE_DATA_DIR -> CLINE_DIR -> ~/.cline), implements probeRoots() so `doctor` can tell "not installed" from "wrong override", emits one call per assistant message's `metrics` block, and falls back to the session rollup when a session carries none. The fallback reads `usage`, not `aggregateUsage`, which folds in spawned subagents that are themselves separate session directories. Two supporting changes, both required for CLI costs to report correctly: - parser.ts re-priced cline-cli calls from tokens because the provider was not on the reported-cost allowlist, inflating a real 12-session local sample from $1.11 to $3.92. - session-cache.ts gains the matching PROVIDER_ENV_VARS entry (so a changed override invalidates) and a `reported-cost-v1` parse version (so sessions cached before the allowlist fix re-parse once instead of being re-priced forever). Cost is treated as metered only when actually present and non-negative, so a metered $0 stays reported while a missing or negative cost falls back to token pricing — applied identically on the per-message and rollup paths. Timestamps promote a seconds-resolution value rather than silently landing in 1970, matching the guard kiro.ts uses. CLINE_DIR / CLINE_DATA_DIR / CLINE_SESSION_DATA_DIR are added to the test env-isolation list so a developer's real sessions cannot bleed into fixtures. The VS Code variant discovery bug reported alongside this in #874 is deliberately NOT fixed here — it shipped in #882. Verified against 18 real local sessions: 142 calls, 4,934,762 input / 224,561 output tokens, and a cost matching the CLI's own metered total to the cent. `codeburn doctor` reports "Cline CLI OK". Refs: #874
58 lines
3.4 KiB
Markdown
58 lines
3.4 KiB
Markdown
# Cline CLI
|
|
|
|
The Cline command-line agent (npm `cline`, 3.x). Separate from the [Cline](cline.md) provider, which reads the VS Code extension's task tree.
|
|
|
|
- **Source:** `src/providers/cline-cli.ts`
|
|
- **Loading:** eager (`src/providers/index.ts`)
|
|
- **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:
|
|
|
|
```jsonc
|
|
"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.
|