opencode-switch-cli 1.0.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 ADDED
@@ -0,0 +1,376 @@
1
+ # opencode-switch
2
+
3
+ CLI and programmatic utilities for managing OpenCode providers, model mappings, and API key aliases.
4
+
5
+ `opencode-switch` keeps your real OpenCode provider configuration in sync while storing its own management metadata separately. It is useful when you want to:
6
+
7
+ - register multiple OpenCode-compatible vendors
8
+ - map stable model types such as `gpt-5.4` and `gemini` to real upstream model IDs
9
+ - maintain multiple API keys per vendor/model pair
10
+ - switch the active vendor or active key without editing JSON files by hand
11
+
12
+ ## Features
13
+
14
+ - interactive shortcuts for common workflows
15
+ - explicit `vendor`, `model`, and `key` subcommands for scripting
16
+ - deterministic updates to OpenCode `model` and `small_model` pointers
17
+ - separate metadata storage for active vendor, managed models, and key aliases
18
+ - programmatic API exports for embedding the workflow in your own tools
19
+
20
+ ## Requirements
21
+
22
+ - Node.js `>= 18.18.0`
23
+ - An existing OpenCode setup, or permission to create files under `~/.config/opencode`
24
+
25
+ ## Installation
26
+
27
+ Install globally:
28
+
29
+ ```bash
30
+ npm install -g opencode-switch-cli
31
+ ```
32
+
33
+ Or run without installing:
34
+
35
+ ```bash
36
+ npx opencode-switch-cli vendor list
37
+ ```
38
+
39
+ ## Files managed by the CLI
40
+
41
+ `opencode-switch` manages two files under `~/.config/opencode`:
42
+
43
+ ### `opencode.json`
44
+
45
+ This is the real OpenCode config file. Providers are written under:
46
+
47
+ ```json
48
+ {
49
+ "provider": {
50
+ "duck": {
51
+ "name": "duck",
52
+ "npm": "@ai-sdk/openai-compatible",
53
+ "options": {
54
+ "baseURL": "https://duck.example.com/v1",
55
+ "apiKey": "duck-key"
56
+ },
57
+ "models": {
58
+ "gpt-5.4": {
59
+ "name": "duck/gpt-5.4"
60
+ }
61
+ }
62
+ }
63
+ },
64
+ "model": "duck/gpt-5.4",
65
+ "small_model": "duck/gemini"
66
+ }
67
+ ```
68
+
69
+ ### `opencode-switch.json`
70
+
71
+ This file stores switch-specific metadata such as:
72
+
73
+ - active vendor
74
+ - managed providers
75
+ - managed model registry
76
+ - active key alias per model
77
+ - stored key aliases and credentials
78
+
79
+ ## Quick start
80
+
81
+ ### 1. Add a vendor
82
+
83
+ ```bash
84
+ opencode-switch vendor add duck \
85
+ --npm @ai-sdk/openai-compatible \
86
+ --base-url https://duck.example.com/v1 \
87
+ --api-key duck-key
88
+ ```
89
+
90
+ ### 2. Add models for that vendor
91
+
92
+ Supported model types are currently:
93
+
94
+ - `gpt-5.4`
95
+ - `gemini`
96
+
97
+ ```bash
98
+ opencode-switch model add duck gpt-5.4 --model duck/gpt-5.4
99
+ opencode-switch model add duck gemini --model google/gemini-2.5-flash
100
+ ```
101
+
102
+ ### 3. Add one or more key aliases
103
+
104
+ ```bash
105
+ opencode-switch key add duck gpt-5.4 project-a --api-key duck-project-a-key
106
+ opencode-switch key add duck gpt-5.4 project-b --api-key duck-project-b-key
107
+ ```
108
+
109
+ The first key added for a `vendor + modelType` becomes the active key by default.
110
+
111
+ ### 4. Switch the active vendor
112
+
113
+ ```bash
114
+ opencode-switch vendor use duck
115
+ ```
116
+
117
+ This updates OpenCode pointers deterministically:
118
+
119
+ - `model` prefers `vendor/gpt-5.4` when available
120
+ - `small_model` prefers `vendor/gemini` when available
121
+ - if the active primary model has an active key alias, the provider `apiKey` is updated too
122
+
123
+ ## Interactive shortcuts
124
+
125
+ These commands are useful for manual day-to-day operations:
126
+
127
+ ```bash
128
+ opencode-switch ls
129
+ opencode-switch add duck https://duck.example.com/v1
130
+ opencode-switch rm
131
+ opencode-switch addk
132
+ opencode-switch switch
133
+ opencode-switch rmk
134
+ ```
135
+
136
+ ### Shortcut behavior
137
+
138
+ - `ls` shows vendors in a dashboard-style list.
139
+ - `add <name> <url>` adds a vendor using the default npm package `@ai-sdk/openai`.
140
+ - `rm` opens an interactive vendor picker and confirmation step.
141
+ - `addk` walks through vendor -> model -> new key creation, and can create a missing model first.
142
+ - `switch` walks through vendor -> model -> existing key selection and activates the chosen key.
143
+ - `rmk` walks through vendor -> model -> key selection before deletion.
144
+
145
+ ## Command reference
146
+
147
+ ### Vendor commands
148
+
149
+ Add a vendor:
150
+
151
+ ```bash
152
+ opencode-switch vendor add <vendorName> \
153
+ --npm <npmPackage> \
154
+ [--base-url <baseUrl>] \
155
+ [--api-key <apiKey>]
156
+ ```
157
+
158
+ Example:
159
+
160
+ ```bash
161
+ opencode-switch vendor add duck \
162
+ --npm @ai-sdk/openai-compatible \
163
+ --base-url https://duck.example.com/v1 \
164
+ --api-key duck-key
165
+ ```
166
+
167
+ List vendors:
168
+
169
+ ```bash
170
+ opencode-switch vendor list
171
+ ```
172
+
173
+ Switch the active vendor:
174
+
175
+ ```bash
176
+ opencode-switch vendor use duck
177
+ ```
178
+
179
+ Remove a vendor:
180
+
181
+ ```bash
182
+ opencode-switch vendor remove duck
183
+ ```
184
+
185
+ ### Model commands
186
+
187
+ Add a model mapping:
188
+
189
+ ```bash
190
+ opencode-switch model add <vendorName> <modelType> --model <realModel>
191
+ ```
192
+
193
+ Examples:
194
+
195
+ ```bash
196
+ opencode-switch model add duck gpt-5.4 --model duck/gpt-5.4
197
+ opencode-switch model add duck gemini --model google/gemini-2.5-flash
198
+ ```
199
+
200
+ List models for a vendor:
201
+
202
+ ```bash
203
+ opencode-switch model list duck
204
+ ```
205
+
206
+ Remove a model mapping:
207
+
208
+ ```bash
209
+ opencode-switch model remove duck gpt-5.4
210
+ ```
211
+
212
+ ### Key commands
213
+
214
+ Add a key alias:
215
+
216
+ ```bash
217
+ opencode-switch key add <vendorName> <modelType> <keyAlias> --api-key <apiKey> [--base-url <baseUrl>]
218
+ ```
219
+
220
+ Example:
221
+
222
+ ```bash
223
+ opencode-switch key add duck gpt-5.4 project-a --api-key duck-project-a-key
224
+ ```
225
+
226
+ List keys for a vendor/model pair:
227
+
228
+ ```bash
229
+ opencode-switch key list duck gpt-5.4
230
+ ```
231
+
232
+ Switch the active key alias:
233
+
234
+ ```bash
235
+ opencode-switch key use duck gpt-5.4 project-a
236
+ ```
237
+
238
+ Remove a key alias:
239
+
240
+ ```bash
241
+ opencode-switch key remove duck gpt-5.4 project-a
242
+ ```
243
+
244
+ ## Behavior notes
245
+
246
+ - Unsupported model types are rejected. Right now only `gpt-5.4` and `gemini` are valid.
247
+ - `model list <vendorName>` includes the active key alias when one is set.
248
+ - `key use` changes the active key only for the selected `vendor + modelType` pair.
249
+ - `vendor use` updates OpenCode's default pointers based on available managed models.
250
+ - Removing a vendor also removes its switch metadata and clears OpenCode pointers that referenced it.
251
+ - Existing provider options and model template metadata are preserved where possible.
252
+
253
+ ## Programmatic API
254
+
255
+ The package also exports reusable functions from `dist/index.js` / `dist/index.mjs`.
256
+
257
+ ### Exported functions
258
+
259
+ ```ts
260
+ import {
261
+ createJsonFileStore,
262
+ createModelService,
263
+ createOpencodeRepository,
264
+ createSwitchRepository,
265
+ createVendorService,
266
+ executeCli,
267
+ SUPPORTED_MODEL_TYPES,
268
+ } from 'opencode-switch-cli';
269
+ ```
270
+
271
+ ### Example: create repositories and services
272
+
273
+ ```ts
274
+ import os from 'node:os';
275
+ import path from 'node:path';
276
+
277
+ import {
278
+ createJsonFileStore,
279
+ createModelService,
280
+ createOpencodeRepository,
281
+ createSwitchRepository,
282
+ createVendorService,
283
+ } from 'opencode-switch-cli';
284
+
285
+ const homeDir = os.homedir();
286
+ const configDir = path.join(homeDir, '.config', 'opencode');
287
+ const jsonStore = createJsonFileStore();
288
+
289
+ const opencodeRepository = createOpencodeRepository({
290
+ filePath: path.join(configDir, 'opencode.json'),
291
+ jsonStore,
292
+ });
293
+
294
+ const switchRepository = createSwitchRepository({
295
+ filePath: path.join(configDir, 'opencode-switch.json'),
296
+ jsonStore,
297
+ });
298
+
299
+ const vendorService = createVendorService({
300
+ opencodeRepository,
301
+ switchRepository,
302
+ });
303
+
304
+ const modelService = createModelService({
305
+ opencodeRepository,
306
+ switchRepository,
307
+ });
308
+
309
+ await vendorService.addVendor({
310
+ vendorName: 'duck',
311
+ npm: '@ai-sdk/openai-compatible',
312
+ baseURL: 'https://duck.example.com/v1',
313
+ });
314
+
315
+ await modelService.addModel({
316
+ vendorName: 'duck',
317
+ modelType: 'gpt-5.4',
318
+ realModel: 'duck/gpt-5.4',
319
+ });
320
+ ```
321
+
322
+ ### Example: execute the CLI programmatically
323
+
324
+ ```ts
325
+ import { executeCli } from 'opencode-switch-cli';
326
+
327
+ const result = await executeCli(['vendor', 'list']);
328
+
329
+ console.log(result.exitCode);
330
+ console.log(result.stdout);
331
+ console.error(result.stderr);
332
+ ```
333
+
334
+ ## Local development
335
+
336
+ Install dependencies:
337
+
338
+ ```bash
339
+ npm install
340
+ ```
341
+
342
+ Run the CLI in development mode:
343
+
344
+ ```bash
345
+ npm run dev -- vendor list
346
+ ```
347
+
348
+ Run verification:
349
+
350
+ ```bash
351
+ npm test
352
+ npm run typecheck
353
+ npm run build
354
+ ```
355
+
356
+ ## Publishing to npm
357
+
358
+ The package is already configured with a `prepublishOnly` script:
359
+
360
+ ```bash
361
+ npm run test && npm run typecheck && npm run build
362
+ ```
363
+
364
+ When you are ready to release:
365
+
366
+ ```bash
367
+ npm login
368
+ npm version patch
369
+ npm publish
370
+ ```
371
+
372
+ If this is the first release for the package name, make sure the package name is available and that you are logged into the correct npm account before publishing.
373
+
374
+ ## License
375
+
376
+ MIT
package/dist/bin.d.mts ADDED
@@ -0,0 +1,2 @@
1
+
2
+ export { }
package/dist/bin.d.ts ADDED
@@ -0,0 +1,2 @@
1
+
2
+ export { }