Roo Code CLI v0.0.50 (#11204)

* Roo Code CLI v0.0.50

* docs(cli): add --exit-on-error to changelog

---------

Co-authored-by: Roo Code <roomote@roocode.com>
This commit is contained in:
Chris Estreich 2026-02-04 18:14:15 -08:00 committed by GitHub
parent dcba685097
commit 6214f4c162
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 69 additions and 47 deletions

View file

@ -1,5 +1,5 @@
---
description: "Create a new release of the Roo Code CLI"
description: "Prepare a new release of the Roo Code CLI"
argument-hint: "[version-description]"
mode: code
---
@ -84,41 +84,3 @@ mode: code
- [ ] All CI checks pass" \
--base main
```
7. Wait for PR approval and merge:
- Request review if required by your workflow
- Ensure CI checks pass
- Merge the PR using: `gh pr merge --squash --delete-branch`
- Or merge via the GitHub UI
8. Run the release script from the monorepo root:
```bash
# Ensure you're on the updated main branch after the PR merge
git checkout main
git pull origin main
# Run the release script
./apps/cli/scripts/release.sh
```
The release script will automatically:
- Build the extension and CLI
- Create a platform-specific tarball
- Verify the installation works correctly (runs --help, --version, and e2e test)
- Extract changelog content and include it in the GitHub release notes
- Create the GitHub release with the tarball attached
9. After a successful release, verify:
- Check the release page: https://github.com/RooCodeInc/Roo-Code/releases
- Verify the "What's New" section contains the changelog content
- Test installation: `curl -fsSL https://raw.githubusercontent.com/RooCodeInc/Roo-Code/main/apps/cli/install.sh | sh`
**Notes:**
- The release script requires GitHub CLI (`gh`) to be installed and authenticated
- If a release already exists for the tag, the script will prompt to delete and recreate it
- The script creates a tarball for the current platform only (darwin-arm64, darwin-x64, linux-arm64, or linux-x64)
- Multi-platform releases require running the script on each platform and manually uploading additional tarballs

View file

@ -5,6 +5,29 @@ All notable changes to the `@roo-code/cli` package will be documented in this fi
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.0.50] - 2026-02-05
### Added
- **Linux Support**: The CLI now supports Linux platforms in addition to macOS
- **Roo Provider API Key Support**: Allow `--api-key` flag and `ROO_API_KEY` environment variable for the roo provider instead of requiring cloud auth token
- **Exit on Error**: New `--exit-on-error` flag to exit immediately on API request errors instead of retrying, useful for CI/CD pipelines
### Changed
- **Improved Dev Experience**: Dev scripts now use `tsx` for running directly from source without building first
- **Path Resolution Fixes**: Fixed path resolution in [`version.ts`](src/lib/utils/version.ts), [`extension.ts`](src/lib/utils/extension.ts), and [`extension-host.ts`](src/agent/extension-host.ts) to work from both source and bundled locations
- **Debug Logging**: Debug log file (`~/.roo/cli-debug.log`) is now disabled by default unless `--debug` flag is passed
- Updated README with complete environment variable table and dev workflow documentation
### Fixed
- Corrected example in install script
### Removed
- Dropped macOS 13 support
## [0.0.49] - 2026-01-18
### Added

View file

@ -71,7 +71,7 @@ By default, the CLI prompts for approval before executing actions:
```bash
export OPENROUTER_API_KEY=sk-or-v1-...
roo "What is this project?" -w ~/Documents/my-project
roo "What is this project?" -w ~/Documents/my-project
```
You can also run without a prompt and enter it interactively in TUI mode:

View file

