Skip to content
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed

- `agent-relay fleet spawn` explains how to reuse a retained agent name with `fleet release <name> --delete-agent --wait` when registration fails with `agent_already_exists`.
- The installer's Quick Start now prints `agent-relay node up --background` and `agent-relay node down`, which exist, instead of the removed `agent-relay up` form that failed with "unknown command 'up'". An install pinned with `AGENT_RELAY_VERSION` to a release older than 9.2.2 still prints the top-level `up`/`down` forms that release has.

## [13.3.0] - 2026-10-10

Expand Down
14 changes: 12 additions & 2 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1279,17 +1279,27 @@ verify_installation() {

# Print usage instructions
print_usage() {
# The broker commands moved under `node` in 9.2.2. A pinned older install
# (AGENT_RELAY_VERSION) still has only the top-level `up`/`down` forms.
local node_group="node "
local major minor patch
if [[ "$VERSION" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+) ]]; then
major=${BASH_REMATCH[1]}; minor=${BASH_REMATCH[2]}; patch=${BASH_REMATCH[3]}
if (( major < 9 || (major == 9 && (minor < 2 || (minor == 2 && patch < 2))) )); then
node_group=""
fi
fi
echo ""
echo -e "${BOLD}Quick Start:${NC}"
echo ""
echo " # Start the local broker (detached so this terminal stays free)"
echo " agent-relay up --background"
echo " agent-relay ${node_group}up --background"
echo ""
echo " # Check status"
echo " agent-relay status"
echo ""
echo " # Stop the broker"
echo " agent-relay down"
echo " agent-relay ${node_group}down"
echo ""
echo -e "${BOLD}Documentation:${NC} https://github.com/AgentWorkforce/relay"
echo ""
Expand Down
42 changes: 42 additions & 0 deletions packages/cli/src/cli/bootstrap.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { execFileSync } from 'node:child_process';
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
Expand Down Expand Up @@ -483,3 +484,44 @@ describe('telemetry context propagation', () => {
}
});
});

describe('install.sh quick start', () => {
const installScript = fs.readFileSync(new URL('../../../../install.sh', import.meta.url), 'utf-8');
const usageFunction = installScript.match(/^print_usage\(\)\s*\{\n[\s\S]*?^\}/m)?.[0] ?? '';

function quickStartCommands(version: string): string[] {
// Run the real function so version-dependent command forms are what we check.
const output = execFileSync('bash', ['-c', `${usageFunction}\nprint_usage`], {
encoding: 'utf-8',
env: { ...process.env, VERSION: version, BOLD: '', NC: '' },
});
return [...output.matchAll(/^\s*agent-relay (.+)$/gm)].map((match) => match[1].trim());
}

it('prints only commands this CLI actually has', () => {
// The installer once printed `agent-relay up --background` after `up` moved
// under `node`, so a first run failed with "unknown command 'up'".
expect(usageFunction).not.toBe('');
const commands = quickStartCommands('latest');
expect(commands).toContain('node up --background');
const program = createProgram();
for (const command of commands) {
let current: Command = program;
// Flags, <placeholders>, and anything after a leaf command are arguments, not command words.
for (const word of command
.split(/\s+/)
.filter((part) => !part.startsWith('-') && !/^<[^>]+>$/.test(part))) {
if (current !== program && current.commands.length === 0) break;
const next = current.commands.find((sub) => sub.name() === word || sub.aliases().includes(word));
expect(next, `agent-relay ${command}: no "${word}" command`).toBeDefined();
current = next as Command;
}
}
});

it('keeps the top-level up/down forms for pinned installs older than 9.2.2', () => {
expect(quickStartCommands('9.2.1')).toEqual(['up --background', 'status', 'down']);
expect(quickStartCommands('9.2.2')).toEqual(['node up --background', 'status', 'node down']);
expect(quickStartCommands('13.1.5')).toEqual(['node up --background', 'status', 'node down']);
});
});
Loading