@alfe.ai/gateway 0.9.0 → 0.9.1

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/health.js CHANGED
@@ -94,7 +94,7 @@ const PINNED_OPENCLAW_VERSION = "2026.6.11";
94
94
  * `PINNED_OPENCLAW_VERSION` — there is no `services/compute/Dockerfile` mirror to
95
95
  * keep in sync.
96
96
  */
97
- const PINNED_CLAUDE_CODE_HOST_VERSION = "0.1.2";
97
+ const PINNED_CLAUDE_CODE_HOST_VERSION = "0.1.3";
98
98
  //#endregion
99
99
  //#region ../../packages-internal/ids/dist/prefixes.js
100
100
  const ID_PREFIXES = {
@@ -414,399 +414,6 @@ var AlfeApiClient = class {
414
414
  }
415
415
  };
416
416
  //#endregion
417
- //#region ../../packages-internal/api-client/dist/services/auth.js
418
- var AuthService = class {
419
- client;
420
- constructor(client) {
421
- this.client = client;
422
- }
423
- prefix = "/auth";
424
- validate(token) {
425
- return this.client.request(`${this.prefix}/validate`, {
426
- method: "POST",
427
- body: JSON.stringify({ token })
428
- });
429
- }
430
- listTokens() {
431
- return this.client.request(`${this.prefix}/tokens`);
432
- }
433
- createToken(data) {
434
- return this.client.request(`${this.prefix}/tokens`, {
435
- method: "POST",
436
- body: JSON.stringify(data)
437
- });
438
- }
439
- deleteToken(tokenId) {
440
- return this.client.request(`${this.prefix}/tokens/${tokenId}`, { method: "DELETE" });
441
- }
442
- /**
443
- * Start a device-code flow. Called by the CLI when the user runs
444
- * `alfe login` and picks the browser path. The returned `device_code`
445
- * is the CLI's bearer secret for polling /auth/device-token; the
446
- * `user_code` is what the user types/sees on the dashboard.
447
- *
448
- * Uses `publicRequest` because the CLI has no token yet — the standard
449
- * `request` path would short-circuit with a synthetic 401.
450
- */
451
- startDeviceCode(input) {
452
- return this.client.publicRequest(`${this.prefix}/device-code`, {
453
- method: "POST",
454
- body: JSON.stringify(input)
455
- });
456
- }
457
- /**
458
- * Poll for the minted API key. Public endpoint. Returns:
459
- * 200 → { api_key, tenantId, tokenExpiresAt } (success — write to config)
460
- * 428 → still pending (caller should sleep `interval` and retry)
461
- * 429 → polling too fast; caller should back off
462
- * 410 → device-code expired; user must run `alfe login` again
463
- * 400 → already redeemed (security: do not retry)
464
- *
465
- * Surface the HTTP-status code via the standard ApiResult error shape
466
- * so callers can branch.
467
- */
468
- pollDeviceToken(deviceCode) {
469
- return this.client.publicRequest(`${this.prefix}/device-token`, {
470
- method: "POST",
471
- body: JSON.stringify({ device_code: deviceCode })
472
- });
473
- }
474
- /** Dashboard-side. Fetch the device fingerprint for an approval card. */
475
- lookupDeviceCode(userCode) {
476
- return this.client.request(`${this.prefix}/device-code/lookup`, {
477
- method: "POST",
478
- body: JSON.stringify({ user_code: userCode })
479
- });
480
- }
481
- /** Dashboard-side. Approve the pending device-code; CLI's next poll gets the key. */
482
- approveDeviceCode(input) {
483
- return this.client.request(`${this.prefix}/device-code/approve`, {
484
- method: "POST",
485
- body: JSON.stringify({
486
- user_code: input.userCode,
487
- expiresIn: input.expiresIn
488
- })
489
- });
490
- }
491
- getOnboardingStatus() {
492
- return this.client.request(`${this.prefix}/onboarding/status`);
493
- }
494
- completeOnboarding(input) {
495
- return this.client.request(`${this.prefix}/onboarding/complete`, {
496
- method: "POST",
497
- body: JSON.stringify(input)
498
- });
499
- }
500
- getAccessStatus() {
501
- return this.client.request(`${this.prefix}/access/status`);
502
- }
503
- redeemAccessCode(code) {
504
- return this.client.request(`${this.prefix}/access/redeem`, {
505
- method: "POST",
506
- body: JSON.stringify({ code })
507
- });
508
- }
509
- /**
510
- * Fetch the caller's current permission list as enforced by the gateway.
511
- * UI permission providers should call this on mount and refetch on
512
- * Clerk org switch to stay in sync with sub-tenant permission changes.
513
- */
514
- getMyPermissions() {
515
- return this.client.request(`${this.prefix}/me/permissions`);
516
- }
517
- /**
518
- * Preview what deleting the caller's own account will do. Drives the Danger
519
- * Zone copy so the user sees an honest, kind-appropriate warning before the
520
- * irreversible action (a last-admin cascade wipes the whole workspace).
521
- */
522
- getDeletionPreview() {
523
- return this.client.request(`${this.prefix}/me/deletion-preview`);
524
- }
525
- /**
526
- * Permanently delete the caller's own account. Returns `{ status: "deleting" }`
527
- * and tears the account down asynchronously — the Clerk user is deleted shortly
528
- * after, so the caller's session dies. On success, sign out and route the user
529
- * to a terminal "account is being deleted" state; do NOT retry.
530
- *
531
- * Pass `confirmKind` (the accountKind the user actually confirmed, from the
532
- * deletion preview): if membership changed between preview and execute, the
533
- * server answers 409 `account_kind_changed` instead of cascading a scope the
534
- * user never agreed to.
535
- */
536
- deleteAccount(confirmKind) {
537
- return this.client.request(`${this.prefix}/me`, {
538
- method: "DELETE",
539
- ...confirmKind ? { body: JSON.stringify({ confirmKind }) } : {}
540
- });
541
- }
542
- getSubscriptionStatus() {
543
- return this.client.request(`${this.prefix}/subscription`);
544
- }
545
- /**
546
- * Mint a short-lived, single-use Clerk sign-in token for the calling user so
547
- * a native client can hand its logged-in session to the web dashboard
548
- * (`${dashboard}/handoff?__clerk_ticket=<token>`). Server mints only for the
549
- * authenticated user — never a caller-supplied id.
550
- */
551
- createHandoffToken() {
552
- return this.client.request(`${this.prefix}/handoff-token`, { method: "POST" });
553
- }
554
- applyForStartup(input) {
555
- return this.client.request(`${this.prefix}/subscription/apply-startup`, {
556
- method: "POST",
557
- body: JSON.stringify(input)
558
- });
559
- }
560
- /**
561
- * Accept an approved Startup Program invite. Call after the applicant has a
562
- * card on file (confirmed or freshly added) — this mints the Professional
563
- * grant subscription. Idempotent: a repeat call on an already-accepted
564
- * application returns `{ status: "accepted" }` without re-charging.
565
- */
566
- acceptStartup() {
567
- return this.client.request(`${this.prefix}/subscription/accept-startup`, { method: "POST" });
568
- }
569
- createCheckoutSession(input) {
570
- return this.client.request(`${this.prefix}/subscription/checkout`, {
571
- method: "POST",
572
- body: JSON.stringify(input)
573
- });
574
- }
575
- /**
576
- * Change a personal (individual-tier) subscriber's platform plan in place on
577
- * their existing Stripe subscription — no second Checkout, no duplicate sub,
578
- * no double charge. Upgrades prorate immediately; downgrades apply with no
579
- * immediate charge/refund. Returns the updated subscription.
580
- */
581
- changePlatformPlan(input) {
582
- return this.client.request(`${this.prefix}/subscription/change`, {
583
- method: "POST",
584
- body: JSON.stringify(input)
585
- });
586
- }
587
- /**
588
- * Preview the proration cost for changing a personal (individual-tier)
589
- * subscriber's platform plan — read-only companion to `changePlatformPlan`.
590
- * Nothing is charged.
591
- */
592
- previewPlatformPlanChange(input) {
593
- return this.client.request(`${this.prefix}/subscription/change/preview`, {
594
- method: "POST",
595
- body: JSON.stringify(input)
596
- });
597
- }
598
- updateSeats(seats) {
599
- return this.client.request(`${this.prefix}/subscription/seats`, {
600
- method: "POST",
601
- body: JSON.stringify({ seats })
602
- });
603
- }
604
- previewSeatChange(seats) {
605
- return this.client.request(`${this.prefix}/subscription/seats/preview`, {
606
- method: "POST",
607
- body: JSON.stringify({ seats })
608
- });
609
- }
610
- listOrgMembers() {
611
- return this.client.request(`${this.prefix}/org/members`);
612
- }
613
- patchOrgMember(userId, body) {
614
- return this.client.request(`${this.prefix}/org/members/${encodeURIComponent(userId)}`, {
615
- method: "PATCH",
616
- body: JSON.stringify(body)
617
- });
618
- }
619
- removeOrgMember(userId) {
620
- return this.client.request(`${this.prefix}/org/members/${encodeURIComponent(userId)}`, { method: "DELETE" });
621
- }
622
- listOrgInvitations() {
623
- return this.client.request(`${this.prefix}/org/invitations`);
624
- }
625
- createOrgInvitation(input) {
626
- return this.client.request(`${this.prefix}/org/invitations`, {
627
- method: "POST",
628
- body: JSON.stringify(input)
629
- });
630
- }
631
- revokeOrgInvitation(invitationId) {
632
- return this.client.request(`${this.prefix}/org/invitations/${encodeURIComponent(invitationId)}`, { method: "DELETE" });
633
- }
634
- listOrgDomains() {
635
- return this.client.request(`${this.prefix}/org/domains`);
636
- }
637
- createOrgDomain(input) {
638
- return this.client.request(`${this.prefix}/org/domains`, {
639
- method: "POST",
640
- body: JSON.stringify(input)
641
- });
642
- }
643
- deleteOrgDomain(domainId) {
644
- return this.client.request(`${this.prefix}/org/domains/${encodeURIComponent(domainId)}`, { method: "DELETE" });
645
- }
646
- updateOrgSettings(input) {
647
- return this.client.request(`${this.prefix}/org/settings`, {
648
- method: "PATCH",
649
- body: JSON.stringify(input)
650
- });
651
- }
652
- };
653
- //#endregion
654
- //#region ../../packages-internal/api-client/dist/services/integrations.js
655
- var IntegrationsService = class {
656
- client;
657
- constructor(client) {
658
- this.client = client;
659
- }
660
- listScopedInstalls(scope, scopeId) {
661
- const params = new URLSearchParams({
662
- scope,
663
- scopeId
664
- });
665
- return this.client.request(`/integrations/scoped?${params}`);
666
- }
667
- installScoped(data) {
668
- return this.client.request("/integrations/scoped", {
669
- method: "POST",
670
- body: JSON.stringify(data)
671
- });
672
- }
673
- getScopedInstall(integrationId, scope, scopeId) {
674
- const params = new URLSearchParams({
675
- scope,
676
- scopeId
677
- });
678
- return this.client.request(`/integrations/scoped/${encodeURIComponent(integrationId)}?${params}`);
679
- }
680
- updateScopedInstall(integrationId, data) {
681
- return this.client.request(`/integrations/scoped/${encodeURIComponent(integrationId)}`, {
682
- method: "PATCH",
683
- body: JSON.stringify(data)
684
- });
685
- }
686
- removeScopedInstall(integrationId, scope, scopeId) {
687
- const params = new URLSearchParams({
688
- scope,
689
- scopeId
690
- });
691
- return this.client.request(`/integrations/scoped/${encodeURIComponent(integrationId)}?${params}`, { method: "DELETE" });
692
- }
693
- /**
694
- * Reinstall (re-apply latest) a scope-level install. Agent scope is rejected
695
- * by the route — use {@link reinstallIntegration} for agent-scoped reinstall.
696
- */
697
- reinstallScoped(integrationId, scope, scopeId) {
698
- return this.client.request(`/integrations/scoped/${encodeURIComponent(integrationId)}/reinstall`, {
699
- method: "POST",
700
- body: JSON.stringify({
701
- scope,
702
- scopeId
703
- })
704
- });
705
- }
706
- listIntegrations(agentId, options) {
707
- const params = new URLSearchParams();
708
- if (options?.includeInherited) params.set("includeInherited", "true");
709
- if (options?.effective) params.set("effective", "true");
710
- const qs = params.toString();
711
- return this.client.request(`/integrations/agents/${agentId}${qs ? `?${qs}` : ""}`);
712
- }
713
- installIntegration(agentId, data) {
714
- return this.client.request(`/integrations/agents/${agentId}`, {
715
- method: "POST",
716
- body: JSON.stringify(data)
717
- });
718
- }
719
- getIntegrationConfig(agentId, integrationId) {
720
- return this.client.request(`/integrations/agents/${agentId}/${integrationId}/config`);
721
- }
722
- updateIntegration(agentId, integrationId, data) {
723
- return this.client.request(`/integrations/agents/${agentId}/${integrationId}`, {
724
- method: "PATCH",
725
- body: JSON.stringify(data)
726
- });
727
- }
728
- removeIntegration(agentId, integrationId) {
729
- return this.client.request(`/integrations/agents/${agentId}/${integrationId}`, { method: "DELETE" });
730
- }
731
- reinstallIntegration(agentId, integrationId) {
732
- return this.client.request(`/integrations/agents/${agentId}/${integrationId}/reinstall`, { method: "POST" });
733
- }
734
- /**
735
- * Upgrade an integration to the registry's latest version via the fast,
736
- * diff-based daemon path (bumps `version` without `reinstallRequestedAt`).
737
- * The agent stays online — no destructive teardown. Distinct from
738
- * {@link reinstallIntegration}, which is the destructive repair path.
739
- */
740
- upgradeIntegration(agentId, integrationId) {
741
- return this.client.request(`/integrations/agents/${agentId}/${integrationId}/upgrade`, { method: "POST" });
742
- }
743
- getRegistry() {
744
- return this.client.request("/integrations/registry");
745
- }
746
- triggerSync(agentId) {
747
- return this.client.request("/integrations/sync/trigger", {
748
- method: "POST",
749
- body: JSON.stringify({ agentId })
750
- });
751
- }
752
- getDiscordGuildChannels(guildId) {
753
- return this.client.request(`/discord/guilds/${encodeURIComponent(guildId)}/channels`);
754
- }
755
- listMobileNumbers() {
756
- return this.client.request("/mobile/numbers");
757
- }
758
- searchMobileNumbers(country, query) {
759
- const params = new URLSearchParams();
760
- if (country) params.set("country", country);
761
- if (query) params.set("query", query);
762
- return this.client.request(`/mobile/numbers/search?${params}`);
763
- }
764
- assignMobileNumber(agentId, phoneNumber, countryCode) {
765
- return this.client.request("/mobile/numbers/assign", {
766
- method: "POST",
767
- body: JSON.stringify({
768
- agentId,
769
- phoneNumber,
770
- countryCode
771
- })
772
- });
773
- }
774
- releaseMobileNumber(agentId) {
775
- return this.client.request("/mobile/numbers/release", {
776
- method: "POST",
777
- body: JSON.stringify({ agentId })
778
- });
779
- }
780
- getMobileNumber(agentId) {
781
- return this.client.request(`/mobile/numbers?agentId=${encodeURIComponent(agentId)}`);
782
- }
783
- disconnectGoogle(agentId, email) {
784
- const query = email ? `?email=${encodeURIComponent(email)}` : "";
785
- return this.client.request(`/google/agents/${encodeURIComponent(agentId)}/account${query}`, { method: "DELETE" });
786
- }
787
- getAtlassianSites(agentId) {
788
- return this.client.request(`/atlassian/agents/${encodeURIComponent(agentId)}/sites`);
789
- }
790
- selectAtlassianSite(agentId, cloudId) {
791
- return this.client.request(`/atlassian/agents/${encodeURIComponent(agentId)}/sites`, {
792
- method: "PUT",
793
- body: JSON.stringify({ cloudId })
794
- });
795
- }
796
- listSlackChannels(agentId) {
797
- return this.client.request(`/slack/agents/${encodeURIComponent(agentId)}/channels`);
798
- }
799
- sendSlackMessage(agentId, channel, text) {
800
- return this.client.request(`/slack/agents/${encodeURIComponent(agentId)}/send`, {
801
- method: "POST",
802
- body: JSON.stringify({
803
- channel,
804
- text
805
- })
806
- });
807
- }
808
- };
809
- //#endregion
810
417
  //#region ../../packages-internal/types/dist/lib/enum-values.js
