@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,225 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { dirname, join } from 'node:path';
3
+ import { tierAgentNames } from '../config.js';
4
+ import { loadAaCatalog, proposeTiers } from '../catalog.js';
5
+ import { nativeTomlFor } from './toml.js';
6
+ import { reconcilePerRoleModels, reconcileTierList, gatewayNamesOf, avoidedKeysOf } from './helpers.js';
7
+ import { configPathFor, agentsDirFor } from './helpers.js';
8
+ import { resolveKeyFromSource, keyReport } from '../native/credentials.js';
9
+ import { credentialDir, credentialFileFor } from '../native/oauth-login.js';
10
+ import { readChatGptOAuth } from '../native/codex-auth.js';
11
+ import { GLOBAL_CONFIG_RELATIVE } from '../config.js';
12
+ import { isOauthGatewayAuth } from '../config.js';
13
+ import { addByokCandidates, addLiveCandidates, rewriteOauthToApiKey } from './candidates.js';
14
+ export function plan(env, state, credentials, opts,
15
+ /**
16
+ * The candidate map the front end (wizard or `--yes`) already built. Both
17
+ * branches call the same three shared operations against it before
18
+ * handing it to `plan`, so re-deriving it here is dead work — and the
19
+ * re-derivation was the substrate the OAuth→api-key divergence lived
20
+ * on. Optional so the existing tests that call `plan` directly with
21
+ * just (env, state, credentials, opts) still work; in that case `plan`
22
+ * builds the map itself from `env`.
23
+ */
24
+ nativeByKey) {
25
+ const configScope = state.configScope ?? 'project';
26
+ const configPathResolved = configPathFor(configScope, opts.cwd, opts.home);
27
+ // Get the config for this scope to read existing avoidGateways and run settings
28
+ const configForScope = env.configsByScope[configScope];
29
+ const avoidGateways = configForScope?.avoidGateways ?? [];
30
+ // ---- migratedModels ----
31
+ // parseConfig always builds unifiedModels from the raw [models] table
32
+ // (migrated or not), so this is complete regardless of whether the
33
+ // existing config was legacy and just migrated in place above, or was
34
+ // already in the unified shape — no need to re-run the migration here.
35
+ const migratedModels = {};
36
+ if (configForScope?.unifiedModels !== undefined) {
37
+ for (const [key, model] of Object.entries(configForScope.unifiedModels)) {
38
+ if (model.harness !== undefined && model.gateway === undefined) {
39
+ migratedModels[key] = { harness: model.harness, harnessId: model.harnessId };
40
+ }
41
+ }
42
+ }
43
+ const nativeKeys = state.nativeKeys ?? [];
44
+ const roles = state.roles ?? [];
45
+ // Build nativeByKey if the front end did not already. The front end's
46
+ // map already has BYOK, live, and OAuth-rewrite applied, so when it is
47
+ // available, this falls through and the three shared operations run
48
+ // nowhere — exactly the case for the wizard and the `--yes` path.
49
+ if (nativeByKey === undefined) {
50
+ const built = new Map();
51
+ for (const candidate of env.allNativeCandidates) {
52
+ built.set(candidate.key, candidate);
53
+ }
54
+ // Custom providers extend env's url map so a model the user added
55
+ // this run can be minted.
56
+ const providerBaseUrls = new Map(Object.entries(env.providerBaseUrls ?? {}));
57
+ for (const provider of state.customProviders ?? []) {
58
+ if (!providerBaseUrls.has(provider.name)) {
59
+ providerBaseUrls.set(provider.name, provider.url);
60
+ }
61
+ }
62
+ addByokCandidates(built, providerBaseUrls, state.byokModels ?? {}, state.customWireFormats ?? {});
63
+ addLiveCandidates(env, built, state.liveModels ?? {});
64
+ rewriteOauthToApiKey(built, state.byokKeys ?? {});
65
+ nativeByKey = built;
66
+ }
67
+ const chosenNative = nativeKeys.map((k) => nativeByKey.get(k)).filter((k) => k !== undefined);
68
+ // ---- tiers block ----
69
+ // The saved tier comes from the wizard's own state when the user re-ranked
70
+ // the tiers in the current run, and from the existing config otherwise —
71
+ // not the user's input combined with the catalog proposal, which is what
72
+ // `proposeTiers` would give a fresh run.
73
+ const savedNativeKeys = configForScope?.unifiedModels
74
+ ? Object.keys(configForScope.unifiedModels).filter((key) => configForScope.unifiedModels[key].gateway !== undefined)
75
+ : [];
76
+ const validTierKeys = new Set([...nativeKeys, ...Object.keys(migratedModels)]);
77
+ const catalog = loadAaCatalog(opts.home);
78
+ const addedKeys = nativeKeys.filter((key) => !savedNativeKeys.includes(key));
79
+ const tiers = Object.fromEntries(roles.map((role) => {
80
+ const proposal = proposeTiers(nativeKeys, catalog, gatewayNamesOf(nativeByKey), avoidedKeysOf(nativeByKey, avoidGateways));
81
+ const saved = state.tiers?.[role] ?? configForScope?.tiers?.[role];
82
+ return [role, {
83
+ simple: reconcileTierList(saved?.simple, validTierKeys, proposal.simple, addedKeys),
84
+ complex: reconcileTierList(saved?.complex, validTierKeys, proposal.complex, addedKeys),
85
+ }];
86
+ }));
87
+ // ---- nativeRoleModels ----
88
+ const nativeRoleModels = Object.fromEntries(Object.entries(reconcilePerRoleModels(configForScope?.native?.generate ?? {}, savedNativeKeys, nativeKeys, roles))
89
+ .map(([role, keys]) => [
90
+ role,
91
+ keys.map((k) => nativeByKey.get(k)).filter((k) => k !== undefined),
92
+ ]));
93
+ // ---- configToml ----
94
+ const configToml = nativeTomlFor(nativeRoleModels, state.credentialSources ?? {}, tiers, migratedModels, chosenNative, configForScope?.run, avoidGateways);
95
+ // ---- notices (key check) ----
96
+ const notices = [];
97
+ const gateways = [...new Set(chosenNative.map((c) => c.gateway))];
98
+ const gatewayAuths = new Map(chosenNative.map((c) => [c.gateway, c.auth]));
99
+ const autoSources = new Map(keyReport(gateways, opts.home).map((r) => [r.gateway, r.source]));
100
+ for (const gateway of gateways) {
101
+ const source = state.credentialSources?.[gateway];
102
+ const auth = gatewayAuths.get(gateway);
103
+ if (auth === 'api-key' && (source === 'sonata' || source === 'opencode')) {
104
+ const found = credentials.hasKey(gateway, source);
105
+ notices.push(found
106
+ ? ` ✓ ${gateway}: key from ${source}`
107
+ : source === 'sonata'
108
+ ? ` ! ${gateway}: no key from sonata — run \`sonata auth add ${gateway}\``
109
+ : ` ! ${gateway}: no key from opencode — log into opencode itself, sonata does not manage its credentials`);
110
+ continue;
111
+ }
112
+ if (auth !== undefined && isOauthGatewayAuth(auth) && source !== undefined) {
113
+ // Bearer keys and device-login OAuth credentials live in different
114
+ // stores per source, so presence and the repair hint both branch on
115
+ // (source, auth) rather than reusing the api-key path above.
116
+ // A stored GitHub token is not the same as a usable one: opencode's own
117
+ // login requests only `read:user`, and GitHub then refuses the Copilot
118
+ // exchange with a 403 — so presence alone would report a credential as
119
+ // healthy that `sonata serve` cannot actually use. `copilotUsable` above
120
+ // already answered this for the one token opencode can hold — reuse it
121
+ // rather than probing GitHub a second time, which could also disagree
122
+ // with the first probe on a flaky connection.
123
+ const found = source === 'sonata'
124
+ ? credentials.hasOauthCredential(gateway, auth)
125
+ : auth === 'copilot-oauth'
126
+ ? credentials.copilotUsable
127
+ : readChatGptOAuth(opts.home, source) !== null;
128
+ const repair = source === 'sonata'
129
+ ? `run \`sonata auth login ${gateway}\``
130
+ : source === 'codex'
131
+ ? 'log in with `codex login`'
132
+ : auth === 'copilot-oauth'
133
+ ? 'log into opencode with a GitHub Copilot account'
134
+ : 'log into opencode with a ChatGPT account';
135
+ notices.push(found
136
+ ? ` ✓ ${gateway}: credential from ${source}`
137
+ : ` ! ${gateway}: no credential from ${source} — ${repair}`);
138
+ continue;
139
+ }
140
+ // A key typed in this run is still only in memory — `apply` writes it, and
141
+ // `keyReport` reads the disk, so it cannot see one yet. Reporting it
142
+ // missing contradicted the `✓ stored the key for <gateway>` line `apply`
143
+ // prints seconds later, and sent the user to `sonata auth add` for a key
144
+ // they had just entered.
145
+ const entered = state.byokKeys?.[gateway] !== undefined;
146
+ const auto = autoSources.get(gateway) ?? null;
147
+ notices.push(entered
148
+ ? ` ✓ ${gateway}: key entered in this run`
149
+ : auto
150
+ ? ` ✓ ${gateway}: key from ${auto}`
151
+ : ` ! ${gateway}: no key — run \`sonata auth add ${gateway}\``);
152
+ }
153
+ // ---- summary ----
154
+ // Counted with the same rule `sync` writes by (`tierAgentNames`), not by
155
+ // roles × models: a role whose `simple` and `complex` lists match collapses
156
+ // to one file, so the old count promised 8 files and `sync` then wrote 4.
157
+ const totalAgents = tierAgentNames(tiers).length;
158
+ const summary = [
159
+ ' Summary',
160
+ ` models ${chosenNative.map((c) => `${c.gateway}/${c.id}`).join(', ')}`,
161
+ ` roles ${roles.join(', ')}`,
162
+ ` agents ${totalAgents} file${totalAgents === 1 ? '' : 's'} in .claude/agents/`,
163
+ ` hook ${state.hookScope === 'skip' ? 'not installed' : `${state.hookScope} settings.json`}`,
164
+ ` routing ${state.routing === 'skip' ? 'not configured' : `sonata route auto${state.routing === 'global' ? ' --global' : ''}`}`,
165
+ ` config ${configPathResolved}`,
166
+ '',
167
+ ];
168
+ // ---- hook ----
169
+ // The hook scope comes from state.hookScope if set, otherwise we need to compute it
170
+ // For the plan, we just use what the state says, the actual hook logic is done during write
171
+ const hookScope = state.hookScope ?? 'project';
172
+ // The allow-list must be touched even when the hook itself is skipped, so an
173
+ // upgrade from the MCP-based release still replaces the old `mcp__sonata__*`
174
+ // tool entries. `existingHookScope` says where the old hook lived, when any.
175
+ const allowListScope = hookScope !== 'skip' ? hookScope : env.existingHookScope;
176
+ const hook = { scope: hookScope, allowListScope };
177
+ // ---- skillPath ----
178
+ const skillBaseDir = configScope === 'global' ? opts.home : opts.cwd;
179
+ const skillPath = join(skillBaseDir, '.claude', 'skills', 'sonata-loop', 'SKILL.md');
180
+ // ---- syncCwd ----
181
+ const syncCwd = configScope === 'global' ? dirname(join(opts.home, GLOBAL_CONFIG_RELATIVE)) : opts.cwd;
182
+ // ---- agentsDir ----
183
+ const agentsDir = agentsDirFor(configScope, opts.cwd, opts.home);
184
+ // ---- routing ----
185
+ const routing = state.routing ?? 'project';
186
+ return {
187
+ configScope,
188
+ configPath: configPathResolved,
189
+ configToml,
190
+ keysToStore: Object.entries(state.byokKeys ?? {}).map(([gateway, key]) => ({ gateway, key })),
191
+ hook,
192
+ skillPath,
193
+ routing,
194
+ syncCwd,
195
+ agentsDir,
196
+ chosenNative,
197
+ roles,
198
+ nativeKeys,
199
+ notices,
200
+ summary,
201
+ };
202
+ }
203
+ /** Production `CredentialProbe`, backed by the key store and the filesystem. */
204
+ export function fsCredentialProbe(home, copilotUsable) {
205
+ return {
206
+ hasKey(gateway, source) {
207
+ if (source === 'sonata' || source === 'opencode') {
208
+ return resolveKeyFromSource(gateway, home, source) !== undefined;
209
+ }
210
+ // 'codex' source: check if ChatGPT OAuth credential exists
211
+ return readChatGptOAuth(home, 'codex') !== null;
212
+ },
213
+ hasOauthCredential(gateway, auth) {
214
+ const dir = credentialDir(home, gateway);
215
+ const file = credentialFileFor(auth);
216
+ return existsSync(join(dir, file));
217
+ },
218
+ autoSource(gateway) {
219
+ const reports = keyReport([gateway], home);
220
+ return reports[0]?.source ?? null;
221
+ },
222
+ copilotUsable,
223
+ };
224
+ }
225
+ //# sourceMappingURL=plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/init/plan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * The `--yes` (non-interactive) branch of `sonata init`.
3
+ *
4
+ * Lifted verbatim from `runInit` — the config-scope resolution, the
5
+ * `providerKeys`/`nativeKeys`/`roles` derivation from flags and the existing
6
+ * config, the BYOK candidate registration, the post-`validate` BYOK
7
+ * missing-key and unknown-model checks, and the `stateForPlan` shaping. Every
8
+ * comment is kept intact; they record real bugs.
9
+ *
10
+ * The return shape is the same `InitState` the wizard produces, so the shared
11
+ * post-branch code (OAuth check, `plan()`, confirm gate, `apply()`) needs no
12
+ * knowledge of which front end ran.
13
+ *
14
+ * `nativeByKey` is built here, not passed in: this is the front end's own
15
+ * candidate map for BYOK additions, and validate's call below uses the same
16
+ * one to catch unknown providers before they leave this branch.
17
+ */
18
+ import { existsSync, readFileSync } from 'node:fs';
19
+ import { KNOWN_ROLES } from '../config.js';
20
+ import { byokCandidateKey } from '../native/models.js';
21
+ import { resolveKeys } from '../native/credentials.js';
22
+ import { byokProviderName } from '../tui-ink/app-state.js';
23
+ import { preTickedNative, deriveInitState, configPathFor, parseCredentialSourceFlags, } from './helpers.js';
24
+ import { validate } from './validate.js';
25
+ import { addByokCandidates } from './candidates.js';
26
+ export function scriptedState(env, opts) {
27
+ const byokUrls = new Map(env.byokProviders.map((provider) => [provider.name, provider.url]));
28
+ const nativeByKey = new Map(env.allNativeCandidates.map((c) => [c.key, c]));
29
+ const configScope = opts.configScope ?? 'project';
30
+ const configPathResolved = configPathFor(configScope, opts.cwd, opts.home);
31
+ const configText = existsSync(configPathResolved) ? readFileSync(configPathResolved, 'utf8') : '';
32
+ const parsedConfig = env.configsByScope[configScope];
33
+ const ticked = preTickedNative(configText, env.allNativeCandidates);
34
+ const d = parsedConfig ? deriveInitState(parsedConfig, configScope, env.offered) : { configScope };
35
+ const credentialSources = {
36
+ ...d.credentialSources,
37
+ ...parseCredentialSourceFlags(opts.credentialSource ?? []),
38
+ };
39
+ // BYOK is opt-in. The default is "everything on offer", and BYOK rows are
40
+ // now on offer — so without this, a plain `--yes` with no --providers asks
41
+ // for a key for all thirty well-known providers and refuses. Only an
42
+ // explicit `--providers byok/x`, or a config that already names one,
43
+ // engages BYOK here.
44
+ const providerKeys = opts.providers ?? d.providerKeys
45
+ ?? env.offered.filter((p) => p.harness !== 'byok').map((p) => p.key);
46
+ // Scope native candidates to the selected providers.
47
+ const selectedProviders = new Set(providerKeys.map((k) => k.split('/')[1] ?? k));
48
+ let inScopeNative = env.allNativeCandidates.filter((c) => selectedProviders.has(c.gateway));
49
+ // A BYOK provider has no local catalogue, so each --models entry is taken
50
+ // as a raw model id. Validating it would mean a network call, and a scripted
51
+ // path must not depend on one.
52
+ const byokSelected = providerKeys
53
+ .map(byokProviderName)
54
+ .filter((name) => name !== undefined);
55
+ // Parse BYOK model ids from opts.models so we can add candidates to
56
+ // nativeByKey BEFORE calling validate. This lets validate's unknown-model
57
+ // check see the BYOK models. The missing-key check itself (which needs
58
+ // home) stays after validate so the unknown-providers check runs first,
59
+ // matching the original --yes branch order where unknown-providers was
60
+ // checked before the BYOK missing-key throw.
61
+ const byokModels = {};
62
+ for (const name of byokSelected) {
63
+ const prefix = `${name}-`;
64
+ byokModels[name] = (opts.models ?? [])
65
+ .filter((key) => key.startsWith(prefix))
66
+ .map((key) => key.slice(prefix.length));
67
+ }
68
+ if (byokSelected.length > 0) {
69
+ addByokCandidates(nativeByKey, byokUrls, byokModels);
70
+ // `addByokCandidates` silently skips a gateway with no resolvable URL
71
+ // (neither `byokUrls` nor `WELL_KNOWN_PROVIDER_URLS` has it). Filter those
72
+ // out here so `validate` can surface the unknown-provider error instead
73
+ // of the next line crashing on `c.key` for a candidate that was never
74
+ // minted — a crash would pre-empt the actionable message.
75
+ const byokAdded = byokSelected.flatMap((name) => byokModels[name]
76
+ .map((id) => nativeByKey.get(byokCandidateKey(name, id)))
77
+ .filter((c) => c !== undefined));
78
+ inScopeNative = [...inScopeNative, ...byokAdded];
79
+ }
80
+ const nativeKeys = opts.models ?? d.nativeKeys
81
+ ?? inScopeNative.filter((c) => ticked.has(c.key)).map((c) => c.key);
82
+ const inScopeNativeByKey = new Map(inScopeNative.map((c) => [c.key, c]));
83
+ const roles = opts.roles ?? d.roles ?? [...KNOWN_ROLES];
84
+ // Build state for validation
85
+ const state = {
86
+ configScope,
87
+ providerKeys,
88
+ nativeKeys,
89
+ roles,
90
+ credentialSources,
91
+ routing: opts.routing ?? 'project',
92
+ };
93
+ const problems = validate(env, state, { nativeByKey });
94
+ if (problems.length > 0)
95
+ throw new Error(problems[0].message);
96
+ // BYOK missing-key check needs home — keep it here (after validation so unknown providers are caught first)
97
+ if (byokSelected.length > 0) {
98
+ const stored = new Set(resolveKeys(byokSelected, opts.home).map((source) => source.gateway));
99
+ const missing = byokSelected.filter((name) => !stored.has(name));
100
+ if (missing.length > 0) {
101
+ throw new Error(`sonata init: no key for ${missing.join(', ')}. ` +
102
+ `Store it first: ${missing.map((name) => `sonata auth add ${name}`).join('; ')}`);
103
+ }
104
+ }
105
+ // Unknown model check (needs inScopeNativeByKey which is built after BYOK candidates added)
106
+ const unknown = nativeKeys.filter((k) => !inScopeNativeByKey.has(k));
107
+ if (unknown.length > 0) {
108
+ throw new Error(`sonata init: the selected providers do not offer ${unknown.join(', ')}. ` +
109
+ `Available: ${[...inScopeNativeByKey.keys()].join(', ')}`);
110
+ }
111
+ return {
112
+ state: {
113
+ configScope,
114
+ providerKeys,
115
+ nativeKeys,
116
+ roles,
117
+ credentialSources,
118
+ routing: opts.routing ?? 'project',
119
+ hookScope: opts.scope ?? (env.existingHookScope ? 'skip' : 'project'),
120
+ customProviders: undefined,
121
+ byokModels,
122
+ liveModels: {},
123
+ customWireFormats: {},
124
+ byokKeys: {},
125
+ tiers: d.tiers,
126
+ },
127
+ nativeByKey,
128
+ };
129
+ }
130
+ //# sourceMappingURL=scripted-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scripted-state.js","sourceRoot":"","sources":["../../src/init/scripted-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ import { isOauthGatewayAuth } from '../config.js';
2
+ import { proposeTiers } from '../catalog.js';
3
+ import { gatewayNamesOf, avoidedKeysOf, duplicateKeys } from './helpers.js';
4
+ const TOML_ESCAPES = {
5
+ '\\': '\\\\', '"': '\\"', '\b': '\\b', '\t': '\\t',
6
+ '\n': '\\n', '\f': '\\f', '\r': '\\r',
7
+ };
8
+ /**
9
+ * A TOML basic string, used for every key and value this file writes.
10
+ */
11
+ export function tomlKey(key) {
12
+ // eslint-disable-next-line no-control-regex
13
+ const escaped = key.replace(/[\\"\x00-\x1f\x7f]/g, (ch) => TOML_ESCAPES[ch] ?? `\\u${ch.charCodeAt(0).toString(16).padStart(4, '0')}`);
14
+ return `"${escaped}"`;
15
+ }
16
+ /**
17
+ * Emit the unified model registry, tier lists, native gateway definitions,
18
+ * and runtime defaults.
19
+ */
20
+ export function nativeTomlFor(roleModels, credentialSources = {}, selectedTiers, extraModels = {}, allChosen = [], existingRun, avoidGateways = []) {
21
+ const allModels = new Map();
22
+ for (const cands of Object.values(roleModels)) {
23
+ for (const c of cands)
24
+ allModels.set(c.key, c);
25
+ }
26
+ for (const c of allChosen)
27
+ allModels.set(c.key, c);
28
+ const tierLists = selectedTiers ?? Object.fromEntries(Object.entries(roleModels).map(([role, candidates]) => {
29
+ const proposal = proposeTiers(candidates.map((candidate) => candidate.key), undefined, gatewayNamesOf(allModels), avoidedKeysOf(allModels, avoidGateways));
30
+ return [role, proposal];
31
+ }));
32
+ const clashes = duplicateKeys([...allModels.keys()]);
33
+ if (clashes.length > 0) {
34
+ throw new Error(`sonata: ${clashes.join(', ')} would name two different models.`);
35
+ }
36
+ const gateways = new Map();
37
+ for (const c of allModels.values())
38
+ gateways.set(c.gateway, {
39
+ baseUrl: c.baseUrl, auth: c.auth, wireFormat: c.wireFormat,
40
+ });
41
+ const lines = [];
42
+ // Top-level keys must precede every table header: a bare key written after
43
+ // one belongs to *that table*, so emitting this beside [tiers] silently made
44
+ // it a field of the last [models."…"] entry and parseConfig never saw it.
45
+ // Dropping it would also be the bug the setting exists to prevent — init
46
+ // would re-propose the ordering the user avoided.
47
+ if (avoidGateways.length > 0) {
48
+ lines.push(`avoid_gateways = [${avoidGateways.map(tomlKey).join(', ')}]`, '');
49
+ }
50
+ for (const [gateway, { baseUrl, auth, wireFormat }] of gateways) {
51
+ lines.push(`[native.gateways.${tomlKey(gateway)}]`);
52
+ // An OAuth gateway takes no base_url: the credential reaches only its own
53
+ // provider's backend, and LiteLLM already knows that URL.
54
+ if (isOauthGatewayAuth(auth))
55
+ lines.push(`auth = ${tomlKey(auth)}`);
56
+ else
57
+ lines.push(`base_url = ${tomlKey(baseUrl)}`);
58
+ const source = credentialSources[gateway];
59
+ if (source !== undefined)
60
+ lines.push(`credential_source = ${tomlKey(source)}`);
61
+ if (wireFormat === 'anthropic')
62
+ lines.push(`wire_format = ${tomlKey(wireFormat)}`);
63
+ lines.push('');
64
+ }
65
+ for (const [key, c] of allModels) {
66
+ lines.push(`[models.${tomlKey(key)}]`, `gateway = ${tomlKey(c.gateway)}`, `id = ${tomlKey(c.id)}`, `context_window = ${c.contextWindow}`);
67
+ if (c.harness !== undefined) {
68
+ lines.push(`harness = ${tomlKey(c.harness)}`, `harness_id = ${tomlKey(c.harnessId ?? c.id)}`);
69
+ }
70
+ lines.push('');
71
+ }
72
+ for (const [key, model] of Object.entries(extraModels)) {
73
+ if (allModels.has(key) || model.harness === undefined || model.harnessId === undefined)
74
+ continue;
75
+ lines.push(`[models.${tomlKey(key)}]`, `harness = ${tomlKey(model.harness)}`, `id = ${tomlKey(model.harnessId)}`, '');
76
+ }
77
+ for (const [role, lists] of Object.entries(tierLists)) {
78
+ lines.push(`[tiers.${tomlKey(role)}]`, `simple = [${lists.simple.map(tomlKey).join(', ')}]`, `complex = [${lists.complex.map(tomlKey).join(', ')}]`, '');
79
+ }
80
+ lines.push('[run]', `tail_window_seconds = ${existingRun?.tailWindowSeconds ?? 20}`, `stall_timeout_seconds = ${existingRun?.stallTimeoutSeconds ?? 120}`, `run_timeout_seconds = ${existingRun?.runTimeoutSeconds ?? 1800}`, `dispatch_window_seconds = ${existingRun?.dispatchWindowSeconds ?? 1500}`, '');
81
+ return lines.join('\n');
82
+ }
83
+ //# sourceMappingURL=toml.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toml.js","sourceRoot":"","sources":["../../src/init/toml.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,149 @@
1
+ import { KNOWN_ROLES } from '../config.js';
2
+ import { existsSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { isOauthGatewayAuth } from '../config.js';
5
+ import { credentialDir, credentialFileFor } from '../native/oauth-login.js';
6
+ import { byokProviderKey } from '../tui-ink/app-state.js';
7
+ export function validate(env, state, opts) {
8
+ const problems = [];
9
+ const configScope = state.configScope ?? 'project';
10
+ const providerKeys = state.providerKeys ?? [];
11
+ const nativeKeys = state.nativeKeys ?? [];
12
+ const roles = state.roles ?? [...KNOWN_ROLES];
13
+ const credentialSources = state.credentialSources ?? {};
14
+ const stateRouting = state.routing;
15
+ // Providers the user added this run via the wizard's "Add custom provider"
16
+ // screen. Such a provider cannot be in `env.offered` (it is computed once at
17
+ // startup, before the screen exists), so the unknown-provider check must
18
+ // skip its byok/<name> key.
19
+ const customProviderNames = new Set((state.customProviders ?? []).map((p) => p.name));
20
+ const customProviderKeys = new Set([...customProviderNames].map((name) => byokProviderKey(name)));
21
+ // Resolve native candidates for the selected providers
22
+ const selectedProviders = new Set(providerKeys.map((k) => k.split('/')[1] ?? k));
23
+ const inScopeNative = env.allNativeCandidates.filter((c) => selectedProviders.has(c.gateway));
24
+ // Scope the front end's `nativeByKey` (which has BYOK and live additions
25
+ // for every gateway) to the selected providers — otherwise a `nativeKey`
26
+ // the user no longer has a provider for slips past the unknown-model check,
27
+ // since the check only asks "is this key in the map?" — and the model
28
+ // would be written into `[models]` for a provider that isn't selected.
29
+ const inScopeNativeByKey = opts?.nativeByKey !== undefined
30
+ ? new Map([...opts.nativeByKey].filter(([, candidate]) => selectedProviders.has(candidate.gateway)))
31
+ : new Map(inScopeNative.map((c) => [c.key, c]));
32
+ // 1. unknownProviders — no harness offers this provider
33
+ // Skip keys for providers the user added through the wizard this run: those
34
+ // are typed in through "Add a custom provider" and never appear in the
35
+ // pre-computed `env.offered` list.
36
+ const unknownProviders = providerKeys.filter((k) => !customProviderKeys.has(k) && !env.offered.some((p) => p.key === k));
37
+ if (unknownProviders.length > 0) {
38
+ problems.push({
39
+ severity: 'error',
40
+ message: `sonata init: no harness offers ${unknownProviders.join(', ')}. ` +
41
+ `Available: ${env.offered.map((p) => p.key).join(', ')}`,
42
+ });
43
+ }
44
+ // 2. BYOK missing-key check — needs home, which we don't have; the --yes
45
+ // branch keeps its own copy with full context.
46
+ // 3. Unknown model check
47
+ const unknown = nativeKeys.filter((k) => !inScopeNativeByKey.has(k));
48
+ if (unknown.length > 0) {
49
+ problems.push({
50
+ severity: 'error',
51
+ message: `sonata init: the selected providers do not offer ${unknown.join(', ')}. ` +
52
+ `Available: ${[...inScopeNativeByKey.keys()].join(', ')}`,
53
+ });
54
+ }
55
+ // 4. No models selected
56
+ if (nativeKeys.length === 0) {
57
+ problems.push({
58
+ severity: 'error',
59
+ message: 'sonata init: no models selected — nothing to generate.',
60
+ });
61
+ }
62
+ // 5. --credential-source naming an unselected gateway
63
+ const chosenNative = nativeKeys.map((k) => inScopeNativeByKey.get(k)).filter((k) => k !== undefined);
64
+ const nativeGateways = new Map(chosenNative.map((candidate) => [candidate.gateway, candidate]));
65
+ for (const gateway of Object.keys(credentialSources)) {
66
+ if (nativeGateways.has(gateway))
67
+ continue;
68
+ problems.push({
69
+ severity: 'error',
70
+ message: `sonata init: --credential-source names gateway "${gateway}", which is not among the selected models. ` +
71
+ `Known gateways: ${[...nativeGateways.keys()].join(', ') || '(none)'}`,
72
+ });
73
+ }
74
+ // 6. Unknown role(s)
75
+ const badRoles = roles.filter((r) => !KNOWN_ROLES.includes(r));
76
+ if (badRoles.length > 0) {
77
+ problems.push({
78
+ severity: 'error',
79
+ message: `sonata init: unknown role(s) ${badRoles.join(', ')}`,
80
+ });
81
+ }
82
+ // 7. No roles selected
83
+ if (roles.length === 0) {
84
+ problems.push({
85
+ severity: 'error',
86
+ message: 'sonata init: no roles selected — nothing to generate.',
87
+ });
88
+ }
89
+ // 8. Credential-source/auth block (codex on api-key, codex on copilot-oauth)
90
+ const gatewayAuths = new Map(chosenNative.map((candidate) => [candidate.gateway, candidate.auth]));
91
+ for (const [gateway, source] of Object.entries(credentialSources)) {
92
+ const auth = gatewayAuths.get(gateway);
93
+ if (source === 'codex' && auth === 'api-key') {
94
+ problems.push({
95
+ severity: 'error',
96
+ message: `sonata init: gateway "${gateway}" is auth = "api-key", so it cannot take its credential from codex — ` +
97
+ 'that is a subscription, not a key.',
98
+ });
99
+ }
100
+ if (source === 'codex' && auth === 'copilot-oauth') {
101
+ problems.push({
102
+ severity: 'error',
103
+ message: `sonata init: gateway "${gateway}" is copilot-oauth, so it cannot take its credential from codex — ` +
104
+ 'Copilot logins come only from opencode.',
105
+ });
106
+ }
107
+ // A gateway pinned to credential_source = "sonata" with an OAuth auth type
108
+ // needs a credential sonata itself minted (via `sonata auth login`), and
109
+ // the --yes path cannot pause for a browser device login. The old runInit
110
+ // carried this as a pre-flight after the front end; validate is the new
111
+ // home for it.
112
+ if (source === 'sonata' && auth !== undefined && isOauthGatewayAuth(auth)) {
113
+ if (!existsSync(join(credentialDir(env.home, gateway), credentialFileFor(auth)))) {
114
+ problems.push({
115
+ severity: 'error',
116
+ message: `sonata init: gateway "${gateway}" needs a credential. ` +
117
+ `Log in first: sonata auth login ${gateway}`,
118
+ });
119
+ }
120
+ }
121
+ }
122
+ // 9. --routing global with project-scoped config
123
+ if (stateRouting === 'global' && configScope === 'project') {
124
+ problems.push({
125
+ severity: 'error',
126
+ message: 'sonata init: --routing global routes every project through the machine config ' +
127
+ '(~/.config/sonata/sonata.toml), but this config was written to the project ' +
128
+ '(./sonata.toml) — the two would silently disagree. Use --config-scope global ' +
129
+ 'together with --routing global, or keep --routing project.',
130
+ });
131
+ }
132
+ // 10. Shadowing sonata.toml check
133
+ if (env.cwd !== undefined &&
134
+ env.home !== undefined &&
135
+ configScope === 'global' &&
136
+ stateRouting !== 'global' &&
137
+ stateRouting !== 'skip' &&
138
+ existsSync(join(env.cwd, 'sonata.toml'))) {
139
+ problems.push({
140
+ severity: 'error',
141
+ message: 'sonata init: this repository has its own sonata.toml, which would shadow the ' +
142
+ 'global config just written when routing is project-scoped — the generated global ' +
143
+ "agents would resolve against this project's local config instead. Use --routing " +
144
+ "global, or remove/rename this project's own sonata.toml.",
145
+ });
146
+ }
147
+ return problems;
148
+ }
149
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/init/validate.ts"],"names":[],"mappings":"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"}