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 +20 -16
- package/dist/index.js +85 -27
- package/package.json +20 -21
- package/scripts/postinstall.cjs +0 -0
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
|
|
69
|
+
### Option 1: Interactive Mode (Easiest)
|
|
69
70
|
|
|
70
71
|
```bash
|
|
71
|
-
#
|
|
72
|
-
|
|
72
|
+
# Just run it - will prompt for API key and model
|
|
73
|
+
claudish
|
|
73
74
|
|
|
74
|
-
#
|
|
75
|
-
|
|
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
|
|
80
|
+
### Option 2: With Environment Variables
|
|
82
81
|
|
|
83
82
|
```bash
|
|
84
|
-
#
|
|
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
|
-
#
|
|
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 |
|
|
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:**
|
|
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
|
|
220
|
-
|
|
221
|
-
|
|
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
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
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.
|
|
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
|
+
"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
|
+
}
|
package/scripts/postinstall.cjs
CHANGED
|
File without changes
|