@alfe.ai/gateway 0.9.11 → 0.9.12

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.
Files changed (2) hide show
  1. package/dist/health.js +282 -187
  2. package/package.json +2 -2
package/dist/health.js CHANGED
@@ -287,190 +287,6 @@ function pluginConnectionId() {
287
287
  return createId(ID_PREFIXES.pluginConnection);
288
288
  }
289
289
  //#endregion
290
- //#region ../../packages-internal/api-client/dist/client.js
291
- /**
292
- * @alfe/api-client — Typed HTTP client for Alfe services.
293
- *
294
- * Platform-agnostic: works in React Native and browser environments.
295
- * Uses standard fetch() API — no Node.js dependencies.
296
- */
297
- var AlfeApiClient = class {
298
- apiBaseUrl;
299
- getToken;
300
- onAuthFailure;
301
- constructor(options) {
302
- this.apiBaseUrl = options.apiBaseUrl.replace(/\/+$/, "");
303
- this.getToken = options.getToken;
304
- this.onAuthFailure = options.onAuthFailure;
305
- }
306
- /**
307
- * Shared fetch logic — handles auth, 401, and network errors.
308
- *
309
- * `skipAuth` callers (public endpoints like OAuth device-code) opt out of
310
- * the auth-header injection AND the synthetic 401 short-circuit. Without
311
- * this opt-out, a CLI calling /auth/device-code (no token yet by design)
312
- * would never reach the network — the `getToken: () => null` path would
313
- * synthesize a 401 and fire onAuthFailure, breaking the entire flow.
314
- */
315
- async _fetchResponse(path, options, skipAuth = false) {
316
- try {
317
- const url = `${this.apiBaseUrl}${path}`;
318
- const headers = new Headers(options?.headers);
319
- if (typeof options?.body === "string" && !headers.has("Content-Type")) headers.set("Content-Type", "application/json");
320
- headers.set("x-correlation-id", correlationId());
321
- if (!skipAuth) {
322
- const token = await this.getToken();
323
- if (!token) {
324
- this.onAuthFailure?.();
325
- return {
326
- ok: false,
327
- result: {
328
- ok: false,
329
- error: "No auth token available",
330
- status: 401
331
- }
332
- };
333
- }
334
- headers.set("Authorization", `Bearer ${token}`);
335
- }
336
- const res = await fetch(url, {
337
- ...options,
338
- headers
339
- });
340
- if (res.status === 401 && !skipAuth) {
341
- this.onAuthFailure?.();
342
- return {
343
- ok: false,
344
- result: {
345
- ok: false,
346
- error: "Session expired",
347
- status: 401
348
- }
349
- };
350
- }
351
- if (!res.ok) {
352
- const text = res.status === 204 ? "" : await res.text();
353
- let body;
354
- if (text) try {
355
- body = JSON.parse(text);
356
- } catch {
357
- body = text;
358
- }
359
- const errBody = body;
360
- return {
361
- ok: false,
362
- result: {
363
- ok: false,
364
- error: (typeof errBody === "object" ? errBody.message : void 0) ?? (typeof body === "string" ? body : `API error: ${String(res.status)}`),
365
- status: res.status
366
- }
367
- };
368
- }
369
- return {
370
- ok: true,
371
- res
372
- };
373
- } catch (err) {
374
- return {
375
- ok: false,
376
- result: {
377
- ok: false,
378
- error: err instanceof Error ? err.message : "Network error"
379
- }
380
- };
381
- }
382
- }
383
- async _fetch(path, options, skipAuth = false) {
384
- const response = await this._fetchResponse(path, options, skipAuth);
385
- if (!response.ok) return response;
386
- const text = response.res.status === 204 ? "" : await response.res.text();
387
- let body;
388
- if (text) try {
389
- body = JSON.parse(text);
390
- } catch {
391
- body = text;
392
- }
393
- return {
394
- ok: true,
395
- res: response.res,
396
- body
397
- };
398
- }
399
- /**
400
- * Make an authenticated request to an Alfe API endpoint.
401
- * Unwraps the @auriclabs/api-core `{ data, timestamp, requestId }` envelope.
402
- */
403
- async request(path, options) {
404
- const result = await this._fetch(path, options);
405
- if (!result.ok) return result.result;
406
- if (result.body === void 0) return {
407
- ok: true,
408
- data: void 0
409
- };
410
- return {
411
- ok: true,
412
- data: result.body.data
413
- };
414
- }
415
- /**
416
- * Make a request to a PUBLIC endpoint that does not require authentication.
417
- * Skips both the Authorization header injection AND the onAuthFailure
418
- * callback. Use for endpoints like /auth/device-code that the CLI hits
419
- * before it has a token.
420
- */
421
- async publicRequest(path, options) {
422
- const result = await this._fetch(path, options, true);
423
- if (!result.ok) return result.result;
424
- if (result.body === void 0) return {
425
- ok: true,
426
- data: void 0
427
- };
428
- return {
429
- ok: true,
430
- data: result.body.data
431
- };
432
- }
433
- /**
434
- * Make an authenticated request that returns the body directly (no envelope unwrap).
435
- * Use for APIs that don't use the @auriclabs/api-core response format (e.g. gateway).
436
- */
437
- async rawRequest(path, options) {
438
- const result = await this._fetch(path, options);
439
- if (!result.ok) return result.result;
440
- return {
441
- ok: true,
442
- data: result.body
443
- };
444
- }
445
- /**
446
- * Make an authenticated request without attempting text/JSON decoding.
447
- * Use for downloads such as a Teams app ZIP where UTF-8 conversion would
448
- * corrupt the payload.
449
- */
450
- async binaryRequest(path, options) {
451
- const result = await this._fetchResponse(path, options);
452
- if (!result.ok) return result.result;
453
- try {
454
- return {
455
- ok: true,
456
- data: {
457
- body: await result.res.arrayBuffer(),
458
- contentType: result.res.headers.get("Content-Type") ?? void 0,
459
- contentDisposition: result.res.headers.get("Content-Disposition") ?? void 0
460
- }
461
- };
462
- } catch (err) {
463
- return {
464
- ok: false,
465
- error: err instanceof Error ? err.message : "Failed to read binary response"
466
- };
467
- }
468
- }
469
- getApiBaseUrl() {
470
- return this.apiBaseUrl;
471
- }
472
- };
473
- //#endregion
474
290
  //#region ../../packages-internal/types/dist/lib/enum-values.js