811
418
  /**
812
419
  * Converts a const enum object into a non-empty readonly tuple.
@@ -4535,6 +4142,7 @@ enumValues({
4535
4142
  Other: "other"
4536
4143
  });
4537
4144
  enumValues({
4145
+ IndividualPayg: "individual_payg",
4538
4146
  IndividualLite: "individual_lite",
4539
4147
  IndividualNormal: "individual_normal",
4540
4148
  IndividualPro: "individual_pro",
@@ -4898,6 +4506,7 @@ const NotificationType = {
4898
4506
  SubscriptionCreated: "subscription.created",
4899
4507
  SubscriptionCancelled: "subscription.cancelled",
4900
4508
  StartupGrantEnded: "startup.grant_ended",
4509
+ GrantEnded: "subscription.grant_ended",
4901
4510
  SubscriptionPastDue: "subscription.past_due",
4902
4511
  BalanceThresholdWarning: "balance.threshold.warning",
4903
4512
  PlatformTierPriceIncrease: "platform.tier_price_increase",
@@ -4918,11 +4527,404 @@ const NotificationChannel = {
4918
4527
  Push: "push",
4919
4528
  Sms: "sms"
4920
4529
  };
4921
- const RecipientStrategy = {
4922
- TenantAdmins: "tenant_admins",
4923
- SpecificUser: "specific_user"
4530
+ const RecipientStrategy = {
4531
+ TenantAdmins: "tenant_admins",
4532
+ SpecificUser: "specific_user"
4533
+ };
4534
+ 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.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.SpecificUser, 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;
4535
+ //#endregion
4536
+ //#region ../../packages-internal/api-client/dist/services/auth.js
4537
+ var AuthService = class {
4538
+ client;
4539
+ constructor(client) {
4540
+ this.client = client;
4541
+ }
4542
+ prefix = "/auth";
4543
+ validate(token) {
4544
+ return this.client.request(`${this.prefix}/validate`, {
4545
+ method: "POST",
4546
+ body: JSON.stringify({ token })
4547
+ });
4548
+ }
4549
+ listTokens() {
4550
+ return this.client.request(`${this.prefix}/tokens`);
4551
+ }
4552
+ createToken(data) {
4553
+ return this.client.request(`${this.prefix}/tokens`, {
4554
+ method: "POST",
4555
+ body: JSON.stringify(data)
4556
+ });
4557
+ }
4558
+ deleteToken(tokenId) {
4559
+ return this.client.request(`${this.prefix}/tokens/${tokenId}`, { method: "DELETE" });
4560
+ }
4561
+ /**
4562
+ * Start a device-code flow. Called by the CLI when the user runs
4563
+ * `alfe login` and picks the browser path. The returned `device_code`
4564
+ * is the CLI's bearer secret for polling /auth/device-token; the
4565
+ * `user_code` is what the user types/sees on the dashboard.
4566
+ *
4567
+ * Uses `publicRequest` because the CLI has no token yet — the standard
4568
+ * `request` path would short-circuit with a synthetic 401.
4569
+ */
4570
+ startDeviceCode(input) {
4571
+ return this.client.publicRequest(`${this.prefix}/device-code`, {
4572
+ method: "POST",
4573
+ body: JSON.stringify(input)
4574
+ });
4575
+ }
4576
+ /**
4577
+ * Poll for the minted API key. Public endpoint. Returns:
4578
+ * 200 → { api_key, tenantId, tokenExpiresAt } (success — write to config)
4579
+ * 428 → still pending (caller should sleep `interval` and retry)
4580
+ * 429 → polling too fast; caller should back off
4581
+ * 410 → device-code expired; user must run `alfe login` again
4582
+ * 400 → already redeemed (security: do not retry)
4583
+ *
4584
+ * Surface the HTTP-status code via the standard ApiResult error shape
4585
+ * so callers can branch.
4586
+ */
4587
+ pollDeviceToken(deviceCode) {
4588
+ return this.client.publicRequest(`${this.prefix}/device-token`, {
4589
+ method: "POST",
4590
+ body: JSON.stringify({ device_code: deviceCode })
4591
+ });
4592
+ }
4593
+ /** Dashboard-side. Fetch the device fingerprint for an approval card. */
4594
+ lookupDeviceCode(userCode) {
4595
+ return this.client.request(`${this.prefix}/device-code/lookup`, {
4596
+ method: "POST",
4597
+ body: JSON.stringify({ user_code: userCode })
4598
+ });
4599
+ }
4600
+ /** Dashboard-side. Approve the pending device-code; CLI's next poll gets the key. */
4601
+ approveDeviceCode(input) {
4602
+ return this.client.request(`${this.prefix}/device-code/approve`, {
4603
+ method: "POST",
4604
+ body: JSON.stringify({
4605
+ user_code: input.userCode,
4606
+ expiresIn: input.expiresIn
4607
+ })
4608
+ });
4609
+ }
4610
+ getOnboardingStatus() {
4611
+ return this.client.request(`${this.prefix}/onboarding/status`);
4612
+ }
4613
+ completeOnboarding(input) {
4614
+ return this.client.request(`${this.prefix}/onboarding/complete`, {
4615
+ method: "POST",
4616
+ body: JSON.stringify(input)
4617
+ });
4618
+ }
4619
+ getAccessStatus() {
4620
+ return this.client.request(`${this.prefix}/access/status`);
4621
+ }
4622
+ redeemAccessCode(code) {
4623
+ return this.client.request(`${this.prefix}/access/redeem`, {
4624
+ method: "POST",
4625
+ body: JSON.stringify({ code })
4626
+ });
4627
+ }
4628
+ /**
4629
+ * Fetch the caller's current permission list as enforced by the gateway.
4630
+ * UI permission providers should call this on mount and refetch on
4631
+ * Clerk org switch to stay in sync with sub-tenant permission changes.
4632
+ */
4633
+ getMyPermissions() {
4634
+ return this.client.request(`${this.prefix}/me/permissions`);
4635
+ }
4636
+ /**
4637
+ * Preview what deleting the caller's own account will do. Drives the Danger
4638
+ * Zone copy so the user sees an honest, kind-appropriate warning before the
4639
+ * irreversible action (a last-admin cascade wipes the whole workspace).
4640
+ */
4641
+ getDeletionPreview() {
4642
+ return this.client.request(`${this.prefix}/me/deletion-preview`);
4643
+ }
4644
+ /**
4645
+ * Permanently delete the caller's own account. Returns `{ status: "deleting" }`
4646
+ * and tears the account down asynchronously — the Clerk user is deleted shortly
4647
+ * after, so the caller's session dies. On success, sign out and route the user
4648
+ * to a terminal "account is being deleted" state; do NOT retry.
4649
+ *
4650
+ * Pass `confirmKind` (the accountKind the user actually confirmed, from the
4651
+ * deletion preview): if membership changed between preview and execute, the
4652
+ * server answers 409 `account_kind_changed` instead of cascading a scope the
4653
+ * user never agreed to.
4654
+ */
4655
+ deleteAccount(confirmKind) {
4656
+ return this.client.request(`${this.prefix}/me`, {
4657
+ method: "DELETE",
4658
+ ...confirmKind ? { body: JSON.stringify({ confirmKind }) } : {}
4659
+ });
4660
+ }
4661
+ getSubscriptionStatus() {
4662
+ return this.client.request(`${this.prefix}/subscription`);
4663
+ }
4664
+ /**
4665
+ * Mint a short-lived, single-use Clerk sign-in token for the calling user so
4666
+ * a native client can hand its logged-in session to the web dashboard
4667
+ * (`${dashboard}/handoff?__clerk_ticket=<token>`). Server mints only for the
4668
+ * authenticated user — never a caller-supplied id.
4669
+ */
4670
+ createHandoffToken() {
4671
+ return this.client.request(`${this.prefix}/handoff-token`, { method: "POST" });
4672
+ }
4673
+ applyForStartup(input) {
4674
+ return this.client.request(`${this.prefix}/subscription/apply-startup`, {
4675
+ method: "POST",
4676
+ body: JSON.stringify(input)
4677
+ });
4678
+ }
4679
+ /**
4680
+ * Accept an approved Startup Program invite. Call after the applicant has a
4681
+ * card on file (confirmed or freshly added) — this mints the Professional
4682
+ * grant subscription. Idempotent: a repeat call on an already-accepted
4683
+ * application returns `{ status: "accepted" }` without re-charging.
4684
+ */
4685
+ acceptStartup() {
4686
+ return this.client.request(`${this.prefix}/subscription/accept-startup`, { method: "POST" });
4687
+ }
4688
+ createCheckoutSession(input) {
4689
+ return this.client.request(`${this.prefix}/subscription/checkout`, {
4690
+ method: "POST",
4691
+ body: JSON.stringify(input)
4692
+ });
4693
+ }
4694
+ /**
4695
+ * Change a personal (individual-tier) subscriber's platform plan in place on
4696
+ * their existing Stripe subscription — no second Checkout, no duplicate sub,
4697
+ * no double charge. Upgrades prorate immediately; downgrades apply with no
4698
+ * immediate charge/refund. Returns the updated subscription.
4699
+ */
4700
+ changePlatformPlan(input) {
4701
+ return this.client.request(`${this.prefix}/subscription/change`, {
4702
+ method: "POST",
4703
+ body: JSON.stringify(input)
4704
+ });
4705
+ }
4706
+ /**
4707
+ * Preview the proration cost for changing a personal (individual-tier)
4708
+ * subscriber's platform plan — read-only companion to `changePlatformPlan`.
4709
+ * Nothing is charged.
4710
+ */
4711
+ previewPlatformPlanChange(input) {
4712
+ return this.client.request(`${this.prefix}/subscription/change/preview`, {
4713
+ method: "POST",
4714
+ body: JSON.stringify(input)
4715
+ });
4716
+ }
4717
+ updateSeats(seats) {
4718
+ return this.client.request(`${this.prefix}/subscription/seats`, {
4719
+ method: "POST",
4720
+ body: JSON.stringify({ seats })
4721
+ });
4722
+ }
4723
+ previewSeatChange(seats) {
4724
+ return this.client.request(`${this.prefix}/subscription/seats/preview`, {
4725
+ method: "POST",
4726
+ body: JSON.stringify({ seats })
4727
+ });
4728
+ }
4729
+ listOrgMembers() {
4730
+ return this.client.request(`${this.prefix}/org/members`);
4731
+ }
4732
+ patchOrgMember(userId, body) {
4733
+ return this.client.request(`${this.prefix}/org/members/${encodeURIComponent(userId)}`, {
4734
+ method: "PATCH",
4735
+ body: JSON.stringify(body)
4736
+ });
4737
+ }
4738
+ removeOrgMember(userId) {
4739
+ return this.client.request(`${this.prefix}/org/members/${encodeURIComponent(userId)}`, { method: "DELETE" });
4740
+ }
4741
+ listOrgInvitations() {
4742
+ return this.client.request(`${this.prefix}/org/invitations`);
4743
+ }
4744
+ createOrgInvitation(input) {
4745
+ return this.client.request(`${this.prefix}/org/invitations`, {
4746
+ method: "POST",
4747
+ body: JSON.stringify(input)
4748
+ });
4749
+ }
4750
+ revokeOrgInvitation(invitationId) {
4751
+ return this.client.request(`${this.prefix}/org/invitations/${encodeURIComponent(invitationId)}`, { method: "DELETE" });
4752
+ }
4753
+ listOrgDomains() {
4754
+ return this.client.request(`${this.prefix}/org/domains`);
4755
+ }
4756
+ createOrgDomain(input) {
4757
+ return this.client.request(`${this.prefix}/org/domains`, {
4758
+ method: "POST",
4759
+ body: JSON.stringify(input)
4760
+ });
4761
+ }
4762
+ deleteOrgDomain(domainId) {
4763
+ return this.client.request(`${this.prefix}/org/domains/${encodeURIComponent(domainId)}`, { method: "DELETE" });
4764
+ }
4765
+ updateOrgSettings(input) {
4766
+ return this.client.request(`${this.prefix}/org/settings`, {
4767
+ method: "PATCH",
4768
+ body: JSON.stringify(input)
4769
+ });
4770
+ }
4771
+ };
4772
+ //#endregion
4773
+ //#region ../../packages-internal/api-client/dist/services/integrations.js
4774
+ var IntegrationsService = class {
4775
+ client;
4776
+ constructor(client) {
4777
+ this.client = client;
4778
+ }
4779
+ listScopedInstalls(scope, scopeId) {
4780
+ const params = new URLSearchParams({
4781
+ scope,
4782
+ scopeId
4783
+ });
4784
+ return this.client.request(`/integrations/scoped?${params}`);
4785
+ }
4786
+ installScoped(data) {
4787
+ return this.client.request("/integrations/scoped", {
4788
+ method: "POST",
4789
+ body: JSON.stringify(data)
4790
+ });
4791
+ }
4792
+ getScopedInstall(integrationId, scope, scopeId) {
4793
+ const params = new URLSearchParams({
4794
+ scope,
4795
+ scopeId
4796
+ });
4797
+ return this.client.request(`/integrations/scoped/${encodeURIComponent(integrationId)}?${params}`);
4798
+ }
4799
+ updateScopedInstall(integrationId, data) {
4800
+ return this.client.request(`/integrations/scoped/${encodeURIComponent(integrationId)}`, {
4801
+ method: "PATCH",
4802
+ body: JSON.stringify(data)
4803
+ });
4804
+ }
4805
+ removeScopedInstall(integrationId, scope, scopeId) {
4806
+ const params = new URLSearchParams({
4807
+ scope,
4808
+ scopeId
4809
+ });
4810
+ return this.client.request(`/integrations/scoped/${encodeURIComponent(integrationId)}?${params}`, { method: "DELETE" });
4811
+ }
4812
+ /**
4813
+ * Reinstall (re-apply latest) a scope-level install. Agent scope is rejected
4814
+ * by the route — use {@link reinstallIntegration} for agent-scoped reinstall.
4815
+ */
4816
+ reinstallScoped(integrationId, scope, scopeId) {
4817
+ return this.client.request(`/integrations/scoped/${encodeURIComponent(integrationId)}/reinstall`, {
4818
+ method: "POST",
4819
+ body: JSON.stringify({
4820
+ scope,
4821
+ scopeId
4822
+ })
4823
+ });
4824
+ }
4825
+ listIntegrations(agentId, options) {
4826
+ const params = new URLSearchParams();
4827
+ if (options?.includeInherited) params.set("includeInherited", "true");
4828
+ if (options?.effective) params.set("effective", "true");
4829
+ const qs = params.toString();
4830
+ return this.client.request(`/integrations/agents/${agentId}${qs ? `?${qs}` : ""}`);
4831
+ }
4832
+ installIntegration(agentId, data) {
4833
+ return this.client.request(`/integrations/agents/${agentId}`, {
4834
+ method: "POST",
4835
+ body: JSON.stringify(data)
4836
+ });
4837
+ }
4838
+ getIntegrationConfig(agentId, integrationId) {
4839
+ return this.client.request(`/integrations/agents/${agentId}/${integrationId}/config`);
4840
+ }
4841
+ updateIntegration(agentId, integrationId, data) {
4842
+ return this.client.request(`/integrations/agents/${agentId}/${integrationId}`, {
4843
+ method: "PATCH",
4844
+ body: JSON.stringify(data)
4845
+ });
4846
+ }
4847
+ removeIntegration(agentId, integrationId) {
4848
+ return this.client.request(`/integrations/agents/${agentId}/${integrationId}`, { method: "DELETE" });
4849
+ }
4850
+ reinstallIntegration(agentId, integrationId) {
4851
+ return this.client.request(`/integrations/agents/${agentId}/${integrationId}/reinstall`, { method: "POST" });
4852
+ }
4853
+ /**
4854
+ * Upgrade an integration to the registry's latest version via the fast,
4855
+ * diff-based daemon path (bumps `version` without `reinstallRequestedAt`).
4856
+ * The agent stays online — no destructive teardown. Distinct from
4857
+ * {@link reinstallIntegration}, which is the destructive repair path.
4858
+ */
4859
+ upgradeIntegration(agentId, integrationId) {
4860
+ return this.client.request(`/integrations/agents/${agentId}/${integrationId}/upgrade`, { method: "POST" });
4861
+ }
4862
+ getRegistry() {
4863
+ return this.client.request("/integrations/registry");
4864
+ }
4865
+ triggerSync(agentId) {
4866
+ return this.client.request("/integrations/sync/trigger", {
4867
+ method: "POST",
4868
+ body: JSON.stringify({ agentId })
4869
+ });
4870
+ }
4871
+ getDiscordGuildChannels(guildId) {
4872
+ return this.client.request(`/discord/guilds/${encodeURIComponent(guildId)}/channels`);
4873
+ }
4874
+ listMobileNumbers() {
4875
+ return this.client.request("/mobile/numbers");
4876
+ }
4877
+ searchMobileNumbers(country, query) {
4878
+ const params = new URLSearchParams();
4879
+ if (country) params.set("country", country);
4880
+ if (query) params.set("query", query);
4881
+ return this.client.request(`/mobile/numbers/search?${params}`);
4882
+ }
4883
+ assignMobileNumber(agentId, phoneNumber, countryCode) {
4884
+ return this.client.request("/mobile/numbers/assign", {
4885
+ method: "POST",
4886
+ body: JSON.stringify({
4887
+ agentId,
4888
+ phoneNumber,
4889
+ countryCode
4890
+ })
4891
+ });
4892
+ }
4893
+ releaseMobileNumber(agentId) {
4894
+ return this.client.request("/mobile/numbers/release", {
4895
+ method: "POST",
4896
+ body: JSON.stringify({ agentId })
4897
+ });
4898
+ }
4899
+ getMobileNumber(agentId) {
4900
+ return this.client.request(`/mobile/numbers?agentId=${encodeURIComponent(agentId)}`);
4901
+ }
4902
+ disconnectGoogle(agentId, email) {
4903
+ const query = email ? `?email=${encodeURIComponent(email)}` : "";
4904
+ return this.client.request(`/google/agents/${encodeURIComponent(agentId)}/account${query}`, { method: "DELETE" });
4905
+ }
4906
+ getAtlassianSites(agentId) {
4907
+ return this.client.request(`/atlassian/agents/${encodeURIComponent(agentId)}/sites`);
4908
+ }
4909
+ selectAtlassianSite(agentId, cloudId) {
4910
+ return this.client.request(`/atlassian/agents/${encodeURIComponent(agentId)}/sites`, {
4911
+ method: "PUT",
4912
+ body: JSON.stringify({ cloudId })
4913
+ });
4914
+ }
4915
+ listSlackChannels(agentId) {
4916
+ return this.client.request(`/slack/agents/${encodeURIComponent(agentId)}/channels`);
4917
+ }
4918
+ sendSlackMessage(agentId, channel, text) {
4919
+ return this.client.request(`/slack/agents/${encodeURIComponent(agentId)}/send`, {
4920
+ method: "POST",
4921
+ body: JSON.stringify({
4922
+ channel,
4923
+ text
4924
+ })
4925
+ });
4926
+ }
4924
4927
  };
