@odla-ai/cli 0.39.0 → 0.40.1
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 +90 -35
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-PJ3RATDD.js → chunk-XUTMQMXZ.js} +86 -34
- package/dist/chunk-XUTMQMXZ.js.map +1 -0
- package/dist/{cli-ALS5OZPB.js → cli-WJSQEBDO.js} +2 -2
- package/dist/index.cjs +85 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/skills/odla/SKILL.md +6 -5
- package/skills/odla/references/agent-identity.md +1 -1
- package/dist/chunk-PJ3RATDD.js.map +0 -1
- /package/dist/{cli-ALS5OZPB.js.map → cli-WJSQEBDO.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-XUTMQMXZ.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-WJSQEBDO.js.map
|
package/dist/index.cjs
CHANGED
|
@@ -295,6 +295,11 @@ var import_node_os2 = require("os");
|
|
|
295
295
|
var import_node_path3 = require("path");
|
|
296
296
|
var import_node_process5 = __toESM(require("process"), 1);
|
|
297
297
|
function odlaHome(env = import_node_process5.default.env) {
|
|
298
|
+
if (env.VITEST && !env.ODLA_HOME) {
|
|
299
|
+
throw new Error(
|
|
300
|
+
"ODLA_HOME must be set under test \u2014 resolving the real ~/.odla would write to the developer's machine"
|
|
301
|
+
);
|
|
302
|
+
}
|
|
298
303
|
return env.ODLA_HOME ?? (0, import_node_path3.join)(env.HOME ?? (0, import_node_os2.homedir)(), ".odla");
|
|
299
304
|
}
|
|
300
305
|
function odlaHomePath(segments, env = import_node_process5.default.env) {
|
|
@@ -320,15 +325,15 @@ function pmContextFile(env) {
|
|
|
320
325
|
}
|
|
321
326
|
function adoptRepoLocalCache(legacyPath, machinePath, out) {
|
|
322
327
|
if (!(0, import_node_fs3.existsSync)(legacyPath) || legacyPath === machinePath) return false;
|
|
323
|
-
const
|
|
324
|
-
if (!
|
|
328
|
+
const superseded2 = (0, import_node_fs3.existsSync)(machinePath);
|
|
329
|
+
if (!superseded2) {
|
|
325
330
|
(0, import_node_fs3.mkdirSync)((0, import_node_path3.dirname)(machinePath), { recursive: true });
|
|
326
331
|
(0, import_node_fs3.copyFileSync)(legacyPath, machinePath);
|
|
327
332
|
(0, import_node_fs3.chmodSync)(machinePath, 384);
|
|
328
333
|
}
|
|
329
334
|
(0, import_node_fs3.rmSync)(legacyPath, { force: true });
|
|
330
335
|
out?.error(
|
|
331
|
-
|
|
336
|
+
superseded2 ? `auth: removed superseded ${legacyPath}; this machine's credentials live in ${odlaHome()}` : `auth: moved ${legacyPath} into ${machinePath}; credentials are per machine now, not per worktree`
|
|
332
337
|
);
|
|
333
338
|
return true;
|
|
334
339
|
}
|
|
@@ -465,7 +470,7 @@ function displayPath(path, rootDir = process.cwd()) {
|
|
|
465
470
|
}
|
|
466
471
|
|
|
467
472
|
// src/auth-guidance.ts
|
|
468
|
-
var ENROL_EVERYTHING = "npx odla-ai device enroll --
|
|
473
|
+
var ENROL_EVERYTHING = "npx odla-ai device enroll --no-open --wait 600";
|
|
469
474
|
var ENROL_PLATFORM_WIDE = "npx odla-ai device enroll --platform-wide --device-ttl 6w --no-open --wait 600";
|
|
470
475
|
function machineAuthState(audience, env = import_node_process6.default.env) {
|
|
471
476
|
const device = readDeviceCredential(audience, env);
|
|
@@ -491,6 +496,20 @@ function scopeInterruptionNotice(scope, state2) {
|
|
|
491
496
|
platformScope ? " A platform scope needs an administrator's approval; an app owner's cannot carry it." : " One approval, every app you own, and it rolls forward while you keep working."
|
|
492
497
|
].join("\n");
|
|
493
498
|
}
|
|
499
|
+
function narrowEnrollmentNotice(envelope) {
|
|
500
|
+
const everyApp = envelope.appIds.includes("*");
|
|
501
|
+
if (everyApp && envelope.capabilities.length > 0 && envelope.scopes.length > 0) return null;
|
|
502
|
+
const missing = [
|
|
503
|
+
everyApp ? null : `only ${envelope.appIds.length} app${envelope.appIds.length === 1 ? "" : "s"} \u2014 a new one will need a new approval`,
|
|
504
|
+
envelope.capabilities.length ? null : "no optional capabilities \u2014 app.manage, crm.read and code.session are not included",
|
|
505
|
+
envelope.scopes.length ? null : "no platform scopes \u2014 runbook edits, config plans and host connect will each ask again"
|
|
506
|
+
].filter(Boolean);
|
|
507
|
+
return [
|
|
508
|
+
`odla: this is a NARROW enrollment: ${missing.join("; ")}.`,
|
|
509
|
+
" That is a fine choice if you meant it. If you did not, drop the flags:",
|
|
510
|
+
` ${ENROL_EVERYTHING}`
|
|
511
|
+
].join("\n");
|
|
512
|
+
}
|
|
494
513
|
function lapseNotice(state2, now = Date.now()) {
|
|
495
514
|
if (!state2.enrolled || !state2.lapsesAt) return null;
|
|
496
515
|
const days = Math.floor((state2.lapsesAt - now) / (24 * 60 * 60 * 1e3));
|
|
@@ -2368,6 +2387,11 @@ async function authCommand(parsed, deps = {}) {
|
|
|
2368
2387
|
"auth login requires --email <odla-account> or ODLA_USER_EMAIL; confirm the signed-in odla email instead of using git or GitHub identity"
|
|
2369
2388
|
);
|
|
2370
2389
|
}
|
|
2390
|
+
if (!machineAuthState(platformAudience(cfg.platformUrl)).enrolled) {
|
|
2391
|
+
out.error("odla: this machine is not enrolled, so this approval buys one project until it lapses.");
|
|
2392
|
+
out.error(` For one approval that covers every app you own, with no repeats:
|
|
2393
|
+
${ENROL_EVERYTHING}`);
|
|
2394
|
+
}
|
|
2371
2395
|
const token = await getDeveloperToken(
|
|
2372
2396
|
cfg,
|
|
2373
2397
|
{
|
|
@@ -6251,7 +6275,7 @@ async function stageWorkspacePair(baselineSource, workspaceSource, options = {})
|
|
|
6251
6275
|
}
|
|
6252
6276
|
}
|
|
6253
6277
|
|
|
6254
|
-
// ../harness/dist/chunk-
|
|
6278
|
+
// ../harness/dist/chunk-L2T3LPEF.js
|
|
6255
6279
|
var import_crypto = require("crypto");
|
|
6256
6280
|
var import_promises5 = require("fs/promises");
|
|
6257
6281
|
var import_path5 = require("path");
|
|
@@ -6588,7 +6612,7 @@ function validateSnapshot(snapshot, limits) {
|
|
|
6588
6612
|
}
|
|
6589
6613
|
}
|
|
6590
6614
|
|
|
6591
|
-
// ../harness/dist/chunk-
|
|
6615
|
+
// ../harness/dist/chunk-L2T3LPEF.js
|
|
6592
6616
|
var import_child_process4 = require("child_process");
|
|
6593
6617
|
var import_promises6 = require("fs/promises");
|
|
6594
6618
|
var import_path6 = require("path");
|
|
@@ -6890,7 +6914,7 @@ function looksLikeDestination(value2) {
|
|
|
6890
6914
|
return /^(?:[a-z][a-z0-9+.-]*:\/\/|\/|\\\\)/i.test(text3) || /^[\w.-]+\.[a-z]{2,}(?:[/:]|$)/i.test(text3);
|
|
6891
6915
|
}
|
|
6892
6916
|
|
|
6893
|
-
// ../harness/dist/chunk-
|
|
6917
|
+
// ../harness/dist/chunk-L2T3LPEF.js
|
|
6894
6918
|
var import_promises10 = require("fs/promises");
|
|
6895
6919
|
var import_promises11 = require("fs/promises");
|
|
6896
6920
|
var import_path10 = require("path");
|
|
@@ -7158,7 +7182,7 @@ async function buildCodeGraph(input) {
|
|
|
7158
7182
|
return builder.build();
|
|
7159
7183
|
}
|
|
7160
7184
|
|
|
7161
|
-
// ../harness/dist/chunk-
|
|
7185
|
+
// ../harness/dist/chunk-L2T3LPEF.js
|
|
7162
7186
|
var import_crypto4 = require("crypto");
|
|
7163
7187
|
async function digestStagedWorkspace(root, limits) {
|
|
7164
7188
|
const files = [];
|
|
@@ -7417,6 +7441,7 @@ function parseSnapshot(value2) {
|
|
|
7417
7441
|
return { host, bindings, commands };
|
|
7418
7442
|
}
|
|
7419
7443
|
async function parseSource(value2) {
|
|
7444
|
+
const repositoryLimits = { maximumFiles: 1e5, maximumBytes: 80 * 1024 * 1024 };
|
|
7420
7445
|
const snapshot = record5(record5(value2)?.snapshot);
|
|
7421
7446
|
if (!snapshot || typeof snapshot.repository !== "string" || typeof snapshot.commitSha !== "string" || typeof snapshot.treeDigest !== "string" || !Array.isArray(snapshot.files)) throw invalid("source");
|
|
7422
7447
|
const files = snapshot.files.map((value22) => {
|
|
@@ -7438,12 +7463,12 @@ async function parseSource(value2) {
|
|
|
7438
7463
|
return { path: file.path, content: file.content };
|
|
7439
7464
|
});
|
|
7440
7465
|
const source2 = { repository: reference.repository, commitSha: reference.commitSha, files: referenceFiles };
|
|
7441
|
-
const referenceDigest = await digestCodeRepositorySnapshot(source2,
|
|
7466
|
+
const referenceDigest = await digestCodeRepositorySnapshot(source2, repositoryLimits);
|
|
7442
7467
|
if (referenceDigest !== reference.treeDigest) throw invalid("reference source digest");
|
|
7443
7468
|
references.push({ alias: reference.alias, ...source2, treeDigest: referenceDigest });
|
|
7444
7469
|
}
|
|
7445
7470
|
const source = { repository: snapshot.repository, commitSha: snapshot.commitSha, files };
|
|
7446
|
-
const digest = await digestCodeRepositorySnapshot(source,
|
|
7471
|
+
const digest = await digestCodeRepositorySnapshot(source, repositoryLimits);
|
|
7447
7472
|
if (digest !== snapshot.treeDigest) throw invalid("source digest");
|
|
7448
7473
|
return { ...source, treeDigest: digest, ...references.length ? { references } : {} };
|
|
7449
7474
|
}
|
|
@@ -8095,8 +8120,11 @@ async function prepareRuntimeLocalSource(input) {
|
|
|
8095
8120
|
}
|
|
8096
8121
|
var RESERVED2 = /* @__PURE__ */ new Set([".git", ".odla", ".wrangler", "node_modules", "dist", "coverage"]);
|
|
8097
8122
|
var SECRET2 = /^(?:\.env(?:\..+)?|\.dev\.vars|credentials(?:\..+)?\.json|dev-token(?:\..+)?\.json)$/i;
|
|
8123
|
+
var SOURCE_MAX_FILES = 1e5;
|
|
8124
|
+
var SOURCE_MAX_BYTES = 80 * 1024 * 1024;
|
|
8125
|
+
var SOURCE_SET_MAX_BYTES = 480 * 1024 * 1024;
|
|
8098
8126
|
async function materializeCodeRuntimeSource(snapshot, tempRoot = (0, import_os3.tmpdir)()) {
|
|
8099
|
-
if (!snapshot.files.length || snapshot.files.length >
|
|
8127
|
+
if (!snapshot.files.length || snapshot.files.length > SOURCE_MAX_FILES) throw new TypeError("Code source file count is invalid");
|
|
8100
8128
|
const root = await (0, import_promises8.mkdtemp)((0, import_path8.join)(tempRoot, "odla-code-source-"));
|
|
8101
8129
|
const sourceDir = (0, import_path8.join)(root, "source");
|
|
8102
8130
|
await (0, import_promises8.mkdir)(sourceDir);
|
|
@@ -8108,7 +8136,7 @@ async function materializeCodeRuntimeSource(snapshot, tempRoot = (0, import_os3.
|
|
|
8108
8136
|
if (seen.has(file.path)) throw new TypeError("Code source repeats a path");
|
|
8109
8137
|
seen.add(file.path);
|
|
8110
8138
|
bytes += Buffer.byteLength(file.path) + Buffer.byteLength(file.content);
|
|
8111
|
-
if (bytes >
|
|
8139
|
+
if (bytes > SOURCE_MAX_BYTES) throw new TypeError("Code source exceeds its byte bound");
|
|
8112
8140
|
const target = (0, import_path8.resolve)(sourceDir, file.path);
|
|
8113
8141
|
if (!target.startsWith(`${(0, import_path8.resolve)(sourceDir)}${import_path8.sep}`)) throw new TypeError("Code source path escapes its root");
|
|
8114
8142
|
await (0, import_promises8.mkdir)((0, import_path8.dirname)(target), { recursive: true });
|
|
@@ -8116,14 +8144,14 @@ async function materializeCodeRuntimeSource(snapshot, tempRoot = (0, import_os3.
|
|
|
8116
8144
|
}
|
|
8117
8145
|
for (const reference of snapshot.references ?? []) {
|
|
8118
8146
|
validateAlias(reference.alias);
|
|
8119
|
-
if (!reference.files.length || reference.files.length >
|
|
8147
|
+
if (!reference.files.length || reference.files.length > SOURCE_MAX_FILES) throw new TypeError("Code reference file count is invalid");
|
|
8120
8148
|
for (const file of reference.files) {
|
|
8121
8149
|
validatePath(file.path);
|
|
8122
8150
|
const path = `.odla-references/${reference.alias}/${file.path}`;
|
|
8123
8151
|
if (seen.has(path)) throw new TypeError("Code reference repeats a path");
|
|
8124
8152
|
seen.add(path);
|
|
8125
8153
|
bytes += Buffer.byteLength(path) + Buffer.byteLength(file.content);
|
|
8126
|
-
if (bytes >
|
|
8154
|
+
if (bytes > SOURCE_SET_MAX_BYTES) throw new TypeError("Code source set exceeds its byte bound");
|
|
8127
8155
|
const target = (0, import_path8.resolve)(sourceDir, path);
|
|
8128
8156
|
if (!target.startsWith(`${(0, import_path8.resolve)(sourceDir)}${import_path8.sep}`)) throw new TypeError("Code reference path escapes its root");
|
|
8129
8157
|
await (0, import_promises8.mkdir)((0, import_path8.dirname)(target), { recursive: true });
|
|
@@ -8149,7 +8177,7 @@ async function attachCodeRuntimeReferences(workspace, references) {
|
|
|
8149
8177
|
validatePath(file.path);
|
|
8150
8178
|
const path = `.odla-references/${reference.alias}/${file.path}`;
|
|
8151
8179
|
bytes += Buffer.byteLength(path) + Buffer.byteLength(file.content);
|
|
8152
|
-
if (bytes >
|
|
8180
|
+
if (bytes > SOURCE_SET_MAX_BYTES - SOURCE_MAX_BYTES) throw new TypeError("Code reference set exceeds its byte bound");
|
|
8153
8181
|
for (const root of [workspace.baselineDir, workspace.workspaceDir]) {
|
|
8154
8182
|
const target = (0, import_path8.resolve)(root, path);
|
|
8155
8183
|
if (!target.startsWith(`${(0, import_path8.resolve)(root)}${import_path8.sep}`)) throw new TypeError("Code reference path escapes its root");
|
|
@@ -8199,7 +8227,10 @@ async function materializeCommandWorkspace(input) {
|
|
|
8199
8227
|
trustedBaseDir: materialized.sourceDir,
|
|
8200
8228
|
trustedBaseCommitSha: source.commitSha,
|
|
8201
8229
|
checkpoint: codeCheckpointPayload(command.payload)
|
|
8202
|
-
})).workspace : await stageWorkspace(materialized.sourceDir
|
|
8230
|
+
})).workspace : await stageWorkspace(materialized.sourceDir, {
|
|
8231
|
+
maxFiles: SOURCE_MAX_FILES,
|
|
8232
|
+
maxBytes: SOURCE_SET_MAX_BYTES
|
|
8233
|
+
});
|
|
8203
8234
|
return { workspace, sourceDigest: source.treeDigest, requestedLocal: null };
|
|
8204
8235
|
} finally {
|
|
8205
8236
|
await materialized.cleanup();
|
|
@@ -10573,13 +10604,16 @@ async function credentialCommand(parsed, deps = {}) {
|
|
|
10573
10604
|
// src/help-usage.ts
|
|
10574
10605
|
var AUTH_SECTION = `
|
|
10575
10606
|
Enrol this machine once, then stop asking:
|
|
10576
|
-
npx odla-ai device enroll --
|
|
10577
|
-
One browser approval
|
|
10578
|
-
own
|
|
10579
|
-
|
|
10580
|
-
|
|
10581
|
-
|
|
10582
|
-
|
|
10607
|
+
npx odla-ai device enroll --no-open --wait 600
|
|
10608
|
+
One browser approval, and no flags to remember: this covers every app you
|
|
10609
|
+
own \u2014 including apps you create later \u2014 with every capability that
|
|
10610
|
+
approval can carry. Afterwards every worktree on this machine mints its
|
|
10611
|
+
own short-lived credentials with nobody's attention. The window rolls
|
|
10612
|
+
forward each time you use it, so continuous work never interrupts anyone;
|
|
10613
|
+
only a real gap does. Give the human the printed /studio?code= URL, keep
|
|
10614
|
+
the process alive, and wait on it.
|
|
10615
|
+
Narrow it deliberately with --app <id> or --capability <c>; the CLI then
|
|
10616
|
+
says what that gave up.
|
|
10583
10617
|
|
|
10584
10618
|
npx odla-ai device enroll --platform-wide --device-ttl 6w --no-open --wait 600
|
|
10585
10619
|
The same thing across all of odla, for weeks. Needs a platform
|
|
@@ -10722,7 +10756,7 @@ Usage:
|
|
|
10722
10756
|
odla-ai security run [target] --ack-redacted-source [--env dev] [--profile odla] [--fail-on high]
|
|
10723
10757
|
odla-ai security run [target] --self --ack-redacted-source
|
|
10724
10758
|
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]
|
|
10725
|
-
odla-ai device enroll [--
|
|
10759
|
+
odla-ai device enroll [--app <id>[,<id>...]|--all-apps] [--capability all|<c>[,<c>...]] [--platform-wide]
|
|
10726
10760
|
[--name <label>] [--device-ttl <30d|6w|2y|forever>] [--email <odla-account>] [--no-open] [--wait <seconds>] [--json]
|
|
10727
10761
|
odla-ai device list [--email <odla-account>] [--json]
|
|
10728
10762
|
odla-ai device revoke <device-id> [--email <odla-account>] [--json]
|
|
@@ -10848,11 +10882,13 @@ Commands:
|
|
|
10848
10882
|
enrollment in the browser; from then on EVERY worktree on this
|
|
10849
10883
|
machine mints its own short-lived credentials with nobody's
|
|
10850
10884
|
attention, until the device is revoked or goes unused.
|
|
10851
|
-
|
|
10852
|
-
|
|
10853
|
-
|
|
10854
|
-
|
|
10855
|
-
|
|
10885
|
+
With no flags it covers every app you own, now and later, with
|
|
10886
|
+
every capability that approval can carry \u2014 so creating an app
|
|
10887
|
+
costs no new approval, and a capability nobody thought to name is
|
|
10888
|
+
not a 403 next week. "--app" or "--capability" narrow it
|
|
10889
|
+
deliberately, and the CLI says what that gave up.
|
|
10890
|
+
"--platform-wide" is the administrator's version, across all of
|
|
10891
|
+
odla.
|
|
10856
10892
|
The expiry is a GAP, not a clock: each use rolls it forward, so
|
|
10857
10893
|
only going quiet brings a human back into the loop \u2014 which is
|
|
10858
10894
|
where anything that changed can be explained.
|
|
@@ -13892,10 +13928,17 @@ function advisoryCollectingFetch(inner, sink) {
|
|
|
13892
13928
|
return response2;
|
|
13893
13929
|
});
|
|
13894
13930
|
}
|
|
13931
|
+
var superseded = /* @__PURE__ */ new Set();
|
|
13932
|
+
function supersedeAdvisory(code) {
|
|
13933
|
+
superseded.add(code);
|
|
13934
|
+
}
|
|
13895
13935
|
function renderAdvisories(out, advisories, env = process.env) {
|
|
13936
|
+
const retracted = new Set(superseded);
|
|
13937
|
+
superseded.clear();
|
|
13896
13938
|
if (env.ODLA_NO_ADVISORIES) return;
|
|
13897
13939
|
const seen = /* @__PURE__ */ new Set();
|
|
13898
13940
|
for (const advisory of advisories) {
|
|
13941
|
+
if (retracted.has(advisory.code)) continue;
|
|
13899
13942
|
const key = `${advisory.code}:${advisory.message}`;
|
|
13900
13943
|
if (seen.has(key)) continue;
|
|
13901
13944
|
seen.add(key);
|
|
@@ -13958,11 +14001,18 @@ async function deviceCommand(parsed, deps) {
|
|
|
13958
14001
|
async function enroll(parsed, deps, cfg, doFetch, out, json) {
|
|
13959
14002
|
const name = stringOpt(parsed.options.name) ?? defaultDeviceName();
|
|
13960
14003
|
const platformWide = parsed.options["platform-wide"] === true;
|
|
13961
|
-
const
|
|
14004
|
+
const narrowed = stringOpt(parsed.options.app) !== void 0 || stringOpt(parsed.options.capability) !== void 0;
|
|
14005
|
+
const apps = platformWide || parsed.options["all-apps"] === true || !narrowed ? [import_db4.ALL_OWNED_APPS] : (stringOpt(parsed.options.app) ?? cfg.app.id).split(",").map((id2) => id2.trim()).filter(Boolean);
|
|
13962
14006
|
if (apps.length === 0) throw new Error("device enroll needs --app <id>[,<id>\u2026], or --all-apps");
|
|
13963
14007
|
const deviceTtlMs = parseDeviceTtl(parsed.options["device-ttl"]);
|
|
13964
14008
|
const extended = platformWide || deviceTtlMs !== void 0 && deviceTtlMs > OWNER_DEVICE_TTL_MS;
|
|
13965
|
-
const { capabilities, scopes } = requestedEnvelope(parsed, platformWide);
|
|
14009
|
+
const { capabilities, scopes } = requestedEnvelope(parsed, platformWide, narrowed);
|
|
14010
|
+
const narrowNotice = narrowEnrollmentNotice({
|
|
14011
|
+
appIds: apps,
|
|
14012
|
+
capabilities: capabilities ?? [],
|
|
14013
|
+
scopes: scopes ?? []
|
|
14014
|
+
});
|
|
14015
|
+
if (narrowNotice) out.error(narrowNotice);
|
|
13966
14016
|
const token = await scopedToken2(
|
|
13967
14017
|
parsed,
|
|
13968
14018
|
deps,
|
|
@@ -13998,8 +14048,10 @@ async function enroll(parsed, deps, cfg, doFetch, out, json) {
|
|
|
13998
14048
|
}, null, 2));
|
|
13999
14049
|
(0, import_node_fs19.chmodSync)(path, 384);
|
|
14000
14050
|
rememberMachineIdentity(cfg.platformUrl.replace(/\/$/, ""), stringOpt(parsed.options.email));
|
|
14051
|
+
supersedeAdvisory("credential.expiring");
|
|
14001
14052
|
const reach = body.device.appIds.includes(import_db4.ALL_OWNED_APPS) ? "every app you own, now and later" : body.device.appIds.join(", ");
|
|
14002
14053
|
out.error(`device: enrolled "${name}" for ${reach}; credential written to ${path}`);
|
|
14054
|
+
if (narrowNotice) out.error(narrowNotice);
|
|
14003
14055
|
out.error(
|
|
14004
14056
|
"device: every worktree on this machine mints its own credentials from now on \u2014 no further approvals,"
|
|
14005
14057
|
);
|
|
@@ -14018,9 +14070,9 @@ async function enroll(parsed, deps, cfg, doFetch, out, json) {
|
|
|
14018
14070
|
}, null, 2));
|
|
14019
14071
|
}
|
|
14020
14072
|
}
|
|
14021
|
-
function requestedEnvelope(parsed, platformWide) {
|
|
14073
|
+
function requestedEnvelope(parsed, platformWide, narrowed) {
|
|
14022
14074
|
const raw = stringOpt(parsed.options.capability);
|
|
14023
|
-
const everything = platformWide || raw?.trim().toLowerCase() === "all";
|
|
14075
|
+
const everything = platformWide || !narrowed || raw?.trim().toLowerCase() === "all";
|
|
14024
14076
|
if (everything) {
|
|
14025
14077
|
return {
|
|
14026
14078
|
capabilities: [...import_db4.OPTIONAL_AGENT_PROJECT_CAPABILITIES],
|