Releases: systeminit/swamp
swamp 20260329.002945.0-sha.1ee6ecd0
What's Changed
- fix: collect writer handles in RawExecutionDriver for extension model dataArtifacts (#908)
Summary
Fixes #907
RawExecutionDriver ignored getHandles() from both createResourceWriter and createFileWriterFactory. After method execution, it relied on result.dataHandles from the method's return value — which is undefined for extension models that return {}.
Impact: All extension models using the raw driver produced empty dataArtifacts in their run output. This broke:
- The CLI JSON output view (no artifacts shown)
- Method-summary reports (empty data output table)
- Output log artifact lookup (
output_logs.tsfilters ondataArtifacts)
The data itself was persisted correctly to disk (writeResource works in-process), which is why this wasn't caught earlier — swamp data get, swamp data list, and CEL expressions like data.latest() all resolve from the filesystem and worked fine.
Fix: Destructure getHandles from both writer factories, then use the combined writer handles as fallback when result.dataHandles is empty. Built-in models that return explicit dataHandles are unaffected — the fallback only triggers when the method returns no handles.
src/domain/drivers/raw_execution_driver.ts— wire upgetHandlesfrom both factories, use as fallbacksrc/domain/drivers/raw_execution_driver_test.ts— 3 new tests: writer handles collected when method returns none, explicit handles take precedence, empty when no writes
Test Plan
- 3 new unit tests for
RawExecutionDrivercovering the fix and backward compatibility - Full test suite passes (3680 tests, 0 failures)
-
deno check,deno lint,deno fmtall clean
🤖 Generated with Claude Code
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260329.002945.0-sha.1ee6ecd0/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/v20260329.002945.0-sha.1ee6ecd0/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/v20260329.002945.0-sha.1ee6ecd0/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/v20260329.002945.0-sha.1ee6ecd0/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260328.174132.0-sha.5388e901
What's Changed
- fix: support spaces in quoted vault.get() arguments (#906)
Summary
- Fix the
vault.get()regex inmodel_resolver.tsto allow spaces inside
quoted arguments (e.g.vault.get("infra", "Client ID")) - Uses alternation: quoted args match any char except the closing quote,
unquoted args preserve current no-space behavior - Updates match extraction for the new capture group positions
Fixes #902
Test Plan
- Added 6 new unit tests in
vault_expression_test.ts:- Spaces in double-quoted key
- Spaces in single-quoted key
- 1Password-style path with slashes and spaces
- Spaces in quoted vault name
- Spaces in both vault name and key
- Mixed quoted vault name with unquoted key
- Added
containsVaultExpressiondetection test for quoted args with spaces - All 3677 existing tests pass (no regression)
deno check,deno lint,deno fmtall pass
🤖 Generated with Claude Code
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260328.174132.0-sha.5388e901/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/v20260328.174132.0-sha.5388e901/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/v20260328.174132.0-sha.5388e901/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/v20260328.174132.0-sha.5388e901/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260328.165141.0-sha.2b1e4036
What's Changed
- fix: quote --allowedTools in issue-triage workflow (#905)
Summary
- Fix
/triagecommand failure caused byshell-quoteparsing of unquotedBash(...)patterns inclaude_args - Wraps the
--allowedToolsvalue in single quotes so spaces and parentheses are preserved as a single token
Root Cause
claude-code-action uses shell-quote to parse claude_args. The Bash(...) patterns added in #852 contain spaces (e.g. Bash(gh api --method POST:*/reactions)), which caused:
- Parentheses treated as shell operators and stripped
- Space-splitting broke patterns into separate tokens
--methodparsed as a standalone CLI flag, corrupting the entire argument structure- Claude Code crashed with exit code 1
Confirmed by workflow logs from the failed #902 triage — allowed tools were ["Read", "Glob", "Grep", "Bash", "gh", "issue", "api"] instead of the intended patterns.
Fixes #904
Test plan
- Re-run
/triageon #902 after merge and verify it completes successfully - Verify the workflow logs show the correct
Bash(...)patterns inallowedTools
🤖 Generated with Claude Code
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260328.165141.0-sha.2b1e4036/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/v20260328.165141.0-sha.2b1e4036/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/v20260328.165141.0-sha.2b1e4036/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/v20260328.165141.0-sha.2b1e4036/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260327.235335.0-sha.0c993a65
What's Changed
- fix: forward driver onLog output as method_output events (#900)
Summary
Out-of-process execution drivers (Tensorlake, Docker, etc.) emit log lines via callbacks.onLog, but these were only forwarded to the logger — not through the onEvent stream. This meant WebSocket clients using swamp serve never received method_output events from these drivers.
Now onLog also emits MethodExecutionEvent { type: "output" } so the output appears in the event stream alongside in-process output.
Test plan
- Tensorlake driver output appears in WebSocket event stream
- Existing forEach tests pass (verified locally)
🤖 Generated with Claude Code
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260327.235335.0-sha.0c993a65/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/v20260327.235335.0-sha.0c993a65/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/v20260327.235335.0-sha.0c993a65/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/v20260327.235335.0-sha.0c993a65/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260327.221916.0-sha.d3225816
What's Changed
- feat: add S3-compatible endpoint support for custom object stores (#895)
Summary
- Thread optional
endpointandforcePathStylefields through the S3 datastore stack so users can target S3-compatible providers like DigitalOcean Spaces - Both fields are conditionally spread (not passed as
undefined) into the AWS SDK client constructor, preserving existing behavior when omitted - Adds
--endpointand--force-path-styleCLI flags toswamp datastore setup s3 - Displays endpoint in
swamp datastore statusoutput
Test Plan
- Added 2 new tests for S3 config resolution with/without endpoint
- Updated 4 existing status tests for the new
endpointfield - Full test suite passes (3676/3676)
deno check,deno lint,deno fmt,deno run compileall pass
🤖 Generated with Claude Code
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260327.221916.0-sha.d3225816/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/v20260327.221916.0-sha.d3225816/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/v20260327.221916.0-sha.d3225816/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/v20260327.221916.0-sha.d3225816/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260327.190643.0-sha.663cadd1
What's Changed
- ci: add JSR publish workflow for @systeminit/swamp-lib (#894)
Summary
Adds a GitHub Actions workflow that publishes the @systeminit/swamp-lib client package to JSR when files in packages/client/ change on merge to main.
- Uses Deno's OIDC token auth (no secrets needed — JSR trusts GitHub Actions)
- Auto-generates semver from date + commit count:
0.YYYYMMDD.N - Runs type check + tests before publishing
- Also supports
workflow_dispatchfor manual publishing
Test plan
- Workflow triggers on merge with
packages/client/changes - Version stamp produces valid semver
-
deno publishsucceeds with OIDC auth
🤖 Generated with Claude Code
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260327.190643.0-sha.663cadd1/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/v20260327.190643.0-sha.663cadd1/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/v20260327.190643.0-sha.663cadd1/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/v20260327.190643.0-sha.663cadd1/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260327.184143.0-sha.444f753d
What's Changed
- feat: swamp serve WebSocket API + @swamp/client package (#892)
Summary
- Adds
swamp servecommand — a WebSocket API server for remote workflow and model method execution - Adds
@swamp/clientTypeScript package (published to JSR as@systeminit/swamp-lib) for consuming the API - Captures
console.log/console.errorfrom in-process extension models asmethod_outputevents in the event stream
Details
swamp serve
swamp serve --port 9090 --host 0.0.0.0 --repo-dir ./my-repoStarts an HTTP+WebSocket server. Health check at GET /health, WebSocket upgrade at /. Supports multiplexed concurrent requests with per-model locking and cancellation via cancel messages.
@swamp/client
Standalone TypeScript client with zero CLI dependencies:
import { SwampClient } from "@systeminit/swamp-lib";
const client = new SwampClient("ws://localhost:9090");
await client.connect();
// Callback-based
const run = await client.workflowRun(
{ workflowIdOrName: "my-workflow", inputs: { env: "dev" } },
{ started: (e) => console.log(e.runId) },
);
// AsyncIterable
for await (const event of client.workflowRunStream({ ... })) {
console.log(event.kind);
}Console capture
Extension models using console.log now have their output captured as method_output events, matching the behavior of out-of-process drivers. Previously, in-process console.log went to the host process stdout and was not visible in the event stream.
Test plan
-
swamp servestarts and responds to health checks - WebSocket connection + workflow execution returns correct events
-
@swamp/clientcallback and AsyncIterable APIs work end-to-end - Console capture emits
method_outputevents for in-process models - Cancellation via
cancelmessage aborts running workflows -
deno task checkpasses
🤖 Generated with Claude Code
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260327.184143.0-sha.444f753d/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/v20260327.184143.0-sha.444f753d/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/v20260327.184143.0-sha.444f753d/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/v20260327.184143.0-sha.444f753d/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260327.161052.0-sha.a20ffa2d
What's Changed
- fix: pin third-party actions and trust docker publisher (#891)
Summary
- Pin
dorny/paths-filter,softprops/action-gh-release, andpeter-evans/repository-dispatchto full commit SHAs for supply chain security - Add
dockertoTRUSTED_PUBLISHERSinscripts/audit_actions.tssodocker/*actions are accepted with tag-only pins
Test Plan
deno fmt --check,deno lint, anddeno run testall pass- CI security review should no longer flag unpinned third-party actions
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260327.161052.0-sha.a20ffa2d/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/v20260327.161052.0-sha.a20ffa2d/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/v20260327.161052.0-sha.a20ffa2d/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/v20260327.161052.0-sha.a20ffa2d/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260327.152947.0-sha.c0abc5ac
What's Changed
- fix: replace Node.js OTLP exporter with fetch-based exporter (#890)
Summary
- Replace
@opentelemetry/exporter-trace-otlp-http(Node.jsHttpsClientRequesttransport) with a customFetchOtlpExporterthat uses Deno's nativefetchAPI - The Node.js HTTPS transport fails TLS connections in Deno's compiled binary, causing 10s timeout errors when exporting traces to HTTPS OTLP endpoints like Honeycomb
- Native
fetchbypasses the Node.js compat layer entirely, fixing HTTPS in compiled binaries - All export errors are silently swallowed — tracing never interferes with the CLI
- Added graceful error handling around
shutdownTracing()so flush failures are caught
What changed
| File | Change |
|---|---|
src/infrastructure/tracing/fetch_otlp_exporter.ts |
New FetchOtlpExporter implementing SpanExporter with fetch + JsonTraceSerializer |
src/infrastructure/tracing/fetch_otlp_exporter_test.ts |
5 unit tests: URL/headers, HTTP errors, network errors, shutdown, timeout |
src/infrastructure/tracing/otel_init.ts |
Swap to FetchOtlpExporter, add try/catch around shutdown |
deno.json |
Remove exporter-trace-otlp-http, add otlp-transformer + core |
deno.lock |
Updated lockfile |
design/tracing.md |
Document new exporter and dependency changes |
Why fetch instead of catching the error?
Catching the timeout would hide the symptom, but traces would still silently fail to export over HTTPS. The HttpsClientRequest transport can't complete TLS handshakes in compiled binaries — the request never succeeds. Switching to fetch fixes the actual transport so traces reach the collector.
Test Plan
- 5 new unit tests for
FetchOtlpExporter(URL, headers, errors, shutdown, timeout) - 3 existing
otel_inittests pass - Full test suite: 3606 tests pass
-
deno check,deno lint,deno fmtall clean - Compiled binary, ran multi-step workflow with
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318— 17 spans exported to local Jaeger across full hierarchy (swamp.cli→swamp.workflow.run→swamp.workflow.job→swamp.workflow.step→swamp.model.method→swamp.driver.execute)
Fixes #889
🤖 Generated with Claude Code
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260327.152947.0-sha.c0abc5ac/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/v20260327.152947.0-sha.c0abc5ac/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/v20260327.152947.0-sha.c0abc5ac/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/v20260327.152947.0-sha.c0abc5ac/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/swamp 20260327.005915.0-sha.86500cc2
What's Changed
- fix: allow scoped @collective/name in workflow and definition names (#888)
Summary
Extension workflows using scoped names like @john/pod-inventory were rejected
at load time with a path traversal error because the WorkflowSchema and
DefinitionSchema name validation unconditionally rejected any name containing
/. The / in scoped @collective/name patterns is a namespace separator, not
a path traversal vector.
Root cause: The Zod refinement on the name field in both WorkflowSchema
(src/domain/workflows/workflow.ts:41-44) and DefinitionSchema
(src/domain/definitions/definition.ts:151-154) used a flat blocklist:
!name.includes("..") && !name.includes("/") && !name.includes("\\") && !name.includes("\0")This blocked all / characters, including legitimate ones in scoped extension
names like @john/pod-inventory or @swamp/aws/ec2.
Fix: Updated the inline validation in both schemas to allow / only when
the full name matches the established SCOPED_NAME_PATTERN
(^@[a-z0-9_-]+\/[a-z0-9_-]+(\/[a-z0-9_-]+)*$), which is the same regex used
in extension_manifest.ts. Unscoped names containing / (e.g. a/b,
/etc/passwd) are still rejected. The data_metadata.ts validation is
intentionally unchanged — data artifact names are internal and should not use
scoped patterns.
Changes:
src/domain/workflows/workflow.ts— Updated name validation refinementsrc/domain/definitions/definition.ts— Updated name validation refinementsrc/domain/workflows/workflow_test.ts— Added tests for scoped name
acceptance and malformed scoped name rejectionsrc/domain/definitions/definition_test.ts— Same test additions
Verified end-to-end: compiled binary, swamp repo init, swamp extension pull @john/k8s, swamp workflow search pod — all 13 workflows load without
warnings.
Test Plan
- Existing path traversal rejection tests pass (
..', unscoped/,\, null bytes) - New tests: scoped
@collective/nameaccepted (@john/pod-inventory,@swamp/aws/ec2) - New tests: malformed scoped names rejected (
@/,@scope/,@UPPER/case) - Full test suite: 3592 tests pass
-
deno check,deno lint,deno fmtall clean - E2E: compiled binary, pulled
@john/k8s, all 13 workflows load correctly
Fixes #887
🤖 Generated with Claude Code
Installation
macOS (Apple Silicon):
curl -L https://github.com/systeminit/swamp/releases/download/v20260327.005915.0-sha.86500cc2/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/v20260327.005915.0-sha.86500cc2/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/v20260327.005915.0-sha.86500cc2/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/v20260327.005915.0-sha.86500cc2/swamp-linux-aarch64 -o swamp
chmod +x swamp && sudo mv swamp /usr/local/bin/