Skip to main content

DOCTOR

swamp doctor runs diagnostics that verify a swamp repository's integrations are healthy. It has three subcommands:

  • audit — verifies the AI-tool audit integration
  • extensions — verifies user-defined extensions load cleanly and inspects catalog state
  • workflows — checks workflow YAML files load cleanly

Global flags

All subcommands accept these flags. Only subcommand-specific flags are listed in each section below.

Flag Description
--json Output in JSON format (non-interactive).
--log Force flat log output (no interactive tree).
--log-level <level> Set log level (trace, debug, info, warning, error, fatal).
-q, --quiet Suppress non-essential output.
--no-telemetry Disable telemetry for this invocation.
--show-properties Show structured properties in log output.
--no-color Disable colored output.
--repo-dir <dir> Repository directory (env: SWAMP_REPO_DIR).
-h, --help Show help.

doctor audit

Verifies that the AI-tool audit integration is healthy for the configured tool.

Flags

Flag Description
--tool <tool> Override the tool from .swamp.yaml. Values: claude, cursor, kiro, opencode, codex, copilot, none.

Exit codes

Code Condition
0 All audit checks pass.
1 One or more checks failed.

Output

Healthy

✓ binary-on-path  claude found at /Users/you/.local/bin/claude
✓ swamp-binary-on-path  swamp is on PATH at /opt/homebrew/bin/swamp
✓ agent-config-loadable  .claude/settings.local.json is present with both PostToolUse hooks wired
– default-agent-set  does not apply to claude
✓ recording-smoke-test  synthetic claude payload landed in today's audit JSONL

4 passed, 0 failed, 1 skipped — OVERALL: PASS

Failed check

When a check fails, a hint suggests a remediation:

✓ binary-on-path  cursor found at /Users/you/.local/bin/cursor
✓ swamp-binary-on-path  swamp is on PATH at /opt/homebrew/bin/swamp
✗ agent-config-loadable  .cursor/hooks.json is missing
    hint: Run `swamp init --tool cursor --force` to regenerate.
– default-agent-set  does not apply to cursor
✓ recording-smoke-test  synthetic cursor payload landed in today's audit JSONL

3 passed, 1 failed, 1 skipped — OVERALL: FAIL

JSON shape

{
  "tool": "claude",
  "overallStatus": "pass",
  "checks": [
    {
      "name": "binary-on-path",
      "status": "pass",
      "message": "claude found at /Users/you/.local/bin/claude",
      "details": {
        "binary": "claude",
        "path": "/Users/you/.local/bin/claude"
      }
    },
    {
      "name": "agent-config-loadable",
      "status": "pass",
      "message": ".claude/settings.local.json is present with both PostToolUse hooks wired"
    },
    {
      "name": "default-agent-set",
      "status": "skip",
      "message": "does not apply to claude"
    },
    {
      "name": "recording-smoke-test",
      "status": "pass",
      "message": "synthetic claude payload landed in today's audit JSONL"
    }
  ]
}

overallStatus is "pass" when all checks pass, "fail" otherwise.

Each entry in checks includes:

  • name — check identifier
  • status"pass", "fail", or "skip"
  • message — human-readable result
  • details — optional object with check-specific data
  • hint — present on failed checks when a remediation is available

Examples

swamp doctor audit                 # check the tool configured in .swamp.yaml
swamp doctor audit --tool kiro     # check a specific tool
swamp doctor audit --json          # machine-readable output for CI

doctor extensions

Verifies that user-defined extensions in a repository load cleanly and inspects the catalog's aggregate state. Checks each registry (model, vault, driver, datastore, report), summarises per-extension source health, detects orphaned catalog rows and bundle files, and optionally repairs the catalog.

Flags

Flag Description
--verbose Show per-source detail for each extension.
--repair Prune Tombstoned catalog rows and evict unreferenced bundle files.
--dry-run Preview repair operations without executing. Use with --repair.
-f, --force Skip the confirmation prompt. Use with --repair.

Exit codes

Code Condition
0 All registry checks pass.
1 One or more registry checks failed.

Output

No extensions installed

✓ model
✓ vault
✓ driver
✓ datastore
✓ report

Extension Catalog State
  0 total source(s) across 0 extension(s), 0 healthy (Indexed)


5 passed, 0 failed — OVERALL: PASS

Healthy catalog

✓ model
✓ vault
✓ driver
✓ datastore
✓ report

Extension Catalog State
  1 total source(s) across 1 extension(s), 1 healthy (Indexed)

  @swamp/[email protected] [pulled]  1 source(s)
    Indexed: 1

5 passed, 0 failed — OVERALL: PASS

Verbose (--verbose)

Adds a Per-Source Detail section listing every source file, its state tag, fingerprint, bundle path, and registry kind.

✓ model
✓ vault
✓ driver
✓ datastore
✓ report

Extension Catalog State
  1 total source(s) across 1 extension(s), 1 healthy (Indexed)

  @swamp/[email protected] [pulled]  1 source(s)
    Indexed: 1

Per-Source Detail
  vault .swamp/pulled-extensions/@swamp/1password/vaults/onepassword.ts  Indexed fp:3398bcef6091 bundle:.swamp/vault-bundles/a52f5a8b/onepassword.js

5 passed, 0 failed — OVERALL: PASS

Repair dry run (--repair --dry-run)

Previews what --repair would clean up without modifying the catalog.

✓ model
✓ vault
✓ driver
✓ datastore
✓ report

Extension Catalog State
  1 total source(s) across 1 extension(s), 1 healthy (Indexed)

  @swamp/[email protected] [pulled]  1 source(s)
    Indexed: 1