4925
- 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.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.SpecificUser, 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;
4926
4928
  //#endregion
4927
4929
  //#region src/config.ts
4928
4930
  /**
@@ -5146,6 +5148,17 @@ async function loadDaemonConfig() {
5146
5148
  const gatewayWsUrl = alfeConfig.gateway_url ?? deriveGatewayWsUrl(apiEndpoint);
5147
5149
  const runtimes = await loadRuntimeConfigs();
5148
5150
  const runtime = alfeConfig.runtime ?? identity.runtime;
5151
+ let defaultModel;
5152
+ if (runtime === "claude-code") {
5153
+ let timer;
5154
+ const ws = await Promise.race([fetchAgentConfig(alfeConfig.api_key, apiEndpoint), new Promise((resolve) => {
5155
+ timer = setTimeout(() => {
5156
+ resolve(null);
5157
+ }, 5e3);
5158
+ })]);
5159
+ if (timer) clearTimeout(timer);
5160
+ defaultModel = ws?.defaultModel;
5161
+ }
5149
5162
  return {
5150
5163
  apiKey: alfeConfig.api_key,
5151
5164
  apiEndpoint,
@@ -5156,7 +5169,8 @@ async function loadDaemonConfig() {
5156
5169
  orgId: identity.orgId,
5157
5170
  runtime,
5158
5171
  runtimes,
5159
- autoStartRuntime: alfeConfig.auto_start_runtime ?? true
5172
+ autoStartRuntime: alfeConfig.auto_start_runtime ?? true,
5173
+ ...defaultModel ? { defaultModel } : {}
5160
5174
  };
5161
5175
  }
5162
5176
  /**
@@ -23999,7 +24013,7 @@ async function startDaemon() {
23999
24013
  runtimeProcess = new RuntimeProcess({
24000
24014
  runtime: config.runtime,
24001
24015
  workspace: runtimeCfg.workspace,
24002
- env: {}
24016
+ env: config.runtime === "claude-code" && config.defaultModel ? { ALFE_DEFAULT_MODEL: config.defaultModel } : {}
24003
24017
  });
24004
24018
  runtimeProcess.setTurnActivityProbe(turnActivityProbe);
24005
24019
  runtimeProcess.start();
@@ -24191,7 +24205,7 @@ async function executeCloudCommand(command) {
24191
24205
  };
24192
24206
  const payload = command.payload;
24193
24207
  const runtime = config.runtime;
24194
- const version = payload?.version ?? (runtime === "openclaw" ? "2026.6.11" : runtime === "claude-code" ? "0.1.2" : void 0);
24208
+ const version = payload?.version ?? (runtime === "openclaw" ? "2026.6.11" : runtime === "claude-code" ? "0.1.3" : void 0);
24195
24209
  upgradingRuntime = true;
24196
24210
  setTimeout(() => {
24197
24211
  (async () => {
@@ -77,7 +77,7 @@ declare const PINNED_OPENCLAW_VERSION = "2026.6.11";
77
77
  * `PINNED_OPENCLAW_VERSION` — there is no `services/compute/Dockerfile` mirror to
78
78
  * keep in sync.
79
79
  */
