Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 1 addition & 39 deletions .roo/commands/cli-release.md
Original file line number Diff line number Diff line change
@@ -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
---
Expand Down Expand Up @@ -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
23 changes: 23 additions & 0 deletions apps/cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Comment on lines +12 to +13
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new --exit-on-error option is implemented in this PR but not documented here. Consider adding it to the changelog entry.

Suggested change
- **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
- **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

Fix it with Roo Code or mention @roomote and request a fix.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@roomote Please fix.

Copy link
Contributor

@roomote roomote bot Feb 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixaroo Clock   See task on Roo Cloud

Fixed the reported issue. Added --exit-on-error documentation to the changelog.

View commit | Revert commit

- **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
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
9 changes: 3 additions & 6 deletions apps/cli/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand All @@ -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": {
Expand Down
12 changes: 12 additions & 0 deletions apps/cli/src/agent/ask-dispatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -87,6 +92,7 @@ export class AskDispatcher {
private promptManager: PromptManager
private sendMessage: (message: WebviewMessage) => void
private nonInteractive: boolean
private exitOnError: boolean
private disabled: boolean

/**
Expand All @@ -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
}

Expand Down Expand Up @@ -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
Expand Down
24 changes: 24 additions & 0 deletions apps/cli/src/agent/extension-host.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
})

Expand Down Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions apps/cli/src/commands/cli/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 3 additions & 1 deletion apps/cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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(
Expand Down
1 change: 1 addition & 0 deletions apps/cli/src/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export type FlagOptions = {
debug: boolean
yes: boolean
dangerouslySkipPermissions: boolean
exitOnError: boolean
apiKey?: string
provider?: SupportedProvider
model?: string
Expand Down
Loading