@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/index.cjs CHANGED
@@ -2616,7 +2616,7 @@ function parseCalendarStatus(raw, env) {
2616
2616
  throw new Error("calendar status returned unsupported access");
2617
2617
  }
2618
2618
  const errorValue = record(value2.error) ?? record(connection.error);
2619
- const errorCode = textField(value2.lastErrorCode, 128);
2619
+ const errorCode2 = textField(value2.lastErrorCode, 128);
2620
2620
  const bookingPageValue = Object.hasOwn(value2, "bookingPageUrl") ? value2.bookingPageUrl : Object.hasOwn(config, "bookingPageUrl") ? config.bookingPageUrl : googleConfig.bookingPageUrl;
2621
2621
  const connected = typeof (value2.connected ?? connection.connected) === "boolean" ? Boolean(value2.connected ?? connection.connected) : ["healthy", "degraded"].includes(stateValue);
2622
2622
  const bookingCalendarId = textField(value2.bookingCalendarId ?? config.bookingCalendarId, 1024);
@@ -2635,10 +2635,10 @@ function parseCalendarStatus(raw, env) {
2635
2635
  ...optionalNullableUrl("bookingPageUrl", bookingPageValue),
2636
2636
  grantedScopes: stringList(value2.grantedScopes ?? connection.grantedScopes ?? connection.scopes),
2637
2637
  ...optionalText("attemptId", value2.attemptId ?? connection.attemptId, 180),
2638
- ...errorValue || errorCode ? { error: {
2638
+ ...errorValue || errorCode2 ? { error: {
2639
2639
  ...textField(errorValue?.code, 128) ? { code: textField(errorValue?.code, 128) } : {},
2640
2640
  ...textField(errorValue?.message, 500) ? { message: textField(errorValue?.message, 500) } : {},
2641
- ...!errorValue && errorCode ? { code: errorCode } : {}
2641
+ ...!errorValue && errorCode2 ? { code: errorCode2 } : {}
2642
2642
  } } : {}
2643
2643
  };
2644
2644
  }
@@ -2765,7 +2765,7 @@ async function calendarCalendars(options) {
2765
2765
  return calendars;
2766
2766
  }
2767
2767
  async function calendarConnect(options) {
2768
- const { cfg, ctx, out } = await lifecycleContext(options);
2768
+ const { cfg, ctx, out } = await lifecycleContext(options, ["app.manage"]);
2769
2769
  productionConsent(ctx.env, options.yes, "connect calendar");
2770
2770
  const page2 = calendarBookingPageUrl(cfg, ctx.env);
2771
2771
  const applied = page2 === void 0 ? await readCalendarStatus(ctx) : await applyCalendarSettings(ctx, page2);
@@ -2791,7 +2791,7 @@ async function ensureCalendarConnected(ctx, options) {
2791
2791
  const connectOptions = connectionOptions(options, out);
2792
2792
  return await continueConnectedCalendar(ctx, current, connectOptions) ?? connectWithContext(ctx, connectOptions);
2793
2793
  }
2794
- async function lifecycleContext(options) {
2794
+ async function lifecycleContext(options, optionalProjectCapabilities = []) {
2795
2795
  const cfg = await loadProjectConfig(options.configPath);
2796
2796
  if (!cfg.services.includes("calendar")) throw new Error("calendar service is not enabled in config services");
2797
2797
  const env = options.env ?? (cfg.envs.includes("dev") ? "dev" : cfg.envs[0]);
@@ -2809,7 +2809,8 @@ async function lifecycleContext(options) {
2809
2809
  openApprovalUrl: options.openConsentUrl
2810
2810
  },
2811
2811
  doFetch,
2812
- out
2812
+ out,
2813
+ { optionalProjectCapabilities }
2813
2814
  );
2814
2815
  return { cfg, ctx: { platform: cfg.platformUrl, appId: cfg.app.id, env, token, fetch: doFetch }, out };
2815
2816
  }
@@ -3184,12 +3185,32 @@ async function assertTenantAdminAccess(doFetch, cfg, env, token) {
3184
3185
  });
3185
3186
  if (res.ok || res.status === 404) return;
3186
3187
  if (res.status === 403) {
3188
+ const detail = await safeText4(res);
3189
+ const code = errorCode(detail);
3190
+ if (code === "human_session_required") {
3191
+ throw new Error(
3192
+ `${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`
3193
+ );
3194
+ }
3195
+ if (code === "provision_approval_required") {
3196
+ throw new Error(
3197
+ `${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`
3198
+ );
3199
+ }
3187
3200
  throw new Error(
3188
3201
  `${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`
3189
3202
  );
3190
3203
  }
3191
3204
  throw new Error(`${env}: tenant access preflight (${tenantId}) failed: ${res.status} ${await safeText4(res)}`);
3192
3205
  }
3206
+ function errorCode(text2) {
3207
+ try {
3208
+ const body = JSON.parse(text2);
3209
+ return typeof body.error?.code === "string" ? body.error.code : null;
3210
+ } catch {
3211
+ return null;
3212
+ }
3213
+ }
3193
3214
  async function postJson(doFetch, url, bearer, body) {
3194
3215
  const res = await doFetch(url, {
3195
3216
  method: "POST",
@@ -4540,7 +4561,9 @@ async function secretsSet(options) {
4540
4561
  throw new Error('"$"-prefixed vault names are platform-reserved; for the Clerk secret key use "odla-ai secrets set-clerk-key"');
4541
4562
  }
4542
4563
  const { cfg, tenantId, value: value2, doFetch, out } = await resolveVaultWrite(options);
4543
- const token = await getDeveloperToken(cfg, options, doFetch, out);
4564
+ const token = await getDeveloperToken(cfg, options, doFetch, out, {
4565
+ optionalProjectCapabilities: ["app.manage"]
4566
+ });
4544
4567
  try {
4545
4568
  await (0, import_ai2.putSecret)({ endpoint: cfg.dbEndpoint, token, fetch: doFetch }, tenantId, name, value2);
4546
4569
  } catch (err) {