Document the mandatory git conventions for all agent team scripts:
always pull main before creating worktrees, use worktrees for parallel
branch work, include Agent: trailers in commits, and clean up worktrees
at end of cycle.
Agent: team-lead
Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add branch-cleaner role that cleans stale remote branches (>4 hours):
merges open PRs if mergeable, closes/deletes if stale
- Require Agent: trailer in all commit messages for traceability
- Switch git workflow from checkout -b to worktrees so parallel agents
don't clobber each other's uncommitted changes
- Always git fetch origin main before creating worktrees to ensure
branches start from latest main
- Add worktree setup/teardown to run_team_cycle and cleanup_between_cycles
Agent: team-lead
Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add branch-cleaner agent (Haiku) that cleans stale remote branches:
merges open PRs if mergeable, closes/deletes if stale >4 hours
- Require Agent: trailer in all commit messages so we can trace which
agent authored each change
- Switch from git checkout to git worktrees for parallel branch work,
preventing agents from clobbering each other's uncommitted changes
- Update Issue Fix Workflow to use worktree pattern
- Update Workflow with branch cleanup passes and worktree setup/teardown
Agent: team-lead
Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* ux: Improve error messages and user guidance across CLI and shell scripts
Enhanced error messages to be more actionable and user-friendly:
CLI improvements (commands.ts):
- Made validateNonEmptyString clearer: "is required but was not provided"
- Reordered troubleshooting steps to check matrix first (most common issue)
- Simplified 404 error message: "doesn't exist yet" vs "may not be implemented"
- Changed "Troubleshooting steps" to just "Troubleshooting" (less formal)
Shared library improvements (shared/common.sh):
- OAuth cancellation now explains why API key is needed and where to get it
- safe_read non-TTY error explains what non-interactive mode is with example
- get_resource_name error shows exact env var syntax needed
- Agent verification failures now list specific possible causes
- All improvements add context and next steps rather than just stating the problem
Hetzner library improvements (hetzner/lib/common.sh):
- Replaced technical "Remediation" with friendly "How to fix"
- Changed log_warn to log_error for error conditions (consistent severity)
- Added spacing for better readability of multi-line errors
- Made server creation errors more specific about account issues
All changes focus on helping users understand WHAT went wrong and HOW to fix it.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: Replace issue-triager with community-coordinator agent
Replace the issue-triager agent in the refactor team with a
community-coordinator that actively engages with GitHub issues:
acknowledges reports, posts interim updates, delegates to relevant
teammates, and posts final resolutions — so reporters feel heard.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fixes#59
The instanceof operator can fail in bundled/minified code or when
errors cross execution realm boundaries, causing the error:
"instanceof called on an object with an invalid prototype property"
This commit replaces all instanceof Error checks with duck typing
(checking for object with 'message' property) which is more reliable
across different execution contexts.
Changes:
- index.ts: Updated handleError() and prompt file error handling
- commands.ts: Updated getErrorMessage() helper
Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Updated overview to reflect current architecture (public sprite URL
with TRIGGER_SECRET bearer auth, not start service API)
- Added Step 5 for setting sprite URL auth to public
- Updated workflow template to use SPRITE_URL + TRIGGER_SECRET secrets
- Updated secret naming convention to match deployed services
- Added Step 10 for CLI-based end-to-end testing
- Added "Current Deployed Services" reference table
- Fixed all stale references and code samples
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Sprite start service API (/services/{name}/start) returns
"service name required" for all service names — appears to be an API
bug. Switched to hitting the sprite's public URL directly with
TRIGGER_SECRET bearer auth instead.
- Re-added TRIGGER_SECRET auth to trigger-server.ts
- Set sprite url_settings.auth to "public"
- Updated both workflows to use SPRITE_URL + TRIGGER_SECRET pattern
- Aligned workflow structure (both use same env vars and curl format)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use env vars from secrets instead of hardcoded names
- Add issues trigger (opened, reopened)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Security:
- Fix command injection in modal/lib/common.sh (run_server, upload_file, interactive_session)
- Fix command injection in fly/lib/common.sh (run_server, upload_file, interactive_session)
- All container providers now use printf '%q' for proper shell escaping
Complexity:
- Extract _api_should_retry_on_error() helper in shared/common.sh (-19 lines)
- Refactor scaleway_api and upcloud_api to use shared retry helper (-24 lines)
- Extract _save_fly_token() helper in fly/lib/common.sh (-11 lines)
- Extract validateAndGetAgent() in commands.ts, reducing cmdRun/cmdAgentInfo duplication
- Refactor cmdList column width calculation to use calculateColumnWidth()
UX:
- Add actionable next steps to error messages in shared/common.sh
- Improve CLI bash fallback error messages with guidance (spawn.sh)
- Add OAuth progress indicator during browser authentication wait
- Show invalid model ID value and link to openrouter.ai/models
- Add troubleshooting steps for agent installation failures
Tests:
- Update test assertions in test/run.sh to match refactored patterns
- All tests passing: 74 TypeScript + 75 bash = 149 total, 0 failures
Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sprite API rejects service names with hyphens. Renamed from
improve-trigger to improve_trigger.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
SERVICE_NAME env var may conflict with GitHub Actions internals.
Inline the secrets directly in the URL template instead.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
~/.bun/bin is often NOT in PATH, causing 'command not found' after
install. Now picks the first dir already in PATH from:
1. ~/.local/bin (most universal)
2. $(bun pm bin -g)
3. ~/.bun/bin
4. ~/bin
Also consolidated PATH detection and instructions into shared helpers,
with clear shell-specific instructions when the dir isn't in PATH.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
bun link only registers packages for project-level linking — it does
not create global CLI binaries. bun install -g has the same issue.
New approach:
- bun: build cli.js, copy directly to $(bun pm bin -g)/spawn (55KB)
- npm: build with esbuild, copy to $(npm bin -g)/spawn
- Both methods put the binary exactly where the runtime expects it
Also replaced brittle hardcoded file downloads with git sparse-checkout
(with GitHub API fallback), so new source files never break the installer.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The install script had a hardcoded list of source files to download,
which broke whenever a new file was added (e.g., security.ts). Also,
openrouter.ai/lab/spawn served a stale cached version without the fix.
Now uses git sparse-checkout (fast, gets only cli/) with a GitHub API
fallback for environments without git. Adding new source files will
never break the installer again.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
commands.ts imports ./security.js but install.sh never downloaded
security.ts, causing build to fail with "Could not resolve" error.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
package.json bin points to cli.js, but it was never built during
installation. Both bun link and npm install -g failed silently because
the file didn't exist.
- Bun path: run `bun run build` before `bun link`
- npm path: use npx esbuild to bundle cli.js with node shebang
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Sprite start service API returns streaming NDJSON, causing curl -f
to fail with exit code 22. Use duration=0s to return immediately and
drop -f flag since the response is streaming.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sprite may take time to wake from pause, causing --max-time 30 to fail
with exit code 22.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove TRIGGER_SECRET from trigger-server.ts and start-improve.sh
- Auth is handled at the Sprite API level via SPRITE_TOKEN
- Update SKILL.md: remove secret generation step, fix step numbering,
update embedded code and verification examples
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace SPRITE_URL/SPRITE_SECRET pattern with SPRITE_NAME/SERVICE_NAME
- Use Sprite start service API endpoint (api.sprites.dev)
- Share SPRITE_TOKEN across all services
- Update skill documentation to reflect new approach
- Delete deprecated URL/SECRET based secrets
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add note that skill is designed to run inside Sprite VM
- Update secret setup instructions for in-Sprite usage
- Add Prerequisites section
- Add troubleshooting for new concurrency limit error
- Improve guidance for obtaining Sprite URL
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Enhance the spawn CLI user experience with actionable error messages,
comprehensive help documentation, and visual progress feedback.
Changes:
- Help text: Add AUTHENTICATION, TROUBLESHOOTING, and MORE INFO sections
- Error messages: Show examples of valid options when validation fails
- Progress indicators: Add spinners for script downloads
- Install flow: Provide clear alternatives when npm install requires sudo
- README: Add environment variable documentation and alternative install URL
- Security errors: Suggest workarounds for false positives
All error messages now follow the pattern:
1. What went wrong
2. Why it matters
3. What to do next
Documentation: .docs/UX_IMPROVEMENTS_20260208.md
Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Add max 3 concurrent run limits:
- GitHub Actions: concurrency groups prevent workflow queue buildup
- trigger-server: tracks concurrent runs, rejects with 429 if at max
- Configurable via MAX_CONCURRENT env var (defaults to 3)
- Returns running count and max in trigger response
This prevents resource exhaustion when workflows trigger frequently.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Reorganize setup-trigger-service skill to be self-contained:
- Move trigger-server.ts, improve.sh, refactor.sh into skill directory
- Update SKILL.md to reference skill directory paths
- Update .gitignore to ignore start-*.sh wrapper scripts in skill dir
- Add guidance for creating new service scripts in the skill directory
This makes the skill fully self-contained and establishes a clear
pattern for adding new automation services.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The hook configuration had two issues:
- Invalid "dangerouslySkipPermissions" setting (not supported)
- Wrong PostToolUse hook format (missing "hooks" array with "type" field)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Reusable skill (/setup-trigger-service) that guides setting up:
- Bun-based HTTP trigger server on a Sprite
- GitHub Actions workflow for cron/event/manual triggers
- Secret generation and GitHub secrets configuration
Co-Authored-By: Claude Opus 4.6 (1M context) <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>
PRs created by autonomous loops must always be either merged or
closed with a comment explaining why. Updates improve.sh, refactor.sh,
and CLAUDE.md to enforce this consistently.
Co-authored-by: Sprite <noreply@sprite.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>