- Add nc_listen helper that detects busybox nc and uses -p flag accordingly
- Add termux-open-url support to open_browser
- Deduplicate inline browser opener in try_oauth_flow to use open_browser
Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add nc_listen helper that detects busybox nc and uses -p flag accordingly
- Add termux-open-url support to open_browser
- Deduplicate inline browser opener in try_oauth_flow to use open_browser
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add NanoClaw spawn script
NanoClaw is a lightweight WhatsApp-based Claude AI assistant that runs
agents in isolated containers. This script sets up a sprite with
nanoclaw pre-configured: clones the repo, installs dependencies,
configures the API key, and launches in dev mode for WhatsApp QR auth.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* Fix verify_sprite_connectivity exiting script early after single failed check
Retry connectivity up to 6 attempts (30s) instead of trying once and
silently continuing, which caused the next sprite exec to fail under set -e.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add test harness for spawn scripts
Mocks the sprite CLI and runs each script end-to-end verifying:
- common.sh sources correctly and all functions resolve
- Log functions write to stderr (not stdout)
- Env var flow (SPRITE_NAME, OPENROUTER_API_KEY)
- Sprite commands called in correct order
- Temp files created and cleaned up
- Each script reaches its final interactive launch
Usage: bash test/run.sh
42 tests, all passing.
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>
Retry connectivity up to 6 attempts (30s) instead of trying once and
silently continuing, which caused the next sprite exec to fail under set -e.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- safe_read(): Test /dev/tty is functional before using it (exists
but fails in containers/VMs)
- Log functions: Write to stderr so they don't pollute stdout in
command substitutions like $(get_sprite_name)
- ensure_sprite_exists(): Fix grep regex (use -E for ERE)
Co-Authored-By: Claude Sonnet 4.5 <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>
## Problem
The command `curl URL | bash` isn't interactive because curl's output
consumes bash's stdin, preventing user prompts from working.
## Solution
Use bash process substitution instead: `bash <(curl URL)`
This keeps stdin available for the script while downloading from curl.
## Changes
- Added INTERACTIVE_CURL.md - Complete guide to interactive execution
- Added NON_INTERACTIVE_MODE.md - Guide to automation/CI usage
- Updated README.md to recommend `bash <(curl ...)` format
- Documented OpenRouter URL alias pattern
## Recommended Usage
Interactive (best UX):
bash <(curl -fsSL https://openrouter.ai/lab/spawn/sprite/claude.sh)
Non-interactive (CI/CD):
SPRITE_NAME=dev-mk1 curl URL | bash
## Why Process Substitution?
- Stdin available for prompts ✅
- Works like normal bash script ✅
- No /dev/tty workarounds needed ✅
- Better user experience ✅
Both methods are supported for maximum compatibility.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The scripts were failing when run via curl | bash because they tried
to read from /dev/tty which doesn't exist in piped contexts.
## Changes
- Added safe_read() helper function that gracefully handles TTY absence
- Updated get_sprite_name() to support SPRITE_NAME env variable
- Updated all read commands to use safe_read()
- Added clear error messages for non-interactive usage
- Updated README with non-interactive mode documentation
## Usage
Interactive:
curl URL | bash
Non-interactive:
SPRITE_NAME=dev-mk1 curl URL | bash
SPRITE_NAME=dev-mk1 OPENROUTER_API_KEY=sk-xxx curl URL | bash
## Fixes
- /dev/tty: No such device or address error
- Scripts now work in CI/CD and automated contexts
- OAuth fallback still works via OPENROUTER_API_KEY env var
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)