@odla-ai/cli 0.36.0 → 0.37.0
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 +46 -7
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-DBZQIMES.js → chunk-OWTIDSL5.js} +39 -8
- package/dist/chunk-OWTIDSL5.js.map +1 -0
- package/dist/{cli-BN6WLH5O.js → cli-QR44X5IB.js} +2 -2
- package/dist/index.cjs +38 -7
- 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-DBZQIMES.js.map +0 -1
- /package/dist/{cli-BN6WLH5O.js.map → cli-QR44X5IB.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
runCli
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-OWTIDSL5.js";
|
|
5
5
|
import {
|
|
6
6
|
exitCodeFor
|
|
7
7
|
} from "./chunk-UKLSRQ5J.js";
|
|
@@ -9,4 +9,4 @@ export {
|
|
|
9
9
|
exitCodeFor,
|
|
10
10
|
runCli
|
|
11
11
|
};
|
|
12
|
-
//# sourceMappingURL=cli-
|
|
12
|
+
//# sourceMappingURL=cli-QR44X5IB.js.map
|
package/dist/index.cjs
CHANGED
|
@@ -287,9 +287,10 @@ async function mintDeviceSession(platformUrl, credential2, doFetch) {
|
|
|
287
287
|
});
|
|
288
288
|
const body = await response2.json().catch(() => ({}));
|
|
289
289
|
if (!response2.ok || typeof body.token !== "string") {
|
|
290
|
-
const
|
|
290
|
+
const revocable = response2.status === 401 || response2.status === 403 || response2.status === 404;
|
|
291
|
+
const detail = body.error?.message ?? (response2.ok ? `registry returned ${response2.status} with no session token` : `registry returned ${response2.status}`);
|
|
291
292
|
throw new Error(
|
|
292
|
-
`device session failed: ${detail} (${response2.status}) \u2014 if this machine's enrollment was revoked or has expired, enroll it again in Studio
|
|
293
|
+
`device session failed: ${detail} (${response2.status})` + (revocable ? " \u2014 if this machine's enrollment was revoked or has expired, enroll it again in Studio" : "")
|
|
293
294
|
);
|
|
294
295
|
}
|
|
295
296
|
return { token: body.token, expiresAt: body.expiresAt ?? Date.now() };
|
|
@@ -637,6 +638,7 @@ var SCOPE_PURPOSE = {
|
|
|
637
638
|
"app:config:write": "apply or inspect one revision-bound configuration operation for an app you own",
|
|
638
639
|
"platform:runbook:write": "read and edit all of odla's operational runbooks, including admin-visible content",
|
|
639
640
|
"app:device:enroll": "enrol this machine so it can mint its own short-lived credentials without asking you again",
|
|
641
|
+
"platform:device:enroll:extended": "enrol this machine with a credential that outlives the seven-day owner ceiling \u2014 a durable secret on a machine you are vouching for",
|
|
640
642
|
"platform:ai:policy:write": "change System AI model routing",
|
|
641
643
|
"platform:ai:policy:read": "read System AI model routing",
|
|
642
644
|
"platform:ai:credential:write": "replace a stored AI provider key",
|
|
@@ -10413,7 +10415,7 @@ Usage:
|
|
|
10413
10415
|
odla-ai security run [target] --ack-redacted-source [--env dev] [--profile odla] [--fail-on high]
|
|
10414
10416
|
odla-ai security run [target] --self --ack-redacted-source
|
|
10415
10417
|
odla-ai provision [--live] [--config odla.config.mjs] [--email <odla-account>] [--request-grant] [--no-open] [--wait <seconds>] [--dry-run] [--push-secrets] [--rotate-o11y-token] [--write-dev-vars[=path]] [--yes]
|
|
10416
|
-
odla-ai device enroll [--app <id>[,<id>...]] [--name <label>] [--capability <c>[,<c>...]] [--email <odla-account>] [--no-open] [--json]
|
|
10418
|
+
odla-ai device enroll [--app <id>[,<id>...]] [--name <label>] [--capability <c>[,<c>...]] [--device-ttl <30d|6w|2y|forever>] [--email <odla-account>] [--no-open] [--json]
|
|
10417
10419
|
odla-ai device list [--email <odla-account>] [--json]
|
|
10418
10420
|
odla-ai device revoke <device-id> [--email <odla-account>] [--json]
|
|
10419
10421
|
odla-ai credentials list [--config odla.config.mjs] [--env dev] [--all] [--json]
|
|
@@ -13504,6 +13506,24 @@ function renderAdvisories(out, advisories, env = process.env) {
|
|
|
13504
13506
|
}
|
|
13505
13507
|
}
|
|
13506
13508
|
|
|
13509
|
+
// src/device-ttl.ts
|
|
13510
|
+
var OWNER_DEVICE_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
13511
|
+
var DAY_MS = 24 * 60 * 60 * 1e3;
|
|
13512
|
+
var UNITS = { d: DAY_MS, w: 7 * DAY_MS, y: 365 * DAY_MS };
|
|
13513
|
+
function parseDeviceTtl(raw) {
|
|
13514
|
+
if (raw === void 0 || raw === true) return void 0;
|
|
13515
|
+
const text3 = String(raw).trim().toLowerCase();
|
|
13516
|
+
if (!text3) return void 0;
|
|
13517
|
+
if (text3 === "forever" || text3 === "never") return 100 * 365 * DAY_MS;
|
|
13518
|
+
const match = /^(\d+)\s*([dwy])$/.exec(text3);
|
|
13519
|
+
if (!match) {
|
|
13520
|
+
throw new Error(
|
|
13521
|
+
`--device-ttl expects a duration like 30d, 6w, 2y, or "forever" (got "${raw}")`
|
|
13522
|
+
);
|
|
13523
|
+
}
|
|
13524
|
+
return Number(match[1]) * UNITS[match[2]];
|
|
13525
|
+
}
|
|
13526
|
+
|
|
13507
13527
|
// src/device-command.ts
|
|
13508
13528
|
var import_node_fs18 = require("fs");
|
|
13509
13529
|
var import_node_path17 = require("path");
|
|
@@ -13523,7 +13543,17 @@ async function enroll(parsed, deps, cfg, doFetch, out, json) {
|
|
|
13523
13543
|
const name = stringOpt(parsed.options.name) ?? defaultDeviceName();
|
|
13524
13544
|
const apps = (stringOpt(parsed.options.app) ?? cfg.app.id).split(",").map((id2) => id2.trim()).filter(Boolean);
|
|
13525
13545
|
if (apps.length === 0) throw new Error("device enroll needs --app <id>[,<id>\u2026]");
|
|
13526
|
-
const
|
|
13546
|
+
const deviceTtlMs = parseDeviceTtl(parsed.options["device-ttl"]);
|
|
13547
|
+
const extended = deviceTtlMs !== void 0 && deviceTtlMs > OWNER_DEVICE_TTL_MS;
|
|
13548
|
+
const token = await scopedToken2(
|
|
13549
|
+
parsed,
|
|
13550
|
+
deps,
|
|
13551
|
+
cfg,
|
|
13552
|
+
doFetch,
|
|
13553
|
+
out,
|
|
13554
|
+
`odla CLI (enroll ${name})`,
|
|
13555
|
+
extended ? "platform:device:enroll:extended" : "app:device:enroll"
|
|
13556
|
+
);
|
|
13527
13557
|
const response2 = await doFetch(`${cfg.platformUrl}/registry/devices`, {
|
|
13528
13558
|
method: "POST",
|
|
13529
13559
|
headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
|
|
@@ -13531,7 +13561,8 @@ async function enroll(parsed, deps, cfg, doFetch, out, json) {
|
|
|
13531
13561
|
name,
|
|
13532
13562
|
platform: import_node_process15.default.platform,
|
|
13533
13563
|
appIds: apps,
|
|
13534
|
-
...parsed.options.capability ? { capabilities: String(parsed.options.capability).split(",").map((c) => c.trim()).filter(Boolean) } : {}
|
|
13564
|
+
...parsed.options.capability ? { capabilities: String(parsed.options.capability).split(",").map((c) => c.trim()).filter(Boolean) } : {},
|
|
13565
|
+
...deviceTtlMs === void 0 ? {} : { deviceTtlMs }
|
|
13535
13566
|
})
|
|
13536
13567
|
});
|
|
13537
13568
|
const body = await response2.json().catch(() => ({}));
|
|
@@ -13584,12 +13615,12 @@ async function revoke(parsed, deps, cfg, doFetch, out, json) {
|
|
|
13584
13615
|
out.error(`device: revoked ${deviceId}; every credential it minted is revoked with it`);
|
|
13585
13616
|
if (json) out.log(JSON.stringify({ deviceId, revoked: true }, null, 2));
|
|
13586
13617
|
}
|
|
13587
|
-
async function scopedToken2(parsed, deps, cfg, doFetch, out, label) {
|
|
13618
|
+
async function scopedToken2(parsed, deps, cfg, doFetch, out, label, scope = "app:device:enroll") {
|
|
13588
13619
|
const { credentials } = await resolveOperatorContext(parsed, { allowMissingConfig: true });
|
|
13589
13620
|
const scopedTokenFile = credentials.scopedTokenFile;
|
|
13590
13621
|
return getScopedPlatformToken({
|
|
13591
13622
|
platform: cfg.platformUrl,
|
|
13592
|
-
scope
|
|
13623
|
+
scope,
|
|
13593
13624
|
email: stringOpt(parsed.options.email),
|
|
13594
13625
|
label,
|
|
13595
13626
|
fetch: doFetch,
|