@heyditto/cli 3.9.0 → 3.10.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.
@@ -0,0 +1,325 @@
1
+ /**
2
+ * `heyditto profile`: named endpoint profiles, and the one place the CLI asks
3
+ * "which endpoint does the user mean when they did not say?".
4
+ *
5
+ * Selection order for a command that reads the default endpoint:
6
+ * --profile <name> (this command only)
7
+ * DITTO_PROFILE (this shell only)
8
+ * the active profile (`heyditto profile use <name>`)
9
+ * With no saved profiles, the implicit `default` profile is `defaultEndpoint`,
10
+ * so an existing install behaves exactly as before.
11
+ */
12
+ import { Option } from "commander";
13
+ import { findEndpoint, listEndpoints } from "./api.js";
14
+ import { LEGACY_PROFILE, materialize, profileView, profilesPatch, setProfileEndpointPatch, unknownProfileMessage, validateProfileName, } from "./profile-state.js";
15
+ import { readStoredAuth, updateStoredAuth } from "./store.js";
16
+ let flagOverride;
17
+ /** Set by `--profile` for the duration of one command. */
18
+ export function setProfileOverride(name) {
19
+ flagOverride = name?.trim() || undefined;
20
+ }
21
+ /** The profile the user named for this command (flag, then env), if any. */
22
+ export function requestedProfile() {
23
+ if (flagOverride)
24
+ return { name: flagOverride, source: "flag" };
25
+ const env = process.env.DITTO_PROFILE?.trim();
26
+ return env ? { name: env, source: "env" } : undefined;
27
+ }
28
+ function select(stored, view = profileView(stored)) {
29
+ const requested = requestedProfile();
30
+ if (requested) {
31
+ const profile = view.profiles[requested.name];
32
+ if (!profile) {
33
+ const via = requested.source === "env" ? " (from DITTO_PROFILE)" : "";
34
+ throw new Error(unknownProfileMessage(requested.name, view) + via);
35
+ }
36
+ return { name: requested.name, profile, source: requested.source, implicit: view.implicit };
37
+ }
38
+ return { name: view.active, profile: view.profiles[view.active], source: "active", implicit: view.implicit };
39
+ }
40
+ export async function selectedProfile() {
41
+ return select(await readStoredAuth());
42
+ }
43
+ /** The endpoint used when --endpoint is omitted: the selected profile's. */
44
+ export async function readDefaultEndpoint() {
45
+ return (await selectedProfile()).profile.endpoint?.trim() || undefined;
46
+ }
47
+ /** Saves (or clears) the endpoint of the selected profile; other profiles are untouched. */
48
+ export async function writeDefaultEndpoint(endpoint) {
49
+ const stored = await readStoredAuth();
50
+ const selected = select(stored);
51
+ await updateStoredAuth(setProfileEndpointPatch(stored, selected.name, endpoint));
52
+ return selected.name;
53
+ }
54
+ /**
55
+ * The endpoint of a profile the user explicitly named (--profile or
56
+ * DITTO_PROFILE), for a launch that should treat it like --endpoint. Undefined
57
+ * when no profile was named; an error when the named one has no endpoint.
58
+ */
59
+ export async function explicitProfileEndpoint() {
60
+ const requested = requestedProfile();
61
+ if (!requested)
62
+ return undefined;
63
+ const selected = await selectedProfile();
64
+ const endpoint = selected.profile.endpoint?.trim();
65
+ if (!endpoint) {
66
+ throw new Error(`profile "${selected.name}" has no endpoint. Set one with \`heyditto profile set ${selected.name} --endpoint <slug>\`.`);
67
+ }
68
+ return { name: selected.name, endpoint, source: requested.source };
69
+ }
70
+ /** After an endpoint's slug changes, follow it in every profile that named it. */
71
+ export async function renameEndpointInProfiles(oldSlug, newSlug) {
72
+ const stored = await readStoredAuth();
73
+ const view = profileView(stored);
74
+ if (view.implicit) {
75
+ if (stored?.defaultEndpoint === oldSlug)
76
+ await updateStoredAuth({ defaultEndpoint: newSlug });
77
+ return;
78
+ }
79
+ let changed = false;
80
+ const profiles = {};
81
+ for (const [name, profile] of Object.entries(view.profiles)) {
82
+ if (profile.endpoint === oldSlug) {
83
+ profiles[name] = { ...profile, endpoint: newSlug };
84
+ changed = true;
85
+ }
86
+ else
87
+ profiles[name] = profile;
88
+ }
89
+ if (changed)
90
+ await updateStoredAuth(profilesPatch(profiles, view.active));
91
+ }
92
+ /** After an endpoint is archived, drop it from every profile that named it (by slug or id). */
93
+ export async function forgetEndpointInProfiles(refs) {
94
+ const stored = await readStoredAuth();
95
+ const view = profileView(stored);
96
+ const matches = (value) => value !== undefined && refs.includes(value);
97
+ if (view.implicit) {
98
+ if (matches(stored?.defaultEndpoint))
99
+ await updateStoredAuth({ defaultEndpoint: undefined });
100
+ return;
101
+ }
102
+ let changed = false;
103
+ const profiles = {};
104
+ for (const [name, profile] of Object.entries(view.profiles)) {
105
+ if (matches(profile.endpoint)) {
106
+ const { endpoint: _dropped, ...rest } = profile;
107
+ profiles[name] = rest;
108
+ changed = true;
109
+ }
110
+ else
111
+ profiles[name] = profile;
112
+ }
113
+ if (changed)
114
+ await updateStoredAuth(profilesPatch(profiles, view.active));
115
+ }
116
+ const tagged = new WeakSet();
117
+ /** `--profile <name>` for a command that reads the default endpoint. */
118
+ export function addProfileOption(cmd) {
119
+ tagged.add(cmd);
120
+ return cmd.option("--profile <name>", "use this endpoint profile for this command only (default: DITTO_PROFILE, then the active profile)");
121
+ }
122
+ /**
123
+ * Applies `--profile` before any action runs. Only commands tagged by
124
+ * addProfileOption are read, so `repo apply --profile` and `review local
125
+ * --profile`, which mean something else, are left alone.
126
+ */
127
+ export function installProfileHook(program) {
128
+ program.hook("preAction", (_root, action) => {
129
+ setProfileOverride(tagged.has(action) ? action.getOptionValue("profile") : undefined);
130
+ });
131
+ }
132
+ const json = (options) => options.output === "json";
133
+ const print = (value) => { process.stdout.write(`${JSON.stringify(value, null, 2)}\n`); };
134
+ function inferenceOf(raw) {
135
+ if (raw === undefined)
136
+ return undefined;
137
+ if (raw !== "router" && raw !== "cliproxy")
138
+ throw new Error("--inference must be router or cliproxy");
139
+ return raw;
140
+ }
141
+ /** Resolves an endpoint ref through the catalog and returns its canonical slug. */
142
+ async function canonicalEndpoint(ref) {
143
+ const catalog = await listEndpoints();
144
+ const match = findEndpoint(catalog.endpoints, ref.trim());
145
+ if (!match)
146
+ throw new Error(`no endpoint named "${ref.trim()}". Available: ${catalog.endpoints.map((e) => e.slug).join(", ") || "(none)"}`);
147
+ return match.slug;
148
+ }
149
+ function listJSON(view) {
150
+ return {
151
+ activeProfile: view.active,
152
+ implicit: view.implicit,
153
+ profiles: Object.keys(view.profiles).sort().map((name) => ({
154
+ name,
155
+ endpoint: view.profiles[name].endpoint ?? null,
156
+ inference: view.profiles[name].inference ?? "cliproxy",
157
+ active: name === view.active,
158
+ })),
159
+ };
160
+ }
161
+ export async function cmdProfileList(options) {
162
+ const stored = await readStoredAuth();
163
+ const view = profileView(stored);
164
+ const requested = requestedProfile();
165
+ if (json(options))
166
+ return print({ ...listJSON(view), ...(requested ? { selected: requested.name, selectedBy: requested.source } : {}) });
167
+ const rows = listJSON(view).profiles;
168
+ const width = Math.max(...rows.map((r) => r.name.length), 4);
169
+ process.stdout.write(` ${"NAME".padEnd(width)} ENDPOINT (INFERENCE)\n`);
170
+ for (const row of rows) {
171
+ process.stdout.write(`${row.active ? "*" : " "} ${row.name.padEnd(width)} ${row.endpoint ?? "(none)"} (${row.inference})\n`);
172
+ }
173
+ if (view.implicit)
174
+ process.stdout.write("\nNo profiles saved yet; `default` is your saved default endpoint. Create one with `heyditto profile create <name> --endpoint <slug>`.\n");
175
+ if (requested)
176
+ process.stdout.write(`\n${requested.source === "env" ? "DITTO_PROFILE" : "--profile"} selects "${requested.name}" for this command.\n`);
177
+ }
178
+ export async function cmdProfileCreate(rawName, options) {
179
+ const name = validateProfileName(rawName);
180
+ const inference = inferenceOf(options.inference);
181
+ const assertCreatable = (view) => {
182
+ if (!view.implicit && Object.hasOwn(view.profiles, name))
183
+ throw new Error(`profile "${name}" already exists; change it with \`heyditto profile set ${name}\``);
184
+ if (view.implicit && name === LEGACY_PROFILE && view.profiles[LEGACY_PROFILE].endpoint) {
185
+ throw new Error(`"${LEGACY_PROFILE}" already names your saved default endpoint; change it with \`heyditto profile set ${LEGACY_PROFILE} --endpoint <slug>\``);
186
+ }
187
+ };
188
+ // Fail fast on a name clash before the network lookup...
189
+ assertCreatable(profileView(await readStoredAuth()));
190
+ const endpoint = await canonicalEndpoint(options.endpoint);
191
+ // ...but build the write from state read after it: another heyditto may
192
+ // have changed profiles while the lookup was in flight, and a patch built
193
+ // from the earlier snapshot would silently drop that change.
194
+ const stored = await readStoredAuth();
195
+ const view = profileView(stored);
196
+ assertCreatable(view);
197
+ const { profiles, active } = materialize(stored);
198
+ const created = { endpoint, ...(inference ? { inference } : {}), createdAt: new Date().toISOString() };
199
+ const nextActive = options.use || active === undefined ? name : active;
200
+ await updateStoredAuth(profilesPatch({ ...profiles, [name]: created }, nextActive));
201
+ if (json(options))
202
+ return print({ name, endpoint, inference: inference ?? "cliproxy", active: nextActive === name, activeProfile: nextActive });
203
+ process.stdout.write(`Created profile ${name} → ${endpoint}${nextActive === name ? " (active)" : ""}.\n`);
204
+ if (view.implicit && profiles[LEGACY_PROFILE]) {
205
+ process.stdout.write(`Your previous default endpoint is saved as profile "${LEGACY_PROFILE}"${nextActive === LEGACY_PROFILE ? " and stays active" : ""}.\n`);
206
+ }
207
+ if (nextActive !== name)
208
+ process.stdout.write(`Switch with \`heyditto profile use ${name}\`, or pass --profile ${name} to one command.\n`);
209
+ }
210
+ export async function cmdProfileSet(rawName, options) {
211
+ const name = rawName.trim();
212
+ const inference = inferenceOf(options.inference);
213
+ if (options.endpoint === undefined && inference === undefined)
214
+ throw new Error("nothing to change: pass --endpoint and/or --inference");
215
+ const stored = await readStoredAuth();
216
+ const view = profileView(stored);
217
+ if (!Object.hasOwn(view.profiles, name))
218
+ throw new Error(unknownProfileMessage(name, view));
219
+ const endpoint = options.endpoint !== undefined ? await canonicalEndpoint(options.endpoint) : undefined;
220
+ let profiles;
221
+ let active;
222
+ if (view.implicit && inference === undefined) {
223
+ await updateStoredAuth({ defaultEndpoint: endpoint });
224
+ }
225
+ else {
226
+ ({ profiles, active } = materialize(stored));
227
+ // An implicit default with no endpoint is not materialized; recreate it.
228
+ const current = profiles[name] ?? {};
229
+ const next = { ...current, ...(endpoint ? { endpoint } : {}), ...(inference ? { inference } : {}) };
230
+ await updateStoredAuth(profilesPatch({ ...profiles, [name]: next }, active ?? name));
231
+ }
232
+ const after = profileView(await readStoredAuth()).profiles[name];
233
+ if (json(options))
234
+ return print({ name, endpoint: after.endpoint ?? null, inference: after.inference ?? "cliproxy" });
235
+ process.stdout.write(`Profile ${name} → ${after.endpoint ?? "(none)"} (${after.inference ?? "cliproxy"}).\n`);
236
+ }
237
+ export async function cmdProfileUse(rawName, options) {
238
+ const name = rawName.trim();
239
+ const stored = await readStoredAuth();
240
+ const view = profileView(stored);
241
+ if (!Object.hasOwn(view.profiles, name))
242
+ throw new Error(unknownProfileMessage(name, view));
243
+ if (!view.implicit)
244
+ await updateStoredAuth(profilesPatch(view.profiles, name));
245
+ const endpoint = view.profiles[name].endpoint ?? null;
246
+ if (json(options))
247
+ return print({ activeProfile: name, endpoint });
248
+ process.stdout.write(`Active profile: ${name} → ${endpoint ?? "(no endpoint yet)"}. New heyditto sessions use it; existing T3 providers keep their own endpoints.\n`);
249
+ if (process.env.DITTO_PROFILE?.trim() && process.env.DITTO_PROFILE.trim() !== name) {
250
+ process.stderr.write(`Note: DITTO_PROFILE=${process.env.DITTO_PROFILE.trim()} still overrides it in this shell.\n`);
251
+ }
252
+ }
253
+ export async function cmdProfileRename(rawOld, rawNew, options) {
254
+ const from = rawOld.trim();
255
+ const to = validateProfileName(rawNew);
256
+ const stored = await readStoredAuth();
257
+ const view = profileView(stored);
258
+ if (!Object.hasOwn(view.profiles, from))
259
+ throw new Error(unknownProfileMessage(from, view));
260
+ if (from === to)
261
+ throw new Error("the new name is the same as the old one");
262
+ if (Object.hasOwn(view.profiles, to))
263
+ throw new Error(`profile "${to}" already exists`);
264
+ const { profiles, active } = materialize(stored);
265
+ const renamed = {};
266
+ for (const [name, profile] of Object.entries(profiles))
267
+ renamed[name === from ? to : name] = profile;
268
+ if (!Object.hasOwn(renamed, to))
269
+ renamed[to] = { ...view.profiles[from] };
270
+ await updateStoredAuth(profilesPatch(renamed, active === from || active === undefined ? to : active));
271
+ if (json(options))
272
+ return print({ renamed: from, to });
273
+ process.stdout.write(`Renamed profile ${from} → ${to}. T3 providers created from it keep their instance id and endpoint.\n`);
274
+ }
275
+ export async function cmdProfileDelete(rawName, options) {
276
+ const name = rawName.trim();
277
+ const stored = await readStoredAuth();
278
+ const view = profileView(stored);
279
+ if (!Object.hasOwn(view.profiles, name))
280
+ throw new Error(unknownProfileMessage(name, view));
281
+ if (name === view.active)
282
+ throw new Error(`profile "${name}" is active; switch to another with \`heyditto profile use <name>\` before deleting it`);
283
+ const { profiles, active } = materialize(stored);
284
+ const { [name]: _removed, ...rest } = profiles;
285
+ await updateStoredAuth(profilesPatch(rest, active));
286
+ if (json(options))
287
+ return print({ deleted: name });
288
+ process.stdout.write(`Deleted profile ${name}. Its endpoint and any T3 provider made from it are unchanged.\n`);
289
+ }
290
+ export function registerProfileCommands(program, addExamples, outputOption) {
291
+ const profile = program
292
+ .command("profile")
293
+ .description("named endpoint profiles: switch which endpoint (and its MCP tools) new sessions use")
294
+ .summary("manage named endpoint profiles")
295
+ .showHelpAfterError()
296
+ .addHelpText("after", `
297
+ A profile names an endpoint. The active one is used when --endpoint is
298
+ omitted; --profile <name> or DITTO_PROFILE=<name> picks another for one
299
+ command or one shell. Profiles are local to this machine and hold no keys.
300
+ (\`heyditto profiles\` is an older alias of \`heyditto endpoints\`.)`);
301
+ addExamples(profile.command("list", { isDefault: true }).description("list profiles (* = active)").addOption(outputOption()).action(cmdProfileList), ` heyditto profile
302
+ heyditto profile list --output json`);
303
+ addExamples(profile
304
+ .command("create")
305
+ .description("save a profile for an endpoint (your current default is kept as profile \"default\")")
306
+ .argument("<name>", "profile name (lowercase letters, digits, - or _)")
307
+ .requiredOption("--endpoint <slug>", "endpoint slug or id")
308
+ .addOption(new Option("--inference <mode>", "inference route for `heyditto t3 setup --profile` (default cliproxy)").choices(["cliproxy", "router"]))
309
+ .option("--use", "make it the active profile")
310
+ .addOption(outputOption())
311
+ .action(cmdProfileCreate), ` heyditto profile create subnet --endpoint my-subnet-endpoint
312
+ heyditto profile create work --endpoint work-router --inference router --use`);
313
+ profile
314
+ .command("set")
315
+ .description("change a profile's endpoint or inference route")
316
+ .argument("<name>")
317
+ .option("--endpoint <slug>", "endpoint slug or id")
318
+ .addOption(new Option("--inference <mode>", "inference route for T3 setup").choices(["cliproxy", "router"]))
319
+ .addOption(outputOption())
320
+ .action(cmdProfileSet);
321
+ profile.command("use").alias("switch").description("make a profile active for new sessions").argument("<name>").addOption(outputOption()).action(cmdProfileUse);
322
+ profile.command("rename").description("rename a profile").argument("<old>").argument("<new>").addOption(outputOption()).action(cmdProfileRename);
323
+ profile.command("delete").alias("rm").description("delete a profile (not the active one)").argument("<name>").addOption(outputOption()).action(cmdProfileDelete);
324
+ }
325
+ //# sourceMappingURL=profiles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profiles.js","sourceRoot":"","sources":["../src/profiles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAgB,MAAM,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACvD,OAAO,EAIL,cAAc,EACd,WAAW,EACX,WAAW,EACX,aAAa,EACb,uBAAuB,EACvB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAmB,cAAc,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAY/E,IAAI,YAAgC,CAAC;AAErC,0DAA0D;AAC1D,MAAM,UAAU,kBAAkB,CAAC,IAAwB;IACzD,YAAY,GAAG,IAAI,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;AAC3C,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,gBAAgB;IAC9B,IAAI,YAAY;QAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAChE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,EAAE,CAAC;IAC9C,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACxD,CAAC;AAED,SAAS,MAAM,CAAC,MAA8B,EAAE,OAAoB,WAAW,CAAC,MAAM,CAAC;IACrF,MAAM,SAAS,GAAG,gBAAgB,EAAE,CAAC;IACrC,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,EAAE,CAAC;YACtE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;QACrE,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;IAC9F,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;AAC/G,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,OAAO,MAAM,CAAC,MAAM,cAAc,EAAE,CAAC,CAAC;AACxC,CAAC;AAED,4EAA4E;AAC5E,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,OAAO,CAAC,MAAM,eAAe,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;AACzE,CAAC;AAED,4FAA4F;AAC5F,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,QAA4B;IACrE,MAAM,MAAM,GAAG,MAAM,cAAc,EAAE,CAAC;IACtC,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAChC,MAAM,gBAAgB,CAAC,uBAAuB,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;IACjF,OAAO,QAAQ,CAAC,IAAI,CAAC;AACvB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB;IAC3C,MAAM,SAAS,GAAG,gBAAgB,EAAE,CAAC;IACrC,IAAI,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IACjC,MAAM,QAAQ,GAAG,MAAM,eAAe,EAAE,CAAC;IACzC,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC;IACnD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,YAAY,QAAQ,CAAC,IAAI,0DAA0D,QAAQ,CAAC,IAAI,uBAAuB,CAAC,CAAC;IAC3I,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC;AACrE,CAAC;AAED,kFAAkF;AAClF,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,OAAe,EAAE,OAAe;IAC7E,MAAM,MAAM,GAAG,MAAM,cAAc,EAAE,CAAC;IACtC,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClB,IAAI,MAAM,EAAE,eAAe,KAAK,OAAO;YAAE,MAAM,gBAAgB,CAAC,EAAE,eAAe,EAAE,OAAO,EAAE,CAAC,CAAC;QAC9F,OAAO;IACT,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,MAAM,QAAQ,GAAoC,EAAE,CAAC;IACrD,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5D,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YACjC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;YACnD,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;;YAAM,QAAQ,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC;IAClC,CAAC;IACD,IAAI,OAAO;QAAE,MAAM,gBAAgB,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;AAC5E,CAAC;AAED,+FAA+F;AAC/F,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,IAAc;IAC3D,MAAM,MAAM,GAAG,MAAM,cAAc,EAAE,CAAC;IACtC,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,MAAM,OAAO,GAAG,CAAC,KAAyB,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC3F,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClB,IAAI,OAAO,CAAC,MAAM,EAAE,eAAe,CAAC;YAAE,MAAM,gBAAgB,CAAC,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC,CAAC;QAC7F,OAAO;IACT,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,MAAM,QAAQ,GAAoC,EAAE,CAAC;IACrD,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5D,IAAI,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9B,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;YAChD,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;YACtB,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;;YAAM,QAAQ,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC;IAClC,CAAC;IACD,IAAI,OAAO;QAAE,MAAM,gBAAgB,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,MAAM,GAAG,IAAI,OAAO,EAAW,CAAC;AAEtC,wEAAwE;AACxE,MAAM,UAAU,gBAAgB,CAAC,GAAY;IAC3C,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChB,OAAO,GAAG,CAAC,MAAM,CAAC,kBAAkB,EAAE,mGAAmG,CAAC,CAAC;AAC7I,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;QAC1C,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAE,MAAM,CAAC,cAAc,CAAC,SAAS,CAAwB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAChH,CAAC,CAAC,CAAC;AACL,CAAC;AAMD,MAAM,IAAI,GAAG,CAAC,OAAsB,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,KAAK,MAAM,CAAC;AACnE,MAAM,KAAK,GAAG,CAAC,KAAc,EAAQ,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAEzG,SAAS,WAAW,CAAC,GAAuB;IAC1C,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACxC,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IACtG,OAAO,GAAG,CAAC;AACb,CAAC;AAED,mFAAmF;AACnF,KAAK,UAAU,iBAAiB,CAAC,GAAW;IAC1C,MAAM,OAAO,GAAG,MAAM,aAAa,EAAE,CAAC;IACtC,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1D,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,GAAG,CAAC,IAAI,EAAE,iBAAiB,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,EAAE,CAAC,CAAC;IAC5I,OAAO,KAAK,CAAC,IAAI,CAAC;AACpB,CAAC;AAED,SAAS,QAAQ,CAAC,IAAiB;IACjC,OAAO;QACL,aAAa,EAAE,IAAI,CAAC,MAAM;QAC1B,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACzD,IAAI;YACJ,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,IAAI,IAAI;YAC9C,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,SAAS,IAAI,UAAU;YACtD,MAAM,EAAE,IAAI,KAAK,IAAI,CAAC,MAAM;SAC7B,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAsB;IACzD,MAAM,MAAM,GAAG,MAAM,cAAc,EAAE,CAAC;IACtC,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,MAAM,SAAS,GAAG,gBAAgB,EAAE,CAAC;IACrC,IAAI,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACzI,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC;IACrC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC3E,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,QAAQ,IAAI,QAAQ,MAAM,GAAG,CAAC,SAAS,KAAK,CAAC,CAAC;IACjI,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,0IAA0I,CAAC,CAAC;IACpL,IAAI,SAAS;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,WAAW,aAAa,SAAS,CAAC,IAAI,uBAAuB,CAAC,CAAC;AACzJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,OAAe,EAAE,OAAgF;IACtI,MAAM,IAAI,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACjD,MAAM,eAAe,GAAG,CAAC,IAAiB,EAAQ,EAAE;QAClD,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,YAAY,IAAI,2DAA2D,IAAI,IAAI,CAAC,CAAC;QAC/J,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,KAAK,cAAc,IAAI,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,QAAQ,EAAE,CAAC;YACvF,MAAM,IAAI,KAAK,CAAC,IAAI,cAAc,sFAAsF,cAAc,sBAAsB,CAAC,CAAC;QAChK,CAAC;IACH,CAAC,CAAC;IACF,yDAAyD;IACzD,eAAe,CAAC,WAAW,CAAC,MAAM,cAAc,EAAE,CAAC,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC3D,wEAAwE;IACxE,0EAA0E;IAC1E,6DAA6D;IAC7D,MAAM,MAAM,GAAG,MAAM,cAAc,EAAE,CAAC;IACtC,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,eAAe,CAAC,IAAI,CAAC,CAAC;IACtB,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACjD,MAAM,OAAO,GAAoB,EAAE,QAAQ,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;IACxH,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,IAAI,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;IACvE,MAAM,gBAAgB,CAAC,aAAa,CAAC,EAAE,GAAG,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC;IACpF,IAAI,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,IAAI,UAAU,EAAE,MAAM,EAAE,UAAU,KAAK,IAAI,EAAE,aAAa,EAAE,UAAU,EAAE,CAAC,CAAC;IAChJ,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,IAAI,MAAM,QAAQ,GAAG,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAC1G,IAAI,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;QAC9C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uDAAuD,cAAc,IAAI,UAAU,KAAK,cAAc,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAC/J,CAAC;IACD,IAAI,UAAU,KAAK,IAAI;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sCAAsC,IAAI,yBAAyB,IAAI,oBAAoB,CAAC,CAAC;AAC7I,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAe,EAAE,OAAkE;IACrH,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAC5B,MAAM,SAAS,GAAG,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACjD,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS,IAAI,SAAS,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IACxI,MAAM,MAAM,GAAG,MAAM,cAAc,EAAE,CAAC;IACtC,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IAC5F,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,iBAAiB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACxG,IAAI,QAAyC,CAAC;IAC9C,IAAI,MAA0B,CAAC;IAC/B,IAAI,IAAI,CAAC,QAAQ,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC7C,MAAM,gBAAgB,CAAC,EAAE,eAAe,EAAE,QAAQ,EAAE,CAAC,CAAC;IACxD,CAAC;SAAM,CAAC;QACN,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;QAC7C,yEAAyE;QACzE,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACrC,MAAM,IAAI,GAAoB,EAAE,GAAG,OAAO,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QACrH,MAAM,gBAAgB,CAAC,aAAa,CAAC,EAAE,GAAG,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC;IACvF,CAAC;IACD,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,cAAc,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjE,IAAI,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,UAAU,EAAE,CAAC,CAAC;IACtH,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,IAAI,MAAM,KAAK,CAAC,QAAQ,IAAI,QAAQ,KAAK,KAAK,CAAC,SAAS,IAAI,UAAU,MAAM,CAAC,CAAC;AAChH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAe,EAAE,OAAsB;IACzE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAC5B,MAAM,MAAM,GAAG,MAAM,cAAc,EAAE,CAAC;IACtC,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IAC5F,IAAI,CAAC,IAAI,CAAC,QAAQ;QAAE,MAAM,gBAAgB,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;IAC/E,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC;IACtD,IAAI,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;IACnE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,IAAI,MAAM,QAAQ,IAAI,mBAAmB,mFAAmF,CAAC,CAAC;IACtK,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;QACnF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uBAAuB,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE,sCAAsC,CAAC,CAAC;IACtH,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,MAAc,EAAE,MAAc,EAAE,OAAsB;IAC3F,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAC3B,MAAM,EAAE,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,MAAM,cAAc,EAAE,CAAC;IACtC,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IAC5F,IAAI,IAAI,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC5E,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC;IACxF,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACjD,MAAM,OAAO,GAAoC,EAAE,CAAC;IACpD,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC;QAAE,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC;IACrG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;QAAE,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IAC1E,MAAM,gBAAgB,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IACtG,IAAI,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IACvD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,IAAI,MAAM,EAAE,uEAAuE,CAAC,CAAC;AAC/H,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,OAAe,EAAE,OAAsB;IAC5E,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAC5B,MAAM,MAAM,GAAG,MAAM,cAAc,EAAE,CAAC;IACtC,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IAC5F,IAAI,IAAI,KAAK,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,YAAY,IAAI,wFAAwF,CAAC,CAAC;IACpJ,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACjD,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,QAAQ,CAAC;IAC/C,MAAM,gBAAgB,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IACpD,IAAI,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,IAAI,kEAAkE,CAAC,CAAC;AAClH,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,OAAgB,EAChB,WAAgD,EAChD,YAA0B;IAE1B,MAAM,OAAO,GAAG,OAAO;SACpB,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,qFAAqF,CAAC;SAClG,OAAO,CAAC,gCAAgC,CAAC;SACzC,kBAAkB,EAAE;SACpB,WAAW,CACV,OAAO,EACP;;;;qEAI+D,CAChE,CAAC;IACJ,WAAW,CACT,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,WAAW,CAAC,4BAA4B,CAAC,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,EACvI;sCACkC,CACnC,CAAC;IACF,WAAW,CACT,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,sFAAsF,CAAC;SACnG,QAAQ,CAAC,QAAQ,EAAE,kDAAkD,CAAC;SACtE,cAAc,CAAC,mBAAmB,EAAE,qBAAqB,CAAC;SAC1D,SAAS,CAAC,IAAI,MAAM,CAAC,oBAAoB,EAAE,sEAAsE,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;SACnJ,MAAM,CAAC,OAAO,EAAE,4BAA4B,CAAC;SAC7C,SAAS,CAAC,YAAY,EAAE,CAAC;SACzB,MAAM,CAAC,gBAAgB,CAAC,EAC3B;+EAC2E,CAC5E,CAAC;IACF,OAAO;SACJ,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,gDAAgD,CAAC;SAC7D,QAAQ,CAAC,QAAQ,CAAC;SAClB,MAAM,CAAC,mBAAmB,EAAE,qBAAqB,CAAC;SAClD,SAAS,CAAC,IAAI,MAAM,CAAC,oBAAoB,EAAE,8BAA8B,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;SAC3G,SAAS,CAAC,YAAY,EAAE,CAAC;SACzB,MAAM,CAAC,aAAa,CAAC,CAAC;IACzB,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,wCAAwC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAChK,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACjJ,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,uCAAuC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;AACnK,CAAC"}
@@ -6,7 +6,7 @@ import { fileURLToPath } from "node:url";
6
6
  import { apiFetch, findEndpoint, listEndpoints } from "../api.js";
