Commit graph

175 commits

Author SHA1 Message Date
A
fa516bad89
fix: improve spawn list and clouds UX (#491)
- Show prompt preview in `spawn list` history for prompted runs
- Include prompt in rerun hint when last spawn used --prompt
- Show auth requirements in `spawn clouds` listing
- Change swap detection from warn to info (auto-correcting, not a warning)
- Update `spawn clouds` help text: "for setup instructions" instead of "for details"

Bump CLI version to 0.2.46.

Agent: ux-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-11 10:34:28 -08:00
A
bc89a2821b
test: add 43 tests for list display logic (formatTimestamp, parseListFilters, cmdList) (#489)
Cover the history list feature display layer added in PRs #486-#488:
- formatTimestamp: valid ISO, invalid dates, edge cases (epoch, far future)
- parseListFilters: -a/-c flag extraction, missing values, duplicates, ordering
- cmdList output: table headers, rerun hint, count summary, filter messages,
  newest-first ordering, singular/plural, corrupted history resilience

Agent: test-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 10:29:50 -08:00
A
6c0e9116a5
fix: show spawn history newest-first with rerun hint (#488)
`spawn list` now shows records in reverse chronological order (newest
first), matching the convention of git log, shell history, and docker ps.
Adds a "Rerun last" hint showing the command to repeat the most recent spawn.

Agent: ux-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-11 10:11:50 -08:00
A
783cba86d5
test: add 34 tests for history module (loadHistory, saveSpawnRecord, filterHistory) (#487)
The history.ts module had zero test coverage. This adds comprehensive tests for:
- getSpawnDir: SPAWN_HOME env var and ~/.spawn fallback
- getHistoryPath: correct path composition
- loadHistory: missing file, valid data, invalid JSON, non-array JSON, empty file
- saveSpawnRecord: directory creation, append, prompt field, pretty JSON, corruption recovery
- filterHistory: agent/cloud/combined filters, case-insensitivity, no-match cases

Agent: test-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 10:10:12 -08:00
A
a932bc3734
feat: store spawn history locally and repurpose spawn list (#486)
- Rename `spawn list` -> `spawn matrix` (alias: m) for the availability matrix
- New `spawn list` / `spawn ls` shows previously provisioned agents from ~/.spawn/history.json
- Support filtering: `spawn list -a <agent>`, `spawn list -c <cloud>`
- Auto-record each spawn with agent, cloud, timestamp, and prompt
- History path respects SPAWN_HOME env var for testability
- Bump CLI version to 0.2.44

Fixes #483

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 10:01:48 -08:00
A
c65b11abbe
test: add 24 tests for missing-cloud error paths and suggestCloudsForPrompt (#485)
Cover untested error paths in index.ts when agent/cloud arguments are missing:
- suggestCloudsForPrompt: --prompt with agent but no cloud shows cloud suggestions
- handleNoCommand: --dry-run and --prompt without any args
- handleDefaultCommand: --dry-run with agent but no cloud
- --prompt-file with agent but no cloud
- Combined flag edge cases

Agent: test-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-11 09:43:31 -08:00
A
7cb37ba88d
fix: show both agent and cloud errors at once instead of one at a time (#484)
Previously, `spawn badagent badcloud` would only show the agent error,
requiring users to fix it and re-run before discovering the cloud was
also wrong. Now both errors are shown together so users can fix
everything in one round trip.

Refactors validateEntity into checkEntity (returns bool) + validateEntity
(exits). cmdRun uses checkEntity for batch validation.

Agent: ux-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 09:40:43 -08:00
A
285bc4c5c2
test: add 41 tests for dry-run preview feature (#482)
The showDryRunPreview function (added in PR #479) had only 1 basic
subprocess test. These tests cover all branches: agent info display
(name, description, install, launch), cloud info (name, description,
defaults), script URL format, env var display with OPENROUTER_API_KEY
redaction, prompt truncation at 100 chars, section ordering, and
verification that no script download occurs in dry-run mode.

Agent: test-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 09:13:14 -08:00
A
7fa9325683
refactor: deduplicate resolveAgentKey/resolveCloudKey into shared resolveEntityKey (#481)
Agent: complexity-hunter

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 09:11:41 -08:00
A
5851a9ce7b
fix: show error when --dry-run used without agent and cloud args (#480)
`spawn --dry-run` silently entered interactive mode, ignoring the flag.
Now it shows an actionable error like `--prompt` does. Also adds
`--dry-run` to the README commands table.

Agent: ux-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 09:09:57 -08:00
A
ca510881f1
feat: add --dry-run flag to preview provisioning details (#478)
Allows users to see what would be provisioned (agent, cloud, server specs,
script URL, env vars) without actually spinning up a server.

Fixes #474

Agent: issue-fixer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 08:56:59 -08:00
A
d41706a377
test: add 39 tests for untested shared/common.sh helper functions (#477)
Cover _load_json_config_fields, _save_json_config, extract_ssh_key_ids,
_generate_csrf_state, and interactive_pick -- all had zero test coverage
despite being used by every cloud provider script.

Agent: test-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 08:49:18 -08:00
A
2ed89d5b52
refactor: reduce complexity in ensure_multi_credentials and handleDefaultCommand (#476)
Extract 4 helper functions from ensure_multi_credentials() (94 lines, CC=14
-> 48 lines, CC=4): _multi_creds_all_env_set, _multi_creds_load_config,
_multi_creds_prompt, _multi_creds_validate.

Flatten handleDefaultCommand() (39 lines, CC=7 -> 15 lines, CC=3) by
extracting suggestCloudsForPrompt() and using early returns to eliminate
nested if/else blocks.

Agent: complexity-hunter

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 08:45:47 -08:00
A
cbee5a8f15
fix: add -f shorthand for --prompt-file and improve CLI UX (#475)
- Add -f as short form for --prompt-file (parity with -p for --prompt)
- Show runnable command in "Did you mean" suggestions
- Show agent install command in agent info page
- Add agent count to "spawn agents" header (consistent with "spawn clouds")
- Update help text and examples to document -f flag
- Bump CLI version to 0.2.40

Agent: ux-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 08:44:43 -08:00
A
1f6133dc47
test: fix 5 failing tests, add 31 cmdHelp content tests, remove stale skips (#472)
Fix download error tests that checked wrong mock target (consoleMocks.error
vs mockLogError) and expected outdated "Troubleshooting" text instead of
"How to fix". Remove 11 stale describe.skip blocks from commands.test.ts
that have been superseded by dedicated test files using mock.module().
Add cmd-help-content.test.ts with 31 tests verifying help output includes
all subcommands, flags, sections, and key content.

Before: 4579 pass, 5 fail, 11 skip
After:  4615 pass, 0 fail, 0 skip

Agent: test-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 08:25:15 -08:00
A
6e789f8cbf
fix: improve error message consistency and clarity across CLI (#470)
- Style all error messages with colored output (pc.red for errors, pc.cyan for commands)
- Fix inconsistent OpenRouter key URL (openrouter.ai/keys -> openrouter.ai/settings/keys)
- Improve exit code 130 guidance to suggest cloud dashboard instead of unhelpful spawn command
- Add actionable recovery hints to token/credential validation failures
- Remove redundant "Invalid input" message from validated_read (validator already shows error)
- Fix nested color codes in cmdUpdate failure spinner
- Clean up version display when binary path is unavailable

Agent: ux-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 08:17:14 -08:00
A
f0dc891a51
refactor: deduplicate agent/cloud validation into generic validateEntity (#469)
Merged four nearly-identical functions (validateAgent, validateCloud,
validateAndGetAgent, validateAndGetCloud) into two generic ones
(validateEntity, validateAndGetEntity), eliminating ~20 lines of
duplicated validation, fuzzy matching, and swap-detection logic.

Agent: complexity-hunter

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 08:14:19 -08:00
A
e38a75ea17
test: add 42 tests for download fallback pipeline and failure reporting (#467)
Cover the real code paths through cmdRun for script downloading, fallback
to GitHub raw URLs, error reporting on 404/500/network errors, script
content validation, and exit code guidance. Tests exercise the actual
exported functions (getScriptFailureGuidance, getStatusDescription,
getErrorMessage) rather than reimplemented copies.

Agent: test-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 07:47:05 -08:00
A
d9037fad32
fix: improve error messages and UX consistency across CLI and shell scripts (#466)
- Clarify download error messages: distinguish HTTP errors from network errors
  with specific status codes in the message
- Add actionable next steps to OAuth timeout: re-run command or set key manually
- Standardize error help labels to "How to fix:" across CLI and shell scripts
  (was inconsistently "What to do:", "Troubleshooting:", or missing)
- Add API method/endpoint context to retry failure messages so users know
  which API call failed
- Make verify_agent_installed error cases mutually exclusive: first for
  PATH/installation issues, second for runtime/dependency issues

Agent: ux-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 07:46:56 -08:00
A
f95d2e4a97
test: add 114 security regression tests for upload_file across all clouds (#465)
Static analysis tests that verify every cloud's upload_file() function
uses safe patterns to prevent command injection. Tests cover:
- Path validation (single-quote, $, backtick rejection) or printf '%q' escaping
- Base64 content encoding before shell embedding
- printf '%s' for safe output (no echo with variable expansion)
- No eval on user-controlled input
- PR #453 regression tests for fly, northflank, daytona, e2b, koyeb
- Classification of all 30+ clouds into safe categories (ssh/scp/cp/exec-based)

Agent: test-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-11 07:26:28 -08:00
A
9d50d8101b
fix: improve user-facing messages and error text across CLI and shell scripts (#464)
- Cancel handling: use p.outro instead of red error text for user cancellation
- Exit code 130: warn that server may still be running instead of falsely claiming it isn't
- Download errors: hide internal URLs, show user-friendly "could not be found" message
- Compact list legend: use "not yet available" consistently instead of jargon "missing"
- Update messages: say "Run your spawn command again" instead of vague "Restart your command"
- API token errors: show friendly "special characters" message instead of listing forbidden chars
- OAuth fallback: explain this is normal on remote/SSH/headless environments
- Interactive picker: show what was entered and valid range on invalid selection
- Bump CLI version to 0.2.39

Agent: ux-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-11 07:26:00 -08:00
A
1316f9f609
fix: show runtime/platform in spawn version, clarify compact list legend (#456)
- `spawn version` now shows runtime (bun/node), version, platform,
  and architecture for easier bug reporting and diagnostics
- Compact list legend changed from confusing "N/N" to descriptive
  "green = all clouds  yellow = some missing"
- Bump CLI to v0.2.38

Agent: ux-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-11 06:55:24 -08:00
A
b4580b4f8f
test: fix 6 broken tests and add coverage for exit code branches (#455)
The getScriptFailureGuidance function was updated (PRs #449, #450) to
add dedicated handlers for exit codes 130, 137, 255, and 2, but the
existing tests still expected these to fall through to the default case.

Fixed 4 broken assertions in script-failure-guidance.test.ts and 2 in
exec-script-errors.test.ts. Added 16 new tests covering the specific
guidance for each newly handled exit code (130=Ctrl+C, 137=OOM/killed,
255=SSH failure, 2=shell syntax error).

Agent: test-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-11 06:55:00 -08:00
A
55fd4022e8
fix: improve error messages with actionable guidance for common failures (#452)
- Add signal exit code handling (130/Ctrl+C, 137/killed, 255/SSH failure, 2/syntax error)
- Replace vague "Cloud API retry logic exhausted" with attempt count and retry advice
- Add network troubleshooting hint to API network error after retries
- Clarify OAuth fallback prompt: explain why OAuth failed and what happens next
- Consolidate auth cancellation message with three clear recovery options

Agent: ux-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 06:26:19 -08:00
A
f2c9af0d79
test: add 35 tests for getScriptFailureGuidance() exit code branches (#451)
Cover all exit code paths in getScriptFailureGuidance() which had zero
direct test coverage despite being recently modified (PRs #450, #449):
- Exit code 127: command not found guidance with tool listing
- Exit code 126: permission denied message
- Exit code 1: credential/API/provisioning failure hints
- Default case: generic troubleshooting for unknown exit codes
- null exit code: falls through to default
- Edge cases: 0, negative, large codes, signal codes (130, 137)
- Structure: return type validation, non-empty arrays, distinct output

Agent: test-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-11 06:25:54 -08:00
A
79cf25d210
fix: improve 404 error message in reportDownloadFailure() (#450)
The old message "This agent + cloud combination doesn't exist yet" was
misleading because by the time reportDownloadFailure runs, the agent/cloud
combination has already been validated in the manifest. A 404 means the
script file is missing from the server, not that the combination is invalid.

New message explains the script couldn't be found, suggests checking the
matrix, retrying, or reporting the issue. Also adds a hint about temporary
server issues for 500-level errors.

Agent: ux-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 05:58:27 -08:00
A
4b76b3422c
refactor: reduce complexity in execScript and netcup pick functions (#449)
Extract error handling from execScript() into dedicated helpers
(reportDownloadError, reportScriptFailure, getScriptFailureGuidance),
reducing the function from 52 to 15 lines and making error guidance
directly testable.

Replace duplicated _pick_vps_product() and _pick_datacenter() in
netcup/lib/common.sh with calls to shared interactive_pick(),
eliminating ~60 lines of copy-pasted selection logic.

Net reduction: 42 lines (-98/+56).

Agent: complexity-hunter

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 05:56:48 -08:00
A
02ecd4123b
test: add 15 tests for cmdInteractive cancel and selection paths (#448)
cmdInteractive is the primary user entry point (bare `spawn` command) with
zero test coverage. Adds tests for: user cancels agent/cloud selection via
Ctrl+C, agent with no implemented clouds, happy path through selection to
script execution, intro/outro messaging, and run-directly hint.

Agent: test-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 05:55:27 -08:00
A
e9e5f1bfea
fix: improve error messages with actionable guidance (#447)
- validatePrompt max-length error now suggests --prompt-file alternative
- validateScriptContent shebang error explains likely download issue
- Compact list view now shows color legend (green=all, yellow=partial)
- Exit code 1 gets specific guidance (credentials, API, provisioning)
- cmdUpdate network error shows current version for context
- Bump CLI version to 0.2.37

Agent: ux-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 05:20:31 -08:00
A
305a782fea
test: add 496 manifest type contract validation tests (#446)
Validates that every field in manifest.json conforms to TypeScript type
definitions (AgentDef, CloudDef) at runtime. Catches data quality issues
that truthiness-only checks miss:

- Required fields are correct types (string, not number/boolean/array)
- Agent env values are all strings with valid env var name keys
- Agent env references OPENROUTER_API_KEY (mandatory per CLAUDE.md)
- Optional fields (pre_launch, deps, config_files, interactive_prompts,
  dotenv, notes, defaults) have correct types when present
- dotenv has path (string) and values (Record<string, string>)
- interactive_prompts entries have prompt+default string fields
- config_files values are objects with path-like keys
- deps is an array of strings
- Cloud type values are lowercase
- Env var interpolation ${...} references valid env var names
- Launch commands don't contain dangerous shell metacharacters
- Display names are unique, agent keys don't collide with cloud keys
- Matrix covers all cloud/agent combinations exhaustively

Agent: test-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 05:20:13 -08:00
A
2bc95fdf15
test: add tests for validateImplementation branching (0, 1-3, >3 clouds) (#442)
Cover the untested code paths in validateImplementation (commands.ts
lines 233-256) that show different error messages based on how many
alternative clouds are available for an agent:
- 0 clouds: "no implemented cloud providers" + suggest "spawn list"
- 1-3 clouds: show all available clouds as examples
- >3 clouds: show first 3 examples + "Run spawn X to see all N options"
- Boundary: exactly 3 vs 4 clouds threshold
- Error message formatting (display names, singular/plural)

24 new tests, all passing (3865 total).

Agent: test-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 04:48:52 -08:00
A
10a40ca574
fix: add log_step for progress messages, fix misleading prompt error (#440)
- Add log_step() function (cyan) for status/progress messages
- Convert misused log_warn calls to log_step in shared/common.sh
  (14 instances: SSH key gen, agent verification, waiting, configuring)
- Convert representative cloud scripts: hetzner, digitalocean, sprite
- Fix misleading validatePrompt error that suggested --prompt-file as a
  workaround when it has the same validation

Agent: ux-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 04:28:17 -08:00
A
5722e13851
test: add 21 tests for execScript bash execution error handling (#433)
Cover the critical untested error paths in commands.ts when spawn scripts
fail with specific exit codes: 127 (command not found), 126 (permission
denied), 130 (Ctrl+C), and generic failures with troubleshooting advice.

Agent: test-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 04:24:09 -08:00
A
3e34133f54
test: fix non-TTY test expectations to match actual CLI behavior (#432)
Tests expected help output (USAGE/EXAMPLES) in non-TTY mode, but the CLI
actually shows a "No interactive terminal detected" hint with exit code 1.

Agent: test-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-11 04:09:53 -08:00
A
a1509ac8b3
fix: improve CLI error messages and cloud auth display (#431)
- Show URL hint only on the first auth var in multi-auth cloud quick-start
  (eliminates duplicate URLs for clouds like Contabo with 4 auth vars)
- Make script failure error messages exit-code-aware: show targeted guidance
  for command-not-found (127) and permission-denied (126) exit codes
- Consolidate generic failure hints into "Common causes" section

Agent: ux-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-11 04:07:45 -08:00
A
81f1630424
test: Add 65 tests for untested shared/common.sh functions (#428)
Cover critical bash functions that had zero test coverage:
- validate_oauth_port: port validation boundary cases and injection
- generate_env_config: shell export generation and value escaping
- calculate_retry_backoff: exponential backoff with jitter range
- _update_retry_interval: indirect variable update via printf -v
- _parse_api_response: HTTP response code extraction
- _api_handle_transient_http_error: retry exhaustion messaging
- get_cloud_init_userdata: cloud-init YAML content validation

Agent: test-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 03:45:13 -08:00
A
5c4f830fea
fix: improve credential guidance in error messages and quick-start hints (#427)
- Show cloud provider URL alongside credential env vars in quick-start
  sections (both `spawn <agent>` and `spawn <cloud>` info views)
- Restructure script failure errors: separate credential issues from
  other causes, inline the `spawn <cloud>` hint next to cloud credentials
- Replace "Check cloud-specific READMEs" with actionable `spawn <cloud>`
  in help troubleshooting section
- Show concise 4-line guidance instead of full help dump when spawn is
  run without a TTY (e.g. piped or in CI)
- Add `spawn <agent> <cloud>` as primary action in `spawn list` footer

Agent: ux-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 03:42:55 -08:00
A
bb4f0c29df
fix: improve credential guidance in error messages and quick-start hints (#426)
- Add OPENROUTER_API_KEY as first item in script failure error (most common cause)
- Replace external GitHub README link with actionable `spawn <cloud>` command in error output
- Fix help text: auth section now correctly says `spawn <cloud>` instead of `spawn <agent> <cloud>`
- Add inline URL hint next to OPENROUTER_API_KEY in quick-start sections
- Add cloud name label next to cloud auth vars in agent info quick-start

Agent: ux-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 03:21:15 -08:00
A
2f03f746ec
test: Add 54 tests for warnExtraArgs and dispatchCommand routing (#424)
Cover the critical untested paths from PR #422:
- warnExtraArgs: singular/plural warning, boundary cases
- dispatchCommand: IMMEDIATE_COMMANDS, SUBCOMMANDS, default handler routing
- SUBCOMMANDS --help flag redirect behavior
- showVersion output format
- End-to-end dispatch scenarios

Agent: test-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 03:19:02 -08:00
A
0181b73506
fix: warn on extra args and detect mismatched agent/cloud types (#422)
- Warn when extra positional arguments are silently ignored (e.g. "spawn
  claude sprite hetzner" now shows that "hetzner" was ignored)
- Detect when user passes two agents (e.g. "spawn claude aider") and
  explain that the second arg should be a cloud, not an agent
- Detect when user passes two clouds (e.g. "spawn hetzner sprite") and
  explain that the first arg should be an agent, not a cloud
- Add tests for both new behaviors

Agent: ux-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-11 02:58:34 -08:00
A
df733d786b
test: Add 34 tests for --prompt-file error handling paths (#421)
Tests handlePromptFileError formatting for ENOENT, EACCES, EISDIR, and
generic error codes. Also tests --prompt-file success path with real
files, edge cases (spaces in paths, dots, deeply nested paths, /dev/null),
mutual exclusion with --prompt, and missing cloud argument errors.

Agent: test-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 02:58:14 -08:00
A
d890740155
refactor: reduce complexity by extracting helpers from main(), cmdCloudInfo(), and resolvePrompt() (#418)
- Extract main() (73 lines) into handleNoCommand(), showVersion(), dispatchCommand() + main() (20 lines)
- Extract cmdCloudInfo() (53 lines) into printCloudQuickStart(), printAgentList() + cmdCloudInfo() (26 lines)
- Extract resolvePrompt() error handling into handlePromptFileError() (37 lines from 50)
- Move IMMEDIATE_COMMANDS and SUBCOMMANDS to module-level constants

Agent: complexity-hunter

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 02:37:32 -08:00
A
42655b6e24
test: Add 57 tests for findClosestKeyByNameOrKey fuzzy matching (#419)
The findClosestKeyByNameOrKey function (added in PR #414) had zero direct
test coverage. This function is used in validateAgent, validateCloud, and
showInfoOrError for typo suggestions. Tests cover key-based matching,
display name matching, priority between key vs name matches, multiple
key competition, edge cases, and integration with manifest-like data.
Also adds boundary tests for levenshtein, findClosestMatch threshold,
and resolveAgentKey/resolveCloudKey display name edge cases.

Agent: test-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 02:36:00 -08:00
A
fa11fed516
fix: improve UX with version hints, clearer non-TTY message, and retry bug fix (#417)
- Add "spawn update" hint to version output so users know how to update
- Simplify non-interactive TTY message (less alarming, more actionable)
- Fix _api_handle_transient_http_error passing wrong first arg to
  _api_should_retry_on_error (was "http_429" instead of attempt number)
- Sync README matrix count (444 -> 445)

Agent: ux-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 02:33:38 -08:00
A
83440dd6f3
fix: improve fuzzy matching to check display names for better typo suggestions (#414)
Fuzzy matching now checks both keys (e.g. "claude") and display names
(e.g. "Claude Code") when suggesting corrections for typos. Previously,
typing "spawn claud" or "spawn Hetzne" would only fuzzy-match against
keys, missing close display name matches. The new findClosestKeyByNameOrKey
function picks the best match across both, and suggestions now always
show the display name for clarity (e.g. "Did you mean claude (Claude Code)?").

Agent: ux-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 02:06:52 -08:00
A
2e7a362fc5
test: Add 23 tests for swapped args detection, resolution logging, and manifest validation (#412)
Tests three previously untested logic paths in commands.ts and manifest.ts:
- detectAndFixSwappedArgs: 8 tests covering swap detection, no-swap cases,
  and swap with missing implementations
- resolveAndLog: 6 tests for case-insensitive key and display name resolution
- isValidManifest: 7 tests for manifest structure validation via loadManifest
- Prompt handling with swapped args: 2 tests for prompt+swap interaction

Agent: test-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-11 02:06:20 -08:00
A
57b1714668
test: Add 57 tests for previously untested exported utility functions (#409)
Add direct unit tests for parseAuthEnvVars, getImplementedAgents,
getMissingClouds, getErrorMessage, getStatusDescription,
calculateColumnWidth, getTerminalWidth, and getImplementedClouds.

These functions were either completely untested or only tested via
inline replicas rather than the actual exports. parseAuthEnvVars is
particularly important as it parses auth config strings used in
user-facing quick-start instructions.

Agent: test-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-11 01:39:45 -08:00
A
387a231a78 test: Update prompt-file error message assertions to match UX improvements
Tests expected old error wording after PR #387 changed the messages.

Agent: team-lead
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 09:26:55 +00:00
A
b760191a9e
test: Add 122 tests for shared/common.sh bash validation functions (#389)
Add comprehensive test coverage for the security-critical bash validation
functions in shared/common.sh that had zero TypeScript test coverage.
Tests run actual bash subprocesses to catch real shell behavior (regex
engine quirks, quoting edge cases) that TypeScript replica tests miss.

Functions covered:
- validate_model_id: 15 tests (valid models, injection attempts)
- validate_server_name: 21 tests (valid names, boundaries, injection)
- validate_api_token: 27 tests (valid tokens, metachar injection)
- validate_region_name: 12 tests (valid regions, boundaries)
- validate_resource_name: 10 tests (valid names, boundaries)
- json_escape: 11 tests (special chars, SSH key injection, round-trip)
- Cross-function security: 12 tests (common injection patterns)

Agent: test-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-11 01:23:09 -08:00
A
5a0fe00d4a
refactor: Extract helpers to reduce complexity in commands.ts (#388)
- Extract resolveAndLog() from cmdRun to handle argument resolution
- Extract detectAndFixSwappedArgs() from cmdRun for swap detection
- Extract printInfoHeader() shared by cmdAgentInfo and cmdCloudInfo
- Extract groupByType() used by cmdAgentInfo, cmdCloudInfo, cmdClouds
- Extract printGroupedList() for displaying grouped items with hints

All tests pass (3260/3260). No functional changes.

Agent: complexity-hunter

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-11 01:17:15 -08:00