fix(sprite): use new --flag forms required by sprite CLI v0.0.1-rc43+ (#3409)
Some checks failed
CLI Release / Build and release CLI (push) Has been cancelled
Lint / ShellCheck (push) Has been cancelled
Lint / Biome Lint (push) Has been cancelled
Lint / macOS Compatibility (push) Has been cancelled

The sprite CLI rejects the legacy single-dash long-flag forms we still
emit, so `spawn run <agent>` fails on sprite at the very first remote
call (`sprite create -skip-console NAME`) before any agent install runs.

Updates the calls + tests to the supported forms:

- sprite create  -skip-console      → --skip-console
- sprite exec    -tty               → --tty
- sprite exec    -file SRC:DST      → --file SRC:DST
- sprite version  (subcommand gone) → sprite --version
- sprite url      (deprecated)      → sprite info  (URL still extracted
                                       via the existing https://… regex)

Bumps @openrouter/spawn to 1.0.44 so users on sprite pick up the fix on
their next run.

Reported by Andrew via Slack; tracking issue #3408.

Co-authored-by: Claude <claude@anthropic.com>
This commit is contained in:
A 2026-05-13 05:58:27 -07:00 committed by GitHub
parent 844808cd7d
commit cdf2bec2d1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 28 additions and 20 deletions

View file

@ -1,6 +1,6 @@
{
"name": "@openrouter/spawn",
"version": "1.0.43",
"version": "1.0.44",
"type": "module",
"bin": {
"spawn": "cli.js"

View file

@ -233,7 +233,7 @@ describe("cmdEnterAgent", () => {
expect(processExitSpy).toHaveBeenCalledWith(1);
});
it("enters agent via sprite exec -tty", async () => {
it("enters agent via sprite exec --tty", async () => {
const conn = makeConn({
ip: "sprite-console",
server_name: "my-sprite",
@ -244,7 +244,7 @@ describe("cmdEnterAgent", () => {
const args = spawnInteractiveSpy.mock.calls[0][0];
expect(args[0]).toBe("sprite");
expect(args).toContain("exec");
expect(args).toContain("-tty");
expect(args).toContain("--tty");
expect(args).toContain("my-sprite");
});

View file

@ -60,7 +60,7 @@ function makeManifest(overrides?: Partial<Manifest>): Manifest {
auth: "sprite login",
provision_method: "cli",
exec_method: "sprite exec NAME",
interactive_method: "sprite exec NAME -tty",
interactive_method: "sprite exec NAME --tty",
},
digitalocean: {
name: "DigitalOcean",

View file

@ -193,7 +193,7 @@ describe("interactiveSession (keep-alive wrapper)", () => {
expect(capturedSessionScript).toContain(expectedB64);
});
it("uses -tty flag for interactive mode (SPAWN_PROMPT not set)", async () => {
it("uses --tty flag for interactive mode (SPAWN_PROMPT not set)", async () => {
delete process.env.SPAWN_PROMPT;
let capturedArgs: string[] = [];
@ -204,10 +204,10 @@ describe("interactiveSession (keep-alive wrapper)", () => {
await interactiveSession("agent-cmd", mockSpawnInteractive);
expect(capturedArgs).toContain("-tty");
expect(capturedArgs).toContain("--tty");
});
it("omits -tty flag when SPAWN_PROMPT is set", async () => {
it("omits --tty flag when SPAWN_PROMPT is set", async () => {
process.env.SPAWN_PROMPT = "non-interactive";
let capturedArgs: string[] = [];
@ -218,7 +218,7 @@ describe("interactiveSession (keep-alive wrapper)", () => {
await interactiveSession("agent-cmd", mockSpawnInteractive);
expect(capturedArgs).not.toContain("-tty");
expect(capturedArgs).not.toContain("--tty");
});
it("returns the exit code from spawnInteractive", async () => {

View file

@ -255,8 +255,9 @@ export async function cmdEnterAgent(
const agentName = agentDef?.name || agentKey;
// Handle Sprite connections — use `sprite exec -tty` to run a command interactively.
// Handle Sprite connections — use `sprite exec --tty` to run a command interactively.
// `sprite console` does NOT accept arguments; it is a pure interactive shell.
// (`-tty` was the old single-dash form; sprite CLI v0.0.1-rc43+ requires `--tty`.)
if (connection.ip === "sprite-console" && connection.server_name) {
p.log.step(`Entering ${pc.bold(agentName)} on sprite ${pc.bold(connection.server_name)}...`);
return runInteractiveCommand(
@ -265,14 +266,14 @@ export async function cmdEnterAgent(
"exec",
"-s",
connection.server_name,
"-tty",
"--tty",
"--",
"bash",
"-lc",
remoteCmd,
],
`Failed to enter ${agentName}`,
`sprite exec -s ${connection.server_name} -tty -- bash -lc '${remoteCmd}'`,
`sprite exec -s ${connection.server_name} --tty -- bash -lc '${remoteCmd}'`,
);
}

View file

@ -142,10 +142,11 @@ function getSpriteCmd(): string | null {
export async function ensureSpriteCli(): Promise<void> {
const cmd = getSpriteCmd();
if (cmd) {
// Log version if available
// Log version if available. The `version` subcommand was removed in
// sprite CLI v0.0.1-rc43+; only `--version` is still supported.
const { stdout } = spawnSync([
cmd,
"version",
"--version",
]);
const ver = stdout.match(/v?\d+\.\d+\.\d+(-rc\d+)?/)?.[0];
if (ver) {
@ -318,7 +319,9 @@ export async function createSprite(name: string): Promise<void> {
cmd,
...orgFlags(),
"create",
"-skip-console",
// `--skip-console` (two dashes) — sprite CLI v0.0.1-rc43+ rejects
// the legacy single-dash `-skip-console` form.
"--skip-console",
name,
],
{
@ -422,11 +425,13 @@ export function startLocalKeepAlive(): void {
return;
}
// Get the sprite's public URL
// Get the sprite's public URL. `sprite url` is deprecated in v0.0.1-rc43+
// ("Command \"url\" is deprecated, use 'sprite info' to view"); `sprite info`
// prints the URL in the same line-form so the existing regex still matches.
const urlResult = spawnSync([
cmd,
...orgFlags(),
"url",
"info",
"-s",
_state.name,
]);
@ -571,8 +576,8 @@ async function runSpriteSilent(cmd: string): Promise<void> {
}
/**
* Upload a local file to the remote sprite using sprite exec -file flag.
* The -file flag format is "localpath:remotepath".
* Upload a local file to the remote sprite using sprite exec --file flag.
* The --file flag format is "localpath:remotepath".
*/
export async function uploadFileSprite(localPath: string, remotePath: string): Promise<void> {
const normalizedRemote = validateRemotePath(remotePath, /^[a-zA-Z0-9/_.~-]+$/);
@ -602,7 +607,8 @@ export async function uploadFileSprite(localPath: string, remotePath: string): P
"exec",
"-s",
_state.name,
"-file",
// `--file` (two dashes) — sprite CLI v0.0.1-rc43+ rejects `-file`.
"--file",
`${localPath}:${tempRemote}`,
"--",
"mkdir",
@ -781,7 +787,8 @@ export async function interactiveSession(cmd: string, spawnFn?: (args: string[])
"exec",
"-s",
_state.name,
"-tty",
// `--tty` (two dashes) — sprite CLI v0.0.1-rc43+ rejects `-tty`.
"--tty",
"--",
"bash",
"-c",