475
291
  /**
476
292
  * Converts a const enum object into a non-empty readonly tuple.
@@ -4193,7 +4009,8 @@ enumValues({
4193
4009
  ClaudeMax: "claude-max",
4194
4010
  OpenAICodexMax: "openai-codex-max",
4195
4011
  OpenAICodexSubscription: "openai-codex-subscription",
4196
- GeminiMax: "gemini-max"
4012
+ GeminiMax: "gemini-max",
4013
+ AlfeAws: "alfe-aws"
4197
4014
  });
4198
4015
  enumValues({
4199
4016
  Month: "month",
@@ -4347,6 +4164,7 @@ const PERMISSION_CATALOG = {
4347
4164
  org_file: ["read", "write"],
4348
4165
  org_knowledge: ["read", "write"],
4349
4166
  model_policy: ["read", "manage"],
4167
+ data_boundary: ["read", "manage"],
4350
4168
  secret: [
4351
4169
  "create",
4352
4170
  "read",
@@ -4379,7 +4197,8 @@ const PERMISSION_CATALOG = {
4379
4197
  discounts: ["manage"],
4380
4198
  stats: ["read"],
4381
4199
  mobile: ["read", "manage"],
4382
- impersonation: ["manage"]
4200
+ impersonation: ["manage"],
4201
+ partner: ["manage"]
4383
4202
  };
4384
4203
  /**
4385
4204
  * Subjects a tenant may grant via a custom role.
@@ -4400,6 +4219,7 @@ const TENANT_ALLOWED_SUBJECTS = [
4400
4219
  "team",
4401
4220
  "project",
4402
4221
  "model_policy",
4222
+ "data_boundary",
4403
4223
  "role_management",
4404
4224
  "billing",
4405
4225
  "identity",
@@ -4562,6 +4382,26 @@ enumValues({
4562
4382
  Demo: "demo",
4563
4383
  Live: "live"
4564
4384
  });
4385
+ function createClerkReverificationResponse(afterMinutes) {
4386
+ if (!Number.isInteger(afterMinutes) || afterMinutes < 0) throw new TypeError("afterMinutes must be a non-negative integer");
4387
+ return { clerk_error: {
4388
+ type: "forbidden",
4389
+ reason: "reverification-error",
4390
+ metadata: { reverification: {
4391
+ level: "second_factor",
4392
+ afterMinutes
4393
+ } }
4394
+ } };
4395
+ }
4396
+ /** Strictly identify the only authorization hint the API client may expose. */
4397
+ function isClerkReverificationResponse(value) {
4398
+ if (!value || typeof value !== "object") return false;
4399
+ const clerkError = value.clerk_error;
4400
+ if (!clerkError || typeof clerkError !== "object") return false;
4401
+ const error = clerkError;
4402
+ const reverification = error.metadata?.reverification;
4403
+ return error.type === "forbidden" && error.reason === "reverification-error" && reverification?.level === "second_factor" && Number.isInteger(reverification.afterMinutes) && reverification.afterMinutes >= 0;
4404
+ }
4565
4405
  //#endregion