7
7
  import { resolveApiKey } from "../config.js";
8
8
  import { findProfileEndpoint, repoDefaultProfile } from "../dittoconfig/profiles.js";
9
- import { readStoredAuth } from "../store.js";
9
+ import { readDefaultEndpoint } from "../profiles.js";
10
10
  import { runChannelServer } from "./channel-server.js";
11
11
  import { remoteSessionURL, UNLINKABLE_SESSION_NOTICE } from "./session-link.js";
12
12
  /** Only these locally constructed setup errors may be shown verbatim. API,
@@ -30,7 +30,7 @@ export async function preparePluginSession(cwd = process.env.DITTO_REMOTE_CWD ??
30
30
  const catalog = await listEndpoints();
31
31
  const explicit = process.env.DITTO_REMOTE_ENDPOINT?.trim();
32
32
  const profile = explicit ? undefined : await repoDefaultProfile(cwd);
33
- const selected = explicit ?? (await readStoredAuth())?.defaultEndpoint;
33
+ const selected = explicit ?? (await readDefaultEndpoint());
34
34
  const endpoint = profile
35
35
  ? await findProfileEndpoint(profile, catalog.endpoints)
36
36
  : selected ? findEndpoint(catalog.endpoints, selected) : catalog.endpoints.length === 1 ? catalog.endpoints[0] : undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-server.js","sourceRoot":"","sources":["../../src/remote/plugin-server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plugin-server.js","sourceRoot":"","sources":["../../src/remote/plugin-server.ts"],"names":[],"mappings":"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"}
package/dist/store.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { type EndpointProfile } from "./profile-state.js";
1
2
  export interface StoredAuth {
2
3
  apiKey?: string;
3
4
  agentMode?: boolean;
@@ -6,8 +7,16 @@ export interface StoredAuth {
6
7
  agentCaller?: string;
7
8
  claimURL?: string;
8
9
  createdAt?: string;
9
- /** Endpoint slug or id used by `heyditto claude` / `heyditto codex` when --endpoint is omitted. */
10
+ /**
11
+ * Endpoint slug or id used by `heyditto claude` / `heyditto codex` when
12
+ * --endpoint is omitted. With named profiles this mirrors the active
13
+ * profile's endpoint, so older CLI versions keep launching the same thing.
14
+ */
10
15
  defaultEndpoint?: string;
