claudish 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,6 +8,7 @@
8
8
 
9
9
  - ✅ **Cross-platform** - Works with both Node.js and Bun (v1.3.0+)
10
10
  - ✅ **Universal compatibility** - Use with `npx` or `bunx` - no installation required
11
+ - ✅ **Interactive setup** - Prompts for API key and model if not provided (zero config!)
11
12
  - ✅ **Monitor mode** - Proxy to real Anthropic API and log all traffic (for debugging)
12
13
  - ✅ **Protocol compliance** - 1:1 compatibility with Claude Code communication protocol
13
14
  - ✅ **Snapshot testing** - Comprehensive test suite with 13/13 passing tests
@@ -65,32 +66,33 @@ bun link # or: npm link
65
66
 
66
67
  ## Quick Start
67
68
 
68
- ### 1. Set up environment
69
+ ### Option 1: Interactive Mode (Easiest)
69
70
 
70
71
  ```bash
71
- # Copy example env file
72
- cp .env.example .env
72
+ # Just run it - will prompt for API key and model
73
+ claudish
73
74
 
74
- # Add your OpenRouter API key
75
- export OPENROUTER_API_KEY=sk-or-v1-...
76
-
77
- # Recommended: Set placeholder to avoid Claude Code's API key prompt
78
- export ANTHROPIC_API_KEY=sk-ant-api03-placeholder
75
+ # Enter your OpenRouter API key when prompted
76
+ # Select a model from the list
77
+ # Start coding!
79
78
  ```
80
79
 
81
- ### 2. Run claudish
80
+ ### Option 2: With Environment Variables
82
81
 
83
82
  ```bash
84
- # Basic usage (auto-approve enabled by default)
83
+ # Set up environment
84
+ export OPENROUTER_API_KEY=sk-or-v1-...
85
+ export ANTHROPIC_API_KEY=sk-ant-api03-placeholder
86
+
87
+ # Run with specific task
85
88
  claudish "implement user authentication"
86
89
 
87
- # Use specific model
90
+ # Or with specific model
88
91
  claudish --model openai/gpt-5-codex "add tests"
89
-
90
- # Fully autonomous mode (auto-approve + dangerous)
91
- claudish --dangerous "refactor codebase"
92
92
  ```
93
93
 
94
+ **Note:** In interactive mode, if `OPENROUTER_API_KEY` is not set, you'll be prompted to enter it. This makes first-time usage super simple!
95
+
94
96
  ## Usage
95
97
 
96
98
  ### Basic Syntax
@@ -119,13 +121,15 @@ claudish [OPTIONS] <claude-args...>
119
121
 
120
122
  | Variable | Description | Required |
121
123
  |----------|-------------|----------|
122
- | `OPENROUTER_API_KEY` | Your OpenRouter API key | Yes |
124
+ | `OPENROUTER_API_KEY` | Your OpenRouter API key | **Optional in interactive mode** (will prompt if not set)<br>✅ **Required in non-interactive mode** |
123
125
  | `ANTHROPIC_API_KEY` | Placeholder to prevent Claude Code dialog (not used for auth) | ✅ **Required** |
124
126
  | `CLAUDISH_MODEL` | Default model to use | ❌ No |
125
127
  | `CLAUDISH_PORT` | Default proxy port | ❌ No |
126
128
  | `CLAUDISH_ACTIVE_MODEL_NAME` | Automatically set by claudish to show active model in status line (read-only) | ❌ No |
127
129
 
128
- **Important:** You MUST set `ANTHROPIC_API_KEY=sk-ant-api03-placeholder` (or any value). Without it, Claude Code will show a dialog, and if you select "No", it will bypass the proxy and use real Anthropic API. Claudish now enforces this requirement.
130
+ **Important Notes:**
131
+ - **NEW in v1.3.0:** In interactive mode, if `OPENROUTER_API_KEY` is not set, you'll be prompted to enter it
132
+ - You MUST set `ANTHROPIC_API_KEY=sk-ant-api03-placeholder` (or any value). Without it, Claude Code will show a dialog
129
133
 
130
134
  ## Available Models
131
135
 
