@agentproto/auth 0.2.0 → 1.0.0

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/README.md CHANGED
@@ -10,7 +10,7 @@ Aligned to the WorkOS [auth.md](https://github.com/workos/auth.md) open standard
10
10
  two-hop `.well-known` discovery, the `agent_auth` metadata block, and the
11
11
  service-auth claim ceremony (`urn:workos:agent-auth:grant-type:claim`).
12
12
 
13
- > **Status: 0.1.0-alpha.** Two flows specified in v1 (`pat`, `service-auth`);
13
+ > **Status: 0.2.0-alpha.** Two flows specified in v1 (`pat`, `service-auth`);
14
14
  > `id-jag` (agentproto-as-IdP) is reserved.
15
15
 
16
16
  Spec: <https://agentproto.sh/docs/aip-50> · Standard: <https://github.com/workos/auth.md>
@@ -240,6 +240,7 @@ through that structural seam. See `@agentproto/secrets`' README.
240
240
  | `runAuthFlow` | resolve → discover → dispatch |
241
241
  | `FLOW_ENGINES` | registered flow engines (`pat`, `service-auth`) |
242
242
  | `CredentialBroker` / `CredentialBrokerOptions` | path → fresh `resolveHeaders` |
243
+ | `eligibleProfiles` | `(adapter × route) → vendor + profile eligibility predicate` |
243
244
  | `CredentialStore` / `StoreRef` / `StoredCredential` | pluggable-store interface + shapes |
244
245
  | `KeychainStore` / `MemoryStore` / `FileStore` / `resolveStoreRef` | built-in backends + ref resolver |
245
246
  | `readKeychainToken` / `writeKeychainToken` / `resolveAccount` | Keychain helpers |
package/dist/index.d.ts CHANGED
@@ -443,6 +443,10 @@ declare function resolveAccount(account: string | undefined, server: string): st
443
443
  declare function readKeychainToken(service: string, account: string): Promise<string | undefined>;
444
444
  /** Write a token to the Keychain (-U updates in place). */
445
445
  declare function writeKeychainToken(service: string, account: string, token: string): Promise<void>;
446
+ /** Remove a token from the Keychain. Returns true if an entry was deleted,
447
+ * false when none existed (a delete of an absent entry is not an error —
448
+ * the desired end state, "no credential at this slot", already holds). */
449
+ declare function deleteKeychainToken(service: string, account: string): Promise<boolean>;
446
450
 
447
451
  /**
448
452
  * KeychainStore — `CredentialStore` backed by the platform Keychain.
@@ -460,6 +464,7 @@ declare function writeKeychainToken(service: string, account: string, token: str
460
464
  declare class KeychainStore implements CredentialStore {
461
465
  read(ref: StoreRef): Promise<StoredCredential | undefined>;
462
466
  write(ref: StoreRef, cred: StoredCredential): Promise<void>;
467
+ delete(ref: StoreRef): Promise<void>;
463
468
  }
464
469
 
465
470
  /**
@@ -543,10 +548,10 @@ declare class CredentialBroker {
543
548
  /**
544
549
  * Named auth-profile types (SPEC §1c/§3.1 — `agentproto-session-config-axes`).
545
550
  *
546
- * A profile is a named credential `{ vendor, method, credentialRef }` that
551
+ * A profile is a named credential `{ endpoint, method, credentialRef }` that
547
552
  * lives independently of any adapter, generalizing `providers-store`'s
548
553
  * `ProviderEntry` (one api-key per provider, `packages/providers-store/src/
549
- * index.ts:68-80`) to N named profiles per vendor. `subscription|api-key` is
554
+ * index.ts:68-80`) to N named profiles per billing endpoint. `subscription|api-key` is
550
555
  * not a session property — it demotes to the `method` facet of a profile.
551
556
  *
552
557
  * The secret itself is NEVER inlined here — `credentialRef` is an opaque
@@ -560,31 +565,103 @@ declare class CredentialBroker {
560
565
  * (`types.ts:151`): `pat` → `api-key`, `oat` → `oauth-bearer`. Extensible —
561
566
  * new methods are additive. */
562
567
  type AuthMethod = "oauth-bearer" | "api-key";
563
- /** A named, vendor-scoped credential reference. */
568
+ /** Per-profile model curation (the allowlist). `mode: "all"` (or an ABSENT
569
+ * {@link AuthProfile.models}) services every model the profile is otherwise
570
+ * eligible for — today's behavior. `mode: "allow"` narrows the profile to
571
+ * exactly `ids`: it services a model only when the model's catalog identity
572
+ * (its `vendor/product` or its route-qualified `ref`) is in the list. The
573
+ * intersection is applied INSIDE the catalog eligibility join
574
+ * (`catalog-models.ts`), never at the endpoint/method predicate here, so a
575
+ * curated profile stays endpoint-eligible but only makes its chosen model
576
+ * refs runnable. */
577
+ interface ModelCuration {
578
+ mode: "all" | "allow";
579
+ /** Model identities allowed when `mode === "allow"` — each a catalog
580
+ * `vendor/product` or route-qualified `ref`. Empty ⇒ services nothing. */
581
+ ids: string[];
582
+ }
583
+ /** Which spend surface a {@link CostBudget} caps. `"session"` bounds the
584
+ * windowed spend of the ONE session the budget is evaluated against;
585
+ * `"profile"` bounds the aggregate windowed spend of every session that
586
+ * resolved to the same auth profile (the session's `accessProfile.profileRef`).
587
+ * Additive — new scopes are back-compat. */
588
+ type CostBudgetScope = "session" | "profile";
589
+ /** A windowed spend cap. DISTINCT from the scalar `maxCostUsd` session-kill
590
+ * (`sessions.ts` turn-end) — a `CostBudget` never kills a session; it trips a
591
+ * governance policy (`policy:failed` on the completion-policy bus) when the
592
+ * ROLLING windowed spend for its {@link scope} crosses `maxCostUsd`. `window`
593
+ * is a rolling spec (`parseWindow` shorthand `"5h"`/`"7d"` or ISO-8601 `"P7D"`);
594
+ * spend is the priced local-estimate rollup over durable usage snapshots. */
595
+ interface CostBudget {
596
+ /** Windowed spend ceiling in USD. The budget trips when the window's priced
597
+ * spend strictly exceeds this. */
598
+ maxCostUsd: number;
599
+ /** Rolling window spec — `parseWindow`-parseable (`"5h"`, `"7d"`, `"P7D"`). */
600
+ window: string;
601
+ /** Which spend surface the window is summed over. See {@link CostBudgetScope}. */
602
+ scope: CostBudgetScope;
603
+ }
604
+ /** A named, billing-endpoint-scoped credential reference. */
564
605
  interface AuthProfile {
565
606
  /** Stable id, unique across all profiles (the `profileRef` a session
566
607
  * attaches). */
567
608
  id: string;
568
- /** Which vendor this credential bills against (`anthropic`, `moonshot`, …) —
569
- * a `CatalogProvider` id, kept as `string` here to stay decoupled from
609
+ /** Which billing endpoint this credential authenticates against
610
+ * (`anthropic`, `openrouter`, `moonshot`, …). This deliberately does NOT
611
+ * mean the model builder: OpenRouter can serve a z-ai model, for example.
612
+ * Kept as `string` here to stay decoupled from
570
613
  * `@agentproto/model-catalog`, same rationale as the driver's
571
614
  * `AgentCliDefinition.provider`. */
572
- vendor: string;
615
+ endpoint: string;
573
616
  /** How this profile authenticates. */
574
617
  method: AuthMethod;
575
618
  /** Opaque handle into this package's credential storage — NEVER the secret
576
619
  * itself. Resolved through `CredentialStore` / `token-store.ts` at use
577
- * time, not stored inline. */
578
- credentialRef: string;
620
+ * time, not stored inline. Set for a credential-backed profile; absent for
621
+ * a source-backed profile. Mutually exclusive with {@link source}. */
622
+ credentialRef?: string;
623
+ /** Self-refreshing credential source (`oauth-bearer` only) — same value
624
+ * spawn's subscription resolution accepts (today, only
625
+ * `"claude-code-oauth"`, `spawn-defaults.ts`'s `CLAUDE_CODE_OAUTH_SOURCE`).
626
+ * A source-backed profile has no stored secret: the credential is resolved
627
+ * fresh at spawn time instead. Mutually exclusive with
628
+ * {@link credentialRef}. */
629
+ source?: string;
579
630
  /** Optional human-readable name ("Jeremy Max", "work OpenRouter"). */
580
631
  label?: string;
632
+ /** Whole-profile enable/disable. ABSENT (or `false`) ⇒ enabled (today's
633
+ * behavior). `true` ⇒ the profile is skipped by {@link eligibleProfiles}
634
+ * entirely, so every model it would otherwise service drops to
635
+ * non-runnable. A REAL persisted state, distinct from the derived
636
+ * `runnable` flag the catalog computes. */
637
+ disabled?: boolean;
638
+ /** Optional per-model curation (the allowlist). ABSENT ⇒ `{ mode: "all" }`
639
+ * — services every eligible model, byte-identical to a profile that
640
+ * predates this field. See {@link ModelCuration}. */
641
+ models?: ModelCuration;
642
+ /** Optional windowed spend cap attached to this profile (SPEC §1c). ABSENT ⇒
643
+ * no profile-level budget — byte-identical to a profile that predates this
644
+ * field. When present with `scope: "profile"`, a governance policy evaluates
645
+ * the aggregate windowed spend of every session on this profile at each
646
+ * turn-end and trips `policy:failed` on overage. Distinct from the scalar
647
+ * session-kill `maxCostUsd` — see {@link CostBudget}. */
648
+ costBudget?: CostBudget;
649
+ /** Provenance: where this profile's credential was IMPORTED from, when it
650
+ * was materialized by the WS6 discovery→import flow
651
+ * (`auth_profile_import`) rather than created by hand. One of the discovery
652
+ * origins (`claude-code`, `hermes-config`, `env`, `codex`, `gemini`). Purely
653
+ * informational — it drives the panel's "imported from <origin>" badge and
654
+ * nothing in the spawn/eligibility path. ABSENT for a hand-created profile.
655
+ * Kept as `string` (not a union) to stay decoupled, same rationale as
656
+ * {@link endpoint}. */
657
+ origin?: string;
581
658
  }
582
659
 
583
660
  /**
584
661
  * Named auth-profile store — CRUD over `~/.agentproto/auth-profiles.json`
585
662
  * (mode 0600), generalizing `providers-store`'s single-key-per-provider file
586
663
  * (`packages/providers-store/src/index.ts:68-90`, `ProviderEntry`/
587
- * `ProvidersFile`) to N named `AuthProfile`s per vendor, keyed by `id`.
664
+ * `ProvidersFile`) to N named `AuthProfile`s per billing endpoint, keyed by `id`.
588
665
  *
589
666
  * This is the profile-metadata store, not the credential store: entries hold
590
667
  * `credentialRef` (a pointer), never a secret, so — unlike `FileStore`
@@ -598,22 +675,58 @@ interface AuthProfile {
598
675
 
599
676
  declare const authProfilesFileSchema: z.ZodObject<{
600
677
  version: z.ZodLiteral<1>;
601
- profiles: z.ZodRecord<z.ZodString, z.ZodObject<{
678
+ profiles: z.ZodRecord<z.ZodString, z.ZodPipe<z.ZodObject<{
602
679
  id: z.ZodString;
603
680
  vendor: z.ZodString;
604
681
  method: z.ZodEnum<{
605
682
  "oauth-bearer": "oauth-bearer";
606
683
  "api-key": "api-key";
607
684
  }>;
608
- credentialRef: z.ZodString;
685
+ credentialRef: z.ZodOptional<z.ZodString>;
686
+ source: z.ZodOptional<z.ZodString>;
609
687
  label: z.ZodOptional<z.ZodString>;
610
- }, z.core.$strip>>;
688
+ disabled: z.ZodOptional<z.ZodBoolean>;
689
+ models: z.ZodOptional<z.ZodObject<{
690
+ mode: z.ZodEnum<{
691
+ allow: "allow";
692
+ all: "all";
693
+ }>;
694
+ ids: z.ZodArray<z.ZodString>;
695
+ }, z.core.$strip>>;
696
+ costBudget: z.ZodOptional<z.ZodObject<{
697
+ maxCostUsd: z.ZodNumber;
698
+ window: z.ZodString;
699
+ scope: z.ZodEnum<{
700
+ session: "session";
701
+ profile: "profile";
702
+ }>;
703
+ }, z.core.$strip>>;
704
+ origin: z.ZodOptional<z.ZodString>;
705
+ }, z.core.$strip>, z.ZodTransform<AuthProfile, {
706
+ id: string;
707
+ vendor: string;
708
+ method: "oauth-bearer" | "api-key";
709
+ credentialRef?: string | undefined;
710
+ source?: string | undefined;
711
+ label?: string | undefined;
712
+ disabled?: boolean | undefined;
713
+ models?: {
714
+ mode: "allow" | "all";
715
+ ids: string[];
716
+ } | undefined;
717
+ costBudget?: {
718
+ maxCostUsd: number;
719
+ window: string;
720
+ scope: "session" | "profile";
721
+ } | undefined;
722
+ origin?: string | undefined;
723
+ }>>>;
611
724
  }, z.core.$strip>;
612
725
  type AuthProfilesFile = z.infer<typeof authProfilesFileSchema>;
613
726
  declare function authProfilesPath(): string;
614
727
  declare function loadAuthProfiles(): Promise<AuthProfilesFile>;
615
- /** List all profiles, optionally filtered to one vendor. */
616
- declare function listAuthProfiles(vendor?: string): Promise<AuthProfile[]>;
728
+ /** List all profiles, optionally filtered to one billing endpoint. */
729
+ declare function listAuthProfiles(endpoint?: string): Promise<AuthProfile[]>;
617
730
  /** Look up a single profile by id, or undefined if none exists. */
618
731
  declare function getAuthProfile(id: string): Promise<AuthProfile | undefined>;
619
732
  /** Add (or replace) a profile, keyed by its `id`. */
@@ -622,16 +735,194 @@ declare function addAuthProfile(profile: AuthProfile): Promise<void>;
622
735
  declare function removeAuthProfile(id: string): Promise<boolean>;
623
736
 
624
737
  /**
625
- * (adapter × route) → vendor resolution + the profile eligibility predicate
738
+ * Auth-profile provisioning — the create/delete flow the store CRUD
739
+ * (`profile-store.ts`) deliberately leaves out.
740
+ *
741
+ * `profile-store.ts` writes only profile *metadata* (`credentialRef`, a
742
+ * pointer). Provisioning is the two-sided operation nobody else owned: write
743
+ * the *secret* to the credential store at a derived slot, THEN record the
744
+ * metadata pointing at it — and, on delete, tear both down together. This is
745
+ * the single place that knows the `agentproto.auth.<vendor>[.<qualifier>]`
746
+ * keychain-slot convention (matching the entries seeded by hand in
747
+ * `~/.agentproto/auth-profiles.json`).
748
+ *
749
+ * The secret is INPUT-only. It is written to the `CredentialStore` and never
750
+ * echoed back: `createAuthProfile` returns non-secret metadata plus a
751
+ * one-way `fingerprint` (same "fingerprint, don't echo" discipline as
752
+ * `broker.ts` / `KeychainStore`), so a caller can confirm *which* credential
753
+ * landed without ever seeing it.
754
+ *
755
+ * Dependency-injected (`ProfileProvisionDeps`) so it's unit-testable against
756
+ * a `MemoryStore` + an in-memory profile map, with no keychain or filesystem.
757
+ */
758
+
759
+ /** Input to {@link createAuthProfile}. `credential` is the raw secret — it is
760
+ * written to the store and NEVER returned. Exactly one of `credential` /
761
+ * `source` must be given for an `oauth-bearer` profile; `api-key` always
762
+ * requires `credential` (a source-backed profile only makes sense for a
763
+ * self-refreshing subscription bearer). */
764
+ interface CreateAuthProfileInput {
765
+ /** Stable id, unique across all profiles. */
766
+ id: string;
767
+ /** Billing endpoint / vendor this credential authenticates against
768
+ * (`anthropic`, `openrouter`, `moonshot`, …). */
769
+ endpoint: string;
770
+ /** How this profile authenticates. */
771
+ method: AuthMethod;
772
+ /** The raw secret (a subscription OAuth bearer, an API key). INPUT-ONLY.
773
+ * Mutually exclusive with `source`. */
774
+ credential?: string;
775
+ /** Self-refreshing credential source (`oauth-bearer` only, e.g.
776
+ * `"claude-code-oauth"`) — the profile stores no secret; the credential is
777
+ * resolved fresh at spawn time instead. Mutually exclusive with
778
+ * `credential`. */
779
+ source?: string;
780
+ /** Optional human-readable name. */
781
+ label?: string;
782
+ /** Optional explicit credential-store slot. Omitted ⇒ derived from
783
+ * `endpoint` + `method` (see {@link deriveCredentialRef}). Ignored for a
784
+ * source-backed profile (nothing is written to the credential store). */
785
+ credentialRef?: string;
786
+ /** Optional provenance — where the credential was imported from (a WS6
787
+ * discovery origin). Stamped verbatim on the created profile; purely
788
+ * informational. */
789
+ origin?: string;
790
+ }
791
+ /** The non-secret result of a create — safe to log, return over the wire, or
792
+ * render in a UI. Carries a fingerprint, never the credential. */
793
+ interface CreatedAuthProfile {
794
+ id: string;
795
+ endpoint: string;
796
+ method: AuthMethod;
797
+ /** Set for a credential-backed profile; absent for a source-backed one. */
798
+ credentialRef?: string;
799
+ /** Set for a source-backed profile; absent for a credential-backed one. */
800
+ source?: string;
801
+ label?: string;
802
+ /** Provenance stamped at import time, when given. */
803
+ origin?: string;
804
+ /** One-way fingerprint of the stored credential (sha256, truncated) — lets
805
+ * a caller confirm *which* secret was stored without exposing it. Absent
806
+ * for a source-backed profile — there is no stored secret to fingerprint. */
807
+ fingerprint?: string;
808
+ }
809
+ /** The result of a delete. `deleted` is false when no profile had that id
810
+ * (idempotent — the desired end state already held). */
811
+ interface DeletedAuthProfile {
812
+ deleted: boolean;
813
+ id: string;
814
+ /** The slot the credential lived at, when a profile was actually removed. */
815
+ credentialRef?: string;
816
+ }
817
+ /** Injectable persistence surface — production wires these to
818
+ * `profile-store.ts` + a `KeychainStore`; tests pass in-memory doubles. */
819
+ interface ProfileProvisionDeps {
820
+ /** Where secrets live (a `KeychainStore` in production). */
821
+ store: CredentialStore;
822
+ getProfile: (id: string) => Promise<AuthProfile | undefined>;
823
+ listProfiles: () => Promise<AuthProfile[]>;
824
+ addProfile: (profile: AuthProfile) => Promise<void>;
825
+ removeProfile: (id: string) => Promise<boolean>;
826
+ }
827
+ /** Raised when create/delete input fails validation. Distinct type so a host
828
+ * (HTTP route, MCP tool) can map it to a 400 rather than a 500. */
829
+ declare class AuthProfileValidationError extends Error {
830
+ constructor(message: string);
831
+ }
832
+ /** Normalized, validated create input — every field trimmed and checked.
833
+ * Exactly one of `credential` / `source` is present. */
834
+ interface ValidatedCreateInput {
835
+ id: string;
836
+ endpoint: string;
837
+ method: AuthMethod;
838
+ credential?: string;
839
+ source?: string;
840
+ label?: string;
841
+ credentialRef?: string;
842
+ origin?: string;
843
+ }
844
+ /**
845
+ * Validate + normalize raw create input. Pure — no I/O. Throws
846
+ * {@link AuthProfileValidationError} with a specific message on the first
847
+ * problem it finds, so the surface layer can surface a clear 400.
848
+ */
849
+ declare function validateCreateInput(input: CreateAuthProfileInput): ValidatedCreateInput;
850
+ /**
851
+ * Derive the credential-store slot for a profile. Matches the convention of
852
+ * the hand-seeded entries: `agentproto.auth.<endpoint>` for an api-key,
853
+ * `agentproto.auth.<endpoint>.sub` for a subscription (oauth-bearer), plus an
854
+ * optional `<qualifier>` to disambiguate a second profile on the same
855
+ * endpoint+method. Pure.
856
+ */
857
+ declare function deriveCredentialRef(input: {
858
+ endpoint: string;
859
+ method: AuthMethod;
860
+ qualifier?: string;
861
+ }): string;
862
+ /** One-way fingerprint of a secret — sha256, first 12 hex chars. Enough to
863
+ * distinguish credentials by eye; not reversible. */
864
+ declare function fingerprintCredential(secret: string): string;
865
+ /** Non-secret identity of a STORED credential — a one-way {@link
866
+ * fingerprintCredential} plus the trailing 4 characters (the standard
867
+ * "which key is this" affordance, like a card's last four). Neither is
868
+ * reversible to the secret. `last4` is omitted for a secret too short to
869
+ * reveal a tail safely (see {@link MIN_LEN_FOR_LAST4}) — fail closed rather
870
+ * than expose. */
871
+ interface CredentialIdentity {
872
+ fingerprint: string;
873
+ last4?: string;
874
+ }
875
+ /** Compute the non-secret {@link CredentialIdentity} of a stored secret.
876
+ * Money-safety: returns ONLY the one-way fingerprint + a trailing tail —
877
+ * never the secret, and never the tail when the secret is too short to
878
+ * reveal one safely. */
879
+ declare function credentialIdentity(secret: string): CredentialIdentity;
880
+ /**
881
+ * Create a profile end-to-end: validate, derive the credential slot (avoiding
882
+ * collision with an existing profile's slot), write the secret to the store,
883
+ * then record the metadata. Rejects a duplicate id rather than silently
884
+ * overwriting. Returns non-secret metadata + a fingerprint; the credential is
885
+ * never echoed back.
886
+ */
887
+ declare function createAuthProfile(input: CreateAuthProfileInput, deps: ProfileProvisionDeps): Promise<CreatedAuthProfile>;
888
+ /**
889
+ * Delete a profile and its credential. Idempotent: a missing id returns
890
+ * `{ deleted: false }` rather than throwing. The keychain entry is removed
891
+ * only when no OTHER profile still references the same slot — two profiles
892
+ * can legitimately share a `credentialRef`, and dropping one must not strand
893
+ * the other.
894
+ */
895
+ declare function deleteAuthProfile(id: string, deps: ProfileProvisionDeps): Promise<DeletedAuthProfile>;
896
+ /**
897
+ * Enable or disable a whole profile (WS2). Metadata-only — never touches the
898
+ * credential store. Enabling CLEARS the `disabled` field entirely rather than
899
+ * writing `disabled: false`, so a re-enabled profile is byte-identical on
900
+ * disk to one that was never disabled (the ABSENT-means-enabled invariant).
901
+ * Throws {@link AuthProfileValidationError} for an unknown id so a host can map
902
+ * it to a 404/400. Returns the updated (non-secret) profile.
903
+ */
904
+ declare function setAuthProfileEnabled(id: string, enabled: boolean, deps: ProfileProvisionDeps): Promise<AuthProfile>;
905
+ /**
906
+ * Set a profile's per-model curation allowlist (WS3). Metadata-only. `mode:
907
+ * "all"` CLEARS the `models` field entirely (curation off ⇒ absent, the
908
+ * byte-identical "services everything" default), so only a genuine `mode:
909
+ * "allow"` persists a `models` object. `ids` are trimmed, de-duped, and
910
+ * blanks dropped. Throws {@link AuthProfileValidationError} for an unknown id.
911
+ * Returns the updated (non-secret) profile.
912
+ */
913
+ declare function setAuthProfileModels(id: string, curation: ModelCuration, deps: ProfileProvisionDeps): Promise<AuthProfile>;
914
+
915
+ /**
916
+ * (adapter × route) → billing-endpoint resolution + the profile eligibility predicate
626
917
  * (SPEC §1c, `agentproto-session-config-axes/SPEC.md:102-125`).
627
918
  *
628
919
  * profile eligible for (adapter, route) iff
629
- * profile.vendor == resolveEndpoint(adapter, route).vendor
920
+ * profile.endpoint == resolveEndpoint(adapter, route).endpoint
630
921
  * AND profile.method ∈ methodsPresentable(adapter, route)
631
922
  *
632
923
  * `route` is the endpoint selector (SPEC axis #4 — direct vs a gateway mode
633
924
  * like `moonshot`/`openrouter`), so access is deliberately downstream of it:
634
- * which vendor (and thus which profiles) are eligible changes when route
925
+ * which endpoint (and thus which profiles) are eligible changes when route
635
926
  * changes. `AdapterAuthManifest` is a narrow, package-local projection of
636
927
  * exactly what this predicate needs from an adapter's real AIP-45 manifest
637
928
  * (`packages/driver/agent-cli/src/types.ts`'s `AgentCliDefinition`) — this
@@ -640,7 +931,7 @@ declare function removeAuthProfile(id: string): Promise<boolean>;
640
931
  * runtime is the one that will later project a real manifest into this
641
932
  * shape (out of scope here — foundation only, no live spawn-path wiring).
642
933
  *
643
- * `methodsByRoute` is the static per-vendor method table ADR'd in SPEC §3.4:
934
+ * `methodsByRoute` is the static per-endpoint method table ADR'd in SPEC §3.4:
644
935
  * "which auth methods this adapter can present for a resolved route." It is
645
936
  * the derivable replacement for two hand-maintained artifacts SPEC §1c calls
646
937
  * out for eventual removal — the per-adapter `authSubscription` boolean
@@ -655,33 +946,36 @@ declare function removeAuthProfile(id: string): Promise<boolean>;
655
946
  */
656
947
 
657
948
  /** A narrow, package-local projection of an adapter's declared auth
658
- * capability — enough to resolve (adapter, route) → vendor and the auth
949
+ * capability — enough to resolve (adapter, route) → endpoint and the auth
659
950
  * methods presentable on that route. Not the real AIP-45 manifest type. */
660
951
  interface AdapterAuthManifest {
661
952
  /** Adapter id (e.g. "claude-code", "hermes"), for error messages only. */
662
953
  id: string;
663
954
  /** route id (e.g. "direct", or a gateway mode id like "moonshot") →
664
- * the vendor billed when spawned on that route. */
665
- vendorByRoute: Readonly<Record<string, string>>;
955
+ * the billing endpoint used when spawned on that route. */
956
+ endpointByRoute: Readonly<Record<string, string>>;
666
957
  /** route id → the auth methods this adapter can present when spawned on
667
958
  * that route — the method-side of the eligibility predicate. */
668
959
  methodsByRoute: Readonly<Record<string, readonly AuthMethod[]>>;
669
960
  }
670
- /** Resolve which vendor a given (adapter, route) pair bills against. Throws
671
- * when the manifest declares no vendor for `route` — an unresolvable route
961
+ /** Resolve which billing endpoint a given (adapter, route) pair uses. Throws
962
+ * when the manifest declares no endpoint for `route` — an unresolvable route
672
963
  * is a caller bug (a bad/unknown route id), not a "no profiles eligible"
673
- * case, so this fails loud rather than returning an empty vendor. */
964
+ * case, so this fails loud rather than returning an empty endpoint. */
674
965
  declare function resolveEndpoint(manifest: AdapterAuthManifest, route: string): {
675
- vendor: string;
966
+ endpoint: string;
676
967
  };
677
968
  /** Which auth methods `manifest`'s adapter can present on `route`. Empty
678
969
  * (never throws) when the route is declared for vendor resolution but has
679
970
  * no methods table entry — that's "no eligible profiles", a legitimate
680
971
  * eligibility outcome, not an error. */
681
972
  declare function methodsPresentable(manifest: AdapterAuthManifest, route: string): AuthMethod[];
682
- /** The eligibility predicate: profiles whose vendor matches the route's
683
- * resolved endpoint AND whose method the adapter can present on that
684
- * route. */
973
+ /** The eligibility predicate: profiles whose endpoint matches the route's
974
+ * resolved endpoint AND whose method the adapter can present on that route.
975
+ * A whole-profile-disabled profile (`disabled: true`) is skipped outright —
976
+ * every model it would otherwise service drops to non-runnable (WS2). This is
977
+ * the profile-level gate; per-model curation (`models`) is intersected
978
+ * downstream in the catalog join, not here (SPEC §1c / catalog-models.ts). */
685
979
  declare function eligibleProfiles(profiles: readonly AuthProfile[], manifest: AdapterAuthManifest, route: string): AuthProfile[];
686
980
 
687
981
  /** Guilde AI company platform.
@@ -714,15 +1008,15 @@ declare const BUILTIN_AUTH_PROVIDERS: readonly AuthProviderHandle[];
714
1008
  * KeychainStore / MemoryStore / FileStore — built-in CredentialStore backends
715
1009
  * resolveStoreRef(spec, server) — map a TokenStoreSpec to a StoreRef
716
1010
  * CredentialBroker — path → ready-to-use auth headers
717
- * AuthProfile / AuthMethod — named, vendor-scoped credential ref
1011
+ * AuthProfile / AuthMethod — named, endpoint-scoped credential ref
718
1012
  * listAuthProfiles/getAuthProfile/
719
1013
  * addAuthProfile/removeAuthProfile — named-profile store CRUD
720
1014
  * resolveEndpoint/methodsPresentable/
721
- * eligibleProfiles — (adapter × route) → vendor + the
1015
+ * eligibleProfiles — (adapter × route) → endpoint + the
722
1016
  * profile eligibility predicate
723
1017
  */
724
1018
 
725
1019
  declare const SPEC_NAME = "agentauth";
726
1020
  declare const SPEC_VERSION = "v1";
727
1021
 
728
- export { type AdapterAuthManifest, type AuthConfig, type AuthMethod, type AuthProfile, type AuthProfilesFile, type AuthProviderDefinition, type AuthProviderFrontmatter, type AuthProviderHandle, type AuthProviderManifest, BUILTIN_AUTH_PROVIDERS, CeremonyRequiredError, CredentialBroker, type CredentialBrokerOptions, type CredentialStore, type DeviceCodeAuthConfig, type DiscoveredEndpoints, DiscoveryError, FLOW_ENGINES, FileStore, type FlowEngine, type FlowId, type FlowResult, type FlowRunOptions, type InstallConfig, KeychainStore, MemoryStore, type PATAuthConfig, type RunFlowOptions, SPEC_NAME, SPEC_VERSION, type ServiceAuthConfig, type StoreRef, type StoredCredential, type TokenStoreSpec, addAuthProfile, authConfigSchema, authProfilesPath, authProviderFrontmatterSchema, defineAuthProvider, discoverEndpoints, eligibleProfiles, getAuthProfile, getAuthProvider, guildeAuthProvider, installConfigSchema, listAuthProfiles, listAuthProviderIds, listAuthProviders, loadAuthProfiles, methodsPresentable, parseAuthProviderManifest, parseAuthProviderManifestRaw, readKeychainToken, registerAuthProvider, removeAuthProfile, resolveAccount, resolveEndpoint, resolveStoreRef, runAuthFlow, tokenStoreSpecSchema, writeKeychainToken };
1022
+ export { type AdapterAuthManifest, type AuthConfig, type AuthMethod, type AuthProfile, AuthProfileValidationError, type AuthProfilesFile, type AuthProviderDefinition, type AuthProviderFrontmatter, type AuthProviderHandle, type AuthProviderManifest, BUILTIN_AUTH_PROVIDERS, CeremonyRequiredError, type CostBudget, type CostBudgetScope, type CreateAuthProfileInput, type CreatedAuthProfile, CredentialBroker, type CredentialBrokerOptions, type CredentialIdentity, type CredentialStore, type DeletedAuthProfile, type DeviceCodeAuthConfig, type DiscoveredEndpoints, DiscoveryError, FLOW_ENGINES, FileStore, type FlowEngine, type FlowId, type FlowResult, type FlowRunOptions, type InstallConfig, KeychainStore, MemoryStore, type ModelCuration, type PATAuthConfig, type ProfileProvisionDeps, type RunFlowOptions, SPEC_NAME, SPEC_VERSION, type ServiceAuthConfig, type StoreRef, type StoredCredential, type TokenStoreSpec, type ValidatedCreateInput, addAuthProfile, authConfigSchema, authProfilesPath, authProviderFrontmatterSchema, createAuthProfile, credentialIdentity, defineAuthProvider, deleteAuthProfile, deleteKeychainToken, deriveCredentialRef, discoverEndpoints, eligibleProfiles, fingerprintCredential, getAuthProfile, getAuthProvider, guildeAuthProvider, installConfigSchema, listAuthProfiles, listAuthProviderIds, listAuthProviders, loadAuthProfiles, methodsPresentable, parseAuthProviderManifest, parseAuthProviderManifestRaw, readKeychainToken, registerAuthProvider, removeAuthProfile, resolveAccount, resolveEndpoint, resolveStoreRef, runAuthFlow, setAuthProfileEnabled, setAuthProfileModels, tokenStoreSpecSchema, validateCreateInput, writeKeychainToken };