DOCTOR EXTENSIONS
swamp doctor extensions verifies that user-defined extensions in a repository
load cleanly and inspects the catalog's aggregate state. It 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.
All commands accept the standard global flags (--json, --log, --no-color,
--quiet, --no-telemetry, --log-level, --show-properties, -h/--help).
Only command-specific flags are listed below.
Flags
| Flag | Description |
|---|---|
--repo-dir <dir> |
Repository directory (env: SWAMP_REPO_DIR). |
--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: PASSHealthy 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: PASSVerbose (--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: PASSRepair 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: PASSRepair 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 nameversion— installed versionorigin—"pulled"(from registry) or"local"(user-defined)sourceCount— total source files for this extensionstateDistribution— 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 rootstateTag— one of the RowState valuesfingerprint— content hash of the source filebundlePath— 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