@odla-ai/cli 0.27.12 → 0.27.13

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.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  exitCodeFor,
4
4
  redactSecrets,
5
5
  runCli
6
- } from "./chunk-ECRBOR66.js";
6
+ } from "./chunk-3YSCRXPF.js";
7
7
 
8
8
  // src/bin.ts
9
9
  runCli().catch((err) => {
@@ -292,23 +292,30 @@ function handshakeWaitMs(waitSeconds, interactive = process4.stdout.isTTY === tr
292
292
 
293
293
  // src/token.ts
294
294
  async function getDeveloperToken(cfg, options, doFetch, out, grantRequest = {}) {
295
- if (options.token) return options.token;
296
295
  const audience = platformAudience(cfg.platformUrl);
297
- if (process5.env.ODLA_DEV_TOKEN) {
298
- const declared = process5.env.ODLA_DEV_TOKEN_AUDIENCE;
299
- if (declared) {
300
- if (platformAudience(declared) !== audience) throw new Error("ODLA_DEV_TOKEN_AUDIENCE does not match the configured platform");
301
- } else if (audience !== "https://odla.ai") {
302
- throw new Error("ODLA_DEV_TOKEN_AUDIENCE is required for a non-default platform");
303
- }
304
- return process5.env.ODLA_DEV_TOKEN;
305
- }
306
296
  const optionalProjectCapabilities = grantRequest.optionalProjectCapabilities ?? [];
307
297
  const grantIntent = { projectIds: [cfg.app.id], optionalProjectCapabilities };
308
298
  const cached = readJsonFile(cfg.local.tokenFile);
309
- if (cached?.token && cached.platform === audience && (cached.expiresAt ?? 0) > Date.now() + 6e4 && cachedGrantCovers(cached, grantIntent)) {
310
- out.error(`auth: using cached developer token (${displayPath(cfg.local.tokenFile, cfg.rootDir)})`);
311
- return cached.token;
299
+ if (!grantRequest.forceReview) {
300
+ if (options.token) return options.token;
301
+ if (process5.env.ODLA_DEV_TOKEN) {
302
+ const declared = process5.env.ODLA_DEV_TOKEN_AUDIENCE;
303
+ if (declared) {
304
+ if (platformAudience(declared) !== audience) throw new Error("ODLA_DEV_TOKEN_AUDIENCE does not match the configured platform");
305
+ } else if (audience !== "https://odla.ai") {
306
+ throw new Error("ODLA_DEV_TOKEN_AUDIENCE is required for a non-default platform");
307
+ }
308
+ return process5.env.ODLA_DEV_TOKEN;
309
+ }
310
+ if (cached?.token && cached.platform === audience && (cached.expiresAt ?? 0) > Date.now() + 6e4 && cachedGrantCovers(cached, grantIntent)) {
311
+ out.error(`auth: using cached developer token (${displayPath(cfg.local.tokenFile, cfg.rootDir)})`);
312
+ return cached.token;
313
+ }
314
+ } else {
315
+ if (options.token) {
316
+ throw new Error("--request-grant cannot be combined with --token; remove --token so the approved replacement credential can be collected and cached");
317
+ }
318
+ out.error(`auth: requesting fresh owner review for app.manage on exact project "${cfg.app.id}"`);
312
319
  }
313
320
  const ctx = {
314
321
  cfg,
@@ -1810,11 +1817,11 @@ async function assertTenantAdminAccess(doFetch, cfg, env, token) {
1810
1817
  }
1811
1818
  if (code === "provision_approval_required") {
1812
1819
  throw new Error(
1813
- `${env}: the agent credential does not carry the owner-reviewed app.manage grant required to provision "${cfg.app.id}" (tenant ${tenantId}). The human owner id on the token is accountability, not agent authority. Discard the cached or supplied token and run this command with the current CLI to approve one fresh exact-project provisioning handshake`
1820
+ `${env}: the agent credential does not carry the owner-reviewed app.manage grant required to provision "${cfg.app.id}" (tenant ${tenantId}). The human owner id on the token is accountability, not agent authority. Run "odla-ai provision --request-grant --email <odla-account>" to open one fresh exact-project owner review; do not change app ownership unless the human account itself is not an owner`
1814
1821
  );
1815
1822
  }
1816
1823
  throw new Error(
1817
- `${env}: this credential lacks live app.manage authority for "${cfg.app.id}" (tenant ${tenantId}) \u2014 nothing was minted or written; re-run provision with a fresh owner-approved provision handshake. If the human account is not an owner, an existing owner must add it in signed-in Studio; an agent token cannot repair ownership`
1824
+ `${env}: this credential lacks live app.manage authority for "${cfg.app.id}" (tenant ${tenantId}) \u2014 nothing was minted or written; run "odla-ai provision --request-grant --email <odla-account>" to open a fresh owner review. If the human account is not an owner, an existing owner must add it in signed-in Studio; an agent token cannot repair ownership`
1818
1825
  );
1819
1826
  }
1820
1827
  throw new Error(`${env}: tenant access preflight (${tenantId}) failed: ${res.status} ${await safeText4(res)}`);
@@ -7241,7 +7248,7 @@ function record6(value2) {
7241
7248
  }
7242
7249
 
7243
7250
  // src/provision.ts
7244
- import { createAppsClient as createAppsClient3, orderAppServices as orderAppServices3, tenantIdFor as tenantIdFor4 } from "@odla-ai/apps";
7251
+ import { AppsError as AppsError2, createAppsClient as createAppsClient3, orderAppServices as orderAppServices3, tenantIdFor as tenantIdFor4 } from "@odla-ai/apps";
7245
7252
  import { putSecret as putSecret2 } from "@odla-ai/ai";
7246
7253
  import process9 from "process";
7247
7254
 
@@ -7462,14 +7469,25 @@ async function provision(options) {
7462
7469
  }
7463
7470
  const doFetch = options.fetch ?? fetch;
7464
7471
  const token = await getDeveloperToken(cfg, options, doFetch, out, {
7465
- optionalProjectCapabilities: ["app.manage"]
7472
+ optionalProjectCapabilities: ["app.manage"],
7473
+ forceReview: options.requestGrant
7466
7474
  });
7467
7475
  const apps = createAppsClient3({ endpoint: cfg.platformUrl, token, fetcher: { fetch: doFetch } });
7468
7476
  const existing = await apps.resolveApp(cfg.app.id);
7469
7477
  if (existing) {
7470
7478
  out.log(`app: ${cfg.app.id} already exists`);
7471
7479
  } else {
7472
- await apps.createApp({ name: cfg.app.name, appId: cfg.app.id });
7480
+ try {
7481
+ await apps.createApp({ name: cfg.app.name, appId: cfg.app.id });
7482
+ } catch (error) {
7483
+ if (error instanceof AppsError2 && error.status === 403) {
7484
+ throw new Error(
7485
+ `app "${cfg.app.id}" does not exist, and this authenticated agent credential has no owner-reviewed app.manage bootstrap grant for that exact id. Run "odla-ai provision --request-grant --email <odla-account>" to open the review URL and continue; developer ownership alone is not agent authority`,
7486
+ { cause: error }
7487
+ );
7488
+ }
7489
+ throw error;
7490
+ }
7473
7491
  out.log(`app: created ${cfg.app.id}`);
7474
7492
  }
7475
7493
  for (const env of cfg.envs) {
@@ -9360,7 +9378,7 @@ Usage:
9360
9378
  odla-ai security report <job-id> [--json]
9361
9379
  odla-ai security run [target] --ack-redacted-source [--env dev] [--profile odla] [--fail-on high]
9362
9380
  odla-ai security run [target] --self --ack-redacted-source
9363
- odla-ai provision [--config odla.config.mjs] [--email <odla-account>] [--wait <seconds>] [--dry-run] [--push-secrets] [--rotate-o11y-token] [--write-dev-vars[=path]] [--yes]
9381
+ odla-ai provision [--config odla.config.mjs] [--email <odla-account>] [--request-grant] [--wait <seconds>] [--dry-run] [--push-secrets] [--rotate-o11y-token] [--write-dev-vars[=path]] [--yes]
9364
9382
  odla-ai smoke [--config odla.config.mjs] [--env dev] [--email <odla-account>] [--no-open]
9365
9383
  odla-ai skill install [--dir <project>] [--agent <name>] [--global] [--force]
9366
9384
  odla-ai secrets push --env <env> [--config odla.config.mjs] [--dry-run] [--yes]
@@ -9495,6 +9513,10 @@ Safety:
9495
9513
  The email is a non-secret identity hint: never provide a password or session
9496
9514
  token. The matching account must already exist, be signed in, explicitly
9497
9515
  review the exact code, and finish any current request before claiming another.
9516
+ If provision reports that the current agent principal has no live app.manage
9517
+ grant, run it once with --request-grant. That flag ignores ODLA_DEV_TOKEN and
9518
+ the local cache, prints and opens a fresh exact-project owner-review URL, then
9519
+ continues provisioning with the approved replacement credential.
9498
9520
  Run Code from a GitHub checkout already connected to an app in Studio; an
9499
9521
  odla.config.mjs may select the app explicitly but is not required. Code host
9500
9522
  approval and credential hashes live in odla-ai/db. The host
@@ -12796,6 +12818,7 @@ async function provisionCommand(parsed, dependencies) {
12796
12818
  "write-credentials",
12797
12819
  "write-dev-vars",
12798
12820
  "token",
12821
+ "request-grant",
12799
12822
  "email",
12800
12823
  "open",
12801
12824
  "wait",
@@ -12811,6 +12834,7 @@ async function provisionCommand(parsed, dependencies) {
12811
12834
  writeCredentials: parsed.options["write-credentials"] !== false,
12812
12835
  writeDevVars: typeof writeDevVars2 === "string" ? writeDevVars2 : writeDevVars2 === true,
12813
12836
  token: stringOpt(parsed.options.token),
12837
+ requestGrant: parsed.options["request-grant"] === true,
12814
12838
  email: stringOpt(parsed.options.email),
12815
12839
  open: parsed.options.open === false ? false : parsed.options.open === true ? true : void 0,
12816
12840
  wait: numberOpt(parsed.options.wait, "--wait"),
@@ -12906,4 +12930,4 @@ export {
12906
12930
  exitCodeFor,
12907
12931
  runCli
12908
12932
  };
12909
- //# sourceMappingURL=chunk-ECRBOR66.js.map
12933
+ //# sourceMappingURL=chunk-3YSCRXPF.js.map