16
+ /** Named endpoint profiles (`heyditto profile`); never holds credentials. */
17
+ profiles?: Record<string, EndpointProfile>;
18
+ /** Name of the profile used when neither --profile nor DITTO_PROFILE is set. */
19
+ activeProfile?: string;
11
20
  /**
12
21
  * Organization slug used when `--org` is omitted, set by `heyditto orgs use`.
13
22
  *
package/dist/store.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { chmod, mkdir, readFile, rm, writeFile } from "node:fs/promises";
2
2
  import { dirname } from "node:path";
3
3
  import { authFilePath } from "./config.js";
4
+ import { profileView, setProfileEndpointPatch } from "./profile-state.js";
4
5
  export async function readStoredAuth() {
5
6
  try {
6
7
  const raw = await readFile(authFilePath(), "utf-8");
@@ -66,8 +67,12 @@ export async function saveLogin(key, extra = {}) {
66
67
  claimURL: undefined,
67
68
  createdAt: new Date().toISOString(),
68
69
  };
69
- if (extra.defaultEndpoint)
70
- partial.defaultEndpoint = extra.defaultEndpoint;
70
+ if (extra.defaultEndpoint) {
71
+ // Saved into the active profile (and its `defaultEndpoint` mirror), so a
72
+ // re-login cannot silently desynchronize the two.
73
+ const current = await readStoredAuth();
74
+ Object.assign(partial, setProfileEndpointPatch(current, profileView(current).active, extra.defaultEndpoint));
75
+ }
71
76
  return updateStoredAuth(partial);
72
77
  }
73
78
  /**
package/dist/store.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,6 @@
1
1
  import { Command } from "commander";
2
+ import { type SelectedProfile } from "../profiles.js";
3
+ export declare const DEFAULT_T3_INSTANCE = "claude_ditto_cliproxy";
2
4
  export interface T3SetupOptions {
3
5
  endpoint?: string;
4
6
  inference?: string;
@@ -9,6 +11,8 @@ export interface T3SetupOptions {
9
11
  heydittoBin?: string;
10
12
  dryRun?: boolean;
11
13
  json?: boolean;
14
+ /** Set by commander; read through the shared --profile hook. */
15
+ profile?: string;
12
16
  }
