@jmanuelcorral/openteam 0.24.0 → 0.24.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.es.md +7 -1
  2. package/README.md +6 -1
  3. package/dist/certificates/graph-release-certificate.json +2 -2
  4. package/dist/certificates/graph-shadow-certificate.json +2 -2
  5. package/dist/cli/setupAdapters.d.ts +2 -2
  6. package/dist/cli/setupAdapters.d.ts.map +1 -1
  7. package/dist/cli.js +826 -298
  8. package/dist/commands/agents.d.ts +6 -4
  9. package/dist/commands/agents.d.ts.map +1 -1
  10. package/dist/commands/dispatch.d.ts +1 -1
  11. package/dist/commands/dispatch.d.ts.map +1 -1
  12. package/dist/commands/setup.d.ts +22 -14
  13. package/dist/commands/setup.d.ts.map +1 -1
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +990 -281
  16. package/dist/local/lemonade.d.ts.map +1 -1
  17. package/dist/local/lemonadeRequestGuard.d.ts +11 -0
  18. package/dist/local/lemonadeRequestGuard.d.ts.map +1 -0
  19. package/dist/local/lemonadeResidency.d.ts +22 -0
  20. package/dist/local/lemonadeResidency.d.ts.map +1 -0
  21. package/dist/local/modelResidency.d.ts +4 -0
  22. package/dist/local/modelResidency.d.ts.map +1 -0
  23. package/dist/local/slotPool.d.ts +13 -7
  24. package/dist/local/slotPool.d.ts.map +1 -1
  25. package/dist/messages/executionSetup.d.ts +19 -0
  26. package/dist/messages/executionSetup.d.ts.map +1 -1
  27. package/dist/messages/modelResidency.d.ts +19 -0
  28. package/dist/messages/modelResidency.d.ts.map +1 -0
  29. package/dist/orchestrator/coordinator.d.ts.map +1 -1
  30. package/dist/orchestrator/runtimeSelection.d.ts +4 -3
  31. package/dist/orchestrator/runtimeSelection.d.ts.map +1 -1
  32. package/dist/plugin/availability.d.ts +4 -1
  33. package/dist/plugin/availability.d.ts.map +1 -1
  34. package/dist/plugin/hooks.d.ts +2 -0
  35. package/dist/plugin/hooks.d.ts.map +1 -1
  36. package/dist/plugin/memoryTool.d.ts +9 -3
  37. package/dist/plugin/memoryTool.d.ts.map +1 -1
  38. package/dist/plugin/modelResidency.d.ts +47 -0
  39. package/dist/plugin/modelResidency.d.ts.map +1 -0
  40. package/dist/router/types.d.ts +2 -0
  41. package/dist/router/types.d.ts.map +1 -1
  42. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -3356,6 +3356,25 @@ var executionSetupMessages = {
3356
3356
  `),
3357
3357
  localOnlyTitle: "Local execution",
3358
3358
  localRequiredError: "local execution requires an enabled local runtime",
3359
+ lemonadeDetectedHint: (loaded, advertised) => `detected - ${loaded} confirmed loaded of ${advertised} advertised text model(s)`,
3360
+ lemonadeNoLoadedModels: "Lemonade has no text models verified as loaded and ready. Keep the intended model active in Lemonade and rerun setup; inactive or unknown models cannot be selected or entered manually.",
3361
+ lemonadeModelNotLoaded: (model) => `Lemonade model "${model}" is not positively verified as loaded and ready. Keep that exact text model active and rerun setup; no substitute was selected and no implicit loading is allowed.`,
3362
+ lemonadeProbeRequired: "Lemonade setup requires a fresh read-only residency probe before writing configuration. Use the CLI with its runtime probe enabled; manual model IDs cannot bypass this requirement.",
3363
+ lemonadeProbeFailed: "Lemonade residency could not be verified at the configured endpoint. Check connectivity and the read-only /models, /health, and /internal/aliases responses, then rerun setup with the intended text models already active.",
3364
+ lemonadeEndpointMismatch: "Lemonade endpoint/provider mapping differs from the selected runtime. Reconcile the configured base URL and provider before rerunning setup; no model was substituted.",
3365
+ lemonadeModelIdentityUnknown: (model) => `Lemonade model "${model}" has no usable registered wire identity in the effective opencode configuration. Fix its model declaration before rerunning setup; setup will not replace or guess an alias.`,
3366
+ lemonadeEffectiveConfigLabel: "effective setup configuration",
3367
+ lemonadeEffectiveConfigAmbiguous: "Cannot establish one effective openteam configuration from the configured plugin loaders. Reconcile their options before rerunning setup; no provider identity was guessed.",
3368
+ lemonadeRetainedProviderUnprotected: (providerID) => `Cannot safely keep retained Lemonade provider "${providerID}": the effective configuration must retain one matching Lemonade runtime, disabled when deselected. Reconcile the plugin options or machine overlay, or explicitly remove the provider registration before rerunning setup; no configuration was written.`,
3369
+ lemonadeV2InvalidProvider: (providerID) => `Lemonade provider ${JSON.stringify(providerID)} cannot be represented as an exact native V2 policy resource. Choose a non-empty provider ID without wildcards, slashes, backslashes, or whitespace; setup will not broaden a deny rule.`,
3370
+ lemonadeV2InvalidPolicies: "Cannot safely preserve experimental.policies: experimental must be an object and policies must be an array of provider.use statements with a string resource and allow/deny effect. Fix the project configuration before rerunning setup.",
3371
+ lemonadeV2Title: "Lemonade transport compatibility",
3372
+ lemonadeV2Restriction: (providers) => `Project policies disable native V2 Lemonade access for: ${providers.join(", ")}. Ordinary guarded V1 configuration remains supported; V2 is not an openteam-hook execution path. Higher-precedence or global policies can override this project restriction; it is not a server-atomic no-autoload guarantee.`,
3373
+ lemonadeInventory: (instanceID, providerID, models) => {
3374
+ const inventory = models.map((model) => `${model.modelID} (${model.loaded === true ? "loaded" : model.loaded === false ? "inactive" : "residency unknown"})`).join(", ");
3375
+ return `Lemonade inventory ${instanceID} (provider ${providerID}): ${inventory || "no advertised text models"}. Only confirmed loaded text models count as ready.`;
3376
+ },
3377
+ lemonadeAgentResidency: (agent, model, state) => `Lemonade readiness: ${agent} (${model}): ${state === "not-loaded" ? "inactive (not ready)" : "residency unknown"}; advertised inventory is not loaded readiness. Keep this exact model active and verify residency before use; requests without verified readiness are blocked.`,
3359
3378
  mixedPrimaryQuestion: "Primary coordinator model",
3360
3379
  mixedPrimaryLocal: (model) => `Use local thinking model ${model}`,
3361
3380
  mixedPrimaryFrontier: "Choose a frontier model",
@@ -9248,7 +9267,7 @@ function parseOpencodeProviders(opencodeConfig) {
9248
9267
  function localRuntimeStates(config) {
9249
9268
  const map = new Map;
9250
9269
  for (const runtime of config.local.runtimes) {
9251
- map.set(runtime.id, { enabled: runtime.enabled });
9270
+ map.set(runtime.defaultModel.providerID, { enabled: runtime.enabled });
9252
9271
  }
9253
9272
  return map;
9254
9273
  }
@@ -9256,7 +9275,7 @@ function disabledLocalProviderIDs(config) {
9256
9275
  const ids = new Set;
9257
9276
  for (const runtime of config.local.runtimes) {
9258
9277
  if (!runtime.enabled) {
9259
- ids.add(runtime.id);
9278
+ ids.add(runtime.defaultModel.providerID);
9260
9279
  }
9261
9280
  }
9262
9281
  return ids;
@@ -9272,7 +9291,11 @@ function computeLive(model, isLocalProvider, liveModels) {
9272
9291
  if (!snapshot.reachable) {
9273
9292
  return "unreachable";
9274
9293
  }
9275
- return snapshot.modelIDs.has(model.modelID) ? "confirmed" : "not-advertised";
9294
+ if (snapshot.modelIDs.has(model.modelID))
9295
+ return "confirmed";
9296
+ if (snapshot.residency?.has(model.modelID))
9297
+ return snapshot.residency.get(model.modelID) === false ? "not-loaded" : "residency-unknown";
9298
+ return "not-advertised";
9276
9299
  }
9277
9300
  function resolveAgentModel(model, context) {
9278
9301
  const isLocalProvider = KNOWN_LOCAL_PROVIDER_IDS.has(model.providerID) || context.localRuntimes.has(model.providerID);
@@ -16012,6 +16035,243 @@ function ensureFoundryV1BaseURL(endpoint) {
16012
16035
  }
16013
16036
  }
16014
16037
 
16038
+ // src/local/lemonadeResidency.ts
16039
+ import { z as z22 } from "zod";
16040
+
16041
+ // src/messages/modelResidency.ts
16042
+ var reasons = {
16043
+ unknown: "fresh residency metadata is unavailable, malformed, or ambiguous",
16044
+ inactive: "the requested model is not verified as resident and serving",
16045
+ identity: "the requested model identity can be rewritten or is ambiguous",
16046
+ destination: "the request destination does not match its configured runtime",
16047
+ transport: "this provider execution path cannot enforce the residency guard",
16048
+ request: "this is not a supported, explicit model inference request",
16049
+ cancelled: "the request was cancelled before residency could be verified",
16050
+ timeout: "the residency metadata deadline expired",
16051
+ configuration: "the residency guard configuration is invalid"
16052
+ };
16053
+ var modelResidencyMessages = {
16054
+ blocked: (reason) => `[openteam] Lemonade model request blocked: ${reasons[reason]}.`,
16055
+ providerDisabled: (providerID) => `[openteam] Lemonade provider "${providerID}" is disabled because its configured transport or runtime mapping cannot enforce loaded-only requests.`,
16056
+ extractionRuntimeUnavailable: "[openteam] Memory extraction requires one enabled local runtime matching the configured extraction provider."
16057
+ };
16058
+
16059
+ // src/local/lemonadeResidency.ts
16060
+ class ModelResidencyError extends Error {
16061
+ code;
16062
+ statusCode = 400;
16063
+ isRetryable = false;
16064
+ constructor(code) {
16065
+ super(modelResidencyMessages.blocked(code));
16066
+ this.code = code;
16067
+ this.name = "ModelResidencyError";
16068
+ }
16069
+ }
16070
+ var modelName = z22.string().min(1).refine((name) => name === name.trim());
16071
+ var LoadedModelSchema = z22.object({
16072
+ model_name: modelName,
16073
+ loaded: z22.boolean().optional(),
16074
+ status: z22.string().optional(),
16075
+ backend_alive: z22.boolean().optional(),
16076
+ backend_health: z22.string().optional(),
16077
+ watchdog_reset: z22.boolean().optional(),
16078
+ watchdog_reset_reason: z22.string().optional(),
16079
+ residency_class: z22.string().optional(),
16080
+ slot_pool: z22.string().optional(),
16081
+ checkpoint: z22.string().optional(),
16082
+ type: z22.string().optional(),
16083
+ device: z22.string().optional(),
16084
+ backend_url: z22.string().optional(),
16085
+ pid: z22.number().int().optional(),
16086
+ launch_command: z22.unknown().optional(),
16087
+ pinned: z22.boolean().optional(),
16088
+ recipe: z22.string().optional(),
16089
+ recipe_options: z22.unknown().optional(),
16090
+ is_busy: z22.boolean().optional(),
16091
+ is_streaming: z22.boolean().optional(),
16092
+ max_context_window: z22.number().optional(),
16093
+ cost_input_per_million: z22.number().optional(),
16094
+ cost_output_per_million: z22.number().optional(),
16095
+ last_use: z22.number().optional()
16096
+ }).strict();
16097
+ var TelemetrySchema = z22.object({
16098
+ enabled: z22.boolean(),
16099
+ captures: z22.array(z22.string()).optional()
16100
+ }).strict();
16101
+ var HealthSchema = z22.object({
16102
+ status: z22.literal("ok"),
16103
+ all_models_loaded: z22.array(LoadedModelSchema),
16104
+ version: z22.string().optional(),
16105
+ model_loaded: z22.string().nullable().optional(),
16106
+ telemetry: TelemetrySchema.optional(),
16107
+ max_models: z22.record(z22.string(), z22.number().int()).optional(),
16108
+ pinned_models: z22.record(z22.string(), z22.number().int()).optional(),
16109
+ pinned_helper_models: z22.record(z22.string(), z22.number().int()).optional(),
16110
+ websocket_port: z22.number().int().optional(),
16111
+ update_check_done: z22.boolean().optional()
16112
+ }).strict();
16113
+ var AliasSchema = z22.object({
16114
+ alias: modelName,
16115
+ target: modelName,
16116
+ downloaded: z22.boolean().optional(),
16117
+ recipe: z22.string().optional()
16118
+ }).strict();
16119
+ var AliasesSchema = z22.object({
16120
+ aliases: z22.array(AliasSchema)
16121
+ }).strict();
16122
+ var MetadataRecordSchema = z22.record(z22.string(), z22.unknown());
16123
+ var inactiveStates = new Set([
16124
+ "loading",
16125
+ "downsizing",
16126
+ "downsized",
16127
+ "evicting",
16128
+ "unloaded"
16129
+ ]);
16130
+ var inactiveHealth = new Set(["stopped", "exited", "watchdog_reset"]);
16131
+ var standardPools = new Set([
16132
+ "standard/llm",
16133
+ "standard/embedding",
16134
+ "standard/reranking",
16135
+ "standard/transcription",
16136
+ "standard/image",
16137
+ "standard/tts",
16138
+ "standard/audio-generation",
16139
+ "standard/classification",
16140
+ "standard/mesh"
16141
+ ]);
16142
+ function usableState(entry) {
16143
+ if (entry.loaded === false || entry.backend_alive === false || entry.watchdog_reset === true || typeof entry.status === "string" && inactiveStates.has(entry.status) || typeof entry.backend_health === "string" && inactiveHealth.has(entry.backend_health) || entry.residency_class === "routing_helper" || typeof entry.slot_pool === "string" && entry.slot_pool.startsWith("routing_helper/")) {
16144
+ return false;
16145
+ }
16146
+ if (entry.loaded !== true || entry.backend_alive !== true || entry.watchdog_reset !== false || entry.status !== "ready" && entry.status !== "in_use" || entry.backend_health !== "ready" && entry.backend_health !== "busy" || entry.watchdog_reset_reason !== undefined && entry.watchdog_reset_reason !== "" || entry.residency_class !== undefined && entry.residency_class !== "standard" || entry.slot_pool !== undefined && (typeof entry.slot_pool !== "string" || !standardPools.has(entry.slot_pool))) {
16147
+ return;
16148
+ }
16149
+ return true;
16150
+ }
16151
+ function projectMetadataObject(payload, keys) {
16152
+ const record2 = MetadataRecordSchema.safeParse(payload);
16153
+ if (!record2.success)
16154
+ throw new ModelResidencyError("unknown");
16155
+ return Object.fromEntries(keys.filter((key) => Object.hasOwn(record2.data, key)).map((key) => [key, record2.data[key]]));
16156
+ }
16157
+ function parseResidency(healthPayload, aliasPayload) {
16158
+ const healthFields = projectMetadataObject(healthPayload, Object.keys(HealthSchema.shape));
16159
+ if (Array.isArray(healthFields.all_models_loaded)) {
16160
+ healthFields.all_models_loaded = healthFields.all_models_loaded.map((entry) => projectMetadataObject(entry, Object.keys(LoadedModelSchema.shape)));
16161
+ }
16162
+ if (healthFields.telemetry !== undefined) {
16163
+ healthFields.telemetry = projectMetadataObject(healthFields.telemetry, Object.keys(TelemetrySchema.shape));
16164
+ }
16165
+ const aliasFields = projectMetadataObject(aliasPayload, Object.keys(AliasesSchema.shape));
16166
+ if (Array.isArray(aliasFields.aliases)) {
16167
+ aliasFields.aliases = aliasFields.aliases.map((entry) => projectMetadataObject(entry, Object.keys(AliasSchema.shape)));
16168
+ }
16169
+ const health = HealthSchema.safeParse(healthFields);
16170
+ const aliases = AliasesSchema.safeParse(aliasFields);
16171
+ if (!health.success || !aliases.success)
16172
+ throw new ModelResidencyError("unknown");
16173
+ const result = new Map;
16174
+ for (const entry of health.data.all_models_loaded) {
16175
+ if (result.has(entry.model_name))
16176
+ throw new ModelResidencyError("unknown");
16177
+ result.set(entry.model_name, {
16178
+ loaded: entry.model_name.endsWith(":latest") ? undefined : usableState(entry),
16179
+ metadata: entry
16180
+ });
16181
+ }
16182
+ const seenAliases = new Set;
16183
+ for (const entry of aliases.data.aliases) {
16184
+ if (seenAliases.has(entry.alias))
16185
+ throw new ModelResidencyError("unknown");
16186
+ seenAliases.add(entry.alias);
16187
+ result.set(entry.alias, {
16188
+ loaded: undefined,
16189
+ metadata: result.get(entry.alias)?.metadata ?? {}
16190
+ });
16191
+ }
16192
+ return result;
16193
+ }
16194
+ function lemonadeBaseURL(value) {
16195
+ let url;
16196
+ try {
16197
+ url = new URL(value);
16198
+ } catch {
16199
+ throw new ModelResidencyError("destination");
16200
+ }
16201
+ if (url.protocol !== "http:" && url.protocol !== "https:" || url.username !== "" || url.password !== "" || url.search !== "" || url.hash !== "" || !/^\/(?:api\/)?v[01]\/?$/.test(url.pathname)) {
16202
+ throw new ModelResidencyError("destination");
16203
+ }
16204
+ return `${url.origin}${url.pathname.replace(/\/$/, "")}`;
16205
+ }
16206
+ async function withResidencyDeadline(operation, options) {
16207
+ const timeoutMs = options.timeoutMs ?? 5000;
16208
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
16209
+ throw new ModelResidencyError("configuration");
16210
+ }
16211
+ const controller = new AbortController;
16212
+ const cancel = () => controller.abort(new ModelResidencyError("cancelled"));
16213
+ if (options.signal?.aborted)
16214
+ throw new ModelResidencyError("cancelled");
16215
+ options.signal?.addEventListener("abort", cancel, { once: true });
16216
+ const schedule = options.scheduleTimeout ?? ((callback, ms2) => {
16217
+ const timer = setTimeout(callback, ms2);
16218
+ return () => clearTimeout(timer);
16219
+ });
16220
+ let onAbort = () => {};
16221
+ const aborted = new Promise((_, reject) => {
16222
+ onAbort = () => reject(controller.signal.reason);
16223
+ controller.signal.addEventListener("abort", onAbort, { once: true });
16224
+ });
16225
+ const clearTimer = schedule(() => controller.abort(new ModelResidencyError("timeout")), timeoutMs);
16226
+ try {
16227
+ controller.signal.throwIfAborted();
16228
+ return await Promise.race([operation(controller.signal), aborted]);
16229
+ } finally {
16230
+ clearTimer();
16231
+ options.signal?.removeEventListener("abort", cancel);
16232
+ controller.signal.removeEventListener("abort", onAbort);
16233
+ controller.abort();
16234
+ }
16235
+ }
16236
+ async function metadata(url, fetch2, signal, headers) {
16237
+ signal.throwIfAborted();
16238
+ let payload;
16239
+ try {
16240
+ const response = await fetch2(url, {
16241
+ method: "GET",
16242
+ headers,
16243
+ signal,
16244
+ redirect: "error",
16245
+ cache: "no-store"
16246
+ });
16247
+ signal.throwIfAborted();
16248
+ if (!response.ok || response.redirected || response.url !== "" && response.url !== url) {
16249
+ throw new ModelResidencyError("unknown");
16250
+ }
16251
+ payload = await response.json();
16252
+ } catch {
16253
+ signal.throwIfAborted();
16254
+ throw new ModelResidencyError("unknown");
16255
+ }
16256
+ signal.throwIfAborted();
16257
+ return payload;
16258
+ }
16259
+ async function readLemonadeResidency(baseURL, fetch2, options = {}) {
16260
+ const base = lemonadeBaseURL(baseURL);
16261
+ const headers = new Headers(options.headers);
16262
+ headers.delete("content-type");
16263
+ headers.delete("content-length");
16264
+ headers.set("accept", "application/json");
16265
+ headers.set("cache-control", "no-cache, no-store");
16266
+ headers.delete("if-none-match");
16267
+ headers.delete("if-modified-since");
16268
+ return withResidencyDeadline(async (signal) => {
16269
+ const aliases = await metadata(`${new URL(base).origin}/internal/aliases`, fetch2, signal, headers);
16270
+ const health = await metadata(`${base}/health`, fetch2, signal, headers);
16271
+ return parseResidency(health, aliases);
16272
+ }, options);
16273
+ }
16274
+
16015
16275
  // src/local/lemonade.ts
16016
16276
  var LEMONADE_DEFAULT_BASE_URL = "http://localhost:13305/api/v1";
16017
16277
  var NON_TEXT_LABELS = new Set([
@@ -16098,36 +16358,19 @@ function isNonTextModel(entry) {
16098
16358
  return entry.labels.some((label) => typeof label === "string" && NON_TEXT_LABELS.has(label));
16099
16359
  }
16100
16360
  async function readLoadedModels(baseURL, fetch2) {
16101
- let payload;
16102
16361
  try {
16103
- const response = await fetch2(`${baseURL}/health`, {
16104
- method: "GET",
16105
- headers: { accept: "application/json" }
16106
- });
16107
- if (!response.ok) {
16108
- return;
16109
- }
16110
- payload = await response.json();
16362
+ const residency = await readLemonadeResidency(baseURL, fetch2);
16363
+ return new Map([...residency].map(([name, entry]) => [
16364
+ name,
16365
+ {
16366
+ loaded: entry.loaded,
16367
+ slots: entry.loaded === true ? readSlotCount(entry.metadata) : undefined,
16368
+ totalContextWindow: entry.loaded === true ? readLoadedContextWindow(entry.metadata) : undefined
16369
+ }
16370
+ ]));
16111
16371
  } catch {
16112
16372
  return;
16113
16373
  }
16114
- if (!isObject2(payload) || !Array.isArray(payload.all_models_loaded)) {
16115
- return;
16116
- }
16117
- const loaded = new Map;
16118
- for (const entry of payload.all_models_loaded) {
16119
- if (!isObject2(entry) || typeof entry.model_name !== "string") {
16120
- continue;
16121
- }
16122
- if (entry.loaded === false) {
16123
- continue;
16124
- }
16125
- loaded.set(entry.model_name, {
16126
- slots: readSlotCount(entry),
16127
- totalContextWindow: readLoadedContextWindow(entry)
16128
- });
16129
- }
16130
- return loaded;
16131
16374
  }
16132
16375
  function readSlotCount(entry) {
16133
16376
  return slotsFromLlamacppArgs(entry) ?? slotsFromLaunchCommand(entry);
@@ -16274,6 +16517,9 @@ function enrichWithLoadState(models, loaded) {
16274
16517
  if (hit === undefined) {
16275
16518
  return { ...base, loaded: false };
16276
16519
  }
16520
+ if (hit.loaded !== true) {
16521
+ return hit.loaded === false ? { ...base, loaded: false } : base;
16522
+ }
16277
16523
  const contextWindow = derivedConservativeContextWindow(model.contextWindow, hit);
16278
16524
  return {
16279
16525
  ...base,
@@ -16290,6 +16536,11 @@ function isObject2(value) {
16290
16536
  return typeof value === "object" && value !== null && !Array.isArray(value);
16291
16537
  }
16292
16538
 
16539
+ // src/local/modelResidency.ts
16540
+ function hasRequiredModelResidency(kind, model) {
16541
+ return kind !== "lemonade" || model?.loaded === true;
16542
+ }
16543
+
16293
16544
  // src/local/lmstudio.ts
16294
16545
  var LMSTUDIO_DEFAULT_BASE_URL = "http://localhost:1234/v1";
16295
16546
  function createLMStudioAdapter() {
@@ -16507,50 +16758,36 @@ function createDetect(exec) {
16507
16758
  foundryDiscovery: foundryDiscoveryFromExec(exec)
16508
16759
  });
16509
16760
  const snapshots = await registry.probe(DETECTION_RUNTIMES);
16510
- return snapshots.map((snapshot) => {
16511
- const detected = {
16512
- id: snapshot.id,
16513
- baseURL: snapshot.baseURL,
16514
- reachable: snapshot.reachable,
16515
- models: snapshot.models.map((model) => model.modelID)
16516
- };
16517
- if (snapshot.models.some((model) => model.loaded !== undefined)) {
16518
- detected.modelInfo = snapshot.models;
16519
- }
16520
- if (snapshot.error !== undefined) {
16521
- detected.error = snapshot.error;
16522
- }
16523
- return detected;
16524
- });
16761
+ return DETECTION_RUNTIMES.map((runtime) => detectedRuntime(runtime, snapshots.find((snapshot) => snapshot.id === runtime.id)));
16762
+ };
16763
+ }
16764
+ function detectedRuntime(runtime, snapshot) {
16765
+ const modelInfo = snapshot?.models ?? [];
16766
+ return {
16767
+ id: runtime.id,
16768
+ baseURL: snapshot?.baseURL ?? runtime.baseURL ?? "",
16769
+ reachable: snapshot?.reachable ?? false,
16770
+ models: modelInfo.filter((model) => hasRequiredModelResidency(localRuntimeKind(runtime), model)).map((model) => model.modelID),
16771
+ modelInfo,
16772
+ ...snapshot?.error === undefined ? {} : { error: snapshot.error }
16525
16773
  };
16526
16774
  }
16527
16775
  function createProbeRuntime(exec) {
16528
- return async (id, baseURL) => {
16776
+ return async (kind, baseURL) => {
16529
16777
  const registry = new RuntimeRegistry({
16530
16778
  fetch: globalThis.fetch,
16531
16779
  clock: () => new Date().toISOString(),
16532
16780
  foundryDiscovery: foundryDiscoveryFromExec(exec)
16533
16781
  });
16534
16782
  const runtime = {
16535
- id,
16783
+ id: kind,
16784
+ kind,
16536
16785
  enabled: true,
16537
16786
  baseURL,
16538
- defaultModel: { providerID: id, modelID: "probe" }
16787
+ defaultModel: { providerID: kind, modelID: "probe" }
16539
16788
  };
16540
16789
  const [snapshot] = await registry.probe([runtime]);
16541
- const detected = {
16542
- id,
16543
- baseURL: snapshot?.baseURL ?? baseURL,
16544
- reachable: snapshot?.reachable ?? false,
16545
- models: snapshot?.models.map((model) => model.modelID) ?? []
16546
- };
16547
- if (snapshot?.models.some((model) => model.loaded !== undefined) === true) {
16548
- detected.modelInfo = snapshot.models;
16549
- }
16550
- if (snapshot?.error !== undefined) {
16551
- detected.error = snapshot.error;
16552
- }
16553
- return detected;
16790
+ return detectedRuntime(runtime, snapshot);
16554
16791
  };
16555
16792
  }
16556
16793
 
@@ -16663,11 +16900,11 @@ function planWorktreeReconciliation(input) {
16663
16900
  }
16664
16901
 
16665
16902
  // src/telemetry/otelConfig.ts
16666
- import { z as z22 } from "zod";
16667
- var OtelBackendConfigSchema = z22.object({
16668
- backend: z22.literal("opentelemetry"),
16669
- connectionEnv: z22.string().min(1),
16670
- serviceName: z22.string().min(1).optional()
16903
+ import { z as z23 } from "zod";
16904
+ var OtelBackendConfigSchema = z23.object({
16905
+ backend: z23.literal("opentelemetry"),
16906
+ connectionEnv: z23.string().min(1),
16907
+ serviceName: z23.string().min(1).optional()
16671
16908
  }).strict();
16672
16909
  function parseConnectionString(raw) {
16673
16910
  const pairs = new Map;
@@ -17809,7 +18046,7 @@ import { posix as pathPosix, win32 as pathWin32 } from "node:path";
17809
18046
  // package.json
17810
18047
  var package_default = {
17811
18048
  name: "@jmanuelcorral/openteam",
17812
- version: "0.24.0",
18049
+ version: "0.24.1",
17813
18050
  packageManager: "bun@1.3.14",
17814
18051
  description: "Cost-aware, local-first routing plugin for opencode with cheapest-capable frontier fallback and multi-agent orchestration.",
17815
18052
  license: "MIT",
@@ -17953,31 +18190,31 @@ function compareSemver(a, b) {
17953
18190
  }
17954
18191
 
17955
18192
  // src/graph/soakLedger.ts
17956
- import { z as z23 } from "zod";
17957
- var Sha256Schema2 = z23.string().regex(/^[0-9a-f]{64}$/);
17958
- var SoakPlatformSchema = z23.enum(["linux", "win32", "darwin"]);
17959
- var PrivacyPairSchema = z23.object({
17960
- surfacesScanned: z23.number().int().nonnegative(),
17961
- rawFindings: z23.number().int().nonnegative()
18193
+ import { z as z24 } from "zod";
18194
+ var Sha256Schema2 = z24.string().regex(/^[0-9a-f]{64}$/);
18195
+ var SoakPlatformSchema = z24.enum(["linux", "win32", "darwin"]);
18196
+ var PrivacyPairSchema = z24.object({
18197
+ surfacesScanned: z24.number().int().nonnegative(),
18198
+ rawFindings: z24.number().int().nonnegative()
17962
18199
  }).strict();
17963
- var DuplicateEffectPairSchema = z23.object({
17964
- effectsExamined: z23.number().int().nonnegative(),
17965
- duplicatesFound: z23.number().int().nonnegative()
18200
+ var DuplicateEffectPairSchema = z24.object({
18201
+ effectsExamined: z24.number().int().nonnegative(),
18202
+ duplicatesFound: z24.number().int().nonnegative()
17966
18203
  }).strict();
17967
- var ModelVerificationPairSchema = z23.object({
17968
- nodesChecked: z23.number().int().nonnegative(),
17969
- unverified: z23.number().int().nonnegative(),
17970
- mismatched: z23.number().int().nonnegative()
18204
+ var ModelVerificationPairSchema = z24.object({
18205
+ nodesChecked: z24.number().int().nonnegative(),
18206
+ unverified: z24.number().int().nonnegative(),
18207
+ mismatched: z24.number().int().nonnegative()
17971
18208
  }).strict();
17972
- var SoakObservationSchema = z23.object({
17973
- version: z23.literal(1),
17974
- seq: z23.number().int().nonnegative(),
17975
- timestamp: z23.string().datetime(),
18209
+ var SoakObservationSchema = z24.object({
18210
+ version: z24.literal(1),
18211
+ seq: z24.number().int().nonnegative(),
18212
+ timestamp: z24.string().datetime(),
17976
18213
  platform: SoakPlatformSchema,
17977
- opencodeVersion: z23.string().min(1),
17978
- provenance: z23.enum(["genuine-usage", "ci-synthetic"]),
18214
+ opencodeVersion: z24.string().min(1),
18215
+ provenance: z24.enum(["genuine-usage", "ci-synthetic"]),
17979
18216
  traceDigest: Sha256Schema2,
17980
- criticalDivergences: z23.number().int().nonnegative().nullable(),
18217
+ criticalDivergences: z24.number().int().nonnegative().nullable(),
17981
18218
  privacy: PrivacyPairSchema.nullable(),
17982
18219
  duplicateEffects: DuplicateEffectPairSchema.nullable(),
17983
18220
  modelVerification: ModelVerificationPairSchema.nullable(),
@@ -18259,6 +18496,12 @@ var KNOWN_RUNTIMES = [
18259
18496
  dynamicPort: true
18260
18497
  }
18261
18498
  ];
18499
+ var LEMONADE_PROJECT_CONFIG_CANDIDATES = [
18500
+ ".opencode/opencode.jsonc",
18501
+ ".opencode/opencode.json",
18502
+ "opencode.jsonc",
18503
+ "opencode.json"
18504
+ ];
18262
18505
  function knownRuntime(id) {
18263
18506
  const found = KNOWN_RUNTIMES.find((runtime) => runtime.id === id);
18264
18507
  if (found === undefined) {
@@ -18275,7 +18518,44 @@ function choiceKind(choice) {
18275
18518
  function choiceProviderID(choice) {
18276
18519
  return choice.providerID ?? choice.id;
18277
18520
  }
18521
+ function selectableModelIDs(models, modelInfo, kind) {
18522
+ const byID = new Map(modelInfo?.map((model) => [model.modelID, model]));
18523
+ return models.filter((id) => hasRequiredModelResidency(kind, byID.get(id)));
18524
+ }
18525
+ function assertRuntimeResidency(choice, primary) {
18526
+ const kind = localRuntimeKind(choice);
18527
+ const references2 = [
18528
+ choice.defaultModelID,
18529
+ choice.thinkingModelID,
18530
+ choice.coderModelID,
18531
+ ...primary.providerID === choiceProviderID(choice) ? [primary.modelID] : []
18532
+ ];
18533
+ for (const id of references2) {
18534
+ if (id === undefined)
18535
+ continue;
18536
+ const info = choice.models.includes(id) ? choice.modelInfo?.find((model) => model.modelID === id) : undefined;
18537
+ if (!hasRequiredModelResidency(kind, info))
18538
+ throw new Error(executionSetupMessages.lemonadeModelNotLoaded(`${choiceProviderID(choice)}/${id}`));
18539
+ }
18540
+ }
18541
+ function assertSetupResidency(answers) {
18542
+ for (const choice of answers.runtimes) {
18543
+ if (choice.enabled) {
18544
+ assertRuntimeResidency(choice, answers.primaryModel);
18545
+ } else if (choiceProviderID(choice) === answers.primaryModel.providerID && !hasRequiredModelResidency(localRuntimeKind(choice), undefined)) {
18546
+ throw new Error(executionSetupMessages.lemonadeModelNotLoaded(`${answers.primaryModel.providerID}/${answers.primaryModel.modelID}`));
18547
+ }
18548
+ }
18549
+ }
18550
+ function lemonadeV2Policies(providers) {
18551
+ return [...new Set(providers)].sort().map((providerID) => {
18552
+ if (providerID.length === 0 || /[*?\\/\s]/.test(providerID))
18553
+ throw new Error(executionSetupMessages.lemonadeV2InvalidProvider(providerID));
18554
+ return { action: "provider.use", resource: providerID, effect: "deny" };
18555
+ });
18556
+ }
18278
18557
  function buildOpenTeamConfig(answers) {
18558
+ assertSetupResidency(answers);
18279
18559
  const runtimes = answers.runtimes.filter((choice) => choice.enabled).map((choice) => {
18280
18560
  const runtime = {
18281
18561
  id: choice.id,
@@ -18344,6 +18624,8 @@ function orchestratorAgentModel(answers) {
18344
18624
  return { ...answers.primaryModel };
18345
18625
  }
18346
18626
  function buildOpencodeConfig(answers) {
18627
+ assertSetupResidency(answers);
18628
+ const policies = lemonadeV2Policies(answers.runtimes.filter((choice) => choice.enabled && choiceKind(choice) === "lemonade").map(choiceProviderID));
18347
18629
  const provider = {};
18348
18630
  const providerOwner = new Map;
18349
18631
  for (const choice of answers.runtimes) {
@@ -18356,7 +18638,7 @@ function buildOpencodeConfig(answers) {
18356
18638
  continue;
18357
18639
  }
18358
18640
  const providerID = choiceProviderID(choice);
18359
- const modelIDs = new Set(choice.models);
18641
+ const modelIDs = new Set(selectableModelIDs(choice.models, choice.modelInfo, meta.id));
18360
18642
  modelIDs.add(choice.defaultModelID);
18361
18643
  if (choice.thinkingModelID !== undefined) {
18362
18644
  modelIDs.add(choice.thinkingModelID);
@@ -18412,6 +18694,8 @@ function buildOpencodeConfig(answers) {
18412
18694
  if (answers.yolo) {
18413
18695
  config.permission = { "*": "allow" };
18414
18696
  }
18697
+ if (policies.length > 0)
18698
+ config.experimental = { policies };
18415
18699
  return config;
18416
18700
  }
18417
18701
  function serializeOpencodeConfig(config) {
@@ -18511,10 +18795,11 @@ async function chooseFrontier(prompt, profiles) {
18511
18795
  }
18512
18796
  return parseFrontierRef(selected);
18513
18797
  }
18514
- function orderModelChoices(models, modelInfo) {
18798
+ function orderModelChoices(models, modelInfo, kind) {
18515
18799
  const byID = new Map((modelInfo ?? []).map((model) => [model.modelID, model]));
18516
18800
  const anyLoadState = (modelInfo ?? []).some((model) => model.loaded !== undefined);
18517
- const decorated = models.map((modelID, index) => {
18801
+ const offered = kind === undefined ? models : selectableModelIDs(models, modelInfo, kind);
18802
+ const decorated = offered.map((modelID, index) => {
18518
18803
  const info = byID.get(modelID);
18519
18804
  return {
18520
18805
  modelID,
@@ -18540,27 +18825,34 @@ function modelStateSuffix(loaded, slots) {
18540
18825
  }
18541
18826
  return slots === undefined ? "(loaded)" : `(loaded · ${slots} slot${slots === 1 ? "" : "s"})`;
18542
18827
  }
18543
- function preferredModelID(models, modelInfo) {
18544
- const loaded = (modelInfo ?? []).find((model) => model.loaded === true && models.includes(model.modelID));
18545
- return loaded?.modelID ?? models[0];
18828
+ function preferredModelID(models, modelInfo, kind) {
18829
+ const offered = kind === undefined ? models : selectableModelIDs(models, modelInfo, kind);
18830
+ const loaded = (modelInfo ?? []).find((model) => model.loaded === true && offered.includes(model.modelID));
18831
+ return loaded?.modelID ?? offered[0];
18546
18832
  }
18547
18833
  async function chooseRuntimeModel(prompt, models, meta, modelInfo) {
18548
- if (models.length === 0) {
18834
+ const offered = selectableModelIDs(models, modelInfo, meta.id);
18835
+ if (offered.length === 0) {
18836
+ if (meta.id === "lemonade")
18837
+ throw new Error(executionSetupMessages.lemonadeNoLoadedModels);
18549
18838
  return prompt.text({
18550
18839
  message: `Default model for ${meta.label} (no models detected)`,
18551
18840
  placeholder: meta.fallbackModelID,
18552
18841
  initial: meta.fallbackModelID
18553
18842
  });
18554
18843
  }
18555
- const first = preferredModelID(models, modelInfo);
18844
+ const first = preferredModelID(offered, modelInfo, meta.id);
18556
18845
  const opts = {
18557
18846
  message: `Default local model for ${meta.label}`,
18558
- choices: orderModelChoices(models, modelInfo)
18847
+ choices: orderModelChoices(offered, modelInfo, meta.id)
18559
18848
  };
18560
18849
  if (first !== undefined) {
18561
18850
  opts.initial = first;
18562
18851
  }
18563
- return prompt.select(opts);
18852
+ const selected = await prompt.select(opts);
18853
+ if (meta.id === "lemonade" && !offered.includes(selected))
18854
+ throw new Error(executionSetupMessages.lemonadeModelNotLoaded(selected));
18855
+ return selected;
18564
18856
  }
18565
18857
  function remoteBaseURLExample(meta) {
18566
18858
  const base = meta.defaultBaseURL ?? "http://localhost:11434/v1";
@@ -18615,6 +18907,8 @@ async function resolveRuntimeConnection(deps, meta, info) {
18615
18907
  initial: RUNTIME_LOCATION_LOCAL
18616
18908
  });
18617
18909
  if (location === RUNTIME_LOCATION_LOCAL) {
18910
+ if (meta.id === "lemonade" && info?.reachable !== true)
18911
+ throw new Error(executionSetupMessages.lemonadeProbeFailed);
18618
18912
  const baseURL2 = info?.baseURL !== undefined && info.baseURL.length > 0 ? info.baseURL : meta.defaultBaseURL;
18619
18913
  return { baseURL: baseURL2, ...connectionOf(info) };
18620
18914
  }
@@ -18624,16 +18918,26 @@ async function resolveRuntimeConnection(deps, meta, info) {
18624
18918
  });
18625
18919
  const baseURL = normalizeRemoteBaseURL(entered, meta.defaultBaseURL);
18626
18920
  let probedRuntime;
18921
+ if (meta.id === "lemonade" && deps.probeRuntime === undefined)
18922
+ throw new Error(executionSetupMessages.lemonadeProbeRequired);
18627
18923
  if (deps.probeRuntime !== undefined) {
18628
18924
  try {
18629
18925
  probedRuntime = await deps.probeRuntime(meta.id, baseURL);
18630
- } catch {}
18926
+ } catch (cause) {
18927
+ if (meta.id === "lemonade")
18928
+ throw new Error(executionSetupMessages.lemonadeProbeFailed, { cause });
18929
+ }
18930
+ if (meta.id === "lemonade" && probedRuntime?.reachable !== true)
18931
+ throw new Error(executionSetupMessages.lemonadeProbeFailed);
18631
18932
  }
18632
18933
  return { baseURL, ...connectionOf(probedRuntime) };
18633
18934
  }
18634
18935
  async function chooseClassModel(prompt, models, meta, defaultModelID, modelClass, modelInfo) {
18635
18936
  const label = modelClass === "thinking" ? `Thinking model for ${meta.label} (design, analysis, review reasoning)` : `Coder model for ${meta.label} (writing and editing code)`;
18636
- if (models.length === 0) {
18937
+ const offered = selectableModelIDs(models, modelInfo, meta.id);
18938
+ if (offered.length === 0) {
18939
+ if (meta.id === "lemonade")
18940
+ throw new Error(executionSetupMessages.lemonadeNoLoadedModels);
18637
18941
  const raw = await prompt.text({
18638
18942
  message: `${label} — enter to reuse the default`,
18639
18943
  placeholder: defaultModelID,
@@ -18641,14 +18945,17 @@ async function chooseClassModel(prompt, models, meta, defaultModelID, modelClass
18641
18945
  });
18642
18946
  return raw.trim().length > 0 ? raw.trim() : defaultModelID;
18643
18947
  }
18644
- return prompt.select({
18948
+ const selected = await prompt.select({
18645
18949
  message: label,
18646
- choices: orderModelChoices(models, modelInfo).map((choice) => ({
18950
+ choices: orderModelChoices(offered, modelInfo, meta.id).map((choice) => ({
18647
18951
  value: choice.value,
18648
18952
  label: choice.value === defaultModelID ? `${choice.label} — default` : choice.label
18649
18953
  })),
18650
18954
  initial: defaultModelID
18651
18955
  });
18956
+ if (meta.id === "lemonade" && !offered.includes(selected))
18957
+ throw new Error(executionSetupMessages.lemonadeModelNotLoaded(selected));
18958
+ return selected;
18652
18959
  }
18653
18960
  async function resolveEnabledRuntime(deps, meta, info) {
18654
18961
  const connection = await resolveRuntimeConnection(deps, meta, info);
@@ -18661,7 +18968,8 @@ async function resolveEnabledRuntime(deps, meta, info) {
18661
18968
  defaultModelID,
18662
18969
  thinkingModelID,
18663
18970
  coderModelID,
18664
- models: connection.models
18971
+ models: selectableModelIDs(connection.models, connection.modelInfo, meta.id),
18972
+ ...connection.modelInfo === undefined ? {} : { modelInfo: connection.modelInfo }
18665
18973
  };
18666
18974
  if (connection.baseURL !== undefined) {
18667
18975
  choice.baseURL = connection.baseURL;
@@ -19161,17 +19469,52 @@ async function readExistingOpencodeConfigFiles(paths, deps) {
19161
19469
  function opencodeFileAt(files, path2) {
19162
19470
  return files.find((file) => file.path === path2);
19163
19471
  }
19164
- function mergeExistingOpencodeConfigFiles(files) {
19472
+ function mergeExistingOpencodeConfigFiles(files, paths, planned = new Map) {
19165
19473
  let merged;
19166
- for (const path2 of [...OPENCODE_CONFIG_CANDIDATES].reverse()) {
19167
- const file = opencodeFileAt(files, path2);
19168
- if (file === undefined) {
19474
+ for (const path2 of [...paths].reverse()) {
19475
+ const raw = planned.get(path2) ?? opencodeFileAt(files, path2)?.raw;
19476
+ if (raw === undefined) {
19169
19477
  continue;
19170
19478
  }
19171
- merged = merged === undefined ? file.raw : mergeOpencodeConfigs(merged, file.raw);
19479
+ merged = merged === undefined ? raw : mergeOpencodeConfigs(merged, raw);
19172
19480
  }
19173
19481
  return merged;
19174
19482
  }
19483
+ async function effectiveSetupConfig(portable, files, deps) {
19484
+ const optionsByLoader = new Map;
19485
+ for (const file of files) {
19486
+ if (!Array.isArray(file.raw.plugin))
19487
+ continue;
19488
+ for (const entry of [...file.raw.plugin].reverse()) {
19489
+ const spec = extractPluginSpec(entry);
19490
+ if (spec === undefined)
19491
+ continue;
19492
+ let identity;
19493
+ if (isOpenteamNpmSpec(spec)) {
19494
+ identity = OPENTEAM_PACKAGE_NAME;
19495
+ } else if (isLocalFileSpec(spec) && await classifyLocalPluginSpecForSetup(spec, file.path, deps.classifyLocalPluginSpec) === "ours") {
19496
+ const resolved = resolvePluginSpecPath(spec, file.path);
19497
+ if (resolved === undefined)
19498
+ throw new Error(executionSetupMessages.lemonadeEffectiveConfigAmbiguous);
19499
+ identity = resolved;
19500
+ } else {
19501
+ continue;
19502
+ }
19503
+ if (!optionsByLoader.has(identity)) {
19504
+ optionsByLoader.set(identity, Array.isArray(entry) ? entry[1] : undefined);
19505
+ }
19506
+ }
19507
+ }
19508
+ const overlayText = await deps.readFile(DEFAULT_LOCAL_OVERLAY_PATH);
19509
+ const overlay = overlayText === undefined ? undefined : parseConfigFileJson(DEFAULT_LOCAL_OVERLAY_PATH, overlayText);
19510
+ const resolutions = [
19511
+ ...optionsByLoader.size > 0 ? optionsByLoader.values() : [undefined]
19512
+ ].map((options) => validateConfigInput(executionSetupMessages.lemonadeEffectiveConfigLabel, mergeConfigInputs(mergeConfigInputs(portable, configOptionsFromPluginOptions(options)), overlay)));
19513
+ const effective = resolutions[0];
19514
+ if (effective === undefined || resolutions.some((config) => JSON.stringify(config) !== JSON.stringify(effective)))
19515
+ throw new Error(executionSetupMessages.lemonadeEffectiveConfigAmbiguous);
19516
+ return effective;
19517
+ }
19175
19518
  function relevantLocalProviderIDs(generated, existingOpenTeamConfig) {
19176
19519
  const ids = new Set(Object.keys(generated.provider ?? {}));
19177
19520
  for (const runtime of existingOpenTeamConfig?.local.runtimes ?? []) {
@@ -19348,15 +19691,42 @@ function highestExistingPinVersion(files) {
19348
19691
  }
19349
19692
  return highest;
19350
19693
  }
19694
+ function reconcileLemonadeV2Policies(raw, denials) {
19695
+ if (denials.length === 0)
19696
+ return raw;
19697
+ const experimental = raw.experimental;
19698
+ if (experimental !== undefined && !isRecord6(experimental))
19699
+ throw new Error(executionSetupMessages.lemonadeV2InvalidPolicies);
19700
+ const policies = experimental?.policies;
19701
+ if (policies !== undefined && !Array.isArray(policies))
19702
+ throw new Error(executionSetupMessages.lemonadeV2InvalidPolicies);
19703
+ const existing = policies ?? [];
19704
+ for (const policy of existing) {
19705
+ if (!isRecord6(policy) || policy.action !== "provider.use" || typeof policy.resource !== "string" || policy.effect !== "allow" && policy.effect !== "deny")
19706
+ throw new Error(executionSetupMessages.lemonadeV2InvalidPolicies);
19707
+ }
19708
+ const terminal = denials.every((denial, index) => {
19709
+ const policy = existing[existing.length - denials.length + index];
19710
+ return isRecord6(policy) && Object.keys(policy).length === 3 && policy.action === denial.action && policy.resource === denial.resource && policy.effect === denial.effect;
19711
+ });
19712
+ if (terminal)
19713
+ return raw;
19714
+ return {
19715
+ ...raw,
19716
+ experimental: { ...experimental, policies: [...existing, ...denials] }
19717
+ };
19718
+ }
19351
19719
  function mergeOpencodeConfigForRerun(generated, targetRaw, options) {
19352
19720
  const effectiveRaw = options.effectiveRaw ?? targetRaw;
19353
19721
  const includePlugin = options.includePlugin ?? true;
19722
+ const managesV2Policies = (generated.experimental?.policies.length ?? 0) > 0;
19354
19723
  const managedKeys = new Set([
19355
19724
  "$schema",
19356
19725
  "provider",
19357
19726
  "model",
19358
19727
  "small_model",
19359
19728
  "permission",
19729
+ ...managesV2Policies ? ["experimental"] : [],
19360
19730
  ...includePlugin ? ["plugin"] : []
19361
19731
  ]);
19362
19732
  const unknownFields = {};
@@ -19419,7 +19789,10 @@ function mergeOpencodeConfigForRerun(generated, targetRaw, options) {
19419
19789
  if (permission !== undefined) {
19420
19790
  result.permission = permission;
19421
19791
  }
19422
- return result;
19792
+ if (managesV2Policies && hasOwn2(targetRaw, "experimental")) {
19793
+ result.experimental = targetRaw.experimental;
19794
+ }
19795
+ return reconcileLemonadeV2Policies(result, generated.experimental?.policies ?? []);
19423
19796
  }
19424
19797
  function mergeOpenTeamConfigForRerun(generated, existing) {
19425
19798
  const existingOrch = existing.orchestrator;
@@ -19469,6 +19842,21 @@ function mergeOpenTeamConfigForRerun(generated, existing) {
19469
19842
  assertEffectiveConfigModelDomains(merged);
19470
19843
  return merged;
19471
19844
  }
19845
+ function preserveRetainedLemonadeRuntimes(generated, previous, opencode) {
19846
+ const providers = recordAt2(opencode, "provider") ?? {};
19847
+ const retained = (previous?.local.runtimes ?? []).filter((runtime) => localRuntimeKind(runtime) === "lemonade" && hasOwn2(providers, runtime.defaultModel.providerID));
19848
+ const deselected = retained.filter((runtime) => !generated.local.runtimes.some((selected) => selected.defaultModel.providerID === runtime.defaultModel.providerID)).map((runtime) => ({ ...runtime, enabled: false }));
19849
+ return {
19850
+ config: deselected.length === 0 ? generated : OpenTeamConfigSchema.parse({
19851
+ ...generated,
19852
+ local: {
19853
+ ...generated.local,
19854
+ runtimes: [...generated.local.runtimes, ...deselected]
19855
+ }
19856
+ }),
19857
+ providerIDs: retained.map((runtime) => runtime.defaultModel.providerID)
19858
+ };
19859
+ }
19472
19860
  async function existingPluginOwnerPath(files, classifyLocalPluginSpec) {
19473
19861
  let unknownLocalPlugin;
19474
19862
  for (const file of files) {
@@ -19496,6 +19884,86 @@ async function confirmJsonNormalization(prompt, path2, format) {
19496
19884
  initial: false
19497
19885
  });
19498
19886
  }
19887
+ function assertPreviousLemonadePrimary(answers, previousConfig) {
19888
+ const priorLemonadePrimary = previousConfig?.local.runtimes.some((runtime) => runtime.defaultModel.providerID === answers.primaryModel.providerID && localRuntimeKind(runtime) === "lemonade");
19889
+ if (priorLemonadePrimary && !answers.runtimes.some((choice) => choice.enabled && choiceProviderID(choice) === answers.primaryModel.providerID)) {
19890
+ throw new Error(executionSetupMessages.lemonadeModelNotLoaded(`${answers.primaryModel.providerID}/${answers.primaryModel.modelID}`));
19891
+ }
19892
+ }
19893
+ async function verifyLemonadeBeforeWrite(deps, answers, config, opencode) {
19894
+ for (const choice of answers.runtimes) {
19895
+ if (choice.enabled && localRuntimeKind(choice) === "lemonade" && !config.local.runtimes.some((runtime) => runtime.enabled && runtime.defaultModel.providerID === choiceProviderID(choice) && localRuntimeKind(runtime) === "lemonade"))
19896
+ throw new Error(executionSetupMessages.lemonadeEndpointMismatch);
19897
+ }
19898
+ for (const runtime of config.local.runtimes) {
19899
+ if (localRuntimeKind(runtime) !== "lemonade")
19900
+ continue;
19901
+ const providerID = runtime.defaultModel.providerID;
19902
+ const provider = isRecord6(opencode.provider) ? opencode.provider[providerID] : undefined;
19903
+ if (!runtime.enabled && provider === undefined)
19904
+ continue;
19905
+ const endpoint = isRecord6(provider) ? (isRecord6(provider.options) ? provider.options.baseURL : undefined) ?? provider.api : undefined;
19906
+ if (typeof endpoint !== "string" || lemonadeBaseURL(endpoint) !== lemonadeBaseURL(runtime.baseURL ?? LEMONADE_DEFAULT_BASE_URL) || config.local.runtimes.filter((candidate) => candidate.defaultModel.providerID === providerID).length !== 1)
19907
+ throw new Error(executionSetupMessages.lemonadeEndpointMismatch);
19908
+ if (!runtime.enabled)
19909
+ continue;
19910
+ if (deps.probeRuntime === undefined)
19911
+ throw new Error(executionSetupMessages.lemonadeProbeRequired);
19912
+ const references2 = new Set([
19913
+ runtime.defaultModel.modelID,
19914
+ runtime.thinkingModel,
19915
+ runtime.coderModel
19916
+ ]);
19917
+ for (const choice of answers.runtimes) {
19918
+ if (choice.enabled && choiceProviderID(choice) === providerID) {
19919
+ for (const id of [
19920
+ ...choice.models,
19921
+ choice.defaultModelID,
19922
+ choice.thinkingModelID,
19923
+ choice.coderModelID
19924
+ ])
19925
+ references2.add(id);
19926
+ }
19927
+ }
19928
+ for (const ref of [
19929
+ answers.primaryModel,
19930
+ config.orchestrator?.primary?.model,
19931
+ config.router.localDefault
19932
+ ]) {
19933
+ if (ref !== null && typeof ref === "object" && ref.providerID === providerID)
19934
+ references2.add(ref.modelID);
19935
+ }
19936
+ for (const key of ["model", "small_model"]) {
19937
+ const ref = opencode[key];
19938
+ if (typeof ref === "string" && ref.startsWith(`${providerID}/`))
19939
+ references2.add(ref.slice(providerID.length + 1));
19940
+ }
19941
+ const models = isRecord6(provider) ? recordAt2(provider, "models") : undefined;
19942
+ const wireIDs = new Set;
19943
+ for (const alias of references2) {
19944
+ if (alias === undefined)
19945
+ continue;
19946
+ const declaration = recordAt2(models, alias);
19947
+ const wireID = declaration !== undefined && hasOwn2(declaration, "id") ? declaration.id : alias;
19948
+ if (declaration === undefined || typeof wireID !== "string" || wireID.length === 0 || wireID !== wireID.trim())
19949
+ throw new Error(executionSetupMessages.lemonadeModelIdentityUnknown(`${providerID}/${alias}`));
19950
+ wireIDs.add(wireID);
19951
+ }
19952
+ let fresh;
19953
+ try {
19954
+ fresh = await deps.probeRuntime(localRuntimeKind(runtime), endpoint);
19955
+ } catch (cause) {
19956
+ throw new Error(executionSetupMessages.lemonadeProbeFailed, { cause });
19957
+ }
19958
+ if (!fresh.reachable || fresh.id !== localRuntimeKind(runtime) || fresh.baseURL.replace(/\/+$/, "") !== endpoint.replace(/\/+$/, ""))
19959
+ throw new Error(executionSetupMessages.lemonadeProbeFailed);
19960
+ for (const wireID of wireIDs) {
19961
+ const info = fresh.models.includes(wireID) ? fresh.modelInfo?.find((model) => model.modelID === wireID) : undefined;
19962
+ if (!hasRequiredModelResidency("lemonade", info))
19963
+ throw new Error(executionSetupMessages.lemonadeModelNotLoaded(`${providerID}/${wireID}`));
19964
+ }
19965
+ }
19966
+ }
19499
19967
  async function runSetup(deps) {
19500
19968
  const { prompt } = deps;
19501
19969
  try {
@@ -19507,7 +19975,7 @@ async function runSetup(deps) {
19507
19975
  return {
19508
19976
  value: meta.id,
19509
19977
  label: meta.label,
19510
- hint: info?.reachable ? `detected · ${info.models.length} model(s)` : "not detected (you can point it to another machine)",
19978
+ hint: info?.reachable ? meta.id === "lemonade" ? executionSetupMessages.lemonadeDetectedHint(selectableModelIDs(info.models, info.modelInfo, meta.id).length, info.modelInfo?.length ?? info.models.length) : `detected · ${info.models.length} model(s)` : "not detected (you can point it to another machine)",
19511
19979
  selected: info?.reachable ?? false
19512
19980
  };
19513
19981
  });
@@ -19624,17 +20092,18 @@ async function runSetup(deps) {
19624
20092
  };
19625
20093
  const openTeamConfig = buildOpenTeamConfig(answers);
19626
20094
  const opencodeConfig = buildOpencodeConfig(answers);
20095
+ const opencodeConfigPaths = LEMONADE_PROJECT_CONFIG_CANDIDATES;
19627
20096
  const orchestratorAgent = buildOrchestratorAgent(orchestratorAgentModel(answers), { yolo });
19628
20097
  const slashCommands = buildOpenteamCommands();
19629
20098
  const openTeamPath = DEFAULT_CONFIG_PATH;
19630
- const existingOpencodePath = await deps.resolveOpencodeWriteTarget(OPENCODE_CONFIG_CANDIDATES);
20099
+ const existingOpencodePath = await deps.resolveOpencodeWriteTarget(opencodeConfigPaths);
19631
20100
  const opencodeDataPath = existingOpencodePath ?? OPENCODE_CONFIG_CANDIDATES[0];
19632
20101
  const agentPath = ORCHESTRATOR_AGENT_PATH;
19633
20102
  let existingOpenTeamConfig;
19634
20103
  let existingOpencodeFiles;
19635
20104
  try {
19636
20105
  existingOpenTeamConfig = await readExistingOpenTeamConfig(openTeamPath, deps);
19637
- existingOpencodeFiles = await readExistingOpencodeConfigFiles(OPENCODE_CONFIG_CANDIDATES, deps);
20106
+ existingOpencodeFiles = await readExistingOpencodeConfigFiles(opencodeConfigPaths, deps);
19638
20107
  } catch (error) {
19639
20108
  if (error instanceof ConfigParseError) {
19640
20109
  return {
@@ -19644,7 +20113,29 @@ async function runSetup(deps) {
19644
20113
  }
19645
20114
  throw error;
19646
20115
  }
19647
- const effectiveExistingOpencode = mergeExistingOpencodeConfigFiles(existingOpencodeFiles);
20116
+ assertPreviousLemonadePrimary(answers, existingOpenTeamConfig);
20117
+ const effectiveExistingOpencode = mergeExistingOpencodeConfigFiles(existingOpencodeFiles, opencodeConfigPaths);
20118
+ const {
20119
+ config: finalOpenTeamConfig,
20120
+ providerIDs: retainedLemonadeProviderIDs
20121
+ } = preserveRetainedLemonadeRuntimes(existingOpenTeamConfig !== undefined ? mergeOpenTeamConfigForRerun(openTeamConfig, existingOpenTeamConfig) : openTeamConfig, existingOpenTeamConfig, effectiveExistingOpencode);
20122
+ assertEffectiveConfigModelDomains(finalOpenTeamConfig);
20123
+ const effectiveOpenTeamConfig = await effectiveSetupConfig(finalOpenTeamConfig, existingOpencodeFiles, deps);
20124
+ assertEffectiveConfigModelDomains(effectiveOpenTeamConfig);
20125
+ for (const providerID of retainedLemonadeProviderIDs) {
20126
+ const matches = effectiveOpenTeamConfig.local.runtimes.filter((runtime) => runtime.defaultModel.providerID === providerID);
20127
+ if (matches.length !== 1 || matches[0] === undefined || localRuntimeKind(matches[0]) !== "lemonade")
20128
+ throw new Error(executionSetupMessages.lemonadeRetainedProviderUnprotected(providerID));
20129
+ }
20130
+ const v2Denials = lemonadeV2Policies([
20131
+ ...opencodeConfig.experimental?.policies.map((policy) => policy.resource) ?? [],
20132
+ ...effectiveOpenTeamConfig.local.runtimes.filter((runtime) => localRuntimeKind(runtime) === "lemonade").map((runtime) => runtime.defaultModel.providerID)
20133
+ ]);
20134
+ if (v2Denials.length > 0)
20135
+ opencodeConfig.experimental = { policies: v2Denials };
20136
+ const v2Notice = v2Denials.length > 0 ? executionSetupMessages.lemonadeV2Restriction(v2Denials.map((policy) => policy.resource)) : undefined;
20137
+ if (v2Notice !== undefined)
20138
+ prompt.note(v2Notice, executionSetupMessages.lemonadeV2Title);
19648
20139
  const relevantProviderIDs = relevantLocalProviderIDs(opencodeConfig, existingOpenTeamConfig);
19649
20140
  for (const file of existingOpencodeFiles) {
19650
20141
  assertRelevantLimitNumbers(file, relevantProviderIDs);
@@ -19673,8 +20164,6 @@ async function runSetup(deps) {
19673
20164
  const pluginOwnerFile = opencodeFileAt(existingOpencodeFiles, pluginOwnerPath);
19674
20165
  const pluginPlan = await mergePluginEntriesForRerun(Array.isArray(pluginOwnerFile?.raw.plugin) ? pluginOwnerFile.raw.plugin : [], pluginOwnerPath, preservePlugin, deps.classifyLocalPluginSpec);
19675
20166
  const includePluginInDataFile = pluginOwnerPath === opencodeDataPath;
19676
- const finalOpenTeamConfig = existingOpenTeamConfig !== undefined ? mergeOpenTeamConfigForRerun(openTeamConfig, existingOpenTeamConfig) : openTeamConfig;
19677
- assertEffectiveConfigModelDomains(finalOpenTeamConfig);
19678
20167
  const dataTargetRaw = opencodeFileAt(existingOpencodeFiles, opencodeDataPath)?.raw ?? {};
19679
20168
  const mergedOpencodeRaw = mergeOpencodeConfigForRerun(opencodeConfig, dataTargetRaw, {
19680
20169
  ...effectiveExistingOpencode !== undefined ? { effectiveRaw: effectiveExistingOpencode } : {},
@@ -19689,7 +20178,7 @@ async function runSetup(deps) {
19689
20178
  providerIDs: relevantProviderIDs
19690
20179
  });
19691
20180
  const opencodeWritePlan = new Map([
19692
- [opencodeDataPath, serializeOpencodeConfig(repairedDataTarget.raw)]
20181
+ [opencodeDataPath, repairedDataTarget.raw]
19693
20182
  ]);
19694
20183
  for (const file of existingOpencodeFiles) {
19695
20184
  if (file.path === opencodeDataPath) {
@@ -19701,14 +20190,14 @@ async function runSetup(deps) {
19701
20190
  generated: opencodeConfig,
19702
20191
  providerIDs: relevantProviderIDs
19703
20192
  });
19704
- let plannedRaw = repaired.raw;
19705
- let changed = repaired.changed;
20193
+ let plannedRaw = reconcileLemonadeV2Policies(repaired.raw, v2Denials);
20194
+ let changed = repaired.changed || plannedRaw !== repaired.raw;
19706
20195
  if (file.path === pluginOwnerPath && !includePluginInDataFile && pluginPlan.changed) {
19707
20196
  plannedRaw = { ...plannedRaw, plugin: [...pluginPlan.plugins] };
19708
20197
  changed = true;
19709
20198
  }
19710
20199
  if (changed) {
19711
- opencodeWritePlan.set(file.path, serializeOpencodeConfig(plannedRaw));
20200
+ opencodeWritePlan.set(file.path, plannedRaw);
19712
20201
  }
19713
20202
  }
19714
20203
  const opencodeGitignorePath = OPENCODE_GITIGNORE_PATH;
@@ -19772,9 +20261,13 @@ async function runSetup(deps) {
19772
20261
  stdout: shouldWriteOpencodeGitignore ? `setup cancelled by user; ${OPENCODE_GITIGNORE_PATH} ensured` : "setup cancelled by user"
19773
20262
  };
19774
20263
  }
20264
+ const effectivePlannedOpencode = mergeExistingOpencodeConfigFiles(existingOpencodeFiles, opencodeConfigPaths, opencodeWritePlan);
20265
+ if (effectivePlannedOpencode === undefined)
20266
+ throw new Error(executionSetupMessages.lemonadeEndpointMismatch);
20267
+ await verifyLemonadeBeforeWrite(deps, answers, effectiveOpenTeamConfig, effectivePlannedOpencode);
19775
20268
  await deps.writeFile(openTeamPath, serializeOpenTeamConfig(finalOpenTeamConfig));
19776
20269
  for (const [path2, contents] of opencodeWritePlan) {
19777
- await deps.writeFile(path2, contents);
20270
+ await deps.writeFile(path2, serializeOpencodeConfig(contents));
19778
20271
  }
19779
20272
  await deps.writeFile(agentPath, orchestratorAgent);
19780
20273
  for (const command of slashCommands) {
@@ -19805,7 +20298,11 @@ async function runSetup(deps) {
19805
20298
  prompt.outro(executionSetupMessages.done);
19806
20299
  return {
19807
20300
  exitCode: 0,
19808
- stdout: executionSetupMessages.complete(`${writtenOpencodePaths}, ${DEFAULT_CONFIG_PATH}, ${ORCHESTRATOR_AGENT_PATH}, ${OPENTEAM_COMMAND_DIR}/*.md, ${OPENCODE_GITIGNORE_PATH}`)
20301
+ stdout: [
20302
+ executionSetupMessages.complete(`${writtenOpencodePaths}, ${DEFAULT_CONFIG_PATH}, ${ORCHESTRATOR_AGENT_PATH}, ${OPENTEAM_COMMAND_DIR}/*.md, ${OPENCODE_GITIGNORE_PATH}`),
20303
+ ...v2Notice === undefined ? [] : [v2Notice]
20304
+ ].join(`
20305
+ `)
19809
20306
  };
19810
20307
  } catch (error) {
19811
20308
  const message = error instanceof Error ? error.message : String(error);
@@ -20460,7 +20957,7 @@ import {
20460
20957
  import { basename as basename3, dirname as dirname8, join as join19, relative as relative2, resolve as resolve11, win32 } from "node:path";
20461
20958
  import { fileURLToPath } from "node:url";
20462
20959
  import { promisify as promisify2 } from "node:util";
20463
- import { z as z24 } from "zod";
20960
+ import { z as z25 } from "zod";
20464
20961
  var NPM_ORIGIN = "https://registry.npmjs.org";
20465
20962
  var NPM_PACKAGE_PATH = "/@jmanuelcorral%2Fopenteam";
20466
20963
  var NPM_LATEST_URL = `${NPM_ORIGIN}${NPM_PACKAGE_PATH}/latest`;
@@ -20479,9 +20976,9 @@ var UPGRADE_BACKUP_DIRECTORY = ".opencode/openteam-local/upgrade-backups";
20479
20976
  function npmVersionUrl(version) {
20480
20977
  return `${NPM_ORIGIN}${NPM_PACKAGE_PATH}/${version}`;
20481
20978
  }
20482
- var RegistryPackageIdentitySchema = z24.object({
20483
- name: z24.string(),
20484
- version: z24.string()
20979
+ var RegistryPackageIdentitySchema = z25.object({
20980
+ name: z25.string(),
20981
+ version: z25.string()
20485
20982
  }).strict();
20486
20983
 
20487
20984
  class TransientFetchError extends Error {
@@ -22140,12 +22637,19 @@ function defaultModelFromOpencode(opencodeConfig) {
22140
22637
  }
22141
22638
  return;
22142
22639
  }
22143
- function liveModelsFromSnapshots(snapshots) {
22640
+ function liveModelsFromSnapshots(snapshots, config) {
22144
22641
  const map = new Map;
22145
22642
  for (const snapshot of snapshots) {
22146
- map.set(snapshot.id, {
22643
+ const runtime = config.local.runtimes.find((runtime2) => runtime2.id === snapshot.id);
22644
+ if (runtime === undefined || !runtime.enabled)
22645
+ continue;
22646
+ const kind = localRuntimeKind(runtime);
22647
+ map.set(runtime.defaultModel.providerID, {
22147
22648
  reachable: snapshot.reachable,
22148
- modelIDs: new Set(snapshot.models.map((model) => model.modelID))
22649
+ modelIDs: new Set(snapshot.models.filter((model) => hasRequiredModelResidency(kind, model)).map((model) => model.modelID)),
22650
+ ...kind === "lemonade" ? {
22651
+ residency: new Map(snapshot.models.map((model) => [model.modelID, model.loaded]))
22652
+ } : {}
22149
22653
  });
22150
22654
  }
22151
22655
  return map;
@@ -22431,7 +22935,7 @@ async function runCli(argv, deps) {
22431
22935
  const agentModels = diagnoseAgentModels(agentFiles, {
22432
22936
  opencodeProviders: parseOpencodeProviders(opencodeConfig),
22433
22937
  localRuntimes: localRuntimeStates(config),
22434
- liveModels: liveModelsFromSnapshots(snapshots),
22938
+ liveModels: liveModelsFromSnapshots(snapshots, config),
22435
22939
  sourceDir: deps.agentDir,
22436
22940
  ...defaultModel !== undefined ? { defaultModel } : {}
22437
22941
  });
@@ -22470,29 +22974,53 @@ async function runCli(argv, deps) {
22470
22974
  const rosterMissing = deps.loadRosterForDoctor !== undefined && roster === undefined && rosterLoadError === undefined;
22471
22975
  const orchestratorAgentName = ORCHESTRATOR_AGENT_PATH.slice(ORCHESTRATOR_AGENT_PATH.lastIndexOf("/") + 1).replace(/\.md$/, "");
22472
22976
  const orchestratorAgentMissing = !agentFiles.some((file) => file.name === orchestratorAgentName);
22977
+ const inventoryNotes = [];
22978
+ const readySnapshots = snapshots.map((snapshot) => {
22979
+ const runtime = config.local.runtimes.find((runtime2) => runtime2.id === snapshot.id);
22980
+ if (runtime === undefined || localRuntimeKind(runtime) !== "lemonade")
22981
+ return snapshot;
22982
+ inventoryNotes.push(executionSetupMessages.lemonadeInventory(runtime.id, runtime.defaultModel.providerID, snapshot.models));
22983
+ return {
22984
+ ...snapshot,
22985
+ models: snapshot.models.filter((model) => hasRequiredModelResidency(localRuntimeKind(runtime), model))
22986
+ };
22987
+ });
22988
+ const residencyNotes = agentModels.flatMap((agent) => {
22989
+ const live = agent.resolution?.live;
22990
+ if (agent.model === undefined || live !== "not-loaded" && live !== "residency-unknown")
22991
+ return [];
22992
+ return [
22993
+ executionSetupMessages.lemonadeAgentResidency(agent.name, `${agent.model.providerID}/${agent.model.modelID}`, live)
22994
+ ];
22995
+ });
22473
22996
  return {
22474
22997
  exitCode: 0,
22475
- stdout: renderDoctor({
22476
- config,
22477
- snapshots,
22478
- telemetryPath,
22479
- telemetryRecords: records.length,
22480
- agentModels,
22481
- opencodeConfigPaths,
22482
- ...opencodeConfig !== undefined ? { opencodeConfig } : {},
22483
- ...queueWait !== undefined ? { queueWait } : {},
22484
- ...rosterAudit !== undefined ? { rosterAudit } : {},
22485
- ...rosterRoleCount !== undefined ? { rosterRoleCount } : {},
22486
- ...rosterLoadError !== undefined ? { rosterLoadError } : {},
22487
- ...rosterMissing ? { rosterMissing } : {},
22488
- ...orchestratorAgentMissing ? { orchestratorAgentMissing } : {},
22489
- ...diagnostics !== undefined && diagnostics.length > 0 ? { diagnostics } : {},
22490
- ...opencodeConfigError !== undefined ? { opencodeConfigError } : {},
22491
- ...cacheEntries !== undefined ? { cacheEntries, cliVersion: deps.version } : {},
22492
- ...legacyLayout !== undefined && legacyLayout.length > 0 ? { legacyLayout } : {},
22493
- ...otelBackend !== undefined ? { otelBackend } : {},
22494
- ...gitignoreCoverage !== undefined ? { gitignore: gitignoreCoverage } : {}
22495
- })
22998
+ stdout: [
22999
+ renderDoctor({
23000
+ config,
23001
+ snapshots: readySnapshots,
23002
+ telemetryPath,
23003
+ telemetryRecords: records.length,
23004
+ agentModels,
23005
+ opencodeConfigPaths,
23006
+ ...opencodeConfig !== undefined ? { opencodeConfig } : {},
23007
+ ...queueWait !== undefined ? { queueWait } : {},
23008
+ ...rosterAudit !== undefined ? { rosterAudit } : {},
23009
+ ...rosterRoleCount !== undefined ? { rosterRoleCount } : {},
23010
+ ...rosterLoadError !== undefined ? { rosterLoadError } : {},
23011
+ ...rosterMissing ? { rosterMissing } : {},
23012
+ ...orchestratorAgentMissing ? { orchestratorAgentMissing } : {},
23013
+ ...diagnostics !== undefined && diagnostics.length > 0 ? { diagnostics } : {},
23014
+ ...opencodeConfigError !== undefined ? { opencodeConfigError } : {},
23015
+ ...cacheEntries !== undefined ? { cacheEntries, cliVersion: deps.version } : {},
23016
+ ...legacyLayout !== undefined && legacyLayout.length > 0 ? { legacyLayout } : {},
23017
+ ...otelBackend !== undefined ? { otelBackend } : {},
23018
+ ...gitignoreCoverage !== undefined ? { gitignore: gitignoreCoverage } : {}
23019
+ }),
23020
+ ...inventoryNotes,
23021
+ ...residencyNotes
23022
+ ].join(`
23023
+ `)
22496
23024
  };
22497
23025
  }
22498
23026
  if (command === "migrate") {
@@ -22609,14 +23137,14 @@ ${HELP}`
22609
23137
  }
22610
23138
 
22611
23139
  // src/orchestrator/roster.ts
22612
- import { z as z25 } from "zod";
22613
- var RosterEntrySchema = z25.object({
22614
- roleID: z25.string().min(1),
22615
- agentName: z25.string().min(1)
23140
+ import { z as z26 } from "zod";
23141
+ var RosterEntrySchema = z26.object({
23142
+ roleID: z26.string().min(1),
23143
+ agentName: z26.string().min(1)
22616
23144
  }).strict();
22617
- var RosterSchema = z25.object({
22618
- universe: z25.string().min(1),
22619
- entries: z25.array(RosterEntrySchema)
23145
+ var RosterSchema = z26.object({
23146
+ universe: z26.string().min(1),
23147
+ entries: z26.array(RosterEntrySchema)
22620
23148
  }).strict();
22621
23149
  var ROSTER_JSON_FENCE = /```json\s*([\s\S]*?)```/;
22622
23150
 
@@ -23170,7 +23698,7 @@ import { readFile as readFile4 } from "node:fs/promises";
23170
23698
  import { basename as basename4, dirname as dirname9 } from "node:path";
23171
23699
 
23172
23700
  // src/graph/certificate.ts
23173
- import { z as z26 } from "zod";
23701
+ import { z as z27 } from "zod";
23174
23702
 
23175
23703
  // src/contract/opencode.ts
23176
23704
  var SUPPORTED_OPENCODE_VERSIONS = [
@@ -23211,7 +23739,7 @@ function isCertificateVersionCompatible(certifiedVersion, liveVersion) {
23211
23739
 
23212
23740
  // src/graph/certificate.ts
23213
23741
  var SHADOW_CERTIFICATE_MIN_RUNS = 1000;
23214
- var DivergenceCodeSchema = z26.enum([
23742
+ var DivergenceCodeSchema = z27.enum([
23215
23743
  "status",
23216
23744
  "order",
23217
23745
  "roles",
@@ -23219,50 +23747,50 @@ var DivergenceCodeSchema = z26.enum([
23219
23747
  "fixes",
23220
23748
  "outcome"
23221
23749
  ]);
23222
- var ProvenanceSchema = z26.enum([
23750
+ var ProvenanceSchema = z27.enum([
23223
23751
  "recomputed",
23224
23752
  "compiled",
23225
23753
  "validated",
23226
23754
  "carried"
23227
23755
  ]);
23228
- var EvidenceSchema = z26.object({
23229
- opencodeVersion: z26.string().min(1),
23230
- parity: z26.object({
23231
- runs: z26.number().int().nonnegative(),
23232
- match: z26.number().int().nonnegative(),
23233
- divergent: z26.number().int().nonnegative(),
23234
- inconclusive: z26.number().int().nonnegative(),
23235
- divergences: z26.array(DivergenceCodeSchema)
23756
+ var EvidenceSchema = z27.object({
23757
+ opencodeVersion: z27.string().min(1),
23758
+ parity: z27.object({
23759
+ runs: z27.number().int().nonnegative(),
23760
+ match: z27.number().int().nonnegative(),
23761
+ divergent: z27.number().int().nonnegative(),
23762
+ inconclusive: z27.number().int().nonnegative(),
23763
+ divergences: z27.array(DivergenceCodeSchema)
23236
23764
  }).strict(),
23237
- legacy: z26.object({
23238
- observed: z26.number().int().nonnegative(),
23239
- duplicated: z26.number().int().nonnegative()
23765
+ legacy: z27.object({
23766
+ observed: z27.number().int().nonnegative(),
23767
+ duplicated: z27.number().int().nonnegative()
23240
23768
  }).strict(),
23241
- privacy: z26.object({
23242
- surfacesScanned: z26.number().int().nonnegative(),
23243
- rawFindings: z26.number().int().nonnegative()
23769
+ privacy: z27.object({
23770
+ surfacesScanned: z27.number().int().nonnegative(),
23771
+ rawFindings: z27.number().int().nonnegative()
23244
23772
  }).strict(),
23245
- overhead: z26.object({
23246
- p95Millis: z26.number().nonnegative(),
23247
- budgetMillis: z26.number().positive(),
23248
- samples: z26.number().int().nonnegative()
23773
+ overhead: z27.object({
23774
+ p95Millis: z27.number().nonnegative(),
23775
+ budgetMillis: z27.number().positive(),
23776
+ samples: z27.number().int().nonnegative()
23249
23777
  }).strict(),
23250
- provenance: z26.record(DivergenceCodeSchema, ProvenanceSchema)
23778
+ provenance: z27.record(DivergenceCodeSchema, ProvenanceSchema)
23251
23779
  }).strict();
23252
- var CertificateSchema = z26.object({
23253
- version: z26.literal(1),
23254
- certificate: z26.literal("graph-shadow"),
23255
- opencodeVersion: z26.string().min(1),
23780
+ var CertificateSchema = z27.object({
23781
+ version: z27.literal(1),
23782
+ certificate: z27.literal("graph-shadow"),
23783
+ opencodeVersion: z27.string().min(1),
23256
23784
  evidence: EvidenceSchema,
23257
- verdict: z26.enum(["pass", "fail"]),
23258
- failedGates: z26.array(z26.enum([
23785
+ verdict: z27.enum(["pass", "fail"]),
23786
+ failedGates: z27.array(z27.enum([
23259
23787
  "sample",
23260
23788
  "parity",
23261
23789
  "one-legacy-execution",
23262
23790
  "privacy",
23263
23791
  "overhead"
23264
23792
  ])),
23265
- digest: z26.string().regex(/^[0-9a-f]{64}$/)
23793
+ digest: z27.string().regex(/^[0-9a-f]{64}$/)
23266
23794
  }).strict();
23267
23795
 
23268
23796
  class ShadowCertificateError extends Error {
@@ -23377,37 +23905,37 @@ function parseShadowCertificate(value, opencodeVersion) {
23377
23905
  }
23378
23906
  return certificate;
23379
23907
  }
23380
- var ReleaseDeterminismSchema = z26.object({ runs: z26.number().int().nonnegative(), allMatch: z26.boolean() }).strict();
23381
- var ReleaseCrashRecoverySchema = z26.object({
23382
- scenarios: z26.number().int().nonnegative(),
23383
- allConverge: z26.boolean()
23908
+ var ReleaseDeterminismSchema = z27.object({ runs: z27.number().int().nonnegative(), allMatch: z27.boolean() }).strict();
23909
+ var ReleaseCrashRecoverySchema = z27.object({
23910
+ scenarios: z27.number().int().nonnegative(),
23911
+ allConverge: z27.boolean()
23384
23912
  }).strict();
23385
- var ReleaseReplayEquivalenceSchema = z26.object({
23386
- checks: z26.number().int().nonnegative(),
23387
- allEquivalent: z26.boolean()
23913
+ var ReleaseReplayEquivalenceSchema = z27.object({
23914
+ checks: z27.number().int().nonnegative(),
23915
+ allEquivalent: z27.boolean()
23388
23916
  }).strict();
23389
- var ReleasePrivacySchema = z26.object({
23390
- surfacesScanned: z26.number().int().nonnegative(),
23391
- rawFindings: z26.number().int().nonnegative()
23917
+ var ReleasePrivacySchema = z27.object({
23918
+ surfacesScanned: z27.number().int().nonnegative(),
23919
+ rawFindings: z27.number().int().nonnegative()
23392
23920
  }).strict();
23393
- var ReleaseContractSchema = z26.object({
23394
- roundTrips: z26.number().int().nonnegative(),
23395
- allSettled: z26.boolean()
23921
+ var ReleaseContractSchema = z27.object({
23922
+ roundTrips: z27.number().int().nonnegative(),
23923
+ allSettled: z27.boolean()
23396
23924
  }).strict();
23397
- var ReleaseHealthSchema = z26.object({
23398
- samples: z26.number().int().nonnegative(),
23399
- bounded: z26.boolean(),
23400
- idempotent: z26.boolean()
23925
+ var ReleaseHealthSchema = z27.object({
23926
+ samples: z27.number().int().nonnegative(),
23927
+ bounded: z27.boolean(),
23928
+ idempotent: z27.boolean()
23401
23929
  }).strict();
23402
- var ReleasePerformanceSchema = z26.object({
23403
- p95Millis: z26.number().nonnegative(),
23404
- budgetMillis: z26.number().positive(),
23405
- samples: z26.number().int().nonnegative()
23930
+ var ReleasePerformanceSchema = z27.object({
23931
+ p95Millis: z27.number().nonnegative(),
23932
+ budgetMillis: z27.number().positive(),
23933
+ samples: z27.number().int().nonnegative()
23406
23934
  }).strict();
23407
- var ReleaseEvidenceSchema = z26.object({
23408
- opencodeVersion: z26.string().min(1),
23409
- platform: z26.enum(["linux", "win32"]),
23410
- shadowCertificateDigest: z26.string().regex(/^[0-9a-f]{64}$/),
23935
+ var ReleaseEvidenceSchema = z27.object({
23936
+ opencodeVersion: z27.string().min(1),
23937
+ platform: z27.enum(["linux", "win32"]),
23938
+ shadowCertificateDigest: z27.string().regex(/^[0-9a-f]{64}$/),
23411
23939
  determinism: ReleaseDeterminismSchema,
23412
23940
  crashRecovery: ReleaseCrashRecoverySchema,
23413
23941
  replayEquivalence: ReleaseReplayEquivalenceSchema,
@@ -23416,15 +23944,15 @@ var ReleaseEvidenceSchema = z26.object({
23416
23944
  health: ReleaseHealthSchema,
23417
23945
  performance: ReleasePerformanceSchema
23418
23946
  }).strict();
23419
- var ReleaseCertificateSchema = z26.object({
23420
- version: z26.literal(2),
23421
- certificate: z26.literal("graph-release"),
23422
- platform: z26.enum(["linux", "win32"]),
23423
- opencodeVersion: z26.string().min(1),
23424
- shadowCertificateDigest: z26.string().regex(/^[0-9a-f]{64}$/),
23947
+ var ReleaseCertificateSchema = z27.object({
23948
+ version: z27.literal(2),
23949
+ certificate: z27.literal("graph-release"),
23950
+ platform: z27.enum(["linux", "win32"]),
23951
+ opencodeVersion: z27.string().min(1),
23952
+ shadowCertificateDigest: z27.string().regex(/^[0-9a-f]{64}$/),
23425
23953
  evidence: ReleaseEvidenceSchema,
23426
- verdict: z26.enum(["pass", "fail"]),
23427
- failedGates: z26.array(z26.enum([
23954
+ verdict: z27.enum(["pass", "fail"]),
23955
+ failedGates: z27.array(z27.enum([
23428
23956
  "shadow-valid",
23429
23957
  "determinism",
23430
23958
  "crash-recovery",
@@ -23434,7 +23962,7 @@ var ReleaseCertificateSchema = z26.object({
23434
23962
  "health",
23435
23963
  "performance"
23436
23964
  ])),
23437
- digest: z26.string().regex(/^[0-9a-f]{64}$/)
23965
+ digest: z27.string().regex(/^[0-9a-f]{64}$/)
23438
23966
  }).strict();
23439
23967
 
23440
23968
  class ReleaseCertificateError extends Error {
@@ -23562,7 +24090,7 @@ function parseReleaseCertificate(value, opencodeVersion, expectedShadowDigest) {
23562
24090
  }
23563
24091
  return certificate;
23564
24092
  }
23565
- var ShadowDivergenceCodeSchema = z26.enum([
24093
+ var ShadowDivergenceCodeSchema = z27.enum([
23566
24094
  "status",
23567
24095
  "order",
23568
24096
  "roles",
@@ -23571,13 +24099,13 @@ var ShadowDivergenceCodeSchema = z26.enum([
23571
24099
  "outcome"
23572
24100
  ]);
23573
24101
  var RECOMPUTED_DIVERGENCE_CODES = ["fixes"];
23574
- var RecomputedDivergenceCodeSchema = z26.enum(RECOMPUTED_DIVERGENCE_CODES);
23575
- var SoakPolicySchema = z26.object({
23576
- minimumGenuineObservations: z26.number().int().positive(),
23577
- minimumDistinctDays: z26.number().int().positive(),
23578
- requireGenuineUsageOnAllPlatforms: z26.boolean(),
23579
- supportedOpencodeVersions: z26.array(z26.string().min(1)).min(1),
23580
- criticalDivergenceCodes: z26.array(RecomputedDivergenceCodeSchema).min(1)
24102
+ var RecomputedDivergenceCodeSchema = z27.enum(RECOMPUTED_DIVERGENCE_CODES);
24103
+ var SoakPolicySchema = z27.object({
24104
+ minimumGenuineObservations: z27.number().int().positive(),
24105
+ minimumDistinctDays: z27.number().int().positive(),
24106
+ requireGenuineUsageOnAllPlatforms: z27.boolean(),
24107
+ supportedOpencodeVersions: z27.array(z27.string().min(1)).min(1),
24108
+ criticalDivergenceCodes: z27.array(RecomputedDivergenceCodeSchema).min(1)
23581
24109
  }).strict();
23582
24110
  var DEFAULT_SOAK_POLICY = {
23583
24111
  minimumGenuineObservations: 100,
@@ -23586,46 +24114,46 @@ var DEFAULT_SOAK_POLICY = {
23586
24114
  supportedOpencodeVersions: [...SUPPORTED_OPENCODE_VERSIONS],
23587
24115
  criticalDivergenceCodes: ["fixes"]
23588
24116
  };
23589
- var SoakPlatformEnumSchema = z26.enum(["linux", "win32", "darwin"]);
23590
- var SoakPrivacyPairEvidenceSchema = z26.object({
23591
- surfacesScanned: z26.number().int().nonnegative(),
23592
- rawFindings: z26.number().int().nonnegative()
24117
+ var SoakPlatformEnumSchema = z27.enum(["linux", "win32", "darwin"]);
24118
+ var SoakPrivacyPairEvidenceSchema = z27.object({
24119
+ surfacesScanned: z27.number().int().nonnegative(),
24120
+ rawFindings: z27.number().int().nonnegative()
23593
24121
  }).strict();
23594
- var SoakDuplicateEffectPairEvidenceSchema = z26.object({
23595
- effectsExamined: z26.number().int().nonnegative(),
23596
- duplicatesFound: z26.number().int().nonnegative()
24122
+ var SoakDuplicateEffectPairEvidenceSchema = z27.object({
24123
+ effectsExamined: z27.number().int().nonnegative(),
24124
+ duplicatesFound: z27.number().int().nonnegative()
23597
24125
  }).strict();
23598
- var SoakModelVerificationPairEvidenceSchema = z26.object({
23599
- nodesChecked: z26.number().int().nonnegative(),
23600
- unverified: z26.number().int().nonnegative(),
23601
- mismatched: z26.number().int().nonnegative()
24126
+ var SoakModelVerificationPairEvidenceSchema = z27.object({
24127
+ nodesChecked: z27.number().int().nonnegative(),
24128
+ unverified: z27.number().int().nonnegative(),
24129
+ mismatched: z27.number().int().nonnegative()
23602
24130
  }).strict();
23603
- var SoakEvidenceSchema = z26.object({
23604
- totalObservations: z26.number().int().nonnegative(),
23605
- genuineUsageObservations: z26.number().int().nonnegative(),
23606
- ciSyntheticObservations: z26.number().int().nonnegative(),
23607
- recorderCount: z26.number().int().nonnegative(),
23608
- ineligibleObservations: z26.number().int().nonnegative(),
23609
- firstTimestamp: z26.string().datetime().nullable(),
23610
- lastTimestamp: z26.string().datetime().nullable(),
23611
- distinctDays: z26.number().int().nonnegative(),
23612
- criticalDivergences: z26.number().int().nonnegative().nullable(),
24131
+ var SoakEvidenceSchema = z27.object({
24132
+ totalObservations: z27.number().int().nonnegative(),
24133
+ genuineUsageObservations: z27.number().int().nonnegative(),
24134
+ ciSyntheticObservations: z27.number().int().nonnegative(),
24135
+ recorderCount: z27.number().int().nonnegative(),
24136
+ ineligibleObservations: z27.number().int().nonnegative(),
24137
+ firstTimestamp: z27.string().datetime().nullable(),
24138
+ lastTimestamp: z27.string().datetime().nullable(),
24139
+ distinctDays: z27.number().int().nonnegative(),
24140
+ criticalDivergences: z27.number().int().nonnegative().nullable(),
23613
24141
  privacy: SoakPrivacyPairEvidenceSchema.nullable(),
23614
24142
  duplicateEffects: SoakDuplicateEffectPairEvidenceSchema.nullable(),
23615
24143
  modelVerification: SoakModelVerificationPairEvidenceSchema.nullable(),
23616
- platformsGenuine: z26.array(SoakPlatformEnumSchema),
23617
- platformsSynthetic: z26.array(SoakPlatformEnumSchema),
23618
- opencodeVersionsObserved: z26.array(z26.string().min(1)),
23619
- invalidChains: z26.number().int().nonnegative()
24144
+ platformsGenuine: z27.array(SoakPlatformEnumSchema),
24145
+ platformsSynthetic: z27.array(SoakPlatformEnumSchema),
24146
+ opencodeVersionsObserved: z27.array(z27.string().min(1)),
24147
+ invalidChains: z27.number().int().nonnegative()
23620
24148
  }).strict();
23621
- var SoakCertificateSchema = z26.object({
23622
- version: z26.literal(1),
23623
- certificate: z26.literal("graph-soak"),
23624
- trustBoundary: z26.literal("contributors"),
24149
+ var SoakCertificateSchema = z27.object({
24150
+ version: z27.literal(1),
24151
+ certificate: z27.literal("graph-soak"),
24152
+ trustBoundary: z27.literal("contributors"),
23625
24153
  policy: SoakPolicySchema,
23626
24154
  evidence: SoakEvidenceSchema,
23627
- verdict: z26.enum(["pass", "fail"]),
23628
- failedGates: z26.array(z26.enum([
24155
+ verdict: z27.enum(["pass", "fail"]),
24156
+ failedGates: z27.array(z27.enum([
23629
24157
  "minimum-observations",
23630
24158
  "minimum-duration",
23631
24159
  "chain-integrity",
@@ -23636,8 +24164,8 @@ var SoakCertificateSchema = z26.object({
23636
24164
  "os-diversity",
23637
24165
  "opencode-pin"
23638
24166
  ])),
23639
- ledgerDigest: z26.string().regex(/^[0-9a-f]{64}$/),
23640
- digest: z26.string().regex(/^[0-9a-f]{64}$/)
24167
+ ledgerDigest: z27.string().regex(/^[0-9a-f]{64}$/),
24168
+ digest: z27.string().regex(/^[0-9a-f]{64}$/)
23641
24169
  }).strict();
23642
24170
 
23643
24171
  class SoakCertificateError extends Error {
@@ -24285,62 +24813,62 @@ var realCacheAdapter = {
24285
24813
  };
24286
24814
 
24287
24815
  // src/memory/types.ts
24288
- import { z as z27 } from "zod";
24816
+ import { z as z28 } from "zod";
24289
24817
  var SHARED_OWNER_KEY = "*";
24290
- var OwnerKeySchema = z27.string().min(1);
24291
- var MemoryKindSchema = z27.enum(["fact", "preference", "entity"]);
24292
- var MemoryBaseSchema = z27.object({
24293
- id: z27.string().min(1),
24818
+ var OwnerKeySchema = z28.string().min(1);
24819
+ var MemoryKindSchema = z28.enum(["fact", "preference", "entity"]);
24820
+ var MemoryBaseSchema = z28.object({
24821
+ id: z28.string().min(1),
24294
24822
  ownerKey: OwnerKeySchema,
24295
- confidence: z27.number().min(0).max(1),
24296
- validFrom: z27.number().finite(),
24297
- validUntil: z27.number().finite().nullable().default(null),
24298
- createdAt: z27.number().finite(),
24299
- invalidatedAt: z27.number().finite().nullable().default(null),
24300
- sourceHash: z27.string().min(1),
24301
- supersededBy: z27.string().min(1).nullable().default(null)
24823
+ confidence: z28.number().min(0).max(1),
24824
+ validFrom: z28.number().finite(),
24825
+ validUntil: z28.number().finite().nullable().default(null),
24826
+ createdAt: z28.number().finite(),
24827
+ invalidatedAt: z28.number().finite().nullable().default(null),
24828
+ sourceHash: z28.string().min(1),
24829
+ supersededBy: z28.string().min(1).nullable().default(null)
24302
24830
  }).strict();
24303
24831
  var FactSchema = MemoryBaseSchema.extend({
24304
- kind: z27.literal("fact"),
24305
- subject: z27.string().min(1),
24306
- predicate: z27.string().min(1),
24307
- object: z27.string().min(1),
24308
- category: z27.string().min(1).nullable().default(null)
24832
+ kind: z28.literal("fact"),
24833
+ subject: z28.string().min(1),
24834
+ predicate: z28.string().min(1),
24835
+ object: z28.string().min(1),
24836
+ category: z28.string().min(1).nullable().default(null)
24309
24837
  });
24310
24838
  var PreferenceSchema = MemoryBaseSchema.extend({
24311
- kind: z27.literal("preference"),
24312
- category: z27.string().min(1),
24313
- preference: z27.string().min(1),
24314
- context: z27.string().min(1).nullable().default(null),
24315
- lastAccessedAt: z27.number().finite().nullable().default(null),
24316
- accessCount: z27.number().int().min(0).default(0)
24839
+ kind: z28.literal("preference"),
24840
+ category: z28.string().min(1),
24841
+ preference: z28.string().min(1),
24842
+ context: z28.string().min(1).nullable().default(null),
24843
+ lastAccessedAt: z28.number().finite().nullable().default(null),
24844
+ accessCount: z28.number().int().min(0).default(0)
24317
24845
  });
24318
24846
  var EntitySchema = MemoryBaseSchema.extend({
24319
- kind: z27.literal("entity"),
24320
- canonicalName: z27.string().min(1),
24321
- type: z27.string().min(1),
24322
- aliases: z27.array(z27.string().min(1)).default([])
24847
+ kind: z28.literal("entity"),
24848
+ canonicalName: z28.string().min(1),
24849
+ type: z28.string().min(1),
24850
+ aliases: z28.array(z28.string().min(1)).default([])
24323
24851
  });
24324
24852
  var RelationSchema = MemoryBaseSchema.extend({
24325
- kind: z27.literal("relation"),
24326
- from: z27.string().min(1),
24327
- to: z27.string().min(1),
24328
- predicate: z27.string().min(1),
24329
- annotation: z27.string().min(1).nullable().default(null)
24853
+ kind: z28.literal("relation"),
24854
+ from: z28.string().min(1),
24855
+ to: z28.string().min(1),
24856
+ predicate: z28.string().min(1),
24857
+ annotation: z28.string().min(1).nullable().default(null)
24330
24858
  });
24331
- var MemoryRecordSchema = z27.discriminatedUnion("kind", [
24859
+ var MemoryRecordSchema = z28.discriminatedUnion("kind", [
24332
24860
  FactSchema,
24333
24861
  PreferenceSchema,
24334
24862
  EntitySchema,
24335
24863
  RelationSchema
24336
24864
  ]);
24337
- var RecallQuerySchema = z27.object({
24865
+ var RecallQuerySchema = z28.object({
24338
24866
  ownerKey: OwnerKeySchema,
24339
- kinds: z27.array(MemoryKindSchema).default(["fact", "preference", "entity"]),
24340
- asOf: z27.number().finite().nullable().default(null),
24341
- limit: z27.number().int().positive().default(8),
24342
- minSimilarity: z27.number().min(0).max(1).default(0.2),
24343
- includeShared: z27.boolean().default(true)
24867
+ kinds: z28.array(MemoryKindSchema).default(["fact", "preference", "entity"]),
24868
+ asOf: z28.number().finite().nullable().default(null),
24869
+ limit: z28.number().int().positive().default(8),
24870
+ minSimilarity: z28.number().min(0).max(1).default(0.2),
24871
+ includeShared: z28.boolean().default(true)
24344
24872
  }).strict();
24345
24873
 
24346
24874
  // src/memory/rank.ts