@odla-ai/cli 0.27.9 → 0.27.11

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-LT56MKDK.js";
6
+ } from "./chunk-Y7WFLSTN.js";
7
7
 
8
8
  // src/bin.ts
9
9
  runCli().catch((err) => {
@@ -1397,7 +1397,7 @@ function parseCalendarStatus(raw, env) {
1397
1397
  throw new Error("calendar status returned unsupported access");
1398
1398
  }
1399
1399
  const errorValue = record(value2.error) ?? record(connection.error);
1400
- const errorCode = textField(value2.lastErrorCode, 128);
1400
+ const errorCode2 = textField(value2.lastErrorCode, 128);
1401
1401
  const bookingPageValue = Object.hasOwn(value2, "bookingPageUrl") ? value2.bookingPageUrl : Object.hasOwn(config, "bookingPageUrl") ? config.bookingPageUrl : googleConfig.bookingPageUrl;
1402
1402
  const connected = typeof (value2.connected ?? connection.connected) === "boolean" ? Boolean(value2.connected ?? connection.connected) : ["healthy", "degraded"].includes(stateValue);
1403
1403
  const bookingCalendarId = textField(value2.bookingCalendarId ?? config.bookingCalendarId, 1024);
@@ -1416,10 +1416,10 @@ function parseCalendarStatus(raw, env) {
1416
1416
  ...optionalNullableUrl("bookingPageUrl", bookingPageValue),
1417
1417
  grantedScopes: stringList(value2.grantedScopes ?? connection.grantedScopes ?? connection.scopes),
1418
1418
  ...optionalText("attemptId", value2.attemptId ?? connection.attemptId, 180),
1419
- ...errorValue || errorCode ? { error: {
1419
+ ...errorValue || errorCode2 ? { error: {
1420
1420
  ...textField(errorValue?.code, 128) ? { code: textField(errorValue?.code, 128) } : {},
1421
1421
  ...textField(errorValue?.message, 500) ? { message: textField(errorValue?.message, 500) } : {},
1422
- ...!errorValue && errorCode ? { code: errorCode } : {}
1422
+ ...!errorValue && errorCode2 ? { code: errorCode2 } : {}
1423
1423
  } } : {}
1424
1424
  };
1425
1425
  }
@@ -1546,7 +1546,7 @@ async function calendarCalendars(options) {
1546
1546
  return calendars;
1547
1547
  }
1548
1548
  async function calendarConnect(options) {
1549
- const { cfg, ctx, out } = await lifecycleContext(options);
1549
+ const { cfg, ctx, out } = await lifecycleContext(options, ["app.manage"]);
1550
1550
  productionConsent(ctx.env, options.yes, "connect calendar");
1551
1551
  const page2 = calendarBookingPageUrl(cfg, ctx.env);
1552
1552
  const applied = page2 === void 0 ? await readCalendarStatus(ctx) : await applyCalendarSettings(ctx, page2);
@@ -1572,7 +1572,7 @@ async function ensureCalendarConnected(ctx, options) {
1572
1572
  const connectOptions = connectionOptions(options, out);
1573
1573
  return await continueConnectedCalendar(ctx, current, connectOptions) ?? connectWithContext(ctx, connectOptions);
1574
1574
  }
1575
- async function lifecycleContext(options) {
1575
+ async function lifecycleContext(options, optionalProjectCapabilities = []) {
1576
1576
  const cfg = await loadProjectConfig(options.configPath);
1577
1577
  if (!cfg.services.includes("calendar")) throw new Error("calendar service is not enabled in config services");
1578
1578
  const env = options.env ?? (cfg.envs.includes("dev") ? "dev" : cfg.envs[0]);
@@ -1590,7 +1590,8 @@ async function lifecycleContext(options) {
1590
1590
  openApprovalUrl: options.openConsentUrl
1591
1591
  },
1592
1592
  doFetch,
1593
- out
1593
+ out,
1594
+ { optionalProjectCapabilities }
1594
1595
  );
1595
1596
  return { cfg, ctx: { platform: cfg.platformUrl, appId: cfg.app.id, env, token, fetch: doFetch }, out };
1596
1597
  }
@@ -1799,12 +1800,32 @@ async function assertTenantAdminAccess(doFetch, cfg, env, token) {
1799
1800
  });
1800
1801
  if (res.ok || res.status === 404) return;
1801
1802
  if (res.status === 403) {
1803
+ const detail = await safeText4(res);
1804
+ const code = errorCode(detail);
1805
+ if (code === "human_session_required") {
1806
+ throw new Error(
1807
+ `${env}: odla-db rejected the provision credential before checking ownership for "${cfg.app.id}" (tenant ${tenantId}): human_session_required. Retrying or changing app owners will not help; the deployed odla-db must accept owner-approved app.manage credentials on provisioning routes`
1808
+ );
1809
+ }
1810
+ if (code === "provision_approval_required") {
1811
+ throw new Error(
1812
+ `${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`
1813
+ );
1814
+ }
1802
1815
  throw new Error(
1803
1816
  `${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`
1804
1817
  );
1805
1818
  }
1806
1819
  throw new Error(`${env}: tenant access preflight (${tenantId}) failed: ${res.status} ${await safeText4(res)}`);
1807
1820
  }
1821
+ function errorCode(text2) {
1822
+ try {
1823
+ const body = JSON.parse(text2);
1824
+ return typeof body.error?.code === "string" ? body.error.code : null;
1825
+ } catch {
1826
+ return null;
1827
+ }
1828
+ }
1808
1829
  async function postJson(doFetch, url, bearer, body) {
1809
1830
  const res = await doFetch(url, {
1810
1831
  method: "POST",
@@ -3305,7 +3326,9 @@ async function secretsSet(options) {
3305
3326
  throw new Error('"$"-prefixed vault names are platform-reserved; for the Clerk secret key use "odla-ai secrets set-clerk-key"');
3306
3327
  }
3307
3328
  const { cfg, tenantId, value: value2, doFetch, out } = await resolveVaultWrite(options);
3308
- const token = await getDeveloperToken(cfg, options, doFetch, out);
3329
+ const token = await getDeveloperToken(cfg, options, doFetch, out, {
3330
+ optionalProjectCapabilities: ["app.manage"]
3331
+ });
3309
3332
  try {
3310
3333
  await putSecret({ endpoint: cfg.dbEndpoint, token, fetch: doFetch }, tenantId, name, value2);
3311
3334
  } catch (err) {
@@ -13199,4 +13222,4 @@ export {
13199
13222
  exitCodeFor,
13200
13223
  runCli
13201
13224
  };
13202
- //# sourceMappingURL=chunk-LT56MKDK.js.map
13225
+ //# sourceMappingURL=chunk-Y7WFLSTN.js.map