@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/bin.js
CHANGED
|
@@ -1616,7 +1616,7 @@ var CAPABILITIES = {
|
|
|
1616
1616
|
"compose declared app-capability schema/rules, create guarded seeds when absent, and configure platform AI, auth, and deployment links",
|
|
1617
1617
|
"apply Google Calendar booking config, then drive state-bound consent, status, discovery, and disconnect flows (bookings run live through the platform proxy)",
|
|
1618
1618
|
"validate integration contracts offline and smoke-test a provisioned db environment plus anonymous capability routes",
|
|
1619
|
-
"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",
|
|
1619
|
+
"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",
|
|
1620
1620
|
"inspect durable agent wakeups as a versioned JSON envelope and explicitly requeue one dead-lettered job with a scoped environment credential",
|
|
1621
1621
|
"run app-attributed hosted security discovery and independent validation without provider keys",
|
|
1622
1622
|
"connect/revoke source-read-only GitHub sources and drive commit-pinned hosted security jobs without PATs or provider keys",
|
|
@@ -1638,7 +1638,7 @@ var CAPABILITIES = {
|
|
|
1638
1638
|
"approve GitHub App repository access separately from redacted-snippet disclosure"
|
|
1639
1639
|
],
|
|
1640
1640
|
studio: [
|
|
1641
|
-
"view application telemetry, reconciled live-sync load/freshness, commit-to-visible canary health, provider-owned Worker runtime metrics, and environment state",
|
|
1641
|
+
"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",
|
|
1642
1642
|
"let signed-in users inventory/revoke their own agent grants and admins audit/global-revoke them",
|
|
1643
1643
|
"review calendar connection, granted read scope, selected calendars, and sync health without exposing provider tokens",
|
|
1644
1644
|
"perform manual credential recovery \u2014 for the primary owner or any co-owner \u2014 when the CLI's local shown-once copy is unavailable",
|
|
@@ -8914,6 +8914,7 @@ function statusVerdict(reads) {
|
|
|
8914
8914
|
sourceHttp(reasons, "canary", reads.canary);
|
|
8915
8915
|
sourceHttp(reasons, "collector", reads.collector);
|
|
8916
8916
|
sourceHttp(reasons, "provider", reads.provider);
|
|
8917
|
+
sourceHttp(reasons, "provider", reads.providerHistory, "provider_history_");
|
|
8917
8918
|
const liveStatus = String(reads.liveSync.body.status ?? "");
|
|
8918
8919
|
if (liveStatus === "partial") {
|
|
8919
8920
|
reasons.push({
|
|
@@ -8985,6 +8986,14 @@ function statusVerdict(reads) {
|
|
|
8985
8986
|
severity: "degraded"
|
|
8986
8987
|
});
|
|
8987
8988
|
}
|
|
8989
|
+
const providerHistoryStatus = String(reads.providerHistory.body.status ?? "");
|
|
8990
|
+
if (providerHistoryStatus && providerHistoryStatus !== "observed" && providerHistoryStatus !== "no_data") {
|
|
8991
|
+
reasons.push({
|
|
8992
|
+
source: "provider",
|
|
8993
|
+
code: `provider_history_${providerHistoryStatus}`,
|
|
8994
|
+
severity: "degraded"
|
|
8995
|
+
});
|
|
8996
|
+
}
|
|
8988
8997
|
return {
|
|
8989
8998
|
status: reasons.some((reason) => reason.severity === "unhealthy") ? "unhealthy" : reasons.length > 0 ? "degraded" : "healthy",
|
|
8990
8999
|
reasons
|
|
@@ -9004,15 +9013,80 @@ function collectorReason(read3, fallback) {
|
|
|
9004
9013
|
);
|
|
9005
9014
|
return typeof first?.code === "string" && first.code ? first.code : fallback;
|
|
9006
9015
|
}
|
|
9007
|
-
function sourceHttp(reasons, source, read3) {
|
|
9016
|
+
function sourceHttp(reasons, source, read3, prefix = "") {
|
|
9008
9017
|
if (read3.httpStatus >= 200 && read3.httpStatus < 300) return;
|
|
9009
9018
|
reasons.push({
|
|
9010
9019
|
source,
|
|
9011
|
-
code:
|
|
9020
|
+
code: `${prefix}http_${read3.httpStatus}`,
|
|
9012
9021
|
severity: read3.httpStatus >= 500 && read3.httpStatus !== 501 ? "unhealthy" : "degraded"
|
|
9013
9022
|
});
|
|
9014
9023
|
}
|
|
9015
9024
|
|
|
9025
|
+
// src/o11y-output.ts
|
|
9026
|
+
function printO11yStatus(status, out) {
|
|
9027
|
+
out.log(
|
|
9028
|
+
`o11y status ${status.scope.appId}/${status.scope.env} (${status.scope.minutes}m)`
|
|
9029
|
+
);
|
|
9030
|
+
const routes = Array.isArray(status.application.body.routes) ? status.application.body.routes.filter(record6) : [];
|
|
9031
|
+
const requests = routes.reduce(
|
|
9032
|
+
(total, row) => total + numeric3(row.requests),
|
|
9033
|
+
0
|
|
9034
|
+
);
|
|
9035
|
+
const errors = routes.reduce(
|
|
9036
|
+
(total, row) => total + numeric3(row.errors),
|
|
9037
|
+
0
|
|
9038
|
+
);
|
|
9039
|
+
out.log(
|
|
9040
|
+
`application ${status.application.httpStatus} ${requests} requests ${errors} errors`
|
|
9041
|
+
);
|
|
9042
|
+
const versions = Array.isArray(status.applicationVersions.body.rows) ? status.applicationVersions.body.rows.filter(record6) : [];
|
|
9043
|
+
out.log(
|
|
9044
|
+
`application-versions ${status.applicationVersions.httpStatus} ${versions.length ? versions.slice(0, 5).map(
|
|
9045
|
+
(row) => `${String(row.value || "(unattributed)")}:${numeric3(row.requests)}`
|
|
9046
|
+
).join(", ") : "none observed"}`
|
|
9047
|
+
);
|
|
9048
|
+
out.log(liveSyncLine(status.liveSync));
|
|
9049
|
+
const canaryDurations = record6(status.canary.body.durationsMs) ? status.canary.body.durationsMs : {};
|
|
9050
|
+
out.log(
|
|
9051
|
+
`canary ${status.canary.httpStatus} ${String(status.canary.body.status ?? status.canary.body.error ?? "unavailable")} ${optionalNumeric(canaryDurations.publishToVisibleMs)} publish-to-visible`
|
|
9052
|
+
);
|
|
9053
|
+
const collectorIngest = record6(status.collector.body.ingest) ? status.collector.body.ingest : {};
|
|
9054
|
+
const collectorStorage = record6(collectorIngest.storage) ? collectorIngest.storage : {};
|
|
9055
|
+
out.log(
|
|
9056
|
+
`collector ${status.collector.httpStatus} ${String(status.collector.body.status ?? status.collector.body.error ?? "unavailable")} ${numeric3(collectorStorage.affectedPoints)} affected points`
|
|
9057
|
+
);
|
|
9058
|
+
const providerMetrics = record6(status.provider.body.metrics) ? status.provider.body.metrics : {};
|
|
9059
|
+
out.log(
|
|
9060
|
+
`cloudflare ${status.provider.httpStatus} ${String(status.provider.body.status ?? status.provider.body.error ?? "unavailable")} ${numeric3(providerMetrics.requests)} invocations ${numeric3(providerMetrics.errors)} runtime errors`
|
|
9061
|
+
);
|
|
9062
|
+
const providerPoints = Array.isArray(status.providerHistory.body.points) ? status.providerHistory.body.points.length : 0;
|
|
9063
|
+
const providerFreshness = record6(status.providerHistory.body.freshness) ? status.providerHistory.body.freshness : {};
|
|
9064
|
+
out.log(
|
|
9065
|
+
`cloudflare-history ${status.providerHistory.httpStatus} ${String(status.providerHistory.body.status ?? status.providerHistory.body.error ?? "unavailable")} ${providerPoints} snapshots ${optionalAge(providerFreshness.ageMs)} old`
|
|
9066
|
+
);
|
|
9067
|
+
out.log(
|
|
9068
|
+
`verdict ${status.verdict.status} ${status.verdict.reasons.map((reason) => `${reason.source}:${reason.code}`).join(", ") || "all required signals healthy"}`
|
|
9069
|
+
);
|
|
9070
|
+
}
|
|
9071
|
+
function liveSyncLine(read3) {
|
|
9072
|
+
const performance = record6(read3.body.performance) ? read3.body.performance : {};
|
|
9073
|
+
const commitToSend = record6(performance.commitToSend) ? performance.commitToSend : {};
|
|
9074
|
+
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`;
|
|
9075
|
+
}
|
|
9076
|
+
function record6(value) {
|
|
9077
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
9078
|
+
}
|
|
9079
|
+
function numeric3(value) {
|
|
9080
|
+
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
9081
|
+
}
|
|
9082
|
+
function optionalNumeric(value) {
|
|
9083
|
+
return typeof value === "number" && Number.isFinite(value) ? `${value} ms` : "\u2014";
|
|
9084
|
+
}
|
|
9085
|
+
function optionalAge(value) {
|
|
9086
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return "unknown";
|
|
9087
|
+
return `${Math.max(0, Math.round(value / 1e3))}s`;
|
|
9088
|
+
}
|
|
9089
|
+
|
|
9016
9090
|
// src/o11y-command.ts
|
|
9017
9091
|
async function o11yCommand(parsed, deps = {}) {
|
|
9018
9092
|
assertArgs(
|
|
@@ -9050,8 +9124,23 @@ async function o11yCommand(parsed, deps = {}) {
|
|
|
9050
9124
|
const base = `${cfg.platformUrl}/o11y/${encodeURIComponent(appId)}`;
|
|
9051
9125
|
const query = new URLSearchParams({ env, minutes: String(minutes) });
|
|
9052
9126
|
const headers = { authorization: `Bearer ${token}` };
|
|
9053
|
-
const
|
|
9127
|
+
const versionsQuery = new URLSearchParams({
|
|
9128
|
+
env,
|
|
9129
|
+
minutes: String(minutes),
|
|
9130
|
+
dimension: "version",
|
|
9131
|
+
metric: "requests"
|
|
9132
|
+
});
|
|
9133
|
+
const [
|
|
9134
|
+
application,
|
|
9135
|
+
applicationVersions,
|
|
9136
|
+
liveSync,
|
|
9137
|
+
canary,
|
|
9138
|
+
collector,
|
|
9139
|
+
provider,
|
|
9140
|
+
providerHistory
|
|
9141
|
+
] = await Promise.all([
|
|
9054
9142
|
read2(`${base}/metrics/red?${query}`, headers, doFetch),
|
|
9143
|
+
read2(`${base}/explore?${versionsQuery}`, headers, doFetch),
|
|
9055
9144
|
read2(
|
|
9056
9145
|
`${base}/live-sync/health?${query}`,
|
|
9057
9146
|
headers,
|
|
@@ -9063,31 +9152,35 @@ async function o11yCommand(parsed, deps = {}) {
|
|
|
9063
9152
|
doFetch
|
|
9064
9153
|
),
|
|
9065
9154
|
read2(`${base}/self-health?${query}`, headers, doFetch),
|
|
9066
|
-
read2(`${base}/provider/cloudflare?${query}`, headers, doFetch)
|
|
9155
|
+
read2(`${base}/provider/cloudflare?${query}`, headers, doFetch),
|
|
9156
|
+
read2(`${base}/provider/cloudflare/history?${query}`, headers, doFetch)
|
|
9067
9157
|
]);
|
|
9068
9158
|
const verdict = statusVerdict({
|
|
9069
9159
|
application,
|
|
9070
9160
|
liveSync,
|
|
9071
9161
|
canary,
|
|
9072
9162
|
collector,
|
|
9073
|
-
provider
|
|
9163
|
+
provider,
|
|
9164
|
+
providerHistory
|
|
9074
9165
|
});
|
|
9075
9166
|
const status = {
|
|
9076
|
-
schemaVersion:
|
|
9167
|
+
schemaVersion: 6,
|
|
9077
9168
|
scope: { appId, env, minutes },
|
|
9078
9169
|
observedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
9079
9170
|
verdict,
|
|
9080
9171
|
application,
|
|
9172
|
+
applicationVersions,
|
|
9081
9173
|
liveSync,
|
|
9082
9174
|
canary,
|
|
9083
9175
|
collector,
|
|
9084
|
-
provider
|
|
9176
|
+
provider,
|
|
9177
|
+
providerHistory
|
|
9085
9178
|
};
|
|
9086
9179
|
if (parsed.options.json === true) {
|
|
9087
9180
|
out.log(JSON.stringify(status, null, 2));
|
|
9088
9181
|
return;
|
|
9089
9182
|
}
|
|
9090
|
-
|
|
9183
|
+
printO11yStatus(status, out);
|
|
9091
9184
|
}
|
|
9092
9185
|
function statusMinutes(value) {
|
|
9093
9186
|
if (!Number.isSafeInteger(value) || value < 1 || value > 7 * 24 * 60) {
|
|
@@ -9109,56 +9202,6 @@ async function read2(url, headers, doFetch) {
|
|
|
9109
9202
|
}
|
|
9110
9203
|
return { httpStatus: response2.status, body };
|
|
9111
9204
|
}
|
|
9112
|
-
function printStatus2(status, out) {
|
|
9113
|
-
out.log(
|
|
9114
|
-
`o11y status ${status.scope.appId}/${status.scope.env} (${status.scope.minutes}m)`
|
|
9115
|
-
);
|
|
9116
|
-
const routes = Array.isArray(status.application.body.routes) ? status.application.body.routes.filter(record6) : [];
|
|
9117
|
-
const requests = routes.reduce(
|
|
9118
|
-
(total, row) => total + numeric3(row.requests),
|
|
9119
|
-
0
|
|
9120
|
-
);
|
|
9121
|
-
const errors = routes.reduce(
|
|
9122
|
-
(total, row) => total + numeric3(row.errors),
|
|
9123
|
-
0
|
|
9124
|
-
);
|
|
9125
|
-
out.log(
|
|
9126
|
-
`application ${status.application.httpStatus} ${requests} requests ${errors} errors`
|
|
9127
|
-
);
|
|
9128
|
-
out.log(
|
|
9129
|
-
liveSyncLine(status.liveSync)
|
|
9130
|
-
);
|
|
9131
|
-
const canaryDurations = record6(status.canary.body.durationsMs) ? status.canary.body.durationsMs : {};
|
|
9132
|
-
out.log(
|
|
9133
|
-
`canary ${status.canary.httpStatus} ${String(status.canary.body.status ?? status.canary.body.error ?? "unavailable")} ${optionalNumeric(canaryDurations.publishToVisibleMs)} publish-to-visible`
|
|
9134
|
-
);
|
|
9135
|
-
const collectorIngest = record6(status.collector.body.ingest) ? status.collector.body.ingest : {};
|
|
9136
|
-
const collectorStorage = record6(collectorIngest.storage) ? collectorIngest.storage : {};
|
|
9137
|
-
out.log(
|
|
9138
|
-
`collector ${status.collector.httpStatus} ${String(status.collector.body.status ?? status.collector.body.error ?? "unavailable")} ${numeric3(collectorStorage.affectedPoints)} affected points`
|
|
9139
|
-
);
|
|
9140
|
-
const providerMetrics = record6(status.provider.body.metrics) ? status.provider.body.metrics : {};
|
|
9141
|
-
out.log(
|
|
9142
|
-
`cloudflare ${status.provider.httpStatus} ${String(status.provider.body.status ?? status.provider.body.error ?? "unavailable")} ${numeric3(providerMetrics.requests)} invocations ${numeric3(providerMetrics.errors)} runtime errors`
|
|
9143
|
-
);
|
|
9144
|
-
out.log(
|
|
9145
|
-
`verdict ${status.verdict.status} ${status.verdict.reasons.map((reason) => `${reason.source}:${reason.code}`).join(", ") || "all required signals healthy"}`
|
|
9146
|
-
);
|
|
9147
|
-
}
|
|
9148
|
-
function liveSyncLine(read3) {
|
|
9149
|
-
const performance = record6(read3.body.performance) ? read3.body.performance : {};
|
|
9150
|
-
const commitToSend = record6(performance.commitToSend) ? performance.commitToSend : {};
|
|
9151
|
-
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`;
|
|
9152
|
-
}
|
|
9153
|
-
function record6(value) {
|
|
9154
|
-
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
9155
|
-
}
|
|
9156
|
-
function numeric3(value) {
|
|
9157
|
-
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
9158
|
-
}
|
|
9159
|
-
function optionalNumeric(value) {
|
|
9160
|
-
return typeof value === "number" && Number.isFinite(value) ? `${value} ms` : "\u2014";
|
|
9161
|
-
}
|
|
9162
9205
|
|
|
9163
9206
|
// src/record.ts
|
|
9164
9207
|
import { appendFileSync } from "fs";
|
|
@@ -10750,4 +10793,4 @@ export {
|
|
|
10750
10793
|
exitCodeFor,
|
|
10751
10794
|
runCli
|
|
10752
10795
|
};
|
|
10753
|
-
//# sourceMappingURL=chunk-
|
|
10796
|
+
//# sourceMappingURL=chunk-MFC4TX6W.js.map
|