@odla-ai/cli 0.26.1 → 0.26.2
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 +0 -19
- package/dist/bin.cjs +58 -216
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-ZAZBUURZ.js → chunk-MBZXWPZP.js} +57 -215
- package/dist/chunk-MBZXWPZP.js.map +1 -0
- package/dist/index.cjs +58 -216
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-ZAZBUURZ.js.map +0 -1
package/README.md
CHANGED
|
@@ -156,25 +156,6 @@ therefore compares that verified expectation with the Worker answering now and
|
|
|
156
156
|
reports `matched`, `drifted`, or `unknown`; an empty or unavailable receipt
|
|
157
157
|
ledger degrades instead of silently treating observed health as intended state.
|
|
158
158
|
|
|
159
|
-
Platform maintainers can rotate the built-in Discussion responder without
|
|
160
|
-
minting an unrestricted app key or exposing the replacement in argv/output:
|
|
161
|
-
|
|
162
|
-
```bash
|
|
163
|
-
npx @odla-ai/cli platform chat-credentials rotate \
|
|
164
|
-
--wrangler-config packages/chat-agent/wrangler.jsonc \
|
|
165
|
-
--expected-version <deployed-chat-version-id> \
|
|
166
|
-
--email <odla-admin-account> \
|
|
167
|
-
--yes --json
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
The command requests only `platform:chat:credential:write`, mints an
|
|
171
|
-
`agent_odla` key restricted to the Discussion namespaces and write envelope,
|
|
172
|
-
pipes the nested `ODLA_BOT_TOKENS` map to Wrangler over stdin, and succeeds only
|
|
173
|
-
after the service-binding health bridge advances from the pre-rotation Worker
|
|
174
|
-
version to a healthy secret-change deployment. `--expected-version` fences the
|
|
175
|
-
pre-rotation version before any credential is minted. Superseded keys are
|
|
176
|
-
revoked separately after that health proof.
|
|
177
|
-
|
|
178
159
|
For repository-managed settings, compare checked-in intent with the live
|
|
179
160
|
owner-visible Registry projection before provisioning:
|
|
180
161
|
|
package/dist/bin.cjs
CHANGED
|
@@ -492,7 +492,6 @@ function audienceBoundEnvToken(token, platform) {
|
|
|
492
492
|
}
|
|
493
493
|
var SCOPE_PURPOSE = {
|
|
494
494
|
"platform:status:read": "read the platform fleet health and deployment snapshot",
|
|
495
|
-
"platform:chat:credential:write": "rotate the built-in Discussion responder credential",
|
|
496
495
|
"app:config:read": "compare checked-in intent with an exact-id app Registry configuration",
|
|
497
496
|
"app:config:write": "apply or inspect one revision-bound configuration operation for an app you own",
|
|
498
497
|
"platform:runbook:write": "add or edit odla's operational runbooks",
|
|
@@ -2743,9 +2742,9 @@ function canonicalValue(value2) {
|
|
|
2743
2742
|
}
|
|
2744
2743
|
if (Array.isArray(value2)) return value2.map(canonicalValue);
|
|
2745
2744
|
if (value2 && typeof value2 === "object") {
|
|
2746
|
-
const
|
|
2745
|
+
const record10 = value2;
|
|
2747
2746
|
return Object.fromEntries(
|
|
2748
|
-
Object.keys(
|
|
2747
|
+
Object.keys(record10).filter((key) => record10[key] !== void 0).sort().map((key) => [key, canonicalValue(record10[key])])
|
|
2749
2748
|
);
|
|
2750
2749
|
}
|
|
2751
2750
|
throw new TypeError("canonical JSON rejects unsupported values");
|
|
@@ -5262,8 +5261,8 @@ async function materializeGitTree(source, commitSha, options = {}) {
|
|
|
5262
5261
|
const maxFiles = options.maxFiles ?? 2e4;
|
|
5263
5262
|
const maxBytes = options.maxBytes ?? 512 * 1024 * 1024;
|
|
5264
5263
|
const inventory = (await gitOutput(sourceDir, ["ls-tree", "-rz", commitSha], 16 * 1024 * 1024)).toString("utf8").split("\0").filter(Boolean);
|
|
5265
|
-
const entries = inventory.flatMap((
|
|
5266
|
-
const match = /^(100644|100755) blob ([0-9a-f]{40,64})\t([\s\S]+)$/.exec(
|
|
5264
|
+
const entries = inventory.flatMap((record10) => {
|
|
5265
|
+
const match = /^(100644|100755) blob ([0-9a-f]{40,64})\t([\s\S]+)$/.exec(record10);
|
|
5267
5266
|
return match && allowedWorkspacePath(match[3]) ? [{ mode: match[1], hash: match[2], path: match[3] }] : [];
|
|
5268
5267
|
});
|
|
5269
5268
|
if (entries.length > maxFiles) throw new Error(`workspace exceeds ${maxFiles} files`);
|
|
@@ -5511,8 +5510,8 @@ function normalize(value2) {
|
|
|
5511
5510
|
if (Array.isArray(value2)) return value2.map(normalize);
|
|
5512
5511
|
if (value2 instanceof Uint8Array) return { $bytes: [...value2] };
|
|
5513
5512
|
if (typeof value2 === "object") {
|
|
5514
|
-
const
|
|
5515
|
-
return Object.fromEntries(Object.keys(
|
|
5513
|
+
const record10 = value2;
|
|
5514
|
+
return Object.fromEntries(Object.keys(record10).filter((key) => record10[key] !== void 0).sort().map((key) => [key, normalize(record10[key])]));
|
|
5516
5515
|
}
|
|
5517
5516
|
throw new CamelError("state_conflict", "Canonical JSON rejects unsupported values.");
|
|
5518
5517
|
}
|
|
@@ -8572,7 +8571,6 @@ Usage:
|
|
|
8572
8571
|
odla-ai context remove <name> --yes [--json]
|
|
8573
8572
|
odla-ai o11y status [--app <id>] [--context <name>] [--platform https://odla.ai] [--env prod] [--minutes 60] [--json]
|
|
8574
8573
|
odla-ai platform status [--context <name>] [--platform https://odla.ai] [--email <odla-account>] [--json]
|
|
8575
|
-
odla-ai platform chat-credentials rotate [--context <name>] [--email <odla-account>] [--wrangler-config <path>] [--expected-version <id>] [--json] --yes
|
|
8576
8574
|
odla-ai whoami [--context <name>] [--platform https://odla.ai] [--json]
|
|
8577
8575
|
odla-ai runbook ask "<question>" [--app <id>] [--all] [--json]
|
|
8578
8576
|
odla-ai runbook search "<question>" [--app <id>] [--all] [--limit <n>] [--json]
|
|
@@ -9405,8 +9403,8 @@ async function pmAdd(ctx, entity, parsed) {
|
|
|
9405
9403
|
emit2(ctx, res, () => ctx.out.log(`created ${entity} ${res.id}`));
|
|
9406
9404
|
}
|
|
9407
9405
|
async function pmGet(ctx, entity, id) {
|
|
9408
|
-
const { record:
|
|
9409
|
-
emit2(ctx,
|
|
9406
|
+
const { record: record10 } = await pmRequest(ctx, "GET", `/${entity}/${encodeURIComponent(id)}`);
|
|
9407
|
+
emit2(ctx, record10, () => printRecord(ctx, entity, record10));
|
|
9410
9408
|
}
|
|
9411
9409
|
async function pmSet(ctx, entity, id, parsed) {
|
|
9412
9410
|
const patch2 = collectEntityFields(entity, parsed, true);
|
|
@@ -9451,9 +9449,9 @@ async function pmHandoff(ctx, parsed) {
|
|
|
9451
9449
|
]);
|
|
9452
9450
|
const handoff = {
|
|
9453
9451
|
appId,
|
|
9454
|
-
unmetGoals: goals.filter((
|
|
9455
|
-
activeTasks: tasks.filter((
|
|
9456
|
-
openBugs: bugs.filter((
|
|
9452
|
+
unmetGoals: goals.filter((record10) => record10.status !== "met"),
|
|
9453
|
+
activeTasks: tasks.filter((record10) => record10.column !== "done"),
|
|
9454
|
+
openBugs: bugs.filter((record10) => record10.status !== "fixed" && record10.status !== "wontfix")
|
|
9457
9455
|
};
|
|
9458
9456
|
const result = {
|
|
9459
9457
|
...handoff,
|
|
@@ -9472,10 +9470,10 @@ async function pmHandoff(ctx, parsed) {
|
|
|
9472
9470
|
]) {
|
|
9473
9471
|
ctx.out.log(`${label}:`);
|
|
9474
9472
|
if (!records.length) ctx.out.log("- (none)");
|
|
9475
|
-
else for (const
|
|
9473
|
+
else for (const record10 of records) printRecord(
|
|
9476
9474
|
ctx,
|
|
9477
9475
|
label === "unmet goals" ? "goal" : label === "active tasks" ? "task" : "bug",
|
|
9478
|
-
|
|
9476
|
+
record10
|
|
9479
9477
|
);
|
|
9480
9478
|
}
|
|
9481
9479
|
});
|
|
@@ -9666,167 +9664,12 @@ function age(input) {
|
|
|
9666
9664
|
return `${Math.round(input / 6e4)}m`;
|
|
9667
9665
|
}
|
|
9668
9666
|
|
|
9669
|
-
// src/platform-chat-credential-command.ts
|
|
9670
|
-
var import_node_process10 = __toESM(require("process"), 1);
|
|
9671
|
-
async function rotatePlatformChatCredential(parsed, deps) {
|
|
9672
|
-
assertArgs(
|
|
9673
|
-
parsed,
|
|
9674
|
-
[
|
|
9675
|
-
"config",
|
|
9676
|
-
"context",
|
|
9677
|
-
"platform",
|
|
9678
|
-
"token",
|
|
9679
|
-
"email",
|
|
9680
|
-
"open",
|
|
9681
|
-
"json",
|
|
9682
|
-
"yes",
|
|
9683
|
-
"wrangler-config",
|
|
9684
|
-
"expected-version"
|
|
9685
|
-
],
|
|
9686
|
-
3
|
|
9687
|
-
);
|
|
9688
|
-
if (parsed.options.yes !== true) {
|
|
9689
|
-
throw new Error(
|
|
9690
|
-
"platform chat-credentials rotate changes the production chat secret; pass --yes"
|
|
9691
|
-
);
|
|
9692
|
-
}
|
|
9693
|
-
const context = await resolveOperatorContext(parsed, {
|
|
9694
|
-
allowMissingConfig: true
|
|
9695
|
-
});
|
|
9696
|
-
const platform = context.platform.value;
|
|
9697
|
-
const doFetch = deps.fetch ?? fetch;
|
|
9698
|
-
const out = deps.stdout ?? console;
|
|
9699
|
-
const run = deps.runner ?? defaultRunner;
|
|
9700
|
-
const cwd = import_node_process10.default.cwd();
|
|
9701
|
-
const wranglerConfig = stringOpt(parsed.options["wrangler-config"]) ?? "packages/chat-agent/wrangler.jsonc";
|
|
9702
|
-
if (!await wranglerLoggedIn(run, cwd)) {
|
|
9703
|
-
throw new Error(
|
|
9704
|
-
'Wrangler is not authenticated; run "npx wrangler login" and retry'
|
|
9705
|
-
);
|
|
9706
|
-
}
|
|
9707
|
-
const priorHealth = await doFetch(`${platform}/health/services/chat`);
|
|
9708
|
-
const priorVersion = priorHealth.headers.get("x-odla-worker-version-id");
|
|
9709
|
-
await priorHealth.body?.cancel().catch(() => {
|
|
9710
|
-
});
|
|
9711
|
-
if (!priorVersion) {
|
|
9712
|
-
throw new Error(
|
|
9713
|
-
"chat health did not identify its current Worker version; refusing to rotate"
|
|
9714
|
-
);
|
|
9715
|
-
}
|
|
9716
|
-
const expectedVersion = stringOpt(parsed.options["expected-version"]);
|
|
9717
|
-
if (expectedVersion && priorVersion !== expectedVersion) {
|
|
9718
|
-
throw new Error(
|
|
9719
|
-
`chat health answered from version ${priorVersion}; expected ${expectedVersion}`
|
|
9720
|
-
);
|
|
9721
|
-
}
|
|
9722
|
-
const token = await resolveAdminPlatformToken({
|
|
9723
|
-
platform,
|
|
9724
|
-
scope: "platform:chat:credential:write",
|
|
9725
|
-
token: stringOpt(parsed.options.token),
|
|
9726
|
-
tokenFile: context.credentials.scopedTokenFile,
|
|
9727
|
-
email: stringOpt(parsed.options.email),
|
|
9728
|
-
open: parsed.options.open === false ? false : parsed.options.open === true ? true : void 0,
|
|
9729
|
-
fetch: doFetch,
|
|
9730
|
-
stdout: out,
|
|
9731
|
-
openApprovalUrl: deps.openUrl,
|
|
9732
|
-
label: "odla CLI (rotate built-in Discussion responder)"
|
|
9733
|
-
});
|
|
9734
|
-
const mintedResponse = await doFetch(
|
|
9735
|
-
`${platform}/registry/platform/chat-credentials/rotate`,
|
|
9736
|
-
{
|
|
9737
|
-
method: "POST",
|
|
9738
|
-
headers: { authorization: `Bearer ${token}` }
|
|
9739
|
-
}
|
|
9740
|
-
);
|
|
9741
|
-
const minted = await mintedResponse.json().catch(() => null);
|
|
9742
|
-
if (!mintedResponse.ok) {
|
|
9743
|
-
throw new Error(
|
|
9744
|
-
`mint Discussion credential failed (HTTP ${mintedResponse.status}): ${apiMessage(minted)}`
|
|
9745
|
-
);
|
|
9746
|
-
}
|
|
9747
|
-
if (!isPlatformChatCredential(minted)) {
|
|
9748
|
-
throw new Error(
|
|
9749
|
-
"platform returned an invalid odla.platform-chat-credential/v1 envelope"
|
|
9750
|
-
);
|
|
9751
|
-
}
|
|
9752
|
-
const put = await wranglerPutSecret(run, {
|
|
9753
|
-
name: "ODLA_BOT_TOKENS",
|
|
9754
|
-
value: JSON.stringify({
|
|
9755
|
-
[minted.appId]: { [minted.principalId]: minted.key }
|
|
9756
|
-
}),
|
|
9757
|
-
configPath: wranglerConfig,
|
|
9758
|
-
cwd
|
|
9759
|
-
});
|
|
9760
|
-
if (put.code !== 0) {
|
|
9761
|
-
throw new Error(
|
|
9762
|
-
"Wrangler could not replace ODLA_BOT_TOKENS; the new scoped key was not activated"
|
|
9763
|
-
);
|
|
9764
|
-
}
|
|
9765
|
-
const version = await waitForRotatedChatHealth({
|
|
9766
|
-
fetch: doFetch,
|
|
9767
|
-
platform,
|
|
9768
|
-
priorVersion,
|
|
9769
|
-
wait: deps.pollWait
|
|
9770
|
-
});
|
|
9771
|
-
const result = {
|
|
9772
|
-
schemaVersion: "odla.platform-chat-credential-rotation/v1",
|
|
9773
|
-
appId: minted.appId,
|
|
9774
|
-
appIncarnation: minted.appIncarnation,
|
|
9775
|
-
principalId: minted.principalId,
|
|
9776
|
-
health: { ok: true, service: "odla-chat-agent", version }
|
|
9777
|
-
};
|
|
9778
|
-
if (parsed.options.json === true) {
|
|
9779
|
-
out.log(JSON.stringify(result, null, 2));
|
|
9780
|
-
} else {
|
|
9781
|
-
out.log(
|
|
9782
|
-
`rotated ${result.appId} ${result.principalId} ${result.health.version}`
|
|
9783
|
-
);
|
|
9784
|
-
}
|
|
9785
|
-
}
|
|
9786
|
-
async function waitForRotatedChatHealth(opts) {
|
|
9787
|
-
const wait2 = opts.wait ?? ((milliseconds) => new Promise((resolve12) => setTimeout(resolve12, milliseconds)));
|
|
9788
|
-
let lastStatus = 0;
|
|
9789
|
-
let lastVersion = null;
|
|
9790
|
-
let lastError = "private_service_unready";
|
|
9791
|
-
for (let attempt = 0; attempt < 60; attempt++) {
|
|
9792
|
-
const response2 = await opts.fetch(
|
|
9793
|
-
`${opts.platform}/health/services/chat`
|
|
9794
|
-
);
|
|
9795
|
-
const body = await response2.json().catch(() => null);
|
|
9796
|
-
const version = response2.headers.get("x-odla-worker-version-id");
|
|
9797
|
-
if (response2.ok && record7(body) && body.ok === true && body.service === "odla-chat-agent" && version && version !== opts.priorVersion) {
|
|
9798
|
-
return version;
|
|
9799
|
-
}
|
|
9800
|
-
lastStatus = response2.status;
|
|
9801
|
-
lastVersion = version;
|
|
9802
|
-
lastError = record7(body) && typeof body.error === "string" ? body.error : "private_service_unready";
|
|
9803
|
-
if (attempt < 59) await wait2(5e3);
|
|
9804
|
-
}
|
|
9805
|
-
throw new Error(
|
|
9806
|
-
`chat health did not converge on the rotated Worker deployment (HTTP ${lastStatus}, version ${lastVersion ?? "unknown"}, ${lastError})`
|
|
9807
|
-
);
|
|
9808
|
-
}
|
|
9809
|
-
function isPlatformChatCredential(value2) {
|
|
9810
|
-
return record7(value2) && value2.schemaVersion === "odla.platform-chat-credential/v1" && value2.appId === "odla-pm" && typeof value2.appIncarnation === "string" && value2.appIncarnation.length > 0 && value2.principalId === "agent_odla" && typeof value2.key === "string" && value2.key.startsWith("odla_sk_");
|
|
9811
|
-
}
|
|
9812
|
-
function apiMessage(value2) {
|
|
9813
|
-
if (!record7(value2)) return "request failed";
|
|
9814
|
-
const error = record7(value2.error) ? value2.error : value2;
|
|
9815
|
-
return typeof error.message === "string" ? error.message : typeof error.code === "string" ? error.code : "request failed";
|
|
9816
|
-
}
|
|
9817
|
-
function record7(value2) {
|
|
9818
|
-
return !!value2 && typeof value2 === "object" && !Array.isArray(value2);
|
|
9819
|
-
}
|
|
9820
|
-
|
|
9821
9667
|
// src/platform-command.ts
|
|
9822
9668
|
async function platformCommand(parsed, deps = {}) {
|
|
9823
9669
|
const action2 = parsed.positionals[1];
|
|
9824
9670
|
if (action2 === "status") {
|
|
9825
9671
|
return platformStatus(parsed, deps);
|
|
9826
9672
|
}
|
|
9827
|
-
if (action2 === "chat-credentials" && parsed.positionals[2] === "rotate") {
|
|
9828
|
-
return rotatePlatformChatCredential(parsed, deps);
|
|
9829
|
-
}
|
|
9830
9673
|
throw new Error(
|
|
9831
9674
|
`unknown platform action "${[
|
|
9832
9675
|
action2,
|
|
@@ -9864,7 +9707,7 @@ async function platformStatus(parsed, deps) {
|
|
|
9864
9707
|
const body = await response2.json().catch(() => null);
|
|
9865
9708
|
if (!response2.ok) {
|
|
9866
9709
|
throw new Error(
|
|
9867
|
-
`read platform status failed (HTTP ${response2.status}): ${
|
|
9710
|
+
`read platform status failed (HTTP ${response2.status}): ${apiMessage(body)}`
|
|
9868
9711
|
);
|
|
9869
9712
|
}
|
|
9870
9713
|
if (!isPlatformStatus(body)) {
|
|
@@ -9877,17 +9720,17 @@ async function platformStatus(parsed, deps) {
|
|
|
9877
9720
|
}
|
|
9878
9721
|
}
|
|
9879
9722
|
function isPlatformStatus(value2) {
|
|
9880
|
-
if (!
|
|
9881
|
-
if (!
|
|
9882
|
-
if (!
|
|
9723
|
+
if (!record7(value2) || value2.schemaVersion !== "odla.platform-status/v1") return false;
|
|
9724
|
+
if (!record7(value2.verdict) || !Array.isArray(value2.verdict.reasons)) return false;
|
|
9725
|
+
if (!record7(value2.catalog) || !record7(value2.summary)) return false;
|
|
9883
9726
|
return Array.isArray(value2.services) && Array.isArray(value2.nextActions);
|
|
9884
9727
|
}
|
|
9885
|
-
function
|
|
9886
|
-
if (!
|
|
9887
|
-
const error =
|
|
9728
|
+
function apiMessage(value2) {
|
|
9729
|
+
if (!record7(value2)) return "request failed";
|
|
9730
|
+
const error = record7(value2.error) ? value2.error : value2;
|
|
9888
9731
|
return typeof error.message === "string" ? error.message : typeof error.code === "string" ? error.code : "request failed";
|
|
9889
9732
|
}
|
|
9890
|
-
function
|
|
9733
|
+
function record7(value2) {
|
|
9891
9734
|
return !!value2 && typeof value2 === "object" && !Array.isArray(value2);
|
|
9892
9735
|
}
|
|
9893
9736
|
|
|
@@ -9928,7 +9771,7 @@ function statusVerdict(reads) {
|
|
|
9928
9771
|
severity: "degraded"
|
|
9929
9772
|
});
|
|
9930
9773
|
}
|
|
9931
|
-
const performance =
|
|
9774
|
+
const performance = record8(reads.liveSync.body.performance) ? reads.liveSync.body.performance : null;
|
|
9932
9775
|
if (performance?.status === "unavailable") {
|
|
9933
9776
|
reasons.push({
|
|
9934
9777
|
source: "liveSync",
|
|
@@ -10009,7 +9852,7 @@ function statusVerdict(reads) {
|
|
|
10009
9852
|
reasons
|
|
10010
9853
|
};
|
|
10011
9854
|
}
|
|
10012
|
-
function
|
|
9855
|
+
function record8(value2) {
|
|
10013
9856
|
return Boolean(value2) && typeof value2 === "object" && !Array.isArray(value2);
|
|
10014
9857
|
}
|
|
10015
9858
|
function numeric2(value2) {
|
|
@@ -10037,7 +9880,7 @@ function printO11yStatus(status, out) {
|
|
|
10037
9880
|
out.log(
|
|
10038
9881
|
`o11y status ${status.scope.appId}/${status.scope.env} (${status.scope.minutes}m)`
|
|
10039
9882
|
);
|
|
10040
|
-
const routes = Array.isArray(status.application.body.routes) ? status.application.body.routes.filter(
|
|
9883
|
+
const routes = Array.isArray(status.application.body.routes) ? status.application.body.routes.filter(record9) : [];
|
|
10041
9884
|
const requests = routes.reduce(
|
|
10042
9885
|
(total, row) => total + numeric3(row.requests),
|
|
10043
9886
|
0
|
|
@@ -10049,39 +9892,39 @@ function printO11yStatus(status, out) {
|
|
|
10049
9892
|
out.log(
|
|
10050
9893
|
`application ${status.application.httpStatus} ${requests} requests ${errors} errors`
|
|
10051
9894
|
);
|
|
10052
|
-
const versions = Array.isArray(status.applicationVersions.body.rows) ? status.applicationVersions.body.rows.filter(
|
|
9895
|
+
const versions = Array.isArray(status.applicationVersions.body.rows) ? status.applicationVersions.body.rows.filter(record9) : [];
|
|
10053
9896
|
out.log(
|
|
10054
9897
|
`application-versions ${status.applicationVersions.httpStatus} ${versions.length ? versions.slice(0, 5).map(
|
|
10055
9898
|
(row) => `${String(row.value || "(unattributed)")}:${numeric3(row.requests)}`
|
|
10056
9899
|
).join(", ") : "none observed"}`
|
|
10057
9900
|
);
|
|
10058
9901
|
out.log(liveSyncLine(status.liveSync));
|
|
10059
|
-
const canaryDurations =
|
|
9902
|
+
const canaryDurations = record9(status.canary.body.durationsMs) ? status.canary.body.durationsMs : {};
|
|
10060
9903
|
out.log(
|
|
10061
9904
|
`canary ${status.canary.httpStatus} ${String(status.canary.body.status ?? status.canary.body.error ?? "unavailable")} ${optionalNumeric(canaryDurations.publishToVisibleMs)} publish-to-visible`
|
|
10062
9905
|
);
|
|
10063
|
-
const collectorIngest =
|
|
10064
|
-
const collectorStorage =
|
|
9906
|
+
const collectorIngest = record9(status.collector.body.ingest) ? status.collector.body.ingest : {};
|
|
9907
|
+
const collectorStorage = record9(collectorIngest.storage) ? collectorIngest.storage : {};
|
|
10065
9908
|
out.log(
|
|
10066
9909
|
`collector ${status.collector.httpStatus} ${String(status.collector.body.status ?? status.collector.body.error ?? "unavailable")} ${numeric3(collectorStorage.affectedPoints)} affected points`
|
|
10067
9910
|
);
|
|
10068
|
-
const providerMetrics =
|
|
10069
|
-
const providerCapacity =
|
|
10070
|
-
const workerMemory =
|
|
9911
|
+
const providerMetrics = record9(status.provider.body.metrics) ? status.provider.body.metrics : {};
|
|
9912
|
+
const providerCapacity = record9(status.provider.body.capacity) ? status.provider.body.capacity : {};
|
|
9913
|
+
const workerMemory = record9(providerCapacity.memory) ? providerCapacity.memory : {};
|
|
10071
9914
|
out.log(
|
|
10072
9915
|
`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`
|
|
10073
9916
|
);
|
|
10074
9917
|
for (const line of providerCapacityLines(status.providerCapacity)) {
|
|
10075
9918
|
out.log(line);
|
|
10076
9919
|
}
|
|
10077
|
-
const coverage =
|
|
10078
|
-
const coverageCounts =
|
|
10079
|
-
const coverageBudget =
|
|
9920
|
+
const coverage = record9(status.providerReconciliation.body.comparison) ? status.providerReconciliation.body.comparison : {};
|
|
9921
|
+
const coverageCounts = record9(status.providerReconciliation.body.counts) ? status.providerReconciliation.body.counts : {};
|
|
9922
|
+
const coverageBudget = record9(status.providerReconciliation.body.budget) ? status.providerReconciliation.body.budget : {};
|
|
10080
9923
|
out.log(
|
|
10081
9924
|
`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`
|
|
10082
9925
|
);
|
|
10083
9926
|
const providerPoints = Array.isArray(status.providerHistory.body.points) ? status.providerHistory.body.points.length : 0;
|
|
10084
|
-
const providerFreshness =
|
|
9927
|
+
const providerFreshness = record9(status.providerHistory.body.freshness) ? status.providerHistory.body.freshness : {};
|
|
10085
9928
|
out.log(
|
|
10086
9929
|
`cloudflare-history ${status.providerHistory.httpStatus} ${String(status.providerHistory.body.status ?? status.providerHistory.body.error ?? "unavailable")} ${providerPoints} snapshots ${optionalAge(providerFreshness.ageMs)} old`
|
|
10087
9930
|
);
|
|
@@ -10090,17 +9933,17 @@ function printO11yStatus(status, out) {
|
|
|
10090
9933
|
);
|
|
10091
9934
|
}
|
|
10092
9935
|
function providerCapacityLines(read3) {
|
|
10093
|
-
const resources =
|
|
10094
|
-
const durableObjects =
|
|
10095
|
-
const periodic =
|
|
10096
|
-
const storage =
|
|
10097
|
-
const d1 =
|
|
10098
|
-
const d1Activity =
|
|
10099
|
-
const d1Storage =
|
|
10100
|
-
const d1Latency =
|
|
10101
|
-
const r2 =
|
|
10102
|
-
const r2Operations =
|
|
10103
|
-
const r2Storage =
|
|
9936
|
+
const resources = record9(read3.body.resources) ? read3.body.resources : {};
|
|
9937
|
+
const durableObjects = record9(resources.durableObjects) ? resources.durableObjects : {};
|
|
9938
|
+
const periodic = record9(durableObjects.periodic) ? durableObjects.periodic : {};
|
|
9939
|
+
const storage = record9(durableObjects.sqliteStorage) ? durableObjects.sqliteStorage : {};
|
|
9940
|
+
const d1 = record9(resources.d1) ? resources.d1 : {};
|
|
9941
|
+
const d1Activity = record9(d1.activity) ? d1.activity : {};
|
|
9942
|
+
const d1Storage = record9(d1.storage) ? d1.storage : {};
|
|
9943
|
+
const d1Latency = record9(d1Activity.latency) ? d1Activity.latency : {};
|
|
9944
|
+
const r2 = record9(resources.r2) ? resources.r2 : {};
|
|
9945
|
+
const r2Operations = record9(r2.operations) ? r2.operations : {};
|
|
9946
|
+
const r2Storage = record9(r2.storage) ? r2.storage : {};
|
|
10104
9947
|
const status = String(
|
|
10105
9948
|
read3.body.status ?? read3.body.error ?? "unavailable"
|
|
10106
9949
|
);
|
|
@@ -10111,11 +9954,11 @@ function providerCapacityLines(read3) {
|
|
|
10111
9954
|
];
|
|
10112
9955
|
}
|
|
10113
9956
|
function liveSyncLine(read3) {
|
|
10114
|
-
const performance =
|
|
10115
|
-
const commitToSend =
|
|
9957
|
+
const performance = record9(read3.body.performance) ? read3.body.performance : {};
|
|
9958
|
+
const commitToSend = record9(performance.commitToSend) ? performance.commitToSend : {};
|
|
10116
9959
|
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`;
|
|
10117
9960
|
}
|
|
10118
|
-
function
|
|
9961
|
+
function record9(value2) {
|
|
10119
9962
|
return Boolean(value2) && typeof value2 === "object" && !Array.isArray(value2);
|
|
10120
9963
|
}
|
|
10121
9964
|
function numeric3(value2) {
|
|
@@ -10300,7 +10143,7 @@ async function read2(url, headers, doFetch) {
|
|
|
10300
10143
|
// src/provision.ts
|
|
10301
10144
|
var import_apps12 = require("@odla-ai/apps");
|
|
10302
10145
|
var import_ai3 = require("@odla-ai/ai");
|
|
10303
|
-
var
|
|
10146
|
+
var import_node_process10 = __toESM(require("process"), 1);
|
|
10304
10147
|
|
|
10305
10148
|
// src/integration-provision.ts
|
|
10306
10149
|
var import_db3 = require("@odla-ai/db");
|
|
@@ -10607,7 +10450,7 @@ ${env}: credentials are already saved; retry "odla-ai secrets push --env ${env}$
|
|
|
10607
10450
|
await provisionIntegrationSeeds(doFetch, cfg.dbEndpoint, tenantId, dbKey, database.integrations, env, out);
|
|
10608
10451
|
}
|
|
10609
10452
|
if (cfg.services.includes("ai") && cfg.ai?.provider && cfg.ai.keyEnv) {
|
|
10610
|
-
const key =
|
|
10453
|
+
const key = import_node_process10.default.env[cfg.ai.keyEnv];
|
|
10611
10454
|
if (key) {
|
|
10612
10455
|
const secretName = cfg.ai.secretName ?? defaultSecretName(cfg.ai.provider);
|
|
10613
10456
|
await (0, import_ai3.putSecret)({ endpoint: cfg.dbEndpoint, token, fetch: doFetch }, tenantId, secretName, key);
|
|
@@ -10649,7 +10492,7 @@ ${env}: credentials are already saved; retry "odla-ai secrets push --env ${env}$
|
|
|
10649
10492
|
|
|
10650
10493
|
// src/record.ts
|
|
10651
10494
|
var import_node_fs16 = require("fs");
|
|
10652
|
-
var
|
|
10495
|
+
var import_node_process11 = __toESM(require("process"), 1);
|
|
10653
10496
|
|
|
10654
10497
|
// src/surface.ts
|
|
10655
10498
|
var PM_ACTIONS = {
|
|
@@ -10717,8 +10560,7 @@ var COMMAND_SURFACE = {
|
|
|
10717
10560
|
o11y: { status: {} },
|
|
10718
10561
|
operations: { get: {}, wait: {} },
|
|
10719
10562
|
platform: {
|
|
10720
|
-
status: {}
|
|
10721
|
-
"chat-credentials": { rotate: {} }
|
|
10563
|
+
status: {}
|
|
10722
10564
|
},
|
|
10723
10565
|
pm: {
|
|
10724
10566
|
...PM_ENTITIES,
|
|
@@ -10798,7 +10640,7 @@ function invocationPath(words2) {
|
|
|
10798
10640
|
|
|
10799
10641
|
// src/record.ts
|
|
10800
10642
|
function recordInvocation(parsed) {
|
|
10801
|
-
const file =
|
|
10643
|
+
const file = import_node_process11.default.env.ODLA_CLI_RECORD;
|
|
10802
10644
|
if (!file) return;
|
|
10803
10645
|
try {
|
|
10804
10646
|
const entry = {
|
|
@@ -11470,9 +11312,9 @@ var import_node_child_process8 = require("child_process");
|
|
|
11470
11312
|
var import_node_fs20 = require("fs");
|
|
11471
11313
|
var import_node_os5 = require("os");
|
|
11472
11314
|
var import_node_path17 = require("path");
|
|
11473
|
-
var
|
|
11315
|
+
var import_node_process12 = __toESM(require("process"), 1);
|
|
11474
11316
|
var EDITOR_ENV = ["ODLA_EDITOR", "VISUAL", "EDITOR"];
|
|
11475
|
-
function resolveEditor(env =
|
|
11317
|
+
function resolveEditor(env = import_node_process12.default.env) {
|
|
11476
11318
|
for (const name of EDITOR_ENV) {
|
|
11477
11319
|
const value2 = env[name];
|
|
11478
11320
|
if (value2 && value2.trim()) return value2.trim();
|
|
@@ -11486,8 +11328,8 @@ function defaultRun(command, path) {
|
|
|
11486
11328
|
return result.status ?? 0;
|
|
11487
11329
|
}
|
|
11488
11330
|
function editText(initial, slug, deps = {}) {
|
|
11489
|
-
const env = deps.env ??
|
|
11490
|
-
const interactive = deps.interactive ?? (() => Boolean(
|
|
11331
|
+
const env = deps.env ?? import_node_process12.default.env;
|
|
11332
|
+
const interactive = deps.interactive ?? (() => Boolean(import_node_process12.default.stdin.isTTY));
|
|
11491
11333
|
const editor = resolveEditor(env);
|
|
11492
11334
|
if (!editor)
|
|
11493
11335
|
throw new Error(
|