Skip to content
GitHubRSS

orchestrator/doctor.ts — the workspace doctor's facts

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 masked

InfoFacts 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, plugin project stage applied); a config that fails to load counts as zero and never fails the doctor — and is named in configErrors, with the loader’s message, because a 0 tasks that hides a typo is the fact a bug report needs.
  • The machine as the process may use it. workers and memory read util/cgroup.ts, so inside a container they say what the cgroup allows and name it as the source.
  • cacheDir follows the run’s rule: an override resolves against cwd exactly as vx run --cache-dir does, 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).