### Install Script - Install Binary Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/260417-1441-openrouter-cli/phase-11-cross-platform-build-release.md Installs the verified OpenRouter CLI binary to the specified prefix, defaulting to /usr/local/bin. Allows overriding the installation path with the PREFIX environment variable. ```bash PREFIX=${PREFIX:-/usr/local} INSTALL_DIR="$PREFIX/bin" chmod +x openrouter mkdir -p "$INSTALL_DIR" mv openrouter "$INSTALL_DIR/openrouter" echo "OpenRouter CLI installed to $INSTALL_DIR/openrouter" echo "Run 'export PATH=\"$INSTALL_DIR:$PATH\"' to add it to your PATH." ``` -------------------------------- ### Install OpenRouter CLI Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plugins/openrouter/skills/openrouter/SKILL.md Choose one installation method for the OpenRouter CLI. Verify the installation with `openrouter --version` and `openrouter --help`. ```bash brew install openrouter/tap/openrouter # macOS / Linux ``` ```bash curl -fsSL https://raw.githubusercontent.com/mrgoonie/openrouter-cli/main/install.sh | sh ``` ```bash npm install -g @mrgoonie/openrouter-cli # npm ``` -------------------------------- ### Build OpenRouter CLI from Source Source: https://github.com/mrgoonie/openrouter-cli/blob/main/README.md Clone the repository, install dependencies with Bun, and build the CLI executable. This is for development or if other installation methods fail. ```bash git clone https://github.com/mrgoonie/openrouter-cli cd openrouter-cli bun install bun run build # outputs bin/openrouter ./bin/openrouter --help ``` -------------------------------- ### Clone and Install Dependencies Source: https://github.com/mrgoonie/openrouter-cli/blob/main/README.md Clone the repository and install project dependencies using bun. ```bash git clone bun install ``` -------------------------------- ### Install OpenRouter CLI with npm Source: https://github.com/mrgoonie/openrouter-cli/blob/main/docs/deployment-guide.md Install the CLI globally using npm. Alternatively, use npx to run the CLI without a global installation. ```bash npm install -g @mrgoonie/openrouter-cli ``` ```bash npx @mrgoonie/openrouter-cli --help ``` -------------------------------- ### Install OpenRouter CLI via npm Source: https://github.com/mrgoonie/openrouter-cli/blob/main/README.md Install the CLI globally using npm. Ensure you have Node.js and npm installed. ```bash npm install -g @mrgoonie/openrouter-cli ``` -------------------------------- ### Environment Variable Configuration Example Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/reports/researcher-260417-1441-cli-agent-friendly-patterns.md Example of environment variables used for configuration. These are loaded after command-line flags and before local files. ```dotenv OPENROUTER_API_URL=https://openrouter.ai/api/v1 OPENROUTER_MODEL=gpt-4 ``` -------------------------------- ### Example .env Configuration Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/reports/researcher-260417-1441-api-key-resolution.md Illustrates the structure for storing an API key in a TOML configuration file. This serves as a fallback mechanism when other sources are not available. ```toml [auth] api_key = "sk-or-..." # Fallback only ``` -------------------------------- ### Local Development Commands Source: https://github.com/mrgoonie/openrouter-cli/blob/main/docs/tech-stack.md Commands for installing dependencies, running the development server, and executing tests locally. ```bash bun install bun run dev -- chat send "hello" # runs src/main.ts directly bun test bun run build # emits ./bin/openrouter ``` -------------------------------- ### Install OpenRouter CLI with Curl Source: https://github.com/mrgoonie/openrouter-cli/blob/main/docs/deployment-guide.md A one-liner command to download and execute the installation script for Linux and macOS. The script automatically detects the OS and architecture. ```bash curl -fsSL https://raw.githubusercontent.com/mrgoonie/openrouter-cli/main/install.sh | sh ``` -------------------------------- ### E2E Test Harness Setup Source: https://github.com/mrgoonie/openrouter-cli/blob/main/docs/code-standards.md Use `startMockServer` and `spawnCli` for end-to-end testing. Gate slow tests with `describe.skipIf` and ensure basic commands exit correctly. ```typescript // Use `startMockServer()` from `tests/fixtures/mock-server.ts` // Spawn CLI via `spawnCli()` from `tests/e2e/harness.ts` // Gate slow tests with `describe.skipIf(!process.env.E2E)` // Always-on smoke tests: `--help` exits 0, missing args exits non-zero ``` -------------------------------- ### Config Precedence Debugging Example Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/reports/researcher-260417-1441-cli-agent-friendly-patterns.md Illustrates how to print the resolved configuration sources when the `--verbose` flag is used, aiding in debugging configuration precedence confusion. ```text [DEBUG] Config sources: env OPENROUTER_API_KEY > .env.local ``` -------------------------------- ### Install OpenRouter CLI with Homebrew Source: https://github.com/mrgoonie/openrouter-cli/blob/main/docs/deployment-guide.md Use this command to install the OpenRouter CLI on macOS or Linux systems that have Homebrew installed. ```bash brew install openrouter/tap/openrouter ``` -------------------------------- ### Local Environment Variable Configuration Example Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/reports/researcher-260417-1441-cli-agent-friendly-patterns.md Example of a local environment file, typically gitignored, for machine-specific secrets like API keys. ```dotenv OPENROUTER_API_KEY=sk-... ``` -------------------------------- ### Curl-based Installer Script Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/260417-1441-openrouter-cli/phase-11-cross-platform-build-release.md This POSIX-compliant shell script fetches the latest release of the OpenRouter CLI, detects the OS and architecture, verifies the SHA-256 checksum, and installs the binary to a common user binary directory. It includes fallback mechanisms for installation paths. ```shell #!/bin/sh # --- Configuration --- REPO="mrgoonie/openrouter-cli" INSTALL_DIR="/usr/local/bin" FALLBACK_INSTALL_DIR="$HOME/.local/bin" # --- Helper Functions --- log() { echo "[openrouter-cli installer] $1" } error() { log "ERROR: $1" exit 1 } # --- Detect OS and Architecture --- OS="$(uname -s | tr '[:upper:]' '[:lower:]')" ARCH="$(uname -m)" case "$OS" in "linux") OS="linux" ;; "darwin") OS="darwin" ;; "freebsd") OS="freebsd" ;; *) error "Unsupported OS: $OS" esac case "$ARCH" in "x86_64" | "amd64") ARCH="x64" ;; "aarch64" | "arm64") ARCH="arm64" ;; "armv7l") ARCH="armv7l" ;; *) error "Unsupported architecture: $ARCH" esac TARGET="${OS}-${ARCH}" # --- Determine Latest Release --- log "Fetching latest release information for $REPO..." API_URL="https://api.github.com/repos/$REPO/releases/latest" # Use curl to fetch release data. Handle potential errors. RELEASE_INFO=$(curl -fsSL "$API_URL") if [ $? -ne 0 ]; then error "Failed to fetch release information from GitHub API." fi # Extract download URL and version using jq (or alternative if jq is not available) # Fallback to grep/sed if jq is not present DOWNLOAD_URL=$(echo "$RELEASE_INFO" | grep 'browser_download_url' | grep "$TARGET" | cut -d '"' -f 4) VERSION=$(echo "$RELEASE_INFO" | grep 'tag_name' | cut -d '"' -f 4 | sed 's/^v//') CHECKSUMS_URL=$(echo "$RELEASE_INFO" | grep 'browser_download_url' | grep 'checksums.txt' | cut -d '"' -f 4) if [ -z "$DOWNLOAD_URL" ]; then error "Could not find a download URL for target $TARGET." fi if [ -z "$VERSION" ]; then error "Could not determine the latest version." fi if [ -z "$CHECKSUMS_URL" ]; then error "Could not find checksums file URL." fi log "Latest version: $VERSION" log "Target: $TARGET" log "Download URL: $DOWNLOAD_URL" # --- Download Artifact and Checksums --- log "Downloading artifact..." ARTIFACT_NAME="openrouter-${TARGET}" if [ "$OS" = "win32" ]; then ARTIFACT_NAME="${ARTIFACT_NAME}.exe" fi TEMP_DIR=$(mktemp -d) ARTIFACT_PATH="$TEMP_DIR/$ARTIFACT_NAME" CHECKSUMS_PATH="$TEMP_DIR/checksums.txt" curl -fSL "$DOWNLOAD_URL" -o "$ARTIFACT_PATH" if [ $? -ne 0 ]; then error "Failed to download artifact." fi log "Downloading checksums..." curl -fSL "$CHECKSUMS_URL" -o "$CHECKSUMS_PATH" if [ $? -ne 0 ]; then error "Failed to download checksums file." fi # --- Verify Checksum --- log "Verifying checksum..." EXPECTED_CHECKSUM=$(grep "$ARTIFACT_NAME" "$CHECKSUMS_PATH" | awk '{print $1}') if [ -z "$EXPECTED_CHECKSUM" ]; then error "Could not find checksum for $ARTIFACT_NAME in checksums file." fi ACTUAL_CHECKSUM="$(sha256sum "$ARTIFACT_PATH" | awk '{print $1}')" if [ "$ACTUAL_CHECKSUM" != "$EXPECTED_CHECKSUM" ]; then error "Checksum mismatch! Expected: $EXPECTED_CHECKSUM, Got: $ACTUAL_CHECKSUM" fi log "Checksum verified successfully." # --- Install Binary --- INSTALL_PATH="" if [ -w "$INSTALL_DIR" ]; then INSTALL_PATH="$INSTALL_DIR/openrouter" log "Installing to $INSTALL_PATH..." else log "$INSTALL_DIR is not writable. Trying fallback: $FALLBACK_INSTALL_DIR" if [ -w "$FALLBACK_INSTALL_DIR" ]; then INSTALL_PATH="$FALLBACK_INSTALL_DIR/openrouter" log "Installing to $INSTALL_PATH..." else error "Neither $INSTALL_DIR nor $FALLBACK_INSTALL_DIR are writable. Please install manually or adjust permissions." fi fi cp "$ARTIFACT_PATH" "$INSTALL_PATH" if [ $? -ne 0 ]; then error "Failed to copy binary to installation path." fi chmod +x "$INSTALL_PATH" # --- Cleanup --- rm -rf "$TEMP_DIR" log "OpenRouter CLI version $VERSION installed successfully to $INSTALL_PATH." exit 0 ``` -------------------------------- ### NPM Wrapper Postinstall Script Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/260417-1441-openrouter-cli/phase-11-cross-platform-build-release.md This script is executed after the npm package is installed. It downloads the appropriate platform-specific binary for the OpenRouter CLI and makes it available. ```javascript #!/usr/bin/env node const fs = require('fs'); const path = require('path'); const os = require('os'); const https = require('https'); const REPO = 'mrgoonie/openrouter-cli'; const BIN_DIR = path.join(__dirname, '..', 'bin'); const EXECUTABLE_NAME = 'openrouter'; const getPlatform = () => { const platform = os.platform(); const arch = os.arch(); let target = ''; switch (platform) { case 'linux': target += 'linux'; break; case 'darwin': target += 'darwin'; break; case 'win32': target += 'win32'; break; default: throw new Error(`Unsupported platform: ${platform}`); } target += '-'; switch (arch) { case 'x64': target += 'x64'; break; case 'arm64': target += 'arm64'; break; default: throw new Error(`Unsupported architecture: ${arch}`); } return target; }; const downloadFile = (url, dest) => { return new Promise((resolve, reject) => { const file = fs.createWriteStream(dest); https.get(url, (response) => { if (response.statusCode !== 200) { reject(new Error(`Failed to download file. Status code: ${response.statusCode}`)); return; } response.pipe(file); file.on('finish', () => { file.close(resolve); }); file.on('error', (err) => { fs.unlink(dest, () => reject(err)); }); }).on('error', (err) => { fs.unlink(dest, () => reject(err)); }); }); }; const main = async () => { try { const target = getPlatform(); const version = 'latest'; // In a real scenario, fetch the latest version dynamically const artifactName = `${EXECUTABLE_NAME}-${target}${target === 'win32-x64' ? '.exe' : ''}`; const downloadUrl = `https://github.com/${REPO}/releases/download/${version}/${artifactName}`; const destPath = path.join(BIN_DIR, EXECUTABLE_NAME); if (!fs.existsSync(BIN_DIR)) { fs.mkdirSync(BIN_DIR, { recursive: true }); } console.log(`Downloading OpenRouter CLI for ${target} from ${downloadUrl}...`); await downloadFile(downloadUrl, destPath); fs.chmodSync(destPath, 0o755); // Make executable console.log(`OpenRouter CLI installed to ${destPath}`); // Optional: Add logic here to ensure the downloaded binary is used by default // or provide instructions to the user. } catch (error) { console.error('Error during OpenRouter CLI installation:', error.message); // Fallback or error handling } }; main(); ``` -------------------------------- ### Build OpenRouter CLI from Source Source: https://github.com/mrgoonie/openrouter-cli/blob/main/docs/deployment-guide.md Steps to clone the repository, install dependencies with Bun, build the binaries, and run the CLI. Requires Bun version 1.1.38 or higher. ```bash git clone https://github.com/mrgoonie/openrouter-cli cd openrouter-cli bun install bun run build # outputs bin/openrouter ./bin/openrouter --help ``` -------------------------------- ### Install Script - Download Binary and Checksums Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/260417-1441-openrouter-cli/phase-11-cross-platform-build-release.md Downloads the OpenRouter CLI binary and its checksums file using curl. It then verifies the integrity of the downloaded binary. ```bash BINARY_URL="${API_URL}/download/v${OPENROUTER_VERSION}/openrouter-${ARCH}-${OS}" CHECKSUMS_URL="${API_URL}/download/v${OPENROUTER_VERSION}/checksums.txt" curl -L "$BINARY_URL" -o openrouter curl -L "$CHECKSUMS_URL" -o checksums.txt # Verify checksum if [ "$OS" = "linux" ]; then sha256sum -c checksums.txt else shasum -a 256 -c checksums.txt fi ``` -------------------------------- ### Install Script - Detect OS and Architecture Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/260417-1441-openrouter-cli/phase-11-cross-platform-build-release.md Detects the operating system and CPU architecture to determine the correct binary to download. Supports Darwin (macOS) and Linux. ```bash OS=$(uname -s) ARCH=$(uname -m) case $OS in Darwin) OS=macos ;; Linux) OS=linux ;; *) echo "Unsupported OS: $OS" exit 1 ;; esac case $ARCH in x86_64) ARCH=x86_64 ;; arm64) ARCH=aarch64 ;; *) echo "Unsupported architecture: $ARCH" exit 1 ;; esac ``` -------------------------------- ### Embeddings Create - Pretty Output Summary Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/260417-1441-openrouter-cli/phase-07-embeddings-rerank.md Example of the summary output for the embeddings create command when not in JSON mode. ```bash N × D vectors · cost $X ``` -------------------------------- ### Install Claude Code Plugin for OpenRouter CLI Source: https://github.com/mrgoonie/openrouter-cli/blob/main/README.md Install the OpenRouter CLI plugin within Claude Code by first adding the plugin from its marketplace URL and then installing the specific `openrouter` package. ```bash # Inside Claude Code: /plugin marketplace add https://github.com/mrgoonie/openrouter-cli /plugin install openrouter@openrouter-cli ``` -------------------------------- ### Agent-Mode JSON Output Example Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plugins/openrouter/skills/openrouter/SKILL.md Example of the stable JSON envelope output when using the --json flag in agent mode. ```json {"schema_version":"1","success":true,"data":{...},"error":null,"meta":{"request_id":"gen-...", ``` -------------------------------- ### Noun-Verb Command Structure Examples Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/reports/researcher-260417-1441-cli-agent-friendly-patterns.md Illustrates the recommended noun-verb pattern for organizing CLI commands, promoting logical grouping and discoverability. This structure mirrors common tools like Git and Docker. ```bash openrouter chat send # Chat API openrouter models list # Models listing openrouter models info # Model details openrouter auth login # Authentication openrouter config set # Configuration openrouter video upload # Video endpoints ``` -------------------------------- ### Rerank Run - Pretty Output Table Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/260417-1441-openrouter-cli/phase-07-embeddings-rerank.md Example of the ranked table output for the rerank run command. ```bash rank · score · doc (truncated 80 char) ``` -------------------------------- ### Verify Release with Homebrew Source: https://github.com/mrgoonie/openrouter-cli/blob/main/docs/deployment-guide.md After a release, update Homebrew and check the installed version of the OpenRouter CLI to confirm the update. ```bash brew update && brew upgrade openrouter openrouter --version # should show X.Y.Z ``` -------------------------------- ### System Prompt and User Message Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plugins/openrouter/skills/openrouter/references/chat-workflows.md Initiate a chat with a system-level instruction followed by a user message. This helps guide the model's behavior for the conversation. ```bash openrouter chat send "Translate to French: Hello" \ --system "You are a precise translator. Reply with the translation only." \ --model openai/gpt-4o --json --no-stream ``` -------------------------------- ### Debug OpenRouter CLI Configuration Source: https://github.com/mrgoonie/openrouter-cli/blob/main/README.md Output detailed configuration information in JSON format to help diagnose setup issues. ```bash openrouter config doctor --json ``` -------------------------------- ### Release to GitHub using gh CLI Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/260417-1441-openrouter-cli/phase-11-cross-platform-build-release.md Uploads compiled binaries to a GitHub Release. Ensure you have the GitHub CLI installed and authenticated. ```bash gh release create v${tag} dist/* --notes "Release v${tag}" ``` -------------------------------- ### Cross-compiling Binaries with Bun Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/260417-1441-openrouter-cli/phase-11-cross-platform-build-release.md This script compiles all specified targets using Bun's build capabilities, stamping the version during the build process. Ensure Bun is installed and the VERSION environment variable is set. ```typescript import { build, type BuildOptions } from "bun"; import fs from "fs"; import path from "path"; const VERSION = process.env.VERSION || "0.0.0"; const targets: BuildOptions[" প্ল্যাটফর্ম"][] = [ "darwin-arm64", "darwin-x64", "linux-x64", "linux-arm64", "win32-x64" ]; const buildBinaries = async () => { console.log(`Building version ${VERSION} for targets: ${targets.join(", ")}`); const distDir = path.resolve(__dirname, "../dist"); fs.mkdirSync(distDir, { recursive: true }); await Promise.all( targets.map(async (target) => { const [os, arch] = target.split("-"); const outfile = path.join(distDir, `openrouter-${target}${os === "win32" ? ".exe" : ""}`); await build({ entrypoints: ["./src/index.ts"], outfile, platform: target as BuildOptions[" প্ল্যাটফর্ম"], define: { "__VERSION__": `"${VERSION}"`, // Stamping version }, sourcemap: "none", minify: true, target: "bun", }); console.log(`Built ${outfile}`); }) ); }; buildBinaries().catch((err) => { console.error("Build failed:", err); process.exit(1); }); ``` -------------------------------- ### Send a Chat Message Source: https://github.com/mrgoonie/openrouter-cli/blob/main/README.md Send a chat message to a specified model and get a response. This example uses the 'openai/gpt-4o' model. ```bash openrouter chat send "What is the capital of France?" --model openai/gpt-4o ``` -------------------------------- ### NDJSON Streaming Events Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plugins/openrouter/skills/openrouter/references/agent-json-mode.md Example of NDJSON output, where each line is a JSON object representing an event like start, delta, tool_call, usage, end, or error. ```jsonl {"type":"start","request_id":"gen-...","model":"openai/gpt-4o"} {"type":"delta","content":"Hel"} {"type":"delta","content":"lo"} {"type":"tool_call","id":"call_1","name":"get_weather","arguments":"{\"city\":\"HCMC\"}"} {"type":"usage","prompt_tokens":12,"completion_tokens":34} {"type":"end","finish_reason":"stop"} {"type":"error","code":"rate_limited","message":"...","status":429} ``` -------------------------------- ### NPM Wrapper - bin/openrouter.cjs Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/260417-1441-openrouter-cli/phase-11-cross-platform-build-release.md Handles downloading the correct platform binary during post-install or re-executes the downloaded binary with provided arguments. ```javascript const fs = require('fs'); const path = require('path'); const { spawn } = require('child_process'); const BIN_DIR = path.join(__dirname, '..', 'binaries'); const BIN_PATH = path.join(BIN_DIR, 'openrouter'); async function downloadBinary() { // ... (logic to detect OS/arch and download binary) ... fs.mkdirSync(BIN_DIR, { recursive: true }); // ... (download logic using fetch or similar) ... fs.writeFileSync(BIN_PATH, downloadedBinary); fs.chmodSync(BIN_PATH, 0o755); } async function main() { if (process.argv.includes('--install')) { await downloadBinary(); console.log('OpenRouter CLI installed successfully.'); } else { if (!fs.existsSync(BIN_PATH)) { await downloadBinary(); } const args = process.argv.slice(2); const child = spawn(BIN_PATH, args, { stdio: 'inherit' }); child.on('exit', (code) => process.exit(code)); } } main().catch(err => { console.error('Error:', err); process.exit(1); }); ``` -------------------------------- ### Get Config Value Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plugins/openrouter/skills/openrouter/references/command-reference.md Retrieve the value of a specific configuration key. ```bash openrouter config get ``` -------------------------------- ### Providers Endpoint Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/reports/researcher-260417-1442-openrouter-api-reference.md Details the GET request to retrieve a list of available AI providers. ```text Path: `/providers` Method: `GET` Auth: User/Provisioning key (Bearer) Response: Array: `id`, `name`, `status`, `url`, `models_count`, `capabilities` ``` -------------------------------- ### Organization Members Endpoint Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/reports/researcher-260417-1442-openrouter-api-reference.md Details the GET request to retrieve a list of organization members. ```text Path: `/organization/members` Method: `GET` Auth: Management key (Bearer) Response: List of org members with `user_id`, `email`, `name`, `created_at`, `role` ``` -------------------------------- ### Get Video Status Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plugins/openrouter/skills/openrouter/references/command-reference.md Check the status of a video generation job using its ID. ```bash video status ``` -------------------------------- ### src/main.ts CLI Entry Point Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/260417-1441-openrouter-cli/phase-01-scaffold-tooling.md Sets up the main command for the OpenRouter CLI using citty, defining metadata and subcommands. It then runs the main command. ```typescript import { defineCommand, runMain } from 'citty'; import { VERSION } from './version'; const main = defineCommand({ meta: { name: 'openrouter', version: VERSION, description: 'OpenRouter CLI', }, subCommands: {}, }); runMain(main); ``` -------------------------------- ### Async Video Generation and Download Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plugins/openrouter/skills/openrouter/SKILL.md Initiates video generation, waits for completion, and downloads the resulting video file. ```bash JOB=$(openrouter video create "cat surfing" --model some/video-model --json | jq -r .data.id) openrouter video wait "$JOB" --json # blocks until terminal state openrouter video download "$JOB" -o out.mp4 ``` -------------------------------- ### OAuth PKCE Flow Steps Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/reports/researcher-260417-1442-openrouter-api-reference.md Outlines the steps for implementing the OAuth PKCE flow, including generating verifiers, hashing, redirection, and token exchange. ```text 1. Generate `code_verifier` (random string) 2. Hash verifier: `code_challenge = base64url(sha256(code_verifier))` 3. **Redirect to:** `https://openrouter.ai/auth?callback_url={YOUR_URL}&code_challenge={CHALLENGE}&code_challenge_method=S256` 4. User logs in & authorizes; redirected to `{callback_url}?code={AUTH_CODE}` 5. **POST to:** `https://openrouter.ai/api/v1/auth/keys` with: - Header: `Authorization: Bearer ` (if user already has key) OR body with OAuth code - Body: `code`, `code_verifier`, `code_challenge_method` 6. Response: `data` with `id` (API key), `app_id`, `created_at` ``` -------------------------------- ### Get Generation Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plugins/openrouter/skills/openrouter/references/command-reference.md Fetch metadata for a completed generation using its request ID. Outputs in JSON format. ```bash openrouter generations get --json ``` -------------------------------- ### List Free Models Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plugins/openrouter/skills/openrouter/SKILL.md This command lists all available models and filters them to show only those with free prompt pricing. It uses `jq` to parse the JSON output. ```bash openrouter models list --json | jq '.data[] | select(.pricing.prompt=="0")' ``` -------------------------------- ### NPM Wrapper - package.json Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/260417-1441-openrouter-cli/phase-11-cross-platform-build-release.md Defines the binary executable for the NPM package and sets up a post-install script to download the appropriate platform binary. ```json { "name": "openrouter-cli-wrapper", "version": "0.0.1", "bin": { "openrouter": "bin/openrouter.cjs" }, "scripts": { "postinstall": "node bin/openrouter.cjs --install" } } ``` -------------------------------- ### Get API Key Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/reports/researcher-260417-1442-openrouter-api-reference.md Fetches the metadata for a specific API key, identified by its ID. Requires a Management key. ```APIDOC ## GET /keys/{key_id} ### Description Fetches metadata for a single API key. ### Method GET ### Endpoint /keys/{key_id} ### Parameters #### Path Parameters - **key_id** (string) - Required - The ID of the API key to retrieve. ### Response #### Success Response (200) - **key_object** (object) - API key metadata including usage, limit, expires_at, and created_at. ``` -------------------------------- ### CLI Agent Architecture Recommendations Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/reports/researcher-260417-1441-cli-agent-friendly-patterns.md Suggests oclif (TypeScript) or Cobra (Go) for CLI frameworks due to built-in features. Recommends JSON output and verbose logging. Outlines streaming strategies for chat (SSE) and video (polling with watch flag). Defines configuration precedence from flags to environment variables and config files. ```markdown For 15 endpoint groups + streaming + 2-3 million agents: ├── Framework: oclif (TypeScript) or Cobra (Go) │ Rationale: Built-in plugin/command generation, TTY detection, arg parsing ├── Output: --json always available, --verbose for debug ├── Stream: Chat = SSE, Video = polling (with --watch flag for tail-like behavior) └── Config: flags > env > .env.* > ~/.openrouter/config ``` -------------------------------- ### List Models and Filter by Pricing Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plugins/openrouter/skills/openrouter/SKILL.md Lists available models and filters them to show only those with zero prompt pricing, outputting their IDs. ```bash openrouter models list --json | jq '.data[] | select(.pricing.prompt=="0") | .id' ``` -------------------------------- ### Get Default Model from OpenRouter Configuration Source: https://github.com/mrgoonie/openrouter-cli/blob/main/README.md Retrieve the currently configured default model from the CLI's settings. ```bash openrouter config get defaults.model ``` -------------------------------- ### Print OpenRouter Configuration File Path Source: https://github.com/mrgoonie/openrouter-cli/blob/main/README.md Display the absolute path to the main configuration file used by the OpenRouter CLI. ```bash openrouter config path ``` -------------------------------- ### CI/CD Workflow for Releases Source: https://github.com/mrgoonie/openrouter-cli/blob/main/docs/tech-stack.md Overview of the CI/CD process for handling pull requests, testing, building, and releasing the CLI. ```yaml ci.yml: on PR + push → bun install → bun run lint → bun test → matrix compile check release.yml: on v* tag → build all targets → upload GH Release → bump Homebrew tap formula → publish npm ``` -------------------------------- ### Get Keychain Value Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/260417-1441-openrouter-cli/phase-03-config-resolution-cascade.md Retrieves a value from the system keychain for a given account. Gracefully handles cases where the keyring module is unavailable. ```typescript async getKeychainValue(account: string): Promise { if (!keyring) { if (!keyringWarned) { console.warn('Keyring module not available. Keychain operations will be no-ops.'); keyringWarned = true; } return null; } try { return await keyring.get(serviceName, account); } catch (error) { console.error(`Error getting keychain value for account ${account}:`, error); return null; } } ``` -------------------------------- ### Distribution Channels for v1 Source: https://github.com/mrgoonie/openrouter-cli/blob/main/docs/tech-stack.md Various methods for distributing the CLI to users, including npm, shell scripts, Homebrew, and direct downloads. ```bash npm i -g @openrouter/cli (runs via Node/Bun) curl -fsSL https://…/install.sh | sh (detects OS, downloads binary) brew install openrouter (custom tap: user/openrouter) Direct download: GitHub Releases per platform Windows: scoop bucket + direct .exe ``` -------------------------------- ### OAuth PKCE Flow - Initiate Authentication Source: https://github.com/mrgoonie/openrouter-cli/blob/main/docs/design-guidelines.md Shows the URL structure for initiating the OAuth PKCE flow by opening a browser. Requires a callback URL, code challenge, and challenge method. ```shell https://openrouter.ai/auth?callback_url=http://localhost:&code_challenge=&code_challenge_method=S256 ``` -------------------------------- ### Diagnose Configuration and Show Current User Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plugins/openrouter/skills/openrouter/SKILL.md Run this command to diagnose potential configuration issues and verify the currently authenticated user. It outputs diagnostic information in JSON format. ```bash openrouter config doctor --json && openrouter auth whoami ``` -------------------------------- ### Set Default Model in OpenRouter Configuration Source: https://github.com/mrgoonie/openrouter-cli/blob/main/README.md Configure a default model to be used for all subsequent chat commands unless overridden. This example sets 'openai/gpt-4o'. ```bash openrouter config set defaults.model openai/gpt-4o ``` -------------------------------- ### Get Analytics Data Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/reports/researcher-260417-1442-openrouter-api-reference.md Retrieves activity data grouped by endpoint for the last 30 completed UTC days. Requires a Management key for authentication. ```APIDOC ## GET /activity ### Description Retrieves activity data grouped by endpoint for the last 30 completed UTC days. ### Method GET ### Endpoint /activity ### Parameters #### Query Parameters - **date** (string) - Optional - Date in YYYY-MM-DD format. - **api_key_hash** (string) - Optional - SHA-256 hash of the API key. - **user_id** (string) - Optional - Organization member ID. ### Response #### Success Response (200) - **activity** (object) - Activity grouped by endpoint. ``` -------------------------------- ### List Providers Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plugins/openrouter/skills/openrouter/references/command-reference.md Retrieve a list of supported providers. Use the `--json` flag for JSON output. ```bash openrouter providers list [--json] ``` -------------------------------- ### Run OpenRouter CLI in Development Mode Source: https://github.com/mrgoonie/openrouter-cli/blob/main/docs/deployment-guide.md Execute the CLI directly using Bun for development purposes without a build step. Useful for testing changes quickly. ```bash bun run dev -- --help ``` ```bash bun run dev -- chat send "hi" --model openai/gpt-4o ``` -------------------------------- ### Configuration File Locations and Precedence Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/reports/researcher-260417-1441-cli-agent-friendly-patterns.md Specifies user-level and project-level configuration file locations, and how to override them with a custom path flag for CI/automation. ```markdown - `~/.openrouter/config.json` (user-level, shared across projects) - `./openrouter.json` (project-level, safe to commit non-secret config) - Flag override: `--config /custom/path` for CI/automation ``` -------------------------------- ### Homebrew Formula Template Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/260417-1441-openrouter-cli/phase-11-cross-platform-build-release.md A template for a Homebrew formula to install the OpenRouter CLI. It includes blocks for different architectures and their respective download URLs and SHA256 checksums. ```ruby class Openrouter < Formula desc "OpenRouter CLI" homepage "https://github.com/mrgoonie/openrouter-cli" version "VERSION" on_macos do if Hardware::CPU.arm? url "https://github.com/mrgoonie/openrouter-cli/releases/download/v#{version}/openrouter-aarch64-apple-darwin" sha256 "SHA256_ARM_MACOS" else url "https://github.com/mrgoonie/openrouter-cli/releases/download/v#{version}/openrouter-x86_64-apple-darwin" sha256 "SHA256_X64_MACOS" end end on_linux do if Hardware::CPU.arm? url "https://github.com/mrgoonie/openrouter-cli/releases/download/v#{version}/openrouter-aarch64-linux-gnu" sha256 "SHA256_ARM_LINUX" else url "https://github.com/mrgoonie/openrouter-cli/releases/download/v#{version}/openrouter-x86_64-linux-gnu" sha256 "SHA256_X64_LINUX" end end def install bin.install "openrouter" end test do system "#{bin}/openrouter", "--version" end end ``` -------------------------------- ### List Models Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plugins/openrouter/skills/openrouter/references/command-reference.md Retrieve a list of available models. Use the `--json` flag for JSON output. ```bash openrouter models list [--json] ``` -------------------------------- ### macOS Keychain Access for Secrets Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/reports/researcher-260417-1441-cli-agent-friendly-patterns.md Example command to retrieve API keys securely stored in the macOS keychain. This pattern avoids committing secrets directly. ```bash security find-generic-password -s openrouter_api_key ``` -------------------------------- ### bunfig.toml Configuration Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/260417-1441-openrouter-cli/phase-01-scaffold-tooling.md Configures Bun runtime settings, specifically for the test environment, by defining preloaded modules. ```toml [test] preload = [] ``` -------------------------------- ### Login via OAuth PKCE Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plugins/openrouter/skills/openrouter/references/command-reference.md Initiate an OAuth PKCE flow for authentication. The API key is stored securely in the OS keychain. ```bash auth login ``` -------------------------------- ### Get Generation Details Command Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/260417-1441-openrouter-cli/phase-06-models-providers-generations-credits.md Retrieves the full metadata for a specific generation using its ID. Displays a detail card in pretty mode or the full JSON envelope. ```typescript GET /generation?id= ``` -------------------------------- ### Create API Key with Limit Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plugins/openrouter/skills/openrouter/SKILL.md Creates a new API key with a specified name and usage limit, outputting details in JSON. ```bash openrouter keys create --name "ci-bot" --limit 5 --json ``` -------------------------------- ### API Key Source Precedence Messages Source: https://github.com/mrgoonie/openrouter-cli/blob/main/plans/reports/researcher-260417-1441-api-key-resolution.md Provides example messages indicating the source from which an API key was successfully retrieved or if none was found. Useful for debugging and user feedback. ```text ✓ Using API key from --api-key flag ✓ Using API key from $OPENROUTER_API_KEY ✓ Using API key from .env.local ⚠️ No API key found. Set OPENROUTER_API_KEY or use --api-key ```