Bladeren bron

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 <[email protected]>
Chris Estreich 1 week geleden
bovenliggende
commit
6214f4c162

+ 1 - 39
.roo/commands/cli-release.md

@@ -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

+ 23 - 0
apps/cli/CHANGELOG.md

@@ -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

+ 1 - 1
apps/cli/README.md

@@ -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:

+ 3 - 6
apps/cli/package.json

@@ -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": {

+ 12 - 0
apps/cli/src/agent/ask-dispatcher.ts

@@ -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

+ 24 - 0
apps/cli/src/agent/extension-host.ts

@@ -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)

+ 1 - 0
apps/cli/src/commands/cli/run.ts

@@ -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,

+ 3 - 1
apps/cli/src/index.ts

@@ -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(

+ 1 - 0
apps/cli/src/types/types.ts

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