Repair DRY RUN
  Nothing to clean up — catalog is healthy.

5 passed, 0 failed — OVERALL: PASS

Repair apply (--repair or --repair --force)

Without --force, a confirmation prompt is shown before modifying the catalog. With --force, the prompt is skipped.

RowState values

Each source file in the catalog carries a state tag. The aggregate state section groups sources by these values.

State Meaning
Indexed Source is registered in the catalog and healthy.
Bundled Source has a compiled bundle but is not yet indexed.
BundleBuildFailed Bundle compilation failed. The source is registered but not usable.
ValidationFailed Source failed validation checks.
EntryPointUnreadable The source file's entry point cannot be read from disk.
OrphanedBundleOnly A bundle file exists with no corresponding catalog row.
Tombstoned Source has been removed but the catalog row remains. Pruned by --repair.

JSON shape

Base (--json)

{
  "overallStatus": "pass",
  "registries": {
    "model": { "registry": "model", "status": "pass", "failures": [] },
    "vault": { "registry": "vault", "status": "pass", "failures": [] },
    "driver": { "registry": "driver", "status": "pass", "failures": [] },
    "datastore": { "registry": "datastore", "status": "pass", "failures": [] },
    "report": { "registry": "report", "status": "pass", "failures": [] }
  },
  "orphanFiles": [],
  "aggregateState": {
    "aggregates": [
      {
        "name": "@swamp/1password",
        "version": "2026.04.22.2",
        "origin": "pulled",
        "sourceCount": 1,
        "stateDistribution": {
          "Indexed": 1,
          "Bundled": 0,
          "BundleBuildFailed": 0,
          "ValidationFailed": 0,
          "EntryPointUnreadable": 0,
          "OrphanedBundleOnly": 0,
          "Tombstoned": 0
        }
      }
    ],
    "sourceDetails": [],
    "catalogOrphans": [],
    "bundleOrphans": [],
    "totalSources": 1,
    "healthySources": 1,
    "orphanRowCount": 0,
    "orphanBundleFileCount": 0
  }
}

overallStatus is "pass" when all registries pass, "fail" otherwise.

Each entry in aggregates includes:

  • name — extension name
  • version — installed version
  • origin"pulled" (from registry) or "local" (user-defined)
  • sourceCount — total source files for this extension
  • stateDistribution — count of sources in each RowState

Verbose (--json --verbose)

sourceDetails is populated with per-source entries:

{
  "sourceDetails": [
    {
      "sourcePath": ".swamp/pulled-extensions/@swamp/1password/vaults/onepassword.ts",
      "stateTag": "Indexed",
      "fingerprint": "3398bcef6091...",
      "bundlePath": ".swamp/vault-bundles/a52f5a8b/onepassword.js",
      "kind": "vault"
    }
  ]
}

Each source detail includes:

  • sourcePath — path to the source file relative to the repository root
  • stateTag — one of the RowState values
  • fingerprint — content hash of the source file
  • bundlePath — path to the compiled bundle (if any)
  • kind — registry kind (model, vault, driver, datastore, report)

Repair (--json --repair --dry-run)

Adds a repairReport object:

{
  "repairReport": {
    "mode": "dry-run",
    "operations": [],
    "prunedRowCount": 0,
    "evictedFileCount": 0
  }
}

mode is "dry-run" or "applied". Each entry in operations describes a pruned catalog row or evicted bundle file. prunedRowCount and evictedFileCount are totals.

Examples

swamp doctor extensions                    # check this repo's extensions
swamp doctor extensions --json             # machine-readable output for CI
swamp doctor extensions --verbose          # show per-source detail
swamp doctor extensions --repair --dry-run # preview what repair would clean up
swamp doctor extensions --repair           # apply repair (with confirmation)
swamp doctor extensions --repair --force   # apply repair without prompting

doctor workflows

Checks that workflow YAML files in a repository load cleanly.

Exit codes

Code Condition
0 All workflows load successfully.
1 One or more workflows failed.

Output

No workflows

Checking workflows...
  No workflow files found

0 passed, 0 failed — OVERALL: PASS

Healthy

Checking workflows...
  ✓ hello

1 passed, 0 failed — OVERALL: PASS

Validation failure

When a workflow has schema errors, the validation messages are shown inline:

Checking workflows...
  ✗ broken
    → [
  {
    "expected": "string",
    "code": "invalid_type",
    "path": [
      "id"
    ],
    "message": "Invalid input: expected string, received undefined"
  },
  {
    "expected": "array",
    "code": "invalid_type",
    "path": [
      "jobs"
    ],
    "message": "Invalid input: expected array, received object"
  }
]
  ✓ hello

1 passed, 1 failed — OVERALL: FAIL

JSON shape

Healthy

{
  "overallStatus": "pass",
  "workflows": [
    {
      "file": "workflows/workflow-....yaml",
      "name": "hello",
      "status": "pass"
    }
  ],
  "totalPassed": 1,
  "totalFailed": 0
}

Failed

{
  "overallStatus": "fail",
  "workflows": [
    {
      "file": "workflows/broken.yaml",
      "name": "broken",
      "status": "fail",
      "error": "[\n  {\n    \"expected\": \"string\",\n    ...\n  }\n]"
    },
    {
      "file": "workflows/workflow-....yaml",
      "name": "hello",
      "status": "pass"
    }
  ],
  "totalPassed": 1,
  "totalFailed": 1
}

Each entry in workflows includes:

  • file — path to the workflow YAML file
  • name — workflow name from the YAML
  • status"pass" or "fail"
  • error — present on failed workflows, contains the validation error

Examples

swamp doctor workflows       # check all workflows
swamp doctor workflows --json # machine-readable output for CI