Skip to main content
← Back to list
01Issue
FeatureShippedSwamp Club
Assigneesstack72

Relationships

#1143 UAT Phase 2: auth and agent commands

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

Summary

Bundled Phase 2 issue covering two small command families that both need HOME isolation:

  • auth (login/logout/whoami) — 3 new test files, new directory tests/cli/auth/
  • agent (setup/list/rm) — 3 new test files, new directory tests/cli/agent/

Total: 6 new test files. No real credentials or server access needed — all tests exercise error paths and local file manipulation with isolated HOME.

Dependency

Phase 8a landed. No other dependencies.

Existing State

Auth:

  • No tests/cli/auth/ directory exists — needs creating
  • One existing auth test: the SWAMP_API_KEY conflict test exists somewhere in the codebase (the coverage plan says "covered — keep"). Check with grep -rl "SWAMP_API_KEY" tests/cli/ before writing.
  • Auth writes to ~/.config/swamp/auth.json (mode 0600) — tests MUST isolate HOME

Agent:

  • No tests/cli/agent/ directory exists — needs creating
  • Agent state lives in .swamp-custom-tools.yaml at the repo root — repo-scoped, no HOME isolation needed
  • Agent is a repo command (requires initialized repo)

Verified Contracts

auth login

  • Credentials stored at ~/.config/swamp/auth.json (mode 0600), fields {serverUrl, apiKey, apiKeyId, username, collectives?}
  • Server resolution: --serverSWAMP_CLUB_URLhttps://swamp-club.com
  • Stdin flow selected when: --username OR --password OR --no-browser OR stdin not a TTY (piped tests always take stdin flow)
  • Empty username/password after prompts → "Username and password are required." exit 1
  • SWAMP_API_KEY set → "Already authenticated via SWAMP_API_KEY environment variable…" exit 1
  • Browser-open failure does NOT error (waits for callback)
  • JSON success: {authenticated:true, serverUrl, username} (not testable without a real server)

auth logout

  • Not logged in → exit 0, {loggedOut:false, reason:"not authenticated"} / "Not currently authenticated."
  • Logged in: removes auth.json; JSON {loggedOut:true, username, serverUrl}
  • SWAMP_API_KEY set → UserError exit 1

auth whoami

  • Unauthenticated → "Not authenticated. Run 'swamp auth login' to sign in." exit 1
  • JSON error has NO code field (§4.3) — assert this explicitly
  • status is an alias for whoami — test alias parity
  • JSON success: {authenticated:true, serverUrl, id, username, email, name, collectives?} (not testable without a real server)

agent setup

  • --json"agent setup requires interactive mode. Remove --json to run the wizard." exit 1
  • Name validation rule: /^[a-zA-Z0-9][a-zA-Z0-9-]*$/
  • Duplicate name → 'Custom tool "<name>" already exists…'

