proxitor 0.9.0-beta.1 โ†’ 0.9.0-beta.11

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
@@ -1,90 +1,70 @@
1
1
  # proxitor
2
2
 
3
3
  <p align="center">
4
- <strong>A transparent proxy between your AI CLI tools and OpenRouter.</strong><br/>
5
- Route by provider. Control costs. Keep streaming. Zero config changes in Claude Code.
4
+ <strong>A friendly proxy between your AI CLI tools and OpenRouter.</strong><br/>
5
+ Route requests to the provider you want. Keep prompt caching alive. Cut costs.<br/>
6
+ Your tools don't even notice.
6
7
  </p>
7
8
 
8
9
  <p align="center">
9
10
  <a href="https://www.npmjs.com/package/proxitor"><img src="https://img.shields.io/npm/v/proxitor?color=6366f1&labelColor=1e2327&label=npm" alt="npm version"></a>
10
- <a href="https://github.com/neiromaster/proxitor/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-22c55e?labelColor=1e2327" alt="MIT License"></a>
11
+ <a href="./LICENSE"><img src="https://img.shields.io/badge/license-MIT-22c55e?labelColor=1e2327" alt="MIT License"></a>
11
12
  <img src="https://img.shields.io/badge/node-%3E%3D22-3b82f6?labelColor=1e2327" alt="Node.js โ‰ฅ 22">
12
- <img src="https://img.shields.io/badge/built_with-TypeScript-3178c6?labelColor=1e2327" alt="TypeScript">
13
13
  </p>
14
14
 
15
- ---
15
+ ๐ŸŒ **English** ยท [ะ ัƒััะบะธะน](./docs/README.ru.md)
16
16
 
17
- ```
18
- Claude Code / Codex
19
- โ”‚
20
- โ”‚ ANTHROPIC_BASE_URL=http://localhost:8828/v1
21
- โ–ผ
22
- โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
23
- โ”‚ proxitor โ”‚ โ† injects provider routing
24
- โ”‚ :8828 โ”‚ โ† streams SSE back unchanged
25
- โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
26
- โ”‚
27
- โ”‚ + X-OpenRouter-* headers
28
- โ–ผ
29
- OpenRouter
30
- โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”
31
- Anthropic DeepInfra Azure ...
32
- ```
17
+ <p align="center"><img src="./docs/assets/proxitor-wizard.gif" alt="proxitor setup wizard" width="640"></p>
33
18
 
34
19
  ---
35
20
 
36
- ## Why
21
+ Proxitor sits between Claude Code (or Codex, or any Anthropic/OpenAI-compatible CLI) and [OpenRouter](https://openrouter.ai). One API key, every model โ€” but **you** decide which provider serves each request, and you make prompt caching actually work.
37
22
 
38
- ### The prompt cache problem
23
+ ```
24
+ your AI CLI โ†’ proxitor โ†’ OpenRouter โ†’ the provider you picked
25
+ ```
39
26
 
40
- OpenRouter is convenient โ€” one key, every model. But by default it load-balances across multiple provider instances for the same model. Each request can land on a different provider, and **prompt caching is provider-scoped**: a cache entry built on Anthropic's infrastructure doesn't help when the next request goes to DeepInfra.
27
+ ## Why you'd want this
41
28
 
42
- Claude Code sends a large system prompt on every single request. Without a pinned provider, you pay full token price every time. With proxitor locking `claude-*` to `anthropic`, that system prompt gets cached after the first hit and subsequent requests cost a fraction.
29
+ OpenRouter is convenient โ€” one key, every model. But it load-balances across providers, and **prompt caching is provider-scoped**: a cache built on Anthropic doesn't help when the next request lands on DeepInfra. Claude Code sends a big system prompt on every request, so without a pinned provider you pay full price every time.
43
30
 
44
- ```yaml
45
- # pin all Claude models to Anthropic โ€” prompt cache works reliably
46
- modelOverrides:
47
- "claude-*":
48
- provider:
49
- only: "anthropic"
50
- ```
31
+ Pin `claude-*` to `anthropic`, and that system prompt gets cached after the first hit. Subsequent requests cost a fraction.
51
32
 
52
- ### Other reasons to use it
33
+ A few other things it's good for:
53
34
 
54
- - **Cost control** โ€” route specific models to cheaper providers when caching isn't the priority
55
- - **Automatic fallbacks** โ€” if Anthropic is degraded, fall back to DeepInfra without touching your tools
56
- - **Mixed routing** โ€” `claude-*` on Anthropic, `gpt-*` on Azure, different rules per model
57
- - **Data privacy** โ€” enforce `dataCollection: deny` or ZDR across all requests
35
+ - **Cost control** โ€” route specific models to cheaper providers when caching isn't the priority.
36
+ - **Automatic fallbacks** โ€” Anthropic down? Fall back to DeepInfra without touching your tools.
37
+ - **Mixed routing** โ€” `claude-*` on Anthropic, `gpt-*` on Azure, different rules per model.
38
+ - **Privacy** โ€” enforce `dataCollection: deny` or zero-data-retention across everything.
58
39
 
59
- Proxitor sits between your CLI tools and OpenRouter, injecting all of this transparently. Your tools don't know anything changed.
60
-
61
- ---
40
+ > Proxitor injects all of this transparently. Your tools see a normal API. Nothing on their side changes.
62
41
 
63
42
  ## Install
64
43
 
44
+ Requires **Node.js 22+**.
45
+
65
46
  ```sh
66
- # npm
67
47
  npm install -g proxitor
68
-
69
- # bun
70
- bun install -g proxitor
71
-
72
- # no install needed
73
- npx proxitor
48
+ # or: bun install -g proxitor
49
+ # or run it once, no install: npx proxitor
74
50
  ```
75
51
 
76
- ---
52
+ ## Quick start
53
+
54
+ **1. Set it up** โ€” the wizard asks a few questions and writes your config:
77
55
 
78
- ## Quick Start
56
+ ```sh
57
+ proxitor config wizard
58
+ ```
79
59
 
80
- **1. Start the proxy**
60
+ **2. Run it**
81
61
 
82
62
  ```sh
83
- OPENROUTER_API_KEY=sk-or-... proxitor
63
+ proxitor
84
64
  # Listening on http://0.0.0.0:8828
85
65
  ```
86
66
 
87
- **2. Point your tools at it**
67
+ **3. Point your tool at it**
88
68
 
89
69
  ```sh
90
70
  # Claude Code
@@ -94,368 +74,59 @@ ANTHROPIC_BASE_URL=http://localhost:8828/v1 claude
94
74
  OPENAI_BASE_URL=http://localhost:8828/v1 codex
95
75
  ```
96
76
 
97
- That's it. Requests flow through proxitor to OpenRouter, SSE streams pass through unchanged.
98
-
99
- ---
100
-
101
- ## Configuration
102
-
103
- Proxitor looks for a config file in this order:
104
-
105
- ```
106
- proxitor.config.yaml โ†’ proxitor.config.yml โ†’ proxitor.config.json
107
- .proxitor.yaml โ†’ .proxitor.yml โ†’ .proxitor.json
108
- ```
109
-
110
- **Priority:** CLI flags > config file > environment variables > defaults
111
-
112
- All defaults are derived from a single Zod schema (`DEFAULTS`) โ€” no hardcoded constants scattered across modules. Config values are validated through Zod on load, including the final merged result.
113
-
114
- See [`proxitor.config.example.yaml`](./proxitor.config.example.yaml) for the complete reference.
115
-
116
- ### Authentication type
117
-
118
- By default, proxitor sends the API key as a `Bearer` token (`Authorization: Bearer sk-...`). If you're using a custom proxy provider that expects an `OAuth` header instead, set `authType` to `oauth`:
119
-
120
- ```yaml
121
- authType: oauth # "bearer" (default) or "oauth"
122
- ```
123
-
124
- This changes the header to `Authorization: OAuth sk-...`.
125
-
126
- ### Custom API URL and data fallback
127
-
128
- When using a custom `openrouterBaseUrl` that points to a third-party service, that service may not support OpenRouter-specific endpoints like `/providers` or `/models/{author}/{slug}/endpoints`. Proxitor handles this automatically:
129
-
130
- - **Automatic fallback** โ€” if the custom API returns an error (4xx/5xx) or an unexpected response format for data endpoints, proxitor falls back to `https://openrouter.ai/api` (no API key needed โ€” these endpoints are public)
131
- - **`openrouterDataUrl`** โ€” set this explicitly to control the primary URL for data fetching, independent of `openrouterBaseUrl` (which is used for proxying requests)
132
-
133
- ```yaml
134
- # Proxy requests go to custom service, data fetching falls back to OpenRouter
135
- # NOTE: do NOT include /v1 in the base URL โ€” request paths like /v1/chat/completions
136
- # are forwarded as-is, so /v1 would be duplicated if included here
137
- openrouterBaseUrl: 'https://custom-service.example.com/api'
138
-
139
- # Explicitly set the primary data URL (optional, defaults to openrouterBaseUrl)
140
- # openrouterDataUrl: 'https://openrouter.ai/api'
141
- ```
142
-
143
- When a fallback occurs, proxitor logs a warning: `Custom API did not return providers, using OpenRouter data as fallback`.
144
-
145
- ### Provider routing
146
-
147
- Control which provider handles your requests. All three options accept a string or an array:
148
-
149
- ```yaml
150
- # Strict lock โ€” only this provider, no fallbacks
151
- provider:
152
- only: "anthropic"
153
-
154
- # Restricted pool โ€” load balance between these providers only
155
- provider:
156
- only:
157
- - "anthropic"
158
- - "deepinfra"
159
-
160
- # Priority order โ€” try Anthropic first, fall back to others if unavailable
161
- provider:
162
- order: "anthropic"
163
- allowFallbacks: true
164
-
165
- # Strict order โ€” try in sequence, no fallbacks outside the list
166
- provider:
167
- order:
168
- - "anthropic"
169
- - "deepinfra"
170
- allowFallbacks: false
171
-
172
- # Blacklist โ€” never use these providers
173
- provider:
174
- ignore: "azure"
175
- ```
176
-
177
- | Option | Behavior |
178
- |---|---|
179
- | `only` | Restrict to the listed provider(s). Load balances by price within the list. Never routes outside it โ€” if all are unavailable, the request fails. |
180
- | `order` | Try providers in the specified priority order. If none work, falls back to other available providers (unless `allowFallbacks: false`). |
181
- | `ignore` | Never route to the listed provider(s). |
182
-
183
- Without `provider` set, requests are forwarded unchanged.
184
-
185
- See [OpenRouter's provider routing docs](https://openrouter.ai/docs/guides/routing/provider-selection) for the full list of supported providers and options.
186
-
187
- ### Per-model overrides
188
-
189
- Route different models differently. Keys are exact names or prefix wildcards. More specific matches win.
190
-
191
- ```yaml
192
- provider:
193
- order: "deepinfra" # global default
194
-
195
- modelOverrides:
196
- # Exact match โ€” force this model to Anthropic
197
- "claude-sonnet-4-6":
198
- provider:
199
- only: "anthropic"
200
-
201
- # Wildcard โ€” all claude-* models prefer Anthropic with fallback
202
- "claude-*":
203
- provider:
204
- order:
205
- - "anthropic"
206
- - "deepinfra"
207
-
208
- # GPT models to OpenAI/Azure, plus a custom header
209
- "gpt-*":
210
- provider:
211
- only:
212
- - "openai"
213
- - "azure"
214
- headers:
215
- X-Model-Family: "gpt"
216
- ```
217
-
218
- **Match priority:** exact name > longer prefix > shorter prefix.
77
+ That's the whole setup. Requests flow through proxitor; streaming responses pass through untouched.
219
78
 
220
- ### Custom headers
79
+ ## Configuring it
221
80
 
222
- Add headers to all proxied requests, or per-model (merged on top of global):
223
-
224
- ```yaml
225
- headers:
226
- X-Custom-Header: "my-value"
227
- X-Environment: "production"
228
-
229
- modelOverrides:
230
- "claude-*":
231
- headers:
232
- X-Custom-Header: "claude-override" # overrides the global value
233
- X-Extra: "only-for-claude" # added only for this model
234
- ```
235
-
236
- ### Advanced provider options
237
-
238
- ```yaml
239
- provider:
240
- sort: "throughput" # sort by: price | throughput | latency
241
- quantizations:
242
- - "fp8" # filter by quantization level
243
- maxPrice:
244
- prompt: 1 # $/M tokens
245
- completion: 2
246
- requireParameters: true # only use providers that support all request params
247
- dataCollection: "deny" # "allow" | "deny"
248
- zdr: true # Zero Data Retention enforcement
249
- preferredMinThroughput:
250
- p90: 50 # tokens/sec (soft threshold)
251
- preferredMaxLatency:
252
- p90: 3 # seconds (soft threshold)
253
- ```
254
-
255
- ### Prompt caching
256
-
257
- By default, OpenRouter doesn't enable prompt caching โ€” every request pays full token price. Proxitor can inject `cache_control` and `session_id` to make caching work automatically.
258
-
259
- **`cacheControl`** โ€” injects `cache_control: { "type": "ephemeral" }` into the request body. OpenRouter uses this to set cache breakpoints and advance them as conversations grow.
260
-
261
- **`cacheControlTtl`** โ€” controls the cache time-to-live. Anthropic's default TTL is 5 minutes (300s). Set to `1h` for a 1-hour cache at higher write cost (2ร— vs 1.25ร—). Only applies to Anthropic models โ€” other providers don't support TTL.
262
-
263
- **`sessionId`** โ€” injects `session_id` for provider sticky routing. Without it, OpenRouter only pins to a provider after detecting a cache hit. With it, routing sticks from the **first request** โ€” critical for OpenAI models where delayed caching means 0 cached tokens on the first 1-2 requests.
264
-
265
- Both `cacheControl` and `sessionId` support `auto` / `always` / `never` modes:
266
-
267
- | Mode | `cacheControl` | `sessionId` |
268
- | --- | --- | --- |
269
- | `auto` (default) | Anthropic models on `/v1/chat/completions`; all models on `/v1/messages` and `/v1/responses` | Use `X-Claude-Code-Session-Id` header if present; otherwise generate proxy UUID |
270
- | `always` | All models, all endpoints | Generate a proxy UUID for sticky routing |
271
- | `never` | Disabled | Disabled |
272
-
273
- `cacheControlTtl` values:
274
-
275
- | Value | TTL | Write cost | Use when |
276
- | --- | --- | --- | --- |
277
- | _(not set)_ | 5 min (Anthropic default) | 1.25ร— | High-frequency requests (>1 per 5 min) |
278
- | `5m` | 5 minutes | 1.25ร— | Explicit short cache |
279
- | `1h` | 1 hour | 2.0ร— | Low-frequency or long-running sessions |
280
-
281
- ```yaml
282
- cacheControl: auto # safe default โ€” Anthropic and safe endpoints only
283
- sessionId: auto # always ensures sticky routing (client header or proxy UUID)
284
-
285
- # Use 1-hour cache for all Anthropic models (higher write cost, longer TTL)
286
- cacheControlTtl: 1h
287
-
288
- # Force caching for all models (may cause 400 on non-Anthropic /v1/chat/completions)
289
- # cacheControl: always
290
-
291
- # Per-model overrides โ€” TTL supports '5m', '1h', or 'default' (cancel global TTL)
292
- modelOverrides:
293
- "gpt-*":
294
- cacheControl: never # OpenAI caches automatically, no injection needed
295
- sessionId: always # but sticky routing still helps
296
- "claude-opus-*":
297
- cacheControlTtl: default # cancel global 1h TTL for Opus โ€” use Anthropic's 5 min default
298
- ```
299
-
300
- **Why all three matter:**
301
-
302
- - **Anthropic models** โ€” `cache_control` activates caching, `cacheControlTtl` extends it beyond 5 min, `session_id` prevents provider flip-flopping that would invalidate it
303
- - **OpenAI models** โ€” caching is automatic (no `cache_control` needed), but `session_id` ensures sticky routing from request #1 instead of waiting for a cache hit
304
- - **All models** โ€” `session_id` prevents the provider switch that silently resets cache
305
-
306
- ### Health check
81
+ The friendly way: an interactive menu โ€” no YAML required.
307
82
 
308
83
  ```sh
309
- curl http://localhost:8828/health
84
+ proxitor config # open the menu
85
+ proxitor config wizard # (re)run guided setup
310
86
  ```
311
87
 
312
- ### Cache usage logging
88
+ From the menu you can set your API key and connection, pick routing per model (with live provider pricing), tune caching, and add or edit model overrides. It pulls live data from OpenRouter, so you browse real models and providers with up-to-date prices.
313
89
 
314
- Proxitor automatically logs cache token usage from upstream responses โ€” both non-streaming JSON and streaming SSE. No configuration needed.
90
+ Prefer to edit a file? The full **[configuration reference](./docs/configuration.md)** covers provider routing, per-model overrides, headers, caching modes, and every option. [`proxitor.config.example.yaml`](./proxitor.config.example.yaml) is a commented template.
315
91
 
316
- ```
317
- [abc123] Cache read: 50000, write: 25000 tokens
318
- [def456] Cache: no cached tokens
319
- ```
320
-
321
- Supports both provider formats:
322
-
323
- | Provider format | Fields |
324
- |---|---|
325
- | Anthropic | `usage.cache_read_input_tokens` / `usage.cache_creation_input_tokens` |
326
- | OpenAI / OpenRouter | `usage.prompt_tokens_details.cached_tokens` / `cache_write_tokens` |
327
-
328
- When both formats are present (e.g., OpenRouter relaying an Anthropic response), Anthropic fields take priority.
329
-
330
- ---
92
+ ## Adding a model override
331
93
 
332
- ## Interactive Config Manager
94
+ Pin a model โ€” or a wildcard like `claude-*` โ€” to specific providers, straight from the menu. It pulls live pricing and latency for every provider of that model.
333
95
 
334
- Proxitor includes an interactive CLI for managing model overrides โ€” search models, pick providers, and write to config without editing YAML by hand.
96
+ <p align="center"><img src="./docs/assets/proxitor-add.gif" alt="proxitor: add a model override" width="640"></p>
335
97
 
336
- ### Setup wizard
337
-
338
- Run the wizard to create or update your config interactively. If no config exists, any command will offer to launch it automatically.
98
+ ## When something's off
339
99
 
340
100
  ```sh
341
- proxitor config wizard
101
+ proxitor doctor # checks environment, config, key, network, port, version
342
102
  ```
343
103
 
344
- The wizard asks for:
104
+ It prints a clear report and exits non-zero if anything fails โ€” handy from CI too (`--json`, `--offline`, `--timeout`).
345
105
 
346
- - **OpenRouter API key** โ€” stored in config or set as `OPENROUTER_API_KEY` env var
347
- - **Port** โ€” default `8828` (avoids conflicts with common dev servers on 8080)
348
- - **API base URL** โ€” default `https://openrouter.ai/api`; change for self-hosted or custom endpoints
349
- - **Data URL** โ€” separate URL for provider/model data fetching; falls back to OpenRouter automatically if the custom API doesn't support these endpoints
350
- - **Authentication type** โ€” `bearer` (default) or `oauth`; use `oauth` for custom proxy providers that pass tokens in the `Authorization: OAuth ...` header
351
- - **Host** โ€” all interfaces (`0.0.0.0`) or localhost only (`127.0.0.1`)
352
- - **Save location** โ€” project directory, `~/.config/proxitor/`, or `$XDG_CONFIG_HOME/proxitor/`
106
+ While proxitor runs, it logs cache usage from upstream so you can see whether caching is actually helping:
353
107
 
354
- If a config already exists, the wizard shows its location and asks whether to reconfigure. Existing `modelOverrides`, `provider`, and other fields are preserved โ€” only the wizard fields are updated.
355
-
356
- ```sh
357
- proxitor config menu # interactive menu
358
- proxitor config add # add a model override
359
- proxitor config edit # edit existing override
360
- proxitor config remove # remove override(s)
361
- proxitor config list # show current overrides
362
- proxitor config browse # explore models with pricing info
363
- proxitor config wizard # interactive setup wizard
364
- proxitor config validate # validate config file
365
108
  ```
366
-
367
- ### Add override walkthrough
368
-
369
- ```sh
370
- $ proxitor config add
371
-
372
- โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
373
- โ”‚ Add Model Override โ”‚
374
- โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
375
-
376
- โ—‡ Search for a model
377
- โ”‚ claude
378
- (23 matches)
379
- โ— anthropic/claude-sonnet-4-6 ยท $3.00/$15.00 ยท 200k
380
- โ—‹ anthropic/claude-opus-4-8 ยท $15.00/$75.00 ยท 200k
381
- ...
382
-
383
- โ—‡ Configure provider routing
384
- โ”‚ โ—‹ Use specific providers only
385
- โ—‹ Set provider priority order
386
- โ—‹ Ignore specific providers
387
- โ—‹ Skip provider routing
109
+ [abc123] Cache read: 50000, write: 25000 tokens (99.6% hit)
388
110
  ```
389
111
 
390
- **"Use specific providers only" / "Ignore specific providers"** โ€” multiselect, pick all that apply:
391
-
392
- ```text
393
- โ—‡ Select providers
394
- โ—ผ anthropic (anthropic) ยท 1.0s ยท 40 t/s
395
- โ—ป google-vertex/global ยท 1.1s ยท 39 t/s
396
- โ—ป amazon-bedrock ยท 1.2s ยท 40 t/s
397
- ```
398
-
399
- **"Set provider priority order"** โ€” pick providers one at a time, then select **โœ“ Done** at the bottom to finish:
400
-
401
- ```text
402
- โ—‡ Select provider #1 (or cancel to finish)
403
- โ”‚ โ— anthropic (anthropic) ยท 1.0s ยท 40 t/s
404
- โ—‹ google-vertex/global ยท 1.1s ยท 39 t/s
405
- โ—‹ amazon-bedrock ยท 1.2s ยท 40 t/s
406
- โ—‹ โœ“ Done
407
-
408
- โ—‡ Select provider #2 (or cancel to finish)
409
- โ”‚ โ— google-vertex/global ยท 1.1s ยท 39 t/s
410
- โ—‹ amazon-bedrock ยท 1.2s ยท 40 t/s
411
- โ—‹ โœ“ Done
412
-
413
- โ—‡ Select provider #3 (or cancel to finish)
414
- โ”‚ โ— โœ“ Done
112
+ Quick health poke: `curl http://localhost:8828/health`.
415
113
 
416
- โ—‡ Allow fallbacks to other providers? Yes
114
+ ## Commands at a glance
417
115
 
418
- โ—‡ Save to config? Yes
419
-
420
- โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
421
- โ”‚ โœ“ Model override saved โ”‚
422
- โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
116
+ ```sh
117
+ proxitor # start the proxy (the default command)
118
+ proxitor config # interactive config menu
119
+ proxitor config wizard # guided setup
120
+ proxitor config browse # explore models + pricing
121
+ proxitor doctor # diagnose everything
122
+ proxitor --help # the rest of the flags
423
123
  ```
424
124
 
425
- The interface uses live data from the OpenRouter API โ€” model search with type-ahead, real provider availability and pricing for each model.
426
-
427
- ---
428
-
429
- ## CLI Options
430
-
431
- | Flag | Default | Description |
432
- |---|---|---|
433
- | `-p, --port <port>` | `8828` | Server port |
434
- | `-h, --host <host>` | `0.0.0.0` | Server host |
435
- | `-c, --config <path>` | auto-discovered | Path to config file |
436
- | `--openrouter-key <key>` | `$OPENROUTER_API_KEY` | OpenRouter API key |
437
- | `--verbose` | `false` | Enable verbose logging |
438
- | `--no-config` | | Skip config file discovery |
439
- | `-v, --version` | | Print version |
440
- | `--help` | | Print help |
125
+ Common flags: `--port`, `--host`, `--config <path>`, `--openrouter-key <key>`. Run `proxitor --help` and `proxitor config --help` for the full list.
441
126
 
442
- ---
443
-
444
- ## Development
445
-
446
- ```sh
447
- pnpm install # install dependencies
448
- pnpm dev # build + watch
449
- pnpm test # run tests
450
- pnpm test:e2e # end-to-end tests
451
- pnpm typecheck # TypeScript check
452
- pnpm check:biome # lint + format check
453
- pnpm lint:fix # auto-fix lint issues
454
- pnpm build # production build
455
- pnpm check # typecheck + biome + test (full CI)
456
- ```
127
+ ## Contributing
457
128
 
458
- ---
129
+ PRs welcome โ€” see **[CONTRIBUTING.md](./CONTRIBUTING.md)** for setup, tests, commits, and changesets.
459
130
 
460
131
  ## License
461
132