13
17
  export interface T3SetupPlan {
14
18
  settingsPath: string;
@@ -35,10 +39,33 @@ export declare function applyT3Setup(plan: T3SetupPlan): {
35
39
  changed: boolean;
36
40
  backup?: string;
37
41
  };
42
+ /**
43
+ * T3 settings a profile implies. The `default` profile keeps the original
44
+ * instance id and label, so an install that predates profiles reruns setup
45
+ * onto the same provider; any other profile gets its own instance
46
+ * (`subnet` → `claude_ditto_subnet_cliproxy`, "Claude Subnet"), so a second
47
+ * provider is created next to the first instead of replacing it.
48
+ */
49
+ export declare function profileT3Defaults(name: string, inference: "router" | "cliproxy"): {
50
+ instance: string;
51
+ name?: string;
52
+ };
38
53
  export interface T3SetupDeps {
39
54
  /** Chooses an endpoint when --endpoint is omitted; `readOnly` for --dry-run. */
40
55
  chooseEndpoint?: (readOnly: boolean) => Promise<{
41
56
  slug: string;
42
57
  }>;
58
+ /** Reads the profile selected by --profile, DITTO_PROFILE or the active one. */
59
+ selectedProfile?: () => Promise<SelectedProfile>;
43
60
  }
61
+ /**
62
+ * Fills endpoint, inference, instance and name from the selected profile.
63
+ * Profiles apply when one was named (--profile / DITTO_PROFILE) or when
64
+ * profiles are saved and --endpoint was omitted. Explicit flags always win.
65
+ * With no saved profiles and no profile named, nothing changes.
66
+ */
67
+ export declare function resolveT3Profile(options: T3SetupOptions, read?: () => Promise<SelectedProfile>): Promise<{
68
+ options: T3SetupOptions;
69
+ profileName?: string;
70
+ }>;
44
71
  export declare function registerT3Commands(program: Command, deps?: T3SetupDeps): void;
package/dist/t3/setup.js CHANGED
@@ -6,6 +6,9 @@ import path from "node:path";
6
6
  import { fileURLToPath } from "node:url";
7
7
  import { Option } from "commander";
8
8
  import { chooseEndpoint } from "../agents/launch.js";
9
+ import { LEGACY_PROFILE, profileLabel } from "../profile-state.js";
10
+ import { addProfileOption, selectedProfile, setProfileOverride } from "../profiles.js";
11
+ export const DEFAULT_T3_INSTANCE = "claude_ditto_cliproxy";
9
12
  function object(value) {
10
13
  return typeof value === "object" && value !== null && !Array.isArray(value);
11
14
  }
@@ -81,7 +84,7 @@ export function planT3Setup(options) {
81
84
  const inference = options.inference ?? "cliproxy";
82
85
  if (inference !== "router" && inference !== "cliproxy")
83
86
  throw new Error("--inference must be router or cliproxy");
84
- const instance = options.instance ?? "claude_ditto_cliproxy";
87
+ const instance = options.instance ?? DEFAULT_T3_INSTANCE;
85
88
  if (!/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,79}$/.test(instance))
86
89
  throw new Error("--instance must contain letters, digits, '-' or '_' and be at most 80 characters");
87
90
  const base = userPath(options.baseDir ?? process.env.T3CODE_HOME ?? path.join(os.homedir(), ".t3"));
@@ -201,20 +204,73 @@ export function applyT3Setup(plan) {
201
204
  unlinkSync(lock);
202
205
  }
203
206
  }
