@odla-ai/cli 0.25.19 → 0.25.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.cjs CHANGED
@@ -82,22 +82,22 @@ function readJsonFile(path) {
82
82
  return null;
83
83
  }
84
84
  }
85
- function writePrivateJson(path, value) {
86
- writePrivateText(path, `${JSON.stringify(value, null, 2)}
85
+ function writePrivateJson(path, value2) {
86
+ writePrivateText(path, `${JSON.stringify(value2, null, 2)}
87
87
  `);
88
88
  }
89
89
  function readCredentials(path) {
90
90
  if (!(0, import_node_fs.existsSync)(path)) return null;
91
- let value;
91
+ let value2;
92
92
  try {
93
- value = JSON.parse((0, import_node_fs.readFileSync)(path, "utf8"));
93
+ value2 = JSON.parse((0, import_node_fs.readFileSync)(path, "utf8"));
94
94
  } catch {
95
95
  throw new Error(`credentials file ${path} is not valid JSON; fix or remove it before provisioning`);
96
96
  }
97
- if (!value || typeof value !== "object" || typeof value.appId !== "string" || !value.envs || typeof value.envs !== "object") {
97
+ if (!value2 || typeof value2 !== "object" || typeof value2.appId !== "string" || !value2.envs || typeof value2.envs !== "object") {
98
98
  throw new Error(`credentials file ${path} has an invalid shape; fix or remove it before provisioning`);
99
99
  }
100
- return value;
100
+ return value2;
101
101
  }
102
102
  function mergeCredential(current, update) {
103
103
  const next = current ?? {
@@ -392,8 +392,8 @@ function stillPending(pending, email) {
392
392
  { retryable: true }
393
393
  );
394
394
  }
395
- function handshakeEmail(value, cached) {
396
- const email = (value ?? import_node_process3.default.env.ODLA_USER_EMAIL ?? cached ?? "").trim().toLowerCase();
395
+ function handshakeEmail(value2, cached) {
396
+ const email = (value2 ?? import_node_process3.default.env.ODLA_USER_EMAIL ?? cached ?? "").trim().toLowerCase();
397
397
  if (email.length > 254 || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
398
398
  throw new Error("a fresh odla handshake requires --email <account> or ODLA_USER_EMAIL");
399
399
  }
@@ -417,10 +417,10 @@ function handshakeUrl(platformUrl, userCode) {
417
417
  url.searchParams.set("code", userCode);
418
418
  return url.toString();
419
419
  }
420
- function platformAudience(value) {
420
+ function platformAudience(value2) {
421
421
  let url;
422
422
  try {
423
- url = new URL(value);
423
+ url = new URL(value2);
424
424
  } catch {
425
425
  throw new Error("platform must be an absolute URL");
426
426
  }
@@ -439,22 +439,22 @@ var import_node_process4 = __toESM(require("process"), 1);
439
439
  var MAX_BYTES = 64 * 1024;
440
440
  async function secretInputValue(options, kind = "credential") {
441
441
  if (options.fromEnv && options.stdin) throw new Error("choose exactly one of --from-env or --stdin");
442
- let value;
443
- if (options.fromEnv) value = import_node_process4.default.env[options.fromEnv];
444
- else if (options.stdin) value = await (options.readStdin ?? (() => readSecretStream(kind)))();
442
+ let value2;
443
+ if (options.fromEnv) value2 = import_node_process4.default.env[options.fromEnv];
444
+ else if (options.stdin) value2 = await (options.readStdin ?? (() => readSecretStream(kind)))();
445
445
  else throw new Error(`${kind} input required: use --from-env <NAME> or --stdin; values are never accepted as arguments`);
446
- value = value?.replace(/[\r\n]+$/, "");
447
- if (!value) throw new Error(options.fromEnv ? `environment variable ${options.fromEnv} is empty or unset` : `stdin ${kind} is empty`);
448
- if (new TextEncoder().encode(value).byteLength > MAX_BYTES) throw new Error(`${kind} exceeds 64 KiB`);
449
- return value;
446
+ value2 = value2?.replace(/[\r\n]+$/, "");
447
+ if (!value2) throw new Error(options.fromEnv ? `environment variable ${options.fromEnv} is empty or unset` : `stdin ${kind} is empty`);
448
+ if (new TextEncoder().encode(value2).byteLength > MAX_BYTES) throw new Error(`${kind} exceeds 64 KiB`);
449
+ return value2;
450
450
  }
451
451
  async function readSecretStream(kind, stream = import_node_process4.default.stdin) {
452
- let value = "";
452
+ let value2 = "";
453
453
  for await (const chunk of stream) {
454
- value += String(chunk);
455
- if (value.length > MAX_BYTES) throw new Error(`${kind} exceeds 64 KiB`);
454
+ value2 += String(chunk);
455
+ if (value2.length > MAX_BYTES) throw new Error(`${kind} exceeds 64 KiB`);
456
456
  }
457
- return value;
457
+ return value2;
458
458
  }
459
459
 
460
460
  // src/admin-ai-auth.ts
@@ -489,6 +489,7 @@ function audienceBoundEnvToken(token, platform) {
489
489
  return token;
490
490
  }
491
491
  var SCOPE_PURPOSE = {
492
+ "platform:status:read": "read the platform fleet health and deployment snapshot",
492
493
  "platform:runbook:write": "add or edit odla's operational runbooks",
493
494
  "platform:ai:policy:write": "change System AI model routing",
494
495
  "platform:ai:policy:read": "read System AI model routing",
@@ -592,13 +593,13 @@ function apiError(status, body) {
592
593
  const message2 = error && typeof error.message === "string" ? error.message : isRecord(body) && typeof body.message === "string" ? body.message : "request failed";
593
594
  return `read System AI admin changes failed (${status}): ${message2}`;
594
595
  }
595
- function timestamp(value) {
596
- if (typeof value !== "number" || !Number.isFinite(value)) return String(value ?? "");
597
- const date = new Date(value);
596
+ function timestamp(value2) {
597
+ if (typeof value2 !== "number" || !Number.isFinite(value2)) return String(value2 ?? "");
598
+ const date = new Date(value2);
598
599
  return Number.isFinite(date.valueOf()) ? date.toISOString() : "";
599
600
  }
600
- function isRecord(value) {
601
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
601
+ function isRecord(value2) {
602
+ return Boolean(value2) && typeof value2 === "object" && !Array.isArray(value2);
602
603
  }
603
604
 
604
605
  // src/admin-ai-policy.ts
@@ -608,11 +609,11 @@ var SYSTEM_AI_PURPOSES = [
608
609
  "security.validation",
609
610
  "runbook.answer"
610
611
  ];
611
- function requireSystemAiPurpose(value) {
612
- if (!SYSTEM_AI_PURPOSES.includes(value)) {
612
+ function requireSystemAiPurpose(value2) {
613
+ if (!SYSTEM_AI_PURPOSES.includes(value2)) {
613
614
  throw new Error(`purpose must be one of: ${SYSTEM_AI_PURPOSES.join(", ")}`);
614
615
  }
615
- return value;
616
+ return value2;
616
617
  }
617
618
 
618
619
  // src/admin-ai-usage.ts
@@ -634,11 +635,11 @@ async function readAdminAiUsage(request2) {
634
635
  if (request2.json) request2.stdout.log(JSON.stringify(body, null, 2));
635
636
  else printUsage(body, request2.stdout);
636
637
  }
637
- function usageLimit(value) {
638
- if (!Number.isSafeInteger(value) || value < 1 || value > 500) {
638
+ function usageLimit(value2) {
639
+ if (!Number.isSafeInteger(value2) || value2 < 1 || value2 > 500) {
639
640
  throw new Error("usage limit must be an integer from 1 to 500");
640
641
  }
641
- return value;
642
+ return value2;
642
643
  }
643
644
  function printUsage(body, out) {
644
645
  const aggregates = isRecord2(body) && isRecord2(body.aggregates) && Array.isArray(body.aggregates.byStatus) ? body.aggregates.byStatus.filter(isRecord2) : [];
@@ -674,15 +675,15 @@ when app/env run actor purpose/role route / policy tokens cost status`);
674
675
  ].join(" "));
675
676
  }
676
677
  }