4566
4406
  //#region ../../packages-internal/types/dist/models.js
4567
4407
  const AnthropicModel = {
@@ -4689,6 +4529,35 @@ _enum(QWEN_MODELS);
4689
4529
  string().trim().min(1);
4690
4530
  AnthropicModel.Opus5, AnthropicModel.Opus48, AnthropicModel.Opus47, AnthropicModel.Opus46, AnthropicModel.Sonnet5, AnthropicModel.Sonnet46, AnthropicModel.Haiku45, OpenAIModel.GPT4o, OpenAIModel.GPT4oMini, OpenAIModel.O3, OpenAIModel.GPT41, OpenAIModel.GPT41Mini, OpenAIModel.GPT41Nano, OpenAIModel.GPT54, OpenAIModel.GPT54Mini, OpenAIModel.GPT54Nano, OpenAIModel.GPT54Pro, OpenAIModel.GPT55, OpenAIModel.GPT55Pro, OpenAIModel.GPT56Sol, OpenAIModel.GPT56Terra, OpenAIModel.GPT56Luna, OpenAIModel.O3Mini, OpenAIModel.O4Mini, OpenAIModel.TextEmbedding3Small, OpenAIModel.TextEmbedding3Large, DeepSeekModel.Chat, DeepSeekModel.Reasoner, DeepSeekModel.V4Flash, DeepSeekModel.V4Pro, GoogleModel.Gemini35Flash, GoogleModel.Gemini31Pro, GoogleModel.Gemini31FlashLite, GoogleModel.Gemini25Pro, GoogleModel.Gemini25Flash, GoogleModel.Gemini25FlashLite, GoogleModel.Gemini20Flash, MiniMaxModel.M3, MiniMaxModel.M27, MiniMaxModel.M27HighSpeed, MiniMaxModel.M25, MiniMaxModel.M21, MiniMaxModel.M2, MistralModel.Large, MistralModel.Medium, MistralModel.Small, MistralModel.Codestral, MistralModel.Ministral8b, MistralModel.Ministral3b, MistralModel.MagistralMedium, MistralModel.MagistralSmall, MistralModel.DevstralMedium, XAIModel.Grok45, XAIModel.Grok43, XAIModel.Grok4, XAIModel.Grok41Fast, ZhipuModel.GLM52, ZhipuModel.GLM51, ZhipuModel.GLM46, ZhipuModel.GLM45, ZhipuModel.GLM45Air, MoonshotModel.K3, MoonshotModel.K26, MoonshotModel.K27Code, MoonshotModel.K27CodeHighSpeed, QwenModel.Qwen37Max, QwenModel.Qwen37Plus, QwenModel.Qwen36Flash, QwenModel.Qwen35Flash;
4691
4531
  AnthropicModel.Opus5, AnthropicModel.Opus48, AnthropicModel.Opus47, AnthropicModel.Opus46, AnthropicModel.Sonnet5, AnthropicModel.Sonnet46, AnthropicModel.Haiku45, OpenAIModel.GPT4o, OpenAIModel.GPT4oMini, OpenAIModel.O3, OpenAIModel.GPT41, OpenAIModel.GPT41Mini, OpenAIModel.GPT41Nano, OpenAIModel.GPT54, OpenAIModel.GPT54Mini, OpenAIModel.GPT54Nano, OpenAIModel.GPT54Pro, OpenAIModel.GPT55, OpenAIModel.GPT55Pro, OpenAIModel.GPT56Sol, OpenAIModel.GPT56Terra, OpenAIModel.GPT56Luna, OpenAIModel.O3Mini, OpenAIModel.O4Mini, OpenAIModel.TextEmbedding3Small, OpenAIModel.TextEmbedding3Large, DeepSeekModel.Chat, DeepSeekModel.Reasoner, DeepSeekModel.V4Flash, DeepSeekModel.V4Pro, GoogleModel.Gemini35Flash, GoogleModel.Gemini31Pro, GoogleModel.Gemini31FlashLite, GoogleModel.Gemini25Pro, GoogleModel.Gemini25Flash, GoogleModel.Gemini25FlashLite, GoogleModel.Gemini20Flash, MiniMaxModel.M3, MiniMaxModel.M27, MiniMaxModel.M27HighSpeed, MiniMaxModel.M25, MiniMaxModel.M21, MiniMaxModel.M2, MistralModel.Large, MistralModel.Medium, MistralModel.Small, MistralModel.Codestral, MistralModel.Ministral8b, MistralModel.Ministral3b, MistralModel.MagistralMedium, MistralModel.MagistralSmall, MistralModel.DevstralMedium, XAIModel.Grok45, XAIModel.Grok43, XAIModel.Grok4, XAIModel.Grok41Fast, ZhipuModel.GLM52, ZhipuModel.GLM51, ZhipuModel.GLM46, ZhipuModel.GLM45, ZhipuModel.GLM45Air, MoonshotModel.K3, MoonshotModel.K26, MoonshotModel.K27Code, MoonshotModel.K27CodeHighSpeed, QwenModel.Qwen37Max, QwenModel.Qwen37Plus, QwenModel.Qwen36Flash, QwenModel.Qwen35Flash;
4532
+ enumValues({
4533
+ Standard: "standard",
4534
+ AwsPrivate: "aws_private"
4535
+ });
4536
+ enumValues({ ApSoutheast2: "ap-southeast-2" });
4537
+ enumValues({
4538
+ Standard: "standard",
4539
+ Requested: "requested",
4540
+ Provisioning: "provisioning",
4541
+ Ready: "ready",
4542
+ CuttingOver: "cutting_over",
4543
+ Active: "active",
4544
+ Failing: "failing",
4545
+ Decommissioning: "decommissioning"
4546
+ });
4547
+ enumValues({
4548
+ RegionalShared: "regional_shared",
4549
+ Dedicated: "dedicated"
4550
+ });
4551
+ enumValues({
4552
+ Inference: "inference",
4553
+ AuthProjection: "auth_projection",
4554
+ ChatGateway: "chat_gateway",
4555
+ AgentCompute: "agent_compute",
4556
+ Attachments: "attachments",
4557
+ Memory: "memory",
4558
+ CapabilityPolicy: "capability_policy",
4559
+ Observability: "observability"
4560
+ });
4692
4561
  enumValues({
4693
4562
  PendingChallenge: "pending_challenge",
4694
4563
  Creating: "creating",
@@ -4777,6 +4646,8 @@ const NotificationType = {
4777
4646
  BrowserTakeoverRequested: "browser_takeover_requested",
4778
4647
  InviteCreated: "onboarding.invite.created",
4779
4648
  OrgClaimed: "onboarding.org.claimed",
4649
+ ElevatedSupportRequested: "partner.elevated_support.requested",
4650
+ ElevatedSupportStarted: "partner.elevated_support.started",
4780
4651
  TeamMemberAdded: "team.member.added",
4781
4652
  ProjectMemberAdded: "project.member.added",
4782
4653
  IntegrationInstalled: "integration.installed",
@@ -4791,7 +4662,213 @@ const RecipientStrategy = {
4791
4662
  TenantAdmins: "tenant_admins",
4792
4663
  SpecificUser: "specific_user"
4793
4664
  };
4794
- NotificationType.PaymentSucceeded, NotificationCategory.Billing, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationType.PaymentFailed, NotificationCategory.Billing, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationChannel.Sms, NotificationType.TopUpCompleted, NotificationCategory.Billing, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationType.AutoRechargeCompleted, NotificationCategory.Billing, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationType.AutoRechargeFailed, NotificationCategory.Billing, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationChannel.Sms, NotificationType.SubscriptionCreated, NotificationCategory.Billing, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationType.SubscriptionCancelled, NotificationCategory.Billing, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationType.StartupGrantEnded, NotificationCategory.Billing, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationType.GrantEnded, NotificationCategory.Billing, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationType.EnterpriseGrantEnded, NotificationCategory.Billing, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationType.SubscriptionPastDue, NotificationCategory.Billing, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationChannel.Sms, NotificationType.BalanceThresholdWarning, NotificationCategory.Billing, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationType.PlatformTierPriceIncrease, NotificationCategory.Billing, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationType.AgentCreated, NotificationCategory.Agents, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationType.AgentProvisionFailed, NotificationCategory.Agents, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationType.AgentBillingSuspended, NotificationCategory.Agents, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationType.AgentDisconnectedExtended, NotificationCategory.Agents, RecipientStrategy.TenantAdmins, NotificationChannel.Push, NotificationType.BrowserTakeoverRequested, NotificationCategory.Agents, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationType.InviteCreated, NotificationCategory.System, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationType.OrgClaimed, NotificationCategory.System, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationType.TeamMemberAdded, NotificationCategory.Team, RecipientStrategy.SpecificUser, NotificationChannel.Email, NotificationChannel.Push, NotificationType.ProjectMemberAdded, NotificationCategory.Team, RecipientStrategy.SpecificUser, NotificationChannel.Email, NotificationChannel.Push, NotificationType.IntegrationInstalled, NotificationCategory.Integrations, RecipientStrategy.TenantAdmins, NotificationChannel.Push, NotificationType.IntegrationRemoved, NotificationCategory.Integrations, RecipientStrategy.TenantAdmins, NotificationChannel.Push;
4665
+ NotificationType.PaymentSucceeded, NotificationCategory.Billing, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationType.PaymentFailed, NotificationCategory.Billing, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationChannel.Sms, NotificationType.TopUpCompleted, NotificationCategory.Billing, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationType.AutoRechargeCompleted, NotificationCategory.Billing, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationType.AutoRechargeFailed, NotificationCategory.Billing, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationChannel.Sms, NotificationType.SubscriptionCreated, NotificationCategory.Billing, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationType.SubscriptionCancelled, NotificationCategory.Billing, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationType.StartupGrantEnded, NotificationCategory.Billing, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationType.GrantEnded, NotificationCategory.Billing, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationType.EnterpriseGrantEnded, NotificationCategory.Billing, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationType.SubscriptionPastDue, NotificationCategory.Billing, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationChannel.Sms, NotificationType.BalanceThresholdWarning, NotificationCategory.Billing, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationType.PlatformTierPriceIncrease, NotificationCategory.Billing, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationType.AgentCreated, NotificationCategory.Agents, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationType.AgentProvisionFailed, NotificationCategory.Agents, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationType.AgentBillingSuspended, NotificationCategory.Agents, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationType.AgentDisconnectedExtended, NotificationCategory.Agents, RecipientStrategy.TenantAdmins, NotificationChannel.Push, NotificationType.BrowserTakeoverRequested, NotificationCategory.Agents, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationType.InviteCreated, NotificationCategory.System, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationType.OrgClaimed, NotificationCategory.System, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationType.ElevatedSupportRequested, NotificationCategory.System, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationType.ElevatedSupportStarted, NotificationCategory.System, RecipientStrategy.TenantAdmins, NotificationChannel.Email, NotificationChannel.Push, NotificationType.TeamMemberAdded, NotificationCategory.Team, RecipientStrategy.SpecificUser, NotificationChannel.Email, NotificationChannel.Push, NotificationType.ProjectMemberAdded, NotificationCategory.Team, RecipientStrategy.SpecificUser, NotificationChannel.Email, NotificationChannel.Push, NotificationType.IntegrationInstalled, NotificationCategory.Integrations, RecipientStrategy.TenantAdmins, NotificationChannel.Push, NotificationType.IntegrationRemoved, NotificationCategory.Integrations, RecipientStrategy.TenantAdmins, NotificationChannel.Push;
4666
+ //#endregion
4667
+ //#region ../../packages-internal/api-client/dist/client.js
4668
+ /**
4669
+ * @alfe/api-client — Typed HTTP client for Alfe services.
4670
+ *
4671
+ * Platform-agnostic: works in React Native and browser environments.
4672
+ * Uses standard fetch() API — no Node.js dependencies.
4673
+ */
4674
+ var AlfeApiClient = class {
4675
+ apiBaseUrl;
4676
+ getToken;
4677
+ onAuthFailure;
4678
+ constructor(options) {
4679
+ this.apiBaseUrl = options.apiBaseUrl.replace(/\/+$/, "");
4680
+ this.getToken = options.getToken;
4681
+ this.onAuthFailure = options.onAuthFailure;
4682
+ }
4683
+ /**
4684
+ * Shared fetch logic — handles auth, 401, and network errors.
4685
+ *
4686
+ * `skipAuth` callers (public endpoints like OAuth device-code) opt out of
4687
+ * the auth-header injection AND the synthetic 401 short-circuit. Without
4688
+ * this opt-out, a CLI calling /auth/device-code (no token yet by design)
4689
+ * would never reach the network — the `getToken: () => null` path would
4690
+ * synthesize a 401 and fire onAuthFailure, breaking the entire flow.
4691
+ */
4692
+ async _fetchResponse(path, options, skipAuth = false) {
4693
+ try {
4694
+ const url = `${this.apiBaseUrl}${path}`;
4695
+ const headers = new Headers(options?.headers);
4696
+ if (typeof options?.body === "string" && !headers.has("Content-Type")) headers.set("Content-Type", "application/json");
4697
+ headers.set("x-correlation-id", correlationId());
4698
+ if (!skipAuth) {
4699
+ const token = await this.getToken();
4700
+ if (!token) {
4701
+ this.onAuthFailure?.();
4702
+ return {
4703
+ ok: false,
4704
+ result: {
4705
+ ok: false,
4706
+ error: "No auth token available",
4707
+ status: 401
4708
+ }
4709
+ };
4710
+ }
4711
+ headers.set("Authorization", `Bearer ${token}`);
4712
+ }
4713
+ const res = await fetch(url, {
4714
+ ...options,
4715
+ headers
4716
+ });
4717
+ if (res.status === 401 && !skipAuth) {
4718
+ this.onAuthFailure?.();
4719
+ return {
4720
+ ok: false,
4721
+ result: {
4722
+ ok: false,
4723
+ error: "Session expired",
4724
+ status: 401
4725
+ }
4726
+ };
4727
+ }
4728
+ if (!res.ok) {
4729
+ const text = res.status === 204 ? "" : await res.text();
4730
+ let body;
4731
+ if (text) try {
4732
+ body = JSON.parse(text);
4733
+ } catch {
4734
+ body = text;
4735
+ }
4736
+ const errBody = body;
4737
+ const errorMessage = typeof errBody === "object" ? errBody.message : void 0;
4738
+ return {
4739
+ ok: false,
4740
+ body,
4741
+ result: {
4742
+ ok: false,
4743
+ error: errorMessage ?? (typeof body === "string" ? body : `API error: ${String(res.status)}`),
4744
+ status: res.status
4745
+ }
4746
+ };
4747
+ }
4748
+ return {
4749
+ ok: true,
4750
+ res
4751
+ };
4752
+ } catch (err) {
4753
+ return {
4754
+ ok: false,
4755
+ result: {
4756
+ ok: false,
4757
+ error: err instanceof Error ? err.message : "Network error"
4758
+ }
4759
+ };
4760
+ }
4761
+ }
4762
+ async _fetch(path, options, skipAuth = false) {
4763
+ const response = await this._fetchResponse(path, options, skipAuth);
4764
+ if (!response.ok) return response;
4765
+ const text = response.res.status === 204 ? "" : await response.res.text();
4766
+ let body;
4767
+ if (text) try {
4768
+ body = JSON.parse(text);
4769
+ } catch {
4770
+ body = text;
4771
+ }
4772
+ return {
4773
+ ok: true,
4774
+ res: response.res,
4775
+ body
4776
+ };
4777
+ }
4778
+ /**
4779
+ * Make an authenticated request to an Alfe API endpoint.
4780
+ * Unwraps the @auriclabs/api-core `{ data, timestamp, requestId }` envelope.
4781
+ */
4782
+ async request(path, options) {
4783
+ const result = await this._fetch(path, options);
4784
+ if (!result.ok) return result.result;
4785
+ if (result.body === void 0) return {
4786
+ ok: true,
4787
+ data: void 0
4788
+ };
4789
+ return {
4790
+ ok: true,
4791
+ data: result.body.data
4792
+ };
4793
+ }
4794
+ /**
4795
+ * Make an authenticated request whose 403 response may ask Clerk to
4796
+ * reverify the current session. Unlike `request`, this preserves only the
4797
+ * strictly validated Clerk hint; all ordinary failures retain `ApiResult`.
4798
+ */
4799
+ async reverifiableRequest(path, options) {
4800
+ const result = await this._fetch(path, options);
4801
+ if (!result.ok) {
4802
+ if (isClerkReverificationResponse(result.body)) return createClerkReverificationResponse(result.body.clerk_error.metadata.reverification.afterMinutes);
4803
+ return result.result;
4804
+ }
4805
+ if (result.body === void 0) return {
4806
+ ok: true,
4807
+ data: void 0
4808
+ };
4809
+ return {
4810
+ ok: true,
4811
+ data: result.body.data
4812
+ };
4813
+ }
4814
+ /**
4815
+ * Make a request to a PUBLIC endpoint that does not require authentication.
4816
+ * Skips both the Authorization header injection AND the onAuthFailure
4817
+ * callback. Use for endpoints like /auth/device-code that the CLI hits
4818
+ * before it has a token.
4819
+ */
4820
+ async publicRequest(path, options) {
4821
+ const result = await this._fetch(path, options, true);
4822
+ if (!result.ok) return result.result;
4823
+ if (result.body === void 0) return {
4824
+ ok: true,
4825
+ data: void 0
4826
+ };
4827
+ return {
4828
+ ok: true,
4829
+ data: result.body.data
4830
+ };
4831
+ }
4832
+ /**
4833
+ * Make an authenticated request that returns the body directly (no envelope unwrap).
4834
+ * Use for APIs that don't use the @auriclabs/api-core response format (e.g. gateway).
4835
+ */
4836
+ async rawRequest(path, options) {
4837
+ const result = await this._fetch(path, options);
4838
+ if (!result.ok) return result.result;
4839
+ return {
4840
+ ok: true,
4841
+ data: result.body
4842
+ };
4843
+ }
4844
+ /**
4845
+ * Make an authenticated request without attempting text/JSON decoding.
4846
+ * Use for downloads such as a Teams app ZIP where UTF-8 conversion would
4847
+ * corrupt the payload.
4848
+ */
4849
+ async binaryRequest(path, options) {
4850
+ const result = await this._fetchResponse(path, options);
4851
+ if (!result.ok) return result.result;
4852
+ try {
4853
+ return {
4854
+ ok: true,
4855
+ data: {
4856
+ body: await result.res.arrayBuffer(),
4857
+ contentType: result.res.headers.get("Content-Type") ?? void 0,
4858
+ contentDisposition: result.res.headers.get("Content-Disposition") ?? void 0
4859
+ }
4860
+ };
4861
+ } catch (err) {
4862
+ return {
4863
+ ok: false,
4864
+ error: err instanceof Error ? err.message : "Failed to read binary response"
4865
+ };
4866
+ }
4867
+ }
4868
+ getApiBaseUrl() {
4869
+ return this.apiBaseUrl;
4870
+ }
4871
+ };
4795
4872
  //#endregion
4796
4873
  //#region ../../packages-internal/api-client/dist/services/auth.js
4797
4874
  var AuthService = class {
@@ -4818,6 +4895,24 @@ var AuthService = class {
4818
4895
  deleteToken(tokenId) {
4819
4896
  return this.client.request(`${this.prefix}/tokens/${encodeURIComponent(tokenId)}`, { method: "DELETE" });
4820
4897
  }
4898
+ mintPartnerDelegation(input) {
4899
+ return this.client.request(`${this.prefix}/partner-delegations`, {
4900
+ method: "POST",
4901
+ body: JSON.stringify(input)
4902
+ });
4903
+ }
4904
+ mintPartnerElevatedDelegation(input) {
4905
+ return this.client.request(`${this.prefix}/partner-delegations/elevated`, {
4906
+ method: "POST",
4907
+ body: JSON.stringify(input)
4908
+ });
4909
+ }
4910
+ refreshPartnerDelegation(delegationId) {
4911
+ return this.client.request(`${this.prefix}/partner-delegations/${encodeURIComponent(delegationId)}/refresh`, { method: "POST" });
4912
+ }
4913
+ revokePartnerDelegation(delegationId) {
4914
+ return this.client.request(`${this.prefix}/partner-delegations/${encodeURIComponent(delegationId)}`, { method: "DELETE" });
4915
+ }
4821
4916
  /**
4822
4917
  * Start a device-code flow. Called by the CLI when the user runs
4823
4918
  * `alfe login` and picks the browser path. The returned `device_code`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alfe.ai/gateway",
3
- "version": "0.9.11",
3
+ "version": "0.9.12",
4
4
  "description": "Alfe local gateway daemon — persistent control plane for agent integrations",
5
5
  "type": "module",
6
6
  "bin": {
@@ -23,7 +23,7 @@
23
23
  "pino-roll": "^1.2.0",
24
24
  "smol-toml": ">=1.6.1",
25
25
  "ws": "^8.18.0",
26
- "@alfe.ai/agent-api-client": "^0.16.1",
26
+ "@alfe.ai/agent-api-client": "^0.17.0",
27
27
  "@alfe.ai/ai-proxy-local": "^0.0.16",
28
28
  "@alfe.ai/config": "^0.4.1",
29
29
  "@alfe.ai/integration-manifest": "^0.3.6",