mirror of
https://github.com/OpenRouterTeam/spawn.git
synced 2026-04-28 03:49:31 +00:00
4 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
b0674550c6
|
feat: recursive spawn (--beta recursive) (#2978)
* feat: add recursive spawn (--beta recursive) Enables VMs to spawn child VMs. When --beta recursive is active: - Injects SPAWN_PARENT_ID, SPAWN_DEPTH, SPAWN_BETA=recursive into .spawnrc - Installs spawn CLI on the VM via install.sh - Delegates cloud + OpenRouter credentials to the VM - Tracks parent_id and depth on SpawnRecord for tree relationships - Adds `spawn tree` command for full recursive tree view - Adds `spawn history export` for pulling child history via SSH - Adds `spawn list --json` and `spawn list --flat` flags - Adds tree rendering in `spawn list` when parent-child relationships exist - Adds cascade delete support in delete.ts - Adds mergeChildHistory() for backward-pass history sync Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add recursive spawn to README Add --beta recursive to beta features table, new commands (spawn tree, spawn history export, spawn list --flat/--json) to commands table, and a dedicated Recursive Spawn section with usage examples for tree view and cascade delete. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * test: add cmdTree coverage tests to fix mock test CI The CI coverage threshold (90% functions, 80% lines) was failing because tree.ts had 0% coverage. Added tests that exercise cmdTree with empty history, tree rendering, JSON output, flat records, and deleted/depth labels. tree.ts now has 100% coverage. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(security): validate cloudName and use valibot in pullChildHistory - Add cloudName validation against ^[a-z0-9-]+$ to prevent command injection in delegateCloudCredentials - Export SpawnRecordSchema from history.ts and replace loose type guard with valibot schema validation in pullChildHistory - Resolve merge conflicts with main (include both docker and recursive beta features) Agent: pr-maintainer Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * test: add installSpawnCli and delegateCloudCredentials coverage Export and test installSpawnCli (success + timeout failure paths) and delegateCloudCredentials (no creds, with creds, write failure, mkdir failure paths) to improve orchestrate.ts function coverage. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: gritQL rule false positives and delete.ts coverage - use TsAsExpression() AST node instead of backtick pattern to avoid matching import aliases as type assertions - export and test findDescendants() and pullChildHistory() to bring delete.ts line coverage above the 35% threshold - add 8 new tests for descendant finding and history pull edge cases Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: B <6723574+louisgv@users.noreply.github.com> Co-authored-by: A <258483684+la14-1@users.noreply.github.com> |
||
|
|
76bdaf2042
|
fix: pin GitHub Actions to commit SHAs, version-lock CI tools (#2983)
* fix: pin all GitHub Actions to commit SHAs and version-lock tools Addresses supply chain hardening findings from issue #2982: - Pin all 6 GitHub Actions to full commit SHAs with version comments: - actions/checkout@v4 → SHA 34e1148... - oven-sh/setup-bun@v2 → SHA 0c5077e... - actions/github-script@v7 → SHA f28e40c... - docker/login-action@v3 → SHA c94ce9f... - docker/build-push-action@v6 → SHA 10e90e3... - hashicorp/setup-packer@main → SHA c3d53c5... (v3.2.0) - Pin Packer version: latest → 1.15.0 (in packer-snapshots.yml) - Pin bun version: latest → 1.3.11 (in agent-tarballs.yml) - Pin shellcheck: replace apt-get (no version) with pinned download of v0.10.0 from GitHub releases with SHA256 integrity check These changes eliminate the primary LiteLLM-style attack vector: a compromised action maintainer can no longer force-push malicious code to an existing tag and have it run in CI. Fixes #2982 Agent: issue-fixer Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * fix: exclude import aliases from no-type-assertion lint rule The `JsNamedImportSpecifier` exclusion prevents `import { foo as bar }` patterns from being flagged as type assertions. Previously, any `as` keyword in import/export statements triggered the ban because the GritQL pattern `$value as $type` matched import specifiers as well as actual TypeScript type assertions. This also removes the `as _foo` import aliases in the script-failure-guidance test file (replaced with direct imports + distinctly-named wrapper functions) which were the original manifestation of this bug. All 1944 tests pass. Biome check clean across 169 files. Agent: issue-fixer Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> --------- Co-authored-by: B <6723574+louisgv@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com> |
||
|
|
65a81edc57
|
fix: add unique spawn IDs to prevent history record corruption (#2235)
* fix: add unique spawn IDs to prevent history record corruption
History records were matched by heuristic ("most recent record for this
cloud without a connection"), which caused saveVmConnection and
saveLaunchCmd to overwrite the wrong record during concurrent or failed
spawns.
Fix: every SpawnRecord now has a unique `id` (UUID). All history
operations (saveVmConnection, saveLaunchCmd, removeRecord,
markRecordDeleted, mergeLastConnection) match by id when available,
falling back to the old heuristic for pre-migration records.
The orchestrator (TS path) now creates the history record AFTER server
creation succeeds, not before — so failed provisions don't leave orphan
entries.
Also adds "Remove from history" option to the spawn ls action picker,
restoring the ability to soft-delete entries without destroying the VM.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test: add 18 unit tests for spawn ID history behavior
Tests cover:
- generateSpawnId returns unique UUIDs
- saveSpawnRecord auto-generates id when not provided
- saveVmConnection matches by spawnId (not heuristic)
- saveVmConnection does not cross-contaminate concurrent spawns
- saveVmConnection falls back to heuristic without spawnId
- saveLaunchCmd matches by spawnId (not heuristic)
- saveLaunchCmd falls back without spawnId
- removeRecord matches by id, not by timestamp+agent+cloud
- removeRecord handles duplicate timestamps correctly
- removeRecord falls back for legacy records without id
- markRecordDeleted targets correct record by id
- mergeLastConnection uses spawn_id from last-connection.json
- mergeLastConnection falls back to heuristic without spawn_id
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* style: enable biome import sorting with grouped imports
Adds organizeImports to biome assist config with groups:
1. Type imports
2. Node built-ins
3. Third-party packages
4. @openrouter/* packages
5. Aliases
Auto-fixed import order and lint issues across all TypeScript files,
including .claude/skills/ and packages/cli/src/.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
||
|
|
6a5e0c5161
|
feat: SPA — Spawn's Personal Agent (#1825)
* feat: add Slack issue bot for #proj-spawn
Socket Mode bot that listens for @mentions in a configured Slack channel,
files GitHub issues via `gh` CLI, and syncs thread replies as issue comments.
State persisted to ~/.config/spawn/slack-issues.json.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: rewrite Spawnis to pipe threads into Claude Code sessions
- @mention triggers Claude Code with full thread as prompt
- Subsequent thread replies in tracked threads auto-trigger new runs
- System prompt focuses on GitHub issue management via `gh` CLI
- Streams Claude Code responses back to Slack in real-time
- Bot resolves own user ID at startup to skip self-messages
- Adds slack-manifest.yml for one-click Slack app creation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: lowercase display name to spawnis
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: rename to SPA — Spawn Processes Autonomously
Display name: spa
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: SPA — Spawn's Personal Agent
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: lowercase app name to Spa
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: add biome config and fix lint/format to match CLI rules
Adds local biome.json mirroring cli/biome.json rules (minus GritQL
plugins). Fixes all useBlockStatements errors and applies expand:always
formatting to match the project style.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: share biome config via root biome.json + extends
Move shared linter rules, formatter, and JS formatter settings to a
root-level biome.json. Both cli/ and .claude/skills/slack-bot/ extend
from it — CLI adds its GritQL plugins and test overrides, slack-bot
just overrides includes and disables VCS.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: move GritQL lint rules to repo root lint/
Move no-type-assertion.grit and no-typeof-string-number.grit from
cli/lint/ to lint/ at the repo root. Both cli/ and slack-bot share
the no-type-assertion rule; cli/ additionally uses no-typeof-string-number.
Plugin paths live in each child biome.json (not root) because biome
resolves plugin paths relative to the consumer config, not the extended
config.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: move shared biome.json into lint/
All shared lint config now lives under lint/:
lint/biome.json
lint/no-type-assertion.grit
lint/no-typeof-string-number.grit
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add no-banner-comments lint rule, fix slack-bot
GritQL can't match comments (they're trivia in biome's CST), so this
is a Bun script at lint/no-banner-comments.ts that catches decorative
// --------- separator blocks and suggests /** Section */ or #region.
Replace all 9 banner blocks in slack-bot.ts with /** */ headers.
Usage: bun run lint/no-banner-comments.ts [files...]
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: use // #region instead of /** */ section headers
Switch slack-bot.ts to // #region / // #endregion for all section
markers (collapsible in most editors). Update no-banner-comments lint
script to recommend #region as the preferred style.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: replace lint script with PostToolUse hook for banner comments
Move banner comment detection into the existing PostToolUse hook on
Write|Edit in .claude/settings.json. Runs inline on every .ts file
edit — no separate bun script needed. Delete lint/no-banner-comments.ts.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: simplify Slack manifest description
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: rename skill from slack-bot to setup-spa
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: use named import for @slack/bolt App class
Bun resolves `import App from "@slack/bolt"` as the App constructor
directly, not a module with a `.default` property. Switch to named
import `{ App }` and remove all `.default` usage.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: add --verbose flag required by stream-json output format
Claude Code requires --verbose when using --output-format=stream-json
with --print. Also fix systemd PATH to include ~/.local/bin for claude.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: stream all Claude Code events to Slack (tools, results, text)
Replace text-only streaming with full event parsing:
- Tool use: shows 🛠️ *ToolName*
- Tool result: shows truncated output in code block
- Text delta: accumulates as before
- Errors: shows ❌ prefix
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: enforce issue title templates in system prompt
Add mandatory bracket prefix format matching the repo's issue templates:
[Bug]:, [CLI]:, [Agent]:, [Cloud]:, [Team]:. Also instructs Claude to
apply matching labels (bug + pending-review, cli + enhancement, etc.).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: reference issue templates at runtime instead of hardcoding
Tell Claude to read .github/ISSUE_TEMPLATE/ for the correct title
prefix, labels, and fields rather than hardcoding them in the prompt.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude <claude@anthropic.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Renamed from cli/lint/no-type-assertion.grit (Browse further)