orchestrator/doctor.ts — the workspace doctor's facts
Purpose
Section titled “Purpose”One collector for what vx info prints and what @vzn/vx-mcp’s
getWorkspaceInfo returns, so the verb and the agent tool cannot
disagree: the CLI renders, this gathers.
collectInfo(cwd, { cacheDir?, warn? }): Promise<InfoFacts>stableSandboxReason(reason: string): string // the probe's reason with the pid-named socket path maskedInfoFacts is the typed object vx info --format json prints: vx,
bun, bunSupported (false below MIN_BUN — bun itself stays the
bare version because this is a machine surface, and the prose goes in
the rendered row only), git, gitStatusCache, workspaceRoot,
projects, tasks,
configErrors ([{ path, message }], the configs that did not load),
plugins ([{ name, seams }], the seams in PLUGIN_HOOKS order),
workers ({ count, source, cores, cpuQuota }), memory
({ usableBytes, totalBytes, cgroupLimitBytes }), cacheDir,
cacheVersion, schemaVersion, cacheEntries, cacheBytes,
orphans, runs24h, hits24h, flakyTasks, lockfile, sandbox
({ available, reason, declared }: whether this host can run an
exec.sandbox, the probe’s reason, and how many loaded tasks declare
one). See
docs/cli.md § vx info for what each row means.
- The task count is the run’s. It comes from the same staged load a
run uses (
loadProjects, pluginprojectstage applied); a config that fails to load counts as zero and never fails the doctor — and is named inconfigErrors, with the loader’s message, because a0 tasksthat hides a typo is the fact a bug report needs. - The machine as the process may use it.
workersandmemoryreadutil/cgroup.ts, so inside a container they say what the cgroup allows and name it as the source. cacheDirfollows the run’s rule: an override resolves againstcwdexactly asvx run --cache-dirdoes, else the workspace’s.
tests/show-info.test.ts (the rows and the JSON facts end to end, the
--cache-dir override, the orphans row) and @vzn/vx-mcp’s server test
(getWorkspaceInfo returns the same facts over the wire).