@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.
- package/LICENSE +21 -0
- package/README.md +437 -0
- package/dist/adapters/claude.js +83 -0
- package/dist/adapters/claude.js.map +1 -0
- package/dist/adapters/codex.js +382 -0
- package/dist/adapters/codex.js.map +1 -0
- package/dist/adapters/index.js +21 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/opencode.js +104 -0
- package/dist/adapters/opencode.js.map +1 -0
- package/dist/adapters/pi.js +152 -0
- package/dist/adapters/pi.js.map +1 -0
- package/dist/adapters/reasonix.js +358 -0
- package/dist/adapters/reasonix.js.map +1 -0
- package/dist/adapters/types.js +2 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/agent-markers.js +3 -0
- package/dist/agent-markers.js.map +1 -0
- package/dist/aipricing.js +109 -0
- package/dist/aipricing.js.map +1 -0
- package/dist/catalog.js +274 -0
- package/dist/catalog.js.map +1 -0
- package/dist/cli.js +766 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/approve.js +23 -0
- package/dist/commands/approve.js.map +1 -0
- package/dist/commands/auth.js +41 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/catalog.js +172 -0
- package/dist/commands/catalog.js.map +1 -0
- package/dist/commands/code.js +113 -0
- package/dist/commands/code.js.map +1 -0
- package/dist/commands/dispatch.js +148 -0
- package/dist/commands/dispatch.js.map +1 -0
- package/dist/commands/doctor.js +545 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/gc.js +25 -0
- package/dist/commands/gc.js.map +1 -0
- package/dist/commands/init-log.js +83 -0
- package/dist/commands/init-log.js.map +1 -0
- package/dist/commands/init.js +157 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/log.js +24 -0
- package/dist/commands/log.js.map +1 -0
- package/dist/commands/route.js +660 -0
- package/dist/commands/route.js.map +1 -0
- package/dist/commands/run.js +199 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/runs.js +37 -0
- package/dist/commands/runs.js.map +1 -0
- package/dist/commands/serve.js +818 -0
- package/dist/commands/serve.js.map +1 -0
- package/dist/commands/status.js +14 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/sync.js +258 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/tail.js +229 -0
- package/dist/commands/tail.js.map +1 -0
- package/dist/commands/usage.js +85 -0
- package/dist/commands/usage.js.map +1 -0
- package/dist/commands/verify.js +69 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/commands/wait.js +38 -0
- package/dist/commands/wait.js.map +1 -0
- package/dist/config.js +588 -0
- package/dist/config.js.map +1 -0
- package/dist/detect.js +445 -0
- package/dist/detect.js.map +1 -0
- package/dist/filelock.js +83 -0
- package/dist/filelock.js.map +1 -0
- package/dist/init/apply.js +96 -0
- package/dist/init/apply.js.map +1 -0
- package/dist/init/candidates.js +115 -0
- package/dist/init/candidates.js.map +1 -0
- package/dist/init/discover.js +216 -0
- package/dist/init/discover.js.map +1 -0
- package/dist/init/helpers.js +429 -0
- package/dist/init/helpers.js.map +1 -0
- package/dist/init/interactive-state.js +128 -0
- package/dist/init/interactive-state.js.map +1 -0
- package/dist/init/plan.js +225 -0
- package/dist/init/plan.js.map +1 -0
- package/dist/init/scripted-state.js +130 -0
- package/dist/init/scripted-state.js.map +1 -0
- package/dist/init/toml.js +83 -0
- package/dist/init/toml.js.map +1 -0
- package/dist/init/validate.js +149 -0
- package/dist/init/validate.js.map +1 -0
- package/dist/ledger.js +123 -0
- package/dist/ledger.js.map +1 -0
- package/dist/mcp/protocol.js +64 -0
- package/dist/mcp/protocol.js.map +1 -0
- package/dist/mcp/server.js +96 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools.js +210 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/mode.js +64 -0
- package/dist/mode.js.map +1 -0
- package/dist/native/claude-shim.js +228 -0
- package/dist/native/claude-shim.js.map +1 -0
- package/dist/native/codex-auth.js +177 -0
- package/dist/native/codex-auth.js.map +1 -0
- package/dist/native/copilot-auth.js +105 -0
- package/dist/native/copilot-auth.js.map +1 -0
- package/dist/native/credentials.js +83 -0
- package/dist/native/credentials.js.map +1 -0
- package/dist/native/hosts.js +60 -0
- package/dist/native/hosts.js.map +1 -0
- package/dist/native/litellm.js +103 -0
- package/dist/native/litellm.js.map +1 -0
- package/dist/native/models.js +96 -0
- package/dist/native/models.js.map +1 -0
- package/dist/native/oauth-login.js +112 -0
- package/dist/native/oauth-login.js.map +1 -0
- package/dist/native/router.js +469 -0
- package/dist/native/router.js.map +1 -0
- package/dist/native/tls.js +73 -0
- package/dist/native/tls.js.map +1 -0
- package/dist/native/usage.js +119 -0
- package/dist/native/usage.js.map +1 -0
- package/dist/normalize.js +98 -0
- package/dist/normalize.js.map +1 -0
- package/dist/pricing.js +86 -0
- package/dist/pricing.js.map +1 -0
- package/dist/roles.js +49 -0
- package/dist/roles.js.map +1 -0
- package/dist/sessions.js +62 -0
- package/dist/sessions.js.map +1 -0
- package/dist/settings.js +131 -0
- package/dist/settings.js.map +1 -0
- package/dist/store.js +70 -0
- package/dist/store.js.map +1 -0
- package/dist/tmux.js +89 -0
- package/dist/tmux.js.map +1 -0
- package/dist/tui-ink/app-state.js +340 -0
- package/dist/tui-ink/app-state.js.map +1 -0
- package/dist/tui-ink/app.js +156 -0
- package/dist/tui-ink/app.js.map +1 -0
- package/dist/tui-ink/components/byok-step.js +102 -0
- package/dist/tui-ink/components/byok-step.js.map +1 -0
- package/dist/tui-ink/components/login-screen.js +80 -0
- package/dist/tui-ink/components/login-screen.js.map +1 -0
- package/dist/tui-ink/components/models-step.js +92 -0
- package/dist/tui-ink/components/models-step.js.map +1 -0
- package/dist/tui-ink/components/multi-select-state.js +56 -0
- package/dist/tui-ink/components/multi-select-state.js.map +1 -0
- package/dist/tui-ink/components/multi-select.js +69 -0
- package/dist/tui-ink/components/multi-select.js.map +1 -0
- package/dist/tui-ink/components/providers-step.js +285 -0
- package/dist/tui-ink/components/providers-step.js.map +1 -0
- package/dist/tui-ink/components/ranked-select-state.js +41 -0
- package/dist/tui-ink/components/ranked-select-state.js.map +1 -0
- package/dist/tui-ink/components/ranked-select.js +61 -0
- package/dist/tui-ink/components/ranked-select.js.map +1 -0
- package/dist/tui-ink/components/search-select.js +47 -0
- package/dist/tui-ink/components/search-select.js.map +1 -0
- package/dist/tui-ink/components/text-input-state.js +42 -0
- package/dist/tui-ink/components/text-input-state.js.map +1 -0
- package/dist/tui-ink/components/text-input.js +48 -0
- package/dist/tui-ink/components/text-input.js.map +1 -0
- package/dist/tui-ink/run.js +38 -0
- package/dist/tui-ink/run.js.map +1 -0
- package/dist/tui-ink/test-compile.js +4 -0
- package/dist/tui-ink/test-compile.js.map +1 -0
- package/dist/tui-ink/types.js +2 -0
- package/dist/tui-ink/types.js.map +1 -0
- package/dist/tui.js +330 -0
- package/dist/tui.js.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/watchdog.js +85 -0
- package/dist/watchdog.js.map +1 -0
- package/hooks/capture-mode.mjs +56 -0
- package/hooks/ensure-serve.mjs +140 -0
- package/hooks/hooks.json +12 -0
- package/hooks/route-session.mjs +47 -0
- package/hooks/route-subagent.mjs +54 -0
- package/package.json +64 -0
- package/roles/code.md +13 -0
- package/roles/explore.md +9 -0
- package/roles/plan.md +10 -0
- package/roles/review.md +11 -0
- package/skills/loop/SKILL.md +43 -0
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure helpers shared by the `src/init/*` pipeline modules and `src/commands/init.ts`.
|
|
3
|
+
*
|
|
4
|
+
* Lifted verbatim from `src/commands/init.ts` so the eight `src/init/*`
|
|
5
|
+
* modules can import from a sibling rather than `../commands/init.js` —
|
|
6
|
+
* which is the cycle this file's existence breaks. Nothing here imports
|
|
7
|
+
* `init.ts`; if a helper ever needs to, that one stays behind.
|
|
8
|
+
*/
|
|
9
|
+
import { join } from 'node:path';
|
|
10
|
+
import { GLOBAL_CONFIG_RELATIVE, parseConfig, isOauthGatewayAuth, oauthGatewayBaseUrl, isAnthropicRoutedName, CREDENTIAL_SOURCES, } from '../config.js';
|
|
11
|
+
import { readChatGptOAuth, readOpencodeChatGptOAuth } from '../native/codex-auth.js';
|
|
12
|
+
import { readCopilotToken } from '../native/copilot-auth.js';
|
|
13
|
+
import { detectTmux, detectHarnesses, WELL_KNOWN_PROVIDER_URLS, } from '../detect.js';
|
|
14
|
+
export const OPENCODE_RANGE = '>=1.18.0 <2.0.0';
|
|
15
|
+
/** Real environment probe. Tests inject a substitute so they stay hermetic. */
|
|
16
|
+
export const defaultDetector = async (env) => ({
|
|
17
|
+
tmux: await detectTmux(),
|
|
18
|
+
harnesses: await detectHarnesses(env),
|
|
19
|
+
});
|
|
20
|
+
/**
|
|
21
|
+
* The provider name an OAuth credential is offered under, when more than one
|
|
22
|
+
* harness reports it.
|
|
23
|
+
*
|
|
24
|
+
* Each of these auth kinds names a single account, not a class of gateway:
|
|
25
|
+
* `codex-oauth` *is* the ChatGPT subscription, `copilot-oauth` *is* the GitHub
|
|
26
|
+
* Copilot entitlement. So two providers resolving to the same kind are the
|
|
27
|
+
* same upstream, reached twice.
|
|
28
|
+
*/
|
|
29
|
+
const OAUTH_CANONICAL_PROVIDER = {
|
|
30
|
+
'codex-oauth': 'codex',
|
|
31
|
+
'copilot-oauth': 'github-copilot',
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* One OAuth credential, one provider row.
|
|
35
|
+
*
|
|
36
|
+
* opencode's `openai` entry is the same ChatGPT credential codex holds —
|
|
37
|
+
* identical `client_id`, which is exactly how `oauthProvidersFor` recognises
|
|
38
|
+
* it. Offering both let the user configure one subscription as two
|
|
39
|
+
* `codex-oauth` gateways serving overlapping models under different keys
|
|
40
|
+
* (`gpt-5.6-luna` and `openai-gpt-5.6-luna`), doubling the generated agents
|
|
41
|
+
* for no added capability.
|
|
42
|
+
*
|
|
43
|
+
* The canonical name only wins when it is actually offered: a machine with
|
|
44
|
+
* opencode but no codex still reaches ChatGPT through `openai`, which is the
|
|
45
|
+
* whole reason that entry is read in the first place.
|
|
46
|
+
*/
|
|
47
|
+
export function dedupeOauthProviders(offered, oauthProviders) {
|
|
48
|
+
const names = new Set(offered.map((provider) => provider.provider));
|
|
49
|
+
return offered.filter((provider) => {
|
|
50
|
+
const auth = oauthProviders.get(provider.provider);
|
|
51
|
+
if (auth === undefined || !isOauthGatewayAuth(auth))
|
|
52
|
+
return true;
|
|
53
|
+
const canonical = OAUTH_CANONICAL_PROVIDER[auth];
|
|
54
|
+
if (canonical === undefined || provider.provider === canonical)
|
|
55
|
+
return true;
|
|
56
|
+
return !names.has(canonical);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/** Build wizard credential rows only for the gateway auth type they can serve. */
|
|
60
|
+
export function credentialAvailabilityFor(providers, oauthProviders, credentials, hasKey) {
|
|
61
|
+
return Object.fromEntries(providers.map((provider) => {
|
|
62
|
+
const auth = oauthProviders.get(provider.provider);
|
|
63
|
+
return [provider.provider, {
|
|
64
|
+
codex: auth === 'codex-oauth' ? credentials.codex : null,
|
|
65
|
+
opencode: auth === 'copilot-oauth'
|
|
66
|
+
? credentials.copilot
|
|
67
|
+
: auth === 'codex-oauth'
|
|
68
|
+
? credentials.opencode
|
|
69
|
+
: null,
|
|
70
|
+
key: hasKey(provider.provider) ? { source: 'sonata' } : null,
|
|
71
|
+
// Only an OAuth gateway needs an override target; everything else
|
|
72
|
+
// already authenticates with a key, so entering one always works.
|
|
73
|
+
keyEntryAvailable: auth === undefined || !isOauthGatewayAuth(auth) || Object.hasOwn(WELL_KNOWN_PROVIDER_URLS, provider.provider),
|
|
74
|
+
}];
|
|
75
|
+
}));
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Where a config is written for a scope. The read-side counterpart is
|
|
79
|
+
* `configPath`, which resolves a precedence chain; this picks one location.
|
|
80
|
+
*/
|
|
81
|
+
export function configPathFor(scope, cwd, home) {
|
|
82
|
+
return scope === 'global'
|
|
83
|
+
? join(home, GLOBAL_CONFIG_RELATIVE)
|
|
84
|
+
: join(cwd, 'sonata.toml');
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Agents follow the config's scope. Keeping them together is the whole point:
|
|
88
|
+
* `init` in $HOME used to write agents globally and config where only $HOME
|
|
89
|
+
* could read it, producing agents that were offered everywhere and worked
|
|
90
|
+
* nowhere.
|
|
91
|
+
*/
|
|
92
|
+
export function agentsDirFor(scope, cwd, home) {
|
|
93
|
+
return scope === 'global'
|
|
94
|
+
? join(home, '.claude', 'agents')
|
|
95
|
+
: join(cwd, '.claude', 'agents');
|
|
96
|
+
}
|
|
97
|
+
export function parseCredentialSourceFlags(values) {
|
|
98
|
+
const out = {};
|
|
99
|
+
for (const value of values) {
|
|
100
|
+
const parts = value.split('=');
|
|
101
|
+
if (parts.length !== 2 || !parts[0] || !parts[1]) {
|
|
102
|
+
throw new Error(`sonata init: --credential-source expects <gateway>=<source>, got "${value}"`);
|
|
103
|
+
}
|
|
104
|
+
const [gateway, source] = parts;
|
|
105
|
+
if (!CREDENTIAL_SOURCES.includes(source)) {
|
|
106
|
+
throw new Error(`sonata init: --credential-source "${value}" names unknown source "${source}". ` +
|
|
107
|
+
`Known: ${CREDENTIAL_SOURCES.join(', ')}`);
|
|
108
|
+
}
|
|
109
|
+
out[gateway] = source;
|
|
110
|
+
}
|
|
111
|
+
return out;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Native candidates from detected refs, deduplicated by (provider, id).
|
|
115
|
+
*
|
|
116
|
+
* `oauthProviders` maps a provider to the OAuth kind its credential actually
|
|
117
|
+
* is — a subscription login rather than a key. Such a provider must not be
|
|
118
|
+
* written with a base URL: its token is refused by the metered endpoint and
|
|
119
|
+
* reaches only the provider's own backend, which LiteLLM addresses itself.
|
|
120
|
+
*/
|
|
121
|
+
export function nativeCandidatesFrom(refs, providerBaseUrls, oauthProviders = new Map()) {
|
|
122
|
+
const seen = new Set();
|
|
123
|
+
return refs
|
|
124
|
+
.filter((r) => {
|
|
125
|
+
// An oauth provider needs no discovered URL — LiteLLM supplies it.
|
|
126
|
+
if (providerBaseUrls[r.provider] === undefined && !oauthProviders.has(r.provider))
|
|
127
|
+
return false;
|
|
128
|
+
// Copilot, acme and anthropic all serve Claude models, but the router
|
|
129
|
+
// sends this prefix to Anthropic, so parseConfig refuses such an entry.
|
|
130
|
+
// Offering one would let init write a config it cannot read back.
|
|
131
|
+
const key = r.ref.replace(/\//g, '-');
|
|
132
|
+
if (isAnthropicRoutedName(key) || isAnthropicRoutedName(r.id ?? r.ref))
|
|
133
|
+
return false;
|
|
134
|
+
const dedup = `${r.provider}/${r.id}`;
|
|
135
|
+
if (seen.has(dedup))
|
|
136
|
+
return false;
|
|
137
|
+
seen.add(dedup);
|
|
138
|
+
return true;
|
|
139
|
+
})
|
|
140
|
+
.map((r) => {
|
|
141
|
+
const auth = oauthProviders.get(r.provider) ?? 'api-key';
|
|
142
|
+
const key = r.ref.replace(/\//g, '-');
|
|
143
|
+
const id = r.id ?? r.ref;
|
|
144
|
+
return {
|
|
145
|
+
key,
|
|
146
|
+
gateway: r.provider,
|
|
147
|
+
id,
|
|
148
|
+
contextWindow: 128000,
|
|
149
|
+
baseUrl: isOauthGatewayAuth(auth)
|
|
150
|
+
? oauthGatewayBaseUrl(auth)
|
|
151
|
+
: providerBaseUrls[r.provider],
|
|
152
|
+
auth,
|
|
153
|
+
harness: r.harness,
|
|
154
|
+
harnessId: r.harness === 'codex' ? id : r.ref,
|
|
155
|
+
};
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Which detected providers authenticate by OAuth rather than a key, judged by
|
|
160
|
+
* reading the credential rather than by provider name.
|
|
161
|
+
*
|
|
162
|
+
* Naming alone would be wrong in both directions: opencode's `openai` provider
|
|
163
|
+
* holds a ChatGPT subscription on this machine but a real API key on another,
|
|
164
|
+
* and marking it by name would either write a metered base URL a subscription
|
|
165
|
+
* cannot use, or refuse a base URL a real key needs.
|
|
166
|
+
*/
|
|
167
|
+
export function oauthProvidersFor(refs, home, deps = {}) {
|
|
168
|
+
const chatGpt = deps.chatGpt ?? readChatGptOAuth;
|
|
169
|
+
const opencodeChatGpt = deps.opencodeChatGpt ?? readOpencodeChatGptOAuth;
|
|
170
|
+
const copilot = deps.copilot ?? readCopilotToken;
|
|
171
|
+
const out = new Map();
|
|
172
|
+
// codex's own provider, when `codex login` used a ChatGPT account.
|
|
173
|
+
if (chatGpt(home) !== null) {
|
|
174
|
+
for (const ref of refs) {
|
|
175
|
+
if (ref.harness === 'codex')
|
|
176
|
+
out.set(ref.provider, 'codex-oauth');
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// opencode serves the same subscription under `openai`.
|
|
180
|
+
if (opencodeChatGpt(home) !== null) {
|
|
181
|
+
if (refs.some((ref) => ref.provider === 'openai'))
|
|
182
|
+
out.set('openai', 'codex-oauth');
|
|
183
|
+
}
|
|
184
|
+
if (copilot(home) !== null) {
|
|
185
|
+
if (refs.some((ref) => ref.provider === 'github-copilot')) {
|
|
186
|
+
out.set('github-copilot', 'copilot-oauth');
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return out;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* The gateway names behind a set of candidates, for `normalizeModelName`.
|
|
193
|
+
*
|
|
194
|
+
* A model key is `<gateway>-<id>`, so without the gateway names the id cannot
|
|
195
|
+
* be recovered from the key, and the model misses the catalog it should have
|
|
196
|
+
* matched — landing on `default` (capable, not cheap) and dropping out of the
|
|
197
|
+
* simple tier.
|
|
198
|
+
*/
|
|
199
|
+
/**
|
|
200
|
+
* The model keys served by an avoided gateway.
|
|
201
|
+
*
|
|
202
|
+
* `avoid_gateways` names gateways, but ranking sorts model keys, so the two
|
|
203
|
+
* are resolved through the candidate set rather than by matching key prefixes
|
|
204
|
+
* — a key only looks like `<gateway>-<id>`, and inferring the gateway back out
|
|
205
|
+
* of it is exactly the guess `normalizeModelName` needs configured providers
|
|
206
|
+
* to avoid.
|
|
207
|
+
*/
|
|
208
|
+
export function avoidedKeysOf(models, avoidGateways) {
|
|
209
|
+
const avoid = new Set(avoidGateways);
|
|
210
|
+
return new Set([...models.values()].filter((c) => avoid.has(c.gateway)).map((c) => c.key));
|
|
211
|
+
}
|
|
212
|
+
export function gatewayNamesOf(models) {
|
|
213
|
+
return [...new Set([...models.values()].map((candidate) => candidate.gateway))];
|
|
214
|
+
}
|
|
215
|
+
export function nativeLabel(c) {
|
|
216
|
+
return `${c.gateway}/${c.id}`;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Per-role model assignments after the selected model set has changed.
|
|
220
|
+
*
|
|
221
|
+
* The saved assignment is a **default for models that are still selected** —
|
|
222
|
+
* never an override of the selection. Treating it as an override is what made
|
|
223
|
+
* `sonata init --models <new>` report the new model in its summary and then
|
|
224
|
+
* write the old ones: a role already present in the config kept its saved list
|
|
225
|
+
* and the selection was discarded in full.
|
|
226
|
+
*
|
|
227
|
+
* So, per role: keep what was assigned and is still selected, and add whatever
|
|
228
|
+
* is newly selected, because "I just added codex" means codex should be usable.
|
|
229
|
+
* A role left with nothing gets the whole selection rather than an empty list,
|
|
230
|
+
* which would generate no agent for it at all.
|
|
231
|
+
*/
|
|
232
|
+
export function reconcilePerRoleModels(saved, savedKeys, chosen, roles) {
|
|
233
|
+
const selected = new Set(chosen);
|
|
234
|
+
const added = chosen.filter((key) => !savedKeys.includes(key));
|
|
235
|
+
const out = {};
|
|
236
|
+
for (const role of roles) {
|
|
237
|
+
const kept = (saved?.[role] ?? []).filter((key) => selected.has(key));
|
|
238
|
+
const merged = [...kept, ...added.filter((key) => !kept.includes(key))];
|
|
239
|
+
out[role] = merged.length > 0 ? merged : [...chosen];
|
|
240
|
+
}
|
|
241
|
+
return out;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Filters a saved tier list down to keys still valid this run — currently
|
|
245
|
+
* selected as native, or preserved as a harness-only fallback — falling back
|
|
246
|
+
* to a fresh proposal when nothing survives. Reusing a saved list verbatim
|
|
247
|
+
* after a model was deselected would write a [tiers] entry `cmdSync` then
|
|
248
|
+
* rejects as referencing a model with no matching [models] entry.
|
|
249
|
+
*/
|
|
250
|
+
export function reconcileTierList(saved, validKeys, fallback, added = []) {
|
|
251
|
+
const kept = (saved ?? []).filter((key) => validKeys.has(key));
|
|
252
|
+
if (kept.length === 0)
|
|
253
|
+
return fallback;
|
|
254
|
+
const extra = added.filter((key) => validKeys.has(key) && !kept.includes(key));
|
|
255
|
+
return [...kept, ...extra];
|
|
256
|
+
}
|
|
257
|
+
export function deriveInitState(config, configScope, offered) {
|
|
258
|
+
const nativeModels = config.native?.models ?? {};
|
|
259
|
+
const unifiedModels = config.unifiedModels;
|
|
260
|
+
const modelKeys = [...new Set([...Object.keys(nativeModels), ...Object.keys(unifiedModels)])]
|
|
261
|
+
.filter((key) => (unifiedModels[key]?.gateway ?? nativeModels[key]?.gateway) !== undefined);
|
|
262
|
+
if (modelKeys.length === 0)
|
|
263
|
+
return { configScope };
|
|
264
|
+
const gateways = [...new Set(modelKeys.map((key) => unifiedModels[key]?.gateway ?? nativeModels[key]?.gateway).filter((gateway) => gateway !== undefined))];
|
|
265
|
+
const providerKeys = [];
|
|
266
|
+
const harnesses = [];
|
|
267
|
+
for (const gateway of gateways) {
|
|
268
|
+
const matches = offered.filter((provider) => provider.provider === gateway);
|
|
269
|
+
// A bare gateway name in sonata.toml doesn't record which harness's
|
|
270
|
+
// discovery produced it. Exactly one matching harness is unambiguous and
|
|
271
|
+
// gets credited below. More than one *distinct* harness sharing the same
|
|
272
|
+
// provider name (e.g. opencode and pi both separately cataloging
|
|
273
|
+
// opencode.ai's public "opencode-go" gateway — verified live) is just as
|
|
274
|
+
// unattributable as no match at all: crediting every one of them
|
|
275
|
+
// pre-selects a harness the user never actually chose, with no way to
|
|
276
|
+
// make it stick unticked. Treat both cases the same way.
|
|
277
|
+
const distinctHarnesses = new Set(matches.map((provider) => provider.harness));
|
|
278
|
+
if (matches.length === 0 || distinctHarnesses.size > 1) {
|
|
279
|
+
providerKeys.push(`config/${gateway}`);
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
for (const provider of matches) {
|
|
283
|
+
if (!providerKeys.includes(provider.key))
|
|
284
|
+
providerKeys.push(provider.key);
|
|
285
|
+
if (provider.harness !== 'config' && !harnesses.includes(provider.harness)) {
|
|
286
|
+
harnesses.push(provider.harness);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return {
|
|
291
|
+
configScope,
|
|
292
|
+
harnesses,
|
|
293
|
+
providerKeys,
|
|
294
|
+
nativeKeys: modelKeys,
|
|
295
|
+
// `undefined`, not `[]`, when the config carries no role configuration at
|
|
296
|
+
// all (a valid native-only unified config with no [tiers] and no legacy
|
|
297
|
+
// generate table). `config.native.generate` is always an object once
|
|
298
|
+
// `[native]` exists at all — parsed as `{}` when there's no
|
|
299
|
+
// `[generate.native]` — so a plain `!== undefined` check would call that
|
|
300
|
+
// "configured", same bug in a different table. A syntactically present
|
|
301
|
+
// but empty `[tiers]` block, by contrast, IS explicit configuration
|
|
302
|
+
// (parseConfig accepts it without error) and must still produce `[]`,
|
|
303
|
+
// not fall through to the default: `config.tiers !== undefined` alone
|
|
304
|
+
// (not a non-empty check) preserves that distinction. Downstream,
|
|
305
|
+
// `d.roles ?? [...KNOWN_ROLES]` only falls through to the default role
|
|
306
|
+
// set on nullish, so an explicit `[]` here was read as "zero roles
|
|
307
|
+
// selected" and made scripted `sonata init --yes` throw "no roles
|
|
308
|
+
// selected" for the genuinely-unconfigured shape.
|
|
309
|
+
roles: config.tiers !== undefined || Object.keys(config.native?.generate ?? {}).length > 0
|
|
310
|
+
? Object.keys(config.tiers ?? config.native?.generate ?? {})
|
|
311
|
+
: undefined,
|
|
312
|
+
tiers: config.tiers
|
|
313
|
+
? Object.fromEntries(Object.entries(config.tiers).map(([role, lists]) => [role, { simple: [...lists.simple], complex: [...lists.complex] }]))
|
|
314
|
+
: undefined,
|
|
315
|
+
perRoleModels: Object.fromEntries(Object.entries(config.tiers ?? config.native?.generate ?? {}).map(([role, models]) => [
|
|
316
|
+
role,
|
|
317
|
+
config.tiers ? [...new Set([...models.simple, ...models.complex])] : [...models],
|
|
318
|
+
])),
|
|
319
|
+
credentialSources: Object.fromEntries(Object.entries(config.native?.gateways ?? {})
|
|
320
|
+
.filter(([, gateway]) => gateway.credentialSource !== undefined)
|
|
321
|
+
.map(([gateway, config]) => [gateway, config.credentialSource])),
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
/** NativeCandidates for every model in the config, from the config's own data. */
|
|
325
|
+
export function configNativeCandidates(config) {
|
|
326
|
+
const gateways = config.native?.gateways ?? {};
|
|
327
|
+
const unified = Object.entries(config.unifiedModels)
|
|
328
|
+
.filter(([, model]) => model.gateway !== undefined && model.id !== undefined)
|
|
329
|
+
.flatMap(([key, model]) => {
|
|
330
|
+
const gateway = model.gateway;
|
|
331
|
+
const gatewayConfig = gateways[gateway];
|
|
332
|
+
if (gatewayConfig === undefined)
|
|
333
|
+
return [];
|
|
334
|
+
return [{
|
|
335
|
+
key, gateway, id: model.id,
|
|
336
|
+
contextWindow: model.contextWindow ?? 128000,
|
|
337
|
+
baseUrl: gatewayConfig.baseUrl, auth: gatewayConfig.auth,
|
|
338
|
+
...(gatewayConfig.wireFormat !== undefined ? { wireFormat: gatewayConfig.wireFormat } : {}),
|
|
339
|
+
...(model.harness !== undefined ? { harness: model.harness, harnessId: model.harnessId } : {}),
|
|
340
|
+
}];
|
|
341
|
+
});
|
|
342
|
+
if (config.native === undefined)
|
|
343
|
+
return unified;
|
|
344
|
+
// `config.native.models` is NOT always genuine legacy data: `parseConfig`
|
|
345
|
+
// projects every unified model into it whenever `[tiers]` is present ("Tier
|
|
346
|
+
// configs are the unified format. Keep a native projection so the router
|
|
347
|
+
// and older consumers can use the same gateway/model data" — config.ts),
|
|
348
|
+
// so a tiered config's `native.models` is a harness-stripped mirror of
|
|
349
|
+
// `unifiedModels`, not independent authored data. Treating it as an
|
|
350
|
+
// independent legacy source there would make every tiered config's own
|
|
351
|
+
// projection of a model shadow that same model's richer unified entry —
|
|
352
|
+
// losing its harness/harnessId fields on every re-init. Only an UNTIERED
|
|
353
|
+
// config (`config.tiers === undefined`) can carry a genuinely distinct,
|
|
354
|
+
// hand-authored `[native.models]` table.
|
|
355
|
+
if (config.tiers !== undefined)
|
|
356
|
+
return unified;
|
|
357
|
+
// A transitional, untiered config can carry a gateway-backed `[models]`
|
|
358
|
+
// entry AND a separate `[native.models]` entry under a different key at
|
|
359
|
+
// the same time — any non-empty `unified` here used to be treated as proof
|
|
360
|
+
// the legacy table was empty, so the legacy-only key was silently dropped
|
|
361
|
+
// from the candidate list even though `deriveInitState` still names it
|
|
362
|
+
// (scripted init then rejects it as unavailable, and the interactive path
|
|
363
|
+
// can't resolve it through `nativeByKey` either). Merge the two sets.
|
|
364
|
+
const legacy = Object.entries(config.native.models).flatMap(([key, model]) => {
|
|
365
|
+
const gateway = config.native.gateways[model.gateway];
|
|
366
|
+
if (gateway === undefined)
|
|
367
|
+
return [];
|
|
368
|
+
return [{
|
|
369
|
+
key, gateway: model.gateway, id: model.id,
|
|
370
|
+
contextWindow: model.contextWindow,
|
|
371
|
+
baseUrl: gateway.baseUrl, auth: gateway.auth,
|
|
372
|
+
...(gateway.wireFormat !== undefined ? { wireFormat: gateway.wireFormat } : {}),
|
|
373
|
+
}];
|
|
374
|
+
});
|
|
375
|
+
// On a same-key collision, legacy wins — not unified. `litellmConfig`
|
|
376
|
+
// (native/litellm.ts) builds its model list from `native.models` first,
|
|
377
|
+
// unconditionally, and skips a unified entry sharing that key; letting
|
|
378
|
+
// unified win here instead would make `sonata init` silently change which
|
|
379
|
+
// upstream a key denotes relative to what's actually being served. This is
|
|
380
|
+
// safe here specifically because `config.tiers === undefined` rules out
|
|
381
|
+
// the projection case above — every entry in `native.models` at this point
|
|
382
|
+
// really was authored under `[native.models]`.
|
|
383
|
+
const legacyKeys = new Set(legacy.map((candidate) => candidate.key));
|
|
384
|
+
return [...legacy, ...unified.filter((candidate) => !legacyKeys.has(candidate.key))];
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Pre-tick from existing `[native.models]` in the config.
|
|
388
|
+
*/
|
|
389
|
+
export function preTickedNative(configText, candidates) {
|
|
390
|
+
try {
|
|
391
|
+
const config = parseConfig(configText);
|
|
392
|
+
const existing = config.tiers
|
|
393
|
+
? config.unifiedModels
|
|
394
|
+
: config.native?.models ?? {};
|
|
395
|
+
const ticked = new Set();
|
|
396
|
+
for (const c of candidates) {
|
|
397
|
+
if (existing[c.key])
|
|
398
|
+
ticked.add(c.key);
|
|
399
|
+
}
|
|
400
|
+
return ticked;
|
|
401
|
+
}
|
|
402
|
+
catch {
|
|
403
|
+
return new Set();
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Emit the unified model registry, tier lists, native gateway definitions,
|
|
408
|
+
* and runtime defaults.
|
|
409
|
+
*/
|
|
410
|
+
export function previousAskedStep(asked, from) {
|
|
411
|
+
for (let k = from - 1; k >= 0; k--)
|
|
412
|
+
if (asked[k])
|
|
413
|
+
return k;
|
|
414
|
+
return from;
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Keys claimed more than once.
|
|
418
|
+
*/
|
|
419
|
+
export function duplicateKeys(keys) {
|
|
420
|
+
const seen = new Set();
|
|
421
|
+
const dupes = new Set();
|
|
422
|
+
for (const k of keys) {
|
|
423
|
+
if (seen.has(k))
|
|
424
|
+
dupes.add(k);
|
|
425
|
+
seen.add(k);
|
|
426
|
+
}
|
|
427
|
+
return [...dupes].sort();
|
|
428
|
+
}
|
|
429
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/init/helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The wizard branch of `sonata init`.
|
|
3
|
+
*
|
|
4
|
+
* Lifted verbatim from `runInit` — the `WizardData` construction, the
|
|
5
|
+
* `runInitTui` call, `addByokCandidates`/`addLiveCandidates` registration, the
|
|
6
|
+
* BYOK base-URL fixups, the validate call, and the final `stateForPlan`
|
|
7
|
+
* shaping. Every comment is kept intact; they record real bugs.
|
|
8
|
+
*
|
|
9
|
+
* Returns the same `InitState` the scripted branch produces, plus a
|
|
10
|
+
* `cancelled` flag so `runInit` can return the standard
|
|
11
|
+
* cancelled-`InitResult` shape — that shape never lived inside the wizard
|
|
12
|
+
* branch and stays in `runInit`/`cmdInit`.
|
|
13
|
+
*
|
|
14
|
+
* `nativeByKey` is built here, not passed in: this is the front end's own
|
|
15
|
+
* candidate map for BYOK and live-candidate additions, and validate's call
|
|
16
|
+
* below resolves candidates separately. `validate` runs twice — once here
|
|
17
|
+
* to catch problems at the screen that produced them, and again in `runInit`
|
|
18
|
+
* after the state is finalised. The duplicated check is the price of
|
|
19
|
+
* surfacing the failure to the right place.
|
|
20
|
+
*/
|
|
21
|
+
import { readChatGptOAuth, readOpencodeChatGptOAuth } from '../native/codex-auth.js';
|
|
22
|
+
import { KNOWN_ROLES, configPath, } from '../config.js';
|
|
23
|
+
import { resolveKeys } from '../native/credentials.js';
|
|
24
|
+
import { credentialAvailabilityFor, nativeLabel, deriveInitState, configPathFor } from './helpers.js';
|
|
25
|
+
import { runInitTui } from '../tui-ink/run.js';
|
|
26
|
+
import { validate } from './validate.js';
|
|
27
|
+
import { addByokCandidates, addLiveCandidates, rewriteOauthToApiKey } from './candidates.js';
|
|
28
|
+
export async function interactiveState(env, opts, log) {
|
|
29
|
+
const byokUrls = new Map(env.byokProviders.map((provider) => [provider.name, provider.url]));
|
|
30
|
+
const nativeByKey = new Map(env.allNativeCandidates.map((c) => [c.key, c]));
|
|
31
|
+
const existingConfigPath = configPath(opts.cwd, opts.home);
|
|
32
|
+
const resolvedScope = existingConfigPath === configPathFor('global', opts.cwd, opts.home)
|
|
33
|
+
? 'global' : 'project';
|
|
34
|
+
const initialState = env.configsByScope[resolvedScope]
|
|
35
|
+
? deriveInitState(env.configsByScope[resolvedScope], resolvedScope, env.offered)
|
|
36
|
+
: { configScope: resolvedScope };
|
|
37
|
+
const initialStateByScope = {};
|
|
38
|
+
for (const scope of ['project', 'global']) {
|
|
39
|
+
if (env.configsByScope[scope])
|
|
40
|
+
initialStateByScope[scope] = deriveInitState(env.configsByScope[scope], scope, env.offered);
|
|
41
|
+
}
|
|
42
|
+
const codexCredential = readChatGptOAuth(opts.home, 'codex');
|
|
43
|
+
const opencodeCredential = readOpencodeChatGptOAuth(opts.home);
|
|
44
|
+
const daysUntil = (expiresAt) => expiresAt === undefined
|
|
45
|
+
? null
|
|
46
|
+
: Math.floor((expiresAt * 1000 - Date.now()) / (24 * 60 * 60 * 1000));
|
|
47
|
+
const data = {
|
|
48
|
+
home: opts.home,
|
|
49
|
+
harnesses: env.harnesses.map((h) => ({ name: h.name, installed: h.installed })),
|
|
50
|
+
providers: env.offered.map((p) => ({ key: p.key, harness: p.harness, provider: p.provider, count: p.count })),
|
|
51
|
+
candidates: env.allNativeCandidates.map((c) => ({ key: c.key, gateway: c.gateway, id: c.id, label: nativeLabel(c) })),
|
|
52
|
+
roles: [...KNOWN_ROLES],
|
|
53
|
+
byokProviders: env.byokProviders,
|
|
54
|
+
// Every offered gateway, not just the BYOK ones: the models step asks a
|
|
55
|
+
// gateway what it serves rather than trusting a harness snapshot, and
|
|
56
|
+
// that call has to authenticate. A gateway with no resolvable key simply
|
|
57
|
+
// keeps its harness list.
|
|
58
|
+
storedKeys: Object.fromEntries(resolveKeys([...new Set([...env.byokProviders.map((provider) => provider.name), ...env.offered.map((p) => p.provider)])], opts.home).map((source) => [source.gateway, source.key])),
|
|
59
|
+
credentialAvailability: credentialAvailabilityFor(env.offered, env.gatewayAuth, {
|
|
60
|
+
codex: codexCredential === null ? null : { expiresInDays: daysUntil(codexCredential.expires_at) },
|
|
61
|
+
opencode: opencodeCredential === null ? null : { expiresInDays: daysUntil(opencodeCredential.expires_at) },
|
|
62
|
+
// Unlike the `oauthProviders` call above, this specifically reports
|
|
63
|
+
// whether *opencode's* token is importable — so it stays gated on
|
|
64
|
+
// exchangeability, not mere presence.
|
|
65
|
+
copilot: env.copilotUsable ? { expiresInDays: null } : null,
|
|
66
|
+
}, (gateway) => resolveKeys([gateway], opts.home)[0] !== undefined),
|
|
67
|
+
gatewayAuth: Object.fromEntries(env.gatewayAuth),
|
|
68
|
+
gatewayBaseUrls: env.providerBaseUrls,
|
|
69
|
+
avoidGateways: env.configsByScope[resolvedScope]?.avoidGateways ?? [],
|
|
70
|
+
initialState,
|
|
71
|
+
initialStateByScope,
|
|
72
|
+
};
|
|
73
|
+
log.line(`wizard: offering ${data.providers.length} providers, ${data.candidates.length} models`);
|
|
74
|
+
const result = await runInitTui(data, (line) => log.line(line));
|
|
75
|
+
// Keys are recorded as the gateways they belong to, never as their value.
|
|
76
|
+
log.line(`wizard returned: cancelled=${result.cancelled} scope=${result.state.configScope} ` +
|
|
77
|
+
`providers=[${result.state.providerKeys ?? []}] models=[${result.state.nativeKeys ?? []}] ` +
|
|
78
|
+
`roles=[${result.state.roles ?? []}] keysEnteredFor=[${Object.keys(result.state.byokKeys ?? {})}]`);
|
|
79
|
+
if (result.cancelled) {
|
|
80
|
+
return { state: result.state, nativeByKey, cancelled: true };
|
|
81
|
+
}
|
|
82
|
+
// Map result.state to the variables the write path needs.
|
|
83
|
+
const configScope = result.state.configScope ?? 'project';
|
|
84
|
+
// Custom providers added through the wizard: register their URL before
|
|
85
|
+
// adding BYOK candidates so validate() can exclude them from the
|
|
86
|
+
// unknown-providers check.
|
|
87
|
+
for (const provider of result.state.customProviders ?? []) {
|
|
88
|
+
byokUrls.set(provider.name, provider.url);
|
|
89
|
+
}
|
|
90
|
+
addByokCandidates(nativeByKey, byokUrls, result.state.byokModels ?? {}, result.state.customWireFormats);
|
|
91
|
+
addLiveCandidates(env, nativeByKey, result.state.liveModels ?? {});
|
|
92
|
+
rewriteOauthToApiKey(nativeByKey, result.state.byokKeys ?? {});
|
|
93
|
+
const credentialSources = result.state.credentialSources ?? {};
|
|
94
|
+
const nativeKeys = result.state.nativeKeys ?? [];
|
|
95
|
+
const roles = result.state.roles ?? [...KNOWN_ROLES];
|
|
96
|
+
// Validate interactive path state (after customProviders are registered
|
|
97
|
+
// so the unknown-providers check skips them).
|
|
98
|
+
const state = {
|
|
99
|
+
configScope,
|
|
100
|
+
providerKeys: result.state.providerKeys ?? [],
|
|
101
|
+
nativeKeys,
|
|
102
|
+
roles,
|
|
103
|
+
credentialSources,
|
|
104
|
+
routing: result.state.routing ?? 'project',
|
|
105
|
+
customProviders: result.state.customProviders,
|
|
106
|
+
};
|
|
107
|
+
const problems = validate(env, state, { nativeByKey });
|
|
108
|
+
if (problems.length > 0)
|
|
109
|
+
throw new Error(problems[0].message);
|
|
110
|
+
// Build stateForPlan for interactive branch
|
|
111
|
+
const stateForPlan = {
|
|
112
|
+
configScope,
|
|
113
|
+
providerKeys: result.state.providerKeys ?? [],
|
|
114
|
+
nativeKeys,
|
|
115
|
+
roles,
|
|
116
|
+
credentialSources,
|
|
117
|
+
routing: result.state.routing ?? 'project',
|
|
118
|
+
hookScope: result.state.hookScope ?? 'project',
|
|
119
|
+
customProviders: result.state.customProviders,
|
|
120
|
+
byokModels: result.state.byokModels,
|
|
121
|
+
liveModels: result.state.liveModels,
|
|
122
|
+
customWireFormats: result.state.customWireFormats,
|
|
123
|
+
byokKeys: result.state.byokKeys,
|
|
124
|
+
tiers: result.state.tiers,
|
|
125
|
+
};
|
|
126
|
+
return { state: stateForPlan, nativeByKey, cancelled: false };
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=interactive-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive-state.js","sourceRoot":"","sources":["../../src/init/interactive-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACrF,OAAO,EACL,WAAW,EAAE,UAAU,GACxB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,yBAAyB,EAAE,WAAW,EAAE,eAAe,EAAE,aAAa,EAAwB,MAAM,cAAc,CAAC;AAC5H,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAK/C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAG7F,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,GAAoB,EACpB,IAMC,EACD,GAAY;IAEZ,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC7F,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5E,MAAM,kBAAkB,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3D,MAAM,aAAa,GAAgB,kBAAkB,KAAK,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC;QACpG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;IACzB,MAAM,YAAY,GAAG,GAAG,CAAC,cAAc,CAAC,aAAa,CAAC;QACpD,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,cAAc,CAAC,aAAa,CAAE,EAAE,aAAa,EAAE,GAAG,CAAC,OAAO,CAAC;QACjF,CAAC,CAAC,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC;IACnC,MAAM,mBAAmB,GAA4C,EAAE,CAAC;IACxE,KAAK,MAAM,KAAK,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAU,EAAE,CAAC;QACnD,IAAI,GAAG,CAAC,cAAc,CAAC,KAAK,CAAC;YAAE,mBAAmB,CAAC,KAAK,CAAC,GAAG,eAAe,CAAC,GAAG,CAAC,cAAc,CAAC,KAAK,CAAE,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IAC9H,CAAC;IAED,MAAM,eAAe,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC7D,MAAM,kBAAkB,GAAG,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/D,MAAM,SAAS,GAAG,CAAC,SAA6B,EAAiB,EAAE,CAAC,SAAS,KAAK,SAAS;QACzF,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;IACxE,MAAM,IAAI,GAAe;QACvB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,SAAS,EAAE,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;QAC/E,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QAC7G,UAAU,EAAE,GAAG,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACrH,KAAK,EAAE,CAAC,GAAG,WAAW,CAAC;QACvB,aAAa,EAAE,GAAG,CAAC,aAAa;QAChC,wEAAwE;QACxE,sEAAsE;QACtE,yEAAyE;QACzE,0BAA0B;QAC1B,UAAU,EAAE,MAAM,CAAC,WAAW,CAC5B,WAAW,CACT,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAC5G,IAAI,CAAC,IAAI,CACV,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAChD;QACD,sBAAsB,EAAE,yBAAyB,CAC/C,GAAG,CAAC,OAAO,EACX,GAAG,CAAC,WAAW,EACf;YACE,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,SAAS,CAAC,eAAe,CAAC,UAAU,CAAC,EAAE;YACjG,QAAQ,EAAE,kBAAkB,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,SAAS,CAAC,kBAAkB,CAAC,UAAU,CAAC,EAAE;YAC1G,oEAAoE;YACpE,kEAAkE;YAClE,sCAAsC;YACtC,OAAO,EAAE,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI;SAC5D,EACD,CAAC,OAAO,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS,CAChE;QACD,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC;QAChD,eAAe,EAAE,GAAG,CAAC,gBAAgB;QACrC,aAAa,EAAE,GAAG,CAAC,cAAc,CAAC,aAAa,CAAC,EAAE,aAAa,IAAI,EAAE;QACrE,YAAY;QACZ,mBAAmB;KACpB,CAAC;IACF,GAAG,CAAC,IAAI,CAAC,oBAAoB,IAAI,CAAC,SAAS,CAAC,MAAM,eAAe,IAAI,CAAC,UAAU,CAAC,MAAM,SAAS,CAAC,CAAC;IAClG,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAChE,0EAA0E;IAC1E,GAAG,CAAC,IAAI,CAAC,8BAA8B,MAAM,CAAC,SAAS,UAAU,MAAM,CAAC,KAAK,CAAC,WAAW,GAAG;QAC1F,cAAc,MAAM,CAAC,KAAK,CAAC,YAAY,IAAI,EAAE,aAAa,MAAM,CAAC,KAAK,CAAC,UAAU,IAAI,EAAE,IAAI;QAC3F,UAAU,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,qBAAqB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC;IAEtG,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACrB,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAC/D,CAAC;IAED,0DAA0D;IAC1D,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,IAAI,SAAS,CAAC;IAC1D,uEAAuE;IACvE,iEAAiE;IACjE,2BAA2B;IAC3B,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,eAAe,IAAI,EAAE,EAAE,CAAC;QAC1D,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC5C,CAAC;IACD,iBAAiB,CAAC,WAAW,EAAE,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU,IAAI,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACxG,iBAAiB,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;IACnE,oBAAoB,CAAC,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;IAC/D,MAAM,iBAAiB,GAAG,MAAM,CAAC,KAAK,CAAC,iBAAiB,IAAI,EAAE,CAAC;IAC/D,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,UAAU,IAAI,EAAE,CAAC;IACjD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC;IAErD,wEAAwE;IACxE,8CAA8C;IAC9C,MAAM,KAAK,GAAc;QACvB,WAAW;QACX,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,YAAY,IAAI,EAAE;QAC7C,UAAU;QACV,KAAK;QACL,iBAAiB;QACjB,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,IAAI,SAAS;QAC1C,eAAe,EAAE,MAAM,CAAC,KAAK,CAAC,eAAe;KAC9C,CAAC;IACF,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;IACvD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAE9D,4CAA4C;IAC5C,MAAM,YAAY,GAAc;QAC9B,WAAW;QACX,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,YAAY,IAAI,EAAE;QAC7C,UAAU;QACV,KAAK;QACL,iBAAiB;QACjB,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,IAAI,SAAS;QAC1C,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,IAAI,SAAS;QAC9C,eAAe,EAAE,MAAM,CAAC,KAAK,CAAC,eAAe;QAC7C,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU;QACnC,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU;QACnC,iBAAiB,EAAE,MAAM,CAAC,KAAK,CAAC,iBAAiB;QACjD,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ;QAC/B,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK;KAC1B,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;AAChE,CAAC"}
|