@ -1,6 +1,6 @@
{
"name": "@roo-code/cli",
"version": "0.0.49",
"version": "0.0.50",
"description": "Roo Code CLI - Run the Roo Code agent from the command line",
"private": true,
"type": "module",
@ -15,11 +15,8 @@
"test": "vitest run",
"build": "tsup",
"build:extension": "pnpm --filter roo-cline bundle",
"build:all": "pnpm --filter roo-cline bundle && tsup",
"dev": "tsx src/index.ts",
"start": "ROO_AUTH_BASE_URL=http://localhost:3000 ROO_SDK_BASE_URL=http://localhost:3001 ROO_CODE_PROVIDER_URL=http://localhost:8080/proxy tsx src/index.ts",
"start:production": "node dist/index.js",
"build:local": "scripts/build.sh",
"dev": "ROO_AUTH_BASE_URL=https://app.roocode.com ROO_SDK_BASE_URL=https://cloud-api.roocode.com ROO_CODE_PROVIDER_URL=https://api.roocode.com/proxy tsx src/index.ts -y",
"dev:local": "ROO_AUTH_BASE_URL=http://localhost:3000 ROO_SDK_BASE_URL=http://localhost:3001 ROO_CODE_PROVIDER_URL=http://localhost:8080/proxy tsx src/index.ts",
"clean": "rimraf dist .turbo"
},
"dependencies": {

View file

@ -59,6 +59,11 @@ export interface AskDispatcherOptions {
*/
nonInteractive?: boolean
/**
* Whether to exit on API request errors instead of retrying.
*/
exitOnError?: boolean
/**
* Whether to disable ask handling (for TUI mode).
* In TUI mode, the TUI handles asks directly.
@ -87,6 +92,7 @@ export class AskDispatcher {
private promptManager: PromptManager
private sendMessage: (message: WebviewMessage) => void
private nonInteractive: boolean
private exitOnError: boolean
private disabled: boolean
/**
@ -100,6 +106,7 @@ export class AskDispatcher {
this.promptManager = options.promptManager
this.sendMessage = options.sendMessage
this.nonInteractive = options.nonInteractive ?? false
this.exitOnError = options.exitOnError ?? false
this.disabled = options.disabled ?? false
}
@ -518,6 +525,11 @@ export class AskDispatcher {
this.outputManager.output(` Error: ${text || "Unknown error"}`)
this.outputManager.markDisplayed(ts, text || "", false)
if (this.exitOnError) {
console.error(`[CLI] API request failed: ${text || "Unknown error"}`)
process.exit(1)
}
if (this.nonInteractive) {
this.outputManager.output("\n[retrying api request]")
// Auto-retry in non-interactive mode

View file

@ -79,6 +79,10 @@ export interface ExtensionHostOptions {
ephemeral: boolean
debug: boolean
exitOnComplete: boolean
/**
* When true, exit the process on API request errors instead of retrying.
*/
exitOnError?: boolean
/**
* When true, completely disables all direct stdout/stderr output.
* Use this when running in TUI mode where Ink controls the terminal.
@ -199,6 +203,7 @@ export class ExtensionHost extends EventEmitter implements ExtensionHostInterfac
promptManager: this.promptManager,
sendMessage: (msg) => this.sendToExtension(msg),
nonInteractive: options.nonInteractive,
exitOnError: options.exitOnError,
disabled: options.disableOutput, // TUI mode handles asks directly.
})
@ -468,6 +473,25 @@ export class ExtensionHost extends EventEmitter implements ExtensionHostInterfac
const cleanup = () => {
this.client.off("taskCompleted", completeHandler)
this.client.off("error", errorHandler)
if (messageHandler) {
this.client.off("message", messageHandler)
}
}
// When exitOnError is enabled, listen for api_req_retry_delayed messages
// (sent by Task.ts during auto-approval retry backoff) and exit immediately.
let messageHandler: ((msg: ClineMessage) => void) | null = null
if (this.options.exitOnError) {
messageHandler = (msg: ClineMessage) => {
if (msg.type === "say" && msg.say === "api_req_retry_delayed") {
cleanup()
reject(new Error(msg.text?.split("\n")[0] || "API request failed"))
}
}
this.client.on("message", messageHandler)
}
this.client.once("taskCompleted", completeHandler)

View file

@ -78,6 +78,7 @@ export async function run(promptArg: string | undefined, flagOptions: FlagOption
workspacePath: effectiveWorkspacePath,
extensionPath: path.resolve(flagOptions.extension || getDefaultExtensionPath(__dirname)),
nonInteractive: effectiveDangerouslySkipPermissions,
exitOnError: flagOptions.exitOnError,
ephemeral: flagOptions.ephemeral,
debug: flagOptions.debug,
exitOnComplete: effectiveExitOnComplete,

View file

@ -18,7 +18,8 @@ program
.option("-p, --print", "Print response and exit (non-interactive mode)", false)
.option("-e, --extension <path>", "Path to the extension bundle directory")
.option("-d, --debug", "Enable debug output (includes detailed debug information)", false)
.option("-y, --yes, --dangerously-skip-permissions", "Auto-approve all prompts (use with caution)", false)
.option("-y, --yes", "Auto-approve all prompts (use with caution)", false)
.option("--dangerously-skip-permissions", "Alias for --yes", false)
.option("-k, --api-key <key>", "API key for the LLM provider")
.option("--provider <provider>", "API provider (roo, anthropic, openai, openrouter, etc.)")
.option("-m, --model <model>", "Model to use", DEFAULT_FLAGS.model)
@ -28,6 +29,7 @@ program
"Reasoning effort level (unspecified, disabled, none, minimal, low, medium, high, xhigh)",
DEFAULT_FLAGS.reasoningEffort,
)
.option("--exit-on-error", "Exit on API request errors instead of retrying", false)
.option("--ephemeral", "Run without persisting state (uses temporary storage)", false)
.option("--oneshot", "Exit upon task completion", false)
.option(

View file

@ -26,6 +26,7 @@ export type FlagOptions = {
debug: boolean
yes: boolean
dangerouslySkipPermissions: boolean
exitOnError: boolean
apiKey?: string
provider?: SupportedProvider
model?: string