80
- declare const PINNED_CLAUDE_CODE_HOST_VERSION = "0.1.2";
80
+ declare const PINNED_CLAUDE_CODE_HOST_VERSION = "0.1.3";
81
81
  //#endregion
82
82
  //#region src/sentry.d.ts
83
83
  /**
@@ -281,6 +281,13 @@ interface DaemonConfig {
281
281
  runtimes: Record<string, RuntimeConfig>;
282
282
  /** Whether to auto-start the agent runtime process (e.g. openclaw) */
283
283
  autoStartRuntime: boolean;
284
+ /**
285
+ * The agent's bare `defaultModel`, resolved for claude-code only (other
286
+ * runtimes receive their model via the desired-state reconcile, not here).
287
+ * The daemon injects it into the host env so `claude -p --model` uses the
288
+ * dashboard-selected model. Never provider-qualified.
289
+ */
290
+ defaultModel?: string;
284
291
  }
285
292
  interface AgentIdentity {
286
293
  agentId: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alfe.ai/gateway",
3
- "version": "0.9.0",
3
+ "version": "0.9.1",
4
4
  "description": "Alfe local gateway daemon — persistent control plane for agent integrations",
5
5
  "type": "module",
6
6
  "bin": {
@@ -23,11 +23,11 @@
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.11.0",
26
+ "@alfe.ai/agent-api-client": "^0.11.1",
27
27
  "@alfe.ai/ai-proxy-local": "^0.0.13",
28
28
  "@alfe.ai/config": "^0.3.0",
29
- "@alfe.ai/integration-manifest": "^0.3.2",
30
- "@alfe.ai/integrations": "^0.5.2",
29
+ "@alfe.ai/integration-manifest": "^0.3.3",
30
+ "@alfe.ai/integrations": "^0.5.3",
31
31
  "@alfe.ai/mcp-bundler": "^0.3.2"
32
32
  },
33
33
  "license": "UNLICENSED",