677
- function numeric(value) {
678
- return typeof value === "number" && Number.isFinite(value) ? value : 0;
678
+ function numeric(value2) {
679
+ return typeof value2 === "number" && Number.isFinite(value2) ? value2 : 0;
679
680
  }
680
- function formatMicrousd(value) {
681
- return typeof value === "number" && Number.isFinite(value) ? `$${(value / 1e6).toFixed(6)}` : "unpriced";
681
+ function formatMicrousd(value2) {
682
+ return typeof value2 === "number" && Number.isFinite(value2) ? `$${(value2 / 1e6).toFixed(6)}` : "unpriced";
682
683
  }
683
- function timestamp2(value) {
684
- if (typeof value !== "number" || !Number.isFinite(value)) return String(value ?? "");
685
- const date = new Date(value);
684
+ function timestamp2(value2) {
685
+ if (typeof value2 !== "number" || !Number.isFinite(value2)) return String(value2 ?? "");
686
+ const date = new Date(value2);
686
687
  return Number.isFinite(date.valueOf()) ? date.toISOString() : "";
687
688
  }
688
689
  async function responseBody2(res) {
@@ -699,8 +700,8 @@ function apiError2(action, status, body) {
699
700
  const message2 = error && typeof error.message === "string" ? error.message : isRecord2(body) && typeof body.message === "string" ? body.message : "request failed";
700
701
  return `${action} failed (${status}): ${message2}`;
701
702
  }
702
- function isRecord2(value) {
703
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
703
+ function isRecord2(value2) {
704
+ return Boolean(value2) && typeof value2 === "object" && !Array.isArray(value2);
704
705
  }
705
706
 
706
707
  // src/admin-ai.ts
@@ -745,11 +746,11 @@ async function adminAi(options) {
745
746
  }
746
747
  if (options.action === "credential-set") {
747
748
  const provider = requireProvider(options.credentialProvider);
748
- const value = await secretInputValue(options);
749
+ const value2 = await secretInputValue(options);
749
750
  const res2 = await doFetch(`${platform}/registry/platform/ai-credentials/${encodeURIComponent(provider)}`, {
750
751
  method: "PUT",
751
752
  headers,
752
- body: JSON.stringify({ value })
753
+ body: JSON.stringify({ value: value2 })
753
754
  });
754
755
  const body2 = await responseBody3(res2);
755
756
  if (!res2.ok) throw new Error(apiError3(`store ${provider} platform credential`, res2.status, body2));
@@ -849,11 +850,11 @@ async function adminAi(options) {
849
850
  const policy = isRecord3(response2) && isRecord3(response2.policy) ? response2.policy : isRecord3(response2) ? response2 : {};
850
851
  out.log(options.json ? JSON.stringify({ policy }, null, 2) : `updated ${purpose}: ${String(policy.provider ?? "unchanged")}/${String(policy.model ?? "unchanged")}`);
851
852
  }
852
- function requireProvider(value) {
853
- if (value !== "anthropic" && value !== "openai" && value !== "google") {
853
+ function requireProvider(value2) {
854
+ if (value2 !== "anthropic" && value2 !== "openai" && value2 !== "google") {
854
855
  throw new Error("provider must be one of: anthropic, openai, google");
855
856
  }
856
- return value;
857
+ return value2;
857
858
  }
858
859
  function policyArray(body) {
859
860
  if (isRecord3(body) && Array.isArray(body.policies)) return body.policies.filter(isRecord3);
@@ -864,7 +865,7 @@ function catalogModels(body) {
864
865
  if (!isRecord3(body) || !isRecord3(body.catalog) || !Array.isArray(body.catalog.models)) {
865
866
  throw new Error("platform returned an invalid System AI model catalog");
866
867
  }
867
- return body.catalog.models.filter((value) => isRecord3(value) && typeof value.id === "string" && typeof value.provider === "string");
868
+ return body.catalog.models.filter((value2) => isRecord3(value2) && typeof value2.id === "string" && typeof value2.provider === "string");
868
869
  }
869
870
  async function responseBody3(res) {
870
871
  const text = await res.text();
@@ -880,8 +881,8 @@ function apiError3(action, status, body) {
880
881
  const message2 = error && typeof error.message === "string" ? error.message : isRecord3(body) && typeof body.message === "string" ? body.message : "request failed";
881
882
  return `${action} failed (${status}): ${message2}`;
882
883
  }
883
- function isRecord3(value) {
884
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
884
+ function isRecord3(value2) {
885
+ return Boolean(value2) && typeof value2 === "object" && !Array.isArray(value2);
885
886
  }
886
887
 
887
888
  // src/argv.ts
@@ -905,10 +906,10 @@ function parseArgv(argv) {
905
906
  addOption(options, rawName, arg.slice(eq + 1));
906
907
  continue;
907
908
  }
908
- const value = argv[i + 1];
909
- if (value !== void 0 && !value.startsWith("--")) {
909
+ const value2 = argv[i + 1];
910
+ if (value2 !== void 0 && !value2.startsWith("--")) {
910
911
  i++;
911
- addOption(options, rawName, value);
912
+ addOption(options, rawName, value2);
912
913
  } else {
913
914
  addOption(options, rawName, true);
914
915
  }
@@ -924,39 +925,39 @@ function assertArgs(parsed, allowedOptions2, maxPositionals) {
924
925
  throw new Error(`unexpected argument "${parsed.positionals[maxPositionals]}"; run "odla-ai help"`);
925
926
  }
926
927
  }
927
- function requiredString(value, name) {
928
- const result = stringOpt(value);
928
+ function requiredString(value2, name) {
929
+ const result = stringOpt(value2);
929
930
  if (!result) throw new Error(`${name} is required`);
930
931
  return result;
931
932
  }
932
- function stringOpt(value) {
933
- if (typeof value === "string") return value;
934
- if (Array.isArray(value)) return value[value.length - 1];
933
+ function stringOpt(value2) {
934
+ if (typeof value2 === "string") return value2;
935
+ if (Array.isArray(value2)) return value2[value2.length - 1];
935
936
  return void 0;
936
937
  }
937
- function listOpt(value) {
938
- if (value === void 0 || typeof value === "boolean") return void 0;
939
- const values = Array.isArray(value) ? value : [value];
938
+ function listOpt(value2) {
939
+ if (value2 === void 0 || typeof value2 === "boolean") return void 0;
940
+ const values = Array.isArray(value2) ? value2 : [value2];
940
941
  return values.flatMap((item) => item.split(",")).map((item) => item.trim()).filter(Boolean);
941
942
  }
942
- function boolOpt(value) {
943
- if (typeof value === "boolean") return value;
944
- if (typeof value === "string" && (value === "true" || value === "false")) return value === "true";
945
- if (value === void 0) return void 0;
943
+ function boolOpt(value2) {
944
+ if (typeof value2 === "boolean") return value2;
945
+ if (typeof value2 === "string" && (value2 === "true" || value2 === "false")) return value2 === "true";
946
+ if (value2 === void 0) return void 0;
946
947
  throw new Error("boolean option must be true or false");
947
948
  }
948
- function numberOpt(value, flag) {
949
- if (value === void 0) return void 0;
950
- const raw = stringOpt(value);
949
+ function numberOpt(value2, flag) {
950
+ if (value2 === void 0) return void 0;
951
+ const raw = stringOpt(value2);
951
952
  const parsed = raw === void 0 ? Number.NaN : Number(raw);
952
953
  if (!Number.isSafeInteger(parsed) || parsed < 1) throw new Error(`${flag} requires a positive integer`);
953
954
  return parsed;
954
955
  }
955
- function addOption(options, name, value) {
956
+ function addOption(options, name, value2) {
956
957
  const current = options[name];
957
- if (current === void 0) options[name] = value;
958
- else if (Array.isArray(current)) current.push(String(value));
959
- else options[name] = [String(current), String(value)];
958
+ if (current === void 0) options[name] = value2;
959
+ else if (Array.isArray(current)) current.push(String(value2));
960
+ else options[name] = [String(current), String(value2)];
960
961
  }
961
962
 
962
963
  // src/operator-context.ts
@@ -968,6 +969,7 @@ var import_node_process8 = __toESM(require("process"), 1);
968
969
  var import_node_fs4 = require("fs");
969
970
  var import_node_path4 = require("path");
970
971
  var import_node_url = require("url");
972
+ var import_apps = require("@odla-ai/apps");
971
973
 
972
974
  // src/integration-validation.ts
973
975
  function validateIntegrations(cfg, path, defaultServices) {
@@ -1022,17 +1024,17 @@ function validateProbes(integration, at) {
1022
1024
  }
1023
1025
  }
1024
1026
  }
1025
- function isRecord4(value) {
1026
- return value !== null && typeof value === "object" && !Array.isArray(value);
1027
+ function isRecord4(value2) {
1028
+ return value2 !== null && typeof value2 === "object" && !Array.isArray(value2);
1027
1029
  }
1028
- function safeText(value, max) {
1029
- return typeof value === "string" && value.trim().length > 0 && value.length <= max && !/[\u0000-\u001f\u007f]/.test(value);
1030
+ function safeText(value2, max) {
1031
+ return typeof value2 === "string" && value2.trim().length > 0 && value2.length <= max && !/[\u0000-\u001f\u007f]/.test(value2);
1030
1032
  }
1031
- function safeProbePath(value) {
1032
- return typeof value === "string" && /^\/[A-Za-z0-9._~!$&'()*+,;=:@%/-]*$/.test(value);
1033
+ function safeProbePath(value2) {
1034
+ return typeof value2 === "string" && /^\/[A-Za-z0-9._~!$&'()*+,;=:@%/-]*$/.test(value2);
1033
1035
  }
1034
- function validId(value) {
1035
- return typeof value === "string" && /^[a-z0-9][a-z0-9-]*$/.test(value);
1036
+ function validId(value2) {
1037
+ return typeof value2 === "string" && /^[a-z0-9][a-z0-9-]*$/.test(value2);
1036
1038
  }
1037
1039
  function unique(values) {
1038
1040
  return [...new Set(values.filter(Boolean))];
@@ -1055,6 +1057,7 @@ async function loadProjectConfig(configPath = "odla.config.mjs") {
1055
1057
  const dbEndpoint = trimSlash(process.env.ODLA_DB_ENDPOINT || raw.dbEndpoint || platformUrl);
1056
1058
  const envs = unique2(raw.envs?.length ? raw.envs : DEFAULT_ENVS);
1057
1059
  const services = unique2(raw.services?.length ? raw.services : DEFAULT_SERVICES);
1060
+ validateServices(services, resolved);
1058
1061
  validateCalendarConfig(raw, envs, services, resolved);
1059
1062
  const local = {
1060
1063
  tokenFile: (0, import_node_path4.resolve)(rootDir, raw.local?.tokenFile ?? ".odla/dev-token.json"),
@@ -1073,10 +1076,10 @@ async function loadProjectConfig(configPath = "odla.config.mjs") {
1073
1076
  local
1074
1077
  };
1075
1078
  }
1076
- async function resolveDataExport(cfg, value, names) {
1077
- if (value === void 0 || value === null || value === false) return void 0;
1078
- if (typeof value !== "string") return value;
1079
- const target = (0, import_node_path4.isAbsolute)(value) ? value : (0, import_node_path4.resolve)(cfg.rootDir, value);
1079
+ async function resolveDataExport(cfg, value2, names) {
1080
+ if (value2 === void 0 || value2 === null || value2 === false) return void 0;
1081
+ if (typeof value2 !== "string") return value2;
1082
+ const target = (0, import_node_path4.isAbsolute)(value2) ? value2 : (0, import_node_path4.resolve)(cfg.rootDir, value2);
1080
1083
  if (target.endsWith(".json")) {
1081
1084
  return JSON.parse((0, import_node_fs4.readFileSync)(target, "utf8"));
1082
1085
  }
@@ -1085,7 +1088,7 @@ async function resolveDataExport(cfg, value, names) {
1085
1088
  if (mod[name] !== void 0) return mod[name];
1086
1089
  }
1087
1090
  if (mod.default !== void 0) return mod.default;
1088
- throw new Error(`${value} did not export ${names.join(", ")} or default`);
1091
+ throw new Error(`${value2} did not export ${names.join(", ")} or default`);
1089
1092
  }
1090
1093
  function buildPlan(cfg) {
1091
1094
  const integrationSchema = cfg.integrations?.some((integration) => integration.schema) ?? false;
@@ -1119,9 +1122,9 @@ function calendarServiceConfig(cfg, env) {
1119
1122
  };
1120
1123
  }
1121
1124
  function calendarBookingPageUrl(cfg, env) {
1122
- const value = cfg.calendar?.google.bookingPageUrl?.[env];
1123
- if (value === void 0 || value === null) return value;
1124
- return new URL(value).toString();
1125
+ const value2 = cfg.calendar?.google.bookingPageUrl?.[env];
1126
+ if (value2 === void 0 || value2 === null) return value2;
1127
+ return new URL(value2).toString();
1125
1128
  }
1126
1129
  function rulesFromSchema(schema) {
1127
1130
  const entities = serializedEntities(schema);
@@ -1135,10 +1138,10 @@ function serializedEntities(schema) {
1135
1138
  if (!entities || typeof entities !== "object" || Array.isArray(entities)) return [];
1136
1139
  return Object.keys(entities);
1137
1140
  }
1138
- function envValue(value) {
1139
- if (!value) return void 0;
1140
- if (value.startsWith("$")) return process.env[value.slice(1)];
1141
- return value;
1141
+ function envValue(value2) {
1142
+ if (!value2) return void 0;
1143
+ if (value2.startsWith("$")) return process.env[value2.slice(1)];
1144
+ return value2;
1142
1145
  }
1143
1146
  function validateRawConfig(raw, path) {
1144
1147
  if (!raw || typeof raw !== "object") throw new Error(`${path} must export an object`);
@@ -1194,8 +1197,8 @@ function validateCalendarConfig(cfg, envs, services, path) {
1194
1197
  if (!isRecord5(google.bookingCalendar)) throw new Error(`${path}: calendar.google.bookingCalendar must map env names to one calendar id`);
1195
1198
  const unknownBookingEnv = Object.keys(google.bookingCalendar).find((env) => !envs.includes(env));
1196
1199
  if (unknownBookingEnv) throw new Error(`${path}: calendar.google.bookingCalendar.${unknownBookingEnv} is not in config envs`);
1197
- for (const [env, value] of Object.entries(google.bookingCalendar)) {
1198
- if (!safeText2(value, 1024)) {
1200
+ for (const [env, value2] of Object.entries(google.bookingCalendar)) {
1201
+ if (!safeText2(value2, 1024)) {
1199
1202
  throw new Error(`${path}: calendar.google.bookingCalendar.${env} must be a calendar id`);
1200
1203
  }
1201
1204
  }
@@ -1204,45 +1207,57 @@ function validateCalendarConfig(cfg, envs, services, path) {
1204
1207
  if (!isRecord5(google.bookingPageUrl)) throw new Error(`${path}: calendar.google.bookingPageUrl must map env names to HTTPS URLs or null`);
1205
1208
  const unknownBookingEnv = Object.keys(google.bookingPageUrl).find((env) => !envs.includes(env));
1206
1209
  if (unknownBookingEnv) throw new Error(`${path}: calendar.google.bookingPageUrl.${unknownBookingEnv} is not in config envs`);
1207
- for (const [env, value] of Object.entries(google.bookingPageUrl)) {
1208
- if (value !== null && !safeHttpsUrl(value)) {
1210
+ for (const [env, value2] of Object.entries(google.bookingPageUrl)) {
1211
+ if (value2 !== null && !safeHttpsUrl(value2)) {
1209
1212
  throw new Error(`${path}: calendar.google.bookingPageUrl.${env} must be an HTTPS URL without credentials or fragment`);
1210
1213
  }
1211
1214
  }
1212
1215
  }
1213
- if (enabled && !services.includes("db")) throw new Error(`${path}: calendar service requires the db service`);
1214
1216
  }
1215
- function assertOnly(value, allowed, label) {
1216
- const extra = Object.keys(value).find((key) => !allowed.includes(key));
1217
+ function validateServices(services, path) {
1218
+ for (const service of services) {
1219
+ const definition = (0, import_apps.appServiceDefinition)(service);
1220
+ if (!definition) {
1221
+ throw new Error(`${path}: unknown service "${service}" (known: ${(0, import_apps.appServiceIds)().join(", ")})`);
1222
+ }
1223
+ for (const dependency of definition.requires) {
1224
+ if (!services.includes(dependency)) {
1225
+ throw new Error(`${path}: ${service} service requires the ${dependency} service`);
1226
+ }
1227
+ }
1228
+ }
1229
+ }
1230
+ function assertOnly(value2, allowed, label) {
1231
+ const extra = Object.keys(value2).find((key) => !allowed.includes(key));
1217
1232
  if (extra) throw new Error(`${label}.${extra} is not supported`);
1218
1233
  }
1219
- function isRecord5(value) {
1220
- return value !== null && typeof value === "object" && !Array.isArray(value);
1234
+ function isRecord5(value2) {
1235
+ return value2 !== null && typeof value2 === "object" && !Array.isArray(value2);
1221
1236
  }
1222
- function safeText2(value, max) {
1223
- return typeof value === "string" && value.trim().length > 0 && value.length <= max && !/[\u0000-\u001f\u007f]/.test(value);
1237
+ function safeText2(value2, max) {
1238
+ return typeof value2 === "string" && value2.trim().length > 0 && value2.length <= max && !/[\u0000-\u001f\u007f]/.test(value2);
1224
1239
  }
1225
- function safeHttpsUrl(value) {
1226
- if (typeof value !== "string" || value.length > 2048) return false;
1240
+ function safeHttpsUrl(value2) {
1241
+ if (typeof value2 !== "string" || value2.length > 2048) return false;
1227
1242
  try {
1228
- const url = new URL(value);
1243
+ const url = new URL(value2);
1229
1244
  return url.protocol === "https:" && !url.username && !url.password && !url.hash;
1230
1245
  } catch {
1231
1246
  return false;
1232
1247
  }
1233
1248
  }
1234
- function validId2(value) {
1235
- return typeof value === "string" && /^[a-z0-9][a-z0-9-]*$/.test(value);
1249
+ function validId2(value2) {
1250
+ return typeof value2 === "string" && /^[a-z0-9][a-z0-9-]*$/.test(value2);
1236
1251
  }
1237
1252
  async function loadConfigModule(path) {
1238
1253
  if (path.endsWith(".json")) return JSON.parse((0, import_node_fs4.readFileSync)(path, "utf8"));
1239
1254
  const mod = await import(`${(0, import_node_url.pathToFileURL)(path).href}?t=${Date.now()}`);
1240
- const value = mod.default ?? mod.config;
1241
- if (typeof value === "function") return await value();
1242
- return value;
1255
+ const value2 = mod.default ?? mod.config;
1256
+ if (typeof value2 === "function") return await value2();
1257
+ return value2;
1243
1258
  }
1244
- function trimSlash(value) {
1245
- return value.replace(/\/+$/, "");
1259
+ function trimSlash(value2) {
1260
+ return value2.replace(/\/+$/, "");
1246
1261
  }
1247
1262
  function unique2(values) {
1248
1263
  return [...new Set(values.filter(Boolean))];
@@ -1268,8 +1283,8 @@ function resolveOperatorProfile(parsed) {
1268
1283
  }
1269
1284
  assertOperatorName(name, "context");
1270
1285
  const profiles = readOperatorProfiles(file);
1271
- const value = Object.hasOwn(profiles, name) ? profiles[name] : void 0;
1272
- if (!value) {
1286
+ const value2 = Object.hasOwn(profiles, name) ? profiles[name] : void 0;
1287
+ if (!value2) {
1273
1288
  throw new Error(
1274
1289
  `operator context "${name}" not found in ${file}; run "odla-ai context list" or save it first`
1275
1290
  );
@@ -1278,7 +1293,7 @@ function resolveOperatorProfile(parsed) {
1278
1293
  name,
1279
1294
  source: fromFlag ? "flag" : "environment",
1280
1295
  file,
1281
- value
1296
+ value: value2
1282
1297
  };
1283
1298
  }
1284
1299
  function listOperatorProfiles(file = operatorProfileFile()) {
@@ -1306,8 +1321,8 @@ function operatorCredentialFiles(selection) {
1306
1321
  scoped: (0, import_node_path5.join)(base, "admin-token.local.json")
1307
1322
  };
1308
1323
  }
1309
- function assertOperatorName(value, label) {
1310
- if (!/^[a-z0-9][a-z0-9-]*$/.test(value)) {
1324
+ function assertOperatorName(value2, label) {
1325
+ if (!/^[a-z0-9][a-z0-9-]*$/.test(value2)) {
1311
1326
  throw new Error(
1312
1327
  `${label} must contain lowercase letters, numbers, and hyphens`
1313
1328
  );
@@ -1333,22 +1348,22 @@ function readOperatorProfiles(file) {
1333
1348
  );
1334
1349
  }
1335
1350
  const profiles = emptyProfiles();
1336
- for (const [name, value] of Object.entries(
1351
+ for (const [name, value2] of Object.entries(
1337
1352
  raw.profiles
1338
1353
  )) {
1339
1354
  assertOperatorName(name, "context");
1340
- profiles[name] = validateProfile(value, `operator context "${name}"`);
1355
+ profiles[name] = validateProfile(value2, `operator context "${name}"`);
1341
1356
  }
1342
1357
  return profiles;
1343
1358
  }
1344
1359
  function emptyProfiles() {
1345
1360
  return /* @__PURE__ */ Object.create(null);
1346
1361
  }
1347
- function validateProfile(value, label) {
1348
- if (!value || typeof value !== "object" || Array.isArray(value)) {
1362
+ function validateProfile(value2, label) {
1363
+ if (!value2 || typeof value2 !== "object" || Array.isArray(value2)) {
1349
1364
  throw new Error(`${label} has an invalid shape`);
1350
1365
  }
1351
- const unknown = Object.keys(value).filter(
1366
+ const unknown = Object.keys(value2).filter(
1352
1367
  (key) => !["platform", "app", "environment"].includes(key)
1353
1368
  );
1354
1369
  if (unknown.length > 0) {
@@ -1356,7 +1371,7 @@ function validateProfile(value, label) {
1356
1371
  `${label} contains unsupported field(s): ${unknown.sort().join(", ")}; contexts store scope metadata only, never credentials`
1357
1372
  );
1358
1373
  }
1359
- const candidate = value;
1374
+ const candidate = value2;
1360
1375
  if (typeof candidate.platform !== "string") {
1361
1376
  throw new Error(`${label} needs an absolute platform URL`);
1362
1377
  }
@@ -1371,8 +1386,8 @@ function validateProfile(value, label) {
1371
1386
  ...environment2 ? { environment: environment2 } : {}
1372
1387
  };
1373
1388
  }
1374
- function clean(value) {
1375
- const normalized = value?.trim();
1389
+ function clean(value2) {
1390
+ const normalized = value2?.trim();
1376
1391
  return normalized || void 0;
1377
1392
  }
1378
1393
 
@@ -1465,8 +1480,8 @@ async function resolveOperatorContext(parsed, options = {}) {
1465
1480
  }
1466
1481
  };
1467
1482
  }
1468
- function clean2(value) {
1469
- const normalized = value?.trim();
1483
+ function clean2(value2) {
1484
+ const normalized = value2?.trim();
1470
1485
  return normalized || void 0;
1471
1486
  }
1472
1487
 
@@ -1534,7 +1549,7 @@ async function adminCommand(parsed, deps = {}) {
1534
1549
  }
1535
1550
 
1536
1551
  // src/tenant.ts
1537
- var import_apps = require("@odla-ai/apps");
1552
+ var import_apps2 = require("@odla-ai/apps");
1538
1553
  function resolveEnv(cfg, requested) {
1539
1554
  const env = requested ?? (cfg.envs.includes("dev") ? "dev" : cfg.envs[0]);
1540
1555
  if (!env || !cfg.envs.includes(env)) {
@@ -1544,7 +1559,7 @@ function resolveEnv(cfg, requested) {
1544
1559
  }
1545
1560
  function resolveTenant(cfg, requested) {
1546
1561
  const env = resolveEnv(cfg, requested);
1547
- return { env, tenant: (0, import_apps.tenantIdFor)(cfg.app.id, env) };
1562
+ return { env, tenant: (0, import_apps2.tenantIdFor)(cfg.app.id, env) };
1548
1563
  }
1549
1564
  function bothTenants(cfg) {
1550
1565
  for (const env of ["dev", "prod"]) {
@@ -1554,7 +1569,7 @@ function bothTenants(cfg) {
1554
1569
  );
1555
1570
  }
1556
1571
  }
1557
- return { sandbox: (0, import_apps.tenantIdFor)(cfg.app.id, "dev"), live: (0, import_apps.tenantIdFor)(cfg.app.id, "prod") };
1572
+ return { sandbox: (0, import_apps2.tenantIdFor)(cfg.app.id, "dev"), live: (0, import_apps2.tenantIdFor)(cfg.app.id, "prod") };
1558
1573
  }
1559
1574
 
1560
1575
  // src/agent-command.ts
@@ -2177,44 +2192,44 @@ var REPLACEMENTS = [
2177
2192
  [/\b(ghp|gho|github_pat)_[A-Za-z0-9_]+/g, "$1_[redacted]"],
2178
2193
  [/\bAKIA[A-Z0-9]{12,}/g, "AKIA[redacted]"]
2179
2194
  ];
2180
- function redactSecrets(value) {
2181
- let result = value;
2195
+ function redactSecrets(value2) {
2196
+ let result = value2;
2182
2197
  for (const [pattern, replacement] of REPLACEMENTS) result = result.replace(pattern, replacement);
2183
2198
  return result;
2184
2199
  }
2185
2200
  function redactingOutput(output) {
2186
- const redactArgs = (args) => args.map((value) => redactOutputValue(value, /* @__PURE__ */ new WeakMap()));
2201
+ const redactArgs = (args) => args.map((value2) => redactOutputValue(value2, /* @__PURE__ */ new WeakMap()));
2187
2202
  return {
2188
2203
  log: (...args) => output.log(...redactArgs(args)),
2189
2204
  error: (...args) => output.error(...redactArgs(args))
2190
2205
  };
2191
2206
  }
2192
- function redactOutputValue(value, seen) {
2193
- if (typeof value === "string") return redactSecrets(value);
2194
- if (value instanceof Error) {
2195
- const redacted = new Error(redactSecrets(value.message));
2196
- redacted.name = value.name;
2197
- if (value.stack) redacted.stack = redactSecrets(value.stack);
2207
+ function redactOutputValue(value2, seen) {
2208
+ if (typeof value2 === "string") return redactSecrets(value2);
2209
+ if (value2 instanceof Error) {
2210
+ const redacted = new Error(redactSecrets(value2.message));
2211
+ redacted.name = value2.name;
2212
+ if (value2.stack) redacted.stack = redactSecrets(value2.stack);
2198
2213
  return redacted;
2199
2214
  }
2200
- if (!value || typeof value !== "object") return value;
2201
- const prior = seen.get(value);
2215
+ if (!value2 || typeof value2 !== "object") return value2;
2216
+ const prior = seen.get(value2);
2202
2217
  if (prior) return prior;
2203
- if (Array.isArray(value)) {
2218
+ if (Array.isArray(value2)) {
2204
2219
  const next2 = [];
2205
- seen.set(value, next2);
2206
- for (const item of value) next2.push(redactOutputValue(item, seen));
2220
+ seen.set(value2, next2);
2221
+ for (const item of value2) next2.push(redactOutputValue(item, seen));
2207
2222
  return next2;
2208
2223
  }
2209
- const prototype = Object.getPrototypeOf(value);
2210
- if (prototype !== Object.prototype && prototype !== null) return value;
2224
+ const prototype = Object.getPrototypeOf(value2);
2225
+ if (prototype !== Object.prototype && prototype !== null) return value2;
2211
2226
  const next = {};
2212
- seen.set(value, next);
2213
- for (const [key, item] of Object.entries(value)) next[key] = redactOutputValue(item, seen);
2227
+ seen.set(value2, next);
2228
+ for (const [key, item] of Object.entries(value2)) next[key] = redactOutputValue(item, seen);
2214
2229
  return next;
2215
2230
  }
2216
- function looksSecret(value) {
2217
- return redactSecrets(value) !== value || value.includes("-----BEGIN");
2231
+ function looksSecret(value2) {
2232
+ return redactSecrets(value2) !== value2 || value2.includes("-----BEGIN");
2218
2233
  }
2219
2234
 
2220
2235
  // src/calendar-http.ts
@@ -2231,9 +2246,9 @@ async function readCalendarStatus(ctx) {
2231
2246
  }
2232
2247
  async function discoverGoogleCalendars(ctx) {
2233
2248
  const raw = await calendarJson(ctx, "/calendars", {});
2234
- const value = record(raw);
2235
- if (!value || !Array.isArray(value.calendars)) throw new Error("calendar discovery returned an invalid response");
2236
- return value.calendars.map((item, index) => {
2249
+ const value2 = record(raw);
2250
+ if (!value2 || !Array.isArray(value2.calendars)) throw new Error("calendar discovery returned an invalid response");
2251
+ return value2.calendars.map((item, index) => {
2237
2252
  const calendar = record(item);
2238
2253
  const id = textField(calendar?.id, 1024);
2239
2254
  if (!calendar || !id) throw new Error(`calendar discovery returned an invalid calendar at index ${index}`);
@@ -2255,10 +2270,10 @@ async function applyCalendarSettings(ctx, bookingPageUrl) {
2255
2270
  }
2256
2271
  async function startCalendarConnection(ctx) {
2257
2272
  const raw = await calendarJson(ctx, "/google/connect", { method: "POST", body: "{}" });
2258
- const value = wrapped(raw, "attempt");
2259
- const attemptId = textField(value.attemptId, 180);
2260
- const consentUrl = textField(value.consentUrl, 4096);
2261
- const expiresAt = timestamp3(value.expiresAt);
2273
+ const value2 = wrapped(raw, "attempt");
2274
+ const attemptId = textField(value2.attemptId, 180);
2275
+ const consentUrl = textField(value2.consentUrl, 4096);
2276
+ const expiresAt = timestamp3(value2.expiresAt);
2262
2277
  if (!attemptId || !consentUrl || expiresAt === void 0) throw new Error("calendar connect returned an invalid attempt");
2263
2278
  return { attemptId, consentUrl, expiresAt };
2264
2279
  }
@@ -2276,42 +2291,42 @@ async function requestCalendarDisconnect(ctx) {
2276
2291
  }
2277
2292
  function parseCalendarStatus(raw, env) {
2278
2293
  const outer = wrapped(raw, "calendar");
2279
- const value = record(outer.attempt) ?? record(outer.status) ?? outer;
2280
- const connection = record(value.connection) ?? {};
2281
- const config = record(value.config) ?? record(outer.config) ?? {};
2294
+ const value2 = record(outer.attempt) ?? record(outer.status) ?? outer;
2295
+ const connection = record(value2.connection) ?? {};
2296
+ const config = record(value2.config) ?? record(outer.config) ?? {};
2282
2297
  const googleConfig = record(config.google) ?? config;
2283
- const stateValue = calendarState(value.status ?? value.state ?? connection.status ?? connection.state);
2298
+ const stateValue = calendarState(value2.status ?? value2.state ?? connection.status ?? connection.state);
2284
2299
  if (!stateValue) {
2285
2300
  throw new Error("calendar status returned an invalid connection state");
2286
2301
  }
2287
- const providerValue = value.provider ?? connection.provider ?? config.provider ?? (config.google ? "google" : void 0);
2302
+ const providerValue = value2.provider ?? connection.provider ?? config.provider ?? (config.google ? "google" : void 0);
2288
2303
  if (providerValue !== void 0 && providerValue !== null && providerValue !== "google") {
2289
2304
  throw new Error("calendar status returned an unsupported provider");
2290
2305
  }
2291
- const accessValue = value.access ?? connection.access ?? config.access ?? googleConfig.access;
2306
+ const accessValue = value2.access ?? connection.access ?? config.access ?? googleConfig.access;
2292
2307
  if (accessValue !== void 0 && accessValue !== "book" && accessValue !== "read") {
2293
2308
  throw new Error("calendar status returned unsupported access");
2294
2309
  }
2295
- const errorValue = record(value.error) ?? record(connection.error);
2296
- const errorCode = textField(value.lastErrorCode, 128);
2297
- const bookingPageValue = Object.hasOwn(value, "bookingPageUrl") ? value.bookingPageUrl : Object.hasOwn(config, "bookingPageUrl") ? config.bookingPageUrl : googleConfig.bookingPageUrl;
2298
- const connected = typeof (value.connected ?? connection.connected) === "boolean" ? Boolean(value.connected ?? connection.connected) : ["healthy", "degraded"].includes(stateValue);
2299
- const bookingCalendarId = textField(value.bookingCalendarId ?? config.bookingCalendarId, 1024);
2310
+ const errorValue = record(value2.error) ?? record(connection.error);
2311
+ const errorCode = textField(value2.lastErrorCode, 128);
2312
+ const bookingPageValue = Object.hasOwn(value2, "bookingPageUrl") ? value2.bookingPageUrl : Object.hasOwn(config, "bookingPageUrl") ? config.bookingPageUrl : googleConfig.bookingPageUrl;
2313
+ const connected = typeof (value2.connected ?? connection.connected) === "boolean" ? Boolean(value2.connected ?? connection.connected) : ["healthy", "degraded"].includes(stateValue);
2314
+ const bookingCalendarId = textField(value2.bookingCalendarId ?? config.bookingCalendarId, 1024);
2300
2315
  return {
2301
2316
  env,
2302
- enabled: typeof value.enabled === "boolean" ? value.enabled : true,
2317
+ enabled: typeof value2.enabled === "boolean" ? value2.enabled : true,
2303
2318
  connected,
2304
- writable: typeof value.writable === "boolean" ? value.writable : stateValue === "healthy",
2319
+ writable: typeof value2.writable === "boolean" ? value2.writable : stateValue === "healthy",
2305
2320
  provider: providerValue === "google" ? "google" : null,
2306
2321
  status: stateValue,
2307
2322
  ...accessValue !== void 0 ? { access: "book" } : {},
2308
2323
  ...bookingCalendarId ? { bookingCalendarId } : {},
2309
2324
  calendars: calendarIds(
2310
- value.availabilityCalendars ?? config.availabilityCalendars ?? value.configuredCalendars ?? value.calendars ?? config.calendars ?? googleConfig.calendars
2325
+ value2.availabilityCalendars ?? config.availabilityCalendars ?? value2.configuredCalendars ?? value2.calendars ?? config.calendars ?? googleConfig.calendars
2311
2326
  ),
2312
2327
  ...optionalNullableUrl("bookingPageUrl", bookingPageValue),
2313
- grantedScopes: stringList(value.grantedScopes ?? connection.grantedScopes ?? connection.scopes),
2314
- ...optionalText("attemptId", value.attemptId ?? connection.attemptId, 180),
2328
+ grantedScopes: stringList(value2.grantedScopes ?? connection.grantedScopes ?? connection.scopes),
2329
+ ...optionalText("attemptId", value2.attemptId ?? connection.attemptId, 180),
2315
2330
  ...errorValue || errorCode ? { error: {
2316
2331
  ...textField(errorValue?.code, 128) ? { code: textField(errorValue?.code, 128) } : {},
2317
2332
  ...textField(errorValue?.message, 500) ? { message: textField(errorValue?.message, 500) } : {},
@@ -2319,9 +2334,9 @@ function parseCalendarStatus(raw, env) {
2319
2334
  } } : {}
2320
2335
  };
2321
2336
  }
2322
- function calendarState(value) {
2323
- if (typeof value !== "string") return null;
2324
- if (CALENDAR_STATES.includes(value)) return value;
2337
+ function calendarState(value2) {
2338
+ if (typeof value2 !== "string") return null;
2339
+ if (CALENDAR_STATES.includes(value2)) return value2;
2325
2340
  const legacy = {
2326
2341
  disabled: "not_connected",
2327
2342
  disconnected: "disconnected",
@@ -2332,7 +2347,7 @@ function calendarState(value) {
2332
2347
  ready: "healthy",
2333
2348
  error: "failed"
2334
2349
  };
2335
- return legacy[value] ?? null;
2350
+ return legacy[value2] ?? null;
2336
2351
  }
2337
2352
  async function calendarJson(ctx, suffix, init) {
2338
2353
  const platform = platformAudience(ctx.platform);
@@ -2366,50 +2381,50 @@ function wrapped(raw, key) {
2366
2381
  if (!outer) throw new Error("calendar returned an invalid response");
2367
2382
  return record(outer[key]) ?? outer;
2368
2383
  }
2369
- function record(value) {
2370
- return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
2384
+ function record(value2) {
2385
+ return value2 !== null && typeof value2 === "object" && !Array.isArray(value2) ? value2 : null;
2371
2386
  }
2372
- function textField(value, max) {
2373
- return typeof value === "string" && value.length > 0 && value.length <= max && !/[\u0000-\u001f\u007f]/.test(value) ? value : void 0;
2387
+ function textField(value2, max) {
2388
+ return typeof value2 === "string" && value2.length > 0 && value2.length <= max && !/[\u0000-\u001f\u007f]/.test(value2) ? value2 : void 0;
2374
2389
  }
2375
- function stringList(value) {
2376
- return Array.isArray(value) ? [...new Set(value.filter((item) => !!textField(item, 4096)))] : [];
2390
+ function stringList(value2) {
2391
+ return Array.isArray(value2) ? [...new Set(value2.filter((item) => !!textField(item, 4096)))] : [];
2377
2392
  }
2378
- function calendarIds(value) {
2379
- if (!Array.isArray(value)) return [];
2380
- return [...new Set(value.flatMap((item) => {
2393
+ function calendarIds(value2) {
2394
+ if (!Array.isArray(value2)) return [];
2395
+ return [...new Set(value2.flatMap((item) => {
2381
2396
  if (typeof item === "string") return textField(item, 4096) ? [item] : [];
2382
2397
  const calendar = record(item);
2383
2398
  const id = textField(calendar?.id, 4096);
2384
2399
  return id && calendar?.selected !== false ? [id] : [];
2385
2400
  }))];
2386
2401
  }
2387
- function timestamp3(value) {
2388
- if (typeof value === "number" && Number.isFinite(value) && value >= 0) return value;
2389
- if (typeof value === "string") {
2390
- const parsed = Date.parse(value);
2402
+ function timestamp3(value2) {
2403
+ if (typeof value2 === "number" && Number.isFinite(value2) && value2 >= 0) return value2;
2404
+ if (typeof value2 === "string") {
2405
+ const parsed = Date.parse(value2);
2391
2406
  if (Number.isFinite(parsed)) return parsed;
2392
2407
  }
2393
2408
  return void 0;
2394
2409
  }
2395
- function optionalText(key, value, max) {
2396
- const parsed = textField(value, max);
2410
+ function optionalText(key, value2, max) {
2411
+ const parsed = textField(value2, max);
2397
2412
  return parsed ? { [key]: parsed } : {};
2398
2413
  }
2399
- function optionalNullableUrl(key, value) {
2400
- if (value === null) return { [key]: null };
2401
- const parsed = textField(value, 4096);
2414
+ function optionalNullableUrl(key, value2) {
2415
+ if (value2 === null) return { [key]: null };
2416
+ const parsed = textField(value2, 4096);
2402
2417
  return parsed ? { [key]: parsed } : {};
2403
2418
  }
2404
- function identifier(value, name) {
2405
- if (typeof value !== "string" || !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,179}$/.test(value)) throw new Error(`${name} is invalid`);
2406
- return value;
2419
+ function identifier(value2, name) {
2420
+ if (typeof value2 !== "string" || !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,179}$/.test(value2)) throw new Error(`${name} is invalid`);
2421
+ return value2;
2407
2422
  }
2408
- function credential(value) {
2409
- if (typeof value !== "string" || value.length < 8 || value.length > 8192 || /\s|[\u0000-\u001f\u007f]/.test(value)) {
2423
+ function credential(value2) {
2424
+ if (typeof value2 !== "string" || value2.length < 8 || value2.length > 8192 || /\s|[\u0000-\u001f\u007f]/.test(value2)) {
2410
2425
  throw new Error("calendar requires an odla developer token");
2411
2426
  }
2412
- return value;
2427
+ return value2;
2413
2428
  }
2414
2429
 
2415
2430
  // src/calendar-poll.ts
@@ -2570,11 +2585,11 @@ async function connectWithContext(ctx, options) {
2570
2585
  }
2571
2586
  throw new Error('Google Calendar consent timed out; run "odla-ai calendar status" and retry connect');
2572
2587
  }
2573
- function trustedCalendarConsentUrl(platform, value) {
2588
+ function trustedCalendarConsentUrl(platform, value2) {
2574
2589
  const origin = platformAudience(platform);
2575
2590
  let url;
2576
2591
  try {
2577
- url = value.startsWith("/") ? new URL(value, origin) : new URL(value);
2592
+ url = value2.startsWith("/") ? new URL(value2, origin) : new URL(value2);
2578
2593
  } catch {
2579
2594
  throw new Error("odla.ai returned an invalid calendar consent URL");
2580
2595
  }
@@ -2585,9 +2600,9 @@ function trustedCalendarConsentUrl(platform, value) {
2585
2600
  }
2586
2601
  return url.toString();
2587
2602
  }
2588
- function pollTimeout(value = 10 * 6e4) {
2589
- if (!Number.isSafeInteger(value) || value < 1e3 || value > 60 * 6e4) throw new Error("calendar poll timeout must be 1000-3600000ms");
2590
- return value;
2603
+ function pollTimeout(value2 = 10 * 6e4) {
2604
+ if (!Number.isSafeInteger(value2) || value2 < 1e3 || value2 > 60 * 6e4) throw new Error("calendar poll timeout must be 1000-3600000ms");
2605
+ return value2;
2591
2606
  }
2592
2607
  function productionConsent(env, yes, action) {
2593
2608
  if ((env === "prod" || env === "production") && !yes) throw new Error(`refusing to ${action} for "${env}" without --yes`);
@@ -2619,6 +2634,7 @@ var CAPABILITIES = {
2619
2634
  "validate integration contracts offline and smoke-test a provisioned db environment plus anonymous capability routes",
2620
2635
  "save and explicitly select non-secret named operator contexts with isolated credential caches; resolve and explain platform, app, environment, and credential provenance without authenticating; then run PM, Discussions, o11y, runbook, and identity operations outside a project checkout",
2621
2636
  "read one versioned o11y status envelope spanning application RED, exact Worker versions and Cloudflare colos observed in traffic, current live-sync freshness/load, the protected commit-to-visible canary, collector ingest/scheduler trust, provider-owned runtime metrics, account-scoped Durable Object, D1, and R2 evidence under odla-db, and a bounded machine verdict",
2637
+ "read one canonical platform fleet snapshot over private service bindings, including release identities, probe latency, Cloudflare load/runtime freshness, explicit unknowns, and stable next actions through a read-only capability",
2622
2638
  "inspect durable agent wakeups as a versioned JSON envelope and explicitly requeue one dead-lettered job with a scoped environment credential",
2623
2639
  "run app-attributed hosted security discovery and independent validation without provider keys",
2624
2640
  "connect/revoke source-read-only GitHub sources and drive commit-pinned hosted security jobs without PATs or provider keys",
@@ -2802,8 +2818,8 @@ function wranglerWarnings(rootDir) {
2802
2818
  }
2803
2819
  const vars = block.vars;
2804
2820
  if (vars && typeof vars === "object") {
2805
- for (const [name, value] of Object.entries(vars)) {
2806
- if (name === "ODLA_API_KEY" || name === "ODLA_O11Y_TOKEN" || typeof value === "string" && looksSecret(value)) {
2821
+ for (const [name, value2] of Object.entries(vars)) {
2822
+ if (name === "ODLA_API_KEY" || name === "ODLA_O11Y_TOKEN" || typeof value2 === "string" && looksSecret(value2)) {
2807
2823
  warnings.push(`wrangler ${label}vars.${name} looks like a secret \u2014 use "odla-ai secrets push" / wrangler secret put, never vars`);
2808
2824
  }
2809
2825
  }
@@ -2971,27 +2987,27 @@ function isUniqueAttr(schema, ns, attr) {
2971
2987
  const definition = entity.attrs[attr];
2972
2988
  return isRecord6(definition) && definition.unique === true;
2973
2989
  }
2974
- function normalizeSchema(value) {
2975
- if (value === void 0 || value === null) return { entities: {}, links: {} };
2976
- if (!isRecord6(value) || !isRecord6(value.entities)) {
2990
+ function normalizeSchema(value2) {
2991
+ if (value2 === void 0 || value2 === null) return { entities: {}, links: {} };
2992
+ if (!isRecord6(value2) || !isRecord6(value2.entities)) {
2977
2993
  throw new Error("db schema must be a serialized schema object with an entities map");
2978
2994
  }
2979
- if (value.links !== void 0 && !isRecord6(value.links)) throw new Error("db schema links must be an object");
2995
+ if (value2.links !== void 0 && !isRecord6(value2.links)) throw new Error("db schema links must be an object");
2980
2996
  return {
2981
- entities: { ...value.entities },
2982
- links: { ...value.links ?? {} }
2997
+ entities: { ...value2.entities },
2998
+ links: { ...value2.links ?? {} }
2983
2999
  };
2984
3000
  }
2985
3001
  function mergeMap(target, fragment, label) {
2986
- for (const [name, value] of Object.entries(fragment)) {
2987
- if (Object.hasOwn(target, name) && !(0, import_node_util.isDeepStrictEqual)(target[name], value)) {
3002
+ for (const [name, value2] of Object.entries(fragment)) {
3003
+ if (Object.hasOwn(target, name) && !(0, import_node_util.isDeepStrictEqual)(target[name], value2)) {
2988
3004
  throw new Error(`${label} "${name}" conflicts with an existing definition`);
2989
3005
  }
2990
- target[name] = value;
3006
+ target[name] = value2;
2991
3007
  }
2992
3008
  }
2993
- function isRecord6(value) {
2994
- return value !== null && typeof value === "object" && !Array.isArray(value);
3009
+ function isRecord6(value2) {
3010
+ return value2 !== null && typeof value2 === "object" && !Array.isArray(value2);
2995
3011
  }
2996
3012
 
2997
3013
  // src/doctor.ts
@@ -3032,9 +3048,9 @@ async function doctor(options) {
3032
3048
  warnings.push(...integrationWarnings(database.integrations, schema, rules));
3033
3049
  if (cfg.services.includes("ai") && !cfg.ai?.provider) warnings.push("ai service is enabled but ai.provider is not set");
3034
3050
  if (cfg.auth?.clerk) {
3035
- for (const [env, value] of Object.entries(cfg.auth.clerk)) {
3036
- if (typeof value === "string" && value.startsWith("$") && !process.env[value.slice(1)]) {
3037
- warnings.push(`auth.clerk.${env} references unset env var ${value}`);
3051
+ for (const [env, value2] of Object.entries(cfg.auth.clerk)) {
3052
+ if (typeof value2 === "string" && value2.startsWith("$") && !process.env[value2.slice(1)]) {
3053
+ warnings.push(`auth.clerk.${env} references unset env var ${value2}`);
3038
3054
  }
3039
3055
  }
3040
3056
  }
@@ -3076,10 +3092,10 @@ function harnessList(parsed) {
3076
3092
  ];
3077
3093
  return selected.length ? selected : ["all"];
3078
3094
  }
3079
- function harnessOption(value, flag) {
3080
- if (value === void 0) return [];
3081
- if (typeof value === "boolean") throw new Error(`${flag} requires a harness name`);
3082
- const raw = Array.isArray(value) ? value : [value];
3095
+ function harnessOption(value2, flag) {
3096
+ if (value2 === void 0) return [];
3097
+ if (typeof value2 === "boolean") throw new Error(`${flag} requires a harness name`);
3098
+ const raw = Array.isArray(value2) ? value2 : [value2];
3083
3099
  const parts = raw.flatMap((item) => item.split(","));
3084
3100
  if (parts.some((item) => !item.trim())) {
3085
3101
  throw new Error(`${flag} requires a harness name`);
@@ -3090,6 +3106,7 @@ function harnessOption(value, flag) {
3090
3106
  // src/init.ts
3091
3107
  var import_node_fs11 = require("fs");
3092
3108
  var import_node_path9 = require("path");
3109
+ var import_apps3 = require("@odla-ai/apps");
3093
3110
  function initProject(options) {
3094
3111
  const out = options.stdout ?? console;
3095
3112
  const rootDir = (0, import_node_path9.resolve)(options.rootDir ?? process.cwd());
@@ -3102,7 +3119,13 @@ function initProject(options) {
3102
3119
  }
3103
3120
  const envs = options.envs?.length ? options.envs : ["dev"];
3104
3121
  const services = options.services?.length ? options.services : ["db", "ai"];
3105
- if (services.includes("calendar") && !services.includes("db")) throw new Error("--services calendar requires db");
3122
+ for (const service of services) {
3123
+ const definition = (0, import_apps3.appServiceDefinition)(service);
3124
+ if (!definition) throw new Error(`--services contains unknown service "${service}" (known: ${(0, import_apps3.appServiceIds)().join(", ")})`);
3125
+ for (const dependency of definition.requires) {
3126
+ if (!services.includes(dependency)) throw new Error(`--services ${service} requires ${dependency}`);
3127
+ }
3128
+ }
3106
3129
  const aiProvider = options.aiProvider ?? "anthropic";
3107
3130
  (0, import_node_fs11.mkdirSync)((0, import_node_path9.dirname)(configPath), { recursive: true });
3108
3131
  (0, import_node_fs11.mkdirSync)((0, import_node_path9.resolve)(rootDir, "src/odla"), { recursive: true });
@@ -3292,7 +3315,7 @@ function assertWranglerConfig(cfg) {
3292
3315
 
3293
3316
  // src/secrets-set.ts
3294
3317
  var import_ai = require("@odla-ai/ai");
3295
- var import_apps2 = require("@odla-ai/apps");
3318
+ var import_apps4 = require("@odla-ai/apps");
3296
3319
  var PROD_ENV_NAMES2 = /* @__PURE__ */ new Set(["prod", "production"]);
3297
3320
  async function secretsSet(options) {
3298
3321
  const name = (options.name ?? "").trim();
@@ -3300,38 +3323,38 @@ async function secretsSet(options) {
3300
3323
  if (name.startsWith("$")) {
3301
3324
  throw new Error('"$"-prefixed vault names are platform-reserved; for the Clerk secret key use "odla-ai secrets set-clerk-key"');
3302
3325
  }
3303
- const { cfg, tenantId, value, doFetch, out } = await resolveVaultWrite(options);
3326
+ const { cfg, tenantId, value: value2, doFetch, out } = await resolveVaultWrite(options);
3304
3327
  const token = await getDeveloperToken(cfg, options, doFetch, out);
3305
3328
  try {
3306
- await (0, import_ai.putSecret)({ endpoint: cfg.dbEndpoint, token, fetch: doFetch }, tenantId, name, value);
3329
+ await (0, import_ai.putSecret)({ endpoint: cfg.dbEndpoint, token, fetch: doFetch }, tenantId, name, value2);
3307
3330
  } catch (err) {
3308
- throw new Error(scrubValue(err instanceof Error ? err.message : String(err), value));
3331
+ throw new Error(scrubValue(err instanceof Error ? err.message : String(err), value2));
3309
3332
  }
3310
3333
  out.log(`${name} stored in the ${tenantId} vault (write-only; the value was never echoed and cannot be read back here)`);
3311
3334
  }
3312
3335
  async function secretsSetClerkKey(options) {
3313
- const { cfg, tenantId, value, doFetch, out } = await resolveVaultWrite(options);
3314
- if (!value.startsWith("sk_")) throw new Error("the Clerk secret key must start with sk_ (sk_test_\u2026 or sk_live_\u2026)");
3315
- if (value.startsWith("sk_test_") && PROD_ENV_NAMES2.has(options.env)) {
3336
+ const { cfg, tenantId, value: value2, doFetch, out } = await resolveVaultWrite(options);
3337
+ if (!value2.startsWith("sk_")) throw new Error("the Clerk secret key must start with sk_ (sk_test_\u2026 or sk_live_\u2026)");
3338
+ if (value2.startsWith("sk_test_") && PROD_ENV_NAMES2.has(options.env)) {
3316
3339
  throw new Error(`refusing to store an sk_test_ Clerk key for "${options.env}" \u2014 use the production instance's sk_live_ key`);
3317
3340
  }
3318
- if (value.startsWith("sk_live_") && !PROD_ENV_NAMES2.has(options.env) && !options.yes) {
3341
+ if (value2.startsWith("sk_live_") && !PROD_ENV_NAMES2.has(options.env) && !options.yes) {
3319
3342
  throw new Error(`refusing to store an sk_live_ Clerk key for "${options.env}" without --yes (live users would sync into a non-prod tenant)`);
3320
3343
  }
3321
3344
  const token = await getDeveloperToken(cfg, options, doFetch, out);
3322
3345
  const res = await doFetch(`${cfg.dbEndpoint}/admin/apps/${encodeURIComponent(tenantId)}/clerk-secret`, {
3323
3346
  method: "POST",
3324
3347
  headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
3325
- body: JSON.stringify({ value })
3348
+ body: JSON.stringify({ value: value2 })
3326
3349
  });
3327
3350
  if (!res.ok) {
3328
- const text = scrubValue((await res.text().catch(() => "")).slice(0, 300), value);
3351
+ const text = scrubValue((await res.text().catch(() => "")).slice(0, 300), value2);
3329
3352
  throw new Error(`store Clerk secret key failed (${res.status}): ${text || "request failed"}`);
3330
3353
  }
3331
3354
  out.log(`Clerk secret key stored for ${tenantId} ($clerk_secret, reserved + write-only; the value was never echoed)`);
3332
3355
  }
3333
- function scrubValue(text, value) {
3334
- return redactSecrets(text).split(value).join("[value redacted]");
3356
+ function scrubValue(text, value2) {
3357
+ return redactSecrets(text).split(value2).join("[value redacted]");
3335
3358
  }
3336
3359
  async function resolveVaultWrite(options) {
3337
3360
  const out = options.stdout ?? console;
@@ -3343,8 +3366,8 @@ async function resolveVaultWrite(options) {
3343
3366
  if (PROD_ENV_NAMES2.has(options.env) && !options.yes) {
3344
3367
  throw new Error(`refusing to store a secret for "${options.env}" without --yes`);
3345
3368
  }
3346
- const value = await secretInputValue(options, "secret");
3347
- return { cfg, tenantId: (0, import_apps2.tenantIdFor)(cfg.app.id, options.env), value, doFetch, out };
3369
+ const value2 = await secretInputValue(options, "secret");
3370
+ return { cfg, tenantId: (0, import_apps4.tenantIdFor)(cfg.app.id, options.env), value: value2, doFetch, out };
3348
3371
  }
3349
3372
 
3350
3373
  // src/skill.ts
@@ -3874,24 +3897,24 @@ var CONTROL = /[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/;
3874
3897
  var HarnessProtocolError = class extends Error {
3875
3898
  name = "HarnessProtocolError";
3876
3899
  };
3877
- function record2(value) {
3878
- return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
3900
+ function record2(value2) {
3901
+ return value2 !== null && typeof value2 === "object" && !Array.isArray(value2) ? value2 : null;
3879
3902
  }
3880
- function boundedText(value, label, max) {
3881
- if (typeof value !== "string" || !value || value.length > max || CONTROL.test(value)) {
3903
+ function boundedText(value2, label, max) {
3904
+ if (typeof value2 !== "string" || !value2 || value2.length > max || CONTROL.test(value2)) {
3882
3905
  throw new HarnessProtocolError(`${label} must be a non-empty string of at most ${max} characters`);
3883
3906
  }
3884
- return value;
3907
+ return value2;
3885
3908
  }
3886
3909
  function parseAgentOutput(line) {
3887
3910
  if (Buffer.byteLength(line, "utf8") > 1e6) throw new HarnessProtocolError("agent message exceeds 1 MB");
3888
- let value;
3911
+ let value2;
3889
3912
  try {
3890
- value = JSON.parse(line);
3913
+ value2 = JSON.parse(line);
3891
3914
  } catch {
3892
3915
  throw new HarnessProtocolError("agent emitted invalid JSON");
3893
3916
  }
3894
- const message2 = record2(value);
3917
+ const message2 = record2(value2);
3895
3918
  if (!message2 || message2.protocolVersion !== HARNESS_PROTOCOL_VERSION) {
3896
3919
  throw new HarnessProtocolError(`agent protocolVersion must be ${HARNESS_PROTOCOL_VERSION}`);
3897
3920
  }
@@ -4200,7 +4223,7 @@ async function gitOutput(cwd, args, maxBytes) {
4200
4223
  else stdout.push(chunk);
4201
4224
  });
4202
4225
  child.stderr.on("data", (chunk) => {
4203
- if (stderr.reduce((sum, value) => sum + value.byteLength, 0) < 16384) stderr.push(chunk);
4226
+ if (stderr.reduce((sum, value2) => sum + value2.byteLength, 0) < 16384) stderr.push(chunk);
4204
4227
  });
4205
4228
  const code = await new Promise((accept, reject) => {
4206
4229
  child.once("error", reject);
@@ -4221,7 +4244,7 @@ async function gitBlobs(cwd, entries, maxBytes) {
4221
4244
  else stdout.push(chunk);
4222
4245
  });
4223
4246
  child.stderr.on("data", (chunk) => {
4224
- if (stderr.reduce((sum, value) => sum + value.byteLength, 0) < 16384) stderr.push(chunk);
4247
+ if (stderr.reduce((sum, value2) => sum + value2.byteLength, 0) < 16384) stderr.push(chunk);
4225
4248
  });
4226
4249
  child.stdin.end(`${entries.map((entry) => entry.hash).join("\n")}
4227
4250
  `);
@@ -4259,8 +4282,8 @@ async function materializeGitTree(source, commitSha, options = {}) {
4259
4282
  const maxFiles = options.maxFiles ?? 2e4;
4260
4283
  const maxBytes = options.maxBytes ?? 512 * 1024 * 1024;
4261
4284
  const inventory = (await gitOutput(sourceDir, ["ls-tree", "-rz", commitSha], 16 * 1024 * 1024)).toString("utf8").split("\0").filter(Boolean);
4262
- const entries = inventory.flatMap((record7) => {
4263
- const match = /^(100644|100755) blob ([0-9a-f]{40,64})\t([\s\S]+)$/.exec(record7);
4285
+ const entries = inventory.flatMap((record8) => {
4286
+ const match = /^(100644|100755) blob ([0-9a-f]{40,64})\t([\s\S]+)$/.exec(record8);
4264
4287
  return match && allowedWorkspacePath(match[3]) ? [{ mode: match[1], hash: match[2], path: match[3] }] : [];
4265
4288
  });
4266
4289
  if (entries.length > maxFiles) throw new Error(`workspace exceeds ${maxFiles} files`);
@@ -4335,7 +4358,7 @@ async function gitSourceFiles(sourceDir, maxFiles, maxBytes) {
4335
4358
  else stdout.push(chunk);
4336
4359
  });
4337
4360
  child.stderr.on("data", (chunk) => {
4338
- if (stderr.reduce((sum, value) => sum + value.byteLength, 0) < 16384) stderr.push(chunk);
4361
+ if (stderr.reduce((sum, value2) => sum + value2.byteLength, 0) < 16384) stderr.push(chunk);
4339
4362
  });
4340
4363
  const code = await new Promise((accept, reject) => {
4341
4364
  child.once("error", reject);
@@ -4395,7 +4418,7 @@ async function captureGitDiff(root, maxBytes) {
4395
4418
  else stdout.push(chunk);
4396
4419
  });
4397
4420
  child.stderr.on("data", (chunk) => {
4398
- if (stderr.reduce((sum, value) => sum + value.byteLength, 0) < 16384) stderr.push(chunk);
4421
+ if (stderr.reduce((sum, value2) => sum + value2.byteLength, 0) < 16384) stderr.push(chunk);
4399
4422
  });
4400
4423
  const code = await new Promise((accept, reject) => {
4401
4424
  child.once("error", reject);
@@ -4482,34 +4505,34 @@ var CamelError = class extends Error {
4482
4505
  };
4483
4506
 
4484
4507
  // ../camel/dist/chunk-L5DYU2E2.js
4485
- function canonicalJson(value) {
4486
- return JSON.stringify(normalize(value));
4508
+ function canonicalJson(value2) {
4509
+ return JSON.stringify(normalize(value2));
4487
4510
  }
4488
- async function sha256Hex(value) {
4489
- const bytes = typeof value === "string" ? new TextEncoder().encode(value) : value;
4511
+ async function sha256Hex(value2) {
4512
+ const bytes = typeof value2 === "string" ? new TextEncoder().encode(value2) : value2;
4490
4513
  const digest = await crypto.subtle.digest("SHA-256", Uint8Array.from(bytes).buffer);
4491
4514
  return [...new Uint8Array(digest)].map((byte) => byte.toString(16).padStart(2, "0")).join("");
4492
4515
  }
4493
- function utf8Length(value) {
4494
- if (typeof value === "string") return new TextEncoder().encode(value).byteLength;
4495
- if (value instanceof Uint8Array) return value.byteLength;
4516
+ function utf8Length(value2) {
4517
+ if (typeof value2 === "string") return new TextEncoder().encode(value2).byteLength;
4518
+ if (value2 instanceof Uint8Array) return value2.byteLength;
4496
4519
  try {
4497
- return new TextEncoder().encode(canonicalJson(value)).byteLength;
4520
+ return new TextEncoder().encode(canonicalJson(value2)).byteLength;
4498
4521
  } catch {
4499
4522
  throw new CamelError("conversion_rejected", "Unsafe input could not be canonically measured.");
4500
4523
  }
4501
4524
  }
4502
- function normalize(value) {
4503
- if (value === null || typeof value === "string" || typeof value === "boolean") return value;
4504
- if (typeof value === "number") {
4505
- if (!Number.isFinite(value)) throw new CamelError("state_conflict", "Canonical JSON rejects non-finite numbers.");
4506
- return value;
4525
+ function normalize(value2) {
4526
+ if (value2 === null || typeof value2 === "string" || typeof value2 === "boolean") return value2;
4527
+ if (typeof value2 === "number") {
4528
+ if (!Number.isFinite(value2)) throw new CamelError("state_conflict", "Canonical JSON rejects non-finite numbers.");
4529
+ return value2;
4507
4530
  }
4508
- if (Array.isArray(value)) return value.map(normalize);
4509
- if (value instanceof Uint8Array) return { $bytes: [...value] };
4510
- if (typeof value === "object") {
4511
- const record7 = value;
4512
- return Object.fromEntries(Object.keys(record7).filter((key) => record7[key] !== void 0).sort().map((key) => [key, normalize(record7[key])]));
4531
+ if (Array.isArray(value2)) return value2.map(normalize);
4532
+ if (value2 instanceof Uint8Array) return { $bytes: [...value2] };
4533
+ if (typeof value2 === "object") {
4534
+ const record8 = value2;
4535
+ return Object.fromEntries(Object.keys(record8).filter((key) => record8[key] !== void 0).sort().map((key) => [key, normalize(record8[key])]));
4513
4536
  }
4514
4537
  throw new CamelError("state_conflict", "Canonical JSON rejects unsupported values.");
4515
4538
  }
@@ -4518,10 +4541,10 @@ function canRead(readers, readerId) {
4518
4541
  }
4519
4542
  function dependenciesOf(values, influence = "data") {
4520
4543
  const result = [];
4521
- for (const value of values) {
4522
- result.push(...value.label.dependencies);
4523
- for (const ref of value.label.provenance) {
4524
- result.push({ ref, influence, promptSafetyAtUse: value.label.promptSafety });
4544
+ for (const value2 of values) {
4545
+ result.push(...value2.label.dependencies);
4546
+ for (const ref of value2.label.provenance) {
4547
+ result.push({ ref, influence, promptSafetyAtUse: value2.label.promptSafety });
4525
4548
  }
4526
4549
  }
4527
4550
  const unique3 = /* @__PURE__ */ new Map();
@@ -4532,32 +4555,32 @@ function dependenciesOf(values, influence = "data") {
4532
4555
  // ../camel/dist/chunk-S7EVNA2U.js
4533
4556
  var camelValueBrand = /* @__PURE__ */ Symbol("@odla-ai/camel/value");
4534
4557
  var authenticCamelValues = /* @__PURE__ */ new WeakSet();
4535
- function isCamelValue(value) {
4536
- return typeof value === "object" && value !== null && authenticCamelValues.has(value);
4558
+ function isCamelValue(value2) {
4559
+ return typeof value2 === "object" && value2 !== null && authenticCamelValues.has(value2);
4537
4560
  }
4538
- function isSafe(value) {
4539
- return isCamelValue(value) && value.label.promptSafety === "safe";
4561
+ function isSafe(value2) {
4562
+ return isCamelValue(value2) && value2.label.promptSafety === "safe";
4540
4563
  }
4541
- function isUnsafe(value) {
4542
- return isCamelValue(value) && value.label.promptSafety === "unsafe";
4564
+ function isUnsafe(value2) {
4565
+ return isCamelValue(value2) && value2.label.promptSafety === "unsafe";
4543
4566
  }
4544
- function createSafeInternal(value, safeBasis, metadata2) {
4545
- return createValue(value, {
4567
+ function createSafeInternal(value2, safeBasis, metadata2) {
4568
+ return createValue(value2, {
4546
4569
  schemaVersion: 1,
4547
4570
  promptSafety: "safe",
4548
4571
  safeBasis,
4549
4572
  ...copyMetadata(metadata2)
4550
4573
  });
4551
4574
  }
4552
- function createUnsafeInternal(value, metadata2) {
4553
- return createValue(value, {
4575
+ function createUnsafeInternal(value2, metadata2) {
4576
+ return createValue(value2, {
4554
4577
  schemaVersion: 1,
4555
4578
  promptSafety: "unsafe",
4556
4579
  ...copyMetadata(metadata2)
4557
4580
  });
4558
4581
  }
4559
- function createValue(value, label) {
4560
- const result = { value, label: Object.freeze(label) };
4582
+ function createValue(value2, label) {
4583
+ const result = { value: value2, label: Object.freeze(label) };
4561
4584
  Object.defineProperty(result, camelValueBrand, { value: label.promptSafety, enumerable: false });
4562
4585
  authenticCamelValues.add(result);
4563
4586
  return Object.freeze(result);
@@ -4663,8 +4686,8 @@ async function createCodePortableCheckpoint(input) {
4663
4686
  const checkpointDigest = `sha256:${await sha256Hex(canonicalJson(fields))}`;
4664
4687
  return freeze({ ...fields, patch: input.patch, checkpointDigest });
4665
4688
  }
4666
- async function verifyCodePortableCheckpoint(value) {
4667
- const input = object(value, "checkpoint");
4689
+ async function verifyCodePortableCheckpoint(value2) {
4690
+ const input = object(value2, "checkpoint");
4668
4691
  exact2(input, ["schemaVersion", "baseCommitSha", "patch", "patchDigest", "state", "stateDigest", "checkpointDigest"]);
4669
4692
  if (input.schemaVersion !== 1 || typeof input.baseCommitSha !== "string" || typeof input.patch !== "string" || typeof input.patchDigest !== "string" || typeof input.stateDigest !== "string" || typeof input.checkpointDigest !== "string") {
4670
4693
  throw invalid2("Portable checkpoint fields are malformed.");
@@ -4679,8 +4702,8 @@ async function verifyCodePortableCheckpoint(value) {
4679
4702
  }
4680
4703
  return created;
4681
4704
  }
4682
- function normalizeState(value) {
4683
- const state2 = object(value, "state");
4705
+ function normalizeState(value2) {
4706
+ const state2 = object(value2, "state");
4684
4707
  exact2(state2, [
4685
4708
  "planCursor",
4686
4709
  "conversationRefs",
@@ -4738,30 +4761,30 @@ function validateBaseAndPatch(baseCommitSha, patch2) {
4738
4761
  throw invalid2("Portable checkpoint base or patch is malformed or outside its bounds.");
4739
4762
  }
4740
4763
  }
4741
- function strings(value, name, pattern, maximum, sort) {
4742
- if (!Array.isArray(value) || value.length > maximum || value.some((item) => typeof item !== "string" || !pattern.test(item)) || new Set(value).size !== value.length) {
4764
+ function strings(value2, name, pattern, maximum, sort) {
4765
+ if (!Array.isArray(value2) || value2.length > maximum || value2.some((item) => typeof item !== "string" || !pattern.test(item)) || new Set(value2).size !== value2.length) {
4743
4766
  throw invalid2(`Portable checkpoint ${name} is malformed or outside its bounds.`);
4744
4767
  }
4745
- const result = [...value];
4768
+ const result = [...value2];
4746
4769
  return sort ? result.sort() : result;
4747
4770
  }
4748
- function object(value, name) {
4749
- if (!value || typeof value !== "object" || Array.isArray(value)) throw invalid2(`Portable ${name} must be an object.`);
4750
- return value;
4771
+ function object(value2, name) {
4772
+ if (!value2 || typeof value2 !== "object" || Array.isArray(value2)) throw invalid2(`Portable ${name} must be an object.`);
4773
+ return value2;
4751
4774
  }
4752
- function exact2(value, keys) {
4753
- if (Object.keys(value).some((key) => !keys.includes(key)) || keys.some((key) => !(key in value))) {
4775
+ function exact2(value2, keys) {
4776
+ if (Object.keys(value2).some((key) => !keys.includes(key)) || keys.some((key) => !(key in value2))) {
4754
4777
  throw invalid2("Portable checkpoint contains missing or unsupported fields.");
4755
4778
  }
4756
4779
  }
4757
- function freeze(value) {
4780
+ function freeze(value2) {
4758
4781
  return Object.freeze({
4759
- ...value,
4782
+ ...value2,
4760
4783
  state: Object.freeze({
4761
- ...value.state,
4762
- conversationRefs: Object.freeze([...value.state.conversationRefs]),
4763
- completedEffects: Object.freeze(value.state.completedEffects.map((item) => Object.freeze({ ...item }))),
4764
- unresolvedApprovals: Object.freeze([...value.state.unresolvedApprovals])
4784
+ ...value2.state,
4785
+ conversationRefs: Object.freeze([...value2.state.conversationRefs]),
4786
+ completedEffects: Object.freeze(value2.state.completedEffects.map((item) => Object.freeze({ ...item }))),
4787
+ unresolvedApprovals: Object.freeze([...value2.state.unresolvedApprovals])
4765
4788
  })
4766
4789
  });
4767
4790
  }
@@ -4852,61 +4875,61 @@ async function createConversionRegistry(config) {
4852
4875
  if (utf8Length(source.value) > policy.maximumSourceBytes) throw new CamelError("limit_exceeded", "Unsafe conversion input exceeds its byte bound.");
4853
4876
  return policy;
4854
4877
  };
4855
- const emit3 = (source, policy, value) => convert(source, policy, value, outputCounts);
4878
+ const emit3 = (source, policy, value2) => convert(source, policy, value2, outputCounts);
4856
4879
  const operations = Object.freeze({
4857
- boolean: async (value, id) => {
4858
- const policy = checked(value, id, "boolean");
4859
- return emit3(value, policy, requireBoolean(value.value));
4880
+ boolean: async (value2, id) => {
4881
+ const policy = checked(value2, id, "boolean");
4882
+ return emit3(value2, policy, requireBoolean(value2.value));
4860
4883
  },
4861
- integer: async (value, id) => {
4862
- const policy = checked(value, id, "integer");
4863
- return emit3(value, policy, boundedInteger(value.value, policy.output));
4884
+ integer: async (value2, id) => {
4885
+ const policy = checked(value2, id, "integer");
4886
+ return emit3(value2, policy, boundedInteger(value2.value, policy.output));
4864
4887
  },
4865
- finiteNumber: async (value, id) => {
4866
- const policy = checked(value, id, "finite_number");
4867
- return emit3(value, policy, boundedNumber(value.value, policy.output));
4888
+ finiteNumber: async (value2, id) => {
4889
+ const policy = checked(value2, id, "finite_number");
4890
+ return emit3(value2, policy, boundedNumber(value2.value, policy.output));
4868
4891
  },
4869
- enum: async (value, id) => {
4870
- const policy = checked(value, id, "enum");
4871
- return emit3(value, policy, enumMember(value.value, policy.output));
4892
+ enum: async (value2, id) => {
4893
+ const policy = checked(value2, id, "enum");
4894
+ return emit3(value2, policy, enumMember(value2.value, policy.output));
4872
4895
  },
4873
- date: async (value, id) => {
4874
- const policy = checked(value, id, "date");
4875
- return emit3(value, policy, canonicalDate(value.value, policy.output));
4896
+ date: async (value2, id) => {
4897
+ const policy = checked(value2, id, "date");
4898
+ return emit3(value2, policy, canonicalDate(value2.value, policy.output));
4876
4899
  },
4877
- registeredId: async (value, id) => {
4878
- const policy = checked(value, id, "registered_id");
4900
+ registeredId: async (value2, id) => {
4901
+ const policy = checked(value2, id, "registered_id");
4879
4902
  const registry = config.registeredIds?.[policy.output.registryId];
4880
- const output = typeof value.value === "string" ? registry?.values[value.value] : void 0;
4903
+ const output = typeof value2.value === "string" ? registry?.values[value2.value] : void 0;
4881
4904
  if (!output) throw new CamelError("conversion_rejected", "Registered-ID conversion rejected the candidate.");
4882
- return emit3(value, policy, output);
4905
+ return emit3(value2, policy, output);
4883
4906
  },
4884
- digest: async (value, id) => {
4885
- const policy = checked(value, id, "digest");
4886
- if (!(value.value instanceof Uint8Array)) throw new CamelError("conversion_rejected", "Digest conversion requires bytes.");
4887
- return emit3(value, policy, await sha256Hex(value.value));
4907
+ digest: async (value2, id) => {
4908
+ const policy = checked(value2, id, "digest");
4909
+ if (!(value2.value instanceof Uint8Array)) throw new CamelError("conversion_rejected", "Digest conversion requires bytes.");
4910
+ return emit3(value2, policy, await sha256Hex(value2.value));
4888
4911
  },
4889
- measure: async (value, metric, id) => {
4890
- const policy = checked(value, id, "integer");
4891
- const measured = measure(value.value, metric);
4892
- return emit3(value, policy, boundedInteger(measured, policy.output));
4912
+ measure: async (value2, metric, id) => {
4913
+ const policy = checked(value2, id, "integer");
4914
+ const measured = measure(value2.value, metric);
4915
+ return emit3(value2, policy, boundedInteger(measured, policy.output));
4893
4916
  },
4894
- test: async (value, predicateId, id) => {
4895
- const policy = checked(value, id, "boolean");
4917
+ test: async (value2, predicateId, id) => {
4918
+ const policy = checked(value2, id, "boolean");
4896
4919
  const predicate = config.predicates?.[predicateId];
4897
4920
  if (!predicate) throw new CamelError("conversion_rejected", "Predicate is not registered.");
4898
- return emit3(value, policy, evaluatePredicate(value.value, predicate, config.registeredIds));
4921
+ return emit3(value2, policy, evaluatePredicate(value2.value, predicate, config.registeredIds));
4899
4922
  }
4900
4923
  });
4901
4924
  return Object.freeze({ operations, policy: (id) => policies.get(id) ?? missingPolicy() });
4902
4925
  }
4903
- async function convert(source, policy, value, counts) {
4926
+ async function convert(source, policy, value2, counts) {
4904
4927
  const sourceKey = sourceIdentity(source);
4905
4928
  const countKey = `${policy.conversionId}\0${sourceKey}`;
4906
4929
  const count = counts.get(countKey) ?? 0;
4907
4930
  if (count >= policy.maximumOutputsPerArtifact) throw new CamelError("limit_exceeded", "Conversion output count exceeds its per-source bound.");
4908
4931
  counts.set(countKey, count + 1);
4909
- return createSafeInternal(value, "atomic_conversion", {
4932
+ return createSafeInternal(value2, "atomic_conversion", {
4910
4933
  readers: source.label.readers,
4911
4934
  provenance: [...source.label.provenance, { kind: "converter", id: policy.conversionId, digest: policy.digest }],
4912
4935
  dependencies: dependenciesOf([source])
@@ -4918,49 +4941,49 @@ function validatePolicyShape(policy) {
4918
4941
  const output = policy.output;
4919
4942
  if ((output.kind === "integer" || output.kind === "finite_number") && (!Number.isFinite(output.minimum) || !Number.isFinite(output.maximum) || output.minimum > output.maximum)) throw new CamelError("state_conflict", "Numeric conversion bounds are invalid.");
4920
4943
  if (output.kind === "finite_number" && (!Number.isSafeInteger(output.maximumDecimalPlaces) || output.maximumDecimalPlaces < 0 || output.maximumDecimalPlaces > 15)) throw new CamelError("state_conflict", "Decimal-place bound is invalid.");
4921
- if (output.kind === "enum" && (output.values.length === 0 || output.values.some((value) => typeof value !== "string" || !value) || new Set(output.values).size !== output.values.length)) throw new CamelError("state_conflict", "Enum conversion members must be unique and non-empty.");
4944
+ if (output.kind === "enum" && (output.values.length === 0 || output.values.some((value2) => typeof value2 !== "string" || !value2) || new Set(output.values).size !== output.values.length)) throw new CamelError("state_conflict", "Enum conversion members must be unique and non-empty.");
4922
4945
  if (output.kind === "registered_id" && (!output.registryId || !output.registryDigest)) throw new CamelError("state_conflict", "Registered-ID conversion identity is invalid.");
4923
4946
  if (output.kind === "date" && output.format !== "date" && output.format !== "rfc3339") throw new CamelError("state_conflict", "Date conversion format is invalid.");
4924
4947
  if (output.kind === "digest" && output.algorithm !== "sha256") throw new CamelError("state_conflict", "Digest conversion algorithm is invalid.");
4925
4948
  }
4926
- function requireBoolean(value) {
4927
- if (typeof value !== "boolean") throw new CamelError("conversion_rejected", "Boolean conversion requires a structured boolean.");
4928
- return value;
4949
+ function requireBoolean(value2) {
4950
+ if (typeof value2 !== "boolean") throw new CamelError("conversion_rejected", "Boolean conversion requires a structured boolean.");
4951
+ return value2;
4929
4952
  }
4930
- function boundedInteger(value, spec) {
4931
- if (spec.kind !== "integer" || typeof value !== "number" || !Number.isSafeInteger(value) || value < spec.minimum || value > spec.maximum) throw new CamelError("conversion_rejected", "Integer conversion rejected the structured value.");
4932
- return value;
4953
+ function boundedInteger(value2, spec) {
4954
+ if (spec.kind !== "integer" || typeof value2 !== "number" || !Number.isSafeInteger(value2) || value2 < spec.minimum || value2 > spec.maximum) throw new CamelError("conversion_rejected", "Integer conversion rejected the structured value.");
4955
+ return value2;
4933
4956
  }
4934
- function boundedNumber(value, spec) {
4935
- if (spec.kind !== "finite_number" || typeof value !== "number" || !Number.isFinite(value) || value < spec.minimum || value > spec.maximum) throw new CamelError("conversion_rejected", "Finite-number conversion rejected the structured value.");
4936
- const text = String(value);
4957
+ function boundedNumber(value2, spec) {
4958
+ if (spec.kind !== "finite_number" || typeof value2 !== "number" || !Number.isFinite(value2) || value2 < spec.minimum || value2 > spec.maximum) throw new CamelError("conversion_rejected", "Finite-number conversion rejected the structured value.");
4959
+ const text = String(value2);
4937
4960
  if (/e/i.test(text) || (text.split(".")[1]?.length ?? 0) > spec.maximumDecimalPlaces) throw new CamelError("conversion_rejected", "Finite-number conversion rejected a non-canonical decimal.");
4938
- return value;
4961
+ return value2;
4939
4962
  }
4940
- function enumMember(value, spec) {
4941
- if (spec.kind !== "enum" || typeof value !== "string") throw new CamelError("conversion_rejected", "Enum conversion requires a structured string member.");
4942
- const member = spec.caseSensitive ? spec.values.find((item) => item === value) : spec.values.find((item) => item.toLocaleLowerCase("en-US") === value.toLocaleLowerCase("en-US"));
4963
+ function enumMember(value2, spec) {
4964
+ if (spec.kind !== "enum" || typeof value2 !== "string") throw new CamelError("conversion_rejected", "Enum conversion requires a structured string member.");
4965
+ const member = spec.caseSensitive ? spec.values.find((item) => item === value2) : spec.values.find((item) => item.toLocaleLowerCase("en-US") === value2.toLocaleLowerCase("en-US"));
4943
4966
  if (member === void 0) throw new CamelError("conversion_rejected", "Enum conversion rejected a non-member.");
4944
4967
  return member;
4945
4968
  }
4946
- function canonicalDate(value, spec) {
4947
- if (spec.kind !== "date" || typeof value !== "string") throw new CamelError("conversion_rejected", "Date conversion requires a canonical structured string.");
4969
+ function canonicalDate(value2, spec) {
4970
+ if (spec.kind !== "date" || typeof value2 !== "string") throw new CamelError("conversion_rejected", "Date conversion requires a canonical structured string.");
4948
4971
  const pattern = spec.format === "date" ? /^\d{4}-\d{2}-\d{2}$/ : /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?(?:Z|[+-]\d{2}:\d{2})$/;
4949
- const instant = Date.parse(spec.format === "date" ? `${value}T00:00:00Z` : value);
4950
- if (!pattern.test(value) || !Number.isFinite(instant) || spec.format === "date" && new Date(instant).toISOString().slice(0, 10) !== value) throw new CamelError("conversion_rejected", "Date conversion rejected a non-canonical value.");
4951
- if (spec.earliest && value < spec.earliest || spec.latest && value > spec.latest) throw new CamelError("conversion_rejected", "Date conversion rejected an out-of-range value.");
4952
- return value;
4953
- }
4954
- function measure(value, metric) {
4955
- if (metric === "byte_length" && (typeof value === "string" || value instanceof Uint8Array)) return utf8Length(value);
4956
- if (metric === "codepoint_length" && typeof value === "string") return [...value].length;
4957
- if (metric === "item_count" && Array.isArray(value)) return value.length;
4972
+ const instant = Date.parse(spec.format === "date" ? `${value2}T00:00:00Z` : value2);
4973
+ if (!pattern.test(value2) || !Number.isFinite(instant) || spec.format === "date" && new Date(instant).toISOString().slice(0, 10) !== value2) throw new CamelError("conversion_rejected", "Date conversion rejected a non-canonical value.");
4974
+ if (spec.earliest && value2 < spec.earliest || spec.latest && value2 > spec.latest) throw new CamelError("conversion_rejected", "Date conversion rejected an out-of-range value.");
4975
+ return value2;
4976
+ }
4977
+ function measure(value2, metric) {
4978
+ if (metric === "byte_length" && (typeof value2 === "string" || value2 instanceof Uint8Array)) return utf8Length(value2);
4979
+ if (metric === "codepoint_length" && typeof value2 === "string") return [...value2].length;
4980
+ if (metric === "item_count" && Array.isArray(value2)) return value2.length;
4958
4981
  throw new CamelError("conversion_rejected", "Measurement input does not match the registered metric.");
4959
4982
  }
4960
- function evaluatePredicate(value, predicate, registries) {
4961
- if (predicate.kind === "has_fields") return typeof value === "object" && value !== null && !Array.isArray(value) && predicate.fields.every((field) => Object.hasOwn(value, field));
4962
- if (predicate.kind === "registered_id") return typeof value === "string" && registries?.[predicate.registryId]?.values[value] !== void 0;
4963
- const actual = value === null ? "null" : Array.isArray(value) ? "array" : typeof value;
4983
+ function evaluatePredicate(value2, predicate, registries) {
4984
+ if (predicate.kind === "has_fields") return typeof value2 === "object" && value2 !== null && !Array.isArray(value2) && predicate.fields.every((field) => Object.hasOwn(value2, field));
4985
+ if (predicate.kind === "registered_id") return typeof value2 === "string" && registries?.[predicate.registryId]?.values[value2] !== void 0;
4986
+ const actual = value2 === null ? "null" : Array.isArray(value2) ? "array" : typeof value2;
4964
4987
  return actual === predicate.valueType;
4965
4988
  }
4966
4989
  function sourceIdentity(source) {
@@ -4983,17 +5006,17 @@ function createCamelIngress(constants2 = []) {
4983
5006
  byId.set(item.id, item);
4984
5007
  }
4985
5008
  const ingress = {
4986
- userInstruction: (value, input) => createSafeInternal(value, "user_instruction", metadata("user_instruction", input.id, input.readers)),
4987
- systemPolicy: (value, input) => createSafeInternal(value, "system_policy", metadata("system_policy", input.id, input.readers)),
5009
+ userInstruction: (value2, input) => createSafeInternal(value2, "user_instruction", metadata("user_instruction", input.id, input.readers)),
5010
+ systemPolicy: (value2, input) => createSafeInternal(value2, "system_policy", metadata("system_policy", input.id, input.readers)),
4988
5011
  control: (id) => {
4989
5012
  const item = byId.get(id);
4990
5013
  if (!item) throw new CamelError("permission_denied", "Unknown control constant.");
4991
5014
  return createSafeInternal(item.value, "harness_constant", metadata("harness", id, item.readers));
4992
5015
  },
4993
- external: (value, label) => createUnsafeInternal(value, label),
4994
- quarantinedOutput: (value, input) => {
5016
+ external: (value2, label) => createUnsafeInternal(value2, label),
5017
+ quarantinedOutput: (value2, input) => {
4995
5018
  if (!input.runId) throw new CamelError("state_conflict", "Quarantined run IDs must be non-empty.");
4996
- return createUnsafeInternal(value, {
5019
+ return createUnsafeInternal(value2, {
4997
5020
  readers: input.readers,
4998
5021
  dependencies: input.dependencies,
4999
5022
  provenance: [{ kind: "quarantined_llm", id: input.runId, digest: input.digest }]
@@ -5002,15 +5025,15 @@ function createCamelIngress(constants2 = []) {
5002
5025
  };
5003
5026
  return Object.freeze(ingress);
5004
5027
  }
5005
- function assertNoUnsafeConstant(value, seen = /* @__PURE__ */ new WeakSet()) {
5006
- if (typeof value !== "object" || value === null || seen.has(value)) return;
5007
- seen.add(value);
5008
- if (isCamelValue(value)) {
5009
- if (isUnsafe(value)) throw new CamelError("unsafe_privileged_flow", "Control constants cannot contain Prompt-Unsafe values.");
5010
- assertNoUnsafeConstant(value.value, seen);
5028
+ function assertNoUnsafeConstant(value2, seen = /* @__PURE__ */ new WeakSet()) {
5029
+ if (typeof value2 !== "object" || value2 === null || seen.has(value2)) return;
5030
+ seen.add(value2);
5031
+ if (isCamelValue(value2)) {
5032
+ if (isUnsafe(value2)) throw new CamelError("unsafe_privileged_flow", "Control constants cannot contain Prompt-Unsafe values.");
5033
+ assertNoUnsafeConstant(value2.value, seen);
5011
5034
  return;
5012
5035
  }
5013
- for (const child of Object.values(value)) assertNoUnsafeConstant(child, seen);
5036
+ for (const child of Object.values(value2)) assertNoUnsafeConstant(child, seen);
5014
5037
  }
5015
5038
  function metadata(kind, id, readers) {
5016
5039
  if (!id) throw new CamelError("state_conflict", "Provenance IDs must be non-empty.");
@@ -5041,7 +5064,7 @@ async function evaluate(input, registries, approvals) {
5041
5064
  if (invalid3) return deny(invalid3);
5042
5065
  if (arg.role === "selector" && !isSafe(arg.value)) confined.add(arg.value);
5043
5066
  }
5044
- if (input.controlDependencies.some((value) => !isSafe(value) && !confined.has(value))) return deny("unsafe_control_dependency");
5067
+ if (input.controlDependencies.some((value2) => !isSafe(value2) && !confined.has(value2))) return deny("unsafe_control_dependency");
5045
5068
  if (confined.size > 0) {
5046
5069
  const fixed = input.tool.unsafeSelectorPolicy?.fixedProviderIds ?? [];
5047
5070
  const destinations = Object.values(input.args).filter((arg) => arg.role === "destination");
@@ -5068,29 +5091,29 @@ async function validateArgument(path, arg, tool, registries) {
5068
5091
  if (!isSafe(arg.value)) return "unsafe_destination_argument";
5069
5092
  if (!isControlOwned(arg.value)) return "destination_not_control_owned";
5070
5093
  const registry = registries[arg.registryId];
5071
- const validValues = registry && registry.values.length > 0 && registry.values.every((value) => typeof value === "string" && value.length > 0) && new Set(registry.values).size === registry.values.length;
5094
+ const validValues = registry && registry.values.length > 0 && registry.values.every((value2) => typeof value2 === "string" && value2.length > 0) && new Set(registry.values).size === registry.values.length;
5072
5095
  if (!registry || !validValues || registry.digest !== arg.registryDigest || await destinationRegistryDigest(registry.values) !== registry.digest || !registry.values.includes(arg.value.value)) return "destination_not_registered";
5073
5096
  }
5074
5097
  if (arg.role === "selector" && !isSafe(arg.value)) return validateUnsafeSelector(path, arg.value, tool);
5075
5098
  return void 0;
5076
5099
  }
5077
- function isControlOwned(value) {
5078
- return value.label.safeBasis === "system_policy" || value.label.safeBasis === "harness_constant";
5100
+ function isControlOwned(value2) {
5101
+ return value2.label.safeBasis === "system_policy" || value2.label.safeBasis === "harness_constant";
5079
5102
  }
5080
5103
  function copyRegistries(registries) {
5081
5104
  return Object.freeze(Object.fromEntries(Object.entries(registries).map(([id, registry]) => [id, Object.freeze({ digest: registry.digest, values: Object.freeze([...registry.values]) })])));
5082
5105
  }
5083
- function validateUnsafeSelector(path, value, tool) {
5106
+ function validateUnsafeSelector(path, value2, tool) {
5084
5107
  const policy = tool.unsafeSelectorPolicy;
5085
5108
  if (!policy || policy.effect !== tool.effect || !policy.selectorPaths.includes(path)) return "unsafe_selector_not_confined";
5086
5109
  if (!policy.fixedDestination || !policy.unsafeOutput || policy.fixedProviderIds.length === 0) return "unsafe_selector_not_confined";
5087
5110
  if (![policy.maximumCalls, policy.maximumResultsPerCall, policy.maximumOutputBytes, policy.maximumSelectorBytes].every((bound) => Number.isSafeInteger(bound) && bound > 0)) return "unsafe_selector_not_confined";
5088
- if (utf8Length(value.value) > policy.maximumSelectorBytes) return "unsafe_selector_too_large";
5089
- if (typeof value.value === "string" && looksLikeDestination(value.value)) return "unsafe_selector_is_destination";
5111
+ if (utf8Length(value2.value) > policy.maximumSelectorBytes) return "unsafe_selector_too_large";
5112
+ if (typeof value2.value === "string" && looksLikeDestination(value2.value)) return "unsafe_selector_is_destination";
5090
5113
  return void 0;
5091
5114
  }
5092
- function looksLikeDestination(value) {
5093
- const text = value.trim();
5115
+ function looksLikeDestination(value2) {
5116
+ const text = value2.trim();
5094
5117
  return /^(?:[a-z][a-z0-9+.-]*:\/\/|\/|\\\\)/i.test(text) || /^[\w.-]+\.[a-z]{2,}(?:[/:]|$)/i.test(text);
5095
5118
  }
5096
5119
 
@@ -5176,9 +5199,9 @@ var CodeRuntimeReconciler = class {
5176
5199
  }
5177
5200
  }
5178
5201
  };
5179
- function retryableControlFailure(value) {
5180
- if (!value || typeof value !== "object") return false;
5181
- const failure = value;
5202
+ function retryableControlFailure(value2) {
5203
+ if (!value2 || typeof value2 !== "object") return false;
5204
+ const failure = value2;
5182
5205
  if (failure.code === "invalid_response" || typeof failure.status !== "number") return false;
5183
5206
  return failure.status === 408 || failure.status === 425 || failure.status === 429 || failure.status >= 500;
5184
5207
  }
@@ -5230,16 +5253,16 @@ function createCodeRuntimeControlClient(options) {
5230
5253
  if (options.signal?.aborted) throw cause;
5231
5254
  throw new CodeRuntimeControlError("Code runtime control plane is unavailable", 503, "transport_unavailable");
5232
5255
  }
5233
- const value = await response2.json().catch(() => null);
5256
+ const value2 = await response2.json().catch(() => null);
5234
5257
  if (!response2.ok) {
5235
- const problem = record3(record3(value)?.error);
5258
+ const problem = record3(record3(value2)?.error);
5236
5259
  throw new CodeRuntimeControlError(
5237
5260
  typeof problem?.message === "string" ? problem.message : `Code runtime request failed (${response2.status})`,
5238
5261
  response2.status,
5239
5262
  typeof problem?.code === "string" ? problem.code : void 0
5240
5263
  );
5241
5264
  }
5242
- return value;
5265
+ return value2;
5243
5266
  };
5244
5267
  return {
5245
5268
  heartbeat: async (version, capabilities) => {
@@ -5254,15 +5277,15 @@ function createCodeRuntimeControlClient(options) {
5254
5277
  await call2(`/registry/code/runtime/sessions/${validSessionId(sessionId)}/source`, {})
5255
5278
  ),
5256
5279
  infer: async (sessionId, inference) => {
5257
- const value = record3(await call2(
5280
+ const value2 = record3(await call2(
5258
5281
  `/registry/code/runtime/sessions/${validSessionId(sessionId)}/inference`,
5259
5282
  inference,
5260
5283
  modelRequestTimeoutMs
5261
5284
  ));
5262
- if (!value || value.requestId !== inference.requestId || !record3(value.response) || !record3(value.receipt)) {
5285
+ if (!value2 || value2.requestId !== inference.requestId || !record3(value2.response) || !record3(value2.receipt)) {
5263
5286
  throw new CodeRuntimeControlError("invalid Code inference response", 502, "invalid_response");
5264
5287
  }
5265
- return value;
5288
+ return value2;
5266
5289
  },
5267
5290
  review: async (sessionId, review) => parseReview(
5268
5291
  await call2(`/registry/code/runtime/sessions/${validSessionId(sessionId)}/review`, review, modelRequestTimeoutMs)
@@ -5287,8 +5310,8 @@ function createCodeRuntimeControlClient(options) {
5287
5310
  }
5288
5311
  };
5289
5312
  }
5290
- function validatedEndpoint(value) {
5291
- const endpoint = value.replace(/\/+$/, "");
5313
+ function validatedEndpoint(value2) {
5314
+ const endpoint = value2.replace(/\/+$/, "");
5292
5315
  let url;
5293
5316
  try {
5294
5317
  url = new URL(endpoint);
@@ -5301,9 +5324,9 @@ function validatedEndpoint(value) {
5301
5324
  }
5302
5325
  return endpoint;
5303
5326
  }
5304
- function validSessionId(value) {
5305
- if (!/^csess_[0-9a-f]{32}$/.test(value)) throw new TypeError("invalid Code session id");
5306
- return value;
5327
+ function validSessionId(value2) {
5328
+ if (!/^csess_[0-9a-f]{32}$/.test(value2)) throw new TypeError("invalid Code session id");
5329
+ return value2;
5307
5330
  }
5308
5331
  function validateHeartbeat(version, capabilities) {
5309
5332
  if (!version.trim() || version.length > 80) throw new TypeError("runtimeVersion is required and at most 80 characters");
@@ -5316,8 +5339,8 @@ function validateHeartbeat(version, capabilities) {
5316
5339
  throw new TypeError("runtime resources must be positive integers");
5317
5340
  }
5318
5341
  }
5319
- function parseSnapshot(value) {
5320
- const root = record3(value);
5342
+ function parseSnapshot(value2) {
5343
+ const root = record3(value2);
5321
5344
  const host = record3(root?.host);
5322
5345
  if (!host || typeof host.hostId !== "string" || typeof host.runtimeVersion !== "string" || !Number.isSafeInteger(host.lastSeenAt) || host.revokedAt !== null || !Array.isArray(root?.bindings) || root.bindings.length > 1024 || !Array.isArray(root?.commands) || root.commands.length > 64) throw invalid("heartbeat");
5323
5346
  const bindingIds = /* @__PURE__ */ new Set();
@@ -5342,11 +5365,11 @@ function parseSnapshot(value) {
5342
5365
  });
5343
5366
  return { host, bindings, commands };
5344
5367
  }
5345
- async function parseSource(value) {
5346
- const snapshot = record3(record3(value)?.snapshot);
5368
+ async function parseSource(value2) {
5369
+ const snapshot = record3(record3(value2)?.snapshot);
5347
5370
  if (!snapshot || typeof snapshot.repository !== "string" || typeof snapshot.commitSha !== "string" || typeof snapshot.treeDigest !== "string" || !Array.isArray(snapshot.files)) throw invalid("source");
5348
- const files = snapshot.files.map((value2) => {
5349
- const file = record3(value2);
5371
+ const files = snapshot.files.map((value22) => {
5372
+ const file = record3(value22);
5350
5373
  if (!file || typeof file.path !== "string" || typeof file.content !== "string") throw invalid("source file");
5351
5374
  return { path: file.path, content: file.content };
5352
5375
  });
@@ -5373,19 +5396,19 @@ async function parseSource(value) {
5373
5396
  if (digest !== snapshot.treeDigest) throw invalid("source digest");
5374
5397
  return { ...source, treeDigest: digest, ...references.length ? { references } : {} };
5375
5398
  }
5376
- function parseReview(value) {
5377
- const review = record3(record3(value)?.review);
5399
+ function parseReview(value2) {
5400
+ const review = record3(record3(value2)?.review);
5378
5401
  if (!review || !["approved", "rejected"].includes(String(review.verdict)) || typeof review.reviewDigest !== "string" || !/^sha256:[0-9a-f]{64}$/.test(review.reviewDigest) || typeof review.provider !== "string" || !review.provider || typeof review.model !== "string" || !review.model || !Number.isSafeInteger(review.policyVersion) || Number(review.policyVersion) < 1) throw invalid("review");
5379
5402
  return review;
5380
5403
  }
5381
- function parseCandidate(value) {
5382
- const candidate = record3(record3(value)?.candidate);
5404
+ function parseCandidate(value2) {
5405
+ const candidate = record3(record3(value2)?.candidate);
5383
5406
  if (!candidate || typeof candidate.candidateId !== "string" || !/^ccand_[0-9a-f]{32}$/.test(candidate.candidateId) || !["submitted", "approved", "published", "failed"].includes(String(candidate.status))) {
5384
5407
  throw invalid("candidate");
5385
5408
  }
5386
5409
  return { candidateId: candidate.candidateId, status: candidate.status };
5387
5410
  }
5388
- var record3 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
5411
+ var record3 = (value2) => value2 && typeof value2 === "object" && !Array.isArray(value2) ? value2 : null;
5389
5412
  var invalid = (part) => new CodeRuntimeControlError(`invalid Code runtime ${part} response`, 502, "invalid_response");
5390
5413
  var RESERVED = /* @__PURE__ */ new Set([".git", ".odla", ".wrangler", "node_modules", "dist", "coverage"]);
5391
5414
  var SECRET = /^(?:\.env(?:\..+)?|\.dev\.vars|credentials(?:\..+)?\.json|dev-token(?:\..+)?\.json)$/i;
@@ -5419,8 +5442,8 @@ function validateCodePatch(patch2, maxBytes) {
5419
5442
  if (!paths.length || new Set(paths).size !== paths.length) throw new TypeError("patch has no diffs or repeats a path");
5420
5443
  return paths;
5421
5444
  }
5422
- function validHeaderPath(value, path, prefix) {
5423
- return value === "/dev/null" || value === `${prefix}/${path}`;
5445
+ function validHeaderPath(value2, path, prefix) {
5446
+ return value2 === "/dev/null" || value2 === `${prefix}/${path}`;
5424
5447
  }
5425
5448
  function validateRelativePath(path) {
5426
5449
  const parts = path.split("/");
@@ -5566,8 +5589,8 @@ function assertCodeBuildRecipe(recipe2) {
5566
5589
  throw new TypeError("build recipe is malformed or exceeds its control bounds");
5567
5590
  }
5568
5591
  }
5569
- function parseMemory(value) {
5570
- const match = /^([1-9][0-9]{0,4})([kmg])$/.exec(value.toLowerCase());
5592
+ function parseMemory(value2) {
5593
+ const match = /^([1-9][0-9]{0,4})([kmg])$/.exec(value2.toLowerCase());
5571
5594
  if (!match?.[1] || !match[2]) return 0;
5572
5595
  const scale = match[2] === "k" ? 1024 : match[2] === "m" ? 1024 ** 2 : 1024 ** 3;
5573
5596
  return Number(match[1]) * scale;
@@ -5802,14 +5825,14 @@ function normalizedRecipe(recipe2) {
5802
5825
  expectedArtifacts: [...recipe2.expectedArtifacts ?? []].sort((left, right) => left.id.localeCompare(right.id)).map((artifact) => ({ id: artifact.id, path: artifact.path, maximumBytes: artifact.maximumBytes }))
5803
5826
  };
5804
5827
  }
5805
- function digestJson(value) {
5806
- return digestBytes(JSON.stringify(value));
5828
+ function digestJson(value2) {
5829
+ return digestBytes(JSON.stringify(value2));
5807
5830
  }
5808
- function digestBytes(value) {
5809
- return `sha256:${(0, import_crypto3.createHash)("sha256").update(value).digest("hex")}`;
5831
+ function digestBytes(value2) {
5832
+ return `sha256:${(0, import_crypto3.createHash)("sha256").update(value2).digest("hex")}`;
5810
5833
  }
5811
- function integer(value, minimum, maximum) {
5812
- return Number.isSafeInteger(value) && value >= minimum && value <= maximum;
5834
+ function integer(value2, minimum, maximum) {
5835
+ return Number.isSafeInteger(value2) && value2 >= minimum && value2 <= maximum;
5813
5836
  }
5814
5837
  async function prepareRuntimeCheckpoint(input) {
5815
5838
  const patch2 = await input.workspace.patch(256 * 1024);
@@ -5862,7 +5885,7 @@ async function prepareRuntimeCheckpoint(input) {
5862
5885
  });
5863
5886
  return { checkpoint, verification, review, note };
5864
5887
  }
5865
- var message = (value) => (value instanceof Error ? value.message : String(value)).slice(0, 500);
5888
+ var message = (value2) => (value2 instanceof Error ? value2.message : String(value2)).slice(0, 500);
5866
5889
  var CodeRuntimeCheckpointManager = class {
5867
5890
  constructor(options) {
5868
5891
  this.options = options;
@@ -6056,7 +6079,7 @@ async function conversionPolicy(id, output) {
6056
6079
  return { ...definition, digest: await conversionPolicyDigest(definition) };
6057
6080
  }
6058
6081
  async function registeredPolicy(id, registryId, values) {
6059
- const mapping = Object.fromEntries(values.map((value) => [value, value]));
6082
+ const mapping = Object.fromEntries(values.map((value2) => [value2, value2]));
6060
6083
  return conversionPolicy(id, {
6061
6084
  kind: "registered_id",
6062
6085
  registryId,
@@ -6065,7 +6088,7 @@ async function registeredPolicy(id, registryId, values) {
6065
6088
  }
6066
6089
  async function conversionRegistry(policies, values) {
6067
6090
  const registeredIds = Object.fromEntries(await Promise.all(Object.entries(values).map(async ([id, entries]) => {
6068
- const mapping = Object.fromEntries(entries.map((value) => [value, value]));
6091
+ const mapping = Object.fromEntries(entries.map((value2) => [value2, value2]));
6069
6092
  return [id, { values: mapping, digest: await registeredIdRegistryDigest(mapping) }];
6070
6093
  })));
6071
6094
  return createConversionRegistry({ policies, registeredIds });
@@ -6089,8 +6112,8 @@ async function environment(input, options, tool) {
6089
6112
  };
6090
6113
  return { ingress, policy, fixedArgs, reader: ingress.control("reader"), runId: `${input.request.requestId}:${tool}` };
6091
6114
  }
6092
- function unsafe(base, value, field) {
6093
- return base.ingress.quarantinedOutput(value, {
6115
+ function unsafe(base, value2, field) {
6116
+ return base.ingress.quarantinedOutput(value2, {
6094
6117
  readers: base.reader.label.readers,
6095
6118
  runId: `${base.runId}:${field}`
6096
6119
  });
@@ -6170,14 +6193,14 @@ async function read(context, request2, options, policy) {
6170
6193
  }
6171
6194
  async function patch(context, request2, options, policy) {
6172
6195
  exactKeys(request2.input, ["patch"]);
6173
- const value = stringField(request2.input, "patch");
6174
- const paths = validateCodePatch(value, options.maxPatchBytes ?? 256 * 1024);
6196
+ const value2 = stringField(request2.input, "patch");
6197
+ const paths = validateCodePatch(value2, options.maxPatchBytes ?? 256 * 1024);
6175
6198
  if (paths.some((path) => options.readOnlyPrefixes?.some((prefix) => path === prefix || path.startsWith(`${prefix}/`)))) {
6176
6199
  throw new TypeError("patch targets a read-only reference source");
6177
6200
  }
6178
- const allowed = await policy.patch(policyContext(context, request2, options, { patch: value }));
6201
+ const allowed = await policy.patch(policyContext(context, request2, options, { patch: value2 }));
6179
6202
  if (!allowed) return response(request2, false, "tool denied by CaMeL policy");
6180
- await applyCodePatch(context.workspaceDir, value, paths);
6203
+ await applyCodePatch(context.workspaceDir, value2, paths);
6181
6204
  return response(request2, true, `Applied patch to ${paths.length} file(s).`, { paths });
6182
6205
  }
6183
6206
  async function recipe(context, request2, options, recipes, policy) {
@@ -6268,14 +6291,14 @@ function exactKeys(input, allowed) {
6268
6291
  if (Object.keys(input).some((key) => !allowed.includes(key))) throw new TypeError("tool input contains an unsupported field");
6269
6292
  }
6270
6293
  function stringField(input, name) {
6271
- const value = input[name];
6272
- if (typeof value !== "string" || !value) throw new TypeError(`${name} must be a non-empty string`);
6273
- return value;
6294
+ const value2 = input[name];
6295
+ if (typeof value2 !== "string" || !value2) throw new TypeError(`${name} must be a non-empty string`);
6296
+ return value2;
6274
6297
  }
6275
- function optionalInteger(value) {
6276
- if (value === void 0) return void 0;
6277
- if (!Number.isSafeInteger(value) || value < 1) throw new TypeError("line bounds must be positive integers");
6278
- return value;
6298
+ function optionalInteger(value2) {
6299
+ if (value2 === void 0) return void 0;
6300
+ if (!Number.isSafeInteger(value2) || value2 < 1) throw new TypeError("line bounds must be positive integers");
6301
+ return value2;
6279
6302
  }
6280
6303
  function response(request2, ok, content2, details) {
6281
6304
  return { requestId: request2.requestId, ok, content: content2, ...details ? { details } : {} };
@@ -6321,9 +6344,9 @@ function codeLocalSource(payload) {
6321
6344
  return source;
6322
6345
  }
6323
6346
  function codeCheckpointPayload(payload) {
6324
- const value = payload.checkpoint;
6325
- if (!value || typeof value !== "object" || Array.isArray(value)) throw new TypeError("resume checkpoint is missing");
6326
- return value;
6347
+ const value2 = payload.checkpoint;
6348
+ if (!value2 || typeof value2 !== "object" || Array.isArray(value2)) throw new TypeError("resume checkpoint is missing");
6349
+ return value2;
6327
6350
  }
6328
6351
  function fakeCodeLease(command, metadata2) {
6329
6352
  return {
@@ -6347,7 +6370,7 @@ function fakeCodeLease(command, metadata2) {
6347
6370
  }
6348
6371
  };
6349
6372
  }
6350
- var record22 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
6373
+ var record22 = (value2) => value2 && typeof value2 === "object" && !Array.isArray(value2) ? value2 : null;
6351
6374
  var SOURCE_LIMITS = { maxFiles: 2e4, maxBytes: 512 * 1024 * 1024 };
6352
6375
  async function prepareRuntimeLocalSource(input) {
6353
6376
  const { command, descriptor: descriptor2, available, repository, baseCommitSha, resume } = input;
@@ -6437,24 +6460,24 @@ async function appendCodeRuntimeEvent(control, command, event, refs) {
6437
6460
  const bounded = event.type === "message" ? { ...event, body: event.body.trim().slice(0, 2e4) || `${event.actor} event` } : event;
6438
6461
  await control.appendSessionEvent(command.sessionId, eventId, bounded);
6439
6462
  }
6440
- var digestRuntimeValue = (value) => `sha256:${(0, import_crypto4.createHash)("sha256").update(value).digest("hex")}`;
6441
- var runtimeErrorMessage = (value) => value instanceof Error ? value.message : String(value);
6442
- var runtimeRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
6443
- var safeRuntimeJson = (value) => {
6463
+ var digestRuntimeValue = (value2) => `sha256:${(0, import_crypto4.createHash)("sha256").update(value2).digest("hex")}`;
6464
+ var runtimeErrorMessage = (value2) => value2 instanceof Error ? value2.message : String(value2);
6465
+ var runtimeRecord = (value2) => value2 && typeof value2 === "object" && !Array.isArray(value2) ? value2 : null;
6466
+ var safeRuntimeJson = (value2) => {
6444
6467
  try {
6445
- return JSON.stringify(value).slice(0, 1e4);
6468
+ return JSON.stringify(value2).slice(0, 1e4);
6446
6469
  } catch {
6447
6470
  return "[event]";
6448
6471
  }
6449
6472
  };
6450
- function runtimeResultText(value) {
6451
- const record32 = runtimeRecord(value);
6473
+ function runtimeResultText(value2) {
6474
+ const record32 = runtimeRecord(value2);
6452
6475
  if (record32 && typeof record32.text === "string") return record32.text.slice(0, 2e4);
6453
6476
  if (record32 && typeof record32.error === "string") return `Pi failed: ${record32.error.slice(0, 19989)}`;
6454
6477
  return null;
6455
6478
  }
6456
- function runtimeResultError(value) {
6457
- const record32 = runtimeRecord(value);
6479
+ function runtimeResultError(value2) {
6480
+ const record32 = runtimeRecord(value2);
6458
6481
  return record32 && typeof record32.error === "string" && record32.error.trim() ? record32.error.trim().slice(0, 2e3) : null;
6459
6482
  }
6460
6483
  var CodePiRuntimeEngine = class {
@@ -6728,14 +6751,14 @@ var CodePiRuntimeEngine = class {
6728
6751
  this.#active.delete(command.sessionId);
6729
6752
  return result;
6730
6753
  }
6731
- async #failure(command, active, value) {
6732
- active.failure = value.slice(0, 2e3);
6754
+ async #failure(command, active, value2) {
6755
+ active.failure = value2.slice(0, 2e3);
6733
6756
  if (active.acknowledged) {
6734
6757
  await this.options.control.reportSessionFailure(command.sessionId, active.failure).catch(() => void 0);
6735
6758
  }
6736
6759
  }
6737
- async #diagnostic(command, active, value) {
6738
- const detail = value.trim().slice(0, 2e3) || "Pi runtime failed";
6760
+ async #diagnostic(command, active, value2) {
6761
+ const detail = value2.trim().slice(0, 2e3) || "Pi runtime failed";
6739
6762
  this.options.onDiagnostic?.(detail);
6740
6763
  await this.#event(
6741
6764
  command,
@@ -6820,6 +6843,7 @@ Usage:
6820
6843
  odla-ai context save <name> [--platform <url>] [--app <id>] [--env <name>] [--json]
6821
6844
  odla-ai context remove <name> --yes [--json]
6822
6845
  odla-ai o11y status [--app <id>] [--context <name>] [--platform https://odla.ai] [--env prod] [--minutes 60] [--json]
6846
+ odla-ai platform status [--context <name>] [--platform https://odla.ai] [--email <odla-account>] [--json]
6823
6847
  odla-ai whoami [--context <name>] [--platform https://odla.ai] [--json]
6824
6848
  odla-ai runbook ask "<question>" [--app <id>] [--all] [--json]
6825
6849
  odla-ai runbook search "<question>" [--app <id>] [--all] [--limit <n>] [--json]
@@ -6944,6 +6968,8 @@ Commands:
6944
6968
  canary, collector ingest/scheduler trust, Cloudflare-owned
6945
6969
  runtime metrics, and a machine verdict.
6946
6970
  --json keeps auth progress on stderr for unattended agents.
6971
+ platform Read canonical fleet health, releases, provider load/freshness,
6972
+ explicit unknowns, and next actions through a read-only grant.
6947
6973
  provision Register services, compose integrations, persist credentials, optionally push secrets.
6948
6974
  smoke Verify credentials, public-config, composed schema, db aggregate, and integration probes.
6949
6975
  skill Same installer; --agent accepts all, claude, codex, cursor,
@@ -7030,31 +7056,31 @@ async function requestHostedSecurityJson(options, path, init, action) {
7030
7056
  }
7031
7057
  return body;
7032
7058
  }
7033
- function hostedIdentifier(value, name) {
7034
- const result = optionalHostedText(value, name, 180);
7059
+ function hostedIdentifier(value2, name) {
7060
+ const result = optionalHostedText(value2, name, 180);
7035
7061
  if (!result || !/^[A-Za-z0-9][A-Za-z0-9._:-]*$/.test(result)) {
7036
7062
  throw new Error(`${name} is invalid`);
7037
7063
  }
7038
7064
  return result;
7039
7065
  }
7040
- function positivePolicyVersion(value, name) {
7041
- if (!Number.isSafeInteger(value) || value < 1) {
7066
+ function positivePolicyVersion(value2, name) {
7067
+ if (!Number.isSafeInteger(value2) || value2 < 1) {
7042
7068
  throw new Error(`${name} is invalid`);
7043
7069
  }
7044
- return value;
7070
+ return value2;
7045
7071
  }
7046
- function optionalHostedText(value, name, maxLength) {
7047
- if (value === void 0 || value === null || value === "") return void 0;
7048
- if (typeof value !== "string" || value.length > maxLength || /[\u0000-\u001f\u007f]/.test(value)) {
7072
+ function optionalHostedText(value2, name, maxLength) {
7073
+ if (value2 === void 0 || value2 === null || value2 === "") return void 0;
7074
+ if (typeof value2 !== "string" || value2.length > maxLength || /[\u0000-\u001f\u007f]/.test(value2)) {
7049
7075
  throw new Error(`${name} is invalid`);
7050
7076
  }
7051
- return value;
7077
+ return value2;
7052
7078
  }
7053
- function githubRepositoryName(value) {
7054
- if (typeof value !== "string" || value.length > 201) {
7079
+ function githubRepositoryName(value2) {
7080
+ if (typeof value2 !== "string" || value2.length > 201) {
7055
7081
  throw new Error("repository must be owner/name");
7056
7082
  }
7057
- const parts = value.split("/");
7083
+ const parts = value2.split("/");
7058
7084
  const owner = parts[0] ?? "";
7059
7085
  const name = (parts[1] ?? "").replace(/\.git$/i, "");
7060
7086
  if (parts.length !== 2 || !/^[A-Za-z0-9](?:[A-Za-z0-9-]{0,98}[A-Za-z0-9])?$/.test(owner) || !/^[A-Za-z0-9_.-]{1,100}$/.test(name) || name === "." || name === "..") {
@@ -7062,10 +7088,10 @@ function githubRepositoryName(value) {
7062
7088
  }
7063
7089
  return `${owner}/${name}`;
7064
7090
  }
7065
- function trustedGitHubInstallUrl(value) {
7091
+ function trustedGitHubInstallUrl(value2) {
7066
7092
  let url;
7067
7093
  try {
7068
- url = new URL(value);
7094
+ url = new URL(value2);
7069
7095
  } catch {
7070
7096
  throw new Error("odla.ai returned an invalid GitHub installation URL");
7071
7097
  }
@@ -7074,17 +7100,17 @@ function trustedGitHubInstallUrl(value) {
7074
7100
  }
7075
7101
  return url.toString();
7076
7102
  }
7077
- function hostedPollInterval(value = 2e3) {
7078
- if (!Number.isSafeInteger(value) || value < 100 || value > 3e4) {
7103
+ function hostedPollInterval(value2 = 2e3) {
7104
+ if (!Number.isSafeInteger(value2) || value2 < 100 || value2 > 3e4) {
7079
7105
  throw new Error("poll interval must be 100-30000ms");
7080
7106
  }
7081
- return value;
7107
+ return value2;
7082
7108
  }
7083
- function hostedPollTimeout(value = 10 * 6e4) {
7084
- if (!Number.isSafeInteger(value) || value < 1e3 || value > 60 * 6e4) {
7109
+ function hostedPollTimeout(value2 = 10 * 6e4) {
7110
+ if (!Number.isSafeInteger(value2) || value2 < 1e3 || value2 > 60 * 6e4) {
7085
7111
  throw new Error("poll timeout must be 1000-3600000ms");
7086
7112
  }
7087
- return value;
7113
+ return value2;
7088
7114
  }
7089
7115
  async function waitForHostedPoll(milliseconds, signal) {
7090
7116
  if (signal?.aborted) throw signal.reason ?? new DOMException("aborted", "AbortError");
@@ -7096,16 +7122,16 @@ async function waitForHostedPoll(milliseconds, signal) {
7096
7122
  }, { once: true });
7097
7123
  });
7098
7124
  }
7099
- function isValidHostedSecurityPlan(value, env) {
7100
- if (!value || value.env !== env || !/^sha256:[a-f0-9]{64}$/.test(value.planDigest) || value.consentContract !== "odla.hosted-security-consent.v1" || value.reportProjection !== "odla.hosted-security-report.v1" || value.redactionContract !== "odla.best-effort-credential-pattern-redaction.v1" || typeof value.promptBundle !== "string" || value.promptBundle.length < 1 || value.promptBundle.length > 100 || typeof value.ready !== "boolean" || typeof value.independent !== "boolean" || value.sourceDisclosure !== "redacted" || value.targetExecution !== false || !Number.isSafeInteger(value.reportRetentionDays) || value.reportRetentionDays < 1) return false;
7125
+ function isValidHostedSecurityPlan(value2, env) {
7126
+ if (!value2 || value2.env !== env || !/^sha256:[a-f0-9]{64}$/.test(value2.planDigest) || value2.consentContract !== "odla.hosted-security-consent.v1" || value2.reportProjection !== "odla.hosted-security-report.v1" || value2.redactionContract !== "odla.best-effort-credential-pattern-redaction.v1" || typeof value2.promptBundle !== "string" || value2.promptBundle.length < 1 || value2.promptBundle.length > 100 || typeof value2.ready !== "boolean" || typeof value2.independent !== "boolean" || value2.sourceDisclosure !== "redacted" || value2.targetExecution !== false || !Number.isSafeInteger(value2.reportRetentionDays) || value2.reportRetentionDays < 1) return false;
7101
7127
  const validRoute = (route2, purpose) => !!route2 && route2.purpose === purpose && typeof route2.enabled === "boolean" && typeof route2.credentialReady === "boolean" && typeof route2.provider === "string" && route2.provider.length > 0 && route2.provider.length <= 100 && typeof route2.model === "string" && route2.model.length > 0 && route2.model.length <= 200 && Number.isSafeInteger(route2.policyVersion) && route2.policyVersion >= 1 && Number.isSafeInteger(route2.maxCallsPerRun) && route2.maxCallsPerRun >= 1 && Number.isSafeInteger(route2.maxInputBytes) && route2.maxInputBytes >= 1 && Number.isSafeInteger(route2.maxOutputTokens) && route2.maxOutputTokens >= 1;
7102
- return validRoute(value.routes?.discovery, "security.discovery") && validRoute(value.routes?.validation, "security.validation");
7128
+ return validRoute(value2.routes?.discovery, "security.discovery") && validRoute(value2.routes?.validation, "security.validation");
7103
7129
  }
7104
- function hostedSecurityCredential(value) {
7105
- if (typeof value !== "string" || value.length < 8 || value.length > 8192 || /\s|[\u0000-\u001f\u007f]/.test(value)) {
7130
+ function hostedSecurityCredential(value2) {
7131
+ if (typeof value2 !== "string" || value2.length < 8 || value2.length > 8192 || /\s|[\u0000-\u001f\u007f]/.test(value2)) {
7106
7132
  throw new Error("Hosted security requires an injected odla developer token");
7107
7133
  }
7108
- return value;
7134
+ return value2;
7109
7135
  }
7110
7136
 
7111
7137
  // src/security-hosted-github.ts
@@ -7258,17 +7284,17 @@ async function prepareCodeLocalSource(cwd, repository, readHead = readGitHead) {
7258
7284
  }
7259
7285
  }
7260
7286
  async function readGitHead(cwd) {
7261
- const value = await new Promise((accept, reject) => {
7287
+ const value2 = await new Promise((accept, reject) => {
7262
7288
  (0, import_node_child_process5.execFile)("git", ["rev-parse", "HEAD"], { cwd, encoding: "utf8", maxBuffer: 16384 }, (error, stdout) => {
7263
7289
  if (error) reject(new Error("code connect requires a Git checkout with an initial commit"));
7264
7290
  else accept(stdout.trim());
7265
7291
  });
7266
7292
  });
7267
- if (!/^[0-9a-f]{40}$/.test(value)) throw new Error("code connect could not resolve the checkout HEAD commit");
7268
- return value;
7293
+ if (!/^[0-9a-f]{40}$/.test(value2)) throw new Error("code connect could not resolve the checkout HEAD commit");
7294
+ return value2;
7269
7295
  }
7270
- function digestText(value) {
7271
- return `sha256:${(0, import_node_crypto.createHash)("sha256").update(value).digest("hex")}`;
7296
+ function digestText(value2) {
7297
+ return `sha256:${(0, import_node_crypto.createHash)("sha256").update(value2).digest("hex")}`;
7272
7298
  }
7273
7299
 
7274
7300
  // src/code-images.ts
@@ -7539,8 +7565,8 @@ async function runCodeRuntime(input) {
7539
7565
  for (const [name, handler] of handlers) process.removeListener(name, handler);
7540
7566
  }
7541
7567
  }
7542
- function parseConnection(value, appId, appEnv) {
7543
- const root = record4(value);
7568
+ function parseConnection(value2, appId, appEnv) {
7569
+ const root = record4(value2);
7544
7570
  const host = record4(root?.host);
7545
7571
  const offer = record4(root?.offer);
7546
7572
  const binding = record4(root?.binding);
@@ -7549,12 +7575,12 @@ function parseConnection(value, appId, appEnv) {
7549
7575
  }
7550
7576
  return root;
7551
7577
  }
7552
- function apiFailure(action, status, value) {
7553
- const message2 = record4(record4(value)?.error)?.message;
7578
+ function apiFailure(action, status, value2) {
7579
+ const message2 = record4(record4(value2)?.error)?.message;
7554
7580
  return `${action} failed (${status})${typeof message2 === "string" ? `: ${message2}` : ""}`;
7555
7581
  }
7556
- function record4(value) {
7557
- return value && typeof value === "object" && !Array.isArray(value) ? value : null;
7582
+ function record4(value2) {
7583
+ return value2 && typeof value2 === "object" && !Array.isArray(value2) ? value2 : null;
7558
7584
  }
7559
7585
 
7560
7586
  // src/code-command.ts
@@ -7613,8 +7639,8 @@ function developerTokenStatus(context, parsed, now = Date.now()) {
7613
7639
  cacheStatus
7614
7640
  };
7615
7641
  }
7616
- function clean3(value) {
7617
- const normalized = value?.trim();
7642
+ function clean3(value2) {
7643
+ const normalized = value2?.trim();
7618
7644
  return normalized || void 0;
7619
7645
  }
7620
7646
 
@@ -7763,8 +7789,8 @@ async function request(ctx, method, path, body) {
7763
7789
  throw new Error(`discuss ${method} ${path} failed: ${data.error ?? `registry returned ${res.status}`}`);
7764
7790
  return data;
7765
7791
  }
7766
- function emit(ctx, value, human) {
7767
- if (ctx.json) ctx.out.log(JSON.stringify(value, null, 2));
7792
+ function emit(ctx, value2, human) {
7793
+ if (ctx.json) ctx.out.log(JSON.stringify(value2, null, 2));
7768
7794
  else human();
7769
7795
  }
7770
7796
  var state = (topic) => topic.resolved ? "resolved" : "open";
@@ -7809,8 +7835,8 @@ async function discussList(ctx, parsed) {
7809
7835
  ["limit", "limit"],
7810
7836
  ["offset", "offset"]
7811
7837
  ]) {
7812
- const value = stringOpt(parsed.options[flag]);
7813
- if (value) query.set(param, value);
7838
+ const value2 = stringOpt(parsed.options[flag]);
7839
+ if (value2) query.set(param, value2);
7814
7840
  }
7815
7841
  const qs = query.toString();
7816
7842
  const page = await request(ctx, "GET", `/topics${qs ? `?${qs}` : ""}`);
@@ -8007,11 +8033,11 @@ var MAX_CONSECUTIVE_FAILURES = 5;
8007
8033
  var MAX_BACKOFF_MS = 3e4;
8008
8034
  function numberOpt2(parsed, flag, fallback) {
8009
8035
  const raw = stringOpt(parsed.options[flag]);
8010
- const value = raw == null ? NaN : Number(raw);
8011
- return Number.isFinite(value) && value > 0 ? value : fallback;
8036
+ const value2 = raw == null ? NaN : Number(raw);
8037
+ return Number.isFinite(value2) && value2 > 0 ? value2 : fallback;
8012
8038
  }
8013
- function jsonl(ctx, parsed, value) {
8014
- if (parsed.options.jsonl === true) ctx.out.log(JSON.stringify({ v: 1, ...value }));
8039
+ function jsonl(ctx, parsed, value2) {
8040
+ if (parsed.options.jsonl === true) ctx.out.log(JSON.stringify({ v: 1, ...value2 }));
8015
8041
  }
8016
8042
  async function discussWatch(ctx, topicId, parsed) {
8017
8043
  if (ctx.json && parsed.options.jsonl === true) throw new Error("--json and --jsonl cannot be combined");
@@ -8273,13 +8299,13 @@ async function pmRequest(ctx, method, path, body) {
8273
8299
  function collectFields(parsed, allowClear) {
8274
8300
  const out = {};
8275
8301
  for (const [flag, spec] of Object.entries(FIELD_MAP)) {
8276
- const value = parsed.options[flag];
8277
- if (value === void 0 || value === true) continue;
8278
- if (value === false) {
8302
+ const value2 = parsed.options[flag];
8303
+ if (value2 === void 0 || value2 === true) continue;
8304
+ if (value2 === false) {
8279
8305
  if (allowClear) out[spec.key] = null;
8280
8306
  continue;
8281
8307
  }
8282
- const text = stringOpt(value);
8308
+ const text = stringOpt(value2);
8283
8309
  out[spec.key] = spec.num ? Number(text) : text;
8284
8310
  }
8285
8311
  return out;
@@ -8300,8 +8326,8 @@ function statusCol(entity, r) {
8300
8326
  function printRecord(ctx, entity, r) {
8301
8327
  ctx.out.log(`${r.id} [${statusCol(entity, r)}] ${r.appId} ${r.title ?? ""}`);
8302
8328
  }
8303
- function emit2(ctx, value, human) {
8304
- if (ctx.json) ctx.out.log(JSON.stringify(value, null, 2));
8329
+ function emit2(ctx, value2, human) {
8330
+ if (ctx.json) ctx.out.log(JSON.stringify(value2, null, 2));
8305
8331
  else human();
8306
8332
  }
8307
8333
  async function pmList(ctx, entity, parsed) {
@@ -8347,8 +8373,8 @@ async function pmAdd(ctx, entity, parsed) {
8347
8373
  emit2(ctx, res, () => ctx.out.log(`created ${entity} ${res.id}`));
8348
8374
  }
8349
8375
  async function pmGet(ctx, entity, id) {
8350
- const { record: record7 } = await pmRequest(ctx, "GET", `/${entity}/${encodeURIComponent(id)}`);
8351
- emit2(ctx, record7, () => printRecord(ctx, entity, record7));
8376
+ const { record: record8 } = await pmRequest(ctx, "GET", `/${entity}/${encodeURIComponent(id)}`);
8377
+ emit2(ctx, record8, () => printRecord(ctx, entity, record8));
8352
8378
  }
8353
8379
  async function pmSet(ctx, entity, id, parsed) {
8354
8380
  const patch2 = collectEntityFields(entity, parsed, true);
@@ -8393,9 +8419,9 @@ async function pmHandoff(ctx, parsed) {
8393
8419
  ]);
8394
8420
  const handoff = {
8395
8421
  appId,
8396
- unmetGoals: goals.filter((record7) => record7.status !== "met"),
8397
- activeTasks: tasks.filter((record7) => record7.column !== "done"),
8398
- openBugs: bugs.filter((record7) => record7.status !== "fixed" && record7.status !== "wontfix")
8422
+ unmetGoals: goals.filter((record8) => record8.status !== "met"),
8423
+ activeTasks: tasks.filter((record8) => record8.column !== "done"),
8424
+ openBugs: bugs.filter((record8) => record8.status !== "fixed" && record8.status !== "wontfix")
8399
8425
  };
8400
8426
  const result = {
8401
8427
  ...handoff,
@@ -8414,10 +8440,10 @@ async function pmHandoff(ctx, parsed) {
8414
8440
  ]) {
8415
8441
  ctx.out.log(`${label}:`);
8416
8442
  if (!records.length) ctx.out.log("- (none)");
8417
- else for (const record7 of records) printRecord(
8443
+ else for (const record8 of records) printRecord(
8418
8444
  ctx,
8419
8445
  label === "unmet goals" ? "goal" : label === "active tasks" ? "task" : "bug",
8420
- record7
8446
+ record8
8421
8447
  );
8422
8448
  }
8423
8449
  });
@@ -8565,6 +8591,113 @@ async function pmCommand(parsed, deps = {}) {
8565
8591
  }
8566
8592
  }
8567
8593
 
8594
+ // src/platform-output.ts
8595
+ function printPlatformStatus(status, out) {
8596
+ out.log(`platform ${status.verdict.status} ${status.observedAt}`);
8597
+ out.log(
8598
+ `fleet ${status.summary.healthy}/${status.summary.services} healthy ${status.summary.required} required ${status.summary.unreachable} unreachable ${status.summary.notConfigured} not configured`
8599
+ );
8600
+ out.log(`catalog ${status.catalog.revision}`);
8601
+ out.log(
8602
+ "service required health probe ms version provider age requests errors cpu p99 us wall p99 us"
8603
+ );
8604
+ for (const service of status.services) {
8605
+ const metrics = service.provider.metrics;
8606
+ out.log([
8607
+ service.id,
8608
+ service.required ? "yes" : "no",
8609
+ service.health.status,
8610
+ value(service.health.latencyMs),
8611
+ service.release.observedVersionId ?? "unknown",
8612
+ service.provider.status,
8613
+ age(service.provider.ageMs),
8614
+ value(metrics?.requests),
8615
+ value(metrics?.errors),
8616
+ value(metrics?.cpuTimeP99),
8617
+ value(metrics?.wallTimeP99)
8618
+ ].join(" "));
8619
+ }
8620
+ if (status.verdict.reasons.length) {
8621
+ out.log(`reasons ${status.verdict.reasons.join(", ")}`);
8622
+ }
8623
+ for (const action of status.nextActions) {
8624
+ out.log(`next ${action.service} ${action.code} ${action.message}`);
8625
+ }
8626
+ }
8627
+ function value(input) {
8628
+ return input === null || input === void 0 ? "unknown" : String(input);
8629
+ }
8630
+ function age(input) {
8631
+ if (input === null) return "unknown";
8632
+ if (input < 1e3) return `${input}ms`;
8633
+ if (input < 6e4) return `${Math.round(input / 1e3)}s`;
8634
+ return `${Math.round(input / 6e4)}m`;
8635
+ }
8636
+
8637
+ // src/platform-command.ts
8638
+ async function platformCommand(parsed, deps = {}) {
8639
+ assertArgs(
8640
+ parsed,
8641
+ ["config", "context", "platform", "token", "email", "open", "json"],
8642
+ 2
8643
+ );
8644
+ const action = parsed.positionals[1];
8645
+ if (action !== "status") {
8646
+ throw new Error(
8647
+ `unknown platform action "${action ?? ""}". Try "odla-ai platform status --json".`
8648
+ );
8649
+ }
8650
+ const context = await resolveOperatorContext(parsed, {
8651
+ allowMissingConfig: true
8652
+ });
8653
+ const platform = context.platform.value;
8654
+ const doFetch = deps.fetch ?? fetch;
8655
+ const out = deps.stdout ?? console;
8656
+ const token = await resolveAdminPlatformToken({
8657
+ platform,
8658
+ scope: "platform:status:read",
8659
+ token: stringOpt(parsed.options.token),
8660
+ tokenFile: context.credentials.scopedTokenFile,
8661
+ email: stringOpt(parsed.options.email),
8662
+ open: parsed.options.open === false ? false : parsed.options.open === true ? true : void 0,
8663
+ fetch: doFetch,
8664
+ stdout: out,
8665
+ openApprovalUrl: deps.openUrl,
8666
+ label: "odla CLI (platform fleet status)"
8667
+ });
8668
+ const response2 = await doFetch(`${platform}/registry/platform/status`, {
8669
+ headers: { authorization: `Bearer ${token}` }
8670
+ });
8671
+ const body = await response2.json().catch(() => null);
8672
+ if (!response2.ok) {
8673
+ throw new Error(
8674
+ `read platform status failed (HTTP ${response2.status}): ${apiMessage(body)}`
8675
+ );
8676
+ }
8677
+ if (!isPlatformStatus(body)) {
8678
+ throw new Error("platform returned an invalid odla.platform-status/v1 envelope");
8679
+ }
8680
+ if (parsed.options.json === true) {
8681
+ out.log(JSON.stringify(body, null, 2));
8682
+ } else {
8683
+ printPlatformStatus(body, out);
8684
+ }
8685
+ }
8686
+ function isPlatformStatus(value2) {
8687
+ if (!record5(value2) || value2.schemaVersion !== "odla.platform-status/v1") return false;
8688
+ if (!record5(value2.verdict) || !Array.isArray(value2.verdict.reasons)) return false;
8689
+ if (!record5(value2.catalog) || !record5(value2.summary)) return false;
8690
+ return Array.isArray(value2.services) && Array.isArray(value2.nextActions);
8691
+ }
8692
+ function apiMessage(value2) {
8693
+ if (!record5(value2)) return "request failed";
8694
+ const error = record5(value2.error) ? value2.error : value2;
8695
+ return typeof error.message === "string" ? error.message : typeof error.code === "string" ? error.code : "request failed";
8696
+ }
8697
+ function record5(value2) {
8698
+ return !!value2 && typeof value2 === "object" && !Array.isArray(value2);
8699
+ }
8700
+
8568
8701
  // src/o11y-verdict.ts
8569
8702
  function statusVerdict(reads) {
8570
8703
  const reasons = [];
@@ -8602,7 +8735,7 @@ function statusVerdict(reads) {
8602
8735
  severity: "degraded"
8603
8736
  });
8604
8737
  }
8605
- const performance = record5(reads.liveSync.body.performance) ? reads.liveSync.body.performance : null;
8738
+ const performance = record6(reads.liveSync.body.performance) ? reads.liveSync.body.performance : null;
8606
8739
  if (performance?.status === "unavailable") {
8607
8740
  reasons.push({
8608
8741
  source: "liveSync",
@@ -8683,11 +8816,11 @@ function statusVerdict(reads) {
8683
8816
  reasons
8684
8817
  };
8685
8818
  }
8686
- function record5(value) {
8687
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
8819
+ function record6(value2) {
8820
+ return Boolean(value2) && typeof value2 === "object" && !Array.isArray(value2);
8688
8821
  }
8689
- function numeric2(value) {
8690
- return typeof value === "number" && Number.isFinite(value) ? value : 0;
8822
+ function numeric2(value2) {
8823
+ return typeof value2 === "number" && Number.isFinite(value2) ? value2 : 0;
8691
8824
  }
8692
8825
  function collectorReason(read3, fallback) {
8693
8826
  const reasons = read3.body.reasons;
@@ -8711,7 +8844,7 @@ function printO11yStatus(status, out) {
8711
8844
  out.log(
8712
8845
  `o11y status ${status.scope.appId}/${status.scope.env} (${status.scope.minutes}m)`
8713
8846
  );
8714
- const routes = Array.isArray(status.application.body.routes) ? status.application.body.routes.filter(record6) : [];
8847
+ const routes = Array.isArray(status.application.body.routes) ? status.application.body.routes.filter(record7) : [];
8715
8848
  const requests = routes.reduce(
8716
8849
  (total, row) => total + numeric3(row.requests),
8717
8850
  0
@@ -8723,39 +8856,39 @@ function printO11yStatus(status, out) {
8723
8856
  out.log(
8724
8857
  `application ${status.application.httpStatus} ${requests} requests ${errors} errors`
8725
8858
  );
8726
- const versions = Array.isArray(status.applicationVersions.body.rows) ? status.applicationVersions.body.rows.filter(record6) : [];
8859
+ const versions = Array.isArray(status.applicationVersions.body.rows) ? status.applicationVersions.body.rows.filter(record7) : [];
8727
8860
  out.log(
8728
8861
  `application-versions ${status.applicationVersions.httpStatus} ${versions.length ? versions.slice(0, 5).map(
8729
8862
  (row) => `${String(row.value || "(unattributed)")}:${numeric3(row.requests)}`
8730
8863
  ).join(", ") : "none observed"}`
8731
8864
  );
8732
8865
  out.log(liveSyncLine(status.liveSync));
8733
- const canaryDurations = record6(status.canary.body.durationsMs) ? status.canary.body.durationsMs : {};
8866
+ const canaryDurations = record7(status.canary.body.durationsMs) ? status.canary.body.durationsMs : {};
8734
8867
  out.log(
8735
8868
  `canary ${status.canary.httpStatus} ${String(status.canary.body.status ?? status.canary.body.error ?? "unavailable")} ${optionalNumeric(canaryDurations.publishToVisibleMs)} publish-to-visible`
8736
8869
  );
8737
- const collectorIngest = record6(status.collector.body.ingest) ? status.collector.body.ingest : {};
8738
- const collectorStorage = record6(collectorIngest.storage) ? collectorIngest.storage : {};
8870
+ const collectorIngest = record7(status.collector.body.ingest) ? status.collector.body.ingest : {};
8871
+ const collectorStorage = record7(collectorIngest.storage) ? collectorIngest.storage : {};
8739
8872
  out.log(
8740
8873
  `collector ${status.collector.httpStatus} ${String(status.collector.body.status ?? status.collector.body.error ?? "unavailable")} ${numeric3(collectorStorage.affectedPoints)} affected points`
8741
8874
  );
8742
- const providerMetrics = record6(status.provider.body.metrics) ? status.provider.body.metrics : {};
8743
- const providerCapacity = record6(status.provider.body.capacity) ? status.provider.body.capacity : {};
8744
- const workerMemory = record6(providerCapacity.memory) ? providerCapacity.memory : {};
8875
+ const providerMetrics = record7(status.provider.body.metrics) ? status.provider.body.metrics : {};
8876
+ const providerCapacity = record7(status.provider.body.capacity) ? status.provider.body.capacity : {};
8877
+ const workerMemory = record7(providerCapacity.memory) ? providerCapacity.memory : {};
8745
8878
  out.log(
8746
8879
  `cloudflare ${status.provider.httpStatus} ${String(status.provider.body.status ?? status.provider.body.error ?? "unavailable")} ${numeric3(providerMetrics.requests)} invocations ${numeric3(providerMetrics.errors)} runtime errors ${optionalBytes(workerMemory.headroomBytes)} isolate memory headroom`
8747
8880
  );
8748
8881
  for (const line of providerCapacityLines(status.providerCapacity)) {
8749
8882
  out.log(line);
8750
8883
  }
8751
- const coverage = record6(status.providerReconciliation.body.comparison) ? status.providerReconciliation.body.comparison : {};
8752
- const coverageCounts = record6(status.providerReconciliation.body.counts) ? status.providerReconciliation.body.counts : {};
8753
- const coverageBudget = record6(status.providerReconciliation.body.budget) ? status.providerReconciliation.body.budget : {};
8884
+ const coverage = record7(status.providerReconciliation.body.comparison) ? status.providerReconciliation.body.comparison : {};
8885
+ const coverageCounts = record7(status.providerReconciliation.body.counts) ? status.providerReconciliation.body.counts : {};
8886
+ const coverageBudget = record7(status.providerReconciliation.body.budget) ? status.providerReconciliation.body.budget : {};
8754
8887
  out.log(
8755
8888
  `request-coverage ${status.providerReconciliation.httpStatus} ${String(status.providerReconciliation.body.status ?? status.providerReconciliation.body.error ?? "unavailable")} ${optionalPercent(coverage.applicationCoverage)} application/provider ${numeric3(coverageCounts.applicationRequests)}/${numeric3(coverageCounts.providerRequests)} requests \xB1${optionalPercent(coverageBudget.maxRelativeError)} budget`
8756
8889
  );
8757
8890
  const providerPoints = Array.isArray(status.providerHistory.body.points) ? status.providerHistory.body.points.length : 0;
8758
- const providerFreshness = record6(status.providerHistory.body.freshness) ? status.providerHistory.body.freshness : {};
8891
+ const providerFreshness = record7(status.providerHistory.body.freshness) ? status.providerHistory.body.freshness : {};
8759
8892
  out.log(
8760
8893
  `cloudflare-history ${status.providerHistory.httpStatus} ${String(status.providerHistory.body.status ?? status.providerHistory.body.error ?? "unavailable")} ${providerPoints} snapshots ${optionalAge(providerFreshness.ageMs)} old`
8761
8894
  );
@@ -8764,17 +8897,17 @@ function printO11yStatus(status, out) {
8764
8897
  );
8765
8898
  }
8766
8899
  function providerCapacityLines(read3) {
8767
- const resources = record6(read3.body.resources) ? read3.body.resources : {};
8768
- const durableObjects = record6(resources.durableObjects) ? resources.durableObjects : {};
8769
- const periodic = record6(durableObjects.periodic) ? durableObjects.periodic : {};
8770
- const storage = record6(durableObjects.sqliteStorage) ? durableObjects.sqliteStorage : {};
8771
- const d1 = record6(resources.d1) ? resources.d1 : {};
8772
- const d1Activity = record6(d1.activity) ? d1.activity : {};
8773
- const d1Storage = record6(d1.storage) ? d1.storage : {};
8774
- const d1Latency = record6(d1Activity.latency) ? d1Activity.latency : {};
8775
- const r2 = record6(resources.r2) ? resources.r2 : {};
8776
- const r2Operations = record6(r2.operations) ? r2.operations : {};
8777
- const r2Storage = record6(r2.storage) ? r2.storage : {};
8900
+ const resources = record7(read3.body.resources) ? read3.body.resources : {};
8901
+ const durableObjects = record7(resources.durableObjects) ? resources.durableObjects : {};
8902
+ const periodic = record7(durableObjects.periodic) ? durableObjects.periodic : {};
8903
+ const storage = record7(durableObjects.sqliteStorage) ? durableObjects.sqliteStorage : {};
8904
+ const d1 = record7(resources.d1) ? resources.d1 : {};
8905
+ const d1Activity = record7(d1.activity) ? d1.activity : {};
8906
+ const d1Storage = record7(d1.storage) ? d1.storage : {};
8907
+ const d1Latency = record7(d1Activity.latency) ? d1Activity.latency : {};
8908
+ const r2 = record7(resources.r2) ? resources.r2 : {};
8909
+ const r2Operations = record7(r2.operations) ? r2.operations : {};
8910
+ const r2Storage = record7(r2.storage) ? r2.storage : {};
8778
8911
  const status = String(
8779
8912
  read3.body.status ?? read3.body.error ?? "unavailable"
8780
8913
  );
@@ -8785,42 +8918,42 @@ function providerCapacityLines(read3) {
8785
8918
  ];
8786
8919
  }
8787
8920
  function liveSyncLine(read3) {
8788
- const performance = record6(read3.body.performance) ? read3.body.performance : {};
8789
- const commitToSend = record6(performance.commitToSend) ? performance.commitToSend : {};
8921
+ const performance = record7(read3.body.performance) ? read3.body.performance : {};
8922
+ const commitToSend = record7(performance.commitToSend) ? performance.commitToSend : {};
8790
8923
  return `live-sync ${read3.httpStatus} ${String(read3.body.status ?? read3.body.error ?? "unavailable")} ${numeric3(read3.body.activeConnections)} active ${optionalNumeric(commitToSend.p95)} commit-to-send p95 ${numeric3(performance.sendFailures)} send failures`;
8791
8924
  }
8792
- function record6(value) {
8793
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
8925
+ function record7(value2) {
8926
+ return Boolean(value2) && typeof value2 === "object" && !Array.isArray(value2);
8794
8927
  }
8795
- function numeric3(value) {
8796
- return typeof value === "number" && Number.isFinite(value) ? value : 0;
8928
+ function numeric3(value2) {
8929
+ return typeof value2 === "number" && Number.isFinite(value2) ? value2 : 0;
8797
8930
  }
8798
- function optionalNumeric(value) {
8799
- return typeof value === "number" && Number.isFinite(value) ? `${value} ms` : "\u2014";
8931
+ function optionalNumeric(value2) {
8932
+ return typeof value2 === "number" && Number.isFinite(value2) ? `${value2} ms` : "\u2014";
8800
8933
  }
8801
- function optionalAge(value) {
8802
- if (typeof value !== "number" || !Number.isFinite(value)) return "unknown";
8803
- return `${Math.max(0, Math.round(value / 1e3))}s`;
8934
+ function optionalAge(value2) {
8935
+ if (typeof value2 !== "number" || !Number.isFinite(value2)) return "unknown";
8936
+ return `${Math.max(0, Math.round(value2 / 1e3))}s`;
8804
8937
  }
8805
- function optionalPercent(value) {
8806
- return typeof value === "number" && Number.isFinite(value) ? `${Math.round(value * 100)}%` : "\u2014";
8938
+ function optionalPercent(value2) {
8939
+ return typeof value2 === "number" && Number.isFinite(value2) ? `${Math.round(value2 * 100)}%` : "\u2014";
8807
8940
  }
8808
- function optionalBytes(value) {
8809
- if (typeof value !== "number" || !Number.isFinite(value)) return "\u2014";
8810
- if (value >= 1024 * 1024 * 1024) {
8811
- return `${(value / (1024 * 1024 * 1024)).toFixed(2)} GiB`;
8941
+ function optionalBytes(value2) {
8942
+ if (typeof value2 !== "number" || !Number.isFinite(value2)) return "\u2014";
8943
+ if (value2 >= 1024 * 1024 * 1024) {
8944
+ return `${(value2 / (1024 * 1024 * 1024)).toFixed(2)} GiB`;
8812
8945
  }
8813
- if (value >= 1024 * 1024) {
8814
- return `${(value / (1024 * 1024)).toFixed(1)} MiB`;
8946
+ if (value2 >= 1024 * 1024) {
8947
+ return `${(value2 / (1024 * 1024)).toFixed(1)} MiB`;
8815
8948
  }
8816
- if (value >= 1024) return `${(value / 1024).toFixed(1)} KiB`;
8817
- return `${Math.round(value)} B`;
8949
+ if (value2 >= 1024) return `${(value2 / 1024).toFixed(1)} KiB`;
8950
+ return `${Math.round(value2)} B`;
8818
8951
  }
8819
- function optionalCount(value, unit) {
8820
- return typeof value === "number" && Number.isFinite(value) ? `${value} ${unit}` : `\u2014 ${unit}`;
8952
+ function optionalCount(value2, unit) {
8953
+ return typeof value2 === "number" && Number.isFinite(value2) ? `${value2} ${unit}` : `\u2014 ${unit}`;
8821
8954
  }
8822
- function optionalAgeSeconds(value) {
8823
- return typeof value === "number" && Number.isFinite(value) ? `${Math.max(0, Math.round(value))}s` : "unknown";
8955
+ function optionalAgeSeconds(value2) {
8956
+ return typeof value2 === "number" && Number.isFinite(value2) ? `${Math.max(0, Math.round(value2))}s` : "unknown";
8824
8957
  }
8825
8958
 
8826
8959
  // src/o11y-command.ts
@@ -8950,11 +9083,11 @@ async function o11yCommand(parsed, deps = {}) {
8950
9083
  }
8951
9084
  printO11yStatus(status, out);
8952
9085
  }
8953
- function statusMinutes(value) {
8954
- if (!Number.isSafeInteger(value) || value < 1 || value > 7 * 24 * 60) {
9086
+ function statusMinutes(value2) {
9087
+ if (!Number.isSafeInteger(value2) || value2 < 1 || value2 > 7 * 24 * 60) {
8955
9088
  throw new Error("--minutes must be an integer from 1 to 10080");
8956
9089
  }
8957
- return value;
9090
+ return value2;
8958
9091
  }
8959
9092
  async function read2(url, headers, doFetch) {
8960
9093
  const response2 = await doFetch(url, { headers });
@@ -8962,8 +9095,8 @@ async function read2(url, headers, doFetch) {
8962
9095
  let body = {};
8963
9096
  if (text) {
8964
9097
  try {
8965
- const value = JSON.parse(text);
8966
- body = value && typeof value === "object" && !Array.isArray(value) ? value : { value };
9098
+ const value2 = JSON.parse(text);
9099
+ body = value2 && typeof value2 === "object" && !Array.isArray(value2) ? value2 : { value: value2 };
8967
9100
  } catch {
8968
9101
  body = { message: text.slice(0, 300) };
8969
9102
  }
@@ -8972,7 +9105,7 @@ async function read2(url, headers, doFetch) {
8972
9105
  }
8973
9106
 
8974
9107
  // src/provision.ts
8975
- var import_apps5 = require("@odla-ai/apps");
9108
+ var import_apps7 = require("@odla-ai/apps");
8976
9109
  var import_ai3 = require("@odla-ai/ai");
8977
9110
  var import_node_process10 = __toESM(require("process"), 1);
8978
9111
 
@@ -9017,8 +9150,8 @@ async function postJson2(doFetch, url, bearer, body) {
9017
9150
  if (!res.ok) throw new Error(`${new URL(url).pathname} failed: ${res.status} ${await responseText(res)}`);
9018
9151
  return res.json().catch(() => ({}));
9019
9152
  }
9020
- function isRecord7(value) {
9021
- return value !== null && typeof value === "object" && !Array.isArray(value);
9153
+ function isRecord7(value2) {
9154
+ return value2 !== null && typeof value2 === "object" && !Array.isArray(value2);
9022
9155
  }
9023
9156
  async function responseText(res) {
9024
9157
  try {
@@ -9029,9 +9162,9 @@ async function responseText(res) {
9029
9162
  }
9030
9163
 
9031
9164
  // src/provision-credentials.ts
9032
- var import_apps3 = require("@odla-ai/apps");
9165
+ var import_apps5 = require("@odla-ai/apps");
9033
9166
  async function provisionEnvCredentials(opts) {
9034
- const tenantId = (0, import_apps3.tenantIdFor)(opts.cfg.app.id, opts.env);
9167
+ const tenantId = (0, import_apps5.tenantIdFor)(opts.cfg.app.id, opts.env);
9035
9168
  const prior = opts.credentials?.envs[opts.env];
9036
9169
  let credentials = opts.credentials;
9037
9170
  let dbKey = opts.cfg.services.includes("db") && !opts.rotateDb ? prior?.dbKey : void 0;
@@ -9125,18 +9258,13 @@ async function safeText4(res) {
9125
9258
 
9126
9259
  // src/provision-helpers.ts
9127
9260
  var import_ai2 = require("@odla-ai/ai");
9128
- var import_apps4 = require("@odla-ai/apps");
9129
- function serviceRank(service) {
9130
- if (service === "db") return 0;
9131
- if (service === "calendar") return 2;
9132
- return 1;
9133
- }
9261
+ var import_apps6 = require("@odla-ai/apps");
9134
9262
  function defaultSecretName(provider) {
9135
9263
  const names = import_ai2.DEFAULT_SECRET_NAMES;
9136
9264
  return names[provider] ?? `${provider}_api_key`;
9137
9265
  }
9138
9266
  async function assertTenantAdminAccess(doFetch, cfg, env, token) {
9139
- const tenantId = (0, import_apps4.tenantIdFor)(cfg.app.id, env);
9267
+ const tenantId = (0, import_apps6.tenantIdFor)(cfg.app.id, env);
9140
9268
  const res = await doFetch(`${cfg.dbEndpoint}/admin/apps/${encodeURIComponent(tenantId)}/entitlements`, {
9141
9269
  headers: { authorization: `Bearer ${token}` }
9142
9270
  });
@@ -9156,14 +9284,14 @@ async function postJson3(doFetch, url, bearer, body) {
9156
9284
  });
9157
9285
  if (!res.ok) throw new Error(`${new URL(url).pathname} failed: ${res.status} ${await safeText5(res)}`);
9158
9286
  }
9159
- function normalizeClerkConfig(value) {
9160
- if (!value) return null;
9161
- if (typeof value === "string") {
9162
- const publishableKey2 = envValue(value);
9287
+ function normalizeClerkConfig(value2) {
9288
+ if (!value2) return null;
9289
+ if (typeof value2 === "string") {
9290
+ const publishableKey2 = envValue(value2);
9163
9291
  return publishableKey2 ? { publishableKey: publishableKey2 } : null;
9164
9292
  }
9165
- if (typeof value !== "object") return null;
9166
- const cfg = value;
9293
+ if (typeof value2 !== "object") return null;
9294
+ const cfg = value2;
9167
9295
  const publishableKey = envValue(cfg.publishableKey);
9168
9296
  return publishableKey ? { publishableKey, ...cfg.audience ? { audience: cfg.audience } : {}, ...cfg.mode ? { mode: cfg.mode } : {} } : null;
9169
9297
  }
@@ -9245,7 +9373,7 @@ async function provision(options) {
9245
9373
  }
9246
9374
  const doFetch = options.fetch ?? fetch;
9247
9375
  const token = await getDeveloperToken(cfg, options, doFetch, out);
9248
- const apps = (0, import_apps5.createAppsClient)({ endpoint: cfg.platformUrl, token, fetcher: { fetch: doFetch } });
9376
+ const apps = (0, import_apps7.createAppsClient)({ endpoint: cfg.platformUrl, token, fetcher: { fetch: doFetch } });
9249
9377
  const existing = await apps.resolveApp(cfg.app.id);
9250
9378
  if (existing) {
9251
9379
  out.log(`app: ${cfg.app.id} already exists`);
@@ -9256,7 +9384,7 @@ async function provision(options) {
9256
9384
  for (const env of cfg.envs) {
9257
9385
  await assertTenantAdminAccess(doFetch, cfg, env, token);
9258
9386
  }
9259
- const serviceOrder = [...cfg.services].sort((a, b) => serviceRank(a) - serviceRank(b));
9387
+ const serviceOrder = (0, import_apps7.orderAppServices)(cfg.services);
9260
9388
  for (const env of cfg.envs) {
9261
9389
  for (const service of serviceOrder) {
9262
9390
  if (service === "ai") {
@@ -9289,7 +9417,7 @@ async function provision(options) {
9289
9417
  }
9290
9418
  }
9291
9419
  for (const env of cfg.envs) {
9292
- const tenantId = (0, import_apps5.tenantIdFor)(cfg.app.id, env);
9420
+ const tenantId = (0, import_apps7.tenantIdFor)(cfg.app.id, env);
9293
9421
  credentials = await provisionEnvCredentials({
9294
9422
  cfg,
9295
9423
  env,
@@ -9440,6 +9568,7 @@ var COMMAND_SURFACE = {
9440
9568
  help: {},
9441
9569
  init: {},
9442
9570
  o11y: { status: {} },
9571
+ platform: { status: {} },
9443
9572
  pm: {
9444
9573
  ...PM_ENTITIES,
9445
9574
  handoff: {}
@@ -9523,7 +9652,7 @@ function recordInvocation(parsed) {
9523
9652
  try {
9524
9653
  const entry = {
9525
9654
  path: invocationPath(parsed.positionals),
9526
- options: Object.entries(parsed.options).map(([name, value]) => value === false ? `no-${name}` : name).sort()
9655
+ options: Object.entries(parsed.options).map(([name, value2]) => value2 === false ? `no-${name}` : name).sort()
9527
9656
  };
9528
9657
  if (!entry.path.length) return;
9529
9658
  (0, import_node_fs15.appendFileSync)(file, `${JSON.stringify(entry)}
@@ -9537,10 +9666,10 @@ var import_node_fs16 = require("fs");
9537
9666
 
9538
9667
  // src/runbook-requires.ts
9539
9668
  var SPEC = /^(@?[\w./-]+?)@(\d+\.\d+\.\d+(?:[\w.-]*)?)$/;
9540
- function parseRequires(value) {
9541
- if (!value) return [];
9669
+ function parseRequires(value2) {
9670
+ if (!value2) return [];
9542
9671
  const out = [];
9543
- for (const token of value.split(/[\s,]+/).filter(Boolean)) {
9672
+ for (const token of value2.split(/[\s,]+/).filter(Boolean)) {
9544
9673
  const match = SPEC.exec(token);
9545
9674
  if (match?.[1] && match[2]) out.push({ name: match[1], min: match[2] });
9546
9675
  }
@@ -9716,9 +9845,9 @@ function parseRunbook(text, slug) {
9716
9845
  for (const line of fm[1].split(/\r?\n/)) {
9717
9846
  const pair = /^(\w+)\s*:\s*(.+)$/.exec(line.trim());
9718
9847
  if (!pair) continue;
9719
- const value = pair[2].trim().replace(/^["']|["']$/g, "");
9720
- if (pair[1] === "summary") meta.summary = value;
9721
- if (pair[1] === "tags") meta.tags = value.replace(/^\[|\]$/g, "").trim();
9848
+ const value2 = pair[2].trim().replace(/^["']|["']$/g, "");
9849
+ if (pair[1] === "summary") meta.summary = value2;
9850
+ if (pair[1] === "tags") meta.tags = value2.replace(/^\[|\]$/g, "").trim();
9722
9851
  }
9723
9852
  }
9724
9853
  const lines = rest.split("\n");
@@ -9835,7 +9964,7 @@ var NOISE = /* @__PURE__ */ new Set([
9835
9964
  "and",
9836
9965
  "for"
9837
9966
  ]);
9838
- var words = (value) => value.replace(/^@[\w-]+\//, "").split(/[^A-Za-z0-9]+/).filter((w) => w.length > 1 && !NOISE.has(w.toLowerCase()));
9967
+ var words = (value2) => value2.replace(/^@[\w-]+\//, "").split(/[^A-Za-z0-9]+/).filter((w) => w.length > 1 && !NOISE.has(w.toLowerCase()));
9839
9968
  function namedExports(clause) {
9840
9969
  return clause.split(",").map((part) => part.trim().split(/\s+as\s+/)[0]?.trim() ?? "").filter((name) => /^[A-Za-z_$][\w$]*$/.test(name) && name !== "type");
9841
9970
  }
@@ -10188,8 +10317,8 @@ var import_node_process12 = __toESM(require("process"), 1);
10188
10317
  var EDITOR_ENV = ["ODLA_EDITOR", "VISUAL", "EDITOR"];
10189
10318
  function resolveEditor(env = import_node_process12.default.env) {
10190
10319
  for (const name of EDITOR_ENV) {
10191
- const value = env[name];
10192
- if (value && value.trim()) return value.trim();
10320
+ const value2 = env[name];
10321
+ if (value2 && value2.trim()) return value2.trim();
10193
10322
  }
10194
10323
  return null;
10195
10324
  }
@@ -10454,9 +10583,9 @@ async function runbookCommand(parsed, deps = {}) {
10454
10583
  });
10455
10584
  }
10456
10585
  case "visibility": {
10457
- const value = parsed.positionals[3] ?? stringOpt(parsed.options.visibility);
10458
- if (!value) throw new Error('"runbook visibility" needs operator|admin, e.g. "runbook visibility release operator"');
10459
- return runbookVisibility(ctx, requireSlug(slug, "visibility"), value);
10586
+ const value2 = parsed.positionals[3] ?? stringOpt(parsed.options.visibility);
10587
+ if (!value2) throw new Error('"runbook visibility" needs operator|admin, e.g. "runbook visibility release operator"');
10588
+ return runbookVisibility(ctx, requireSlug(slug, "visibility"), value2);
10460
10589
  }
10461
10590
  case "publish":
10462
10591
  return runbookStatus(ctx, requireSlug(slug, "publish"), "published");
@@ -10512,13 +10641,13 @@ async function interactiveConfirmation(message2, dependencies) {
10512
10641
  }
10513
10642
  }
10514
10643
  function requiredSecurityPositional(parsed, index, label) {
10515
- const value = parsed.positionals[index];
10516
- if (!value) throw new Error(`${label} is required`);
10517
- return value;
10644
+ const value2 = parsed.positionals[index];
10645
+ if (!value2) throw new Error(`${label} is required`);
10646
+ return value2;
10518
10647
  }
10519
- function securityProfile(value) {
10520
- if (value === void 0) return void 0;
10521
- if (value === "odla" || value === "cloudflare-app" || value === "generic") return value;
10648
+ function securityProfile(value2) {
10649
+ if (value2 === void 0) return void 0;
10650
+ if (value2 === "odla" || value2 === "cloudflare-app" || value2 === "generic") return value2;
10522
10651
  throw new Error("--profile must be odla, cloudflare-app, or generic");
10523
10652
  }
10524
10653
 
@@ -10619,9 +10748,9 @@ function routeLabel(route2) {
10619
10748
  return `${route2.provider}/${route2.model}${route2.policyVersion ? ` policy v${route2.policyVersion}` : ""}`;
10620
10749
  }
10621
10750
  var HOSTED_SEVERITIES = ["informational", "low", "medium", "high", "critical"];
10622
- function hostedSeverity(value, flag) {
10623
- if (HOSTED_SEVERITIES.includes(value)) {
10624
- return value;
10751
+ function hostedSeverity(value2, flag) {
10752
+ if (HOSTED_SEVERITIES.includes(value2)) {
10753
+ return value2;
10625
10754
  }
10626
10755
  throw new Error(`${flag} must be informational, low, medium, high, or critical`);
10627
10756
  }
@@ -10704,13 +10833,13 @@ function selectEnv(requested, declared, configPath, rootDir) {
10704
10833
  return env;
10705
10834
  }
10706
10835
  async function injectedToken(options, request2) {
10707
- const value = options.token ?? await options.getToken?.(Object.freeze({ ...request2 }));
10708
- if (typeof value !== "string" || value.length < 8 || value.length > 8192 || /\s|[\u0000-\u001f\u007f]/.test(value)) {
10836
+ const value2 = options.token ?? await options.getToken?.(Object.freeze({ ...request2 }));
10837
+ if (typeof value2 !== "string" || value2.length < 8 || value2.length > 8192 || /\s|[\u0000-\u001f\u007f]/.test(value2)) {
10709
10838
  throw new Error(
10710
10839
  request2.selfAudit ? "Self-audit requires an injected, scoped platform security token" : "Hosted security requires an injected app developer token or getToken callback"
10711
10840
  );
10712
10841
  }
10713
- return value;
10842
+ return value2;
10714
10843
  }
10715
10844
  function profileFor(name, maxHuntTasks) {
10716
10845
  const profile = name === "odla" ? (0, import_security.odlaProfile)() : name === "cloudflare-app" ? (0, import_security.cloudflareAppProfile)() : name === "generic" ? (0, import_security.genericProfile)() : void 0;
@@ -10756,8 +10885,8 @@ async function getHostedSecurityIntent(options) {
10756
10885
  }
10757
10886
  return response2;
10758
10887
  }
10759
- function isValidIntent(value, expected) {
10760
- return !!value && value.executionContract === "odla.hosted-security-execution-consent.v1" && /^sha256:[a-f0-9]{64}$/.test(value.executionDigest) && /^sha256:[a-f0-9]{64}$/.test(value.planDigest) && value.appId === expected.appId && value.env === expected.env && value.sourceId === expected.sourceId && typeof value.repository === "string" && value.repository.length > 2 && value.repository.length <= 201 && typeof value.defaultBranch === "string" && value.defaultBranch.length > 0 && value.defaultBranch.length <= 255 && typeof value.requestedRef === "string" && value.requestedRef.length > 0 && value.requestedRef.length <= 255 && !/[\u0000-\u001f\u007f]/.test(value.requestedRef) && ["odla", "cloudflare-app", "generic"].includes(value.profile) && value.sourceDisclosure === "redacted";
10888
+ function isValidIntent(value2, expected) {
10889
+ return !!value2 && value2.executionContract === "odla.hosted-security-execution-consent.v1" && /^sha256:[a-f0-9]{64}$/.test(value2.executionDigest) && /^sha256:[a-f0-9]{64}$/.test(value2.planDigest) && value2.appId === expected.appId && value2.env === expected.env && value2.sourceId === expected.sourceId && typeof value2.repository === "string" && value2.repository.length > 2 && value2.repository.length <= 201 && typeof value2.defaultBranch === "string" && value2.defaultBranch.length > 0 && value2.defaultBranch.length <= 255 && typeof value2.requestedRef === "string" && value2.requestedRef.length > 0 && value2.requestedRef.length <= 255 && !/[\u0000-\u001f\u007f]/.test(value2.requestedRef) && ["odla", "cloudflare-app", "generic"].includes(value2.profile) && value2.sourceDisclosure === "redacted";
10761
10890
  }
10762
10891
 
10763
10892
  // src/security-hosted-jobs.ts
@@ -10872,17 +11001,17 @@ function hostedJobPath(appIdInput, jobIdInput) {
10872
11001
  const jobId = hostedIdentifier(jobIdInput, "jobId");
10873
11002
  return `/registry/apps/${encodeURIComponent(appId)}/security/jobs/${encodeURIComponent(jobId)}`;
10874
11003
  }
10875
- function securityPlanDigest(value) {
10876
- if (!/^sha256:[a-f0-9]{64}$/.test(value)) {
11004
+ function securityPlanDigest(value2) {
11005
+ if (!/^sha256:[a-f0-9]{64}$/.test(value2)) {
10877
11006
  throw new Error("expected plan digest must be a sha256 digest from security plan");
10878
11007
  }
10879
- return value;
11008
+ return value2;
10880
11009
  }
10881
- function securityExecutionDigest(value) {
10882
- if (!/^sha256:[a-f0-9]{64}$/.test(value)) {
11010
+ function securityExecutionDigest(value2) {
11011
+ if (!/^sha256:[a-f0-9]{64}$/.test(value2)) {
10883
11012
  throw new Error("expected execution digest must be a sha256 digest from security intent");
10884
11013
  }
10885
- return value;
11014
+ return value2;
10886
11015
  }
10887
11016
 
10888
11017
  // src/security-run-command.ts
@@ -10946,7 +11075,7 @@ async function runSourceSecurityCommand(parsed, dependencies, sourceId) {
10946
11075
  ...context,
10947
11076
  jobId: job.jobId,
10948
11077
  wait: dependencies.pollWait,
10949
- onUpdate: parsed.options.json === true ? void 0 : (value) => printHostedJob(context.stdout, value, context.platform, context.appId)
11078
+ onUpdate: parsed.options.json === true ? void 0 : (value2) => printHostedJob(context.stdout, value2, context.platform, context.appId)
10950
11079
  }) : job;
10951
11080
  if (!follow) {
10952
11081
  if (parsed.options.json === true) {
@@ -11046,9 +11175,9 @@ function enforceLocalGate(report4, parsed) {
11046
11175
  throw new Error(`hosted security gate failed: ${confirmed.length} confirmed >= ${failOn}; ${leads.length} leads >= ${failOnCandidates ?? "disabled"}${incomplete ? "; coverage incomplete" : ""}`);
11047
11176
  }
11048
11177
  }
11049
- function severityOpt(value, flag) {
11050
- if (["informational", "low", "medium", "high", "critical"].includes(value)) {
11051
- return value;
11178
+ function severityOpt(value2, flag) {
11179
+ if (["informational", "low", "medium", "high", "critical"].includes(value2)) {
11180
+ return value2;
11052
11181
  }
11053
11182
  throw new Error(`${flag} must be informational, low, medium, high, or critical`);
11054
11183
  }
@@ -11156,7 +11285,7 @@ async function securityStatus(parsed, dependencies) {
11156
11285
  ...context,
11157
11286
  jobId,
11158
11287
  wait: dependencies.pollWait,
11159
- onUpdate: parsed.options.json === true ? void 0 : (value) => printHostedJob(context.stdout, value, context.platform, context.appId)
11288
+ onUpdate: parsed.options.json === true ? void 0 : (value2) => printHostedJob(context.stdout, value2, context.platform, context.appId)
11160
11289
  }) : await getHostedSecurityJob({ ...context, jobId });
11161
11290
  if (parsed.options.json === true) context.stdout.log(JSON.stringify(job, null, 2));
11162
11291
  else if (parsed.options.follow !== true) {
@@ -11240,6 +11369,10 @@ async function runCli(argv = process.argv.slice(2), dependencies = {}) {
11240
11369
  await o11yCommand(parsed, runtime);
11241
11370
  return;
11242
11371
  }
11372
+ if (command === "platform") {
11373
+ await platformCommand(parsed, runtime);
11374
+ return;
11375
+ }
11243
11376
  if (command === "provision") {
11244
11377
  await provisionCommand(parsed, runtime);
11245
11378
  return;