package/dist/index.js CHANGED
@@ -56,7 +56,9 @@ var ENV = {
56
56
  OPENROUTER_API_KEY: "OPENROUTER_API_KEY",
57
57
  CLAUDISH_MODEL: "CLAUDISH_MODEL",
58
58
  CLAUDISH_PORT: "CLAUDISH_PORT",
59
- CLAUDISH_ACTIVE_MODEL_NAME: "CLAUDISH_ACTIVE_MODEL_NAME"
59
+ CLAUDISH_ACTIVE_MODEL_NAME: "CLAUDISH_ACTIVE_MODEL_NAME",
60
+ ANTHROPIC_MODEL: "ANTHROPIC_MODEL",
61
+ ANTHROPIC_SMALL_FAST_MODEL: "ANTHROPIC_SMALL_FAST_MODEL"
60
62
  };
61
63
 
62
64
  // src/claude-runner.ts
@@ -121,7 +123,9 @@ async function runClaudeWithProxy(config, proxyUrl) {
121
123
  const env = {
122
124
  ...process.env,
123
125
  ANTHROPIC_BASE_URL: proxyUrl,
124
- [ENV.CLAUDISH_ACTIVE_MODEL_NAME]: modelId
126
+ [ENV.CLAUDISH_ACTIVE_MODEL_NAME]: modelId,
127
+ [ENV.ANTHROPIC_MODEL]: modelId,
128
+ [ENV.ANTHROPIC_SMALL_FAST_MODEL]: modelId
125
129
  };
126
130
  if (config.monitor) {
127
131
  delete env.ANTHROPIC_API_KEY;
@@ -216,9 +220,12 @@ function parseArgs(args) {
216
220
  stdin: false,
217
221
  claudeArgs: []
218
222
  };
219
- const envModel = process.env[ENV.CLAUDISH_MODEL];
220
- if (envModel) {
221
- config.model = envModel;
223
+ const claudishModel = process.env[ENV.CLAUDISH_MODEL];
224
+ const anthropicModel = process.env[ENV.ANTHROPIC_MODEL];
225
+ if (claudishModel) {
226
+ config.model = claudishModel;
227
+ } else if (anthropicModel) {
228
+ config.model = anthropicModel;
222
229
  }
223
230
  const envPort = process.env[ENV.CLAUDISH_PORT];
224
231
  if (envPort) {
@@ -299,6 +306,9 @@ function parseArgs(args) {
299
306
  }
300
307
  i++;
301
308
  }
309
+ if ((!config.claudeArgs || config.claudeArgs.length === 0) && !config.stdin) {
310
+ config.interactive = true;
311
+ }
302
312
  if (config.monitor) {
303
313
  if (process.env.ANTHROPIC_API_KEY && process.env.ANTHROPIC_API_KEY.includes("placeholder")) {
304
314
  delete process.env.ANTHROPIC_API_KEY;
@@ -314,27 +324,19 @@ function parseArgs(args) {
314
324
  } else {
315
325
  const apiKey = process.env[ENV.OPENROUTER_API_KEY];
316
326
  if (!apiKey) {
317
- console.error("Error: OPENROUTER_API_KEY environment variable is required");
318
- console.error("Get your API key from: https://openrouter.ai/keys");
319
- process.exit(1);
320
- }
321
- config.openrouterApiKey = apiKey;
322
- if (!process.env.ANTHROPIC_API_KEY) {
323
- console.error(`
324
- Error: ANTHROPIC_API_KEY is not set`);
325
- console.error("This placeholder key is required to prevent Claude Code from prompting.");
326
- console.error("");
327
- console.error("Set it now:");
328
- console.error(" export ANTHROPIC_API_KEY='sk-ant-api03-placeholder'");
329
- console.error("");
330
- console.error("Or add it to your shell profile (~/.zshrc or ~/.bashrc) to set permanently.");
331
- console.error("");
332
- console.error("Note: This key is NOT used for auth - claudish uses OPENROUTER_API_KEY");
333
- process.exit(1);
327
+ if (!config.interactive) {
328
+ console.error("Error: OPENROUTER_API_KEY environment variable is required");
329
+ console.error("Get your API key from: https://openrouter.ai/keys");
330
+ console.error("");
331
+ console.error("Set it now:");
332
+ console.error(" export OPENROUTER_API_KEY='sk-or-v1-...'");
333
+ process.exit(1);
334
+ }
335
+ config.openrouterApiKey = undefined;
336
+ } else {
337
+ config.openrouterApiKey = apiKey;
334
338
  }
335
- }
336
- if (!config.claudeArgs || config.claudeArgs.length === 0) {
337
- config.interactive = true;
339
+ config.anthropicApiKey = process.env.ANTHROPIC_API_KEY;
338
340
  }
339
341
  if (config.quiet === undefined) {
340
342
  config.quiet = !config.interactive;
@@ -345,7 +347,7 @@ Error: ANTHROPIC_API_KEY is not set`);
345
347
  return config;
346
348
  }
347
349
  function printVersion() {
348
- console.log("claudish version 1.3.0");
350
+ console.log("claudish version 1.3.1");
349
351
  }
350
352
  function printHelp() {
351
353
  console.log(`
@@ -387,7 +389,9 @@ NOTES:
387
389
 
388
390
  ENVIRONMENT VARIABLES:
389
391
  OPENROUTER_API_KEY Required: Your OpenRouter API key
390
- CLAUDISH_MODEL Default model to use
392
+ CLAUDISH_MODEL Default model to use (takes priority)
393
+ ANTHROPIC_MODEL Claude Code standard: model to use (fallback if CLAUDISH_MODEL not set)
394
+ ANTHROPIC_SMALL_FAST_MODEL Claude Code standard: fast model (auto-set by claudish)
391
395
  CLAUDISH_PORT Default port for proxy
392
396
  CLAUDISH_ACTIVE_MODEL_NAME Auto-set by claudish (read-only) - shows active model in status line
393
397
 
@@ -450,12 +454,62 @@ Available OpenRouter Models (in priority order):
450
454
  console.log("");
451
455
  }
452
456
  console.log("Set default with: export CLAUDISH_MODEL=<model>");
457
+ console.log(" or: export ANTHROPIC_MODEL=<model>");
453
458
  console.log(`Or use: claudish --model <model> ...
454
459
  `);
455
460
  }
456
461
 
457
462
  // src/simple-selector.ts
458
463
  import { createInterface } from "readline";
464
+ async function promptForApiKey() {
465
+ return new Promise((resolve) => {
466
+ console.log(`
467
+ \x1B[1m\x1B[36mOpenRouter API Key Required\x1B[0m
468
+ `);
469
+ console.log(`\x1B[2mGet your free API key from: https://openrouter.ai/keys\x1B[0m
470
+ `);
471
+ console.log("Enter your OpenRouter API key:");
472
+ console.log(`\x1B[2m(it will not be saved, only used for this session)\x1B[0m
473
+ `);
474
+ const rl = createInterface({
475
+ input: process.stdin,
476
+ output: process.stdout,
477
+ terminal: false
478
+ });
479
+ let apiKey = null;
480
+ rl.on("line", (input) => {
481
+ const trimmed = input.trim();
482
+ if (!trimmed) {
483
+ console.log("\x1B[31mError: API key cannot be empty\x1B[0m");
484
+ return;
485
+ }
486
+ if (!trimmed.startsWith("sk-or-v1-")) {
487
+ console.log("\x1B[33mWarning: OpenRouter API keys usually start with 'sk-or-v1-'\x1B[0m");
488
+ console.log("\x1B[2mContinuing anyway...\x1B[0m");
489
+ }
490
+ apiKey = trimmed;
491
+ rl.close();
492
+ });
493
+ rl.on("close", () => {
494
+ if (apiKey) {
495
+ process.stdin.pause();
496
+ process.stdin.removeAllListeners("data");
497
+ process.stdin.removeAllListeners("end");
498
+ process.stdin.removeAllListeners("error");
499
+ process.stdin.removeAllListeners("readable");
500
+ if (process.stdin.isTTY && process.stdin.setRawMode) {
501
+ process.stdin.setRawMode(false);
502
+ }
503
+ setTimeout(() => {
504
+ resolve(apiKey);
505
+ }, 200);
506
+ } else {
507
+ console.error("\x1B[31mError: API key is required\x1B[0m");
508
+ process.exit(1);
509
+ }
510
+ });
511
+ });
512
+ }
459
513
  async function selectModelInteractively() {
460
514
  return new Promise((resolve) => {
461
515
  console.log(`
@@ -4113,6 +4167,10 @@ async function main() {
4113
4167
  console.error("Install it from: https://claude.com/claude-code");
4114
4168
  process.exit(1);
4115
4169
  }
4170
+ if (config.interactive && !config.monitor && !config.openrouterApiKey) {
4171
+ config.openrouterApiKey = await promptForApiKey();
4172
+ console.log("");
4173
+ }
4116
4174
  if (config.interactive && !config.monitor && !config.model) {
4117
4175
  config.model = await selectModelInteractively();
4118
4176
  console.log("");
package/package.json CHANGED
@@ -1,29 +1,12 @@
1
1
  {
2
2
  "name": "claudish",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "CLI tool to run Claude Code with any OpenRouter model (Grok, GPT-5, MiniMax, etc.) via local Anthropic API-compatible proxy",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "bin": {
8
8
  "claudish": "dist/index.js"
9
9
  },
10
- "scripts": {
11
- "dev": "bun run src/index.ts",
12
- "dev:grok": "bun run src/index.ts --interactive --model x-ai/grok-code-fast-1",
13
- "dev:grok:debug": "bun run src/index.ts --interactive --debug --log-level info --model x-ai/grok-code-fast-1",
14
- "dev:info": "bun run src/index.ts --interactive --monitor",
15
- "build": "bun build src/index.ts --outdir dist --target node && chmod +x dist/index.js",
16
- "link": "npm link",
17
- "unlink": "npm unlink -g claudish",
18
- "install-global": "bun run build && npm link",
19
- "kill-all": "pkill -f 'bun.*claudish' || pkill -f 'claude.*claudish-settings' || echo 'No claudish processes found'",
20
- "test": "bun test ./tests/comprehensive-model-test.ts",
21
- "typecheck": "tsc --noEmit",
22
- "lint": "biome check .",
23
- "format": "biome format --write .",
24
- "install": "bun run build && bun link",
25
- "postinstall": "node scripts/postinstall.cjs"
26
- },
27
10
  "dependencies": {
28
11
  "hono": "^4.9.0",
29
12
  "@hono/node-server": "^1.13.7"
@@ -31,7 +14,6 @@
31
14
  "devDependencies": {
32
15
  "@biomejs/biome": "^1.9.4",
33
16
  "@types/bun": "latest",
34
- "@types/react": "^19.2.2",
35
17
  "typescript": "^5.7.0"
36
18
  },
37
19
  "files": [
@@ -52,5 +34,22 @@
52
34
  "ai"
53
35
  ],
54
36
  "author": "Jack Rudenko <i@madappgang.com>",
55
- "license": "MIT"
56
- }
37
+ "license": "MIT",
38
+ "scripts": {
39
+ "dev": "bun run src/index.ts",
40
+ "dev:grok": "bun run src/index.ts --interactive --model x-ai/grok-code-fast-1",
41
+ "dev:grok:debug": "bun run src/index.ts --interactive --debug --log-level info --model x-ai/grok-code-fast-1",
42
+ "dev:info": "bun run src/index.ts --interactive --monitor",
43
+ "build": "bun build src/index.ts --outdir dist --target node && chmod +x dist/index.js",
44
+ "link": "npm link",
45
+ "unlink": "npm unlink -g claudish",
46
+ "install-global": "bun run build && npm link",
47
+ "kill-all": "pkill -f 'bun.*claudish' || pkill -f 'claude.*claudish-settings' || echo 'No claudish processes found'",
48
+ "test": "bun test ./tests/comprehensive-model-test.ts",
49
+ "typecheck": "tsc --noEmit",
50
+ "lint": "biome check .",
51
+ "format": "biome format --write .",
52
+ "install": "bun run build && bun link",
53
+ "postinstall": "node scripts/postinstall.cjs"
54
+ }
55
+ }
File without changes