Commit graph

1130 commits

Author SHA1 Message Date
A
8564e6d984
refactor: reduce complexity in cmdConnect and setup_claude_code_config (#1191)
Extract helper functions to reduce nesting and duplication:

1. cmdConnect (54 → 28 lines): Extract runInteractiveCommand() helper to
   eliminate duplicate spawn/Promise handling for Sprite and SSH connections

2. interactiveListPicker (48 → 21 lines): Extract handleRecordAction() helper
   to reduce nesting in reconnect/rerun logic

3. setup_claude_code_config (46 → 40 lines): Extract _generate_claude_code_settings()
   and _generate_claude_code_state() helpers to clarify JSON generation and
   make the main function focus on orchestration

All changes preserve existing behavior and pass existing tests.

Agent: complexity-hunter

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-15 05:18:40 -05:00
A
90417c2e1b
test: fix agent-config-setup.test.ts - shell mocking for HOME variable substitution (#1195)
All 40 tests in agent-config-setup.test.ts now pass by properly handling
$HOME variable substitution in mock_run callbacks. Added createMockSetup()
helper function to DRY up repeated mock configuration across openclaw and
continue tests (16 tests total).

Changes:
- Fix mock_run() to replace $HOME before evaluating commands
- Add createMockSetup(tempDir, configDir) helper to reduce code duplication
- Update all setup_openclaw_config and setup_continue_config tests to use helper
- Ensures /tmp/spawn_config_* temp files are redirected to temp test directory

Agent: test-engineer

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-15 05:16:11 -05:00
L
1ddf2695d0
fix: document Sprite vs normal VM paths in SKILL.md, never invent directories (#1196)
- Add environment table: Sprite VMs use /home/sprite/, normal VMs use /root/
- Replace all hardcoded /root/spawn paths with <REPO_ROOT> placeholders
- Instruct agents to ask the user for the repo path, never guess
- Explicitly ban inventing directories like /home/claude-runner/

Co-authored-by: Security Reviewer <security-reviewer@spawn.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-15 02:10:43 -08:00
L
5b4f02d9b1
fix: clarify monitoring loop requirements to prevent early session termination (#1194)
All four run modes (team_building, triage, review_all, scan) now have
explicit "Monitor Loop (CRITICAL)" sections with step-by-step instructions:

1. Call TaskList to check task status
2. Process completed tasks/messages
3. Call Bash("sleep 15") to wait
4. REPEAT until done or timeout

This fixes the issue where team leads would spawn teammates, then fail
to enter the monitoring loop, causing the session to end prematurely
(since "session ENDS when you produce a response with NO tool calls").

The previous vague instruction "Loop: TaskList → process → sleep 5"
was insufficient. The new format makes it crystal clear that:
- The loop must be INFINITE (keep repeating)
- EVERY iteration must include BOTH TaskList AND Bash sleep calls
- The session will end if you stop calling tools

This addresses the bug where review_all sessions ended after ~115s
instead of running the full 30min cycle.

Co-authored-by: Security Reviewer <security-reviewer@spawn.dev>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-15 01:43:17 -08:00
A
3db288c3dd
feat: trim to 9 curated launch clouds, upvote-driven discovery (#1184)
Reduce from 41 cloud providers to 10 (9 + local) curated for launch:
- local (free), oracle (free tier), hetzner (~€3.29/mo), ovh (~€3.50/mo),
  fly (free tier), aws-lightsail ($3.50/mo), daytona (pay-per-second),
  digitalocean ($4/mo), gcp ($7.11/mo), sprite (Fly.io VMs)

Changes:
- Remove 30 cloud directories, test fixtures, and provider-specific tests
- Slim manifest.json from 600 to 150 matrix entries, sorted by price
- Update CLAUDE.md with higher bar for adding clouds (prestige + pricing)
- Transform discovery service from code-implementing team to upvote-driven
  demand tracker that creates proposal issues and only implements when a
  proposal reaches 50+ upvotes
- Create GitHub issue #1183 as cloud wishlist with all dropped clouds
- Add discovery-team/cloud-proposal/agent-proposal labels
- Protect discovery-team issues from refactor team (no comments/changes)
- Fix all CLI tests (8034 pass, 0 fail) and shell tests (80 pass, 0 fail)

Co-authored-by: lab <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-15 00:19:39 -08:00
A
49c8c4f60b
feat: add VM reconnect functionality to spawn list (#1175)
* feat: add VM reconnect functionality to spawn list (#1144)

Implements ability to reconnect to previously spawned VMs instead of
always creating new instances. Changes include:

- Add VMConnection interface to track IP, user, and server metadata
- Add save_vm_connection() bash function for scripts to persist connection info
- Modify spawn list to show connection status and offer reconnect option
- Support both SSH (cloud providers) and sprite console reconnection
- Update digitalocean/claude.sh and sprite/claude.sh as reference implementations

Fixes #1144

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* improve: add helpful error message when VM reconnect fails

Show user-friendly message suggesting to spawn a new VM if
reconnection fails, rather than just showing raw SSH error.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-15 00:16:53 -05:00
A
1826fceee3
test: add missing coverage for cmdLast (#1176)
Added comprehensive test suite for cmdLast function (PR #1171 feature).
Covers:
- Empty history (no records)
- History with records (rerunning latest)
- Record hints and prompt display
- Helper functions (buildRecordLabel, buildRecordHint)
- Edge cases (old timestamps, metadata fields, selection logic)

Tests increased from 13,685 to 13,712 (+27 tests).

Agent: test-engineer

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-15 00:08:33 -05:00
A
8df6724ef4
fix: improve reliability in shared/common.sh error handling (#1177)
This commit fixes 3 critical reliability bugs in shared/common.sh:

1. Float arithmetic in OAuth polling loop (line 702)
   - Bug: elapsed=$((elapsed + POLL_INTERVAL)) fails when POLL_INTERVAL is decimal
   - Impact: OAuth timeout detection breaks when users set SPAWN_POLL_INTERVAL=0.5
   - Fix: Use python3 for float addition with integer fallback

2. Missing error handling in extract_ssh_key_ids (line 1249)
   - Bug: No error handling when python3 fails or API returns malformed JSON
   - Impact: Silent failures in SSH key provisioning across 7+ cloud providers
   - Fix: Add error handling with clear diagnostic messages

3. Unsafe fallback in calculate_retry_backoff (line 1312)
   - Bug: Empty interval returned if python3 unavailable and echo fails
   - Impact: sleep "" errors break retry loops in all cloud API wrappers
   - Fix: Add input validation and use printf instead of echo

All tests pass (13685 pass, 0 fail).

Agent: code-health

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-15 00:08:27 -05:00
A
74e208a579
security: fix command injection in upload_config_file (#1169)
* security: fix command injection in upload_config_file via unquoted path

VULNERABILITY: The upload_config_file() function passes remote_path
to mv without proper quoting, enabling command injection if the path
contains spaces or shell metacharacters.

IMPACT: HIGH — While current callers use hardcoded paths (~/.claude/...),
the function signature accepts arbitrary paths, making this a latent
vulnerability. A malicious or crafted path could execute arbitrary
commands on the remote server.

FIX: Double-quote remote_path in all command contexts (dirname, mv).
Tilde expansion still works correctly in double quotes when the tilde
is at the start of the path.

BEFORE:
  mv '${temp_remote}' ${remote_path}
  # If remote_path = "~/.config; rm -rf /" → command injection

AFTER:
  mv '${temp_remote}' "${remote_path}"
  # Path is properly quoted, no injection possible

Tracked in: #763

Agent: security-auditor
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: replace ~ with $HOME in upload_config_file callers

- Replace ~ with $HOME in all upload_config_file calls (lines 2432, 2443, 2522, 2575)
- Update comment to clarify tilde does not expand inside double quotes
- Update documentation example to use $HOME instead of ~

This addresses the review feedback that tilde expansion does not work
inside double quotes in bash. Using $HOME allows proper path expansion
on the remote shell while maintaining secure double-quoting.

Agent: security-auditor
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-15 00:08:17 -05:00
A
01ed4a8158
fix: replace echo|grep with bash builtins in digitalocean/lib/common.sh (#1174)
echo "$response" | grep -q can cause "write error: Broken pipe" when
grep -q exits early and echo gets SIGPIPE. This is non-deterministic
and depends on response size and timing, which is why it only fails
intermittently in CI. Using [[ == *pattern* ]] avoids pipes entirely.

Co-authored-by: lab <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-15 00:08:13 -05:00
A
89f1712761
test: fix failing test assertions to match implementations (#1173)
Updates test assertion strings in 10 test files to match current
implementation error messages. Implements changes from PR #1159
which were blocked due to merge conflicts.

Fixes #1161

Agent: test-engineer

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-14 23:30:27 -05:00
A
70c7f9f8c5
ux: add spawn last command to instantly rerun most recent spawn (#1171)
Adds a new `spawn last` command (with `rerun` alias) that instantly
reruns the most recent spawn from history without requiring the
interactive picker. This improves the workflow for users who frequently
want to restart their last session.

Features:
- `spawn last` or `spawn rerun` to instantly rerun last spawn
- Shows descriptive label and timestamp before rerunning
- Handles empty history gracefully with helpful message
- Preserves prompt from original spawn if it had one
- Updated help text and examples

Agent: ux-engineer

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-14 23:27:59 -05:00
A
58232baf4d
fix: improve error handling and reliability in OAuth flow and script download (#1170)
This commit fixes 3 high-impact reliability issues that could cause runtime failures:

1. **OAuth server PID race condition** (shared/common.sh)
   - BEFORE: Used pgrep to find server PID, which could match wrong processes
   - AFTER: Store PID in a file and read it reliably
   - IMPACT: Prevents OAuth cleanup failures and orphaned server processes

2. **Unhandled curl failures in OAuth code exchange** (shared/common.sh)
   - BEFORE: curl failures returned empty response without error detection
   - AFTER: Check curl exit code and report network/API errors clearly
   - IMPACT: Users get actionable feedback instead of cryptic "empty key" errors

3. **Missing error handling in script download** (cli/src/commands.ts)
   - BEFORE: Caught download error but continued execution with undefined scriptContent
   - AFTER: Exit early when download fails to prevent crash
   - IMPACT: Prevents "Cannot read property of undefined" runtime errors

All changes preserve existing behavior while adding defensive error handling.

Agent: code-health

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-14 23:26:53 -05:00
A
2fbe225855
refactor: extract helper functions to reduce complexity in discovery and commands (#1172)
Reduced complexity in 2 functions by extracting focused helpers:

1. preflightCredentialCheck (42 → 30 lines):
   - collectMissingCredentials(): validate env vars
   - getCredentialGuidance(): context-specific messaging
   - confirmContinueWithMissingCreds(): user confirmation logic

2. build_single_prompt (54 → 14 lines):
   - _find_first_gap(): extract matrix gap lookup
   - _print_gap_implementation_steps(): format implementation guidance
   - _print_matrix_full_guidance(): format discovery guidance

Improves testability and readability while preserving behavior.

Agent: complexity-hunter

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-14 23:23:26 -05:00
A
df96db3499
refactor: reduce complexity in display/selection and streaming functions (#1162)
Extract helper functions to reduce cyclomatic complexity:

- shared/common.sh: Split _display_and_select() (81 lines) into:
  - _prepare_fzf_input(): Format items for fzf
  - _fzf_select(): Handle fzf interactive selection
  - _numbered_list_select(): Fallback numbered list mode

- trigger-server.ts: Extract startStreamingRun() (133 lines) helpers:
  - createEnqueuer(): Manage client connection state safely
  - drainStreamOutput(): Generic stream draining with activity tracking

- render/lib/common.sh: Extract repeated error messages from
  _render_wait_for_service() (51 lines) into helper functions:
  - _render_print_deployment_failed_help()
  - _render_print_timeout_help()

Agent: complexity-hunter

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-14 22:12:58 -05:00
A
bf738bee69
ux: improve CLI help examples and remove duplicate auth text (#1163)
- Diversify help command examples to showcase more agents and clouds
  (openclaw, goose, interpreter, vultr, digitalocean, linode)
- Remove duplicate "Auth: token" text in cloud info display
- Update test to match new help examples

Agent: ux-engineer

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-14 22:11:42 -05:00
Ahmed Abushagur
51de0a9dcb
refactor: remove sprite-env usage from bot scripts (#1168)
Bots no longer run on Sprite VMs. Remove all sprite-env checkpoint
calls and Sprite-specific comments/docs from automation scripts.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 22:07:56 -05:00
A
a4fe0388c1
fix: allow repo collaborators through the gate workflow (#1166)
Previously only org members were allowed. Now checks both org membership
and repo collaborator status, so invited collaborators can open issues
and PRs without being blocked.

Co-authored-by: lab <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-14 18:32:50 -08:00
A
2d8c4a4734
feat: add code-health teammate to refactor team (#1164)
New teammate that proactively scans for reliability, maintainability,
readability, testability, scalability, and best practice issues. Picks
top 3 highest-impact findings per cycle and fixes them in one PR.

Co-authored-by: lab <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-14 18:17:02 -08:00
A
2605499f1a
refactor: extract helper functions to reduce checkEntity complexity (#1153)
Split checkEntity into three focused helpers that each handle a specific
correction strategy (wrong kind, same-kind typo, opposite-kind typo).
This reduces cyclomatic complexity from 6 to 2 in the main function,
making it easier to test and understand.

Agent: complexity-hunter

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-14 20:48:48 -05:00
A
a653549e83
refactor: reduce complexity in cmdHelp and cmdAgentInfo functions (#1157)
Extract cmdHelp's 76-line help message into 6 modular helper functions
(getHelpUsageSection, getHelpExamplesSection, getHelpAuthSection,
getHelpInstallSection, getHelpTroubleshootingSection, getHelpEnvVarsSection,
getHelpFooterSection) to improve maintainability and allow reuse.

Extract cmdAgentInfo's cloud listing logic into printAgentCloudsList helper
to reduce the function's cognitive load and separate display concerns.

Both refactorings maintain identical user-facing behavior while reducing
code duplication and improving testability.

Agent: complexity-hunter

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-14 20:45:44 -05:00
A
4f7f840f53
fix: align install script tests with actual implementation (#1154)
- Fix install-script-validation tests that checked for non-existent
  source-mode fallback features (PRs #707, #710 were not implemented)
- Rename test suite to "build fallback and binary download" to match
  actual behavior (pre-built binary download, not source mode)
- Remove assertions for non-existent features (${HOME}/.spawn,
  exec bun wrapper, forced reinstall)
- Add test for actual fallback behavior (downloading cli.js from releases)
- Fix download-and-failure test to match actual error message casing
  ("Firewall or proxy" not "firewall or proxy")

These tests were blocking CI and preventing clarity on actual vs desired
implementation. Now tests accurately reflect the current install.sh behavior.

Agent: test-engineer

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-14 20:45:35 -05:00
A
8174ed1547
fix: HIGH severity security issues (command injection + weak VNC password) (#1150)
Fixes #1120

1. Command injection in shared/key-request.sh:86
   - BEFORE: export "${var_name}=${val}" allowed injection via $(...)
   - AFTER: Use printf -v to safely assign the value
   - Impact: Prevents arbitrary command execution via crafted API key values

2. Weak VNC password in cloudsigma/lib/common.sh:266
   - BEFORE: openssl rand -hex 8 (64 bits of entropy)
   - AFTER: openssl rand -hex 16 (128 bits of entropy)
   - Impact: Strengthens VNC password against brute force attacks

Agent: security-auditor

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-14 20:39:48 -05:00
A
0c75e54704
feat: add interactive picker with filtering for Hetzner flow (#1151)
Fixes #1145

Replaces numeric input with interactive fuzzy picker for server/location selection.
- Uses fzf when available for interactive filtering
- Falls back to numbered list when fzf is not installed
- Applies to all interactive_pick flows (Hetzner locations, server types, etc.)
- Improves UX with type-to-filter capability

Agent: ux-engineer

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-14 20:39:44 -05:00
A
e4a3b60c90
ux: improve GCP CLI installation and setup guidance (#1149) (#1156)
Enhanced error messages in gcp/lib/common.sh to provide comprehensive,
platform-specific guidance for users getting started with GCP:

Changes:
- Added detailed install instructions for macOS (Homebrew), Ubuntu/Debian,
  and Fedora/RHEL platforms
- Included post-installation steps (auth and project configuration)
- Added links to create GCP project and enable Compute Engine API
- Improved error message structure with clear "How to fix" sections
- Maintained color-coded output for better readability

This addresses the issue where users felt the GCP flow "doesn't guide
me toward finding the right resource". The new error messages walk
users through the complete setup process from CLI installation to
project configuration.

Agent: ux-engineer

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-14 20:39:41 -05:00
A
292e38faf2
fix: stop refactor team from deferring issues to future cycles (#1152)
When there are ≤10 open issues, the team lead must assign them to
teammates and deliver PRs immediately instead of acknowledging and
deferring. Community-coordinator now required to assign every issue
to a teammate for fixing, never just comment and move on.

Co-authored-by: lab <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-14 20:39:16 -05:00
A
6d825684a4
fix: use sonnet for security triage instead of opus (#1158)
* fix: use sonnet instead of opus for security triage and routine tasks

- Triage mode: run claude with --model sonnet (single-agent safety check
  doesn't need opus)
- PR reviewers: opus → sonnet (routine review work)
- Issue-checker: haiku → sonnet (needs better judgment for dedup/labels)
- Kept opus for: team-building implementer/reviewer, full scan auditors

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: use moonshotai/kimi-k2.5 for issue triage and community coordination

- Security triage mode: sonnet → moonshotai/kimi-k2.5
- Security issue-checker: sonnet → moonshotai/kimi-k2.5
- Refactor community-coordinator: sonnet → moonshotai/kimi-k2.5

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: lab <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-14 17:37:20 -08:00
A
54311ca685
fix: stop security team from re-triaging issues and add label progression (#1155)
Two problems fixed:
1. issue-checker was posting duplicate triage comments ("Re-triage",
   "Status Check") on already-triaged issues. Strengthened dedup to
   check for both security/triage AND security/issue-checker sign-offs,
   and explicitly banned re-triage comment patterns.
2. Issues stuck in "under-review" forever because no agent transitioned
   them to "safe-to-work". Added silent label progression: if a triage
   comment exists, move under-review → safe-to-work without commenting.

Also fixed triage mode to recognize issue-checker sign-offs as prior
triage to prevent cross-agent duplicate work.

Co-authored-by: lab <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-14 17:10:31 -08:00
A
4e19859d77
test: fix outdated error message assertions (#1141)
Update test expectations to match current UX error messages:
- "Cannot run interactive picker" instead of "No interactive terminal"
- "Next steps" instead of "What to do"
- "experiencing issues" instead of "recovering"
- "Firewall or proxy" (capitalized) instead of "firewall or proxy"

All affected tests now pass with the current CLI error messages.

Agent: ux-engineer

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-14 16:43:35 -08:00
A
8108d57999
fix: add write permissions to gate workflow (#1148)
The default GITHUB_TOKEN lacks issues and pull-requests write access,
causing 403 when trying to close issues/PRs from non-org members.

Co-authored-by: lab <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-14 16:37:49 -08:00
A
2a5137a919
feat: add gate workflow to restrict issues/PRs to org members (#1146)
Automatically closes issues and PRs opened by non-members of the
OpenRouterTeam org with an explanatory comment.

Co-authored-by: lab <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-14 19:33:02 -05:00
A
30b31904df
refactor: reduce complexity in error handling and list display (cli/commands.ts) (#1142)
- Move exit code conditional logic into EXIT_CODE_GUIDANCE callbacks
- Extract buildEnvironmentLines() and buildPromptLines() helpers
- Extract buildListFooterLines() to separate formatting from display
- Reduces cyclomatic complexity and improves code reusability

Agent: complexity-hunter

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-14 18:49:57 -05:00
A
69df76f3a8
fix: correct test expectations to match actual CLI error messages (#1143)
Updated failing test cases to match the actual error messages generated by the CLI:
- "Cannot run interactive picker: not a terminal" (not "No interactive terminal")
- "Try manual installation:" (not "Try the installation manually")
- "Retry with a fresh server" (not "Re-run spawn to try")
- "installation failed" (not "installation failed to complete successfully")
- "Next steps" (not "What to do")
- "temporarily unavailable" (not "recovering")

Shell tests (80/80) pass. CLI tests improved from 128 failures to 47 failures.

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-14 18:48:03 -05:00
A
1cb9f5a5cb
fix: correct scaleway SSH key assertion endpoint (/sshkeys → /ssh-keys) (#1140)
The mock test assertion was checking for GET /sshkeys but the actual
Scaleway API endpoint is /ssh-keys (with a hyphen), causing all 15
scaleway agent tests to fail the "fetches SSH keys" check.

Co-authored-by: lab <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-14 18:20:07 -05:00
A
92ac7b8f67
ux: clarify non-interactive terminal error message (#1137)
Improved the error message when spawn is run without arguments in a
non-interactive environment (piped/redirected stdin/stdout).

Before: 'No interactive terminal detected.'
After: 'Cannot run interactive picker: not a terminal'
       '(stdin/stdout is piped or redirected)'

This makes it clearer why the interactive picker cannot run and what
the actual issue is (not just 'detected' but explicitly explaining
the stdin/stdout state).

Agent: ux-engineer

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-14 18:11:47 -05:00
A
9576cd5005
refactor: reduce function complexity in shared/common.sh and cli/commands.ts (#1138)
Extracted helper functions to improve code maintainability:

1. shared/common.sh:
   - Extracted _prompt_and_validate_api_key() from get_openrouter_api_key_manual()
   - Simplified API key validation loop and confirmation logic

2. cli/commands.ts:
   - Extracted selectAgent() from cmdInteractive() for agent selection
   - Extracted getAndValidateCloudChoices() for cloud validation and prioritization
   - Extracted selectCloud() for cloud selection UI
   - Extracted report404Failure() and reportHTTPFailure() from reportDownloadFailure()
   - Extracted classifyNetworkError(), showTimeoutCauses(), showConnectionCauses(), etc.
   - Simplified error handling with switch statement in reportDownloadError()

These changes reduce cyclomatic complexity and improve testability while preserving
all existing functionality.

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-14 18:11:36 -05:00
A
829cbea7b8
feat: rename /cleanup-branches skill to /pcl (#1139)
Shorter slash command for branch cleanup.

Co-authored-by: lab <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-14 18:09:00 -05:00
A
462da8c352
feat: add cleanup-branches skill for stale branch/worktree cleanup (#1136)
Adds a /cleanup-branches skill that deletes local and remote branches
with no open PR, and prunes stale worktrees. Supports --dry-run to
preview what would be deleted. Protects branches with open PRs.

Co-authored-by: lab <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-14 18:02:42 -05:00
A
8e55123e43
test: improve test coverage for provider delegation patterns (#1135)
* test: fix codesandbox provider pattern tests for helper function indirection

Update tests to account for functions that delegate to SDK helpers
(_csb_sdk_eval and _csb_run_cmd) rather than directly inlining SDK code.
Also add aliyun CLI auth pattern to credential handling test.

- Fix codesandbox tests to check for helper calls when patterns aren't direct
- Update test_codesandbox_token test to accept "How to fix" variant
- Allow interactive_session validation to check via run_server delegation
- Fixed: 42 codesandbox failures reduced to 0, 1 alibabacloud failure fixed

Agent: test-engineer

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* test: fix alibabacloud provider pattern tests for delegation

Update tests to account for alibabacloud delegating to shared SSH functions
instead of implementing SSH/SCP directly. Also adjust validation expectations
to match actual implementation which uses _aliyun_validate_create_params.

- Accept _aliyun_validate_create_params as validation pattern
- Update SSH test expectations for ssh_run_server and ssh_interactive_session
- Fixed: 6 alibabacloud failures reduced to 0

Agent: test-engineer

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* test: fix new-cloud-provider-patterns codesandbox validation tests

Update tests to account for codesandbox delegating to _csb_run_cmd helper
and interactive_session delegating to run_server.

- Accept _csb_run_cmd as SDK execution pattern
- Allow interactive_session validation via run_server delegation
- Fixed: 2 codesandbox validation failures reduced to 0

Agent: test-engineer

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-14 17:48:18 -05:00
A
22cdd75f80
ux: improve error message clarity and formatting (#1133)
Enhance user-facing error messages with better structure and visual hierarchy:

**CLI Error Messages:**
- Add bold headers for "Next steps:" and "Possible causes:" sections
- Make action items more scannable and directive
- Simplify language (e.g., "temporarily" vs "temporarily unavailable")
- Reduce redundancy in network error messages

**Shell Error Messages:**
- Add color-coded section headers (yellow for "Common causes" and "Next steps")
- Apply syntax highlighting to commands with CYAN color
- Improve readability of multi-step installation instructions
- Use bullet points (•) instead of dashes for better visual scanning
- Add inline comments to commands (e.g., "# Check disk space")

**Impact:**
Users experiencing errors will:
- Find actionable steps faster with clear visual hierarchy
- Copy-paste commands more easily with syntax highlighting
- Understand root causes quicker with color-coded sections
- Have a better experience during failure scenarios

All changes maintain backward compatibility and work across bash 3.x (macOS) and modern bash.

Agent: ux-engineer

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-14 17:44:47 -05:00
A
21b8f612e5
fix: enforce strict dedup rules to prevent duplicate agent comments (#1134)
Agents were posting redundant comments on issues because dedup checks
were soft prompt instructions that agents didn't reliably follow.
Strengthens all three team prompts with explicit STRICT DEDUP rules:

- security/issue-checker: skip issues entirely if already commented,
  do label fixes silently without commenting
- refactor/community-coordinator: only re-comment to link a new PR or
  report a concrete resolution, remove interim update instructions
- refactor/issue-fixer: check for ANY team's sign-off before posting
  acknowledgment, not just own team
- discovery/issue-responder: skip if already commented unless linking
  a concrete PR or fix

Co-authored-by: lab <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-14 17:43:38 -05:00
A
7609cf2d6f
refactor: reduce complexity in OAuth and Hetzner validation functions (#1132)
Extract helper functions to simplify complex control flow:
- try_oauth_flow: Extract _start_oauth_session_with_server helper to handle server startup phase, improving readability and testability
- _hetzner_resolve_server_type: Extract _hetzner_log_validation_error and _hetzner_log_type_change helpers to separate error handling logic from main flow

These changes reduce nesting levels and improve function cohesion while maintaining identical behavior.

Agent: complexity-hunter

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-14 17:43:05 -05:00
A
aaa886a7a9
test: fix failing test assertions to match actual implementation (#1130)
Updated test assertions to reflect refactored helper functions and changed
error messages. Key changes:

- Fixed atlanticnet security tests to verify ensure_multi_credentials
  delegation instead of checking implementation details in provider code
- Updated shared-common-decomposed-helpers tests to check actual error output
  messages instead of outdated wording
- Fixed shared-github-auth test mocking to properly override command
  builtin for platform detection
- Updated CloudSigma manifest auth field to explicitly mention HTTP Basic Auth

Tests now pass with 517/517 success across affected test files.

Agent: test-engineer

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-14 14:14:33 -08:00
A
d589b0d74e
fix: tilde expansion in upload_config_file + bump refactor frequency (#1131)
Fix #1114 — `mv` failed because `~/.claude/settings.json` was
single-quoted on the remote shell, preventing tilde expansion.
Remove the single quotes around remote_path and add a mkdir -p
safety net.

Also bump the refactor team cron from hourly to every 5 minutes.

Co-authored-by: lab <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-14 17:08:36 -05:00
A
11eff028a1
refactor: reduce complexity in shared/common.sh and test/mock.sh (#1128)
Extract pattern-matching logic in _strip_api_base() into separate helper functions (_strip_gcore_endpoint, _strip_scaleway_endpoint) to reduce function complexity from 36 lines to organized cases with extracted handlers.

Refactor ensure_api_token_with_provider() in shared/common.sh by extracting:
- _prompt_for_api_token() handles user prompting
- _validate_env_var_name() handles security validation
Reduces main function complexity and improves testability.

Agent: complexity-hunter

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-14 16:24:41 -05:00
A
f871996a82
ux: create parent directories before moving config files (#1127)
Fixes #1125 and #1114

The upload_config_file() function now creates parent directories
before moving config files to paths like ~/.claude/settings.json
and ~/.openclaw/openclaw.json.

Previously, if these directories didn't exist, the mv command would
fail with "No such file or directory" errors. This affected all
agents using setup_claude_code_config() and setup_openclaw_config().

Changes:
- Extract directory path using dirname
- Create parent directories with mkdir -p
- Execute chmod and mv in same command chain

Agent: ux-engineer

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-14 16:10:17 -05:00
A
b0843f6144
test: fix error message assertions in 7 test files (#1124)
Fixed 24 failing test assertions by aligning test expectations with actual error message output from the codebase:
- Updated error message strings to match actual implementation (e.g., "What to do" instead of "How to fix")
- Fixed case sensitivity issues ("Report it" vs "report it", "Server is still booting" vs "may still be booting")
- Adjusted assertions to match specific error paths (Network timeout vs Connection refused)
- All 284 tests in these 7 files now pass

Files fixed:
- cli-entry-edge-cases.test.ts: 56 tests
- cmdrun-happy-path.test.ts: 27 tests
- commands-swap-resolve.test.ts: 23 tests
- commands-update-download.test.ts: 17 tests
- download-and-failure.test.ts: 42 tests
- shared-common-ssh-helpers.test.ts: 52 tests
- shared-common-untested-helpers.test.ts: 67 tests

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-14 15:49:12 -05:00
A
c6d42e6f07
refactor: reduce complexity in discovery.sh, record.sh, and common.sh (#1123)
Break down overly complex functions into smaller, single-purpose helpers:

discovery.sh:
  - Extract _sync_and_setup() from run_team_cycle() for git sync + setup
  - Extract _launch_claude() to handle process startup
  - Extract _session_completed() to check session status
  - Extract _cleanup_cycle_files() for file cleanup
  - Reduces run_team_cycle() from 71 lines to 39 lines

record.sh:
  - Extract _validate_response_not_empty() for empty check
  - Extract _validate_response_json() for JSON validation
  - Extract _validate_response_no_error() for API error checking
  - Extract _record_fixture_metadata() for metadata recording
  - Reduces _save_live_fixture() from 34 lines to 15 lines

shared/common.sh:
  - Extract _check_agent_in_path() for PATH verification
  - Extract _check_agent_runs() for execution verification
  - Reduces verify_agent_installed() from 32 lines to 11 lines

Each helper is focused on one concern, improving maintainability and testability.

Co-authored-by: spawn-refactor-bot <refactor@openrouter.ai>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-14 15:44:05 -05:00
A
8f4f091988
ux: improve auth error messages with provider URLs (#1122)
Agent: ux-engineer

Enhance error messages when authentication fails by including direct
URLs to the provider's API token page in the remediation steps.

Changes:
- Updated _validate_token_with_provider() to accept help_url parameter
- Updated _validate_multi_credentials() to include help_url in errors
- Modified ensure_api_token_with_provider() to pass help_url to validator

Users now see the provider dashboard URL immediately when auth fails,
reducing friction and eliminating the need to search for token pages.

Before:
  1. Re-run the command to enter a new token
  2. Or set it directly: HCLOUD_TOKEN=your-token spawn ...

After:
  1. Get a new token from: https://console.hetzner.cloud/projects
  2. Re-run the command and paste the new token
  3. Or set it directly: HCLOUD_TOKEN=your-token spawn ...

Co-authored-by: Spawn Refactor Service <refactor@spawn.service>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-14 15:09:31 -05:00
A
5e3060616c
refactor: reduce complexity in test/mock.sh and discovery.sh (#1119)
Extract 60+ line nested case statement in _validate_body() into
dedicated _get_required_fields() function using cloud:endpoint pattern
matching. Reduces _validate_body() from 93 to 35 lines while improving
readability and maintainability.

Extract 162-line heredoc from build_team_prompt() into external
discovery-team-prompt.txt template file. Reduces function to 6 lines,
making discovery.sh more maintainable.

All 80 bash tests pass. No functionality change.

Co-authored-by: Spawn Refactor Service <refactor@spawn.service>
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-14 14:11:36 -05:00