Releases: systeminit/swamp
swamp 20260316.161521.0-sha.7fc8a69a
What's Changed
- fix: skip auth check in
extension push --dry-run(#718)
Summary
swamp extension push --dry-runnow works without authentication- Auth loading (step 3) and collective membership validation (step 4) are wrapped in a
!dryRunguard so they only run for real pushes - Unblocks CI validation workflows that don't have swamp-club credentials
What changed
In src/cli/commands/extension_push.ts, the auth check and collective membership validation previously ran unconditionally before the dry-run exit point. Since --dry-run only builds the archive locally and never contacts the registry, authentication is unnecessary.
The credentials variable is now typed as | undefined and only populated when not in dry-run mode. The existing non-dry-run code paths (steps 13 and 17) already have their own if (!options.dryRun) guards, so credentials are never accessed in dry-run mode.
Trade-off
Dry-run will skip collective ownership validation. This is acceptable because:
- Dry-run validates the build, not permissions — its purpose is to verify the extension compiles and packages correctly
- The real push still enforces collective membership — no security bypass
- CI pipelines just need to verify the extension archives correctly without needing registry credentials
Test plan
-
deno checkpasses -
deno lintpasses -
deno fmtpasses -
deno run testpasses -
deno run compilepasses -
swamp extension push <manifest> --dry-runsucceeds without auth -
swamp extension push <manifest>without auth still fails with "Not authenticated"
Fixes #717
🤖 Generated with Claude Code
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260316.161521.0-sha.7fc8a69a/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/v20260316.161521.0-sha.7fc8a69a/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/v20260316.161521.0-sha.7fc8a69a/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/v20260316.161521.0-sha.7fc8a69a/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260315.010849.0-sha.5a9897f6
What's Changed
- feat: add --global-arg flag to model create command (#714)
Summary
- Adds a repeatable
--global-arg key=valueoption toswamp model create, eliminating the need to manually edit definition YAML to set globalArguments after creation - Reuses the existing
parseKeyValueInputsparser, supporting dot notation for nested objects (config.db.host=localhost), file references (key=@path), and values containing= - Validates provided args against the model type's globalArguments Zod schema (when one exists) at create time, failing early with clear errors
User impact
Before this change, setting globalArguments required a two-step workflow:
swamp model create aws/ec2 my-vpc
swamp model edit my-vpc # manually add globalArguments in YAMLNow it's a single command:
swamp model create aws/ec2 my-vpc \
--global-arg region=us-east-1 \
--global-arg config.timeout=30Nested objects are supported via dot notation:
--global-arg config.db.host=localhost --global-arg config.db.port=5432
# → { config: { db: { host: "localhost", port: "5432" } } }Invalid args are caught immediately:
swamp model create mytype foo --global-arg badformat
# Error: Invalid input format: "badformat". Expected key=value format.Test plan
-
deno check— type checking passes -
deno lint&&deno fmt— clean -
deno run test src/cli/commands/model_create_test.ts— 12 tests pass (9 new) -
deno run test— full suite passes (2978 tests) -
deno run compile— binary compiles - Manual testing: simple args, multiple args, nested dot notation, values with
=, error cases (missing=, empty key), default behavior without flag
Closes #699
🤖 Generated with Claude Code
Co-authored-by: Blake Irvin blakeirvin@me.com
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260315.010849.0-sha.5a9897f6/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/v20260315.010849.0-sha.5a9897f6/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/v20260315.010849.0-sha.5a9897f6/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/v20260315.010849.0-sha.5a9897f6/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260315.000926.0-sha.aa09224f
What's Changed
- fix: resolve vault expressions in readResource() (#712)
Closes #710
Summary
- Add
resolveVaultRefsInData()to transparently resolve vault expression strings (${{ vault.get('...', '...') }}) back to their original secret values when reading resource data viareadResource() - Wire
VaultServiceandSecretRedactorfrom the execution context intocreateResourceReader()inRawExecutionDriver - Add runtime validation that
JSON.parsereturns a plain object (not an array or primitive), fixing a type safety gap where theRecord<string, unknown>return type was not enforced
Why this is needed
When extension models write resource data with sensitive fields, processSensitiveResourceData() replaces actual values with vault expression strings like ${{ vault.get('vault-name', 'key') }}. Before this change, readResource() returned these as literal strings, which meant:
- Leaked vault internals — extension authors had to know about and parse vault expression syntax
- Confusing errors — code expecting an API key got a template string instead, causing opaque failures downstream
- Broken round-trips — write a secret, read it back, get something completely different
How it works
- After JSON parsing,
resolveVaultRefsInData()recursively walks all string values in the result object - Strings matching the vault ref pattern (anchored regex — must be the entire string) are resolved via
VaultService.get() - Resolved secrets are registered with
SecretRedactor.addSecret()to prevent log leakage - Without a
VaultService, behavior is unchanged (backward compatible) - The JSON parse type safety fix ensures corrupted/manually-edited data files fail fast with a clear error instead of silently returning wrong types
Files changed
| File | Change |
|---|---|
src/domain/models/data_writer.ts |
Add resolveVaultRefsInData(), update createResourceReader() signature and implementation |
src/domain/drivers/raw_execution_driver.ts |
Pass vaultService and redactor to createResourceReader() |
src/domain/models/model.ts |
Update JSDoc to reflect new behavior |
src/domain/models/data_writer_test.ts |
10 new tests covering vault resolution, backward compat, type safety |
Test plan
-
deno check— type checking passes -
deno lint— no lint errors -
deno fmt— properly formatted -
deno run test— all 2967 tests pass (48 in data_writer_test.ts) -
deno run compile— binary compiles successfully
🤖 Generated with Claude Code
Co-authored-by: Blake Irvin blakeirvin@me.com
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260315.000926.0-sha.aa09224f/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/v20260315.000926.0-sha.aa09224f/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/v20260315.000926.0-sha.aa09224f/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/v20260315.000926.0-sha.aa09224f/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260314.235538.0-sha.0cbfc0e8
What's Changed
- feat: add readResource() to MethodContext (#711)
Summary
- Add symmetric
readResource(instanceName, version?)convenience method toMethodContext, eliminating theJSON.parse(new TextDecoder().decode(context.dataRepository.getContent(...)))boilerplate every extension model repeats when reading stored data - Create
createResourceReader()factory indata_writer.tsalongside the existingcreateResourceWriter()for symmetry - Wire
readResourceinto the raw execution driver and add a stub in the Docker runner (returnsnullwith warning since containers lack host data access) - Update all extension model docs (API reference, SKILL.md, examples, scenarios) to use
readResourceas the preferred read path
User impact
Extension model authors can now read stored resource data with one call:
// Before (every model repeated this)
const content = await context.dataRepository.getContent(
context.modelType, context.modelId, "vpc");
if (!content) throw new Error("...");
const data = JSON.parse(new TextDecoder().decode(content));
// After
const data = await context.readResource!("vpc");
if (!data) throw new Error("...");Vault reference expressions are returned as-is (not resolved). The low-level getContent() remains available for binary data.
Test plan
- 4 unit tests for
createResourceReader(happy path, null for missing data, version passthrough, vault reference preservation) - 1 test verifying
readResourceis available on context during method execution -
deno checkpasses -
deno lintpasses -
deno fmtpasses - Full test suite passes (2957 tests, 0 failures)
-
deno run compilesucceeds
🤖 Generated with Claude Code
Co-authored-by: Blake Irvin blakeirvin@me.com
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260314.235538.0-sha.0cbfc0e8/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/v20260314.235538.0-sha.0cbfc0e8/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/v20260314.235538.0-sha.0cbfc0e8/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/v20260314.235538.0-sha.0cbfc0e8/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260313.235152.0-sha.bb94615c
What's Changed
- fix: add 'install' as alias for 'extension pull' (#704)
Summary
- Add
.alias("install")to theextension pullcommand soswamp extension installworks as expected - AI agents naturally try
swamp extension installwhich previously failed with a confusing error
Closes #702
Test plan
-
deno checkpasses -
deno lintpasses -
swamp extension --helpshowspull, installin the command list -
swamp extension install <ext>routes to the pull handler
🤖 Generated with Claude Code
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260313.235152.0-sha.bb94615c/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/v20260313.235152.0-sha.bb94615c/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/v20260313.235152.0-sha.bb94615c/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/v20260313.235152.0-sha.bb94615c/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260313.230033.0-sha.9ad8cbad
What's Changed
- feat: pluggable execution drivers with Docker support (#703)
Fixes: #701
Summary
- Pluggable execution driver abstraction — a new
ExecutionDriverinterface that decouples where a model method runs from what it does. Two built-in drivers:raw(in-process, the default) anddocker(containerized). - Docker bundle mode — extension models (TypeScript) can now run inside Docker containers with no code changes. Swamp auto-generates a self-contained JavaScript bundle (zod inlined) and executes it via an embedded runner script inside the container.
- Comprehensive documentation — design doc (
design/execution-drivers.md), skill reference files forswamp-model,swamp-workflow, andswamp-extension-model, all registered inBUNDLED_SKILLSforrepo init/repo upgrade.
User Impact
New CLI flags
swamp model method run my-model execute --driver docker
swamp workflow run my-workflow --driver dockerDefinition-level driver config
Models and workflows can declare their driver in YAML:
driver: docker
driverConfig:
image: "alpine:latest"
bundleImage: "denoland/deno:alpine"
timeout: 30000
memory: "512m"Multi-level configuration
Driver config can be set at workflow, job, or step level. Resolution priority (first match wins): CLI flag > step > job > workflow > definition > raw default.
Podman / nerdctl support
Set command: "podman" (or nerdctl) in driverConfig to use alternative container runtimes.
Extension model Docker execution
TypeScript extension models work in Docker with zero changes — context.writeResource(), context.createFileWriter(), and context.logger all behave identically. The only limitation: getFilePath() throws in Docker mode.
No breaking changes
Existing models, workflows, and extensions continue to work unchanged. The default driver remains raw (in-process).
Commits
-
6d24aed4—feat: add pluggable execution driver abstraction
CoreExecutionDriverinterface,ExecutionRequest/DriverOutput/ExecutionResulttypes, raw and docker drivers, driver type registry, multi-level config resolution, CLI--driverflag, and integration with the method execution service. -
13bc6443—feat: add Docker bundle mode for TypeScript extension models
Self-contained bundling (bundleExtension({ selfContained: true })), embedded Docker runner script,bundleImageconfig field,ModelDefinition.bundleSource, dual-mode detection (command vs bundle), and full test coverage. -
fb3ca28f—docs: add execution driver documentation and skill references
Design doc with ASCII flow diagrams and implementation file tables, three skill reference files (model, workflow, extension-model),--driverrows in SKILL.md option tables,BUNDLED_SKILLSregistration.
Test plan
-
deno check— type checking passes -
deno lint— no lint errors -
deno fmt— all files formatted -
deno run test— 2952 tests pass -
deno run compile— binary compiles with new skill files embedded - Manual:
swamp model method run <model> <method> --driver dockerwith a command/shell model - Manual:
swamp model method run <model> <method> --driver dockerwith an extension model (bundle mode) - Manual: verify
--driverflag onswamp workflow run
🤖 Generated with Claude Code
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260313.230033.0-sha.9ad8cbad/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/v20260313.230033.0-sha.9ad8cbad/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/v20260313.230033.0-sha.9ad8cbad/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/v20260313.230033.0-sha.9ad8cbad/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260312.232506.0-sha.dfa7c4e9
What's Changed
- fix: warn when check has empty appliesTo array (#698)
Summary
- Adds validation warning when a check has
appliesTo: [](empty array), which silently disables the check since no method name can match - The warning message tells the author to either remove
appliesToor populate it with method names
Addresses review feedback from #697.
Review comment #2 (execution order)
The second comment about non-deterministic check execution order across extension loads is acknowledged but not actioned. Checks are documented as stateless and independent — order should not matter. Object.entries preserves insertion order per spec, and extension merging via spread is deterministic for a given set of extensions.
Test plan
- New test:
validateModel warns when appliesTo is empty array - All 56 validation service tests pass
🤖 Generated with Claude Code
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260312.232506.0-sha.dfa7c4e9/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/v20260312.232506.0-sha.dfa7c4e9/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/v20260312.232506.0-sha.dfa7c4e9/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/v20260312.232506.0-sha.dfa7c4e9/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260312.231622.0-sha.27c95bb0
What's Changed
- feat: add pre-flight checks for model method execution (#697)
Summary
Adds pre-flight checks that run automatically before mutating model methods (create/update/delete/action), catching invalid inputs early with clear error messages instead of letting them fail as raw API errors.
Closes #619
Core Implementation
CheckDefinitioninterface withdescription,labels,appliesTo, andexecute(context) => CheckResultCheckResultwithpass: booleanand optionalerrors: string[]- Checks run automatically before mutating methods; read/list methods skip checks
isMutatingKind()helper for method kind classification
Extension Checks
ModelRegistry.extend()accepts optional thirdchecksparameter- Extension checks merge with model-type checks; conflicts throw at registration time
- Extension checks format matches
methods: array ofRecord<string, CheckDefinition>
Definition-Level Check Selection
CheckSelectiontype:{ require?: string[]; skip?: string[] }on definitionsskipalways wins (even overrequire)requirechecks are immune to CLI skip flags (--skip-checks,--skip-check,--skip-check-label)- Validation warns on nonexistent check names and require/skip overlap
CLI Flags
model method run:--skip-checks,--skip-check <name>,--skip-check-label <label>model validate:--label <label>,--method <method>for check filtering
Validation Service
- Check results appear alongside schema validations in
model validateoutput - Label and method filtering for targeted check execution
- Definition-level skip lists honored during validation
Test plan
- 17 new unit tests covering all check behaviors (pass/fail, filtering, skip flags, extension merging, definition-level selection)
- Integration tests updated for new validation count
- All 2875 tests pass
-
deno check,deno lint,deno fmtpass - End-to-end tested with
command/shellmodel extension checks:- Check pass/fail on method execution
- Label-based filtering (
--skip-check-label) - Named check skipping (
--skip-check) - Skip all checks (
--skip-checks) - Definition-level require (immune to skip flags)
- Definition-level skip (overrides require)
model validatewith--labeland--methodfiltering- Invalid check selection validation warnings
🤖 Generated with Claude Code
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260312.231622.0-sha.27c95bb0/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/v20260312.231622.0-sha.27c95bb0/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/v20260312.231622.0-sha.27c95bb0/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/v20260312.231622.0-sha.27c95bb0/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260312.014128.0-sha.a040be69
What's Changed
- fix: use write lock for evaluate commands (#695)
Summary
Follow-up to #694 — model evaluate and workflow evaluate were incorrectly migrated to the read-only path, but both commands persist evaluated definitions/workflows via .save() that are consumed by subsequent run commands. They must hold the datastore lock.
Fixes the blocking review feedback from #694.
Test Plan
-
deno checkpasses -
deno lintpasses -
deno fmt --checkpasses -
deno run test— all 2839 tests pass
🤖 Generated with Claude Code
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260312.014128.0-sha.a040be69/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/v20260312.014128.0-sha.a040be69/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/v20260312.014128.0-sha.a040be69/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/v20260312.014128.0-sha.a040be69/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260312.011512.0-sha.4fc37f53
What's Changed
- fix: skip datastore lock for read-only CLI commands (#694)
Summary
Fixes #692 — read-only CLI commands no longer acquire the exclusive datastore lock, allowing them to run concurrently with write operations like workflow runs.
Previously, every CLI command went through requireInitializedRepo() which acquired an exclusive distributed lock. This meant that running swamp workflow search or swamp data list while a workflow was executing would block for ~60 seconds then fail with a lock timeout error.
Changes
- New function
requireInitializedRepoReadOnly()inrepo_context.ts— builds the fullRepositoryContextbut skips lock acquisition and datastore sync. This follows the existing pattern where breakglass commands (datastore lock status) already bypass locking viaresolveDatastoreForRepo(). - 33 read-only commands migrated to use the new function: all
search,get,list,validate,evaluate,describe,history,logs,data,schema,summarise,audit,telemetry stats,datastore status, andextension list/searchcommands. - Write commands unchanged —
create,edit,delete,run,gc,rename,setup,sync,pull,push,rm,update,fmtcontinue to acquire the lock viarequireInitializedRepo(). - Updated design docs (
design/datastores.md) and skills (.claude/skills/swamp-repo/SKILL.md) to document the read-only vs write distinction. - 4 new tests including a concurrency test that proves the read-only path succeeds while the write lock is held.
Why this is safe
All file writes in the codebase use atomic write-to-temp-then-rename (atomicWriteTextFile), so concurrent reads never see partial or corrupt files. The lock's purpose is to prevent concurrent writes from corrupting state — concurrent reads are inherently safe.
Trade-offs
Filesystem datastores: No trade-off. Both read and write paths access the same .swamp/ directory, so reads see writes immediately.
S3 datastores: Read-only commands read from the local S3 cache without pulling latest from S3 first. This means during a running workflow, a concurrent read in another terminal sees the cache as it was before the workflow started. This is acceptable because:
- Write commands always call
pullChanged()before executing, so data is fresh when it matters (during execution) - Once a write command finishes, the next write in any terminal pulls the latest
- Users can run
swamp datastore sync --pullto explicitly refresh the cache - The alternative (blocking all reads for 60s+ during any write) is a much worse UX than slightly stale read results
Test Plan
-
deno check— type checking passes -
deno lint— no lint errors -
deno fmt --check— formatting clean -
deno run test— all 2839 tests pass - New test:
requireInitializedRepoReadOnly - does not block concurrent accessverifies read-only path succeeds while write lock is held - Manual: run
swamp workflow run <workflow> --jsonthen concurrently runswamp workflow search <query> --json— search should return immediately instead of blocking
🤖 Generated with Claude Code
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260312.011512.0-sha.4fc37f53/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/v20260312.011512.0-sha.4fc37f53/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/v20260312.011512.0-sha.4fc37f53/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/v20260312.011512.0-sha.4fc37f53/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/