You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
doctor: extend probeRoots() beyond 7/42 providers to kill the silent-zero class #899
#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:
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).
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.
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:
--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.
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):
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.
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.
Activity
therickfactr commentedon Aug 4, 2026
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:
--verboseadded 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:
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 betweendiscoverSessions()andprobeRoots()is the only way this stays honest as providers add overrides.The env vars a provider probes should match its
PROVIDER_ENV_VARSentry. Those feedcomputeEnvFingerprint, 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
doctorrun 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.
therickfactr commentedon Aug 4, 2026
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_VARSagainst the providers that implementprobeRoots()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,zerostackPlan — batches of 5-8 per your suggestion, first batch the Cline family and its closest cousins:
cline,roo-code,kilo-code,grok,pi,kimicopilot,devin,kiro,gemini,mistral-vibe,codebuffzed,zcode,zerostack,mux,openclaw,open-design,forge,session-messageThere is a nice symmetry in batch 1:
clineis the provider whose silence started #874, and it still has noprobeRoots()— 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:
probeRoots()calls the exact resolution helpers itsdiscoverSessions()uses, so the two can never drift. Where a provider factory takes an override, the test asserts the override comes back throughprobeRoots()— that is what proves one shared resolution rather than two lookalike ones.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 onmainso 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 frommain, 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 turndoctorinto 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.feat(doctor): probeRoots for six fixed-location providers (#899 Tier …
feat(doctor): probeRoots for 12 more providers (#899 Tier 1)
Merge pull request #903 from ozymandiashh/feat/899-proberoots-tier1
feat(doctor): probeRoots for five fixed-location providers (#899 Tier…
Merge pull request #1122 from avs-io/local/899-proberoots
fix(doctor): add probeRoots for seven filesystem-silent providers (#899)
test: pin that a provider-scoped run stamps the whole cache complete
iamtoruk commentedon Oct 7, 2026
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.