@odla-ai/cli 0.25.10 → 0.25.12
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 +7 -2
- package/dist/bin.cjs +103 -60
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-335ODYSF.js → chunk-MFC4TX6W.js} +104 -61
- package/dist/chunk-MFC4TX6W.js.map +1 -0
- package/dist/index.cjs +103 -60
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/skills/odla-o11y-debug/SKILL.md +15 -3
- package/dist/chunk-335ODYSF.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -2448,7 +2448,7 @@ var CAPABILITIES = {
|
|
|
2448
2448
|
"compose declared app-capability schema/rules, create guarded seeds when absent, and configure platform AI, auth, and deployment links",
|
|
2449
2449
|
"apply Google Calendar booking config, then drive state-bound consent, status, discovery, and disconnect flows (bookings run live through the platform proxy)",
|
|
2450
2450
|
"validate integration contracts offline and smoke-test a provisioned db environment plus anonymous capability routes",
|
|
2451
|
-
"read one versioned o11y status envelope spanning application RED, current live-sync freshness/load, the protected commit-to-visible canary, collector ingest/scheduler trust, provider-owned runtime metrics, and a bounded machine verdict",
|
|
2451
|
+
"read one versioned o11y status envelope spanning application RED, exact Worker versions observed in traffic, current live-sync freshness/load, the protected commit-to-visible canary, collector ingest/scheduler trust, provider-owned runtime metrics, and a bounded machine verdict",
|
|
2452
2452
|
"inspect durable agent wakeups as a versioned JSON envelope and explicitly requeue one dead-lettered job with a scoped environment credential",
|
|
2453
2453
|
"run app-attributed hosted security discovery and independent validation without provider keys",
|
|
2454
2454
|
"connect/revoke source-read-only GitHub sources and drive commit-pinned hosted security jobs without PATs or provider keys",
|
|
@@ -2470,7 +2470,7 @@ var CAPABILITIES = {
|
|
|
2470
2470
|
"approve GitHub App repository access separately from redacted-snippet disclosure"
|
|
2471
2471
|
],
|
|
2472
2472
|
studio: [
|
|
2473
|
-
"view application telemetry, reconciled live-sync load/freshness, commit-to-visible canary health, provider-owned Worker runtime metrics, and environment state",
|
|
2473
|
+
"view application telemetry grouped by exact Worker version, reconciled live-sync load/freshness, commit-to-visible canary health, provider-owned Worker runtime metrics, and environment state",
|
|
2474
2474
|
"let signed-in users inventory/revoke their own agent grants and admins audit/global-revoke them",
|
|
2475
2475
|
"review calendar connection, granted read scope, selected calendars, and sync health without exposing provider tokens",
|
|
2476
2476
|
"perform manual credential recovery \u2014 for the primary owner or any co-owner \u2014 when the CLI's local shown-once copy is unavailable",
|
|
@@ -8175,6 +8175,7 @@ function statusVerdict(reads) {
|
|
|
8175
8175
|
sourceHttp(reasons, "canary", reads.canary);
|
|
8176
8176
|
sourceHttp(reasons, "collector", reads.collector);
|
|
8177
8177
|
sourceHttp(reasons, "provider", reads.provider);
|
|
8178
|
+
sourceHttp(reasons, "provider", reads.providerHistory, "provider_history_");
|
|
8178
8179
|
const liveStatus = String(reads.liveSync.body.status ?? "");
|
|
8179
8180
|
if (liveStatus === "partial") {
|
|
8180
8181
|
reasons.push({
|
|
@@ -8246,6 +8247,14 @@ function statusVerdict(reads) {
|
|
|
8246
8247
|
severity: "degraded"
|
|
8247
8248
|
});
|
|
8248
8249
|
}
|
|
8250
|
+
const providerHistoryStatus = String(reads.providerHistory.body.status ?? "");
|
|
8251
|
+
if (providerHistoryStatus && providerHistoryStatus !== "observed" && providerHistoryStatus !== "no_data") {
|
|
8252
|
+
reasons.push({
|
|
8253
|
+
source: "provider",
|
|
8254
|
+
code: `provider_history_${providerHistoryStatus}`,
|
|
8255
|
+
severity: "degraded"
|
|
8256
|
+
});
|
|
8257
|
+
}
|
|
8249
8258
|
return {
|
|
8250
8259
|
status: reasons.some((reason) => reason.severity === "unhealthy") ? "unhealthy" : reasons.length > 0 ? "degraded" : "healthy",
|
|
8251
8260
|
reasons
|
|
@@ -8265,15 +8274,80 @@ function collectorReason(read3, fallback) {
|
|
|
8265
8274
|
);
|
|
8266
8275
|
return typeof first?.code === "string" && first.code ? first.code : fallback;
|
|
8267
8276
|
}
|
|
8268
|
-
function sourceHttp(reasons, source, read3) {
|
|
8277
|
+
function sourceHttp(reasons, source, read3, prefix = "") {
|
|
8269
8278
|
if (read3.httpStatus >= 200 && read3.httpStatus < 300) return;
|
|
8270
8279
|
reasons.push({
|
|
8271
8280
|
source,
|
|
8272
|
-
code:
|
|
8281
|
+
code: `${prefix}http_${read3.httpStatus}`,
|
|
8273
8282
|
severity: read3.httpStatus >= 500 && read3.httpStatus !== 501 ? "unhealthy" : "degraded"
|
|
8274
8283
|
});
|
|
8275
8284
|
}
|
|
8276
8285
|
|
|
8286
|
+
// src/o11y-output.ts
|
|
8287
|
+
function printO11yStatus(status, out) {
|
|
8288
|
+
out.log(
|
|
8289
|
+
`o11y status ${status.scope.appId}/${status.scope.env} (${status.scope.minutes}m)`
|
|
8290
|
+
);
|
|
8291
|
+
const routes = Array.isArray(status.application.body.routes) ? status.application.body.routes.filter(record6) : [];
|
|
8292
|
+
const requests = routes.reduce(
|
|
8293
|
+
(total, row) => total + numeric3(row.requests),
|
|
8294
|
+
0
|
|
8295
|
+
);
|
|
8296
|
+
const errors = routes.reduce(
|
|
8297
|
+
(total, row) => total + numeric3(row.errors),
|
|
8298
|
+
0
|
|
8299
|
+
);
|
|
8300
|
+
out.log(
|
|
8301
|
+
`application ${status.application.httpStatus} ${requests} requests ${errors} errors`
|
|
8302
|
+
);
|
|
8303
|
+
const versions = Array.isArray(status.applicationVersions.body.rows) ? status.applicationVersions.body.rows.filter(record6) : [];
|
|
8304
|
+
out.log(
|
|
8305
|
+
`application-versions ${status.applicationVersions.httpStatus} ${versions.length ? versions.slice(0, 5).map(
|
|
8306
|
+
(row) => `${String(row.value || "(unattributed)")}:${numeric3(row.requests)}`
|
|
8307
|
+
).join(", ") : "none observed"}`
|
|
8308
|
+
);
|
|
8309
|
+
out.log(liveSyncLine(status.liveSync));
|
|
8310
|
+
const canaryDurations = record6(status.canary.body.durationsMs) ? status.canary.body.durationsMs : {};
|
|
8311
|
+
out.log(
|
|
8312
|
+
`canary ${status.canary.httpStatus} ${String(status.canary.body.status ?? status.canary.body.error ?? "unavailable")} ${optionalNumeric(canaryDurations.publishToVisibleMs)} publish-to-visible`
|
|
8313
|
+
);
|
|
8314
|
+
const collectorIngest = record6(status.collector.body.ingest) ? status.collector.body.ingest : {};
|
|
8315
|
+
const collectorStorage = record6(collectorIngest.storage) ? collectorIngest.storage : {};
|
|
8316
|
+
out.log(
|
|
8317
|
+
`collector ${status.collector.httpStatus} ${String(status.collector.body.status ?? status.collector.body.error ?? "unavailable")} ${numeric3(collectorStorage.affectedPoints)} affected points`
|
|
8318
|
+
);
|
|
8319
|
+
const providerMetrics = record6(status.provider.body.metrics) ? status.provider.body.metrics : {};
|
|
8320
|
+
out.log(
|
|
8321
|
+
`cloudflare ${status.provider.httpStatus} ${String(status.provider.body.status ?? status.provider.body.error ?? "unavailable")} ${numeric3(providerMetrics.requests)} invocations ${numeric3(providerMetrics.errors)} runtime errors`
|
|
8322
|
+
);
|
|
8323
|
+
const providerPoints = Array.isArray(status.providerHistory.body.points) ? status.providerHistory.body.points.length : 0;
|
|
8324
|
+
const providerFreshness = record6(status.providerHistory.body.freshness) ? status.providerHistory.body.freshness : {};
|
|
8325
|
+
out.log(
|
|
8326
|
+
`cloudflare-history ${status.providerHistory.httpStatus} ${String(status.providerHistory.body.status ?? status.providerHistory.body.error ?? "unavailable")} ${providerPoints} snapshots ${optionalAge(providerFreshness.ageMs)} old`
|
|
8327
|
+
);
|
|
8328
|
+
out.log(
|
|
8329
|
+
`verdict ${status.verdict.status} ${status.verdict.reasons.map((reason) => `${reason.source}:${reason.code}`).join(", ") || "all required signals healthy"}`
|
|
8330
|
+
);
|
|
8331
|
+
}
|
|
8332
|
+
function liveSyncLine(read3) {
|
|
8333
|
+
const performance = record6(read3.body.performance) ? read3.body.performance : {};
|
|
8334
|
+
const commitToSend = record6(performance.commitToSend) ? performance.commitToSend : {};
|
|
8335
|
+
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`;
|
|
8336
|
+
}
|
|
8337
|
+
function record6(value) {
|
|
8338
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
8339
|
+
}
|
|
8340
|
+
function numeric3(value) {
|
|
8341
|
+
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
8342
|
+
}
|
|
8343
|
+
function optionalNumeric(value) {
|
|
8344
|
+
return typeof value === "number" && Number.isFinite(value) ? `${value} ms` : "\u2014";
|
|
8345
|
+
}
|
|
8346
|
+
function optionalAge(value) {
|
|
8347
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return "unknown";
|
|
8348
|
+
return `${Math.max(0, Math.round(value / 1e3))}s`;
|
|
8349
|
+
}
|
|
8350
|
+
|
|
8277
8351
|
// src/o11y-command.ts
|
|
8278
8352
|
async function o11yCommand(parsed, deps = {}) {
|
|
8279
8353
|
assertArgs(
|
|
@@ -8311,8 +8385,23 @@ async function o11yCommand(parsed, deps = {}) {
|
|
|
8311
8385
|
const base = `${cfg.platformUrl}/o11y/${encodeURIComponent(appId)}`;
|
|
8312
8386
|
const query = new URLSearchParams({ env, minutes: String(minutes) });
|
|
8313
8387
|
const headers = { authorization: `Bearer ${token}` };
|
|
8314
|
-
const
|
|
8388
|
+
const versionsQuery = new URLSearchParams({
|
|
8389
|
+
env,
|
|
8390
|
+
minutes: String(minutes),
|
|
8391
|
+
dimension: "version",
|
|
8392
|
+
metric: "requests"
|
|
8393
|
+
});
|
|
8394
|
+
const [
|
|
8395
|
+
application,
|
|
8396
|
+
applicationVersions,
|
|
8397
|
+
liveSync,
|
|
8398
|
+
canary,
|
|
8399
|
+
collector,
|
|
8400
|
+
provider,
|
|
8401
|
+
providerHistory
|
|
8402
|
+
] = await Promise.all([
|
|
8315
8403
|
read2(`${base}/metrics/red?${query}`, headers, doFetch),
|
|
8404
|
+
read2(`${base}/explore?${versionsQuery}`, headers, doFetch),
|
|
8316
8405
|
read2(
|
|
8317
8406
|
`${base}/live-sync/health?${query}`,
|
|
8318
8407
|
headers,
|
|
@@ -8324,31 +8413,35 @@ async function o11yCommand(parsed, deps = {}) {
|
|
|
8324
8413
|
doFetch
|
|
8325
8414
|
),
|
|
8326
8415
|
read2(`${base}/self-health?${query}`, headers, doFetch),
|
|
8327
|
-
read2(`${base}/provider/cloudflare?${query}`, headers, doFetch)
|
|
8416
|
+
read2(`${base}/provider/cloudflare?${query}`, headers, doFetch),
|
|
8417
|
+
read2(`${base}/provider/cloudflare/history?${query}`, headers, doFetch)
|
|
8328
8418
|
]);
|
|
8329
8419
|
const verdict = statusVerdict({
|
|
8330
8420
|
application,
|
|
8331
8421
|
liveSync,
|
|
8332
8422
|
canary,
|
|
8333
8423
|
collector,
|
|
8334
|
-
provider
|
|
8424
|
+
provider,
|
|
8425
|
+
providerHistory
|
|
8335
8426
|
});
|
|
8336
8427
|
const status = {
|
|
8337
|
-
schemaVersion:
|
|
8428
|
+
schemaVersion: 6,
|
|
8338
8429
|
scope: { appId, env, minutes },
|
|
8339
8430
|
observedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8340
8431
|
verdict,
|
|
8341
8432
|
application,
|
|
8433
|
+
applicationVersions,
|
|
8342
8434
|
liveSync,
|
|
8343
8435
|
canary,
|
|
8344
8436
|
collector,
|
|
8345
|
-
provider
|
|
8437
|
+
provider,
|
|
8438
|
+
providerHistory
|
|
8346
8439
|
};
|
|
8347
8440
|
if (parsed.options.json === true) {
|
|
8348
8441
|
out.log(JSON.stringify(status, null, 2));
|
|
8349
8442
|
return;
|
|
8350
8443
|
}
|
|
8351
|
-
|
|
8444
|
+
printO11yStatus(status, out);
|
|
8352
8445
|
}
|
|
8353
8446
|
function statusMinutes(value) {
|
|
8354
8447
|
if (!Number.isSafeInteger(value) || value < 1 || value > 7 * 24 * 60) {
|
|
@@ -8370,56 +8463,6 @@ async function read2(url, headers, doFetch) {
|
|
|
8370
8463
|
}
|
|
8371
8464
|
return { httpStatus: response2.status, body };
|
|
8372
8465
|
}
|
|
8373
|
-
function printStatus2(status, out) {
|
|
8374
|
-
out.log(
|
|
8375
|
-
`o11y status ${status.scope.appId}/${status.scope.env} (${status.scope.minutes}m)`
|
|
8376
|
-
);
|
|
8377
|
-
const routes = Array.isArray(status.application.body.routes) ? status.application.body.routes.filter(record6) : [];
|
|
8378
|
-
const requests = routes.reduce(
|
|
8379
|
-
(total, row) => total + numeric3(row.requests),
|
|
8380
|
-
0
|
|
8381
|
-
);
|
|
8382
|
-
const errors = routes.reduce(
|
|
8383
|
-
(total, row) => total + numeric3(row.errors),
|
|
8384
|
-
0
|
|
8385
|
-
);
|
|
8386
|
-
out.log(
|
|
8387
|
-
`application ${status.application.httpStatus} ${requests} requests ${errors} errors`
|
|
8388
|
-
);
|
|
8389
|
-
out.log(
|
|
8390
|
-
liveSyncLine(status.liveSync)
|
|
8391
|
-
);
|
|
8392
|
-
const canaryDurations = record6(status.canary.body.durationsMs) ? status.canary.body.durationsMs : {};
|
|
8393
|
-
out.log(
|
|
8394
|
-
`canary ${status.canary.httpStatus} ${String(status.canary.body.status ?? status.canary.body.error ?? "unavailable")} ${optionalNumeric(canaryDurations.publishToVisibleMs)} publish-to-visible`
|
|
8395
|
-
);
|
|
8396
|
-
const collectorIngest = record6(status.collector.body.ingest) ? status.collector.body.ingest : {};
|
|
8397
|
-
const collectorStorage = record6(collectorIngest.storage) ? collectorIngest.storage : {};
|
|
8398
|
-
out.log(
|
|
8399
|
-
`collector ${status.collector.httpStatus} ${String(status.collector.body.status ?? status.collector.body.error ?? "unavailable")} ${numeric3(collectorStorage.affectedPoints)} affected points`
|
|
8400
|
-
);
|
|
8401
|
-
const providerMetrics = record6(status.provider.body.metrics) ? status.provider.body.metrics : {};
|
|
8402
|
-
out.log(
|
|
8403
|
-
`cloudflare ${status.provider.httpStatus} ${String(status.provider.body.status ?? status.provider.body.error ?? "unavailable")} ${numeric3(providerMetrics.requests)} invocations ${numeric3(providerMetrics.errors)} runtime errors`
|
|
8404
|
-
);
|
|
8405
|
-
out.log(
|
|
8406
|
-
`verdict ${status.verdict.status} ${status.verdict.reasons.map((reason) => `${reason.source}:${reason.code}`).join(", ") || "all required signals healthy"}`
|
|
8407
|
-
);
|
|
8408
|
-
}
|
|
8409
|
-
function liveSyncLine(read3) {
|
|
8410
|
-
const performance = record6(read3.body.performance) ? read3.body.performance : {};
|
|
8411
|
-
const commitToSend = record6(performance.commitToSend) ? performance.commitToSend : {};
|
|
8412
|
-
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`;
|
|
8413
|
-
}
|
|
8414
|
-
function record6(value) {
|
|
8415
|
-
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
8416
|
-
}
|
|
8417
|
-
function numeric3(value) {
|
|
8418
|
-
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
8419
|
-
}
|
|
8420
|
-
function optionalNumeric(value) {
|
|
8421
|
-
return typeof value === "number" && Number.isFinite(value) ? `${value} ms` : "\u2014";
|
|
8422
|
-
}
|
|
8423
8466
|
|
|
8424
8467
|
// src/provision.ts
|
|
8425
8468
|
var import_apps5 = require("@odla-ai/apps");
|