@srouter/cli 0.1.3
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 +203 -0
- package/bin/srouter.js +49 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +2409 -0
- package/dist/index.js.map +1 -0
- package/package.json +33 -0
package/README.md
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# SRouter CLI
|
|
2
|
+
|
|
3
|
+
`@srouter/cli` is the command-line companion for SRouter. It connects AI coding tools to a SRouter gateway, writes the required tool configuration, generates shell environment variables, and provides diagnostics and rollback.
|
|
4
|
+
|
|
5
|
+
Part of the [`SRouter`](../../README.md) monorepo.
|
|
6
|
+
|
|
7
|
+
## Supported workflow
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
┌───────────────┐
|
|
11
|
+
│ srouter setup │
|
|
12
|
+
└───────┬───────┘
|
|
13
|
+
│
|
|
14
|
+
├── detect gateway
|
|
15
|
+
├── select tool / model
|
|
16
|
+
└── write client config
|
|
17
|
+
│
|
|
18
|
+
▼
|
|
19
|
+
Claude Code / OpenCode
|
|
20
|
+
│
|
|
21
|
+
▼
|
|
22
|
+
SRouter Gateway
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The CLI currently targets:
|
|
26
|
+
|
|
27
|
+
- **Claude Code**
|
|
28
|
+
- **OpenCode**
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
From the SRouter monorepo:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
corepack enable
|
|
36
|
+
pnpm install
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Run the local CLI through the root workspace:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pnpm srouter --help
|
|
43
|
+
pnpm srouter setup
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The package also exposes a `srouter` binary. When the built CLI is available, the bin entry loads `dist/index.js`; during local development it falls back to the TypeScript source through `tsx`.
|
|
47
|
+
|
|
48
|
+
## Commands
|
|
49
|
+
|
|
50
|
+
### `srouter setup`
|
|
51
|
+
|
|
52
|
+
Interactive setup wizard for connecting coding tools to SRouter.
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pnpm srouter setup
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Useful options include:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
pnpm srouter setup \
|
|
62
|
+
--url http://localhost:3000/v1 \
|
|
63
|
+
--key sr-live-your-key \
|
|
64
|
+
--model anthropic/claude-3-7-sonnet
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Claude Code tier-specific model options are also supported:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
pnpm srouter setup \
|
|
71
|
+
--opus-model claude-3-opus-20240229 \
|
|
72
|
+
--sonnet-model claude-3-7-sonnet \
|
|
73
|
+
--haiku-model claude-3-5-haiku-20241022
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### `srouter link <tool>`
|
|
77
|
+
|
|
78
|
+
Configure a specific supported tool.
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
pnpm srouter link claude --model claude-3-7-sonnet
|
|
82
|
+
pnpm srouter link opencode --model claude-3-7-sonnet
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Preview changes without writing files:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
pnpm srouter link claude --dry-run
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### `srouter status`
|
|
92
|
+
|
|
93
|
+
Inspect gateway connectivity, available models, and current tool-link state.
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
pnpm srouter status
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
`doctor` is an alias:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
pnpm srouter doctor
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### `srouter env [tool]`
|
|
106
|
+
|
|
107
|
+
Print proxy environment variables for a shell session.
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
eval "$(pnpm srouter env claude)"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Supported shell syntax includes bash, zsh, fish, PowerShell, and cmd.
|
|
114
|
+
|
|
115
|
+
Examples:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
pnpm srouter env --shell fish
|
|
119
|
+
pnpm srouter env --shell powershell
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### `srouter run <tool>`
|
|
123
|
+
|
|
124
|
+
Launch a coding tool with the SRouter proxy environment injected into its process.
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
pnpm srouter run claude
|
|
128
|
+
pnpm srouter run opencode
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Arguments after the tool name are forwarded to the target CLI.
|
|
132
|
+
|
|
133
|
+
### `srouter unlink <tool>`
|
|
134
|
+
|
|
135
|
+
Restore a supported tool's previous configuration from the backup created by the CLI.
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
pnpm srouter unlink claude
|
|
139
|
+
pnpm srouter unlink opencode
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Configuration model
|
|
143
|
+
|
|
144
|
+
The CLI accepts a common set of gateway options:
|
|
145
|
+
|
|
146
|
+
| Option | Purpose |
|
|
147
|
+
| ---------------- | --------------------------------------------- |
|
|
148
|
+
| `--url` | SRouter gateway base URL |
|
|
149
|
+
| `--key` | SRouter API key |
|
|
150
|
+
| `--model` | Default model ID |
|
|
151
|
+
| `--opus-model` | Claude Code Opus model |
|
|
152
|
+
| `--sonnet-model` | Claude Code Sonnet model |
|
|
153
|
+
| `--haiku-model` | Claude Code Haiku model |
|
|
154
|
+
| `--dry-run` | Preview changes without writing configuration |
|
|
155
|
+
|
|
156
|
+
The default development gateway is normally `http://localhost:3000/v1`.
|
|
157
|
+
|
|
158
|
+
## Project structure
|
|
159
|
+
|
|
160
|
+
```text
|
|
161
|
+
apps/cli/
|
|
162
|
+
├── src/
|
|
163
|
+
│ ├── commands/
|
|
164
|
+
│ │ ├── setup.ts
|
|
165
|
+
│ │ ├── link.ts
|
|
166
|
+
│ │ ├── unlink.ts
|
|
167
|
+
│ │ ├── status.ts
|
|
168
|
+
│ │ ├── env.ts
|
|
169
|
+
│ │ └── run.ts
|
|
170
|
+
│ └── index.ts
|
|
171
|
+
├── bin/
|
|
172
|
+
│ └── srouter.js
|
|
173
|
+
├── tests/
|
|
174
|
+
└── package.json
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
The CLI uses Commander for argument parsing and Clack prompts for the interactive setup experience. Shared SRouter constants and types come from workspace packages.
|
|
178
|
+
|
|
179
|
+
## Development and testing
|
|
180
|
+
|
|
181
|
+
Run the CLI from source through the workspace script:
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
pnpm srouter --help
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Run CLI tests:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
pnpm --filter @srouter/cli test
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
The package includes a `bin/srouter.js` launcher that prefers a compiled `dist/index.js` and otherwise falls back to the local TypeScript entrypoint through `tsx`.
|
|
194
|
+
|
|
195
|
+
## Safety / rollback
|
|
196
|
+
|
|
197
|
+
Configuration changes made by the linking flow are designed to be reversible. Use `srouter unlink <tool>` to restore a previous configuration from the CLI's backup mechanism.
|
|
198
|
+
|
|
199
|
+
## Related apps
|
|
200
|
+
|
|
201
|
+
- [`apps/api`](../api/README.md) — gateway server
|
|
202
|
+
- [`apps/web`](../web/README.md) — management dashboard
|
|
203
|
+
- [`../../README.md`](../../README.md) — complete SRouter documentation
|
package/bin/srouter.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { spawn } from "node:child_process";
|
|
6
|
+
import { createRequire } from "node:module";
|
|
7
|
+
|
|
8
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const distEntry = path.join(__dirname, "../dist/index.js");
|
|
10
|
+
const srcEntry = path.join(__dirname, "../src/index.ts");
|
|
11
|
+
|
|
12
|
+
if (fs.existsSync(distEntry)) {
|
|
13
|
+
await import("../dist/index.js");
|
|
14
|
+
} else {
|
|
15
|
+
const require = createRequire(import.meta.url);
|
|
16
|
+
let tsxCli = "";
|
|
17
|
+
try {
|
|
18
|
+
const tsxPkg = require.resolve("tsx/package.json");
|
|
19
|
+
const distCli = path.join(path.dirname(tsxPkg), "dist/cli.mjs");
|
|
20
|
+
if (fs.existsSync(distCli)) {
|
|
21
|
+
tsxCli = distCli;
|
|
22
|
+
}
|
|
23
|
+
} catch {
|
|
24
|
+
const localBin = path.join(__dirname, "../node_modules/.bin/tsx");
|
|
25
|
+
if (fs.existsSync(localBin)) {
|
|
26
|
+
tsxCli = localBin;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (tsxCli && fs.existsSync(tsxCli)) {
|
|
31
|
+
const child = spawn(process.execPath, [tsxCli, srcEntry, ...process.argv.slice(2)], {
|
|
32
|
+
stdio: "inherit"
|
|
33
|
+
});
|
|
34
|
+
child.on("exit", (code) => {
|
|
35
|
+
process.exit(code ?? 0);
|
|
36
|
+
});
|
|
37
|
+
} else {
|
|
38
|
+
const child = spawn(
|
|
39
|
+
"pnpm",
|
|
40
|
+
["--filter", "@srouter/cli", "exec", "tsx", srcEntry, ...process.argv.slice(2)],
|
|
41
|
+
{
|
|
42
|
+
stdio: "inherit"
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
child.on("exit", (code) => {
|
|
46
|
+
process.exit(code ?? 0);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|