The sprite/claude.sh script was using 'claude install' which requires
claude to already be on PATH. Changed to use the curl installer which
downloads and installs the binary from scratch.
Fixes#88
Agent: issue-responder
Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The redirect `> /dev/null 2>&1` was being escaped by `run_sprite`'s
`printf %q`, causing the command to be interpreted incorrectly:
/usr/bin/bash: line 1: claude install > /dev/null 2>&1: No such file or directory
Removing the redirect allows users to see installation progress and
simplifies the command. Installation success is already verified by
the subsequent check on line 33.
Fixes#80
Agent: ux-engineer
Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Root causes:
- `clear` command fails with exit 1 when TERM is not set (test env has
no terminal), crashing the script due to set -e. Guard with || true.
- Test patterns for Claude settings/state uploads used old temp file
naming convention (/tmp/claude_settings, /tmp/claude_global) that no
longer matches the paths generated by upload_config_file +
upload_file_sprite (/tmp/*settings.json, /tmp/*.claude.json).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: extract shared test helpers and utilities
Created centralized test-helpers.ts module to eliminate duplication across test files:
**Extracted Helpers:**
- createMockManifest() - Reusable mock manifest data
- createEmptyManifest() - Empty manifest for edge cases
- createConsoleMocks() - Console spy setup
- createProcessExitMock() - Process exit mock
- restoreMocks() - Mock cleanup utility
- mockSuccessfulFetch() - Simplified successful fetch mock
- mockFailedFetch() - Simplified failed fetch mock
- mockFetchWithStatus() - Fetch mock with custom status
- setupTestEnvironment() - Test directory and env setup
- teardownTestEnvironment() - Cleanup utility
**Deduplication Impact:**
- commands.test.ts: Removed 50+ lines of duplicate mock setup
- manifest.test.ts: Removed 80+ lines of duplicate manifest data and setup code
- integration.test.ts: Removed 40+ lines of duplicate setup/teardown
**Benefits:**
- Single source of truth for test fixtures
- Consistent mock patterns across all tests
- Easier maintenance - changes to test setup in one place
- Improved test readability
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* refactor: Add non-interactive mode for agent execution
Implements --prompt and --prompt-file flags to enable non-interactive
agent execution. This allows users to:
- Execute agents with a prompt and exit automatically
- Use spawn in CI/CD pipelines and automation scripts
- Pass prompts via command line or file
Changes:
- TypeScript CLI: Parse --prompt/-p and --prompt-file flags
- Security: Add validatePrompt() to prevent command injection
- Commands: Pass prompt via SPAWN_PROMPT env var to bash scripts
- Bash scripts: Detect SPAWN_PROMPT and fork interactive/non-interactive
- Help text: Document new flags with examples
Implementation:
- claude.sh: Use 'claude -p' for non-interactive execution
- aider.sh: Use 'aider -m' for non-interactive execution
- shared/common.sh: Add execute_agent_non_interactive() helper
Security:
- Validates prompts for command injection patterns
- Length limit: 10KB max
- Blocks $(), backticks, piping to bash/sh
- Uses printf %q for proper shell escaping
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* docs: Add testing guide for non-interactive mode
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
The refactor in f9dd9a7 hardcoded /root/ as the upload destination for
Claude Code and OpenClaw config files, breaking all non-root providers
(Lambda, AWS Lightsail, GCP, Sprite, E2B, Modal, Fly). Upload to /tmp/
first then mv to ~/ via run_callback so the remote shell expands ~ to
the correct home directory.
Also add OPENROUTER_API_KEY env var check to sprite scripts (claude,
openclaw, nanoclaw) so the OAuth flow is skipped when the key is already
set, and fix echo -e to printf for macOS bash 3.x compat.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The autonomous refactoring added `set -euo pipefail` but the scripts
check optional env vars with `[[ -n "$VAR" ]]` which is a fatal error
under nounset when the var isn't set (e.g. SPRITE_NAME, OPENROUTER_API_KEY).
Fix: downgrade to `set -eo pipefail` across all 42 affected files.
Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
macOS ships bash 3.x which doesn't support nested process substitution.
When scripts are run via `bash <(curl ...)`, the inner `source <(curl ...)`
for loading common.sh fails silently, causing "command not found" errors.
Fix: replace `source <(curl -fsSL URL)` with `eval "$(curl -fsSL URL)"`
across all 100 agent scripts. eval+curl works on bash 3.x and newer.
Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
BASH_SOURCE[0] is /proc/self/fd/N with process substitution, not
"-" or "bash". Instead of guessing execution context, just check
if the local lib/common.sh file actually exists.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- OAuth authentication flow with OpenRouter to mint API keys
- Automatic sprite creation and environment configuration
- Claude Code setup with bypassed onboarding and dark theme
- OpenClaw setup with gateway and TUI launch
- Shell environment setup (bun PATH, zsh switch)