@zhihaohong52/sonata 0.4.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.
Files changed (183) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +437 -0
  3. package/dist/adapters/claude.js +83 -0
  4. package/dist/adapters/claude.js.map +1 -0
  5. package/dist/adapters/codex.js +382 -0
  6. package/dist/adapters/codex.js.map +1 -0
  7. package/dist/adapters/index.js +21 -0
  8. package/dist/adapters/index.js.map +1 -0
  9. package/dist/adapters/opencode.js +104 -0
  10. package/dist/adapters/opencode.js.map +1 -0
  11. package/dist/adapters/pi.js +152 -0
  12. package/dist/adapters/pi.js.map +1 -0
  13. package/dist/adapters/reasonix.js +358 -0
  14. package/dist/adapters/reasonix.js.map +1 -0
  15. package/dist/adapters/types.js +2 -0
  16. package/dist/adapters/types.js.map +1 -0
  17. package/dist/agent-markers.js +3 -0
  18. package/dist/agent-markers.js.map +1 -0
  19. package/dist/aipricing.js +109 -0
  20. package/dist/aipricing.js.map +1 -0
  21. package/dist/catalog.js +274 -0
  22. package/dist/catalog.js.map +1 -0
  23. package/dist/cli.js +766 -0
  24. package/dist/cli.js.map +1 -0
  25. package/dist/commands/approve.js +23 -0
  26. package/dist/commands/approve.js.map +1 -0
  27. package/dist/commands/auth.js +41 -0
  28. package/dist/commands/auth.js.map +1 -0
  29. package/dist/commands/catalog.js +172 -0
  30. package/dist/commands/catalog.js.map +1 -0
  31. package/dist/commands/code.js +113 -0
  32. package/dist/commands/code.js.map +1 -0
  33. package/dist/commands/dispatch.js +148 -0
  34. package/dist/commands/dispatch.js.map +1 -0
  35. package/dist/commands/doctor.js +545 -0
  36. package/dist/commands/doctor.js.map +1 -0
  37. package/dist/commands/gc.js +25 -0
  38. package/dist/commands/gc.js.map +1 -0
  39. package/dist/commands/init-log.js +83 -0
  40. package/dist/commands/init-log.js.map +1 -0
  41. package/dist/commands/init.js +157 -0
  42. package/dist/commands/init.js.map +1 -0
  43. package/dist/commands/log.js +24 -0
  44. package/dist/commands/log.js.map +1 -0
  45. package/dist/commands/route.js +660 -0
  46. package/dist/commands/route.js.map +1 -0
  47. package/dist/commands/run.js +199 -0
  48. package/dist/commands/run.js.map +1 -0
  49. package/dist/commands/runs.js +37 -0
  50. package/dist/commands/runs.js.map +1 -0
  51. package/dist/commands/serve.js +818 -0
  52. package/dist/commands/serve.js.map +1 -0
  53. package/dist/commands/status.js +14 -0
  54. package/dist/commands/status.js.map +1 -0
  55. package/dist/commands/sync.js +258 -0
  56. package/dist/commands/sync.js.map +1 -0
  57. package/dist/commands/tail.js +229 -0
  58. package/dist/commands/tail.js.map +1 -0
  59. package/dist/commands/usage.js +85 -0
  60. package/dist/commands/usage.js.map +1 -0
  61. package/dist/commands/verify.js +69 -0
  62. package/dist/commands/verify.js.map +1 -0
  63. package/dist/commands/wait.js +38 -0
  64. package/dist/commands/wait.js.map +1 -0
  65. package/dist/config.js +588 -0
  66. package/dist/config.js.map +1 -0
  67. package/dist/detect.js +445 -0
  68. package/dist/detect.js.map +1 -0
  69. package/dist/filelock.js +83 -0
  70. package/dist/filelock.js.map +1 -0
  71. package/dist/init/apply.js +96 -0
  72. package/dist/init/apply.js.map +1 -0
  73. package/dist/init/candidates.js +115 -0
  74. package/dist/init/candidates.js.map +1 -0
  75. package/dist/init/discover.js +216 -0
  76. package/dist/init/discover.js.map +1 -0
  77. package/dist/init/helpers.js +429 -0
  78. package/dist/init/helpers.js.map +1 -0
  79. package/dist/init/interactive-state.js +128 -0
  80. package/dist/init/interactive-state.js.map +1 -0
  81. package/dist/init/plan.js +225 -0
  82. package/dist/init/plan.js.map +1 -0
  83. package/dist/init/scripted-state.js +130 -0
  84. package/dist/init/scripted-state.js.map +1 -0
  85. package/dist/init/toml.js +83 -0
  86. package/dist/init/toml.js.map +1 -0
  87. package/dist/init/validate.js +149 -0
  88. package/dist/init/validate.js.map +1 -0
  89. package/dist/ledger.js +123 -0
  90. package/dist/ledger.js.map +1 -0
  91. package/dist/mcp/protocol.js +64 -0
  92. package/dist/mcp/protocol.js.map +1 -0
  93. package/dist/mcp/server.js +96 -0
  94. package/dist/mcp/server.js.map +1 -0
  95. package/dist/mcp/tools.js +210 -0
  96. package/dist/mcp/tools.js.map +1 -0
  97. package/dist/mode.js +64 -0
  98. package/dist/mode.js.map +1 -0
  99. package/dist/native/claude-shim.js +228 -0
  100. package/dist/native/claude-shim.js.map +1 -0
  101. package/dist/native/codex-auth.js +177 -0
  102. package/dist/native/codex-auth.js.map +1 -0
  103. package/dist/native/copilot-auth.js +105 -0
  104. package/dist/native/copilot-auth.js.map +1 -0
  105. package/dist/native/credentials.js +83 -0
  106. package/dist/native/credentials.js.map +1 -0
  107. package/dist/native/hosts.js +60 -0
  108. package/dist/native/hosts.js.map +1 -0
  109. package/dist/native/litellm.js +103 -0
  110. package/dist/native/litellm.js.map +1 -0
  111. package/dist/native/models.js +96 -0
  112. package/dist/native/models.js.map +1 -0
  113. package/dist/native/oauth-login.js +112 -0
  114. package/dist/native/oauth-login.js.map +1 -0
  115. package/dist/native/router.js +469 -0
  116. package/dist/native/router.js.map +1 -0
  117. package/dist/native/tls.js +73 -0
  118. package/dist/native/tls.js.map +1 -0
  119. package/dist/native/usage.js +119 -0
  120. package/dist/native/usage.js.map +1 -0
  121. package/dist/normalize.js +98 -0
  122. package/dist/normalize.js.map +1 -0
  123. package/dist/pricing.js +86 -0
  124. package/dist/pricing.js.map +1 -0
  125. package/dist/roles.js +49 -0
  126. package/dist/roles.js.map +1 -0
  127. package/dist/sessions.js +62 -0
  128. package/dist/sessions.js.map +1 -0
  129. package/dist/settings.js +131 -0
  130. package/dist/settings.js.map +1 -0
  131. package/dist/store.js +70 -0
  132. package/dist/store.js.map +1 -0
  133. package/dist/tmux.js +89 -0
  134. package/dist/tmux.js.map +1 -0
  135. package/dist/tui-ink/app-state.js +340 -0
  136. package/dist/tui-ink/app-state.js.map +1 -0
  137. package/dist/tui-ink/app.js +156 -0
  138. package/dist/tui-ink/app.js.map +1 -0
  139. package/dist/tui-ink/components/byok-step.js +102 -0
  140. package/dist/tui-ink/components/byok-step.js.map +1 -0
  141. package/dist/tui-ink/components/login-screen.js +80 -0
  142. package/dist/tui-ink/components/login-screen.js.map +1 -0
  143. package/dist/tui-ink/components/models-step.js +92 -0
  144. package/dist/tui-ink/components/models-step.js.map +1 -0
  145. package/dist/tui-ink/components/multi-select-state.js +56 -0
  146. package/dist/tui-ink/components/multi-select-state.js.map +1 -0
  147. package/dist/tui-ink/components/multi-select.js +69 -0
  148. package/dist/tui-ink/components/multi-select.js.map +1 -0
  149. package/dist/tui-ink/components/providers-step.js +285 -0
  150. package/dist/tui-ink/components/providers-step.js.map +1 -0
  151. package/dist/tui-ink/components/ranked-select-state.js +41 -0
  152. package/dist/tui-ink/components/ranked-select-state.js.map +1 -0
  153. package/dist/tui-ink/components/ranked-select.js +61 -0
  154. package/dist/tui-ink/components/ranked-select.js.map +1 -0
  155. package/dist/tui-ink/components/search-select.js +47 -0
  156. package/dist/tui-ink/components/search-select.js.map +1 -0
  157. package/dist/tui-ink/components/text-input-state.js +42 -0
  158. package/dist/tui-ink/components/text-input-state.js.map +1 -0
  159. package/dist/tui-ink/components/text-input.js +48 -0
  160. package/dist/tui-ink/components/text-input.js.map +1 -0
  161. package/dist/tui-ink/run.js +38 -0
  162. package/dist/tui-ink/run.js.map +1 -0
  163. package/dist/tui-ink/test-compile.js +4 -0
  164. package/dist/tui-ink/test-compile.js.map +1 -0
  165. package/dist/tui-ink/types.js +2 -0
  166. package/dist/tui-ink/types.js.map +1 -0
  167. package/dist/tui.js +330 -0
  168. package/dist/tui.js.map +1 -0
  169. package/dist/types.js +2 -0
  170. package/dist/types.js.map +1 -0
  171. package/dist/watchdog.js +85 -0
  172. package/dist/watchdog.js.map +1 -0
  173. package/hooks/capture-mode.mjs +56 -0
  174. package/hooks/ensure-serve.mjs +140 -0
  175. package/hooks/hooks.json +12 -0
  176. package/hooks/route-session.mjs +47 -0
  177. package/hooks/route-subagent.mjs +54 -0
  178. package/package.json +64 -0
  179. package/roles/code.md +13 -0
  180. package/roles/explore.md +9 -0
  181. package/roles/plan.md +10 -0
  182. package/roles/review.md +11 -0
  183. package/skills/loop/SKILL.md +43 -0
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Native candidate minting for `sonata init` — the three operations that
3
+ * turn user-supplied model picks into full `NativeCandidate` rows:
4
+ *
5
+ * - `addByokCandidates` — models a user named directly (typed in or picked
6
+ * from a gateway's `/models` response) that no harness listed
7
+ * - `addLiveCandidates` — models a gateway's own `/models` endpoint
8
+ * returned but the harness catalogue did not
9
+ * - `rewriteOauthToApiKey` — gateways that were originally OAuth (LiteLLM
10
+ * sets the base URL) but now have a BYOK key, so they need to be
11
+ * rewritten to the well-known api-key base URL
12
+ *
13
+ * The wizard, the `--yes` path, and `plan()` all need the same three
14
+ * operations applied in the same order against the same `nativeByKey` map.
15
+ * Three separate copies drifted: the original threw on an OAuth→api-key
16
+ * rewrite whose gateway was not in `WELL_KNOWN_PROVIDER_URLS`, and `plan`
17
+ * silently skipped instead. The silent skip kept the OAuth base URL on a
18
+ * candidate whose auth had just been flipped to `api-key`, so the config
19
+ * got a route that authenticates and then 401s. Single source lives here.
20
+ */
21
+ import { isOauthGatewayAuth } from '../config.js';
22
+ import { WELL_KNOWN_PROVIDER_URLS } from '../detect.js';
23
+ import { byokCandidateKey } from '../native/models.js';
24
+ /**
25
+ * Candidates for models a user named directly.
26
+ *
27
+ * These must join `nativeByKey` before `nativeKeys` is resolved through it,
28
+ * or every BYOK key looks up `undefined` and is filtered out silently — a
29
+ * wizard that appears to work and writes an empty config.
30
+ *
31
+ * The base URL falls back to `WELL_KNOWN_PROVIDER_URLS[gateway]` when the
32
+ * caller didn't already supply one for that gateway. The front ends
33
+ * (wizard, `--yes`) build `byokUrls` from `env.byokProviders`, which IS the
34
+ * well-known set, so the fallback never fires there. `plan()` builds
35
+ * `byokUrls` from `env.providerBaseUrls` (a live-detected subset), so the
36
+ * fallback is what keeps a `--providers byok/<x>` row with no live detect
37
+ * working — and what keeps a saved-config re-init that goes through plan
38
+ * (because the front end's map was unused) alive when the harness is gone
39
+ * and nothing in `env.providerBaseUrls` mentions the saved gateway any
40
+ * more. A gateway with no known URL — neither passed in nor well-known —
41
+ * is silently skipped; the unknown-providers check upstream is what stops
42
+ * truly-unknown gateways from reaching here.
43
+ */
44
+ export function addByokCandidates(nativeByKey, byokUrls, byokModels, wireFormats = {}) {
45
+ for (const [gateway, ids] of Object.entries(byokModels)) {
46
+ const baseUrl = byokUrls.get(gateway) ?? WELL_KNOWN_PROVIDER_URLS[gateway];
47
+ if (baseUrl === undefined)
48
+ continue;
49
+ const wireFormat = wireFormats[gateway];
50
+ for (const id of ids) {
51
+ const key = byokCandidateKey(gateway, id);
52
+ nativeByKey.set(key, {
53
+ key, gateway, id, contextWindow: 128000, baseUrl, auth: 'api-key',
54
+ ...(wireFormat !== undefined ? { wireFormat } : {}),
55
+ });
56
+ }
57
+ }
58
+ }
59
+ /**
60
+ * Candidates for models only a gateway's own `/models` endpoint reported.
61
+ *
62
+ * The models step refreshes each gateway's list from the gateway itself, so
63
+ * it can surface a model the harness catalogue never listed. Such a model has no
64
+ * `NativeCandidate`, and `nativeKeys` is resolved through `nativeByKey` — so
65
+ * without this it is selected, kept in the tiers, and then silently dropped
66
+ * from `[models]`, producing a config that names a model it never defines.
67
+ * An existing candidate always wins: the harness one carries a `harness`
68
+ * route this cannot know about.
69
+ */
70
+ export function addLiveCandidates(env, nativeByKey, liveModels) {
71
+ for (const [gateway, ids] of Object.entries(liveModels)) {
72
+ const baseUrl = env.providerBaseUrls[gateway];
73
+ if (baseUrl === undefined)
74
+ continue;
75
+ const auth = env.gatewayAuth.get(gateway) ?? 'api-key';
76
+ // Only a key-authenticated gateway is ever refreshed, so this is a
77
+ // guard rather than a case: an OAuth gateway's URL is LiteLLM's, and
78
+ // writing it as an api-key entry would produce a route that 401s.
79
+ if (isOauthGatewayAuth(auth))
80
+ continue;
81
+ for (const id of ids) {
82
+ const key = byokCandidateKey(gateway, id);
83
+ if (nativeByKey.has(key))
84
+ continue;
85
+ nativeByKey.set(key, { key, gateway, id, contextWindow: 128000, baseUrl, auth: 'api-key' });
86
+ }
87
+ }
88
+ }
89
+ /**
90
+ * A gateway that was originally OAuth (from `env.gatewayAuth`) but now has a
91
+ * BYOK key gets switched to api-key auth with the well-known base URL.
92
+ *
93
+ * THROWS — the OAuth→api-key transition MUST use a well-known provider URL,
94
+ * not any URL from the original config (which would be the OAuth endpoint).
95
+ * Silently skipping leaves a candidate with `auth: 'api-key'` but the
96
+ * OAuth base URL, so the config gets a route that authenticates and 401s
97
+ * later. The pre-refactor behaviour was to throw, and that is the
98
+ * behaviour kept here: any caller without a well-known URL for the
99
+ * gateway is in the wrong place. The message string is the contract
100
+ * callers test against and must stay byte-identical.
101
+ */
102
+ export function rewriteOauthToApiKey(nativeByKey, byokKeys) {
103
+ for (const gateway of Object.keys(byokKeys)) {
104
+ for (const [key, candidate] of nativeByKey) {
105
+ if (candidate.gateway !== gateway || candidate.auth === 'api-key')
106
+ continue;
107
+ if (!Object.hasOwn(WELL_KNOWN_PROVIDER_URLS, gateway)) {
108
+ throw new Error(`sonata init: no API base URL is known for ${gateway}; cannot use an API key.`);
109
+ }
110
+ const baseUrl = WELL_KNOWN_PROVIDER_URLS[gateway];
111
+ nativeByKey.set(key, { ...candidate, baseUrl, auth: 'api-key' });
112
+ }
113
+ }
114
+ }
115
+ //# sourceMappingURL=candidates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"candidates.js","sourceRoot":"","sources":["../../src/init/candidates.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,216 @@
1
+ /**
2
+ * Environment discovery for `sonata init`.
3
+ *
4
+ * Lifted verbatim from `runInit` — detection printing, `configsByScope` loading
5
+ * with its legacy migration, `configuredGateways`, `providerBaseUrls`, the
6
+ * copilot probe, `oauthProviders`, `gatewayAuth`, `allNativeCandidates`,
7
+ * `byokProviders`, `dedupeOauthProviders`, the no-harness warning, and the
8
+ * `existingHookScope` computation. Every comment is kept intact; they record
9
+ * real bugs.
10
+ *
11
+ * `discover` reports problems; it does not decide what to do about them. The
12
+ * blocking-problems early return stays in `runInit`, reading `env.problems`.
13
+ */
14
+ import { existsSync, readFileSync } from 'node:fs';
15
+ import { parseConfig, } from '../config.js';
16
+ import { readCopilotToken, copilotTokenCanExchange } from '../native/copilot-auth.js';
17
+ import { offerableProviders, } from '../detect.js';
18
+ import { settingsPath, readSettings, hookInstalled, hookCommand, } from '../settings.js';
19
+ import { migrateLegacyConfig } from '../normalize.js';
20
+ import { wellKnownProviders } from '../native/models.js';
21
+ import { byokProviderKey } from '../tui-ink/app-state.js';
22
+ import { oauthProvidersFor, nativeCandidatesFrom, configNativeCandidates, dedupeOauthProviders, configPathFor, defaultDetector, OPENCODE_RANGE } from './helpers.js';
23
+ export async function discover(opts, out) {
24
+ // ---- detect -----------------------------------------------------------
25
+ const detect = opts.detect ?? defaultDetector;
26
+ const { tmux, harnesses } = await detect({ home: opts.home, supportedVersions: OPENCODE_RANGE });
27
+ const problems = [...tmux.problems, ...harnesses.flatMap((h) => h.problems)];
28
+ out(tmux.installed ? ` ✓ tmux ${tmux.version}` : ' ✗ tmux not found');
29
+ for (const h of harnesses) {
30
+ out(h.installed
31
+ ? ` ✓ ${h.name} ${h.version} · ${h.refs.length} models`
32
+ : ` · ${h.name} not installed`);
33
+ }
34
+ out('');
35
+ const allRefs = harnesses.flatMap((h) => h.refs);
36
+ const authed = harnesses.flatMap((h) => h.authedProviders);
37
+ let offered = offerableProviders(allRefs, authed);
38
+ const configsByScope = {};
39
+ for (const scope of ['project', 'global']) {
40
+ const path = configPathFor(scope, opts.cwd, opts.home);
41
+ if (!existsSync(path))
42
+ continue;
43
+ try {
44
+ const parsed = parseConfig(readFileSync(path, 'utf8'));
45
+ if (parsed.tiers === undefined && (Object.keys(parsed.generate.roles).length > 0 || Object.keys(parsed.native?.generate ?? {}).length > 0)) {
46
+ const migrated = migrateLegacyConfig(parsed);
47
+ configsByScope[scope] = {
48
+ ...parsed,
49
+ unifiedModels: migrated.models,
50
+ tiers: migrated.tiers,
51
+ native: parsed.native === undefined ? undefined : {
52
+ ...parsed.native,
53
+ generate: Object.fromEntries(Object.entries(migrated.tiers).map(([role, lists]) => [
54
+ role, [...new Set([...lists.simple, ...lists.complex])],
55
+ ])),
56
+ },
57
+ };
58
+ }
59
+ else {
60
+ configsByScope[scope] = parsed;
61
+ }
62
+ }
63
+ catch (err) {
64
+ out(` ! could not read ${path}; init is starting from defaults: ${err instanceof Error ? err.message : String(err)}`);
65
+ }
66
+ }
67
+ const configuredGateways = new Map();
68
+ for (const config of Object.values(configsByScope)) {
69
+ for (const model of Object.values(config?.native?.models ?? {})) {
70
+ configuredGateways.set(model.gateway, (configuredGateways.get(model.gateway) ?? 0) + 1);
71
+ }
72
+ // A native-only unified [models] entry names its gateway here too — an
73
+ // untiered config with no legacy [native.models] table at all otherwise
74
+ // never gets its gateway a synthetic `config/<gateway>` provider, so
75
+ // `deriveInitState`'s own providerKeys (computed from both tables)
76
+ // names a provider `offered` never actually has, and scripted
77
+ // `sonata init --yes` rejects it as unknown before role selection is
78
+ // even reached.
79
+ for (const model of Object.values(config?.unifiedModels ?? {})) {
80
+ if (model.gateway === undefined)
81
+ continue;
82
+ configuredGateways.set(model.gateway, (configuredGateways.get(model.gateway) ?? 0) + 1);
83
+ }
84
+ }
85
+ // deriveInitState names a gateway `config/<gateway>` when no harness
86
+ // offers it OR when more than one distinct harness does — both are equally
87
+ // unattributable; only the first case was synthesized here, so an ambiguous
88
+ // gateway produced a providerKey that `offered` never contained, and the
89
+ // `--yes` path rejected it as unknown.
90
+ const harnessesPerGateway = new Map();
91
+ for (const provider of offered) {
92
+ if (!harnessesPerGateway.has(provider.provider)) {
93
+ harnessesPerGateway.set(provider.provider, new Set());
94
+ }
95
+ harnessesPerGateway.get(provider.provider).add(provider.harness);
96
+ }
97
+ for (const [gateway, count] of configuredGateways) {
98
+ const harnessCount = harnessesPerGateway.get(gateway)?.size ?? 0;
99
+ if (harnessCount !== 1) {
100
+ offered.push({ harness: 'config', provider: gateway, key: `config/${gateway}`, count });
101
+ }
102
+ }
103
+ const providerBaseUrls = {};
104
+ for (const h of harnesses) {
105
+ for (const [k, v] of Object.entries(h.providerBaseUrls ?? {})) {
106
+ if (!providerBaseUrls[k])
107
+ providerBaseUrls[k] = v;
108
+ }
109
+ }
110
+ // A gateway a harness no longer discovers (removed from opencode, say) but
111
+ // that is still configured in sonata.toml has no live-detected base URL, so
112
+ // re-authenticating it through the wizard could never fetch a fresh model
113
+ // list — only the models already persisted from whenever it was first
114
+ // imported. Fall back to the config's own base_url so it can.
115
+ for (const config of Object.values(configsByScope)) {
116
+ for (const [gateway, gatewayConfig] of Object.entries(config?.native?.gateways ?? {})) {
117
+ if (!providerBaseUrls[gateway] && gatewayConfig.baseUrl !== undefined) {
118
+ providerBaseUrls[gateway] = gatewayConfig.baseUrl;
119
+ }
120
+ }
121
+ }
122
+ // A harness logged in with a subscription holds an OAuth credential, not an
123
+ // API key. Writing such a provider with a metered base URL produces a gateway
124
+ // that authenticates and is then refused for quota, which reads to the user as
125
+ // a missing key. Record how each provider actually authenticates instead.
126
+ // opencode's stored GitHub token usually cannot mint a Copilot key: opencode
127
+ // requests only `read:user`, so the exchange 403s and LiteLLM drops the
128
+ // model. That is a property of *opencode's specific credential*, not of the
129
+ // github-copilot gateway itself — the gateway is always OAuth-authenticated,
130
+ // and "Add provider" can still run its own device-flow login (which asks
131
+ // for the `copilot` scope directly) independent of opencode's token. So
132
+ // `copilotUsable` gates only whether opencode's token is offered for
133
+ // *import* — it must not stop the gateway from being recognized as OAuth,
134
+ // or the models opencode already lists for it would be filtered out of the
135
+ // candidate set entirely (nativeCandidatesFrom drops any provider absent
136
+ // from both providerBaseUrls and oauthProviders), leaving "Add provider"'s
137
+ // fresh login with nothing to select afterward.
138
+ const copilotToken = readCopilotToken(opts.home);
139
+ const copilotUsable = copilotToken !== null
140
+ && await copilotTokenCanExchange(copilotToken);
141
+ if (copilotToken !== null && !copilotUsable) {
142
+ out(' ! github-copilot: the stored opencode token cannot mint a Copilot key ' +
143
+ '(needs the `copilot` scope) — not importable from opencode; use Add provider to log in directly');
144
+ }
145
+ const oauthProviders = oauthProvidersFor(allRefs, opts.home, {
146
+ copilot: () => copilotToken,
147
+ });
148
+ const gatewayAuth = new Map();
149
+ for (const config of Object.values(configsByScope)) {
150
+ for (const [gateway, gatewayConfig] of Object.entries(config?.native?.gateways ?? {})) {
151
+ gatewayAuth.set(gateway, gatewayConfig.auth);
152
+ }
153
+ }
154
+ for (const [gateway, auth] of oauthProviders)
155
+ gatewayAuth.set(gateway, auth);
156
+ const detectedNativeCandidates = nativeCandidatesFrom(allRefs, providerBaseUrls, oauthProviders);
157
+ const allNativeCandidates = [...new Map([
158
+ ...detectedNativeCandidates.map((candidate) => [candidate.key, candidate]),
159
+ ...Object.values(configsByScope).flatMap((config) => configNativeCandidates(config)).map((candidate) => [candidate.key, candidate]),
160
+ ]).values()];
161
+ // Providers a user can name without any harness installed. Offered alongside
162
+ // the discovered ones, minus any whose name a real provider already covers —
163
+ // otherwise deepseek appears twice, once with a catalogue and once without.
164
+ const byokProviders = wellKnownProviders()
165
+ .filter((provider) => !offered.some((existing) => existing.provider === provider.name));
166
+ for (const provider of byokProviders) {
167
+ offered.push({
168
+ harness: 'byok',
169
+ provider: provider.name,
170
+ key: byokProviderKey(provider.name),
171
+ count: 0,
172
+ });
173
+ }
174
+ // Applied after the BYOK block so a hidden provider is not re-offered as a
175
+ // BYOK row: that filter skips any name already in `offered`, which it still
176
+ // is at this point.
177
+ offered = dedupeOauthProviders(offered, oauthProviders);
178
+ // Having no harness is no longer fatal: BYOK is exactly that case, and the
179
+ // wizard can reach a working config from it. It is still worth saying, so it
180
+ // stays a problem — a warning, which does not stop the run.
181
+ if (offered.every((provider) => provider.harness === 'byok')) {
182
+ problems.push({
183
+ severity: 'warn',
184
+ message: 'no harness reported a usable model provider',
185
+ fix: 'pick a provider below and enter its API key, or run `opencode auth login`',
186
+ });
187
+ }
188
+ // ---- hook scope -------------------------------------------------------
189
+ const command = hookCommand(opts.packageRoot);
190
+ const alreadyGlobal = hookInstalled(readSettings(settingsPath('global', opts.cwd, opts.home)), command);
191
+ const alreadyProject = hookInstalled(readSettings(settingsPath('project', opts.cwd, opts.home)), command);
192
+ // Where an already-installed hook actually lives — kept separate from
193
+ // `scope` so an upgrade (hook present, but its settings file still carries
194
+ // the pre-dispatch-CLI MCP tool names) still gets its allow-list checked
195
+ // below, even though `scope` itself becomes 'skip' for "no new hook to ask
196
+ // about".
197
+ const existingHookScope = alreadyGlobal ? 'global' : alreadyProject ? 'project' : undefined;
198
+ return {
199
+ cwd: opts.cwd,
200
+ home: opts.home,
201
+ tmux,
202
+ harnesses,
203
+ problems,
204
+ offered,
205
+ allNativeCandidates,
206
+ providerBaseUrls,
207
+ gatewayAuth,
208
+ oauthProviders,
209
+ byokProviders,
210
+ configsByScope,
211
+ existingHookScope,
212
+ copilotUsable,
213
+ };
214
+ }
215
+ export { defaultDetector, OPENCODE_RANGE } from './helpers.js';
216
+ //# sourceMappingURL=discover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover.js","sourceRoot":"","sources":["../../src/init/discover.ts"],"names":[],"mappings":"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"}