@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
package/dist/bin.js
CHANGED
|
@@ -174,7 +174,7 @@ function absoluteEntryPath(entryPath) {
|
|
|
174
174
|
|
|
175
175
|
// src/bin.ts
|
|
176
176
|
var argv = process.argv.slice(2);
|
|
177
|
-
requireCurrentCliForProvision(argv).then(() => requireCoherentProvisionRuntime(argv)).then(async () => (await import("./cli-
|
|
177
|
+
requireCurrentCliForProvision(argv).then(() => requireCoherentProvisionRuntime(argv)).then(async () => (await import("./cli-WJSQEBDO.js")).runCli()).catch((err) => {
|
|
178
178
|
console.error(redactSecrets(`odla-ai: ${err instanceof Error ? err.message : String(err)}`));
|
|
179
179
|
process.exitCode = exitCodeFor(err);
|
|
180
180
|
});
|
|
@@ -208,6 +208,11 @@ import { homedir as homedir2 } from "os";
|
|
|
208
208
|
import { dirname as dirname2, join as join3 } from "path";
|
|
209
209
|
import process6 from "process";
|
|
210
210
|
function odlaHome(env = process6.env) {
|
|
211
|
+
if (env.VITEST && !env.ODLA_HOME) {
|
|
212
|
+
throw new Error(
|
|
213
|
+
"ODLA_HOME must be set under test \u2014 resolving the real ~/.odla would write to the developer's machine"
|
|
214
|
+
);
|
|
215
|
+
}
|
|
211
216
|
return env.ODLA_HOME ?? join3(env.HOME ?? homedir2(), ".odla");
|
|
212
217
|
}
|
|
213
218
|
function odlaHomePath(segments, env = process6.env) {
|
|
@@ -233,15 +238,15 @@ function pmContextFile(env) {
|
|
|
233
238
|
}
|
|
234
239
|
function adoptRepoLocalCache(legacyPath, machinePath, out) {
|
|
235
240
|
if (!existsSync2(legacyPath) || legacyPath === machinePath) return false;
|
|
236
|
-
const
|
|
237
|
-
if (!
|
|
241
|
+
const superseded2 = existsSync2(machinePath);
|
|
242
|
+
if (!superseded2) {
|
|
238
243
|
mkdirSync(dirname2(machinePath), { recursive: true });
|
|
239
244
|
copyFileSync(legacyPath, machinePath);
|
|
240
245
|
chmodSync(machinePath, 384);
|
|
241
246
|
}
|
|
242
247
|
rmSync2(legacyPath, { force: true });
|
|
243
248
|
out?.error(
|
|
244
|
-
|
|
249
|
+
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`
|
|
245
250
|
);
|
|
246
251
|
return true;
|
|
247
252
|
}
|
|
@@ -378,7 +383,7 @@ function displayPath(path, rootDir = process.cwd()) {
|
|
|
378
383
|
}
|
|
379
384
|
|
|
380
385
|
// src/auth-guidance.ts
|
|
381
|
-
var ENROL_EVERYTHING = "npx odla-ai device enroll --
|
|
386
|
+
var ENROL_EVERYTHING = "npx odla-ai device enroll --no-open --wait 600";
|
|
382
387
|
var ENROL_PLATFORM_WIDE = "npx odla-ai device enroll --platform-wide --device-ttl 6w --no-open --wait 600";
|
|
383
388
|
function machineAuthState(audience, env = process7.env) {
|
|
384
389
|
const device = readDeviceCredential(audience, env);
|
|
@@ -404,6 +409,20 @@ function scopeInterruptionNotice(scope, state2) {
|
|
|
404
409
|
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."
|
|
405
410
|
].join("\n");
|
|
406
411
|
}
|
|
412
|
+
function narrowEnrollmentNotice(envelope) {
|
|
413
|
+
const everyApp = envelope.appIds.includes("*");
|
|
414
|
+
if (everyApp && envelope.capabilities.length > 0 && envelope.scopes.length > 0) return null;
|
|
415
|
+
const missing = [
|
|
416
|
+
everyApp ? null : `only ${envelope.appIds.length} app${envelope.appIds.length === 1 ? "" : "s"} \u2014 a new one will need a new approval`,
|
|
417
|
+
envelope.capabilities.length ? null : "no optional capabilities \u2014 app.manage, crm.read and code.session are not included",
|
|
418
|
+
envelope.scopes.length ? null : "no platform scopes \u2014 runbook edits, config plans and host connect will each ask again"
|
|
419
|
+
].filter(Boolean);
|
|
420
|
+
return [
|
|
421
|
+
`odla: this is a NARROW enrollment: ${missing.join("; ")}.`,
|
|
422
|
+
" That is a fine choice if you meant it. If you did not, drop the flags:",
|
|
423
|
+
` ${ENROL_EVERYTHING}`
|
|
424
|
+
].join("\n");
|
|
425
|
+
}
|
|
407
426
|
function lapseNotice(state2, now = Date.now()) {
|
|
408
427
|
if (!state2.enrolled || !state2.lapsesAt) return null;
|
|
409
428
|
const days = Math.floor((state2.lapsesAt - now) / (24 * 60 * 60 * 1e3));
|
|
@@ -2281,6 +2300,11 @@ async function authCommand(parsed, deps = {}) {
|
|
|
2281
2300
|
"auth login requires --email <odla-account> or ODLA_USER_EMAIL; confirm the signed-in odla email instead of using git or GitHub identity"
|
|
2282
2301
|
);
|
|
2283
2302
|
}
|
|
2303
|
+
if (!machineAuthState(platformAudience(cfg.platformUrl)).enrolled) {
|
|
2304
|
+
out.error("odla: this machine is not enrolled, so this approval buys one project until it lapses.");
|
|
2305
|
+
out.error(` For one approval that covers every app you own, with no repeats:
|
|
2306
|
+
${ENROL_EVERYTHING}`);
|
|
2307
|
+
}
|
|
2284
2308
|
const token = await getDeveloperToken(
|
|
2285
2309
|
cfg,
|
|
2286
2310
|
{
|
|
@@ -6121,7 +6145,7 @@ async function stageWorkspacePair(baselineSource, workspaceSource, options = {})
|
|
|
6121
6145
|
}
|
|
6122
6146
|
}
|
|
6123
6147
|
|
|
6124
|
-
// ../harness/dist/chunk-
|
|
6148
|
+
// ../harness/dist/chunk-L2T3LPEF.js
|
|
6125
6149
|
import { createHash as createHash3 } from "crypto";
|
|
6126
6150
|
import { readFile as readFile2, readdir as readdir2 } from "fs/promises";
|
|
6127
6151
|
import { relative as relative4, resolve as resolve10 } from "path";
|
|
@@ -6458,7 +6482,7 @@ function validateSnapshot(snapshot, limits) {
|
|
|
6458
6482
|
}
|
|
6459
6483
|
}
|
|
6460
6484
|
|
|
6461
|
-
// ../harness/dist/chunk-
|
|
6485
|
+
// ../harness/dist/chunk-L2T3LPEF.js
|
|
6462
6486
|
import { spawn as spawn4 } from "child_process";
|
|
6463
6487
|
import { lstat as lstat2 } from "fs/promises";
|
|
6464
6488
|
import { resolve as resolve23, sep as sep3 } from "path";
|
|
@@ -6763,7 +6787,7 @@ function looksLikeDestination(value2) {
|
|
|
6763
6787
|
return /^(?:[a-z][a-z0-9+.-]*:\/\/|\/|\\\\)/i.test(text3) || /^[\w.-]+\.[a-z]{2,}(?:[/:]|$)/i.test(text3);
|
|
6764
6788
|
}
|
|
6765
6789
|
|
|
6766
|
-
// ../harness/dist/chunk-
|
|
6790
|
+
// ../harness/dist/chunk-L2T3LPEF.js
|
|
6767
6791
|
import { readFile as readFile4, stat as stat2 } from "fs/promises";
|
|
6768
6792
|
import { readFile as readFile3 } from "fs/promises";
|
|
6769
6793
|
import { join as join33 } from "path";
|
|
@@ -7031,7 +7055,7 @@ async function buildCodeGraph(input) {
|
|
|
7031
7055
|
return builder.build();
|
|
7032
7056
|
}
|
|
7033
7057
|
|
|
7034
|
-
// ../harness/dist/chunk-
|
|
7058
|
+
// ../harness/dist/chunk-L2T3LPEF.js
|
|
7035
7059
|
import { createHash as createHash32 } from "crypto";
|
|
7036
7060
|
async function digestStagedWorkspace(root, limits) {
|
|
7037
7061
|
const files = [];
|
|
@@ -7290,6 +7314,7 @@ function parseSnapshot(value2) {
|
|
|
7290
7314
|
return { host, bindings, commands };
|
|
7291
7315
|
}
|
|
7292
7316
|
async function parseSource(value2) {
|
|
7317
|
+
const repositoryLimits = { maximumFiles: 1e5, maximumBytes: 80 * 1024 * 1024 };
|
|
7293
7318
|
const snapshot = record5(record5(value2)?.snapshot);
|
|
7294
7319
|
if (!snapshot || typeof snapshot.repository !== "string" || typeof snapshot.commitSha !== "string" || typeof snapshot.treeDigest !== "string" || !Array.isArray(snapshot.files)) throw invalid("source");
|
|
7295
7320
|
const files = snapshot.files.map((value22) => {
|
|
@@ -7311,12 +7336,12 @@ async function parseSource(value2) {
|
|
|
7311
7336
|
return { path: file.path, content: file.content };
|
|
7312
7337
|
});
|
|
7313
7338
|
const source2 = { repository: reference.repository, commitSha: reference.commitSha, files: referenceFiles };
|
|
7314
|
-
const referenceDigest = await digestCodeRepositorySnapshot(source2,
|
|
7339
|
+
const referenceDigest = await digestCodeRepositorySnapshot(source2, repositoryLimits);
|
|
7315
7340
|
if (referenceDigest !== reference.treeDigest) throw invalid("reference source digest");
|
|
7316
7341
|
references.push({ alias: reference.alias, ...source2, treeDigest: referenceDigest });
|
|
7317
7342
|
}
|
|
7318
7343
|
const source = { repository: snapshot.repository, commitSha: snapshot.commitSha, files };
|
|
7319
|
-
const digest = await digestCodeRepositorySnapshot(source,
|
|
7344
|
+
const digest = await digestCodeRepositorySnapshot(source, repositoryLimits);
|
|
7320
7345
|
if (digest !== snapshot.treeDigest) throw invalid("source digest");
|
|
7321
7346
|
return { ...source, treeDigest: digest, ...references.length ? { references } : {} };
|
|
7322
7347
|
}
|
|
@@ -7968,8 +7993,11 @@ async function prepareRuntimeLocalSource(input) {
|
|
|
7968
7993
|
}
|
|
7969
7994
|
var RESERVED2 = /* @__PURE__ */ new Set([".git", ".odla", ".wrangler", "node_modules", "dist", "coverage"]);
|
|
7970
7995
|
var SECRET2 = /^(?:\.env(?:\..+)?|\.dev\.vars|credentials(?:\..+)?\.json|dev-token(?:\..+)?\.json)$/i;
|
|
7996
|
+
var SOURCE_MAX_FILES = 1e5;
|
|
7997
|
+
var SOURCE_MAX_BYTES = 80 * 1024 * 1024;
|
|
7998
|
+
var SOURCE_SET_MAX_BYTES = 480 * 1024 * 1024;
|
|
7971
7999
|
async function materializeCodeRuntimeSource(snapshot, tempRoot = tmpdir3()) {
|
|
7972
|
-
if (!snapshot.files.length || snapshot.files.length >
|
|
8000
|
+
if (!snapshot.files.length || snapshot.files.length > SOURCE_MAX_FILES) throw new TypeError("Code source file count is invalid");
|
|
7973
8001
|
const root = await mkdtemp3(join23(tempRoot, "odla-code-source-"));
|
|
7974
8002
|
const sourceDir = join23(root, "source");
|
|
7975
8003
|
await mkdir3(sourceDir);
|
|
@@ -7981,7 +8009,7 @@ async function materializeCodeRuntimeSource(snapshot, tempRoot = tmpdir3()) {
|
|
|
7981
8009
|
if (seen.has(file.path)) throw new TypeError("Code source repeats a path");
|
|
7982
8010
|
seen.add(file.path);
|
|
7983
8011
|
bytes += Buffer.byteLength(file.path) + Buffer.byteLength(file.content);
|
|
7984
|
-
if (bytes >
|
|
8012
|
+
if (bytes > SOURCE_MAX_BYTES) throw new TypeError("Code source exceeds its byte bound");
|
|
7985
8013
|
const target = resolve32(sourceDir, file.path);
|
|
7986
8014
|
if (!target.startsWith(`${resolve32(sourceDir)}${sep23}`)) throw new TypeError("Code source path escapes its root");
|
|
7987
8015
|
await mkdir3(dirname10(target), { recursive: true });
|
|
@@ -7989,14 +8017,14 @@ async function materializeCodeRuntimeSource(snapshot, tempRoot = tmpdir3()) {
|
|
|
7989
8017
|
}
|
|
7990
8018
|
for (const reference of snapshot.references ?? []) {
|
|
7991
8019
|
validateAlias(reference.alias);
|
|
7992
|
-
if (!reference.files.length || reference.files.length >
|
|
8020
|
+
if (!reference.files.length || reference.files.length > SOURCE_MAX_FILES) throw new TypeError("Code reference file count is invalid");
|
|
7993
8021
|
for (const file of reference.files) {
|
|
7994
8022
|
validatePath(file.path);
|
|
7995
8023
|
const path = `.odla-references/${reference.alias}/${file.path}`;
|
|
7996
8024
|
if (seen.has(path)) throw new TypeError("Code reference repeats a path");
|
|
7997
8025
|
seen.add(path);
|
|
7998
8026
|
bytes += Buffer.byteLength(path) + Buffer.byteLength(file.content);
|
|
7999
|
-
if (bytes >
|
|
8027
|
+
if (bytes > SOURCE_SET_MAX_BYTES) throw new TypeError("Code source set exceeds its byte bound");
|
|
8000
8028
|
const target = resolve32(sourceDir, path);
|
|
8001
8029
|
if (!target.startsWith(`${resolve32(sourceDir)}${sep23}`)) throw new TypeError("Code reference path escapes its root");
|
|
8002
8030
|
await mkdir3(dirname10(target), { recursive: true });
|
|
@@ -8022,7 +8050,7 @@ async function attachCodeRuntimeReferences(workspace, references) {
|
|
|
8022
8050
|
validatePath(file.path);
|
|
8023
8051
|
const path = `.odla-references/${reference.alias}/${file.path}`;
|
|
8024
8052
|
bytes += Buffer.byteLength(path) + Buffer.byteLength(file.content);
|
|
8025
|
-
if (bytes >
|
|
8053
|
+
if (bytes > SOURCE_SET_MAX_BYTES - SOURCE_MAX_BYTES) throw new TypeError("Code reference set exceeds its byte bound");
|
|
8026
8054
|
for (const root of [workspace.baselineDir, workspace.workspaceDir]) {
|
|
8027
8055
|
const target = resolve32(root, path);
|
|
8028
8056
|
if (!target.startsWith(`${resolve32(root)}${sep23}`)) throw new TypeError("Code reference path escapes its root");
|
|
@@ -8072,7 +8100,10 @@ async function materializeCommandWorkspace(input) {
|
|
|
8072
8100
|
trustedBaseDir: materialized.sourceDir,
|
|
8073
8101
|
trustedBaseCommitSha: source.commitSha,
|
|
8074
8102
|
checkpoint: codeCheckpointPayload(command.payload)
|
|
8075
|
-
})).workspace : await stageWorkspace(materialized.sourceDir
|
|
8103
|
+
})).workspace : await stageWorkspace(materialized.sourceDir, {
|
|
8104
|
+
maxFiles: SOURCE_MAX_FILES,
|
|
8105
|
+
maxBytes: SOURCE_SET_MAX_BYTES
|
|
8106
|
+
});
|
|
8076
8107
|
return { workspace, sourceDigest: source.treeDigest, requestedLocal: null };
|
|
8077
8108
|
} finally {
|
|
8078
8109
|
await materialized.cleanup();
|
|
@@ -10446,13 +10477,16 @@ async function credentialCommand(parsed, deps = {}) {
|
|
|
10446
10477
|
// src/help-usage.ts
|
|
10447
10478
|
var AUTH_SECTION = `
|
|
10448
10479
|
Enrol this machine once, then stop asking:
|
|
10449
|
-
npx odla-ai device enroll --
|
|
10450
|
-
One browser approval
|
|
10451
|
-
own
|
|
10452
|
-
|
|
10453
|
-
|
|
10454
|
-
|
|
10455
|
-
|
|
10480
|
+
npx odla-ai device enroll --no-open --wait 600
|
|
10481
|
+
One browser approval, and no flags to remember: this covers every app you
|
|
10482
|
+
own \u2014 including apps you create later \u2014 with every capability that
|
|
10483
|
+
approval can carry. Afterwards every worktree on this machine mints its
|
|
10484
|
+
own short-lived credentials with nobody's attention. The window rolls
|
|
10485
|
+
forward each time you use it, so continuous work never interrupts anyone;
|
|
10486
|
+
only a real gap does. Give the human the printed /studio?code= URL, keep
|
|
10487
|
+
the process alive, and wait on it.
|
|
10488
|
+
Narrow it deliberately with --app <id> or --capability <c>; the CLI then
|
|
10489
|
+
says what that gave up.
|
|
10456
10490
|
|
|
10457
10491
|
npx odla-ai device enroll --platform-wide --device-ttl 6w --no-open --wait 600
|
|
10458
10492
|
The same thing across all of odla, for weeks. Needs a platform
|
|
@@ -10595,7 +10629,7 @@ Usage:
|
|
|
10595
10629
|
odla-ai security run [target] --ack-redacted-source [--env dev] [--profile odla] [--fail-on high]
|
|
10596
10630
|
odla-ai security run [target] --self --ack-redacted-source
|
|
10597
10631
|
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]
|
|
10598
|
-
odla-ai device enroll [--
|
|
10632
|
+
odla-ai device enroll [--app <id>[,<id>...]|--all-apps] [--capability all|<c>[,<c>...]] [--platform-wide]
|
|
10599
10633
|
[--name <label>] [--device-ttl <30d|6w|2y|forever>] [--email <odla-account>] [--no-open] [--wait <seconds>] [--json]
|
|
10600
10634
|
odla-ai device list [--email <odla-account>] [--json]
|
|
10601
10635
|
odla-ai device revoke <device-id> [--email <odla-account>] [--json]
|
|
@@ -10721,11 +10755,13 @@ Commands:
|
|
|
10721
10755
|
enrollment in the browser; from then on EVERY worktree on this
|
|
10722
10756
|
machine mints its own short-lived credentials with nobody's
|
|
10723
10757
|
attention, until the device is revoked or goes unused.
|
|
10724
|
-
|
|
10725
|
-
|
|
10726
|
-
|
|
10727
|
-
|
|
10728
|
-
|
|
10758
|
+
With no flags it covers every app you own, now and later, with
|
|
10759
|
+
every capability that approval can carry \u2014 so creating an app
|
|
10760
|
+
costs no new approval, and a capability nobody thought to name is
|
|
10761
|
+
not a 403 next week. "--app" or "--capability" narrow it
|
|
10762
|
+
deliberately, and the CLI says what that gave up.
|
|
10763
|
+
"--platform-wide" is the administrator's version, across all of
|
|
10764
|
+
odla.
|
|
10729
10765
|
The expiry is a GAP, not a clock: each use rolls it forward, so
|
|
10730
10766
|
only going quiet brings a human back into the loop \u2014 which is
|
|
10731
10767
|
where anything that changed can be explained.
|
|
@@ -13765,10 +13801,17 @@ function advisoryCollectingFetch(inner, sink) {
|
|
|
13765
13801
|
return response2;
|
|
13766
13802
|
});
|
|
13767
13803
|
}
|
|
13804
|
+
var superseded = /* @__PURE__ */ new Set();
|
|
13805
|
+
function supersedeAdvisory(code) {
|
|
13806
|
+
superseded.add(code);
|
|
13807
|
+
}
|
|
13768
13808
|
function renderAdvisories(out, advisories, env = process.env) {
|
|
13809
|
+
const retracted = new Set(superseded);
|
|
13810
|
+
superseded.clear();
|
|
13769
13811
|
if (env.ODLA_NO_ADVISORIES) return;
|
|
13770
13812
|
const seen = /* @__PURE__ */ new Set();
|
|
13771
13813
|
for (const advisory of advisories) {
|
|
13814
|
+
if (retracted.has(advisory.code)) continue;
|
|
13772
13815
|
const key = `${advisory.code}:${advisory.message}`;
|
|
13773
13816
|
if (seen.has(key)) continue;
|
|
13774
13817
|
seen.add(key);
|
|
@@ -13836,11 +13879,18 @@ async function deviceCommand(parsed, deps) {
|
|
|
13836
13879
|
async function enroll(parsed, deps, cfg, doFetch, out, json) {
|
|
13837
13880
|
const name = stringOpt(parsed.options.name) ?? defaultDeviceName();
|
|
13838
13881
|
const platformWide = parsed.options["platform-wide"] === true;
|
|
13839
|
-
const
|
|
13882
|
+
const narrowed = stringOpt(parsed.options.app) !== void 0 || stringOpt(parsed.options.capability) !== void 0;
|
|
13883
|
+
const apps = platformWide || parsed.options["all-apps"] === true || !narrowed ? [ALL_OWNED_APPS] : (stringOpt(parsed.options.app) ?? cfg.app.id).split(",").map((id2) => id2.trim()).filter(Boolean);
|
|
13840
13884
|
if (apps.length === 0) throw new Error("device enroll needs --app <id>[,<id>\u2026], or --all-apps");
|
|
13841
13885
|
const deviceTtlMs = parseDeviceTtl(parsed.options["device-ttl"]);
|
|
13842
13886
|
const extended = platformWide || deviceTtlMs !== void 0 && deviceTtlMs > OWNER_DEVICE_TTL_MS;
|
|
13843
|
-
const { capabilities, scopes } = requestedEnvelope(parsed, platformWide);
|
|
13887
|
+
const { capabilities, scopes } = requestedEnvelope(parsed, platformWide, narrowed);
|
|
13888
|
+
const narrowNotice = narrowEnrollmentNotice({
|
|
13889
|
+
appIds: apps,
|
|
13890
|
+
capabilities: capabilities ?? [],
|
|
13891
|
+
scopes: scopes ?? []
|
|
13892
|
+
});
|
|
13893
|
+
if (narrowNotice) out.error(narrowNotice);
|
|
13844
13894
|
const token = await scopedToken2(
|
|
13845
13895
|
parsed,
|
|
13846
13896
|
deps,
|
|
@@ -13876,8 +13926,10 @@ async function enroll(parsed, deps, cfg, doFetch, out, json) {
|
|
|
13876
13926
|
}, null, 2));
|
|
13877
13927
|
chmodSync3(path, 384);
|
|
13878
13928
|
rememberMachineIdentity(cfg.platformUrl.replace(/\/$/, ""), stringOpt(parsed.options.email));
|
|
13929
|
+
supersedeAdvisory("credential.expiring");
|
|
13879
13930
|
const reach = body.device.appIds.includes(ALL_OWNED_APPS) ? "every app you own, now and later" : body.device.appIds.join(", ");
|
|
13880
13931
|
out.error(`device: enrolled "${name}" for ${reach}; credential written to ${path}`);
|
|
13932
|
+
if (narrowNotice) out.error(narrowNotice);
|
|
13881
13933
|
out.error(
|
|
13882
13934
|
"device: every worktree on this machine mints its own credentials from now on \u2014 no further approvals,"
|
|
13883
13935
|
);
|
|
@@ -13896,9 +13948,9 @@ async function enroll(parsed, deps, cfg, doFetch, out, json) {
|
|
|
13896
13948
|
}, null, 2));
|
|
13897
13949
|
}
|
|
13898
13950
|
}
|
|
13899
|
-
function requestedEnvelope(parsed, platformWide) {
|
|
13951
|
+
function requestedEnvelope(parsed, platformWide, narrowed) {
|
|
13900
13952
|
const raw = stringOpt(parsed.options.capability);
|
|
13901
|
-
const everything = platformWide || raw?.trim().toLowerCase() === "all";
|
|
13953
|
+
const everything = platformWide || !narrowed || raw?.trim().toLowerCase() === "all";
|
|
13902
13954
|
if (everything) {
|
|
13903
13955
|
return {
|
|
13904
13956
|
capabilities: [...OPTIONAL_AGENT_PROJECT_CAPABILITIES],
|
|
@@ -15747,4 +15799,4 @@ export {
|
|
|
15747
15799
|
isTerminalHostedSecurityStatus,
|
|
15748
15800
|
runCli
|
|
15749
15801
|
};
|
|
15750
|
-
//# sourceMappingURL=chunk-
|
|
15802
|
+
//# sourceMappingURL=chunk-XUTMQMXZ.js.map
|