@odla-ai/cli 0.25.6 → 0.25.7

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/README.md CHANGED
@@ -72,7 +72,8 @@ snapshot instead of scraping Studio or composing collector routes themselves:
72
72
  npx odla-ai o11y status --app <appId> --env prod --minutes 60 --json
73
73
  ```
74
74
 
75
- Schema v3 keeps application RED, reconciled live-sync load/freshness, the exact
75
+ Schema v4 keeps application RED, reconciled live-sync load/freshness and
76
+ subscription recompute/fanout/payload/commit-to-send performance, the exact
76
77
  latest protected commit-to-visible canary, collector ingest/scheduler trust,
77
78
  and Cloudflare-owned Worker runtime evidence separate. It derives one
78
79
  `healthy`, `degraded`, or `unhealthy` verdict with stable reason codes while
package/dist/bin.cjs CHANGED
@@ -3946,8 +3946,8 @@ async function materializeGitTree(source, commitSha, options = {}) {
3946
3946
  const maxFiles = options.maxFiles ?? 2e4;
3947
3947
  const maxBytes = options.maxBytes ?? 512 * 1024 * 1024;
3948
3948
  const inventory = (await gitOutput(sourceDir, ["ls-tree", "-rz", commitSha], 16 * 1024 * 1024)).toString("utf8").split("\0").filter(Boolean);
3949
- const entries = inventory.flatMap((record6) => {
3950
- const match = /^(100644|100755) blob ([0-9a-f]{40,64})\t([\s\S]+)$/.exec(record6);
3949
+ const entries = inventory.flatMap((record7) => {
3950
+ const match = /^(100644|100755) blob ([0-9a-f]{40,64})\t([\s\S]+)$/.exec(record7);
3951
3951
  return match && allowedWorkspacePath(match[3]) ? [{ mode: match[1], hash: match[2], path: match[3] }] : [];
3952
3952
  });
3953
3953
  if (entries.length > maxFiles) throw new Error(`workspace exceeds ${maxFiles} files`);
@@ -4195,8 +4195,8 @@ function normalize(value) {
4195
4195
  if (Array.isArray(value)) return value.map(normalize);
4196
4196
  if (value instanceof Uint8Array) return { $bytes: [...value] };
4197
4197
  if (typeof value === "object") {
4198
- const record6 = value;
4199
- return Object.fromEntries(Object.keys(record6).filter((key) => record6[key] !== void 0).sort().map((key) => [key, normalize(record6[key])]));
4198
+ const record7 = value;
4199
+ return Object.fromEntries(Object.keys(record7).filter((key) => record7[key] !== void 0).sort().map((key) => [key, normalize(record7[key])]));
4200
4200
  }
4201
4201
  throw new CamelError("state_conflict", "Canonical JSON rejects unsupported values.");
4202
4202
  }
@@ -7650,8 +7650,8 @@ async function pmAdd(ctx, entity, parsed) {
7650
7650
  emit2(ctx, res, () => ctx.out.log(`created ${entity} ${res.id}`));
7651
7651
  }
7652
7652
  async function pmGet(ctx, entity, id) {
7653
- const { record: record6 } = await pmRequest(ctx, "GET", `/${entity}/${encodeURIComponent(id)}`);
7654
- emit2(ctx, record6, () => printRecord(ctx, entity, record6));
7653
+ const { record: record7 } = await pmRequest(ctx, "GET", `/${entity}/${encodeURIComponent(id)}`);
7654
+ emit2(ctx, record7, () => printRecord(ctx, entity, record7));
7655
7655
  }
7656
7656
  async function pmSet(ctx, entity, id, parsed) {
7657
7657
  const patch2 = collectEntityFields(entity, parsed, true);
@@ -7696,9 +7696,9 @@ async function pmHandoff(ctx, parsed) {
7696
7696
  ]);
7697
7697
  const handoff = {
7698
7698
  appId,
7699
- unmetGoals: goals.filter((record6) => record6.status !== "met"),
7700
- activeTasks: tasks.filter((record6) => record6.column !== "done"),
7701
- openBugs: bugs.filter((record6) => record6.status !== "fixed" && record6.status !== "wontfix")
7699
+ unmetGoals: goals.filter((record7) => record7.status !== "met"),
7700
+ activeTasks: tasks.filter((record7) => record7.column !== "done"),
7701
+ openBugs: bugs.filter((record7) => record7.status !== "fixed" && record7.status !== "wontfix")
7702
7702
  };
7703
7703
  const result = {
7704
7704
  ...handoff,
@@ -7717,10 +7717,10 @@ async function pmHandoff(ctx, parsed) {
7717
7717
  ]) {
7718
7718
  ctx.out.log(`${label}:`);
7719
7719
  if (!records.length) ctx.out.log("- (none)");
7720
- else for (const record6 of records) printRecord(
7720
+ else for (const record7 of records) printRecord(
7721
7721
  ctx,
7722
7722
  label === "unmet goals" ? "goal" : label === "active tasks" ? "task" : "bug",
7723
- record6
7723
+ record7
7724
7724
  );
7725
7725
  }
7726
7726
  });
@@ -7861,6 +7861,21 @@ function statusVerdict(reads) {
7861
7861
  severity: "degraded"
7862
7862
  });
7863
7863
  }
7864
+ const performance = record5(reads.liveSync.body.performance) ? reads.liveSync.body.performance : null;
7865
+ if (performance?.status === "unavailable") {
7866
+ reasons.push({
7867
+ source: "liveSync",
7868
+ code: "subscription_metrics_unavailable",
7869
+ severity: "degraded"
7870
+ });
7871
+ }
7872
+ if (numeric2(performance?.telemetryDropped) > 0) {
7873
+ reasons.push({
7874
+ source: "liveSync",
7875
+ code: "subscription_telemetry_dropped",
7876
+ severity: "degraded"
7877
+ });
7878
+ }
7864
7879
  const canaryStatus = String(reads.canary.body.status ?? "");
7865
7880
  if (canaryStatus === "failing") {
7866
7881
  reasons.push({
@@ -7908,6 +7923,12 @@ function statusVerdict(reads) {
7908
7923
  reasons
7909
7924
  };
7910
7925
  }
7926
+ function record5(value) {
7927
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
7928
+ }
7929
+ function numeric2(value) {
7930
+ return typeof value === "number" && Number.isFinite(value) ? value : 0;
7931
+ }
7911
7932
  function collectorReason(read3, fallback) {
7912
7933
  const reasons = read3.body.reasons;
7913
7934
  if (!Array.isArray(reasons)) return fallback;
@@ -7965,7 +7986,7 @@ async function o11yCommand(parsed, deps = {}) {
7965
7986
  const [application, liveSync, canary, collector, provider] = await Promise.all([
7966
7987
  read2(`${base}/metrics/red?${query}`, headers, doFetch),
7967
7988
  read2(
7968
- `${base}/live-sync/health?${new URLSearchParams({ env })}`,
7989
+ `${base}/live-sync/health?${query}`,
7969
7990
  headers,
7970
7991
  doFetch
7971
7992
  ),
@@ -7985,7 +8006,7 @@ async function o11yCommand(parsed, deps = {}) {
7985
8006
  provider
7986
8007
  });
7987
8008
  const status = {
7988
- schemaVersion: 3,
8009
+ schemaVersion: 4,
7989
8010
  scope: { appId, env, minutes },
7990
8011
  observedAt: (/* @__PURE__ */ new Date()).toISOString(),
7991
8012
  verdict,
@@ -8025,42 +8046,47 @@ function printStatus2(status, out) {
8025
8046
  out.log(
8026
8047
  `o11y status ${status.scope.appId}/${status.scope.env} (${status.scope.minutes}m)`
8027
8048
  );
8028
- const routes = Array.isArray(status.application.body.routes) ? status.application.body.routes.filter(record5) : [];
8049
+ const routes = Array.isArray(status.application.body.routes) ? status.application.body.routes.filter(record6) : [];
8029
8050
  const requests = routes.reduce(
8030
- (total, row) => total + numeric2(row.requests),
8051
+ (total, row) => total + numeric3(row.requests),
8031
8052
  0
8032
8053
  );
8033
8054
  const errors = routes.reduce(
8034
- (total, row) => total + numeric2(row.errors),
8055
+ (total, row) => total + numeric3(row.errors),
8035
8056
  0
8036
8057
  );
8037
8058
  out.log(
8038
8059
  `application ${status.application.httpStatus} ${requests} requests ${errors} errors`
8039
8060
  );
8040
8061
  out.log(
8041
- `live-sync ${status.liveSync.httpStatus} ${String(status.liveSync.body.status ?? status.liveSync.body.error ?? "unavailable")} ${numeric2(status.liveSync.body.activeConnections)} active`
8062
+ liveSyncLine(status.liveSync)
8042
8063
  );
8043
- const canaryDurations = record5(status.canary.body.durationsMs) ? status.canary.body.durationsMs : {};
8064
+ const canaryDurations = record6(status.canary.body.durationsMs) ? status.canary.body.durationsMs : {};
8044
8065
  out.log(
8045
8066
  `canary ${status.canary.httpStatus} ${String(status.canary.body.status ?? status.canary.body.error ?? "unavailable")} ${optionalNumeric(canaryDurations.publishToVisibleMs)} publish-to-visible`
8046
8067
  );
8047
- const collectorIngest = record5(status.collector.body.ingest) ? status.collector.body.ingest : {};
8048
- const collectorStorage = record5(collectorIngest.storage) ? collectorIngest.storage : {};
8068
+ const collectorIngest = record6(status.collector.body.ingest) ? status.collector.body.ingest : {};
8069
+ const collectorStorage = record6(collectorIngest.storage) ? collectorIngest.storage : {};
8049
8070
  out.log(
8050
- `collector ${status.collector.httpStatus} ${String(status.collector.body.status ?? status.collector.body.error ?? "unavailable")} ${numeric2(collectorStorage.affectedPoints)} affected points`
8071
+ `collector ${status.collector.httpStatus} ${String(status.collector.body.status ?? status.collector.body.error ?? "unavailable")} ${numeric3(collectorStorage.affectedPoints)} affected points`
8051
8072
  );
8052
- const providerMetrics = record5(status.provider.body.metrics) ? status.provider.body.metrics : {};
8073
+ const providerMetrics = record6(status.provider.body.metrics) ? status.provider.body.metrics : {};
8053
8074
  out.log(
8054
- `cloudflare ${status.provider.httpStatus} ${String(status.provider.body.status ?? status.provider.body.error ?? "unavailable")} ${numeric2(providerMetrics.requests)} invocations ${numeric2(providerMetrics.errors)} runtime errors`
8075
+ `cloudflare ${status.provider.httpStatus} ${String(status.provider.body.status ?? status.provider.body.error ?? "unavailable")} ${numeric3(providerMetrics.requests)} invocations ${numeric3(providerMetrics.errors)} runtime errors`
8055
8076
  );
8056
8077
  out.log(
8057
8078
  `verdict ${status.verdict.status} ${status.verdict.reasons.map((reason) => `${reason.source}:${reason.code}`).join(", ") || "all required signals healthy"}`
8058
8079
  );
8059
8080
  }
8060
- function record5(value) {
8081
+ function liveSyncLine(read3) {
8082
+ const performance = record6(read3.body.performance) ? read3.body.performance : {};
8083
+ const commitToSend = record6(performance.commitToSend) ? performance.commitToSend : {};
8084
+ 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`;
8085
+ }
8086
+ function record6(value) {
8061
8087
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
8062
8088
  }
8063
- function numeric2(value) {
8089
+ function numeric3(value) {
8064
8090
  return typeof value === "number" && Number.isFinite(value) ? value : 0;
8065
8091
  }
8066
8092
  function optionalNumeric(value) {