@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.cjs CHANGED
@@ -2548,7 +2548,7 @@ function parseCalendarStatus(raw, env) {
2548
2548
  throw new Error("calendar status returned unsupported access");
2549
2549
  }
2550
2550
  const errorValue = record(value2.error) ?? record(connection.error);
2551
- const errorCode = textField(value2.lastErrorCode, 128);
2551
+ const errorCode2 = textField(value2.lastErrorCode, 128);
2552
2552
  const bookingPageValue = Object.hasOwn(value2, "bookingPageUrl") ? value2.bookingPageUrl : Object.hasOwn(config, "bookingPageUrl") ? config.bookingPageUrl : googleConfig.bookingPageUrl;
2553
2553
  const connected = typeof (value2.connected ?? connection.connected) === "boolean" ? Boolean(value2.connected ?? connection.connected) : ["healthy", "degraded"].includes(stateValue);
2554
2554
  const bookingCalendarId = textField(value2.bookingCalendarId ?? config.bookingCalendarId, 1024);
@@ -2567,10 +2567,10 @@ function parseCalendarStatus(raw, env) {
2567
2567
  ...optionalNullableUrl("bookingPageUrl", bookingPageValue),
2568
2568
  grantedScopes: stringList(value2.grantedScopes ?? connection.grantedScopes ?? connection.scopes),
2569
2569
  ...optionalText("attemptId", value2.attemptId ?? connection.attemptId, 180),
2570
- ...errorValue || errorCode ? { error: {
2570
+ ...errorValue || errorCode2 ? { error: {
2571
2571
  ...textField(errorValue?.code, 128) ? { code: textField(errorValue?.code, 128) } : {},
2572
2572
  ...textField(errorValue?.message, 500) ? { message: textField(errorValue?.message, 500) } : {},
2573
- ...!errorValue && errorCode ? { code: errorCode } : {}
2573
+ ...!errorValue && errorCode2 ? { code: errorCode2 } : {}
2574
2574
  } } : {}
2575
2575
  };
2576
2576
  }
@@ -2697,7 +2697,7 @@ async function calendarCalendars(options) {
2697
2697
  return calendars;
2698
2698
  }
2699
2699
  async function calendarConnect(options) {
2700
- const { cfg, ctx, out } = await lifecycleContext(options);
2700
+ const { cfg, ctx, out } = await lifecycleContext(options, ["app.manage"]);
2701
2701
  productionConsent(ctx.env, options.yes, "connect calendar");
2702
2702
  const page2 = calendarBookingPageUrl(cfg, ctx.env);
2703
2703
  const applied = page2 === void 0 ? await readCalendarStatus(ctx) : await applyCalendarSettings(ctx, page2);
@@ -2723,7 +2723,7 @@ async function ensureCalendarConnected(ctx, options) {
2723
2723
  const connectOptions = connectionOptions(options, out);
2724
2724
  return await continueConnectedCalendar(ctx, current, connectOptions) ?? connectWithContext(ctx, connectOptions);
2725
2725
  }
2726
- async function lifecycleContext(options) {
2726
+ async function lifecycleContext(options, optionalProjectCapabilities = []) {
2727
2727
  const cfg = await loadProjectConfig(options.configPath);
2728
2728
  if (!cfg.services.includes("calendar")) throw new Error("calendar service is not enabled in config services");
2729
2729
  const env = options.env ?? (cfg.envs.includes("dev") ? "dev" : cfg.envs[0]);
@@ -2741,7 +2741,8 @@ async function lifecycleContext(options) {
2741
2741
  openApprovalUrl: options.openConsentUrl
2742
2742
  },
2743
2743
  doFetch,
2744
- out
2744
+ out,
2745
+ { optionalProjectCapabilities }
2745
2746
  );
2746
2747
  return { cfg, ctx: { platform: cfg.platformUrl, appId: cfg.app.id, env, token, fetch: doFetch }, out };
2747
2748
  }
@@ -3116,12 +3117,32 @@ async function assertTenantAdminAccess(doFetch, cfg, env, token) {
3116
3117
  });
3117
3118
  if (res.ok || res.status === 404) return;
3118
3119
  if (res.status === 403) {
3120
+ const detail = await safeText4(res);
3121
+ const code = errorCode(detail);
3122
+ if (code === "human_session_required") {
3123
+ throw new Error(
3124
+ `${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`
3125
+ );
3126
+ }
3127
+ if (code === "provision_approval_required") {
3128
+ throw new Error(
3129
+ `${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`
3130
+ );
3131
+ }
3119
3132
  throw new Error(
3120
3133
  `${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`
3121
3134
  );
3122
3135
  }
3123
3136
  throw new Error(`${env}: tenant access preflight (${tenantId}) failed: ${res.status} ${await safeText4(res)}`);
3124
3137
  }
3138
+ function errorCode(text2) {
3139
+ try {
3140
+ const body = JSON.parse(text2);
3141
+ return typeof body.error?.code === "string" ? body.error.code : null;
3142
+ } catch {
3143
+ return null;
3144
+ }
3145
+ }
3125
3146
  async function postJson(doFetch, url, bearer, body) {
3126
3147
  const res = await doFetch(url, {
3127
3148
  method: "POST",
@@ -4472,7 +4493,9 @@ async function secretsSet(options) {
4472
4493
  throw new Error('"$"-prefixed vault names are platform-reserved; for the Clerk secret key use "odla-ai secrets set-clerk-key"');
4473
4494
  }
4474
4495
  const { cfg, tenantId, value: value2, doFetch, out } = await resolveVaultWrite(options);
4475
- const token = await getDeveloperToken(cfg, options, doFetch, out);
4496
+ const token = await getDeveloperToken(cfg, options, doFetch, out, {
4497
+ optionalProjectCapabilities: ["app.manage"]
4498
+ });
4476
4499
  try {
4477
4500
  await (0, import_ai2.putSecret)({ endpoint: cfg.dbEndpoint, token, fetch: doFetch }, tenantId, name, value2);
4478
4501
  } catch (err) {