Releases: systeminit/swamp
swamp 20260319.010016.0-sha.bc242ef2
What's Changed
- feat: support deno.json project config for extension bundling (#770)
Summary
Extensions can now optionally include a deno.json file with an import map alongside their manifest.yaml. When present, swamp extension push uses it for dependency resolution (bundling) and quality checks (lint/fmt rules). This enables the swamp-extensions workflow where each extension is a self-contained Deno project with pinned dependencies, tests, and standard tooling.
Also fixes a pre-existing bug where fully-pinned zod versions (e.g., npm:zod@4.3.6) were silently inlined into bundles instead of being externalized.
What changed
Push path (3 files)
bundle.ts— AddeddenoConfigPathoption toBundleOptions. When provided, uses--config <path>instead of--no-lock. Added source scanning for exact zod specifiers (e.g.,npm:zod@4.3.6) to fix the pre-existing externalization bug. AddedresolveZodFromConfig()to read the deno.json import map and externalize the mapped zod version. UpdatedrewriteZodImports()regex to handle bare"zod"specifiers (not justnpm:zod), with safety guard to only match zod 4.x.extension_quality_checker.ts— Added optionaldenoConfigPathparameter. When provided, uses--config <path>instead of--no-configfor bothdeno fmtanddeno lint.extension_push.ts— AddedfindDenoConfig()that walks up from the manifest directory to the repo root (.swamp.yaml/.gitboundary) looking fordeno.json. Threads the result through to the quality checker and all four bundle loops (models, vaults, drivers, datastores).
Runtime path (4 files)
user_model_loader.ts,user_vault_loader.ts,user_driver_loader.ts,user_datastore_loader.ts— AddedsourceHasBareSpecifiers()check before re-bundling. When source has bare specifiers (e.g.,from "zod"instead offrom "npm:zod@4") and a cached bundle exists, the loader uses the cached bundle instead of attempting a re-bundle that would fail without thedeno.jsonimport map. This handles pulled extensions that were built with a project config — the archive includes pre-built bundles but not thedeno.json.
Tests
bundle_test.ts— 10 new tests: deno.json-aware bundling, bare specifier rewriting ("zod","zod"star import, aliased),sourceHasBareSpecifiers(7 cases covering npm:, relative, jsr:, node:, bare, scoped)extension_quality_checker_test.ts— 1 new test fordenoConfigPathparameterextension_pull_test.ts— 1 new integration test: pulls@stack72/letsencrypt-certificate@2026.03.04.1, verifies bundle extraction, and confirms the model type loads at runtime viamodel type search
Docs
design/extension.md— Documented project-aware bundling, zod externalization details, and runtime bundle cachingdesign/datastores.md— Added note about bare specifier cache fallback- Skills — Updated key rules in model, driver, and datastore skills; added import map examples to
references/examples.md; updated push workflow steps inreferences/publishing.md
User impact
- Extensions with
deno.json: Users can write extensions as proper Deno projects with bare specifiers resolved via import maps.swamp extension pushandswamp extension fmthonor the project config automatically. - Extensions without
deno.json: Zero change in behavior. Existing extensions withnpm:prefixed imports continue to work identically. - Zod externalization fix: Extensions using fully-pinned
npm:zod@4.3.6(like those in swamp-extensions) now correctly externalize zod instead of inlining it. This reduces bundle sizes (~203KB vs ~278KB compressed for the aws-sm extension) and ensures zodinstanceofchecks work correctly. - Pulled extensions: Extensions built with a
deno.jsonproject can be pulled and loaded at runtime without thedeno.json— the pre-built bundle from the archive is used.
Design decisions
- Detection via walk-up, not config field:
deno.jsonis detected by walking up from the manifest directory to the repo root, rather than adding a field tomanifest.yaml. This avoids a schema change and mirrors how tools liketsconfig.jsonand.eslintrcare resolved. - Repo root as boundary: The walk-up stops at
.swamp.yaml/.gitto prevent escaping the project and accidentally picking up an unrelateddeno.json. - Source scanning for zod version: Rather than parsing the full import map, the bundler scans the entry point source for the exact
npm:zod@4.x.xspecifier. This fixes both inline and import-map scenarios with one mechanism. - Conservative regex:
rewriteZodImportsonly matches zod 4.x or unversioned —zod@3is explicitly excluded to prevent silent runtime breakage. - Cached bundle preference: Runtime loaders check
sourceHasBareSpecifiers()before re-bundling. This is conservative — it prefers a known-good cached bundle over a re-bundle that will fail.
Testing performed
Automated (3376 tests, 0 failed)
deno check— zero type errors across all filesdeno lint— 736 files cleandeno fmt --check— 797 files cleandeno run test— 3376 tests passed, 0 failed- Integration test: pull + load
@stack72/letsencrypt-certificate@2026.03.04.1
Manual end-to-end
- Import map path: Created aws-sm extension with
deno.jsonimport map + bare specifiers →swamp extension fmtpassed →swamp extension push --dry-runproduced 203.5KB archive with zod externalized - Inline deps path: Used original aws-sm source with
npm:zod@4.3.6(nodeno.json) → push produced 203.9KB archive with zod externalized (was 277.9KB before the fix) - Pull + runtime load: Pulled
@stack72/letsencrypt-certificate, verified model type loads viaswamp model type search - Cache fallback: Removed
deno.jsonafter building cache, verified vault still loads from cached bundle viasourceHasBareSpecifiersdetection - No deno.json + no cache: Removed both
deno.jsonand cache, confirmed expected error (Import "zod" not a dependency) — verifying the cache fallback is necessary - Regex safety: Verified
rewriteZodImportsdoes NOT matchzod-utils,zodiac,npm:zod@3, orzod@3
Test plan
- CI passes (type check, lint, fmt, tests)
- Verify
swamp extension push --dry-runworks for an extension withdeno.json+ bare specifiers - Verify
swamp extension push --dry-runworks for an extension with inlinenpm:deps (nodeno.json) - Verify
swamp extension pull+ runtime load works for existing published extensions
🤖 Generated with Claude Code
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260319.010016.0-sha.bc242ef2/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/v20260319.010016.0-sha.bc242ef2/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/v20260319.010016.0-sha.bc242ef2/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/v20260319.010016.0-sha.bc242ef2/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260318.232456.0-sha.01a4aa77
What's Changed
- feat: add createXxxDeps factories for all 12 Batch 2 commands (#769)
Summary
- Extract
readUpstreamExtensionstosrc/infrastructure/persistence/upstream_extensions.tsso it can be imported from libswamp without reaching into CLI code - Add
createXxxDeps()factory functions to all 12 Batch 2 libswamp generators, following the same pattern ascreateDataGetDeps()from Batch 1 - Simplify all 12 CLI handlers to ~20-line wrappers: parse args → factory → renderer →
consumeStream() - Rewrite
workflowSchemagenerator to import Zod schemas directly (pure computation, no deps needed)
Factories added
| Command | Factory |
|---|---|
workflow_schema |
(no deps — generator does pure computation) |
extension_list |
createExtensionListDeps(repoDir) |
telemetry_stats |
createTelemetryStatsDeps(repoDir, version) |
data_list |
createDataListDeps(repoDir) |
data_versions |
createDataVersionsDeps(repoDir) |
vault_list_keys |
createVaultListKeysDeps(repoDir) |
model_validate |
createModelValidateDeps(repoDir, options?) |
workflow_validate |
createWorkflowValidateDeps(repoDir) |
workflow_history_logs |
createWorkflowHistoryLogsDeps(repoDir) |
model_method_history_logs |
createModelMethodHistoryLogsDeps(repoDir) |
model_output_logs |
createModelOutputLogsDeps(repoDir) |
model_output_data |
createModelOutputDataDeps(repoDir) |
Any consumer can now import { dataList, createDataListDeps } from "libswamp/mod.ts" and have a fully working operation without importing domain internals.
Test Plan
deno check src/— passes (0 errors)deno lint— passes (737 files)deno fmt --check— passes (798 files)deno run test— all 3361 tests passdeno run compile— binary compiles successfully
🤖 Generated with Claude Code
Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.232456.0-sha.01a4aa77/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.232456.0-sha.01a4aa77/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.232456.0-sha.01a4aa77/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.232456.0-sha.01a4aa77/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260318.222412.0-sha.ea3d7b68
What's Changed
- fix: handle broken extensions with missing source files from older publishes (#768)
Summary
- Skip
_-prefixed directories (_lib/,_internal/) indiscoverFiles()across all four loaders (model, vault, driver, datastore) — these are helper modules imported by entry points, not standalone types that should be individually bundled - Strip ANSI escape codes from
deno bundleerror messages and CLI startup warnings so users see clean text instead of raw escape sequences - Validate source completeness during
extension pull— after extraction, resolve imports from entry-point.tsfiles and warn if referenced source files are missing, with guidance to ask the author to re-publish
Context
Extensions published before the multiline import regex fix (commit 4955f3d2, March 16) may have incomplete source files. For example, @stack72/letsencrypt-certificate was published March 4 and is missing _lib/acme.ts because the old single-line regex in local_import_resolver.ts couldn't match multiline imports during publish.
When users pulled these extensions, discoverFiles() found helper files in _lib/ and tried to bundle them independently, which failed because their imports were unresolvable. Users saw raw deno bundle errors with ANSI escape codes — a confusing experience since the pre-built JS bundle actually works fine.
User impact
Before this fix, pulling @stack72/letsencrypt-certificate produced confusing bundle errors with ANSI garbage. After this fix, users see:
WRN Extension has incomplete source files (1 missing). The pre-built bundle will be used.
WRN To fix, ask the extension author to re-publish with swamp 20260316 or later.
WRN missing: _lib/acme.ts
And swamp model type describe @stack72/letsencrypt-certificate works correctly via the pre-built bundle.
Test plan
- New test:
UserModelLoader skips _-prefixed directories in discoverFiles— creates_lib/helper.tsalongside a valid model and verifies it never appears inresult.failedorresult.loaded - New test:
renderExtensionPullMissingSources outputs JSON in json mode— verifies JSON output format for missing source file warnings - All 3363 existing tests pass
- Manual verification:
swamp init && swamp extension pull @stack72/letsencrypt-certificate && swamp model type describe @stack72/letsencrypt-certificate— shows missing source warning, no bundle errors, type describe works
🤖 Generated with Claude Code
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.222412.0-sha.ea3d7b68/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.222412.0-sha.ea3d7b68/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.222412.0-sha.ea3d7b68/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.222412.0-sha.ea3d7b68/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260318.215201.0-sha.3f5812f1
What's Changed
- fix: handle shorthand configSchema property syntax in extension extractor (#767)
Summary
- Bug: The extension content extractor failed to detect
configSchemawhen using ES shorthand property syntax (configSchema,instead ofconfigSchema: value). The regex/configSchema\s*:/required a colon, so shorthand was silently ignored. - Fix: Updated
hasConfigSchemadetection to/configSchema\s*[:,}]/and added a shorthand fallback in the named-ref resolution branch that looks upconst configSchema = z.object({in the full file content when shorthand syntax is detected. - Scope: Applied identically to all three extraction blocks — vaults (~line 265), drivers (~line 647), and datastores (~line 716).
Test plan
- All 30 existing tests pass (
deno run test src/domain/extensions/extension_content_extractor_test.ts) - Type checking passes (
deno check) - Binary recompiled (
deno run compile)
🤖 Generated with Claude Code
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.215201.0-sha.3f5812f1/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.215201.0-sha.3f5812f1/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.215201.0-sha.3f5812f1/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.215201.0-sha.3f5812f1/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260318.210703.0-sha.c7e8f28f
What's Changed
- feat: add
swamp extension trustCLI commands (#766)
Summary
Adds CLI commands to manage trusted collectives for extension auto-resolution, solving a discoverability problem where the feature was completely invisible to both users and AI agents.
The Problem
A user asked Claude about trusted collectives in their swamp repo, and Claude responded: "The trusted collectives feature doesn't exist in swamp yet." Despite the feature being fully implemented (PRs #725 and #727), it was only configurable by manually editing .swamp.yaml — no CLI command, no --help text, no discoverability path.
The Solution
Four new commands under swamp extension trust:
swamp extension trust list # Show explicit, membership, and resolved collectives
swamp extension trust add <collective> # Add a collective to the trusted list
swamp extension trust rm <collective> # Remove a collective from the trusted list
swamp extension trust auto-trust <on|off> # Enable/disable membership auto-trustThe list command shows the full picture — explicit collectives from .swamp.yaml, membership collectives from auth, and the resolved/merged effective list. This means even on a fresh repo with no config, a user sees that swamp and si are trusted by default.
Architecture
Follows the libswamp + renderer pattern (issue #739):
| Layer | Files | Purpose |
|---|---|---|
| Shared types | src/libswamp/extensions/trust.ts |
DEFAULT_TRUSTED, TrustModifyData, TrustModifyEvent, resolveTrustedCollectives() |
| Generators | src/libswamp/extensions/trust_{list,add,rm,auto_trust}.ts |
Pure business logic with injected deps |
| Renderers | src/presentation/renderers/trust_{list,modify,auto_trust}.ts |
Log + Json output modes |
| CLI commands | src/cli/commands/extension_trust*.ts |
Pure wiring (deps → generator → renderer) |
Refactoring
- Extracted
resolveTrustedCollectives()fromsrc/cli/mod.tsintosrc/libswamp/extensions/trust.ts— it was domain logic living in the CLI layer - Moved 8 tests from
src/cli/mod_test.tstosrc/libswamp/extensions/trust_test.tsto follow the code - Single
TrustModifyEventshared by bothtrust_addandtrust_rmgenerators (identical event shapes, no reason for separate types) DEFAULT_TRUSTEDdefined once, used everywhere
Documentation Updates
design/extension.md— documents CLI commands in "Trusted Collectives" sectiondesign/repo.md— cross-references CLI commands fromtrustedCollectivesconfig- 7 skill files updated with
swamp extension trustreferences for discoverability
Test Plan
- 26 generator tests (
src/libswamp/extensions/) — all pass - 16 renderer tests (
src/presentation/renderers/trust_*_test.ts) — all pass - 8
resolveTrustedCollectivestests moved to proper location — all pass - Existing
mod_test.tstests still pass (57 tests, down from 65 after moving 8) -
deno checkpasses on all files -
deno lintpasses -
deno fmtapplied
🤖 Generated with Claude Code
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260318.210703.0-sha.c7e8f28f/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.210703.0-sha.c7e8f28f/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.210703.0-sha.c7e8f28f/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.210703.0-sha.c7e8f28f/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/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/