@minniexcode/codex-switch 0.0.11 → 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/README.AI.md +110 -152
- package/README.CN.md +179 -215
- package/README.md +183 -217
- package/dist/app/add-provider.js +9 -3
- package/dist/app/edit-provider.js +17 -3
- package/dist/app/get-status.js +8 -3
- package/dist/app/list-providers.js +48 -1
- package/dist/app/run-doctor.js +4 -0
- package/dist/cli/output.js +153 -18
- package/dist/commands/handlers.js +10 -6
- package/dist/commands/help.js +9 -5
- package/dist/commands/registry.js +22 -14
- package/dist/domain/config.js +26 -1
- package/dist/domain/providers.js +16 -0
- package/dist/domain/runtime-state.js +30 -8
- package/dist/infra/config-repo.js +16 -206
- package/dist/interaction/interactive.js +16 -6
- package/dist/runtime/copilot-bridge.js +2 -1
- package/dist/storage/config-repo.js +0 -23
- package/docs/Design/codex-switch-v0.0.12-design.md +343 -0
- package/docs/Design/codex-switch-v0.1.0-design.md +152 -0
- package/docs/PRD/codex-switch-prd-v0.0.12.md +279 -0
- package/docs/PRD/codex-switch-prd-v0.1.0.md +217 -317
- package/docs/Tests/testing.md +31 -151
- package/docs/cli-usage.md +223 -524
- package/docs/codex-switch-command-design.md +649 -646
- package/docs/codex-switch-product-overview.md +86 -241
- package/docs/codex-switch-technical-architecture.md +1115 -1112
- package/package.json +51 -51
- package/dist/app/rollback-latest.js +0 -26
package/README.md
CHANGED
|
@@ -1,217 +1,183 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
It
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
##
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
codexs
|
|
52
|
-
codexs
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
codexs
|
|
82
|
-
codexs
|
|
83
|
-
codexs
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
codexs
|
|
90
|
-
codexs
|
|
91
|
-
codexs
|
|
92
|
-
codexs
|
|
93
|
-
codexs
|
|
94
|
-
codexs
|
|
95
|
-
codexs status
|
|
96
|
-
codexs
|
|
97
|
-
codexs
|
|
98
|
-
codexs
|
|
99
|
-
codexs
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
- pass all required arguments explicitly in scripts or CI
|
|
185
|
-
- use `--codex-dir <path>` for sandbox or test environments
|
|
186
|
-
- use `CODEXS_HOME` when you want tool state isolated from your default workstation setup
|
|
187
|
-
|
|
188
|
-
## Testing
|
|
189
|
-
|
|
190
|
-
Build and test locally:
|
|
191
|
-
|
|
192
|
-
```bash
|
|
193
|
-
npm run build
|
|
194
|
-
npm test
|
|
195
|
-
npx tsc --noEmit
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
The repository includes a development fixture under `dev-codex/local-sandbox` plus dedicated test docs:
|
|
199
|
-
|
|
200
|
-
- [Testing Guide](./docs/Tests/testing.md)
|
|
201
|
-
- [Bridge Testing Notes](./docs/Tests/testing-bridge-v0.0.9.md)
|
|
202
|
-
- [Test Report for 0.0.7](./docs/Tests/test-report-0.0.7.md)
|
|
203
|
-
|
|
204
|
-
## Documentation
|
|
205
|
-
|
|
206
|
-
- [Chinese README](./README.CN.md)
|
|
207
|
-
- [AI README](./README.AI.md)
|
|
208
|
-
- [Detailed CLI Usage](./docs/cli-usage.md)
|
|
209
|
-
- [Testing Guide](./docs/Tests/testing.md)
|
|
210
|
-
- [Product Overview](./docs/codex-switch-product-overview.md)
|
|
211
|
-
- [Technical Architecture](./docs/codex-switch-technical-architecture.md)
|
|
212
|
-
- [PRD 0.0.11](./docs/PRD/codex-switch-prd-v0.0.11.md)
|
|
213
|
-
- [Design Doc 0.0.11](./docs/Design/codex-switch-v0.0.11-design.md)
|
|
214
|
-
|
|
215
|
-
## License
|
|
216
|
-
|
|
217
|
-
MIT
|
|
1
|
+
# @minniexcode/codex-switch
|
|
2
|
+
|
|
3
|
+
`@minniexcode/codex-switch` is a local-first CLI for managing and switching Codex provider and profile configuration safely.
|
|
4
|
+
|
|
5
|
+
It keeps `codex-switch` tool state separate from the target Codex runtime, so provider management, backup flow, and runtime projection stay explicit instead of relying on manual file edits.
|
|
6
|
+
|
|
7
|
+
Chinese version: [README.CN.md](./README.CN.md)
|
|
8
|
+
|
|
9
|
+
## Version
|
|
10
|
+
|
|
11
|
+
Current package version: `0.1.0`
|
|
12
|
+
|
|
13
|
+
This is the first stable release line. The current release focuses on keeping the primary workflows, help text, operational boundaries, and release docs aligned with the implementation.
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install -g @minniexcode/codex-switch
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Run without a global install:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npx @minniexcode/codex-switch --help
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Built CLI entrypoint:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
codexs --help
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Primary Workflows
|
|
34
|
+
|
|
35
|
+
Direct provider workflow:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
codexs init
|
|
39
|
+
codexs add my-provider --profile my-provider --api-key sk-xxx
|
|
40
|
+
codexs switch my-provider
|
|
41
|
+
codexs status
|
|
42
|
+
codexs doctor
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
GitHub Copilot workflow:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
codexs init
|
|
49
|
+
codexs login copilot
|
|
50
|
+
codexs add copilot-main --copilot --profile copilot-main
|
|
51
|
+
codexs switch copilot-main
|
|
52
|
+
codexs status
|
|
53
|
+
codexs doctor
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Notes:
|
|
57
|
+
|
|
58
|
+
- `init` prepares the `codex-switch` tool home and managed state.
|
|
59
|
+
- `login copilot` handles upstream Copilot onboarding and auth readiness.
|
|
60
|
+
- `add --copilot` does not perform login for you; it assumes Copilot login is already ready.
|
|
61
|
+
- `status` is the main read command after switching.
|
|
62
|
+
- `doctor` is the main repair-oriented diagnostic command.
|
|
63
|
+
|
|
64
|
+
## Advanced Adopt Workflow
|
|
65
|
+
|
|
66
|
+
Use `migrate` only when you already have Codex runtime state that should be adopted into managed `providers.json` state:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
codexs init
|
|
70
|
+
codexs migrate
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
`migrate` is an advanced adopt helper. It is not the default first step for a fresh install.
|
|
74
|
+
|
|
75
|
+
## Command Surface
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
codexs init
|
|
79
|
+
codexs login copilot
|
|
80
|
+
codexs migrate
|
|
81
|
+
codexs list
|
|
82
|
+
codexs show <provider>
|
|
83
|
+
codexs current
|
|
84
|
+
codexs status
|
|
85
|
+
codexs config show [profile]
|
|
86
|
+
codexs config list-profiles
|
|
87
|
+
codexs add <provider> --profile <name> --api-key <key>
|
|
88
|
+
codexs add <provider> --copilot --profile <name>
|
|
89
|
+
codexs edit <provider>
|
|
90
|
+
codexs switch <provider>
|
|
91
|
+
codexs remove <provider> [--force] [--switch-to <profile>]
|
|
92
|
+
codexs import <file>
|
|
93
|
+
codexs export <file> [--force]
|
|
94
|
+
codexs bridge start [provider]
|
|
95
|
+
codexs bridge status [provider]
|
|
96
|
+
codexs bridge stop [provider]
|
|
97
|
+
codexs backups list
|
|
98
|
+
codexs rollback [backup-id]
|
|
99
|
+
codexs doctor
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
`setup` still exists only as a deprecated compatibility entry that points callers to `init` or `migrate`.
|
|
103
|
+
|
|
104
|
+
## Runtime Model
|
|
105
|
+
|
|
106
|
+
`codex-switch` uses a dual-path model.
|
|
107
|
+
|
|
108
|
+
Tool home:
|
|
109
|
+
|
|
110
|
+
```text
|
|
111
|
+
~/.config/codex-switch/
|
|
112
|
+
codex-switch.json
|
|
113
|
+
providers.json
|
|
114
|
+
backups/
|
|
115
|
+
runtime/
|
|
116
|
+
runtimes/
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Target Codex runtime:
|
|
120
|
+
|
|
121
|
+
```text
|
|
122
|
+
~/.codex/
|
|
123
|
+
config.toml
|
|
124
|
+
auth.json
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Key points:
|
|
128
|
+
|
|
129
|
+
- `providers.json` is the managed provider registry and lives under the tool home.
|
|
130
|
+
- `codex-switch.json` stores tool-level metadata such as `defaultCodexDir`.
|
|
131
|
+
- `config.toml` remains the active runtime routing file in the target Codex directory.
|
|
132
|
+
- `auth.json` remains the active auth projection file in the target Codex directory.
|
|
133
|
+
- Direct providers rewrite `OPENAI_API_KEY` into the active runtime projection.
|
|
134
|
+
- Copilot providers keep upstream GitHub authentication in the official Copilot runtime while `codex-switch` manages local bridge state and routing.
|
|
135
|
+
|
|
136
|
+
Path controls:
|
|
137
|
+
|
|
138
|
+
- `--codex-dir <path>` targets a specific Codex runtime directory.
|
|
139
|
+
- `CODEXS_CODEX_DIR` provides the default target runtime when `--codex-dir` is not passed.
|
|
140
|
+
- `CODEXS_HOME` overrides the tool home location.
|
|
141
|
+
|
|
142
|
+
## Automation Notes
|
|
143
|
+
|
|
144
|
+
This CLI supports both human TTY usage and non-interactive automation.
|
|
145
|
+
|
|
146
|
+
Global flags:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
--json
|
|
150
|
+
--codex-dir <path>
|
|
151
|
+
--help
|
|
152
|
+
--version
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Operational limits:
|
|
156
|
+
|
|
157
|
+
- `login copilot` requires a real TTY and does not support `--json`.
|
|
158
|
+
- `migrate` remains interactive when provider adoption requires human input.
|
|
159
|
+
- Automation should pass explicit arguments and prefer `--json` for stable parsing.
|
|
160
|
+
|
|
161
|
+
## Local Development
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
npm run build
|
|
165
|
+
npm test
|
|
166
|
+
npx tsc --noEmit
|
|
167
|
+
node dist/cli.js --help
|
|
168
|
+
npm pack --dry-run
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Documentation
|
|
172
|
+
|
|
173
|
+
- [Chinese README](./README.CN.md)
|
|
174
|
+
- [AI README](./README.AI.md)
|
|
175
|
+
- [Detailed CLI Usage](./docs/cli-usage.md)
|
|
176
|
+
- [Testing Guide](./docs/Tests/testing.md)
|
|
177
|
+
- [Product Overview](./docs/codex-switch-product-overview.md)
|
|
178
|
+
- [Release PRD 0.1.0](./docs/PRD/codex-switch-prd-v0.1.0.md)
|
|
179
|
+
- [Release Gate PRD 0.1.0](./docs/PRD/codex-switch-prd-v0.1.0.md)
|
|
180
|
+
|
|
181
|
+
## License
|
|
182
|
+
|
|
183
|
+
MIT
|
package/dist/app/add-provider.js
CHANGED
|
@@ -99,6 +99,7 @@ async function addProvider(args) {
|
|
|
99
99
|
provider: args.providerName,
|
|
100
100
|
});
|
|
101
101
|
}
|
|
102
|
+
const directBaseUrl = args.baseUrl;
|
|
102
103
|
const upsertProfiles = !existingProfile && args.createProfile
|
|
103
104
|
? {
|
|
104
105
|
[args.profile]: (0, config_1.validateManagedProfileCreation)(args.profile, {
|
|
@@ -107,15 +108,20 @@ async function addProvider(args) {
|
|
|
107
108
|
}),
|
|
108
109
|
}
|
|
109
110
|
: undefined;
|
|
111
|
+
if (!args.copilot && !existingModelProvider && args.createProfile && (!directBaseUrl || directBaseUrl.trim() === "")) {
|
|
112
|
+
throw (0, errors_1.cliError)("MANAGED_PROFILE_FIELDS_MISSING", `Model provider "${args.profile}" requires base_url.`, {
|
|
113
|
+
profile: args.profile,
|
|
114
|
+
modelProvider: args.profile,
|
|
115
|
+
missingFields: ["base_url"],
|
|
116
|
+
});
|
|
117
|
+
}
|
|
110
118
|
const upsertModelProviders = args.copilot
|
|
111
119
|
? {
|
|
112
120
|
[args.profile]: (0, providers_1.buildCopilotModelProviderProjection)(runtime),
|
|
113
121
|
}
|
|
114
122
|
: !existingModelProvider && args.createProfile
|
|
115
123
|
? {
|
|
116
|
-
[args.profile]:
|
|
117
|
-
baseUrl: args.baseUrl ?? undefined,
|
|
118
|
-
},
|
|
124
|
+
[args.profile]: (0, providers_1.buildDirectModelProviderProjection)(args.profile, directBaseUrl),
|
|
119
125
|
}
|
|
120
126
|
: undefined;
|
|
121
127
|
if (existingProfile) {
|
|
@@ -53,6 +53,13 @@ function editProvider(args) {
|
|
|
53
53
|
provider: args.providerName,
|
|
54
54
|
});
|
|
55
55
|
}
|
|
56
|
+
if (!args.baseUrl || args.baseUrl.trim() === "") {
|
|
57
|
+
throw (0, errors_1.cliError)("MANAGED_PROFILE_FIELDS_MISSING", `Model provider "${newProfile}" requires base_url.`, {
|
|
58
|
+
profile: newProfile,
|
|
59
|
+
modelProvider: newProfile,
|
|
60
|
+
missingFields: ["base_url"],
|
|
61
|
+
});
|
|
62
|
+
}
|
|
56
63
|
upsertProfiles = {
|
|
57
64
|
[newProfile]: (0, config_1.validateManagedProfileCreation)(newProfile, {
|
|
58
65
|
model: args.model ?? undefined,
|
|
@@ -60,14 +67,21 @@ function editProvider(args) {
|
|
|
60
67
|
}),
|
|
61
68
|
};
|
|
62
69
|
upsertModelProviders = {
|
|
63
|
-
[newProfile]:
|
|
64
|
-
baseUrl: args.baseUrl ?? undefined,
|
|
65
|
-
},
|
|
70
|
+
[newProfile]: (0, providers_1.buildDirectModelProviderProjection)(newProfile, args.baseUrl),
|
|
66
71
|
};
|
|
67
72
|
}
|
|
68
73
|
else {
|
|
69
74
|
(0, config_repo_1.requireManagedProfileRuntime)(document, providers, newProfile);
|
|
70
75
|
}
|
|
76
|
+
if (targetProfileExists &&
|
|
77
|
+
!current.runtime &&
|
|
78
|
+
args.baseUrl !== undefined &&
|
|
79
|
+
args.baseUrl !== null) {
|
|
80
|
+
upsertModelProviders = {
|
|
81
|
+
...(upsertModelProviders ?? {}),
|
|
82
|
+
[newProfile]: (0, providers_1.buildDirectModelProviderProjection)(newProfile, args.baseUrl),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
71
85
|
const nextRecord = (0, providers_1.cleanProviderRecord)({
|
|
72
86
|
profile: newProfile,
|
|
73
87
|
apiKey: args.apiKey ?? current.apiKey,
|
package/dist/app/get-status.js
CHANGED
|
@@ -67,8 +67,10 @@ async function getStatus(codexDir, configPath, providersPath, authPath, options)
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
const liveState = (0, runtime_state_1.inspectLiveStateDrift)(currentProfile, providers);
|
|
70
|
-
const activeProviderCandidates =
|
|
71
|
-
const activeProvider =
|
|
70
|
+
const activeProviderCandidates = liveState.mappedProviders;
|
|
71
|
+
const activeProvider = liveState.providerResolvable && providers && liveState.mappedProvider
|
|
72
|
+
? providers.providers[liveState.mappedProvider]
|
|
73
|
+
: null;
|
|
72
74
|
const copilotInstall = (0, copilot_installer_1.probeCopilotSdkInstall)(options?.runtimesDir);
|
|
73
75
|
const runtimeStateInspection = (0, runtime_state_repo_1.inspectCopilotBridgeState)(options?.runtimeDir);
|
|
74
76
|
const runtimeState = runtimeStateInspection.state;
|
|
@@ -108,6 +110,9 @@ async function getStatus(codexDir, configPath, providersPath, authPath, options)
|
|
|
108
110
|
// Surface unmanaged live state without mutating anything during a read-only status call.
|
|
109
111
|
warnings.push("Current config profile is not mapped in providers.json. Backfill would be required before treating live state as managed.");
|
|
110
112
|
}
|
|
113
|
+
if (liveState.reason === "shared-profile") {
|
|
114
|
+
warnings.push(`Current config profile "${currentProfile}" is shared by multiple providers in providers.json, so the active provider cannot be resolved uniquely.`);
|
|
115
|
+
}
|
|
111
116
|
if (runtimeStateInspection.exists && !runtimeStateInspection.valid) {
|
|
112
117
|
warnings.push(`Copilot bridge runtime state is unreadable: ${runtimeStateInspection.parseError ?? "unknown parse failure"}`);
|
|
113
118
|
}
|
|
@@ -128,7 +133,7 @@ async function getStatus(codexDir, configPath, providersPath, authPath, options)
|
|
|
128
133
|
currentProfile,
|
|
129
134
|
currentProfileMapped: liveState.profileMapped,
|
|
130
135
|
provider: liveState.mappedProvider,
|
|
131
|
-
activeProviderResolvable:
|
|
136
|
+
activeProviderResolvable: liveState.providerResolvable,
|
|
132
137
|
activeProviderCandidates,
|
|
133
138
|
runtimeProvider: activeProvider && (0, providers_1.isCopilotBridgeProvider)(activeProvider) ? activeProvider.runtime?.kind ?? null : null,
|
|
134
139
|
copilotSdk: {
|
|
@@ -1,16 +1,59 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
36
|
exports.listProviders = listProviders;
|
|
37
|
+
const fs = __importStar(require("node:fs"));
|
|
38
|
+
const providers_1 = require("../domain/providers");
|
|
39
|
+
const runtime_state_1 = require("../domain/runtime-state");
|
|
40
|
+
const config_repo_1 = require("../storage/config-repo");
|
|
4
41
|
const providers_repo_1 = require("../storage/providers-repo");
|
|
5
42
|
/**
|
|
6
43
|
* Returns the sorted list of configured providers for display.
|
|
7
44
|
*/
|
|
8
|
-
function listProviders(providersPath) {
|
|
45
|
+
function listProviders(providersPath, configPath) {
|
|
9
46
|
const providers = (0, providers_repo_1.readProvidersFile)(providersPath);
|
|
10
47
|
const names = Object.keys(providers.providers).sort();
|
|
48
|
+
const currentProfile = configPath && fs.existsSync(configPath)
|
|
49
|
+
? (0, config_repo_1.readStructuredConfig)(configPath).activeProfile
|
|
50
|
+
: null;
|
|
51
|
+
const liveState = (0, runtime_state_1.inspectLiveStateDrift)(currentProfile, providers);
|
|
11
52
|
const items = names.map((name) => ({
|
|
12
53
|
name,
|
|
13
54
|
profile: providers.providers[name].profile,
|
|
55
|
+
providerType: (0, providers_1.isCopilotBridgeProvider)(providers.providers[name]) ? "copilot" : "direct",
|
|
56
|
+
isActive: liveState.providerResolvable && liveState.mappedProvider === name,
|
|
14
57
|
note: providers.providers[name].note ?? null,
|
|
15
58
|
tags: providers.providers[name].tags ?? [],
|
|
16
59
|
}));
|
|
@@ -18,6 +61,10 @@ function listProviders(providersPath) {
|
|
|
18
61
|
data: {
|
|
19
62
|
providers: items,
|
|
20
63
|
count: items.length,
|
|
64
|
+
currentProfile,
|
|
65
|
+
activeProvider: liveState.mappedProvider,
|
|
66
|
+
activeProviderResolvable: liveState.providerResolvable,
|
|
67
|
+
activeProviderCandidates: liveState.mappedProviders,
|
|
21
68
|
},
|
|
22
69
|
};
|
|
23
70
|
}
|
package/dist/app/run-doctor.js
CHANGED
|
@@ -245,6 +245,10 @@ function renderConfigIssueMessage(issue) {
|
|
|
245
245
|
return `Model provider section "${issue.modelProvider}" for profile "${issue.profile}" is missing from config.toml.`;
|
|
246
246
|
case "MODEL_PROVIDER_BASE_URL_MISSING":
|
|
247
247
|
return `Model provider section "${issue.modelProvider}" for profile "${issue.profile}" is missing base_url.`;
|
|
248
|
+
case "PROVIDER_BASE_URL_MISMATCH":
|
|
249
|
+
return issue.providerType === "direct"
|
|
250
|
+
? `Direct provider "${issue.provider}" baseUrl does not match config.toml model provider "${issue.profile}" base_url.`
|
|
251
|
+
: String(issue.code ?? "UNKNOWN_ISSUE");
|
|
248
252
|
case "ACTIVE_PROVIDER_UNRESOLVED":
|
|
249
253
|
return `Active profile "${issue.profile}" maps to multiple providers, so the active managed provider cannot be resolved uniquely.`;
|
|
250
254
|
case "AUTH_JSON_INVALID":
|