Commit graph

804 commits

Author SHA1 Message Date
A
4e33cc39cd
fix: address medium security findings from #753 (#755)
- Replace `echo -e` with `printf` in cli/install.sh for macOS bash 3.x compat
- Remove `-u` (nounset) from test/run.sh — use `${VAR:-}` pattern instead
- Replace `source <(curl ...)` with `eval "$(curl ...)"` in test/run.sh for curl|bash compat
- Add .gitignore patterns for sensitive files (.env, *.pem, *.key, credentials)

Refs #753

Agent: security-auditor

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-12 15:48:52 -08:00
A
4bd5f2205f
test: add 71 tests for cloud API helper functions in shared/common.sh (#754)
Cover _parse_api_response, _update_retry_interval, _api_should_retry_on_error,
calculate_retry_backoff, _cloud_api_retry_loop, generic_cloud_api,
generic_cloud_api_custom_auth, _make_api_request, _make_api_request_custom_auth,
and _curl_api -- all recently refactored with zero prior test coverage.

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-12 15:48:46 -08:00
A
cf53ea1fb2
fix: use log_step (cyan) for in-progress messages instead of log_info (green) (#757)
Consistently use log_step for progress/status messages ("Waiting for...",
"Fetching...", "Creating...") and reserve log_info for success/completion
messages. This gives users a clear visual distinction between operations
that are still running (cyan) vs operations that have completed (green).

Also adds periodic progress updates to silent polling loops in ramnode,
cherry, and netcup IP wait functions so users see activity during long waits.

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-12 15:48:38 -08:00
L
32a3e6e276
feat: add PR labeling + stale issue re-triage to security review_all (#748)
- Created missing repo labels: malicious, needs-human-review,
  maintenance, team-building
- PR reviewers now label PRs after review:
  - security-review-required for CRITICAL/HIGH findings
  - security-approved for clean/MEDIUM/LOW PRs
- Added issue-checker agent to review_all mode that monitors stale
  issues (no activity >1 hour) and re-triggers review:
  - Re-flags safe-to-work issues with no activity
  - Re-notifies needs-human-review issues via Slack
  - Ensures all open issues have a status label
  - Adds Pending Review to un-triaged issues

Co-authored-by: Sprite <noreply@sprites.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-12 15:39:44 -08:00
A
e36e087029
feat: prioritize clouds with detected credentials in interactive picker (#752)
When running `spawn` interactively, clouds where the user already has
auth env vars set (e.g. HCLOUD_TOKEN, DO_API_TOKEN) now appear first
in the cloud selection list with a "credentials detected" hint. This
reduces friction by surfacing the most likely-to-succeed options.

Fixes #685

Agent: ux-engineer

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
2026-02-12 15:33:14 -08:00
A
eae6219f27
fix: use timing-safe comparison and validate reason param in trigger-server (#747)
Replace direct string comparison (!==) with crypto.timingSafeEqual() for
Bearer token authentication, preventing timing side-channel attacks on
TRIGGER_SECRET. Pattern matches existing key-server.ts implementation.

Also validate the `reason` query parameter against an allowlist of known
values to prevent injection of arbitrary strings into the SPAWN_REASON
env var passed to spawned scripts.

Fixes #745

Agent: security-auditor

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-12 15:32:44 -08:00
A
62dec3ea91
feat: add ramnode/codex agent implementation (#749)
Implements Codex CLI deployment on RamNode Cloud using OpenStack API.

Agent: gap-filler-3

Co-authored-by: Sprite <noreply@sprites.dev>
2026-02-12 15:31:36 -08:00
A
0f9f1e0b30
feat: implement local/gemini script (#750)
Add support for running Gemini CLI on local machine with OpenRouter
integration. Script installs @google/gemini-cli via npm and injects
required environment variables per manifest.json spec.

Agent: gap-filler-2

Co-authored-by: Sprite <noreply@sprites.dev>
2026-02-12 15:31:26 -08:00
A
2b73cf6ce0
docs: Sync README matrix with manifest.json (#746)
Agent: team-lead

Co-authored-by: Sprite <noreply@sprites.dev>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-12 15:30:55 -08:00
A
cec1806128
refactor: improve readability of config setup and shellcheck discovery (#744)
- Replace hardcoded 4-cloud script list in run_shellcheck with dynamic
  discovery that covers all 21 clouds automatically
- Convert 3 inline JSON templates (setup_claude_code_config,
  setup_openclaw_config, setup_continue_config) from single-line printf
  to readable heredocs while preserving json_escape security

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-12 15:19:11 -08:00
A
242eb1dde0
test: add 54 tests for env injection, JSON extraction, SSH key, and opencode helpers (#743)
Cover previously untested shared/common.sh functions:
- inject_env_vars_ssh: env var injection via SSH (argument passing, content, permissions)
- inject_env_vars_local: env var injection for container providers (local arg format)
- _extract_json_field: Python-based JSON field extraction with defaults
- check_ssh_key_by_fingerprint: SSH key fingerprint lookup via API
- opencode_install_cmd: robust OpenCode install command generation
- track_temp_file/cleanup_temp_files: secure temp file lifecycle
- validate_resource_name: resource name validation 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-12 15:18:57 -08:00
L
dda01e7e2f
feat: replace branch-cleaner with pr-maintainer in refactor team (#741)
* feat: replace branch-cleaner with pr-maintainer in refactor team

The refactor team now actively maintains open PRs instead of just
cleaning branches. The new pr-maintainer agent (Sonnet):

- Reviews all open PRs for correctness and security
- Approves and merges clean PRs (squash + delete branch)
- Rebases PRs with merge conflicts onto main
- Posts review comments for issues (never closes PRs)
- Cleans up orphan branches (no open PR, stale >4h)

Pre-cycle cleanup also updated: stale PRs with conflicts are left
for the pr-maintainer agent to rebase, never auto-closed.

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

* feat: file follow-up issues when closing PRs with valid changes

When the security review_all mode closes a stale PR with merge
conflicts, it now reads the PR's intent first. If the change is
still valid (security fix, bug fix, feature), it files a follow-up
issue preserving the context before closing — so knowledge isn't
lost. Trivial/outdated PRs are closed without a follow-up.

Motivated by PR #721 which had a valid timing-safe auth fix that
was lost when auto-closed for merge conflicts after a path rename.

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

---------

Co-authored-by: Sprite <noreply@sprites.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-12 15:12:03 -08:00
A
e8dc7b4752
fix: replace unsafe inline API key injection with secure helpers (#676)
8 scripts were embedding OPENROUTER_API_KEY directly into shell command
strings passed to run_server/run_in_codespace, allowing command injection
if the API key contains shell metacharacters (single quotes, semicolons,
backticks, etc.).

The worst case was latitude/continue.sh which had zero quoting:
  export OPENROUTER_API_KEY=${OPENROUTER_API_KEY}
allowing arbitrary command execution on the remote server with a
crafted API key value.

Fixed by replacing unsafe inline patterns with the existing secure
helpers (inject_env_vars_ssh, inject_env_vars_local, inject_env_vars)
which use generate_env_config to properly single-quote values with
embedded quote escaping.

Affected scripts:
- scaleway/continue.sh (single-quote breakout)
- upcloud/continue.sh (double-quote breakout)
- e2b/continue.sh (single-quote breakout)
- modal/continue.sh (single-quote breakout)
- daytona/continue.sh (single-quote breakout)
- latitude/continue.sh (no quoting at all - critical)
- github-codespaces/continue.sh (single-quote breakout)
- kamatera/nanoclaw.sh (single-quote breakout in .env write)

Agent: security-auditor

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 15:03:12 -08:00
A
149a1feac5
test: add 41 tests for cmdMatrix, cmdAgents, cmdClouds listing output (#732)
Cover the grid/compact matrix views, agent/cloud listing content,
type grouping, auth hints, footer statistics, edge cases, and
cross-command consistency for the three main listing commands.

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-12 15:02:55 -08:00
A
e103a6f2af
test: add CLI version output, dispatch routing, and flag validation tests (#674)
Add 62 subprocess-based integration tests that exercise the actual index.ts
entry point, catching issues that unit tests with mocked modules miss:
- showVersion output format (version string, runtime, platform, arch)
- Version/help flag aliases (--version, -v, -V, --help, -h)
- Trailing help flags on subcommands (agents --help, matrix -h, etc.)
- handleNoCommand error paths (--dry-run, --prompt without agent/cloud)
- Unknown flag detection and error messaging
- Flag value requirements (--prompt, -p, --prompt-file, -f)
- --prompt and --prompt-file mutual exclusion
- Verb alias routing (run, launch, start, deploy, exec)
- Extra arguments warning
- Prompt file error handling (nonexistent, directory)
- Non-interactive terminal detection
- Subcommand alias routing (m for matrix, ls/history for list)
- List command -a/-c flag validation

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-12 15:02:52 -08:00
A
cbffb856aa
test: add 46 tests for install.sh helper functions (#720)
install.sh was modified in 3 of the last 5 commits but had zero test
coverage for its core helper functions. This adds tests for:

- version_gte: semver comparison (22 tests covering equal, greater,
  lesser versions, segment edge cases, realistic bun version checks)
- find_install_dir: PATH-aware install directory resolution (6 tests
  covering SPAWN_INSTALL_DIR override, PATH heuristics, fallback)
- ensure_in_path: PATH detection and shell-specific instructions (8 tests
  covering bash/zsh/fish detection, partial prefix matching, long PATHs)
- install.sh syntax and structure validation (10 tests)

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-12 15:02:49 -08:00
A
0ebaadb345
refactor: replace inline Claude config with setup_claude_code_config in fly/koyeb/railway (#711)
Replace 40 lines of duplicated inline Claude Code configuration in each
of fly/claude.sh, koyeb/claude.sh, and railway/claude.sh with the shared
setup_claude_code_config helper from shared/common.sh. This eliminates
~120 lines of copy-pasted config generation (mktemp, heredoc, upload, rm)
and uses json_escape for the API key, matching the pattern already used
by 30+ other claude.sh scripts.

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-12 15:02:25 -08:00
A
52b91f4c43
fix: redirect 'spawn agents <name>' and 'spawn clouds <name>' to info pages (#709)
When users type 'spawn agents claude' or 'spawn clouds hetzner', they
intuitively expect to see info about that agent/cloud. Previously, the
extra argument was silently ignored with a warning, and the full list was
shown instead. Now these commands redirect to the info page for the
given name, with a tip suggesting the shorter 'spawn <name>' form.

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-12 15:02:23 -08:00
A
dcf8242b0a
refactor: extract _curl_api and _extract_json_field helpers in shared/common.sh (#673)
Consolidate duplicated curl logic from _make_api_request and
_make_api_request_custom_auth into a shared _curl_api core function,
reducing copy-paste and making both functions thin wrappers.

Extract inline Python JSON extraction from generic_wait_for_instance
into a reusable _extract_json_field helper.

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-12 15:02:20 -08:00
A
a626faf619
test: add 75 tests for resolveListFilters and related functions (#724)
Cover the previously untested resolveListFilters function in commands.ts
which resolves display names to keys, handles case-insensitive matching,
and intelligently swaps bare positional args from agent to cloud filter.

Also adds tests for resolveAgentKey, resolveCloudKey, resolveDisplayName,
getImplementedClouds, getImplementedAgents, and cmdList integration with
filter resolution including table rendering and footer display.

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-12 15:02:06 -08:00
A
f131eb82a6
test: add coverage for compact matrix view and footer rendering (#708)
Add 57 tests covering renderCompactList and renderMatrixFooter functions
which had zero test coverage. Tests cover compact list agent/cloud counts,
missing cloud display, "all clouds supported" logic, matrix footer legends
for compact vs grid modes, implementation counts, and consistency between
rendering helpers (getMissingClouds, getImplementedClouds, calculateColumnWidth).

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-12 15:01:59 -08:00
A
35997c8ae5
refactor: extract helpers from run_test() in test/mock.sh (#713)
Break down the 150-line run_test() function into focused helpers:
- run_script_with_timeout(): script execution with env vars and timeout
- show_failure_output(): display last 20 lines on failure
- assert_error_scenario(): handle error scenario assertions
- assert_cloud_api_calls(): cloud-specific API call assertions
- record_test_result(): write pass/fail to RESULTS_FILE

run_test() is now 57 lines (62% reduction), each helper is under 35 lines.

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-12 15:01:49 -08:00
A
6ca02f9362
test: add 55 tests for credential management functions in shared/common.sh (#714)
Add comprehensive test coverage for the untested credential management
pipeline (_load_token_from_env, _load_token_from_config,
_validate_token_with_provider, _save_token_to_config,
_multi_creds_all_env_set, _multi_creds_load_config,
_multi_creds_validate) plus save/load roundtrip integration tests.

These functions are used by every cloud provider script but had zero
test coverage. Tests run in real bash subprocesses sourcing
shared/common.sh to catch actual shell behavior.

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-12 15:01:44 -08:00
A
26829b1065
test: add 83 tests for install.sh script validation (#716)
install.sh is the critical entry point for new users (curl | bash) and
has been modified in 3 recent PRs but had zero test coverage. These tests
validate structure, conventions, security, curl|bash compatibility, the
source-mode fallback wrapper, clone_cli logic, find_install_dir, and
ensure_in_path behavior.

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-12 15:01:43 -08:00
A
ea943d1583
refactor: decompose 287-line setup_mock_curl into named helpers (#718)
The mock curl heredoc script was a monolithic 287-line function with
inline arg parsing, error injection, URL routing, body validation,
fixture lookup, and state tracking all in one flow.

Extract 10 focused helper functions within the heredoc:
- _parse_args: curl argument parsing
- _maybe_inject_error: MOCK_ERROR_SCENARIO handling
- _handle_special_urls: install scripts, OpenRouter, spawn repo
- _strip_api_base: URL-to-endpoint mapping for 14 cloud APIs
- _check_fields / _validate_body: POST body validation
- _try_fixture: fixture file lookup
- _synthetic_active_response: cloud-specific GET-by-ID responses
- _respond_get / _respond_post: METHOD-based response routing
- _track_state: creation/deletion state tracking

The main logic is now a 26-line sequence of named function calls,
making the mock's control flow immediately readable.

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-12 15:01:41 -08:00
A
30c61aa809
test: add 66 tests for ensure_api_token_with_provider credential flow (#729)
Add comprehensive test coverage for the single-token credential management
functions in shared/common.sh that previously had zero test coverage:
- _load_token_from_env (env var detection, edge cases)
- _load_token_from_config (JSON config loading, error handling)
- _validate_token_with_provider (validation callback, env var cleanup)
- _save_token_to_config (secure file creation, JSON escaping, roundtrips)
- ensure_api_token_with_provider (full flow integration tests)

These functions are used by every single-token cloud provider (Hetzner,
DigitalOcean, Vultr, Lambda, Linode, etc.) and are security-critical
for credential handling.

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-12 15:01:03 -08:00
A
9a851b36b6
refactor: extract assert_equals/assert_match helpers in test/run.sh (#727)
Replace 36 inline if/else assertion blocks across 9 test functions with
calls to two new reusable helpers (assert_equals, assert_match). Reduces
test/run.sh by 126 lines (794 -> 668) while keeping all 79 tests passing.

Key functions reduced:
- _test_open_browser: 53 -> 36 lines (-32%)
- _test_ssh_key_utils: 48 -> 26 lines (-46%)
- _test_cloud_init: 41 -> 22 lines (-46%)
- _test_oauth_functions: 39 -> 23 lines (-41%)
- _test_ssh_wait: 33 -> 21 lines (-36%)

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-12 15:00:59 -08:00
A
d5d7da0833
refactor: decompose setup_mock_agents and record_cloud into helpers (#722)
- Extract _create_logging_mock and _create_silent_mock from setup_mock_agents
  (test/mock.sh) to eliminate repetitive mock creation patterns
- Extract _record_ensure_credentials, _record_endpoint, and
  _record_write_metadata from record_cloud (test/record.sh) to separate
  credential checking, API recording, and metadata writing concerns

Pure refactoring — no behavior changes.

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-12 15:00:56 -08:00
A
b33b3cf6ea
fix: restore --prompt in retry command after script failure (#731)
When a spawn script fails (e.g., SSH timeout, credentials issue), the
retry command shown to the user was `spawn <agent> <cloud>`, dropping
the --prompt argument the user originally provided. This was a regression
from PR #683 which accidentally removed the buildRetryCommand function
and prompt parameter that PR #712 had added.

Restores buildRetryCommand (truncates to 60 chars, escapes quotes) and
passes prompt through reportScriptFailure so users can copy-paste the
full retry command without reconstructing it from memory.

Adds 7 tests for buildRetryCommand covering truncation, quote escaping,
empty/undefined prompt, and boundary cases.

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-12 15:00:46 -08:00
A
96d96b3ef6
fix: show cleanup warning when script is interrupted by Ctrl+C (#723)
Previously, when a user hit Ctrl+C during script execution, the CLI
silently exited with code 130. This left users unaware that a server
may have already been created and could still be running, potentially
incurring charges.

Now shows a warning about orphaned resources before exiting.

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-12 15:00:30 -08:00
A
8140c1b61b
fix: remove leaked trigger secret and fix service path (#735) (#740)
- Delete start-refactor.sh from setup-trigger-service (hardcoded secret)
- Broaden .gitignore to cover all .claude/skills/*/start-*.sh
- Rotated REFACTOR_TRIGGER_SECRET in GitHub Actions
- Service now runs from correct setup-agent-team location

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-12 14:55:41 -08:00
L
15e2ca6caf
feat: consolidate security modes — merge pr+hygiene into review_all (#739)
Simplify from 6 modes (Hexa-Mode) to 4 modes (Quad-Mode) by folding
single-PR review and hygiene into a unified review_all mode that runs
every 15 minutes. This removes the pull_request trigger entirely since
review_all catches all open PRs on schedule, and absorbs staleness
checks + branch cleanup into the same cycle.

Remaining modes: team_building, triage, review_all, scan.

Co-authored-by: Sprite <noreply@sprites.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-12 14:53:26 -08:00
L
4924a7d5db
feat: add security triage gate for issue safety before agent processing (#734)
New issues are triaged by the security team before other workflows can
act on them. The triage agent checks for prompt injection, social
engineering, spam, and unsafe payloads — marking safe issues with
`safe-to-work`, closing malicious ones, or flagging unclear ones for
human review. Discovery and refactor workflows now require the
`safe-to-work` label in addition to their existing label requirements.

Co-authored-by: Sprite <noreply@sprites.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-12 14:23:33 -08:00
L
4d175ae6c7
feat: add Team Building issue template + route workflows by label (#733)
- New issue template: Team Building (team-building label) — 2 fields:
  which agent team to improve + what to change
- Security team gets a new team_building mode: reads the issue, spawns
  implementer + reviewer (both Opus), creates PR, reviews, merges, closes issue
- Discovery workflow: only triggers on cloud-request / agent-request issues
- Refactor workflow: only triggers on bug / cli issues
- Security workflow: only triggers on team-building issues (+ PR/schedule)
- All workflows still run on schedule and workflow_dispatch as before

Co-authored-by: Sprite <noreply@sprites.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-12 14:17:57 -08:00
A
8c99244ac4 refactor: Automated improvements
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-12 22:09:19 +00:00
L
56ba47109c
feat: add security review team for PR review (#543) (#730)
* feat: add security review team for PR review (#543)

Adds a security team that automatically reviews every PR for security
issues (injection, credential leaks, unsafe patterns, macOS compat)
and sends Slack notifications to #spawn when concerns are found.

- security.sh: dual-mode cycle script (PR review + scheduled scan)
- security.yml: GitHub Actions workflow on pull_request events
- start-security.sh: gitignored wrapper with secrets (deployed)

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

* feat: expand security team with hygiene, scan modes + auto-merge clean PRs

- PR mode: 2-agent team (code-reviewer + test-verifier) reviews PRs.
  If zero findings, auto-approves AND merges. If concerns, requests
  changes and sends Slack notification to #spawn.
- Hygiene mode (every 6h): pr-triager + branch-cleaner close stale PRs,
  file follow-up issues, delete orphan branches.
- Scan mode (daily): shell-auditor + code-auditor + drift-detector
  perform full repo security audit, file GitHub issues for findings.
- All modes use Claude Code agent teams (TeamCreate, parallel teammates
  via Task tool, SendMessage coordination, TaskList monitoring).
- Workflow updated with schedule triggers and workflow_dispatch inputs.

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

* chore: upgrade all security auditor agents to Opus model

All security-critical roles (code-reviewer, pr-triager, shell-auditor,
code-auditor) now use Opus. Helper roles (test-verifier, branch-cleaner,
drift-detector) remain on Haiku.

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

* chore: auto-merge PRs with MEDIUM/LOW or no findings

Only CRITICAL/HIGH findings block a PR. MEDIUM/LOW are informational
notes included in the approving review — PR still gets merged.

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

---------

Co-authored-by: Sprite <noreply@sprites.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-12 14:04:38 -08:00
L
d961947983
fix: download pre-built CLI from GitHub release when local build fails (#728)
Root cause: bun install creates empty directories in proot (Termux)
because proot can't intercept bun's symlink/hardlink/copy_file_range
syscalls. This breaks both local build and source-mode fallback.

Fix: when `bun run build` fails, download the pre-built cli.js from
the `cli-latest` GitHub release. The bundled binary is self-contained
(80KB, all deps inlined) and only needs the bun runtime.

- Add CI workflow (.github/workflows/cli-release.yml) that builds and
  uploads cli.js to a rolling `cli-latest` release on every push to main
- Replace broken source-mode fallback with GitHub release download
- Bump CLI version to 0.2.63

Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-12 13:48:45 -08:00
Sprite
aff3000d01 rename: setup-trigger-service -> setup-agent-team
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-12 21:38:58 +00:00
A
f576661f3e
fix: show setup instructions in script failure credential hints (#683)
When a spawn script fails with credential-related errors, the error
message now always includes "Run spawn <cloud> for setup instructions"
alongside the required env var names. Previously, this setup hint was
only shown when the auth env var names were unknown.

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-12 13:34:25 -08:00
L
ecfd8e2f4e
fix: source-mode wrapper must cd into ~/.spawn for package resolution (#710)
bun 1.3.8 on Termux proot doesn't resolve node_modules by walking up
from the source file directory. Changing cwd to ~/.spawn/ (where
node_modules lives) before exec ensures packages are found.

Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-12 12:17:06 -08:00
A
2e02ab71e0
fix: retry script execution on transient SSH failures (exit 255) (#706)
When a spawn script fails with exit code 255 (SSH connection failure),
the CLI now retries up to 2 times with progressive delays (5s, 10s).

Non-retryable failures (syntax errors, permission denied, Ctrl+C, and
generic exit code 1) are not retried and fail immediately as before.

Fixes #705

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-12 12:13:38 -08:00
L
db72074e0a
fix: fall back to source-mode install when bundled build fails (#707)
bun 1.3.8 in Termux proot cannot resolve packages with --packages bundle
even with bun.lock present and after --force reinstall. When the bundled
build fails, install source + node_modules to ~/.spawn/ and create a
wrapper script that runs via `bun` directly.

Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-12 12:13:19 -08:00
L
ac1f8239c8
fix: install.sh fails on Termux proot due to missing bun.lock (#704)
The non-git download path did not fetch bun.lock, causing bun install
to resolve dependencies from scratch. On older bun versions (e.g. 1.3.8
in Termux proot), this produced a node_modules layout that broke
`bun build --packages bundle`.

- Download bun.lock in the non-git (curl) path
- Add build retry with `bun install --force` fallback
- Enforce minimum bun version (1.2.0) with auto-upgrade
- Bump CLI version to 0.2.60

Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-12 11:49:20 -08:00
A
6c7ced54dd
fix: replace log_warn with log_step/log_info for non-warning messages (#604)
Agent: ux-engineer

Many shell scripts misused log_warn (yellow) for normal progress/status
messages, making routine operations appear alarming. This fixes 59 files:

- Progress messages -> log_step (cyan): "Injecting environment variables...",
  "Attaching volume...", "Powering on instance...", "Retrieving server IP...",
  "Terminating sandbox/server...", "Creating datacenter...", "Importing SSH key...",
  "Deleting service/app...", "Modal not authenticated. Running setup..."
- Informational notices -> log_info (green): WhatsApp QR code authentication
  notices (30 nanoclaw scripts), codespace delete hints (14 scripts),
  "Appending environment variables to ~/.zshrc..." (6 local scripts),
  credential prompt hints, package update skipped, app reuse notices

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-12 03:24:30 -08:00
A
a550aecb22
feat: Update manifest.json to mark local/opencode as implemented (#616)
The local/opencode.sh script already exists and is functional.

Agent: gap-filler

Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-12 02:16:28 -08:00
L
627abd2fb0
feat: enforce no-self-merge rule across all team scripts (#585)
Agents can self-review their PRs (read diff, add comments) but must
never merge. PRs get labeled `needs-team-review` and stay open for
external review by maintainers or a separate review cycle.

Changes across all three scripts:
- refactor.sh: added No Self-Merge Rule section, updated worktree
  pattern, issue fix workflow, monitoring loop, and lifecycle mgmt
- discovery.sh: added No Self-Merge Rule section, updated worktree
  pattern, git workflow, branch cleaner, and lifecycle mgmt
- qa-cycle.sh: renamed push_and_merge_pr to push_and_create_pr,
  removed all gh pr merge calls, added self-review + labeling

Agent: team-lead

Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 23:02:32 -08:00
Ahmed Abushagur
1ad2371a25
feat: qa bot and emails (#565) 2026-02-11 20:19:45 -08:00
A
11cf3a188e
refactor: replace custom credential/polling logic with shared helpers in kamatera and ovh (#564)
Kamatera: Replace _load_kamatera_config, _validate_kamatera_credentials, and
ensure_kamatera_token (62 lines of custom env/config/prompt/validate/save logic)
with ensure_multi_credentials (5 lines).

OVH: Replace _ovh_prompt_credentials, ensure_ovh_authenticated (72 lines of
custom credential management) with ensure_multi_credentials (8 lines).
Replace wait_for_ovh_instance (38 lines of custom polling with backoff) with
generic_wait_for_instance (8 lines).

Net: -175 lines, same behavior, consistent patterns across providers.

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 17:54:23 -08:00
A
477ce58367
fix: spawn list <cloud> now correctly filters by cloud instead of failing (#563)
Previously, `spawn list hetzner` always treated the bare positional
argument as an agent filter, returning 0 results since "hetzner" is a
cloud, not an agent. Now resolveListFilters auto-detects: when the
filter doesn't resolve as an agent but does resolve as a cloud, it
reclassifies to a cloud filter. This matches the help text which
promises "Filter history by agent or cloud name".

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 17:54:19 -08:00
L
746adb4f41
fix: integrate automatic issue label management into refactor.sh (#562)
Adds label lifecycle transitions (Pending Review → Under Review → In Progress)
directly into both issue mode and refactor mode prompts per maintainer request
on #546. The community-coordinator now manages labels at each stage of issue
engagement, and the shutdown checklist verifies all open issues are labeled.

Fixes #546

Agent: team-lead

Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-11 17:45:38 -08:00