Skip to main content
← Back to list
01Issue
FeatureShippedUAT
Assigneesstack72

Relationships

#1128 UAT Phase 2: source commands and completions extension

Opened by stack72 · 7/14/2026· Shipped 7/14/2026

Summary

Bundled Phase 2 issue covering two small command families:

  • source (fetch/path/clean) — 3 new test files, new directory tests/cli/source/
  • completions (extend existing) — extend tests/cli/completions/shells_test.ts with custom completion action checks

Total: 3 new test files + 1 extended file.

Dependency

Phase 8a landed. No other dependencies.

Existing State

Source:

  • No tests/cli/source/ directory exists — needs creating
  • Source commands write to ~/.swamp/source/ and metadata .swamp-source-meta.json — tests MUST isolate HOME / XDG_CONFIG_HOME to a temp dir

Completions:

  • tests/cli/completions/shells_test.ts exists — currently checks that bash/zsh/fish scripts are non-empty and contain basic markers (#!/usr/bin/env bash, #compdef swamp, #!/usr/bin/env fish)
  • Needs extending with custom completion action checks

Verified Contracts

source fetch

  • Default version = the binary's VERSION
  • URL: https://github.com/swamp-club/swamp/archive/refs/tags/v<version>.tar.gz (mainheads/[HOST-1])
  • Dev builds (VERSION ending -sha.) produce a tag that 404s — use --version main or expect 'Source version "<v>" not found…'
  • Re-fetch of a DIFFERENT version deletes the old source dir BEFORE downloading (mid-download failure ⇒ no source at all — pin this)
  • Offline / unreachable → "Download failed: <msg>" exit 1, no metadata written
  • JSON: {status:"fetched"|"already_fetched", version, path, fileCount, fetchedAt, previousVersion?}
  • Paths: ~/.swamp/source/, metadata .swamp-source-meta.json

source path

  • {status:"found", version, path, fileCount, fetchedAt} when source exists
  • {status:"not_found"} when no source fetched
  • Log not-found: "No source fetched. Run \swamp source fetch` first."`

source clean

  • Idempotent: {status:"cleaned"|"not_found", path}
  • Never errors (always exit 0)

completions (custom completion actions)

  • Generated bash/zsh/fish scripts contain references to the custom completion actions model_name, model_type, workflow_name (registered as globalTypes, mod.ts:1267-1269)
  • These are used on model/workflow/data args for tab completion

New Test Files

source/path_test.ts (NEW)

  • Not fetched → {status:"not_found"} / log hint "No source fetched. Run \swamp source fetch` first."`, pin exit code (verify in Task 0 — likely exit 0)
  • After faking a source dir + metadata (hand-write ~/.swamp/source/ dir and .swamp-source-meta.json in the isolated HOME) → {status:"found", version, path, fileCount, fetchedAt} shape validated
  • JSON schema: SourcePathSchema
  • Must isolate HOME to a temp dir
  • Exit codes: 0

source/clean_test.ts (NEW)

  • Idempotent on empty (no source dir) → {status:"not_found"}, exit 0
  • After faking a source dir → clean removes it → {status:"cleaned"}, exit 0
  • Second clean after first → {status:"not_found"} again (idempotent)
  • JSON schema: SourceCleanSchema
  • Must isolate HOME to a temp dir
  • Exit codes: always 0

source/fetch_test.ts (NEW)

  • Unreachable network (set a bogus HTTPS_PROXY or equivalent to prevent network access) → "Download failed:" exit 1, no metadata file written, no partial source dir left behind
  • Dev-version tag 404 message: run with default version on a dev build → pin the 'Source version "<v>" not found…' message
  • JSON schema: SourceFetchSchema (for the error shape on stderr)
  • Must isolate HOME to a temp dir
  • Exit codes: 1 for failures
  • NOTE: Do NOT actually download source from GitHub in tests — only test the failure paths. The success path would require network access to GitHub.

completions/shells_test.ts (EXTEND)

Add tests to the existing file:

  • Bash script references model_name custom completion action
  • Bash script references model_type custom completion action
  • Bash script references workflow_name custom completion action
  • Zsh script references the same three actions
  • Fish script references the same three actions (may use different identifiers — verify in Task 0)

These are simple assertStringIncludes or assertMatch calls on the existing completion script output.

Schemas

Add to src/cli/helpers/schemas.ts:

  • SourcePathFoundSchema{status: z.literal("found"), version, path, fileCount, fetchedAt}
  • SourcePathNotFoundSchema{status: z.literal("not_found")}
  • SourceCleanSchema{status: z.enum(["cleaned", "not_found"]), path}
  • SourceFetchSchema{status: z.enum(["fetched", "already_fetched"), version, path, fileCount, fetchedAt, previousVersion?} (may not be testable without network — verify if error output is also JSON)

Use .passthrough() (matching existing codebase convention).

HOME Isolation Pattern

Source commands read/write ~/.swamp/source/. Tests MUST isolate HOME:

Deno.test("swamp source path reports not_found when no source fetched", async () => {
  const tmpHome = await Deno.makeTempDir();
  try {
    const result = await runCommand(runner, Deno.cwd(), ["source", "path", "--json"], {
      env: { HOME: tmpHome, XDG_CONFIG_HOME: `${tmpHome}/.config` },
    });
    // assert {status: "not_found"}
  } finally {
    await Deno.remove(tmpHome, { recursive: true });
  }
});

Verify in Task 0 that runCommand supports env overrides, or use the appropriate helper pattern.

Ground Rules

  • Read CLAUDE.md in the repo root first
  • Tests are more accurate than the code under test. Assert the documented contract. If swamp disagrees, file upstream.
  • Use the github-pr skill for commits and PR creation
  • Task 0 — ground truth: Build tip-of-main swamp, run source path --json, source clean --json, source fetch --json by hand (with isolated HOME). Run completions bash | grep model_name to verify custom actions appear.
  • Check open swamp-uat PRs before starting

CI Shard Wiring

  • tests/cli/source/ is a NEW directory — must be added to the misc shard paths in ci.yml and uat.yml
  • tests/cli/completions/ is already in the misc shard — no changes needed for the extension
  • The CI guard test will fail if the new directory isn't wired

How to Run & Verify

deno task fmt
deno task lint
deno task check
deno task test

# Source tests
SWAMP_NO_TELEMETRY=1 SWAMP_SOURCE_DIR=~/code/swamp-club/swamp deno test --allow-read --allow-write --allow-env --allow-run --allow-net tests/cli/source/

# Completions tests
SWAMP_NO_TELEMETRY=1 SWAMP_SOURCE_DIR=~/code/swamp-club/swamp deno test --allow-read --allow-write --allow-env --allow-run --allow-net tests/cli/completions/

# Full CLI suite
SWAMP_NO_TELEMETRY=1 SWAMP_SOURCE_DIR=~/code/swamp-club/swamp deno task uat:cli

Definition of Done

  • 3 new test files created: source/path_test.ts, source/clean_test.ts, source/fetch_test.ts
  • completions/shells_test.ts extended with custom completion action checks
  • tests/cli/source/ added to misc shard paths in ci.yml and uat.yml
  • All source tests isolate HOME to a temp directory
  • Zod schemas added to schemas.ts
  • Every test spawns the real swamp binary — no mocking
  • Every test asserts an explicit exit code
  • Every --json test validates through a Zod schema
  • deno task fmt && deno task lint && deno task check && deno task test all green
  • SWAMP_NO_TELEMETRY=1 SWAMP_SOURCE_DIR=~/code/swamp-club/swamp deno task uat:cli passes
  • PR opened via github-pr skill, branching from main
02Bog Flow
OPENTRIAGEDIN PROGRESSSHIPPED+ 1 MOREASSIGNED+ 2 MOREREVIEW+ 3 MOREPR_MERGED+ 1 MORENOTIFICATION_SKIPPED

Shipped

7/14/2026, 1:36:38 AM

Click a lifecycle step above to view its details.

03Sludge Pulse
stack72 assigned stack727/14/2026, 12:19:36 AM

Sign in to post a ripple.