Agent skill
run-doctor
Run the GTM-OS health check across all 5 diagnostic layers (environment, database, configuration, provider connectivity, runtime state).
From Othmane-Khadri/YALC-the-GTM-operating-system · 61 skills · 290 · pushed 2026-08-20
What it does when it runs
Run the GTM-OS health check across all 5 diagnostic layers (environment, database, configuration, provider connectivity, runtime state). Use when the user says 'is YALC working', 'diagnose YALC', 'check YALC health', 'is everything configured', 'run the health check', or 'are my keys set up'. Read-only — never writes anything. Surfaces /keys/connect/<provider> URLs alongside any failed provider so the user has a one-click path to fix.
Read from the skill and the 1 file bundled beside it. A skill’s own description is written to be selected by an agent, so it describes the job and not the dependencies.
- Keys and connectors you must supply
- ANTHROPIC_API_KEY
- CRUSTDATA_API_KEY
- ENCRYPTION_KEY
- FIRECRAWL_API_KEY
- FULLENRICH_API_KEY
- INSTANTLY_API_KEY
- NOTION_API_KEY
- UNIPILE_API_KEY
- Hosts it reaches
- No third-party host appears in the skill or its bundled files.
- Tool permissions it declares
- No
allowed-toolsin the frontmatter. It does act, so it runs under whatever permissions your session already grants. - Actions present in the files
- shell
Install it
View source on GitHub ↗git clone --depth 1 --filter=blob:none --sparse https://github.com/Othmane-Khadri/YALC-the-GTM-operating-system.git /tmp/YALC-the-GTM-operating-system git -C /tmp/YALC-the-GTM-operating-system sparse-checkout set ".claude/skills/run-doctor" mkdir -p ~/.claude/skills/run-doctor cp -R "/tmp/YALC-the-GTM-operating-system/.claude/skills/run-doctor/." ~/.claude/skills/run-doctor/
Picked up without a restart. A project skill of the same name is shadowed by your personal one. For one repository only, swap ~/.claude/skills for .claude/skills. Claude Code docs ↗
The folder is the same in every client that implements the format — 46 of them — so if yours is not above, only the destination changes.
Before you install: this skill will not complete its job on a bare agent. It needs ANTHROPIC_API_KEY, CRUSTDATA_API_KEY, ENCRYPTION_KEY, FIRECRAWL_API_KEY, FULLENRICH_API_KEY, INSTANTLY_API_KEY, NOTION_API_KEY, UNIPILE_API_KEY, which you have to obtain separately.
The skill
Source on GitHub ↗Reproduced in full from Othmane-Khadri/YALC-the-GTM-operating-system/blob/5686d1f2f526346133f78eef3349fc5a655757b4/.claude/skills/run-doctor/SKILL.md, which is licensed MIT (repository). 1,122 words, 14 headings.
Run Doctor
I'll run the 5-layer health check and tell you what's missing. This is the read-only diagnostic that proves YALC is wired up correctly — environment file, SQLite schema, framework + user config, live provider connectivity, and runtime state. Nothing here writes to disk or burns credits.
When This Skill Applies
Use this skill when the user says:
- "is YALC working"
- "diagnose YALC"
- "check YALC health"
- "is everything configured"
- "run the health check"
- "are my keys set up"
NOT this skill (use debugger instead):
- A specific command failed — debugger walks the error funnel layer by layer.
- "fix", "not working", "broken", "troubleshoot" — those route to debugger.
NOT this skill (use setup instead):
- "set up YALC" — that's the onboarding flow.
What This Skill Does
- Imports the
runDoctorfunction fromsrc/lib/diagnostics/doctor.tsdirectly (no fresh CLI subprocess). - Captures the printed health check output by intercepting
console.logandprocess.exit. - Renders a clean per-layer summary: PASS / FAIL / WARN / SKIP for each check.
- For any FAIL'd or WARN'd provider, surfaces the matching
/keys/connect/<provider>URL (the URL hint A5 added). - Offers to walk you through fixing each failure — typically by opening the relevant
/keys/connect/...route in your browser viayalc-gtm dashboard --route /keys/connect/<provider>.
What This Skill Does NOT
- Modify env files, configs, or the database. Read-only.
- Send any external requests beyond the live provider probes that doctor itself runs.
- Auto-fix anything. All fixes need your approval.
Pre-flight (do this before step 1)
Onboarding interruption guard. Run:
test -f ~/.gtm-os/.in-flight-setup && echo "BLOCKED" || echo "OK"
If BLOCKED, surface a soft warning: setup is mid-flight and the diagnostic snapshot may be incomplete (config + DB are still being assembled). Since this skill is read-only and never writes anything, ask the user whether to (a) run anyway against the in-flight state, or (b) finish yalc-gtm setup --resume first and re-invoke. Default to (b) unless the user explicitly opts in to (a).
Workflow
Step 0: No user input needed
This is a read-only command. Skip straight to step 1.
Step 1: Generate the inline runner
Generate /tmp/yalc-skill-run-doctor.mjs from the gtm-os root (~/Desktop/gtm-os/). The runner imports runDoctor directly (the import-direct pattern from 0.13.0), monkey-patches console.log and process.exit so the output is collected as structured lines, and prints JSON to stdout.
Important — the import path must be absolute. tsx resolves relative imports against the script's own directory, not against cwd. Since the runner lives in /tmp/, a relative ./src/... import resolves to /tmp/src/... and fails. Build the runner with the absolute path baked in via heredoc expansion:
cd ~/Desktop/gtm-os && cat > /tmp/yalc-skill-run-doctor.mjs <<RUNNEREOF
import { runDoctor } from '\${PWD}/src/lib/diagnostics/doctor.ts'
const lines = []
const origLog = console.log
const origExit = process.exit
console.log = (...args) => {
lines.push(args.map((a) => (typeof a === 'string' ? a : JSON.stringify(a))).join(' '))
}
let exitCode = 0
process.exit = (code) => {
exitCode = typeof code === 'number' ? code : 0
}
let runError = null
try {
await runDoctor({ report: false })
} catch (err) {
runError = err instanceof Error ? { message: err.message, stack: err.stack } : { message: String(err) }
}
console.log = origLog
process.exit = origExit
process.stdout.write(JSON.stringify({ exitCode, runError, lines }, null, 2))
process.stdout.write('\n')
RUNNEREOF
Note: do not add a --json flag — runDoctor does not accept one; this wrapper is how we get JSON.
Step 2: Run it
From the gtm-os root (~/Desktop/gtm-os/):
npx tsx /tmp/yalc-skill-run-doctor.mjs
Step 3: Parse the JSON output
The runner emits { exitCode, runError, lines }. The lines array is the verbatim sequence of console.log calls doctor made — including the layer headers (── Environment ──, ── Database ──, etc.), the per-check rows ( ✓ [OK ] ANTHROPIC_API_KEY, ✗ [FAIL] Crustdata), and the summary block.
Parse it like this:
- A line starting with
──and ending with──opens a new layer. - A line starting with
✓ [OK ],✗ [FAIL],! [WARN], or✓ [SKIP]is a check row. The bracketed token is the status; the rest is the check name. - Indented lines (prefix
) that follow a non-PASS check carry the detail/explanation. - The summary lines (
X passed, Y failed, Z warnings, W skipped) appear under── Summary ──. - A trailing line of MCP-loader noise (
[mcp-loader] ...) may appear between the layer headers — ignore it.
Step 4: Render a clean diagnosis
Group checks by layer. For each layer, list the checks in order with their status. For any check whose detail contains Fix: http://localhost:3847/keys/connect/<provider>, surface the URL prominently next to the failing line.
See references/example-output.md for a full rendered example.
End the summary with the overall verdict: healthy / minor warnings / N issues need attention.
Step 5: Offer to fix any FAIL or provider-related WARN
For each FAIL or WARN row whose detail includes a /keys/connect/<provider> URL, ask the user:
"Want me to open
/keys/connect/<provider>in your browser? I'll runyalc-gtm dashboard --route /keys/connect/<provider>."
Don't run the dashboard command unless they say yes. The dashboard command (A2) starts the SPA on port 3847 and routes the user to the connect screen for that provider.
For non-provider failures (missing .env file, missing core tables, malformed YAML), surface the specific recovery hint the doctor itself emitted in the detail line — those are already actionable.
Step 6: Fallback path
If the inline runner errors out (e.g., the import path moves, the function signature changes, an unhandled exception escapes runDoctor), fall back to the CLI:
npx tsx src/cli/index.ts doctor
The CLI command takes only --report (no --json flag). Its stdout is the same human-readable output doctor would have printed; parse it the same way as the captured lines from the runner.
Notes
runDoctoraccepts only{ report?: boolean }. There is no{ json: true }option. The inline runner is the JSON wrapper.- The 5 layers are: Environment, Database, Configuration, Provider Connectivity, Runtime State. Two optional layers — Preview Confidence (when a
_preview/folder exists) and Retired Frameworks (when ≥1 retired framework is installed) — appear only when relevant. - Doctor never prints secrets. Env values are masked before any line is logged. Safe to re-render the lines verbatim.
- The
/keys/connect/<provider>URLs hard-codehttp://localhost:3847— they're only useful once the dashboard is running. - The runner's heredoc must use
'\${PWD}/...'(single-quoted with escaped$) so the shell expands$PWDon write but the resulting JS file contains a literal absolute path. Inside JS, plain string literal syntax — no template literal needed.
Files bundled with it
These load only when the skill asks for them, so they cost nothing until it runs.
Other skills for the same job
Different authors, same problem. Matched on the words in the skill name, across every library in the catalogue except this one.
- qual-doctor by octavehq · 11
Need help setting it up?
This page tells you what run-doctor does and what it needs. Cheetah builds the agent setup it runs inside: data, CRM, sequencing and the guardrails.
Book a call →The directory stays free. There is nothing gated behind this.