207
+ /**
208
+ * T3 settings a profile implies. The `default` profile keeps the original
209
+ * instance id and label, so an install that predates profiles reruns setup
210
+ * onto the same provider; any other profile gets its own instance
211
+ * (`subnet` → `claude_ditto_subnet_cliproxy`, "Claude Subnet"), so a second
212
+ * provider is created next to the first instead of replacing it.
213
+ */
214
+ export function profileT3Defaults(name, inference) {
215
+ if (name === LEGACY_PROFILE && inference === "cliproxy")
216
+ return { instance: DEFAULT_T3_INSTANCE };
217
+ const id = name.replace(/-/g, "_");
218
+ return { instance: `claude_ditto_${id}_${inference}`, name: `Claude ${profileLabel(name)}${inference === "router" ? " (Router)" : ""}` };
219
+ }
220
+ /**
221
+ * Fills endpoint, inference, instance and name from the selected profile.
222
+ * Profiles apply when one was named (--profile / DITTO_PROFILE) or when
223
+ * profiles are saved and --endpoint was omitted. Explicit flags always win.
224
+ * With no saved profiles and no profile named, nothing changes.
225
+ */
226
+ export async function resolveT3Profile(options, read = selectedProfile) {
227
+ const selected = await read();
228
+ const named = selected.source !== "active";
229
+ if (!named && (selected.implicit || options.endpoint !== undefined))
230
+ return { options };
231
+ if (named && options.endpoint !== undefined)
232
+ throw new Error("pass either --profile or --endpoint, not both");
233
+ const endpoint = selected.profile.endpoint?.trim();
234
+ // The active profile may not have an endpoint yet: let the picker choose
235
+ // one (it saves the choice into that profile) but keep its own instance.
236
+ if (!endpoint && named)
237
+ throw new Error(`profile "${selected.name}" has no endpoint. Set one with \`heyditto profile set ${selected.name} --endpoint <slug>\`.`);
238
+ const inference = (options.inference ?? selected.profile.inference ?? "cliproxy");
239
+ const derived = profileT3Defaults(selected.name, inference);
240
+ return {
241
+ options: { ...options, ...(endpoint ? { endpoint } : {}), inference, instance: options.instance ?? derived.instance, name: options.name ?? derived.name },
242
+ profileName: selected.name,
243
+ };
244
+ }
204
245
  export function registerT3Commands(program, deps = {}) {
205
246
  const choose = deps.chooseEndpoint ?? ((readOnly) => chooseEndpoint("claude", readOnly));
206
- program.command("t3").description("configure a local T3 Code provider for Ditto").command("setup")
247
+ const readProfile = deps.selectedProfile ?? selectedProfile;
248
+ const setup = program.command("t3").description("configure a local T3 Code provider for Ditto").command("setup")
207
249
  .description("install a Claude launcher and configure a T3 provider while T3 is stopped")
208
- .option("--endpoint <slug>", "Ditto endpoint supplying tools (and inference in Router mode); default: your saved default, or pick or create one")
209
- .addOption(new Option("--inference <mode>", "inference route").choices(["cliproxy", "router"]).default("cliproxy"))
210
- .option("--instance <id>", "T3 provider instance id", "claude_ditto_cliproxy")
211
- .option("--name <name>", "provider display name")
250
+ .option("--endpoint <slug>", "Ditto endpoint supplying tools (and inference in Router mode); default: the selected profile's, or pick or create one")
251
+ .addOption(new Option("--inference <mode>", "inference route (default: the profile's, else cliproxy)").choices(["cliproxy", "router"]))
252
+ .option("--instance <id>", `T3 provider instance id (default: ${DEFAULT_T3_INSTANCE}, or claude_ditto_<profile>_<inference> for a named profile)`)
253
+ .option("--name <name>", "provider display name (default from the profile, e.g. \"Claude Subnet\")")
212
254
  .option("--base-dir <dir>", "T3 base directory (default: T3CODE_HOME or ~/.t3; userdata is appended)")
213
255
  .option("--claude-bin <path>", "installed Claude executable named claude")
214
256
  .option("--heyditto-bin <path>", "installed heyditto executable")
215
257
  .option("--dry-run", "show the setup plan; write nothing and allow T3 to remain open")
216
258
  .option("--json", "print a credential-free setup summary")
217
- .action(async (options) => {
259
+ .action(async (raw) => {
260
+ // Also honour --profile when this command is registered without the
261
+ // program-wide hook (tests, embedders).
262
+ if (raw.profile !== undefined)
263
+ setProfileOverride(raw.profile);
264
+ const { profile: flagProfile, ...rest } = raw;
265
+ if (flagProfile !== undefined && rest.endpoint !== undefined)
266
+ throw new Error("pass either --profile or --endpoint, not both");
267
+ // An explicit --endpoint keeps the original behaviour (and stays
268
+ // synchronous): no profile is read, even with DITTO_PROFILE set.
269
+ const resolved = rest.endpoint !== undefined ? { options: rest } : await resolveT3Profile(rest, readProfile);
270
+ let options = resolved.options;
271
+ const profileName = resolved.profileName;
272
+ if (profileName !== undefined)
273
+ process.stderr.write(`Using profile ${profileName} → ${options.endpoint} as T3 provider ${options.instance ?? DEFAULT_T3_INSTANCE}\n`);
218
274
  if (options.endpoint === undefined) {
219
275
  // Fail on local problems (T3 settings, binaries) before a browser
220
276
  // login, picker or endpoint creation. The throwaway plan needs any
@@ -228,7 +284,7 @@ export function registerT3Commands(program, deps = {}) {
228
284
  }
229
285
  const plan = planT3Setup(options);
230
286
  const applied = options.dryRun ? undefined : applyT3Setup(plan);
231
- const summary = { action: plan.action, dryRun: Boolean(options.dryRun), instance: plan.instance, displayName: plan.displayName, endpoint: plan.endpoint, inference: plan.inference, settingsPath: plan.settingsPath, binaryPath: plan.launcherPath, homePath: plan.homePath, runningPid: plan.runningPid ?? null, ...applied };
287
+ const summary = { action: plan.action, dryRun: Boolean(options.dryRun), profile: profileName ?? null, instance: plan.instance, displayName: plan.displayName, endpoint: plan.endpoint, inference: plan.inference, settingsPath: plan.settingsPath, binaryPath: plan.launcherPath, homePath: plan.homePath, runningPid: plan.runningPid ?? null, ...applied };
232
288
  if (options.json)
233
289
  process.stdout.write(JSON.stringify(summary, null, 2) + "\n");
234
290
  else {
@@ -241,5 +297,6 @@ export function registerT3Commands(program, deps = {}) {
241
297
  process.stdout.write("Open T3 and select this provider in a new chat. Setup did not mint any keys or send inference requests.\n");
242
298
  }
243
299
  });
300
+ addProfileOption(setup);
244
301
  }
245
302
  //# sourceMappingURL=setup.js.map