Skip to content

doctor: extend probeRoots() beyond 7/42 providers to kill the silent-zero class #899

Closed

Description

@ozymandiashh

Motivation

#874's real lesson was not the missing provider, it was the silence: Cline CLI usage was reported as $0.00 with no signal anywhere, not even --verbose, and the reporter had to reverse-engineer discovery to learn why. probeRoots() was added there so codeburn doctor can distinguish "tool not installed" from "override points at an empty directory" from "sessions found".

That capability currently covers 7 of the 42 providers. The other 35 keep the silent-zero failure mode: any of them whose data directory moves, whose env override is stale, or whose product update relocates storage will just quietly contribute nothing, and the user's headline will disagree with reality with no diagnostic anywhere.

Proposal

Extend probeRoots() across the provider fleet, in tiers:

  1. Tier 1 - env-overridable local-dir providers (the exact Cline provider misses every Cline CLI session (~/.cline/data/sessions, cline@3.0.49) — silently reported as $0.00 #874 shape): every provider with a PROVIDER_ENV_VARS entry should report its resolved root(s). The env override being wrong is the most common silent-zero cause and the cheapest to detect.
  2. Tier 2 - fixed-location providers: report the well-known path and whether it exists. Still valuable: product updates move storage (the ChatGPT desktop schema churn in Feature Request: ChatGPT desktop app provider support #234 is the extreme case of this class).
  3. Network providers: out of scope; their failure modes are auth errors, which already surface.

Each implementation is mechanical (return the resolved discovery roots with a label), so this is a good campaign to run incrementally: a batch of 5-8 providers per PR, doctor output reviewed once at the start for format.

If the direction is agreed, I can start with Tier 1 (the PROVIDER_ENV_VARS set minus the 7 already covered) and keep PRs small.

Activity

  1. therickfactr commented on Aug 4, 2026

    @therickfactr
    Contributor

    Reporter of #874 here — happy to take this if it is unclaimed.

    Concrete before/after from that report, since it makes the tiering argument better than I can in the abstract. Before, with the CLI installed and 18 sessions on disk, every surface said the same thing:

    $ codeburn export --format json --provider cline-cli --from ... --to ...
    {"Cost (USD)": 0, "API Calls": 0, "Sessions": 0}
    

    --verbose added nothing. There was no way to tell "not installed" from "installed, wrong root" without reading the provider source, which is exactly what I ended up doing.

    After, the same machine:

    │  Cline              │         0  │       -  │       0  │  NOTHING FOUND (tool likely not installed or no history yet)
    │  Cline CLI          │        18  │    8/8+  │      18  │  OK (18 sessions)
        Cline CLI sessions: /Users/<user>/.cline/data/sessions (exists)
    

    The (exists) marker is the part that does the work: a stale override shows the resolved path plus (missing), which is self-diagnosable without touching code.

    Your Tier 1 framing matches what I hit exactly. Two things I would add from doing it once:

    Resolve the root the same way discovery resolves it, including every override level. Cline CLI has a three-level chain (CLINE_SESSION_DATA_DIR → CLINE_DATA_DIR → CLINE_DIR → ~/.cline), and a probe that hardcodes the default would have reported a path discovery never actually reads — worse than no probe, because it looks authoritative. Sharing one resolver between discoverSessions() and probeRoots() is the only way this stays honest as providers add overrides.

    The env vars a provider probes should match its PROVIDER_ENV_VARS entry. Those feed computeEnvFingerprint, so a var that changes discovery but is missing from that list is a stale-cache bug hiding behind the same silence. Tier 1 is a good moment to catch mismatches in both directions; a test asserting the two lists agree per provider would keep them honest.

    One caution on Tier 2: a probe that only reports paths without an existence check is close to useless for this failure mode, and a probe that stats a large tree on every doctor run will get slow across 42 providers. Cheap (exists) on the root only, as Tier 1 does, seems like the right stopping point.

    Assign it to me and I will start with the Tier 1 sweep, one PR per batch of providers so the diffs stay reviewable.

  2. therickfactr commented on Aug 4, 2026

    @therickfactr
    Contributor

    Thanks @iamtoruk — taking this, and treating the assignment as covering the campaign rather than a single PR.

    Scope check first, so I do not collide with #903.

    Tier 1 is complete once #903 lands. I diffed PROVIDER_ENV_VARS against the providers that implement probeRoots() today plus the twelve in #903, and the remainder is empty — every env-overridable provider is covered. So Tier 1 needs nothing from me beyond review if you want a second pair of eyes on it.

    That leaves Tier 2: 20 providers. Fixed-location, excluding vercel-gateway (network, out of scope per the issue):

    cline, codebuff, copilot, devin, forge, gemini, grok, kilo-code, kimi, kiro, mistral-vibe, mux, open-design, openclaw, pi, roo-code, session-message, zcode, zed, zerostack

    Plan — batches of 5-8 per your suggestion, first batch the Cline family and its closest cousins:

    1. cline, roo-code, kilo-code, grok, pi, kimi
    2. copilot, devin, kiro, gemini, mistral-vibe, codebuff
    3. zed, zcode, zerostack, mux, openclaw, open-design, forge, session-message

    There is a nice symmetry in batch 1: cline is the provider whose silence started #874, and it still has no probeRoots() — the CLI half got one, the extension half never did. Its roots also make the Tier 2 case concretely: three VS Code variant globalStorage paths plus ~/.cline/data, four places to look and today no way to see which of them CodeBurn actually found.

    Two conventions I will follow from #903, since they are the right calls and worth stating so the campaign stays consistent:

    • Every probeRoots() calls the exact resolution helpers its discoverSessions() uses, so the two can never drift. Where a provider factory takes an override, the test asserts the override comes back through probeRoots() — that is what proves one shared resolution rather than two lookalike ones.
    • Report candidate roots before any existence filter, as you did for lingtai-tui. Dropping non-existent dirs is right for discovery and wrong for doctor, whose entire job is to show where it looked.

    Coordination: #903 is unmerged and creates tests/provider-probe-roots.test.ts. I will base batch 1 on it rather than on main so the test file has one owner and you do not get a merge conflict in it; if you would rather I wait for #903 to land first and branch from main, say so and I will. Either way I will not touch the twelve providers in your PR.

    One question on Tier 2 semantics: for providers whose discovery globs (e.g. ~/.gemini/tmp/<project>/chats), do you want the glob parent reported, or the resolved matches? Parent is cheap and stable; resolved matches are more useful but turn doctor into a directory walk. I lean parent-only, consistent with the "cheap existence check on the root" shape, and will go that way unless you prefer otherwise.

  3. added 2 commits that reference this issue on Aug 10, 2026
  4. added 2 commits that reference this issue on Aug 23, 2026
  5. added
    enhancementNew feature or request
    area: cliThe codeburn CLI and its core parsing/reporting engine
    status: has-prAn open pull request references this issue
    on Sep 14, 2026
  6. iamtoruk commented on Oct 7, 2026

    @iamtoruk
    Member

    probeRoots now covers every local provider (#903, #938, #1122, #1272), so doctor checks all of them. Closing as done. Thanks @ozymandiashh for the proposal and @therickfactr for the batches.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area: cliThe codeburn CLI and its core parsing/reporting engineenhancementNew feature or request

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions