switchboard-fyi 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Switchboard
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,538 @@
1
+ # Switchboard
2
+
3
+ ## Local routing CLI
4
+
5
+ Switchboard is designed to sit in front of normal `codex` and `claude` usage.
6
+ The install step creates local PATH shims so those commands route through
7
+ Switchboard anywhere in the terminal.
8
+
9
+ Install from npm:
10
+
11
+ ```bash
12
+ npm install -g switchboard-fyi
13
+ ```
14
+
15
+ Or install with Homebrew after the public tap is published:
16
+
17
+ ```bash
18
+ brew install switchboardfyi/tap/switchboard-fyi
19
+ ```
20
+
21
+ Installed CLI entrypoint:
22
+
23
+ ```bash
24
+ switchboard
25
+ ```
26
+
27
+ Bare `switchboard` opens the interactive local console. The published CLI
28
+ supports macOS and Linux for launch; Windows shims are intentionally not
29
+ included in this release.
30
+
31
+ The interactive `start` action opens the live dashboard for that harness. It
32
+ does not launch Codex or Claude Code.
33
+
34
+ Harness state is runtime scoped:
35
+
36
+ - `installed`: Switchboard is ready, but routing is off. Codex and Claude use
37
+ your normal model settings.
38
+ - `observe`: `switchboard observe <harness>` is running in a terminal. Harness
39
+ calls go through Switchboard for logging, but models are preserved.
40
+ - `routing`: `switchboard start <harness>` is running in a terminal. Harness calls
41
+ go through Switchboard and can be routed according to the selected profile.
42
+
43
+ Closing the `start` or `observe` terminal turns that harness back to
44
+ `installed`.
45
+
46
+ Only one `start` or `observe` terminal can own a harness at a time. If Codex or
47
+ Claude Code is already active in another window, Switchboard refuses the second
48
+ start and shows the owning process id.
49
+
50
+ Only one wrapped Codex or Claude Code session can run through Switchboard for a
51
+ harness at a time. That keeps local gateways tied to visible terminal sessions
52
+ instead of accumulating in the background.
53
+
54
+ The home screen is harness-first: before a shim is active, each harness only
55
+ offers `install`; after install, it offers `start`, `observe`, `settings`, and
56
+ `uninstall`.
57
+
58
+ Install the shims:
59
+
60
+ ```bash
61
+ switchboard install
62
+ ```
63
+
64
+ This writes `codex` and `claude` wrappers to `~/.switchboard/bin`, records the
65
+ real binary paths in `~/.switchboard/install.json`, and adds a managed PATH
66
+ block to your shell rc file. Open a new terminal after install. Then use the
67
+ tools normally:
68
+
69
+ ```bash
70
+ codex
71
+ claude
72
+ ```
73
+
74
+ To install one harness or remove the shims:
75
+
76
+ ```bash
77
+ switchboard install codex
78
+ switchboard install claude
79
+ switchboard uninstall codex
80
+ switchboard uninstall claude
81
+ switchboard uninstall
82
+ ```
83
+
84
+ Settings expose each installed harness model set, including the difficulty
85
+ `1..5` model map for each harness.
86
+
87
+ Run Codex through the Responses model-provider proxy:
88
+
89
+ ```bash
90
+ codex
91
+ ```
92
+
93
+ Codex must be routed at the model-provider boundary, not the app-server
94
+ `turn/start` boundary. The canonical path is:
95
+
96
+ ```text
97
+ codex -> Switchboard /v1/responses -> chatgpt.com/backend-api/codex/responses
98
+ ```
99
+
100
+ This preserves ChatGPT/Codex subscription auth locally and exposes each internal
101
+ Codex model request to Switchboard.
102
+ Switchboard v1 supports ChatGPT subscription auth only for Codex. API-key Codex
103
+ requests are rejected locally before routing, without spending a Switchboard
104
+ request credit or forwarding to `api.openai.com`.
105
+
106
+ Run Claude Code through the Anthropic-compatible gateway:
107
+
108
+ ```bash
109
+ claude
110
+ ```
111
+
112
+ Switchboard v1 supports Claude Code subscription OAuth only, including
113
+ `CLAUDE_CODE_OAUTH_TOKEN` from `claude setup-token`. Anthropic API-key,
114
+ PAYG, Bedrock, Vertex, and Foundry auth paths are stripped or rejected before
115
+ routing.
116
+
117
+ Observe mode:
118
+
119
+ ```bash
120
+ --observe
121
+ ```
122
+
123
+ Switchboard API routing:
124
+
125
+ ```bash
126
+ switchboard login
127
+ switchboard balance
128
+ switchboard config use-switchboard-api https://api.switchboard.fyi
129
+ ```
130
+
131
+ The gateway sends a compact classification packet and local routing settings to
132
+ the Switchboard API. The Cloudflare API owns the classifier prompt, checks
133
+ credits, calls Workers AI, and returns difficulty `1..5`, a reason code, and a
134
+ short dashboard task label. The local CLI maps that difficulty to the configured
135
+ model for the active harness. A successful new API classification spends one request credit,
136
+ including best and observe recommendations. It sends a compact routing summary,
137
+ not the raw provider request, and the billing ledger does not store full
138
+ prompts. If the API is unavailable or the account has no request credits, the
139
+ dashboard records an explicit router error or insufficient-balance state.
140
+
141
+ After that, this is enough:
142
+
143
+ Terminal 1:
144
+
145
+ ```bash
146
+ switchboard start codex
147
+ ```
148
+
149
+ Terminal 2:
150
+
151
+ ```bash
152
+ codex \
153
+ exec --skip-git-repo-check --dangerously-bypass-approvals-and-sandbox \
154
+ "Reply with exactly: router-ok"
155
+ ```
156
+
157
+ For an interactive Codex session, use:
158
+
159
+ ```bash
160
+ codex
161
+ ```
162
+
163
+ If the default local proxy port is already occupied, the wrapper automatically
164
+ uses the next free port and prints the port it selected.
165
+
166
+ Model catalog and difficulty map:
167
+
168
+ ```bash
169
+ switchboard models
170
+ switchboard models list
171
+ switchboard models codex
172
+ switchboard models claude-code
173
+ switchboard difficulty
174
+ switchboard difficulty set codex 5 gpt-5.5 xhigh
175
+ switchboard difficulty set claude-code 3 claude-sonnet-4-6 medium
176
+ ```
177
+
178
+ Switchboard classifies each request as difficulty `1..5`, then resolves that
179
+ difficulty locally from the configured map for the active harness. Use
180
+ `models` to inspect the bundled catalog and `difficulty set` to edit a single
181
+ difficulty level. The default Codex map is:
182
+
183
+ ```text
184
+ 5 gpt-5.5 reasoning=xhigh
185
+ 4 gpt-5.5 reasoning=medium
186
+ 3 gpt-5.4 reasoning=medium
187
+ 2 gpt-5.4-mini reasoning=medium
188
+ 1 gpt-5.4-mini reasoning=low
189
+ ```
190
+
191
+ For Codex, the three main-model choices are `gpt-5.5 reasoning=xhigh`,
192
+ `gpt-5.5 reasoning=high`, and `gpt-5.5 reasoning=medium`. For Claude Code,
193
+ the default map routes lower difficulty requests to Haiku/Sonnet and higher
194
+ difficulty requests to Opus.
195
+
196
+ The model catalog lists standard uncached input and output billing rates per
197
+ million tokens: Codex uses Codex credits, and Claude uses USD API pricing.
198
+ The local CLI dashboard shows requests and provider token usage from local
199
+ responses. Account status shows hosted request counts; hosted token totals are
200
+ shown only when token accounting is available. It does not show cost estimates.
201
+
202
+ The bundled model catalog is curated and updates with new Switchboard releases.
203
+
204
+ CLI updates:
205
+
206
+ ```bash
207
+ switchboard update check
208
+ switchboard update
209
+ ```
210
+
211
+ After the npm package is published, `switchboard update check` reads the npm
212
+ registry and `switchboard update` runs the package-manager update flow. The CLI
213
+ also checks periodically and can show a TTY-only update prompt:
214
+
215
+ ```text
216
+ ✨ Switchboard update available! 0.1.0 -> 0.1.1
217
+
218
+ Release notes: https://switchboard.fyi/release/latest
219
+
220
+ 1. Update Switchboard
221
+ 2. Skip
222
+ ```
223
+
224
+ Skipping only applies to the current run; if the same version is still latest,
225
+ Switchboard prompts again on the next interactive `switchboard` launch. Normal
226
+ wrapped `codex` and `claude` runs never show this prompt. The latest npm result
227
+ is cached in `~/.switchboard/update-state.json` so normal Switchboard launches
228
+ do not hit the registry every time.
229
+
230
+ Component status:
231
+
232
+ ```bash
233
+ switchboard status
234
+ switchboard status set codex needs-update "Codex harness needs a Switchboard update"
235
+ switchboard status set claude down "Claude harness temporarily disabled"
236
+ switchboard status set switchboard api degraded "Classifier API latency is elevated"
237
+ switchboard status clear codex
238
+ switchboard config set componentStatus.url https://status.example.com/switchboard.json
239
+ switchboard status refresh
240
+ ```
241
+
242
+ `status set` writes a local override to `~/.switchboard/config.json`. By default,
243
+ remote component status is read from `<api.baseUrl>/v1/status`. That API-owned
244
+ feed is the production source of truth for `claude`, `codex`, and `api`
245
+ compatibility. Its steady state should be `ok`; `unknown` is only a local
246
+ fallback when no status source has been read.
247
+
248
+ Production incidents should be handled through the API status feed, not local
249
+ overrides. The operational runbook is in
250
+ `docs/component-status-runbook.md`.
251
+
252
+ Use API-level component status when an upstream Claude Code or Codex release
253
+ breaks Switchboard compatibility, or when the Switchboard API itself is
254
+ degraded. The CLI renders `ok` as a checkmark and `degraded`, `needs_update`,
255
+ or `down` as attention states. For incidents that should use a different feed,
256
+ publish a small JSON manifest at `componentStatus.url`; the CLI caches it in
257
+ `~/.switchboard/component-status.json` and still allows local overrides for
258
+ testing or emergency support.
259
+
260
+ Manifest shape:
261
+
262
+ ```json
263
+ {
264
+ "schemaVersion": 1,
265
+ "updatedAt": "2026-05-19T12:00:00Z",
266
+ "components": {
267
+ "codex": { "state": "ok" },
268
+ "claude": { "state": "needs-update", "message": "Run switchboard update before using Claude Code." },
269
+ "api": { "state": "degraded", "message": "Classifier latency is elevated." }
270
+ }
271
+ }
272
+ ```
273
+
274
+ Logs:
275
+
276
+ ```bash
277
+ switchboard watch codex
278
+ switchboard watch claude-code
279
+ switchboard inspect
280
+ switchboard inspect --harness codex
281
+ switchboard inspect --harness claude-code
282
+ switchboard status codex
283
+ switchboard config show
284
+ switchboard dashboard --local codex
285
+ switchboard dashboard --local claude-code
286
+ switchboard watch codex
287
+ switchboard logs codex
288
+ tail -f ~/.switchboard/harnesses/codex/events.jsonl
289
+ tail -f ~/.switchboard/harnesses/claude/events.jsonl
290
+ ```
291
+
292
+ Switchboard keeps runtime logs and health state per harness under
293
+ `~/.switchboard/harnesses/<harness>/`, while global config remains shared.
294
+ Use `switchboard inspect` for the local web inspector. It groups calls by
295
+ `decisionId` and shows the routing payload, API/router response, applied
296
+ route, forwarding status, and raw JSONL events.
297
+
298
+ More detail is in `docs/mvp-usage.md`, `docs/codex-subscription-provider-proxy.md`,
299
+ `docs/routing-api.md`, `docs/known-limitations.md`, and `docs/smoke-test.md`.
300
+
301
+ ## 1-Page Product Spec
302
+
303
+ Switchboard — 1-Page Product Spec
304
+ Product summary
305
+
306
+ Switchboard is an API-directed model-routing gateway for developers using tools like Claude Code, Codex, and future AI coding harnesses.
307
+
308
+ Developers keep using their existing tools exactly as normal. Switchboard sits behind the harness as the model endpoint, asks the Switchboard API where to route, tries the recommended cheaper model when directed, and automatically falls back to the original model if the routed provider call fails before useful output is sent.
309
+
310
+ Use the right model without thinking about it.
311
+
312
+ Core promise
313
+
314
+ Switchboard does one thing:
315
+
316
+ Route when the Switchboard API says to route, and protect the developer with automatic original-call fallback.
317
+
318
+ It does not rewrite prompts, compact context, modify tools, change agent behavior, or interfere with the developer’s workflow.
319
+
320
+ Problem
321
+
322
+ Developers love Claude Code and Codex because the harness is already excellent: repo awareness, shell access, tool use, patches, context handling, and workflow muscle memory.
323
+
324
+ But these tools often use expensive models for tasks that do not need them:
325
+
326
+ Rename this variable
327
+ Write a PR description
328
+ Explain this small error
329
+ Summarize this diff
330
+ Make this copy clearer
331
+
332
+ At the same time, many tasks genuinely deserve the strongest model:
333
+
334
+ Fix this auth bug
335
+ Refactor this module
336
+ Debug failing tests
337
+ Think through this architecture
338
+ Make a complex multi-file change
339
+
340
+ Today, users have to manually decide which model is worth using. Most will not. So they either overspend or risk underpowering important work.
341
+
342
+ Target users
343
+
344
+ Initial users are AI-heavy developers, indie hackers, founders, and small teams who already use Claude Code, Codex, Cursor, or similar tools daily.
345
+
346
+ They want:
347
+
348
+ - lower AI model spend
349
+ - less top-tier quota waste
350
+ - no workflow migration
351
+ - no degraded quality on hard tasks
352
+ - simple override controls
353
+ Non-goals
354
+
355
+ Switchboard v1 should be intentionally narrow.
356
+
357
+ It should not do:
358
+
359
+ - prompt rewriting
360
+ - context compaction
361
+ - tool blocking
362
+ - repo analysis
363
+ - validation loops
364
+ - custom agent behavior
365
+ - coding-agent replacement
366
+ - new IDE/chat interface
367
+
368
+ The trust boundary is simple:
369
+
370
+ Switchboard only chooses the destination model.
371
+
372
+ How it works
373
+ Claude Code / Codex
374
+
375
+ Switchboard Gateway
376
+
377
+ Route Classifier
378
+
379
+ Lower-cost model OR strongest model
380
+
381
+ Response streams back to original harness
382
+
383
+ The user configures their tool to use Switchboard as the model endpoint.
384
+
385
+ Example model alias:
386
+
387
+ model = "auto"
388
+
389
+ Switchboard maps `auto` to the model configured for the API-assigned
390
+ difficulty. It maps `auto` to the configured best model when preserved,
391
+ uncertain, or falling back.
392
+ Routing policy
393
+
394
+ Switchboard classifies each request into difficulty `1..5`:
395
+
396
+ - `1` → trivial, exact, mechanical, or simple text work
397
+ - `2` → light routine text or bounded work
398
+ - `3` → normal bounded coding or analysis
399
+ - `4` → substantial multi-step, tool-driven, or multi-file work
400
+ - `5` → hard debugging, architecture, large context, or high-risk work
401
+
402
+ The API owns difficulty classification. The CLI owns model selection,
403
+ execution, retry, and narrow routed-path cooldowns after real routed failures.
404
+
405
+ Default principle:
406
+
407
+ Route to save money when the API recommends it; fall back to the original model when execution proves that route unhealthy.
408
+
409
+ Lower-tier examples
410
+ - naming
411
+ - simple rewrites
412
+ - small explanations
413
+ - commit messages
414
+ - PR descriptions
415
+ - formatting
416
+ - command generation
417
+
418
+ Mid-tier examples
419
+ - summarizing short diffs
420
+ - simple terminal-output explanation
421
+ - large-context summarization
422
+ - straightforward single-file edits
423
+ - routine config/docs work
424
+
425
+ Best-tier examples
426
+ - bug fixing
427
+ - auth/payments/security work
428
+ - refactors
429
+ - multi-file edits
430
+ - test failures
431
+ - architecture decisions
432
+ - unclear requirements
433
+ - consequential security review
434
+ - repeated failed attempts
435
+ - anything the router is unsure about
436
+ Product modes
437
+ 1. Observe
438
+
439
+ No routing. Switchboard only reports what it would have done.
440
+
441
+ 12 calls would have been preserved on the strongest model.
442
+ 7 calls could likely have used cheaper routing.
443
+ 2. Auto
444
+
445
+ Switchboard automatically routes obvious low-risk calls down and preserves the strongest model for everything else.
446
+
447
+ Three routing modes:
448
+
449
+ - `Quality`: prioritize the strongest model for harder work while still routing clear low-risk waste
450
+ - `Balanced`: recommended default for everyday sessions
451
+ - `Saver`: route more aggressively to reduce spend while still protecting high-risk work
452
+ User experience
453
+
454
+ The product should be quiet.
455
+
456
+ The developer still runs:
457
+
458
+ claude
459
+
460
+ or:
461
+
462
+ codex
463
+
464
+ Optional session receipt:
465
+
466
+ Disabled by default. Enable it with:
467
+
468
+ ```bash
469
+ switchboard config set sessionReceipt.enabled true
470
+ ```
471
+
472
+ Switchboard session receipt
473
+
474
+ Requests: 8
475
+ Tokens processed: 42k
476
+ Cheap-route retries: 0
477
+
478
+ Power-user overrides:
479
+
480
+ auto
481
+ lower
482
+ best
483
+ MVP
484
+ Must-have
485
+ - gateway endpoint
486
+ - Claude Code / Codex setup instructions
487
+ - model alias: auto
488
+ - API-directed route classifier
489
+ - difficulty-to-model mapping
490
+ - streaming response passthrough
491
+ - request/cost logging
492
+ - session receipt
493
+ - user override: force best
494
+ Should-have
495
+ - observe mode
496
+ - auto mode
497
+ - simple dashboard
498
+ - per-project settings
499
+ - routed-request regret tracking
500
+ Success metrics
501
+
502
+ Primary metric:
503
+
504
+ Best-tier requests avoided without increasing retries.
505
+
506
+ Track:
507
+
508
+ - strongest-model requests avoided
509
+ - tokens processed
510
+ - routed-request retry rate
511
+ - user override rate
512
+ - router disable rate
513
+ - preserved-request rate
514
+ - cost per accepted task
515
+
516
+ Most important quality metric:
517
+
518
+ Lower-tier regret rate
519
+
520
+ Meaning:
521
+
522
+ How often did a user rerun, override, or escalate after Switchboard used a lower-cost tier?
523
+
524
+ That number must stay low.
525
+
526
+ Positioning
527
+
528
+ Simple version:
529
+
530
+ Switchboard routes AI coding requests through the Switchboard API and falls back to the original model when a routed provider call fails.
531
+
532
+ Developer version:
533
+
534
+ An API-directed model-routing layer for Claude Code, Codex, and other AI coding harnesses. Keep your workflow. Cut wasted top-tier calls. Fall back safely.
535
+
536
+ Punchier tagline:
537
+
538
+ Use your strongest model where it matters.