Releases: systeminit/swamp
swamp 20260318.203746.0-sha.e3308e87
What's Changed
- feat: port Batch 2 commands to libswamp + renderer pattern (#765)
Summary
- Port ~12 List/Versions/Validate/Stats commands to the async generator + renderer architecture (part of #739)
- Migrated:
data list,data versions,vault list-keys,extension list,model validate,workflow validate,workflow schema,workflow history logs,model method history logs,model output logs,model output data,telemetry stats - Each command gets a typed event generator in
src/libswamp/, Log+Json renderers insrc/presentation/renderers/, and unit tests for both layers - Old
src/presentation/output/files and their tests removed
Test Plan
- All 3319 existing tests pass
- New generator unit tests verify event streams with fake deps
- New renderer tests verify log and JSON output parity
deno fmt,deno lint,deno checkall pass
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.203746.0-sha.e3308e87/swamp-darwin-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/macOS (Intel):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.203746.0-sha.e3308e87/swamp-darwin-x86_64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/Linux (x86_64):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.203746.0-sha.e3308e87/swamp-linux-x86_64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/Linux (aarch64):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.203746.0-sha.e3308e87/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260318.193004.0-sha.bf464c17
What's Changed
- feat: add --content-type filter to extension search (#764)
Summary
Closes #754
Adds a --content-type filter flag to swamp extension search so users can narrow results by content type (models, workflows, vaults, datastores, drivers). This leverages the new contentType query parameter added to the swamp-club API in swamp-club#281.
What changed
- API client: Added
contentType?: string[]toExtensionSearchParamsandcontentTypes?: string[]toExtensionSearchEntry. ThesearchExtensionsmethod serializes content type values as repeated query params (same pattern asplatformandlabel). - CLI: Added
--content-type <contentType:string>option withcollect: true. Values are validated against the allowed set with a clear error message on invalid input. - Presentation: Content types are displayed in the interactive detail view and included in JSON output (omitted when empty, matching the platforms/labels pattern).
User impact
Before this change, users had no reliable way to find extensions containing specific content types — they had to rely on keyword matching which was unreliable. Now they can run:
# Find all extensions that contain models
swamp extension search --content-type models
# Find extensions with both workflows and datastores
swamp extension search --content-type workflows --content-type datastores
# Combine with other filters
swamp extension search --content-type models --platform aws --label networkingTest plan
-
deno check— type checking passes -
deno lint— no lint errors -
deno fmt— formatting correct -
deno run test— all 38 tests pass (7 new tests added) -
deno run compile— binary compiles
New tests cover:
- Invalid content type value throws
UserError - Valid content type values are accepted
contentTypearray params appended correctly to URLcontentTypesrenders in JSON output when presentcontentTypesomitted from JSON when empty
🤖 Generated with Claude Code
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.193004.0-sha.bf464c17/swamp-darwin-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/macOS (Intel):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.193004.0-sha.bf464c17/swamp-darwin-x86_64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/Linux (x86_64):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.193004.0-sha.bf464c17/swamp-linux-x86_64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/Linux (aarch64):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.193004.0-sha.bf464c17/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260318.183528.0-sha.8855e7df
What's Changed
- fix: allow multi-line Zod chain methods in content extractor (#763)
Summary
- Fix
parseZodObjectFieldschain-method regex to allow whitespace/newlines
before chained method calls (e.g..min(),.describe()) - Add test covering multi-line vault configSchema with chained validators and
descriptions
Problem
When extension authors write Zod schemas across multiple lines:
configSchema: z.object({
op_vault: z.string()
.min(1, "Vault name is required")
.describe("The 1Password vault to use"),
})The chain-method regex ^.\w+( failed to match because the newline and
indentation before .min( meant the ^ anchor saw whitespace, not a dot.
The chain loop broke immediately, so .describe() was never reached and
field descriptions were silently empty.
Fix
^\.\w+\( → ^\s*\.\w+\( in parseZodObjectFields (line 420).
Test plan
- New test: extracts vault configSchema descriptions with chained validators
- All 30 existing extractor tests pass
- Verified end-to-end: pushed 1Password vault extension, descriptions render on extension page
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.183528.0-sha.8855e7df/swamp-darwin-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/macOS (Intel):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.183528.0-sha.8855e7df/swamp-darwin-x86_64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/Linux (x86_64):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.183528.0-sha.8855e7df/swamp-linux-x86_64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/Linux (aarch64):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.183528.0-sha.8855e7df/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260318.171704.0-sha.15076fa0
What's Changed
- feat: port Batch 0 and Batch 1 commands to libswamp + renderer pattern (#762)
Implements Batches 0 and 1 from the CLI refactor plan (closes #739 partial):
Batch 0 - Infrastructure:
- Add shared error factories to src/libswamp/errors.ts: notFound(), alreadyExists(), validationFailed(), with full unit tests
Batch 1 - Simple Read-Only Gets (10 commands):
- model get, model output get, model method describe, model method history get
- workflow get, workflow history get
- vault get, vault describe
- data get
- type describe
For each command:
- Define typed event union with resolving/completed/error kinds
- Define XxxDeps interface + createXxxDeps() factory wiring real infrastructure
- Implement async function* generator (zero presentation logic)
- Implement LogXxxRenderer + JsonXxxRenderer via Renderer interface
- Update CLI handler to pure orchestration via consumeStream()
- Export from src/libswamp/mod.ts, remove old src/presentation/output/ files
- Generator unit tests with fake deps
Also fixes design compliance issues:
- Add _ctx: LibSwampContext as first param to all 9 Batch 1 generators
- Use writeOutput() in LogDataGetRenderer (not console.log) for semantic consistency with other log-mode renderers
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.171704.0-sha.15076fa0/swamp-darwin-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/macOS (Intel):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.171704.0-sha.15076fa0/swamp-darwin-x86_64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/Linux (x86_64):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.171704.0-sha.15076fa0/swamp-linux-x86_64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/Linux (aarch64):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.171704.0-sha.15076fa0/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260318.162717.0-sha.f1293de2
What's Changed
- fix: collective validator error message omits drivers and datastores (#761)
Summary
Fixes #755.
When swamp extension push fails collective validation, the error message only mentioned "model types, vault types, and workflow names" — it did not mention drivers or datastores. This was confusing for users whose push failed due to a driver or datastore type not matching the extension collective.
Changes:
src/cli/commands/extension_push.ts— updated the user-facingUserErrormessage to include "driver types, and datastore types"src/domain/extensions/extension_collective_validator.ts— updated the JSDoc comment to reflect that drivers and datastores are also validated
No logic changes; the validator already correctly checked driver and datastore types.
User Impact
Before this fix, a user pushing an extension with a mismatched driver or datastore type would see:
All model types, vault types, and workflow names must use the same collective as the extension.
…with no mention of drivers or datastores, leaving them uncertain what was actually wrong.
After this fix, the message reads:
All model types, vault types, workflow names, driver types, and datastore types must use the same collective as the extension.
Test Plan
-
deno check— passes -
deno lint— passes -
deno fmt --check— passes -
deno run test— 3198 tests pass
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.162717.0-sha.f1293de2/swamp-darwin-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/macOS (Intel):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.162717.0-sha.f1293de2/swamp-darwin-x86_64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/Linux (x86_64):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.162717.0-sha.f1293de2/swamp-linux-x86_64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/Linux (aarch64):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.162717.0-sha.f1293de2/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260318.021802.0-sha.3848499d
What's Changed
- docs: document custom datastore and driver extensibility (#756)
Summary
The design docs (datastores.md, execution-drivers.md, extension.md) only documented built-in backends but the codebase fully supports user-defined datastores and drivers via the extension system. This gap meant contributors and advanced users reading design docs had no understanding of the plugin architecture — even though the code, type registries, loaders, and bundling are all in place.
Why this matters
- Contributor onboarding: Someone reading
design/datastores.mdto understand the architecture would conclude swamp only supports filesystem and S3. They'd miss that the entire system is pluggable viaDatastoreProviderandDriverTypeRegistry. This makes it harder for contributors to extend swamp correctly. - Design doc ↔ code drift: The skills (
swamp-extension-datastore,swamp-extension-driver) teach users how to create custom backends, but the design docs didn't explain the architecture behind the extensibility. Design docs should be the authoritative source for architectural decisions. - Discoverability: Custom datastores and drivers are a major capability. Without design doc coverage, users discovering swamp through the docs would never know these extension points exist.
Changes
design/datastores.md— Added "Custom Backends" section covering: type registry singleton,DatastoreProviderinterface (5 methods),UserDatastoreLoaderbundling pipeline, configuration with custom types, and implementation files tabledesign/execution-drivers.md— Added "Custom Drivers" section covering:DriverTypeRegistrysingleton,ExecutionDriverinterface,UserDriverLoaderbundling pipeline, resolution priority with custom types, and implementation files tabledesign/extension.md— Added "Vaults, Drivers, and Datastores" subsection explaining the bundling strategy and export validation schemas for all three content types, plus "Collective Validation" subsection
All interface details and file paths were verified against the current source code.
Test plan
- Verified all referenced source files exist and type-check
- Confirmed interface details match actual code (
DatastoreProvider,ExecutionDriver, registries, loaders) - No duplication with skills — design docs explain architecture, skills explain workflow
- Review for accuracy and completeness
🤖 Generated with Claude Code
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.021802.0-sha.3848499d/swamp-darwin-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/macOS (Intel):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.021802.0-sha.3848499d/swamp-darwin-x86_64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/Linux (x86_64):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.021802.0-sha.3848499d/swamp-linux-x86_64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/Linux (aarch64):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.021802.0-sha.3848499d/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260318.013358.0-sha.8dff2b77
What's Changed
- docs: add extension datastore and driver skills (#752)
Summary
PRs #745-#750 built the full custom datastore/driver extension pipeline (type registries, loaders, extension push/pull, runtime wiring) but shipped with zero skill documentation. Without these skills, AI assistants have no guidance to help users build custom datastores or drivers.
This PR adds:
swamp-extension-datastoreskill — Full documentation for creating custom datastore backends (GCS, Azure Blob, databases, etc.). CoversDatastoreProvider,DistributedLock,DatastoreVerifier, andDatastoreSyncServiceinterfaces with quick start, working examples, API reference, and troubleshooting.swamp-extension-driverskill — Full documentation for creating custom execution drivers (SSH, Lambda, Kubernetes, etc.). CoversExecutionDriver,ExecutionRequest,ExecutionResult, andDriverOutputinterfaces with quick start, working examples, API reference, and troubleshooting.swamp-reposkill updates — Adds "Custom Datastores" and "Custom Drivers" subsections with.swamp.yamlconfig format, env var format (SWAMP_DATASTORE='@org/name:{"key":"val"}'), and cross-references to the new skills. Updated "When to Use Other Skills" table.skill_assets.ts— Both new skills (8 files total) registered inBUNDLED_SKILLSso they are installed duringswamp repo initandswamp repo upgrade.skill_assets_test.ts— 4 new tests verifying all skill files are discovered and copied correctly.
User Impact
Before this PR, users who wanted to create a custom datastore or driver had to read the TypeScript source code directly — there was no skill to guide them through the workflow, export contract, configuration, or verification steps.
After this PR:
- AI assistants can guide users through the full create → configure → verify workflow for both datastores and drivers
swamp repo initandswamp repo upgradeinstall the new skills automatically- The
swamp-reposkill now documents custom datastore/driver configuration alongside the built-in filesystem and S3 options
Why This Is Correct
- All interface signatures were verified against the actual source files (
datastore_provider.ts,distributed_lock.ts,datastore_health.ts,datastore_sync_service.ts,execution_driver.ts,docker_execution_driver.ts,driver_resolution.ts,user_datastore_loader.ts,user_driver_loader.ts,resolve_datastore.ts) - Skill structure follows the established pattern from
swamp-extension-modelandswamp-vaultskills - Both new skills score 100% on
tessl skill reviewvalidation (description + content) - All 27 skill asset tests pass
deno check,deno lintpass with no regressions
Test Plan
-
deno check— no type errors -
deno lint— no lint issues -
deno run test src/infrastructure/assets/skill_assets_test.ts— 27/27 pass (4 new) -
npx tessl skill review .claude/skills/swamp-extension-datastore— 100% -
npx tessl skill review .claude/skills/swamp-extension-driver— 100% -
npx tessl skill review .claude/skills/swamp-repo— 100%
🤖 Generated with Claude Code
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.013358.0-sha.8dff2b77/swamp-darwin-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/macOS (Intel):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.013358.0-sha.8dff2b77/swamp-darwin-x86_64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/Linux (x86_64):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.013358.0-sha.8dff2b77/swamp-linux-x86_64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/Linux (aarch64):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.013358.0-sha.8dff2b77/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260318.010420.0-sha.4aba80d3
What's Changed
- fix: health-check embedded deno after extraction, fall back to system deno on failure (#750)
Root Cause
When the compiled swamp binary extracts the embedded deno via Deno.writeFile, macOS records the writing process's provenance in com.apple.provenance. In certain conditions — a stale binary left by a prior swamp version, or OS-level security policy differences between how a programmatically-written file vs a user-copied file is treated — the extracted binary gets SIGKILL'd (exit 137) when spawned as a subprocess.
This produced the silent failure reported in the issue:
error: Bundle compilation failed:
"/path/to/extensions/models/hello.ts": "deno bundle failed for /path/to/hello.ts: "
Exit code non-zero, stderr empty, stdout empty — because the deno subprocess never ran at all.
Why the Previous Fixes Were Wrong
Two prior commits attempted to address this symptom:
- #748 (
5705468c) — treated empty output fromdeno fmt/deno lintas a pass, to avoid false-positive quality check failures. This masked the SIGKILL rather than fixing it: the quality check silently passed, and the failure surfaced later at bundle time with an even more confusing empty error. - #750 (
1efdc301) — added--unstable-bundleto thedeno bundleinvocation, assuming a deno 2.7.x flag change was the cause. Testing confirmed deno 2.7.5 bundles correctly without this flag. The root cause was the bad binary, not a missing flag.
Both commits are reverted in this PR.
Mitigations Added in EmbeddedDenoRuntime
1. Health check after extraction
After writing the binary, swamp immediately runs deno --version. If it fails (SIGKILL, permission error, or any other cause), swamp re-extracts rather than caching a broken path. The health check also runs on the "version already matches" fast path, so a stale/broken binary from a prior swamp version is caught on first use after upgrade.
2. xattr -c after writing (macOS only)
After writing the extracted binary, swamp runs xattr -c <path> to clear extended attributes. This is best-effort — macOS re-adds com.apple.provenance — but may prevent restrictions in configurations where the provenance value written during extraction differs from what macOS expects.
3. System deno fallback
If the extracted binary still fails the health check after a fresh extraction, swamp searches PATH for a system-installed deno and uses it with a warning. If no system deno is found either, a clear error is thrown:
Embedded deno at ~/.swamp/deno/deno failed health check and no system deno found in PATH.
Try: xattr -c ~/.swamp/deno/deno
Also Reverted
| File | Change |
|---|---|
src/domain/models/bundle.ts |
Removed --unstable-bundle (not needed on deno 2.7.5) |
src/domain/extensions/extension_quality_checker.ts |
Removed empty-output-as-pass logic (was masking failures; health check now catches bad binaries before quality checking runs) |
Test Plan
- Deleted
~/.swamp/deno/, ranswamp extension push --dry-runwith newly compiled binary — fresh extraction succeeded,deno --versionhealth check passed, bundle completed - Verified
~/.swamp/deno/denoruns cleanly (exit 0) after extraction by new binary - Full test suite: 3183 tests pass, 0 failed
-
deno fmt --checkanddeno lintclean
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.010420.0-sha.4aba80d3/swamp-darwin-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/macOS (Intel):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.010420.0-sha.4aba80d3/swamp-darwin-x86_64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/Linux (x86_64):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.010420.0-sha.4aba80d3/swamp-linux-x86_64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/Linux (aarch64):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.010420.0-sha.4aba80d3/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260318.000231.0-sha.42789cff
What's Changed
- feat: wire custom datastores into repo context (#749)
Summary
PR 3 of 4 in the custom datastore extension series. PRs 1-2 (#735, #745) established the datastore type registry, loader, and extension push/pull. This PR wires registered custom datastore types into the runtime — every switch point in the repo context that previously hardcoded if (type === "filesystem") ... else if (type === "s3") ... now has a third path that delegates to the DatastoreProvider obtained from the registry.
- Add
CustomDatastoreConfigto theDatastoreConfigdiscriminated union with eagerly-resolveddatastorePath/cachePath - Handle custom types in
resolve_datastore.tsfor env var, CLI arg, and.swamp.yamlpaths - Add custom branches to all 6
repo_context.tsswitch points (read-only, locked, unlocked, model lock, model lock acquisition, global lock) - Wire custom verifier/sync into
datastore status,datastore sync, anddatastore lockcommands - Generalize
DatastoreSyncCoordinatorto accept anySyncableService, not justS3CacheSyncService - 11 new tests covering custom type resolution, config validation, type guard, and error paths
Design decisions and trade-offs
Built-in paths untouched
The filesystem and S3 code paths are not modified — they continue to use their richer interfaces (S3CacheSyncService.pushAll(), pullChangedForModel(), etc.) that the generic DatastoreProvider interface cannot expose. Custom types get the generic pullChanged()/pushChanged() interface. This means custom datastores don't support model-scoped sync (they pull everything), but it avoids breaking the well-tested built-in paths.
Custom check first for type narrowing
Because CustomDatastoreConfig.type is string (it can be any registered type name), TypeScript can't narrow the discriminated union when checking type === "filesystem" first. All switch points check isCustomDatastoreConfig() first, then the built-in types narrow correctly in else if / else branches. This is a compile-time concern only — no runtime cost.
Single provider instance in acquireModelLocks
The custom DatastoreProvider is resolved once at the top of acquireModelLocks and reused for global lock inspection, per-model lock creation, sync service creation, and the flush push lock. This avoids repeated registry lookups and prevents correctness issues with stateful providers that track locks internally.
Sync coordinator label parameter
The coordinator's log messages now use a label parameter ("S3", the custom type name, etc.) instead of hardcoded "S3". Existing S3 users see identical log output — the label defaults to "datastore" but S3 registration passes "S3" explicitly.
No health check on read-only path
The read-only path (requireInitializedRepoReadOnly) does not run a health check for custom datastores — it only ensures the cache directory exists, matching what S3 does. Health checks run in datastore status where they belong. This avoids adding potentially slow network round-trips to every read-only command (search, list, get, validate).
datastore sync for custom types
Custom sync uses the generic pullChanged()/pushChanged() interface (no pushAll/pullAll/sync full-sync methods). The datastore sync command for custom types does pull + push sequentially. This parallels how requireInitializedRepo also registers a sync service with the coordinator, so there is some redundant pull/push — but this matches the existing S3 pattern where the coordinator does incremental sync and the manual command does full sync.
User impact
- Filesystem users: Zero change. No new code executes.
- S3 users: Zero behavioral change. Log messages unchanged. Same lock/sync lifecycle.
- Custom datastore users: Can now configure a custom datastore in
.swamp.yamlor viaSWAMP_DATASTOREenv var and have it work with locking, sync, health checks, and all CLI commands.
Verification
-
deno check— clean (0 errors) -
deno lint— clean -
deno fmt— clean -
deno run test— 3186 passed, 0 failed -
deno run compile— binary compiles
🤖 Generated with Claude Code
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.000231.0-sha.42789cff/swamp-darwin-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/macOS (Intel):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.000231.0-sha.42789cff/swamp-darwin-x86_64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/Linux (x86_64):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.000231.0-sha.42789cff/swamp-linux-x86_64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/Linux (aarch64):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.000231.0-sha.42789cff/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260317.234411.0-sha.5705468c
What's Changed
- fix: skip quality-check false positives when deno 2.7.x exits non-zero with no output (#748)
Summary
extension pushwas blocked by spurious quality-check failures on Deno 2.7.5 where bothdeno fmt --check --no-configanddeno lint --no-configexit with a non-zero code but write nothing to stdout or stderr- The checker was treating any non-zero exit code as a real quality issue, producing
"Formatting"and"Lint"errors with empty""descriptions - Fix: only add a quality issue to the result when the tool produces non-empty output — an empty-output non-zero exit is a deno version-specific no-op, not a real problem
Root cause
Deno 2.7.x introduced a behavioural change where deno fmt --check --no-config and deno lint --no-config can exit 1 with no diagnostic output when run as a subprocess via Deno.Command with piped stdio (confirmed on Deno 2.7.5, macOS aarch64). On Deno 2.6.x the same invocation exits 0 on clean files.
Every known version of deno fmt --check and deno lint that detects a real formatting or lint problem always writes a non-empty diagnostic to stderr. An empty-output non-zero exit is therefore a version-specific no-op rather than a genuine quality failure, so skipping it is safe.
The deno changelog and issue tracker do not document this as an intentional change; it is most likely a regression introduced in the 2.7.x series related to how these tools detect TTY/pipe mode and gate diagnostic output accordingly.
Test plan
- All 25
extension_quality_checker_test.tstests continue to pass -
deno fmt --check— no formatting issues -
deno lint— no lint errors -
deno run test— 3183 passed, 0 failed
🤖 Generated with Claude Code
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260317.234411.0-sha.5705468c/swamp-darwin-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/macOS (Intel):
curl -L https://github.com/systeminit/swamp/releases/download/v20260317.234411.0-sha.5705468c/swamp-darwin-x86_64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/Linux (x86_64):
curl -L https://github.com/systeminit/swamp/releases/download/v20260317.234411.0-sha.5705468c/swamp-linux-x86_64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/Linux (aarch64):
curl -L https://github.com/systeminit/swamp/releases/download/v20260317.234411.0-sha.5705468c/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/