@hasna/switcher 0.1.1 → 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 +146 -7
- package/dist/aider-args.d.ts +7 -0
- package/dist/aider-config.d.ts +6 -0
- package/dist/auth.d.ts +3 -0
- package/dist/cli/index.js +7548 -2558
- package/dist/cli.d.ts +2 -0
- package/dist/cline-backend.d.ts +7 -0
- package/dist/codex-model-policy.d.ts +65 -0
- package/dist/credentials.d.ts +5 -5
- package/dist/direct-launch.d.ts +3 -3
- package/dist/domain.d.ts +320 -50
- package/dist/dsh-args.d.ts +5 -0
- package/dist/gemini-bridge.d.ts +6 -0
- package/dist/gemini-config.d.ts +12 -0
- package/dist/gemini-model-policy.d.ts +56 -0
- package/dist/generated/api.d.ts +220 -21
- package/dist/harness-arguments.d.ts +1 -0
- package/dist/harness-installation.d.ts +19 -0
- package/dist/harness-types.d.ts +10 -0
- package/dist/harnesses.d.ts +5 -2
- package/dist/hermes-backend.d.ts +19 -0
- package/dist/hermes-model-policy.d.ts +30 -0
- package/dist/index.js +136 -43
- package/dist/inference-gateway.d.ts +24 -0
- package/dist/kilo-config.d.ts +13 -0
- package/dist/kilo.d.ts +5 -0
- package/dist/launcher.d.ts +12 -6
- package/dist/mcp/index.js +139 -55
- package/dist/model-policy-schema.d.ts +137 -0
- package/dist/model-policy.d.ts +31 -0
- package/dist/native-model-policy.d.ts +23 -0
- package/dist/omp-backend.d.ts +7 -0
- package/dist/opencode-model-policy.d.ts +33 -0
- package/dist/opencode2-config.d.ts +3 -3
- package/dist/ori-backend.d.ts +2 -2
- package/dist/ori-model-policy.d.ts +8 -0
- package/dist/presets.d.ts +11 -10
- package/dist/sdk.d.ts +279 -38
- package/dist/sdk.js +136 -43
- package/dist/serve/index.js +1306 -125
- package/docs/MODEL-POLICY.md +82 -0
- package/openapi.json +973 -14
- package/package.json +14 -3
package/README.md
CHANGED
|
@@ -4,17 +4,43 @@ title: "Switcher"
|
|
|
4
4
|
type: "package-documentation"
|
|
5
5
|
owner: "codex-fixer"
|
|
6
6
|
created_at: "2026-09-05T12:50:21.698672Z"
|
|
7
|
-
updated_at: "2026-09-
|
|
7
|
+
updated_at: "2026-09-06T15:23:09.568156+00:00"
|
|
8
8
|
status: "active"
|
|
9
9
|
source_task: "01a07181-ca8d-70c1-99a2-b276dc5770f3"
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
# Switcher
|
|
13
13
|
|
|
14
|
-
Launch Claude Code, Codex, Grok Build, OpenCode 2
|
|
14
|
+
Launch Claude Code, Codex, Grok Build, OpenCode 2, legacy OpenCode, Kilo, Pi, OMP, DeepSeek Harness, Cline, Hermes, Prime Agent, Gemini CLI or Aider with a chosen compatible provider and its model catalog. An authenticated API owns profiles and run metadata; the CLI starts the native harness on your computer. Import the same HTTP client from `@hasna/switcher/sdk`.
|
|
15
15
|
|
|
16
16
|
Requires Bun 1.3.14 or newer. Install the native harnesses separately.
|
|
17
17
|
|
|
18
|
+
Switcher never installs or upgrades a native harness. `switcher doctor` reports
|
|
19
|
+
the executable name, verified version requirement, upstream project and
|
|
20
|
+
installation guidance for every adapter. If a harness is installed outside
|
|
21
|
+
`PATH`, pass its trusted absolute executable path with `--executable PATH`.
|
|
22
|
+
|
|
23
|
+
| Harness | Executable and verified version | Install target | Official instructions |
|
|
24
|
+
| --- | --- | --- | --- |
|
|
25
|
+
| Claude Code | `claude`, >=2.1.257 | Claude Code official distribution | [Quickstart](https://code.claude.com/docs/en/quickstart) |
|
|
26
|
+
| Codex CLI | `codex`, >=0.153.0 | OpenAI Codex official distribution | [Project](https://github.com/openai/codex) |
|
|
27
|
+
| Grok Build | `grok`, >=1.0.13 | xAI Grok Build official project | [Project](https://github.com/xai-org/grok-build) |
|
|
28
|
+
| OpenCode (legacy) | `opencode`, >=1.18.0 | `opencode-ai` | [CLI guide](https://github.com/anomalyco/opencode/blob/dev/packages/web/src/content/docs/cli.mdx) |
|
|
29
|
+
| OpenCode 2 | `opencode2`, beta-19157 or newer (including stable >=2.0.0) | OpenCode 2 official distribution | [v2 docs](https://opencode.ai/v2/docs/) |
|
|
30
|
+
| Pi Coding Agent | `pi`, >=0.85.1 | `@earendil-works/pi-coding-agent` | [Coding agent README](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/README.md) |
|
|
31
|
+
| OMP (oh-my-pi) | `omp`, >=18.1.11 | `@oh-my-pi/pi-coding-agent` | [Project](https://github.com/can1357/oh-my-pi) |
|
|
32
|
+
| DeepSeek Harness | `dsh`, >=0.1.2-rc.1 | `@deepseek-ai/dsh` | [CLI reference](https://github.com/deepseek-ai/deepseek-harness/blob/master/apps/cli/reference/README.md) |
|
|
33
|
+
| Cline | `cline`, >=3.0.61 | `cline` | [CLI project](https://github.com/cline/cline/tree/main/apps/cli) |
|
|
34
|
+
| Hermes Agent | `hermes`, >=0.21.0 | NousResearch Hermes Agent official installer | [Quick install](https://github.com/NousResearch/hermes-agent#quick-install) |
|
|
35
|
+
| Prime Agent | `prime-agent`, >=0.9.2 | PrimeIntellect versioned release artifact | [Project](https://github.com/PrimeIntellect-ai/prime-agent) |
|
|
36
|
+
| Gemini CLI | `gemini`, exactly 0.58.0 | `@google/gemini-cli` | [Project](https://github.com/google-gemini/gemini-cli) |
|
|
37
|
+
| Aider | `aider`, exactly 0.86.2 | `aider-chat` | [Installation](https://aider.chat/docs/install.html) |
|
|
38
|
+
| Kilo Code | `kilo`, >=7.5.15 | `@kilocode/cli` | [Release v7.5.15](https://github.com/Kilo-Org/kilocode/releases/tag/v7.5.15) |
|
|
39
|
+
|
|
40
|
+
For project distributions without a verified package command, follow the
|
|
41
|
+
linked upstream instructions and pass the resulting executable explicitly.
|
|
42
|
+
Launch rejects unsupported native versions before starting a coding session.
|
|
43
|
+
|
|
18
44
|
```sh
|
|
19
45
|
npm install -g @hasna/switcher
|
|
20
46
|
switcher --help
|
|
@@ -23,7 +49,10 @@ switcher doctor
|
|
|
23
49
|
|
|
24
50
|
## Direct launch
|
|
25
51
|
|
|
26
|
-
The direct launch flow is available from 0.1.1. Version 0.1.0 requires explicit API/provider/profile setup.
|
|
52
|
+
The direct launch flow is available from 0.1.1. The additional OMP, DeepSeek Harness, Cline, Hermes, Prime Agent, legacy OpenCode, Kilo, Gemini CLI and Aider adapters are introduced in 0.1.2. Version 0.1.0 requires explicit API/provider/profile setup.
|
|
53
|
+
|
|
54
|
+
Version 0.1.3 automatically injects model guidance and enforces allowed model IDs through a per-launch gateway. Native child and utility models default to your selected provider model. Use `--role-model ROLE=ID` or `--model-policy-file FILE` for explicit assignments, aliases and fallbacks. The full catalog stays visible; using another catalog entry requires an allowed assignment or a new launch. See [model policy](docs/MODEL-POLICY.md) for native role support, routing traces and enforcement scope.
|
|
55
|
+
|
|
27
56
|
|
|
28
57
|
Supply the provider key through environment injection (`DEEPSEEK_API_KEY`, `OPENROUTER_API_KEY`, or an explicit `SWITCHER_PROVIDER_*` reference), or configure a local credential binding below. Switcher never saves the value.
|
|
29
58
|
|
|
@@ -62,6 +91,15 @@ For provider keys already stored in macOS Keychain, use `--keychain-service SERV
|
|
|
62
91
|
|
|
63
92
|
`credentials list` displays bindings; `credentials remove PRESET_OR_REFERENCE` removes only the locator. Replacement requires explicit removal. Custom credential references require `--origin URL` (repeatable); preset bindings authorize their documented origins by default. `credentials check` reports availability, length and hash, not successful provider authentication. Provider credentials needed by a remote API's catalog discovery must still be configured on that server independently.
|
|
64
93
|
|
|
94
|
+
On Linux, use a vault binding without `--vault-account` and have your approved secret manager inject `HASNA_SECRETS_API_KEY` into each Switcher process. The binding records the vault URL and key locator; it stores no credential value. Alternatively, let the authenticated `secrets` CLI inject a provider credential for one command:
|
|
95
|
+
|
|
96
|
+
```sh
|
|
97
|
+
secrets exec providers/deepseek/live/api_key --as DEEPSEEK_API_KEY -- \
|
|
98
|
+
switcher launch claude --provider deepseek --model deepseek-v4-flash --dry-run
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Authenticate that Secrets process through your existing secret manager or service environment. `--dry-run` performs authenticated model discovery, creates provider/profile records as needed and returns a launch plan without starting the native harness or inference; remove it to launch. Every new process needs its own runtime injection. `credentials check` inspects configured bindings, not environment aliases. Keychain bindings are macOS-only; on Linux they fail with `keychain_unavailable` and recommend a vault binding or runtime environment. Native subscription/OAuth login is separate from Switcher's provider-key mode; Switcher does not import or reuse it.
|
|
102
|
+
|
|
65
103
|
## OpenCode 2 configuration
|
|
66
104
|
|
|
67
105
|
OpenCode 2 requires beta-19157 or newer. Each launch isolates its provider configuration, home, configuration directory and cache. Switcher snapshots native global and project tool permissions, safe agent prompts and permissions, and the global and working-directory ancestor `AGENTS.md` files. Provider/model overrides, agent request headers and bodies, plugins, and live configuration reloads are excluded. Unsupported permission forms, unreadable policy files and malformed JSONC or agent YAML stop the launch instead of dropping rules.
|
|
@@ -76,6 +114,87 @@ Pi 0.85.1 or newer supports all three wire protocols. Use `switcher launch pi --
|
|
|
76
114
|
|
|
77
115
|
Pi sessions persist under Switcher state per profile; pass native `--continue` or `--session PATH` after `--`. Each launch uses a temporary Pi agent directory. Global settings, keybindings, extensions, themes and skills are not loaded, and changes to that temporary configuration disappear at exit. Project customization follows Pi's native behavior.
|
|
78
116
|
|
|
117
|
+
## OMP
|
|
118
|
+
|
|
119
|
+
OMP 18.1.11 or newer supports the three Switcher wire protocols through its native `models.yml` provider API. Switcher writes a per-launch provider catalog and `config.yml` under `PI_CODING_AGENT_DIR`, selects the exact provider-qualified model, and keeps the API key in the child environment. OMP's native project instructions, tools and permissions stay enabled. Sessions persist under the profile's Switcher-owned `--session-dir`; model, provider, profile and config overrides are reserved by the launch profile.
|
|
120
|
+
|
|
121
|
+
## DeepSeek Harness
|
|
122
|
+
|
|
123
|
+
Use the official [`@deepseek-ai/dsh`](https://github.com/deepseek-ai/deepseek-harness) executable, version 0.1.2-rc.1 or newer, with its supported Node runtime. This is the native DeepSeek Harness, separate from Claude Code using a DeepSeek provider. Switcher supplies the full coding catalog through DSH's native `llm-pi-ai` adapter, supporting Chat Completions, Responses and Messages. The selected model becomes the default for new sessions; native model choices remain available within that catalog.
|
|
124
|
+
|
|
125
|
+
```sh
|
|
126
|
+
# Native browser UI, bound to an allocated loopback port.
|
|
127
|
+
switcher launch dsh --provider deepseek --model deepseek-v4-flash
|
|
128
|
+
# Print the authenticated local URL without opening a browser.
|
|
129
|
+
switcher launch dsh --provider deepseek --model deepseek-v4-flash -- --no-open
|
|
130
|
+
# Native one-shot task; headless has no resume flag.
|
|
131
|
+
switcher launch dsh --provider deepseek --model deepseek-v4-flash -- --profile headless "Inspect this project"
|
|
132
|
+
# Standard ACP over stdin/stdout for a programmatic client.
|
|
133
|
+
switcher launch dsh --provider deepseek --model deepseek-v4-flash -- --profile acp
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
DSH sessions and attachments persist under Switcher state per launch profile. Resume through the native browser UI or ACP `session/list` and `session/resume`; a resumed session retains its native conversation and model selection. Each launch uses a temporary DSH home. Existing global profiles, settings, plugins and saved credentials are not loaded, and edits to the temporary configuration disappear on exit. Project customization remains native. Native browser authentication uses a launch URL and a host/port-bound cookie; its own temporary signing grant is removed with that home. Provider keys remain environment references in configuration.
|
|
137
|
+
|
|
138
|
+
Only the shipped `web`, `headless` and `acp` profiles are supported. SDK initialization can mount a different provider independently of the launch profile, so SDK/custom profiles and arbitrary patches are rejected. Listener overrides are also rejected. Ori's `dsh` command performs setup only and is not accepted as a launch backend.
|
|
139
|
+
|
|
140
|
+
The opt-in `test:native-dsh` script runs the actual Switcher CLI and installed DSH against local inference fixtures, verifies a real file-read tool and second-process resume after deleting the file, and rejects model choices outside the catalog. `SWITCHER_TEST_DSH_PROTOCOL` selects a wire protocol, `SWITCHER_TEST_DSH_AUTH` selects `bearer`, `x-api-key` or `none`, and `SWITCHER_TEST_DSH_MODE=headless` checks the native one-shot path. `test:native-dsh-web` checks the browser catalog, authentication, Host/Origin protections and shutdown without opening a browser. Set `SWITCHER_TEST_DSH_EXECUTABLE` to the official executable and `SWITCHER_TEST_ROOT` to an owned scratch directory. These checks do not make paid provider calls.
|
|
141
|
+
|
|
142
|
+
## Aider
|
|
143
|
+
|
|
144
|
+
The direct Aider adapter is verified with `aider-chat` 0.86.2. Install that native Python application separately and select its executable if needed. Other versions, GUI mode and Ori launching are rejected. The GUI uses a different initialization path that defaults to blanket confirmation; this adapter preserves native CLI confirmations.
|
|
145
|
+
|
|
146
|
+
```sh
|
|
147
|
+
switcher launch aider --provider deepseek --model deepseek-v4-flash
|
|
148
|
+
# Native read-only context and a bounded request; confirmations remain native.
|
|
149
|
+
switcher launch aider --provider deepseek --model deepseek-v4-flash -- \
|
|
150
|
+
--read CONVENTIONS.md --file app.py --message "Implement the requested change."
|
|
151
|
+
# Continue the same profile's last closed conversation.
|
|
152
|
+
switcher launch aider --provider deepseek --model deepseek-v4-flash -- \
|
|
153
|
+
--restore-chat-history
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Aider uses native file context and text edit formats, rather than an autonomous file-read function tool. Text-input/output models can be selected without advertised function-tool support. Switcher registers the full catalog using `openai/ID`, `openai/responses/ID`, or `anthropic/ID`; these are Aider/LiteLLM transport names, and the provider receives its original model ID. All three protocols have installed-native edit/history fixture coverage. Chat and Messages support upstream streaming; Aider/LiteLLM buffers Responses requests even when native streaming is requested. `/models` and `--list-models` also enumerate built-in definitions; this is an available-model listing, not an isolated interactive picker. Use the full generated name with `/model`. Chat catalog IDs beginning `responses/` are rejected because LiteLLM reserves that prefix for a different transport. Responses IDs containing `responses/` are also rejected because LiteLLM removes those segments.
|
|
157
|
+
|
|
158
|
+
Every launch has a private home, configuration and cache. An authenticated loopback bridge owns the upstream key and admits only catalog model IDs. The native child receives only the temporary bridge token. Dotenv loading, provider credentials, aliases and model transport overrides are excluded; no provider key is written to native files. Original Git global configuration is loaded through Git include directives; global writes target a private file, retaining identity and repository policy. Ordinary global, Git-root and project Aider preferences retain native precedence; read-only paths using `~/` retain their original home meaning.
|
|
159
|
+
|
|
160
|
+
Preflight rejects conflicting configured startup commands, blanket approval, upgrade/test/lint/commit startup switches, ambiguous YAML/options, unreadable read-only context, custom model transport/callback settings, non-UTF-8 history and editable files belonging to a different Git root. Select the intended repository with `--cwd`. Explicit native task options and confirmations remain available. These checks do not sandbox concurrent project edits; keep native startup configuration unchanged while launching.
|
|
161
|
+
|
|
162
|
+
Aider has no session ID. Each launch writes a separate owner-only transcript under Switcher state, and `--restore-chat-history` copies the last closed conversation for that profile into a new transcript before native restoration. Concurrent runs keep independent history; diagnostic-only runs do not replace it. This does not import an existing standalone Aider transcript. Set `SWITCHER_TEST_AIDER_EXECUTABLE` and run `bun run test:native-aider` for controlled installed-native protocol, edit, history, catalog, hostile-routing and dry-run checks. Paid-provider, Linux and interactive-terminal acceptance remain separate gates.
|
|
163
|
+
|
|
164
|
+
## Gemini CLI
|
|
165
|
+
|
|
166
|
+
The native Gemini adapter supports exactly Gemini CLI 0.58.0 and the `gemini-generate-content` protocol with `x-api-key` authentication (the native wire header is `x-goog-api-key`). Use `switcher launch gemini --provider gemini --model MODEL`, selecting an ID from the discovered catalog. A compatible custom gateway must implement the same Gemini protocol and discovery contract. Chat Completions, OAuth, Vertex/ADC and Ori are separate interfaces and are not provided by this native adapter.
|
|
167
|
+
|
|
168
|
+
The API retains Gemini's full catalog and its documented `supportedGenerationMethods` metadata. Models that explicitly lack `generateContent`, such as embedding or prediction-only entries, are excluded from coding selections. Absent metadata remains unknown; support for `generateContent` alone does not establish text output or function-tool support. See the [Gemini model catalog contract](https://ai.google.dev/api/models).
|
|
169
|
+
|
|
170
|
+
Switcher holds the upstream key in an authenticated loopback bridge; the native CLI receives a temporary local token. The bridge accepts only catalog model IDs and the `generateContent`, `streamGenerateContent` and `countTokens` routes, preserves the configured deployment prefix, and cancels unfinished streams on exit. It does not allow a native client to replace the upstream endpoint or headers. Native helper requests for models outside the catalog fail closed.
|
|
171
|
+
|
|
172
|
+
Each launch gets private user, default and system settings. The complete compatible catalog replaces native picker visibility, and explicit model resolution preserves upstream IDs. Native profile sessions remain durable across fresh launches: pass `-- --resume latest --prompt PROMPT` for headless continuation. Concurrent launches share session storage but have separate configuration and native session IDs.
|
|
173
|
+
|
|
174
|
+
Workspace trust remains a native user decision; Switcher never enables it automatically. Original system/default/user settings, native user policies, project instructions and project permission handling remain active. Global Markdown context files and nested imports inside the original `.gemini` directory are copied with their import paths preserved. Context imports outside that directory, non-Markdown or nested global context filenames, symlinked configuration, and project policy paths using `~` fail explicitly; use ordinary Markdown names and explicit absolute policy paths. System/default/user and native `--policy` home paths retain their original home meaning. Private user settings, trust and policy changes disappear at exit; project changes remain native. Global extensions, custom agents, skills and keybindings are not copied into the private home.
|
|
175
|
+
|
|
176
|
+
Inherited nonempty `modelConfigs`, custom agent model transport settings and incompatible enforced authentication policies stop launch before catalog refresh or credential resolution. Keep routing configuration stable during launch; this preflight does not sandbox concurrent project edits. ACP is rejected because its client can replace authentication and routing. Normal native approval flags and literal prompt arguments remain available.
|
|
177
|
+
|
|
178
|
+
For local acceptance, set `SWITCHER_TEST_NATIVE_EXECUTABLE` to the installed Gemini executable and run `bun run test:native-gemini`. The fixture uses native plan permissions and a narrow trusted-folder entry for its owned project, verifies file reading, deleted-file resume, two concurrent sessions, global/project imports, user deny rules and cleanup. Set `SWITCHER_TEST_GEMINI_PACKAGE` to the official 0.58.0 package directory to run the native settings/catalog loader regression with `bun test`. Real-provider, interactive-terminal and Linux Gemini acceptance remain separate gates.
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
## Kilo
|
|
182
|
+
|
|
183
|
+
Kilo 7.5.15 or newer supports Chat Completions, Responses and Anthropic Messages through a scoped parent bridge. Use `switcher launch kilo --provider PROVIDER --model EXACT_MODEL`; pass native arguments after `--`. Switcher supplies the exact provider/model catalog and preserves supported project instructions and permission rules. Each launch uses a private native home/config/cache and profile session directory.
|
|
184
|
+
|
|
185
|
+
The upstream provider key stays in the Switcher bridge; Kilo receives only a short-lived local token. Kilo 7.5.15 can load legacy project MCP configuration, and those trusted MCP processes may inherit that scoped bridge capability. This adapter does not claim a complete MCP sandbox. Conflicting native provider/model/endpoint/auth flags, unsupported policy forms, remote instruction URLs and system-managed configuration are rejected before native launch.
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
## Cline, Hermes and Prime Agent
|
|
189
|
+
|
|
190
|
+
Use `switcher launch cline`, `switcher launch hermes` or `switcher launch prime-agent` with the same `--provider` and `--model` options. These adapters support Chat, Responses and Messages with full provider catalogs and per-profile native history. Cline requires 3.0.61 or newer, Hermes 0.21.0 or newer and Prime Agent 0.9.2 or newer.
|
|
191
|
+
|
|
192
|
+
Cline uses its native ACP backend with per-launch configuration, durable sessions and native permission requests. Hermes uses its native custom-provider interface and keeps `state.db` and sessions under profile state; its model menu also retains built-in free-provider/MOA entries. Prime keeps its foreground supervisor and workers within the launch lifetime. It automatically chooses a shorter private runtime directory if the system temporary path cannot hold native Unix sockets. Native history and resume remain profile-specific.
|
|
193
|
+
|
|
194
|
+
## Legacy OpenCode
|
|
195
|
+
|
|
196
|
+
`switcher launch opencode --provider PROVIDER --model MODEL` selects legacy OpenCode 1.18.0 or newer, tested with 1.18.29. It is distinct from `opencode2` and uses the legacy singular-provider configuration schema. The adapter supplies the provider catalog, preserves supported native instructions and permission rules, and stores sessions per profile. Chat, Responses and Messages have controlled native tool/read/resume coverage. Use native `models` for its full provider-qualified catalog; visual picker acceptance is recorded separately.
|
|
197
|
+
|
|
79
198
|
## Run a persistent service
|
|
80
199
|
|
|
81
200
|
Inject a random operator token of at least 24 characters as `HASNA_SWITCHER_API_KEY` through your secret manager. Inject provider credentials separately, using names beginning `SWITCHER_PROVIDER_`. Only environment references are persisted. Explicitly hosted servers read `SWITCHER_PROVIDER_*` references; the local launcher also accepts the standard aliases declared by each built-in preset.
|
|
@@ -110,10 +229,16 @@ switcher launch coding
|
|
|
110
229
|
|
|
111
230
|
The model ID is an example; choose an exact ID from the current catalog and verify account access. Use `--url https://provider.example/api/v1` instead of the preset for any compatible endpoint. The base URL includes the provider API version/path. Presets declare the appropriate discovery URL separately; DeepSeek discovers models at its root while Messages inference uses its Anthropic path. Select a separate provider profile for each wire protocol. The launch adapters normalize native endpoint conventions.
|
|
112
231
|
|
|
113
|
-
For Claude use `--harness claude` with `anthropic-messages`; for Grok or OpenCode 2 use their supported protocol. Pass native arguments after `--`, such as `switcher launch coding -- exec "Reply with exactly: connected"`. `--backend direct` is the default; the optional `--backend ori` is OpenRouter-only and accepts `--ori-executable PATH`, while `--executable` remains the direct adapter option. `--cwd`, `--state-dir`, and `--timeout SECONDS` are local launcher options. Native approval and sandbox settings remain in effect. See [the Ori backend contract](docs/ori-backend-integration.md) for its supported target and catalog boundaries.
|
|
232
|
+
For Claude use `--harness claude` with `anthropic-messages`; for Grok, Hermes or OpenCode 2 use their supported protocol. Pass native arguments after `--`, such as `switcher launch coding -- exec "Reply with exactly: connected"`. `--backend direct` is the default; the optional `--backend ori` is OpenRouter-only and accepts `--ori-executable PATH`, while `--executable` remains the direct adapter option. `--cwd`, `--state-dir`, and `--timeout SECONDS` are local launcher options. Native approval and sandbox settings remain in effect. See [the Ori backend contract](https://github.com/hasna/apps/blob/main/apps/switcher/docs/ori-backend-integration.md) for its supported target and catalog boundaries.
|
|
114
233
|
|
|
115
234
|
When the API runs remotely, inject the provider credential into the API process for authenticated catalog discovery and into the local launcher for direct inference. The API never returns a provider key. An external compatible gateway can be the configured provider. Switcher does not translate between wire protocols.
|
|
116
235
|
|
|
236
|
+
## Catalog refresh and offline use
|
|
237
|
+
|
|
238
|
+
`switcher models PROVIDER` reads an existing stored catalog without contacting the provider. When no catalog exists, it discovers one. `--refresh` and every `launch` request fetch the upstream catalog. Failed refreshes preserve the previous snapshot, but launch fails instead of silently using that snapshot. API launch plans warn when their catalog is more than five minutes old.
|
|
239
|
+
|
|
240
|
+
Discovery allows at most two retries per page for network failures and HTTP 408, 425, 429, 500, 502, 503 or 504. A request has a 20-second limit and the refresh has a 60-second aggregate limit. Valid numeric or HTTP-date `Retry-After` values are honored; a delay beyond the remaining budget fails immediately. Otherwise, retry delays are 100 ms and 200 ms. Redirects and other HTTP failures are terminal. Existing limits remain 16 MiB per response, 100 pages and 10,000 unique models. Credentials, origin restrictions and parser validation stay the same on every retry.
|
|
241
|
+
|
|
117
242
|
## Optional Ori backend
|
|
118
243
|
|
|
119
244
|
`switcher launch codex --provider openrouter --model MODEL --backend ori` uses installed Ori 0.12.x. Add `--ori-executable PATH` to choose its installation. `--dry-run` validates the Ori contract without resolving a launch credential. The Codex picker uses Switcher's complete compatible catalog. Grok is supported through Ori's Chat route and its entitled OpenRouter catalog. Direct adapters remain the default. Ori launches reject other provider authorities, Claude's global-configuration mutations, and the legacy OpenCode target; use the direct Claude and OpenCode 2 adapters. Ori live acceptance remains tracked separately from fixture checks.
|
|
@@ -122,12 +247,22 @@ When the API runs remotely, inject the provider credential into the API process
|
|
|
122
247
|
|
|
123
248
|
| Harness | Required wire protocol | Native catalog |
|
|
124
249
|
| --- | --- | --- |
|
|
125
|
-
| Claude Code ≥2.1.
|
|
250
|
+
| Claude Code ≥2.1.257 | Anthropic Messages | Per-launch `modelPicker` on compatible Claude versions |
|
|
126
251
|
| Codex ≥0.153.0 | OpenAI Responses | Startup `model_catalog_json` |
|
|
127
252
|
| Grok Build ≥1.0.13 | Chat Completions, Responses or Messages | Authenticated loopback remote catalog with upstream model IDs |
|
|
128
253
|
| OpenCode 2 (tested beta-19157) | Chat Completions, Responses or Messages | Version 2 provider/model configuration and standalone server |
|
|
129
|
-
|
|
130
|
-
|
|
254
|
+
| Pi ≥0.85.1 | Chat, Responses, Messages | Provider-scoped native picker and model cycling |
|
|
255
|
+
| OMP ≥18.1.11 | Chat, Responses, Messages | Native models.yml catalog and model roles |
|
|
256
|
+
| DeepSeek Harness ≥0.1.2-rc.1 | Chat, Responses, Messages | Native web/ACP catalog |
|
|
257
|
+
| Cline ≥3.0.61 | Chat, Responses, Messages | Native ACP model catalog and session selection |
|
|
258
|
+
| Hermes ≥0.21.0 | Chat, Responses, Messages | Selected-provider catalog; built-in menu rows also remain |
|
|
259
|
+
| Prime Agent ≥0.9.2 | Chat, Responses, Messages | Native catalog, RPC selection and owned supervisor |
|
|
260
|
+
| Legacy OpenCode (tested 1.18.29) | Chat, Responses, Messages | Singular-provider models and native diagnostic |
|
|
261
|
+
| Kilo ≥7.5.15 | Chat, Responses, Messages | Native provider catalog with scoped bridge |
|
|
262
|
+
| Gemini CLI 0.58.0 | Gemini generateContent | Exact native dynamic model catalog |
|
|
263
|
+
| Aider 0.86.2 | Chat, Responses, Messages | Native available-model listing; Responses is buffered |
|
|
264
|
+
|
|
265
|
+
The CLI catalog includes all provider output modalities. Native coding pickers exclude unavailable models and those explicitly lacking a required generation method, text output or tool support; unknown metadata remains unknown. This is a capability filter, not a guarantee of successful tool use. Catalog refresh happens before every launch. Native pickers are startup snapshots, not promised live reloads. OpenCode requires a complete capability object; missing fields use text-only/tool-enabled native defaults with a warning. Its beta `models --standalone` command may return an early empty snapshot; the native `/api/model` API and interactive picker expose the settled catalog.
|
|
131
266
|
|
|
132
267
|
The Claude adapter sets `ANTHROPIC_DEFAULT_MODEL` and the default subagent model to the selected provider model. Explicit subagent definitions and managed model restrictions still apply. These follow the [native model precedence rules](https://code.claude.com/docs/en/model-config).
|
|
133
268
|
|
|
@@ -137,6 +272,8 @@ For a provider without discovery, use `providers add ID --file provider.json` wi
|
|
|
137
272
|
|
|
138
273
|
Grok uses a per-launch authenticated loopback bridge because its environment overlay cannot define providers. The bridge serves model metadata and forwards the selected protocol unchanged. It holds upstream credentials only in memory; Grok receives an ephemeral local token. The same bridge handles credentialless endpoints and OpenCode auth-header mismatches. Bridged requests are limited to 4 MiB and four minutes. Grok resumes retain the selected profile model. Use `-- --resume SESSION_ID -p PROMPT` for headless continuation, or omit the prompt and type after the interactive session loads. Interactive resume with an inline positional prompt is rejected because the native client can send it before applying the selected model. Grok 1.0.13 passed source and installed development CLI resume checks against a controlled Messages fixture and live DeepSeek Flash. OpenCode's provider identity stays stable across temporary bridge ports; `-- run --session SESSION_ID PROMPT` resumes with fresh launch settings. The installed beta-19157 passed two-process Messages resume checks against a controlled local upstream and live DeepSeek Flash, including a proof-file read and preserved history. Other provider/protocol and registry-release cells remain tracked separately in COMPATIBILITY.md.
|
|
139
274
|
|
|
275
|
+
Hermes uses the same loopback boundary with its documented `custom` provider. The bridge exposes only the Switcher catalog, translates the selected provider's Bearer, `x-api-key` or literal `api-key` credential, and forwards deployment prefixes unchanged. Hermes `state.db` and `sessions/` are linked to a profile-owned stable directory for resume; generated config and bridge credentials remain per-launch. Focused bridge tests cover all three native protocol routes and auth styles, including cleanup of an active stream without caller cancellation. Run `bun scripts/test-native-hermes.ts` with `SWITCHER_TEST_HERMES_EXECUTABLE` for the installed native CLI fixture proof, which performs a real `read_file` loop and deleted-file resume against a generic preset.
|
|
276
|
+
|
|
140
277
|
Native history and credentials stay with the harness. Resume only with the same profile/provider/model configuration unless the harness explicitly supports a change; cross-provider reasoning/session migration is not provided. Temporary nonsecret picker/config files are removed when the child exits. Run records contain launch/end metadata and initial model, not transcripts or a claim about later native picker selections.
|
|
141
278
|
|
|
142
279
|
## SDK and API
|
|
@@ -154,6 +291,8 @@ console.log(plan.catalog.models.length);
|
|
|
154
291
|
|
|
155
292
|
The SDK supports Node and Bun. It has no database or launcher imports. Explicit credentials may be supplied as a string or a fresh resolver function; `clientFromEnv()` uses the shared contracts resolver with environment-only inputs and no disk fallback.
|
|
156
293
|
|
|
294
|
+
SDK and CLI API-error diagnostics validate code/request-ID fields, bound message length, remove terminal control characters, and redact the operator credential actually sent with that request. Redaction covers raw, JSON-string-escaped, URL-encoded and Base64/Base64url representations. Native harness stdout and terminal output remain under the native client's control.
|
|
295
|
+
|
|
157
296
|
Public lifecycle endpoints: `GET /health`, `/ready`, `/version`. Authenticated OpenAPI: `GET /v1/openapi.json`. Provider/profile CRUD, `/v1/provider-presets`, catalog list/refresh, launch-plan validation and run metadata are under `/v1`. The SDK includes `listProviderPresets()`, `getProviderPreset()`, `health()`, `ready()`, and `version()`. SDK types are generated from that OpenAPI document. API errors include code, message and request ID.
|
|
158
297
|
|
|
159
298
|
All mutations require `Idempotency-Key`. Reuse the same key and payload after an uncertain response; changing the payload returns 409. Updates/deletes also require the numeric record version in `If-Match`. SDK methods supply these headers and accept a caller-provided idempotency key. Run creation requires the `planToken` from a launch plan; a changed provider, profile or catalog rejects the stale plan with 409 before local execution. List endpoints accept `limit` (1–1000), `offset` and `search`. Referenced providers/profiles cannot be deleted while children exist.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { HarnessLaunchInput, PreparedLaunch } from "./harness-types";
|
|
2
|
+
type Config = Record<string, unknown>;
|
|
3
|
+
export declare function validateAiderConfiguration(cwd: string, args?: readonly string[], home?: string): Promise<Config>;
|
|
4
|
+
export declare function aiderModelName(protocol: HarnessLaunchInput["protocol"], id: string): string;
|
|
5
|
+
export declare function prepareAider(input: HarnessLaunchInput): Promise<PreparedLaunch>;
|
|
6
|
+
export {};
|
package/dist/auth.d.ts
ADDED