agent list

  • --json{tools:[…]}
  • Empty → "No custom tools defined. Run \swamp agent setup` to create one."` exit 0
  • Hand-authored .swamp-custom-tools.yaml → tools are listed

agent rm

  • Log-mode prompt 'Remove custom tool "<name>"…?' — decline → "Cancelled." exit 0
  • --json skips the prompt
  • JSON: {name, removed:true|false}
  • Asymmetry to pin: JSON mode exits 0 even when not found (removed:false), log mode throws 'Custom tool "<name>" not found.' exit 1
  • Removes entry from .swamp-custom-tools.yaml (list empty after)

New Test Files

auth/login_test.ts (NEW)

  • Piped (non-TTY) no-flags → stdin flow → empty-credentials error "Username and password are required.", exit 1 (must NOT hang waiting for input)
  • --username foo --password bar against unreachable SWAMP_CLUB_URL (set to http://localhost:1 or similar) → clean network error, no auth.json written in isolated HOME; JSON error envelope on stderr
  • SWAMP_API_KEY set → "Already authenticated via SWAMP_API_KEY environment variable…", exit 1
  • Must isolate HOME to a temp dir
  • Exit codes: 1 for all testable paths

auth/logout_test.ts (NEW)

  • Not logged in (clean isolated HOME) → exit 0, {loggedOut:false, reason:"not authenticated"} / "Not currently authenticated."
  • Hand-written auth.json in isolated HOME → logout removes the file, {loggedOut:true, username, serverUrl} with values from the hand-written file
  • SWAMP_API_KEY set → exit 1
  • JSON schema validated
  • Must isolate HOME to a temp dir
  • Exit codes: 0 (success/not-logged-in), 1 (SWAMP_API_KEY conflict)

auth/whoami_test.ts (NEW)

  • Unauthenticated → exit 1, exact message "Not authenticated. Run 'swamp auth login' to sign in."
  • JSON error envelope on stderr: assert error field present, assert code field is ABSENT (pin this per §4.3)
  • status alias parity: auth status output ≡ auth whoami output
  • Must isolate HOME to a temp dir
  • Exit codes: 1

agent/setup_test.ts (NEW)

  • --json"agent setup requires interactive mode. Remove --json to run the wizard.", exit 1
  • Exit codes: 1

agent/list_test.ts (NEW)

  • Empty (no .swamp-custom-tools.yaml) → hint message "No custom tools defined. Run \swamp agent setup` to create one."`, exit 0
  • Hand-authored .swamp-custom-tools.yaml with a valid tool entry → tools listed in output, JSON {tools:[…]} validated
  • Required YAML fields per tool: name, skillsDir, instructionsFile, instructionsMode (shared|owned), skillReferenceStyle (name|path)
  • Exit codes: 0

agent/rm_test.ts (NEW)

  • Remove existing tool → list is empty after
  • Log-mode decline (piped stdin, EOF = "no") → "Cancelled.", exit 0, tool still in list
  • Log-mode nonexistent tool → 'Custom tool "<name>" not found.', exit 1
  • JSON nonexistent → exit 0, {removed:false} — pin this asymmetry and file upstream bug
  • --json removes without prompt → {removed:true}
  • Exit codes: 0 (success/decline/JSON-not-found), 1 (log-not-found)

Schemas

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

  • AuthLogoutSchema{loggedOut, username?, serverUrl?, reason?}
  • AuthWhoamiSchema{authenticated, serverUrl, id, username, email, name, collectives?} (for future use — whoami success isn't testable without a server, but the schema documents the contract)
  • AgentListSchema{tools:[…]}
  • AgentRmSchema{name, removed}

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

Agent YAML Pattern

For agent list/rm tests, hand-author .swamp-custom-tools.yaml:

tools:
  - name: test-tool
    skillsDir: skills/
    instructionsFile: INSTRUCTIONS.md
    instructionsMode: shared
    skillReferenceStyle: name

Write this directly to ${repo.dir}/.swamp-custom-tools.yaml in the test.

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 each command by hand with isolated HOME. Verify auth.json format, agent YAML schema, and the rm asymmetry.
  • Check open swamp-uat PRs before starting

CI Shard Wiring

  • tests/cli/auth/ and tests/cli/agent/ are NEW directories — both must be added to the misc shard paths in ci.yml and uat.yml
  • The CI guard test will fail if they're not wired

How to Run & Verify

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

# Auth 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/auth/

# Agent 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/agent/

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

Definition of Done

  • 6 test files created: auth/login_test.ts, auth/logout_test.ts, auth/whoami_test.ts, agent/setup_test.ts, agent/list_test.ts, agent/rm_test.ts
  • Both new directories added to misc shard paths in ci.yml and uat.yml
  • All auth tests isolate HOME to a temp directory
  • Agent rm asymmetry pinned (JSON exit 0 vs log exit 1 for not-found) and upstream bug filed
  • Whoami JSON error explicitly asserts code field is absent
  • 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+ 3 MOREFINDINGS+ 3 MOREPR_MERGED+ 1 MORENOTIFICATION_SKIPPED

Shipped

7/14/2026, 11:19:02 PM

Click a lifecycle step above to view its details.

03Sludge Pulse
stack72 assigned stack727/14/2026, 3:30:53 PM

Sign in to post a ripple.