@beignet/agent-auth-better-auth 0.0.35 → 0.0.36

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @beignet/agent-auth-better-auth
2
2
 
3
+ ## 0.0.36
4
+
5
+ ### Patch Changes
6
+
7
+ - 5c7f6bb: Harden agent capability execution with lazy Better Auth executors, runtime required-constraint checks, validated lifecycle data, and adapter test utilities.
8
+
3
9
  ## 0.0.35
4
10
 
5
11
  ### Patch Changes
package/README.md CHANGED
@@ -133,18 +133,53 @@ export const auth = betterAuth({
133
133
  });
134
134
  ```
135
135
 
136
+ If auth initialization and server composition depend on each other, provide a
137
+ lazy executor instead of building an app-owned proxy:
138
+
139
+ ```typescript
140
+ import { agentCapabilityRegistry } from "@/lib/agent-capability-registry";
141
+
142
+ const agentCapabilities = createBetterAuthAgentCapabilityAdapter({
143
+ registry: agentCapabilityRegistry,
144
+ executor: () =>
145
+ import("@/server/agent-capabilities").then(
146
+ ({ agentCapabilityExecutor }) => agentCapabilityExecutor,
147
+ ),
148
+ principal({ agentSession }) {
149
+ if (!agentSession.userId) {
150
+ throw new APIError("FORBIDDEN", {
151
+ message: "A delegated user is required.",
152
+ });
153
+ }
154
+ return { agentId: agentSession.agentId, userId: agentSession.userId };
155
+ },
156
+ });
157
+ ```
158
+
159
+ Keep the transport-safe registry in a module that does not import server
160
+ composition; only the executor needs the dynamic server import.
161
+ The adapter loads the executor on the first execution and memoizes the first
162
+ successful resolution for the lifetime of the warm module instance. Concurrent
163
+ executions share initialization; a failed resolution is not cached.
164
+
136
165
  Zod schemas are converted to protocol JSON Schema by default. Pass a Beignet
137
166
  `SchemaConverter` through `schemaConverter` when using another Standard Schema
138
167
  library. Conversion runs at adapter creation so unsupported schemas fail during
139
168
  boot instead of on the first agent request.
140
169
 
141
170
  Agent Auth authorizes grant constraints against raw arguments before invoking
142
- the adapter. Beignet therefore rejects an invocation when schema validation
143
- changes a field constrained by the active grant. Keep constrained identifiers
144
- and amounts non-transforming; normalization remains available for unconstrained
145
- fields. The adapter snapshots active constrained values before validation,
146
- parses once, and checks the exact parsed input subsequently used for context
147
- construction and execution.
171
+ the adapter. The adapter also verifies at execution time that the active grant
172
+ still contains every field currently declared in `requiredConstraints`. This
173
+ prevents older broad grants from remaining usable after capability metadata is
174
+ tightened. Revoke or migrate stale grants so agents can request replacement
175
+ grants with the newly required scope.
176
+
177
+ Beignet also rejects an invocation when schema validation changes a field
178
+ constrained by the active grant. Keep constrained identifiers and amounts
179
+ non-transforming; normalization remains available for unconstrained fields.
180
+ The adapter snapshots active constrained values before validation, parses once,
181
+ and checks the exact parsed input subsequently used for context construction
182
+ and execution.
148
183
 
149
184
  This bridge intentionally uses Agent Auth's default capability execution
150
185
  endpoint. It does not expose custom capability `location` metadata because
@@ -165,6 +200,24 @@ Only synchronous request/response capability results are supported in this
165
200
  release. Agent Auth asynchronous polling and streaming results remain
166
201
  transport-owned and are not produced by the Beignet executor.
167
202
 
203
+ ## Testing
204
+
205
+ Use the adapter testing subpath to exercise `onExecute` without manufacturing
206
+ Better Auth's internal endpoint context:
207
+
208
+ ```typescript
209
+ import { createBetterAuthAgentCapabilityTestContext } from
210
+ "@beignet/agent-auth-better-auth/testing";
211
+
212
+ await agentCapabilities.onExecute?.(
213
+ createBetterAuthAgentCapabilityTestContext({
214
+ capability: "issues.create",
215
+ arguments: { workspaceId: "workspace_1", title: "Fix login" },
216
+ constraints: { workspaceId: "workspace_1" },
217
+ }),
218
+ );
219
+ ```
220
+
168
221
  ## Agent skills
169
222
 
170
223
  This package ships a TanStack Intent skill:
package/dist/index.d.ts CHANGED
@@ -16,9 +16,12 @@ export declare class BetterAuthAgentCapabilityAdapterError extends Error {
16
16
  /** Options for adapting a Beignet registry to Better Auth Agent Auth. */
17
17
  export interface CreateBetterAuthAgentCapabilityAdapterOptions<Definitions extends readonly AnyAgentCapabilityDef[]> {
18
18
  registry: AgentCapabilityRegistry<Definitions>;
19
- executor: AgentCapabilityExecutor<AgentCapabilityPrincipal<Definitions[number]>, Definitions>;
19
+ /** Direct executor or lazy factory memoized after its first successful load. */
20
+ executor: AgentCapabilityExecutor<AgentCapabilityPrincipal<Definitions[number]>, Definitions> | (() => MaybePromise<AgentCapabilityExecutor<AgentCapabilityPrincipal<Definitions[number]>, Definitions>>);
20
21
  principal(context: Parameters<NonNullable<AgentAuthOptions["onExecute"]>>[0]): MaybePromise<AgentCapabilityPrincipal<Definitions[number]>>;
22
+ /** Converter used to expose Standard Schema inputs and outputs as JSON Schema. */
21
23
  schemaConverter?: SchemaConverter;
24
+ /** Transport metadata keyed by names in the Beignet capability registry. */
22
25
  metadata?: Partial<Record<Definitions[number]["name"], BetterAuthAgentCapabilityMetadata>>;
23
26
  }
24
27
  /** Better Auth options produced from a Beignet capability registry. */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,uBAAuB,EACvB,wBAAwB,EACxB,uBAAuB,EACvB,qBAAqB,EACrB,YAAY,EACb,MAAM,kCAAkC,CAAC;AAG1C,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,KAAK,gBAAgB,EAErB,KAAK,UAAU,EAChB,MAAM,yBAAyB,CAAC;AAGjC,iFAAiF;AACjF,MAAM,MAAM,iCAAiC,GAAG,IAAI,CAClD,UAAU,EACV,kBAAkB,GAAG,UAAU,GAAG,qBAAqB,CACxD,CAAC;AAEF,iEAAiE;AACjE,qBAAa,qCAAsC,SAAQ,KAAK;IAC9D,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,SAAkB,KAAK,CAAC,EAAE,OAAO,CAAC;gBAEtB,IAAI,EAAE;QAChB,cAAc,EAAE,MAAM,CAAC;QACvB,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB;CAMF;AAED,yEAAyE;AACzE,MAAM,WAAW,6CAA6C,CAC5D,WAAW,SAAS,SAAS,qBAAqB,EAAE;IAEpD,QAAQ,EAAE,uBAAuB,CAAC,WAAW,CAAC,CAAC;IAC/C,QAAQ,EAAE,uBAAuB,CAC/B,wBAAwB,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,EAC7C,WAAW,CACZ,CAAC;IACF,SAAS,CACP,OAAO,EAAE,UAAU,CAAC,WAAW,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GACjE,YAAY,CAAC,wBAAwB,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC/D,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,EAAE,OAAO,CAChB,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE,iCAAiC,CAAC,CACvE,CAAC;CACH;AAED,uEAAuE;AACvE,MAAM,MAAM,gCAAgC,GAAG,IAAI,CACjD,gBAAgB,EAChB,cAAc,GAAG,WAAW,CAC7B,CAAC;AAmIF;;;GAGG;AACH,wBAAgB,sCAAsC,CACpD,KAAK,CAAC,WAAW,SAAS,SAAS,qBAAqB,EAAE,EAE1D,OAAO,EAAE,6CAA6C,CAAC,WAAW,CAAC,GAClE,gCAAgC,CAgDlC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,uBAAuB,EACvB,wBAAwB,EACxB,uBAAuB,EACvB,qBAAqB,EACrB,YAAY,EACb,MAAM,kCAAkC,CAAC;AAG1C,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,KAAK,gBAAgB,EAErB,KAAK,UAAU,EAChB,MAAM,yBAAyB,CAAC;AAGjC,iFAAiF;AACjF,MAAM,MAAM,iCAAiC,GAAG,IAAI,CAClD,UAAU,EACV,kBAAkB,GAAG,UAAU,GAAG,qBAAqB,CACxD,CAAC;AAEF,iEAAiE;AACjE,qBAAa,qCAAsC,SAAQ,KAAK;IAC9D,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,SAAkB,KAAK,CAAC,EAAE,OAAO,CAAC;gBAEtB,IAAI,EAAE;QAChB,cAAc,EAAE,MAAM,CAAC;QACvB,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB;CAMF;AAED,yEAAyE;AACzE,MAAM,WAAW,6CAA6C,CAC5D,WAAW,SAAS,SAAS,qBAAqB,EAAE;IAEpD,QAAQ,EAAE,uBAAuB,CAAC,WAAW,CAAC,CAAC;IAC/C,gFAAgF;IAChF,QAAQ,EACJ,uBAAuB,CACrB,wBAAwB,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,EAC7C,WAAW,CACZ,GACD,CAAC,MAAM,YAAY,CACjB,uBAAuB,CACrB,wBAAwB,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,EAC7C,WAAW,CACZ,CACF,CAAC,CAAC;IACP,SAAS,CACP,OAAO,EAAE,UAAU,CAAC,WAAW,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GACjE,YAAY,CAAC,wBAAwB,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC/D,kFAAkF;IAClF,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,OAAO,CAChB,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE,iCAAiC,CAAC,CACvE,CAAC;CACH;AAED,uEAAuE;AACvE,MAAM,MAAM,gCAAgC,GAAG,IAAI,CACjD,gBAAgB,EAChB,cAAc,GAAG,WAAW,CAC7B,CAAC;AAyLF;;;GAGG;AACH,wBAAgB,sCAAsC,CACpD,KAAK,CAAC,WAAW,SAAS,SAAS,qBAAqB,EAAE,EAE1D,OAAO,EAAE,6CAA6C,CAAC,WAAW,CAAC,GAClE,gCAAgC,CA0DlC"}
package/dist/index.js CHANGED
@@ -99,6 +99,33 @@ function snapshotConstrainedInput(args) {
99
99
  : undefined;
100
100
  return Object.fromEntries(Object.keys(args.constraints).map((field) => [field, rawInput?.[field]]));
101
101
  }
102
+ function assertGrantHasRequiredConstraints(args) {
103
+ const requiredConstraints = args.capability?.requiredConstraints ?? [];
104
+ if (requiredConstraints.length === 0)
105
+ return;
106
+ const missing = requiredConstraints.filter((field) => !args.constraints || !Object.hasOwn(args.constraints, field));
107
+ if (missing.length === 0)
108
+ return;
109
+ throw agentError("FORBIDDEN", AGENT_AUTH_ERROR_CODES.CONSTRAINT_VIOLATED, `The active grant for capability "${args.capability?.name}" is missing required constraints: ${missing.join(", ")}. Request a new constrained grant.`);
110
+ }
111
+ function createExecutorResolver(source) {
112
+ if (typeof source !== "function") {
113
+ return async () => source;
114
+ }
115
+ let pending;
116
+ return () => {
117
+ if (pending)
118
+ return pending;
119
+ const resolution = Promise.resolve().then(source);
120
+ const guarded = resolution.catch((error) => {
121
+ if (pending === guarded)
122
+ pending = undefined;
123
+ throw error;
124
+ });
125
+ pending = guarded;
126
+ return pending;
127
+ };
128
+ }
102
129
  /**
103
130
  * Convert a Beignet capability registry and executor into options accepted by
104
131
  * Better Auth's `agentAuth(...)` plugin.
@@ -122,18 +149,26 @@ export function createBetterAuthAgentCapabilityAdapter(options) {
122
149
  }),
123
150
  ...options.metadata?.[capability.name],
124
151
  }));
152
+ const capabilitiesByName = new Map(capabilities.map((capability) => [capability.name, capability]));
153
+ const resolveExecutor = createExecutorResolver(options.executor);
125
154
  return {
126
155
  capabilities,
127
156
  async onExecute(context) {
128
157
  try {
158
+ assertGrantHasRequiredConstraints({
159
+ capability: capabilitiesByName.get(context.capability),
160
+ constraints: context.grant.constraints,
161
+ });
129
162
  const rawInput = context.arguments ?? {};
130
163
  const constrainedInput = snapshotConstrainedInput({
131
164
  constraints: context.grant.constraints,
132
165
  rawInput,
133
166
  });
134
- return await options.executor.executeDynamic({
167
+ const principal = await options.principal(context);
168
+ const executor = await resolveExecutor();
169
+ return await executor.executeDynamic({
135
170
  name: context.capability,
136
- principal: await options.principal(context),
171
+ principal,
137
172
  input: rawInput,
138
173
  authorize({ input }) {
139
174
  assertConstrainedFieldsAreStable({
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EAAiB,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EACL,wBAAwB,GAEzB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,sBAAsB,EAEtB,UAAU,GAEX,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAQ3C,iEAAiE;AACjE,MAAM,OAAO,qCAAsC,SAAQ,KAAK;IAI9D,YAAY,IAIX;QACC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpB,IAAI,CAAC,IAAI,GAAG,uCAAuC,CAAC;QACpD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;QAC1C,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;IAC1B,CAAC;CACF;AAoCD,SAAS,aAAa,CAAC,IAKtB;IACC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,qCAAqC,CAAC;YAC9C,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,OAAO,EAAE,qBAAqB,IAAI,CAAC,SAAS,CAAC,IAAI,wBAAwB,IAAI,CAAC,EAAE,iCAAiC,IAAI,CAAC,cAAc,IAAI;SACzI,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE;YAC9C,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,QAAQ,EAAE,GAAG,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,EAAE,EAAE;SAC9C,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,qCAAqC,CAAC;YAC9C,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,OAAO,EAAE,qBAAqB,IAAI,CAAC,SAAS,CAAC,IAAI,2BAA2B,IAAI,CAAC,EAAE,iCAAiC,IAAI,CAAC,cAAc,IAAI;YAC3I,KAAK,EAAE,KAAK;SACb,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,KAAe;IACpC,MAAM,UAAU,CACd,KAAK,CAAC,MAAmD,EACzD;QACE,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,OAAO,EAAE,KAAK,CAAC,OAAO;KACvB,EACD,SAAS,EACT,KAAK,CAAC,OAAO,EACb;QACE,GAAG,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;KACnE,CACF,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAc;IACvC,IAAI,oBAAoB,CAAC,KAAK,CAAC;QAAE,MAAM,KAAK,CAAC;IAC7C,IAAI,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;IAEnD,IAAI,CAAC,CAAC,KAAK,YAAY,oBAAoB,CAAC,EAAE,CAAC;QAC7C,MAAM,UAAU,CACd,uBAAuB,EACvB,sBAAsB,CAAC,cAAc,CACtC,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;QACtC,IAAI,oBAAoB,CAAC,KAAK,CAAC,KAAK,CAAC;YAAE,MAAM,KAAK,CAAC,KAAK,CAAC;QACzD,IAAI,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC;YAAE,OAAO,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACjE,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,KAAK,oBAAoB,EAAE,CAAC;QACxC,MAAM,UAAU,CACd,aAAa,EACb,sBAAsB,CAAC,oBAAoB,CAC5C,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;QACnC,MAAM,UAAU,CAAC,aAAa,EAAE,sBAAsB,CAAC,eAAe,CAAC,CAAC;IAC1E,CAAC;IAED,MAAM,UAAU,CACd,uBAAuB,EACvB,sBAAsB,CAAC,cAAc,CACtC,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAc;IAC1C,IAAI,KAAK,YAAY,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU;QAAE,OAAO,KAAK,CAAC;IACzE,IAAI,CAAC,CAAC,YAAY,IAAI,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;QACrE,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,MAAM,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,gCAAgC,CAAC,IAIzC;IACC,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;IACrC,IAAI,CAAC,WAAW;QAAE,OAAO;IAEzB,MAAM,iBAAiB,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACnD,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAE3C,MAAM,WAAW,GACf,IAAI,CAAC,WAAW,IAAI,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ;QACtD,CAAC,CAAE,IAAI,CAAC,WAAuC;QAC/C,CAAC,CAAC,SAAS,CAAC;IAEhB,KAAK,MAAM,KAAK,IAAI,iBAAiB,EAAE,CAAC;QACtC,IACE,CAAC,IAAI,CAAC,gBAAgB;YACtB,CAAC,WAAW;YACZ,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,EAC5D,CAAC;YACD,MAAM,UAAU,CACd,WAAW,EACX,sBAAsB,CAAC,mBAAmB,EAC1C,oCAAoC,KAAK,8BAA8B,CACxE,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,wBAAwB,CAAC,IAGjC;IACC,IAAI,CAAC,IAAI,CAAC,WAAW;QAAE,OAAO,SAAS,CAAC;IACxC,MAAM,QAAQ,GACZ,IAAI,CAAC,QAAQ,IAAI,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ;QAChD,CAAC,CAAE,IAAI,CAAC,QAAoC;QAC5C,CAAC,CAAC,SAAS,CAAC;IAChB,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CACzE,CAAC;AACJ,CAAC;AAED,SAAS,iCAAiC,CAAC,IAG1C;IACC,MAAM,mBAAmB,GAAG,IAAI,CAAC,UAAU,EAAE,mBAAmB,IAAI,EAAE,CAAC;IACvE,IAAI,mBAAmB,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAE7C,MAAM,OAAO,GAAG,mBAAmB,CAAC,MAAM,CACxC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CACxE,CAAC;IACF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAEjC,MAAM,UAAU,CACd,WAAW,EACX,sBAAsB,CAAC,mBAAmB,EAC1C,oCAAoC,IAAI,CAAC,UAAU,EAAE,IAAI,sCAAsC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,oCAAoC,CACtJ,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAG7B,MAA8E;IAO9E,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;QACjC,OAAO,KAAK,IAAI,EAAE,CAAC,MAAM,CAAC;IAC5B,CAAC;IAED,IAAI,OAOS,CAAC;IAEd,OAAO,GAAG,EAAE;QACV,IAAI,OAAO;YAAE,OAAO,OAAO,CAAC;QAC5B,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YACzC,IAAI,OAAO,KAAK,OAAO;gBAAE,OAAO,GAAG,SAAS,CAAC;YAC7C,MAAM,KAAK,CAAC;QACd,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,OAAO,CAAC;QAClB,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sCAAsC,CAGpD,OAAmE;IAEnE,MAAM,SAAS,GAAG,OAAO,CAAC,eAAe,IAAI,wBAAwB,EAAE,CAAC;IACxE,MAAM,YAAY,GAAiB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,CACjE,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QACf,IAAI,EAAE,UAAU,CAAC,IAAI;QACrB,WAAW,EAAE,UAAU,CAAC,WAAW;QACnC,KAAK,EAAE,aAAa,CAAC;YACnB,cAAc,EAAE,UAAU,CAAC,IAAI;YAC/B,MAAM,EAAE,UAAU,CAAC,KAAK;YACxB,EAAE,EAAE,OAAO;YACX,SAAS;SACV,CAAC;QACF,MAAM,EAAE,aAAa,CAAC;YACpB,cAAc,EAAE,UAAU,CAAC,IAAI;YAC/B,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,EAAE,EAAE,QAAQ;YACZ,SAAS;SACV,CAAC;QACF,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,IAAmC,CAAC;KACtE,CAAC,CACH,CAAC;IACF,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAChC,YAAY,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAChE,CAAC;IACF,MAAM,eAAe,GAAG,sBAAsB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEjE,OAAO;QACL,YAAY;QACZ,KAAK,CAAC,SAAS,CAAC,OAAO;YACrB,IAAI,CAAC;gBACH,iCAAiC,CAAC;oBAChC,UAAU,EAAE,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC;oBACtD,WAAW,EAAE,OAAO,CAAC,KAAK,CAAC,WAAW;iBACvC,CAAC,CAAC;gBACH,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC;gBACzC,MAAM,gBAAgB,GAAG,wBAAwB,CAAC;oBAChD,WAAW,EAAE,OAAO,CAAC,KAAK,CAAC,WAAW;oBACtC,QAAQ;iBACT,CAAC,CAAC;gBACH,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;gBACnD,MAAM,QAAQ,GAAG,MAAM,eAAe,EAAE,CAAC;gBACzC,OAAO,MAAM,QAAQ,CAAC,cAAc,CAAC;oBACnC,IAAI,EAAE,OAAO,CAAC,UAAU;oBACxB,SAAS;oBACT,KAAK,EAAE,QAAQ;oBACf,SAAS,CAAC,EAAE,KAAK,EAAE;wBACjB,gCAAgC,CAAC;4BAC/B,WAAW,EAAE,OAAO,CAAC,KAAK,CAAC,WAAW;4BACtC,gBAAgB;4BAChB,WAAW,EAAE,KAAK;yBACnB,CAAC,CAAC;oBACL,CAAC;iBACF,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,iBAAiB,CAAC,KAAK,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,29 @@
1
+ import type { AgentAuthOptions } from "@better-auth/agent-auth";
2
+ /** Better Auth execution context accepted by an Agent Auth adapter. */
3
+ export type BetterAuthAgentCapabilityTestContext = Parameters<NonNullable<AgentAuthOptions["onExecute"]>>[0];
4
+ /** Options for a minimal Better Auth Agent Auth execution context. */
5
+ export interface CreateBetterAuthAgentCapabilityTestContextOptions {
6
+ /** Capability name presented to the adapter. */
7
+ capability?: string;
8
+ /** Raw capability arguments presented by Agent Auth. */
9
+ arguments?: Record<string, unknown>;
10
+ /** Constraints attached to the active grant. */
11
+ constraints?: BetterAuthAgentCapabilityTestContext["grant"]["constraints"];
12
+ /** Verified agent identifier. */
13
+ agentId?: string;
14
+ /** Represented user identifier, or null for an autonomous agent. */
15
+ userId?: string | null;
16
+ /** Complete capability definition override for advanced adapter tests. */
17
+ capabilityDef?: BetterAuthAgentCapabilityTestContext["capabilityDef"];
18
+ /** Agent session fields merged over the generated session. */
19
+ agentSession?: Partial<BetterAuthAgentCapabilityTestContext["agentSession"]>;
20
+ /** Grant fields merged over the generated active grant. */
21
+ grant?: Partial<BetterAuthAgentCapabilityTestContext["grant"]>;
22
+ /** Better Auth endpoint context override. */
23
+ ctx?: BetterAuthAgentCapabilityTestContext["ctx"];
24
+ /** Grant revocation callback override. */
25
+ revokeGrant?: BetterAuthAgentCapabilityTestContext["revokeGrant"];
26
+ }
27
+ /** Create a typed execution context for adapter unit tests. */
28
+ export declare function createBetterAuthAgentCapabilityTestContext(options?: CreateBetterAuthAgentCapabilityTestContextOptions): BetterAuthAgentCapabilityTestContext;
29
+ //# sourceMappingURL=testing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,uEAAuE;AACvE,MAAM,MAAM,oCAAoC,GAAG,UAAU,CAC3D,WAAW,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAC3C,CAAC,CAAC,CAAC,CAAC;AAEL,sEAAsE;AACtE,MAAM,WAAW,iDAAiD;IAChE,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,gDAAgD;IAChD,WAAW,CAAC,EAAE,oCAAoC,CAAC,OAAO,CAAC,CAAC,aAAa,CAAC,CAAC;IAC3E,iCAAiC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,0EAA0E;IAC1E,aAAa,CAAC,EAAE,oCAAoC,CAAC,eAAe,CAAC,CAAC;IACtE,8DAA8D;IAC9D,YAAY,CAAC,EAAE,OAAO,CAAC,oCAAoC,CAAC,cAAc,CAAC,CAAC,CAAC;IAC7E,2DAA2D;IAC3D,KAAK,CAAC,EAAE,OAAO,CAAC,oCAAoC,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/D,6CAA6C;IAC7C,GAAG,CAAC,EAAE,oCAAoC,CAAC,KAAK,CAAC,CAAC;IAClD,0CAA0C;IAC1C,WAAW,CAAC,EAAE,oCAAoC,CAAC,aAAa,CAAC,CAAC;CACnE;AAED,+DAA+D;AAC/D,wBAAgB,0CAA0C,CACxD,OAAO,GAAE,iDAAsD,GAC9D,oCAAoC,CAyDtC"}
@@ -0,0 +1,59 @@
1
+ /** Create a typed execution context for adapter unit tests. */
2
+ export function createBetterAuthAgentCapabilityTestContext(options = {}) {
3
+ const capability = options.capability ?? "capability.test";
4
+ const agentId = options.agentId ?? "agent_test";
5
+ const userId = options.userId === undefined ? "user_test" : options.userId;
6
+ const now = new Date("2026-01-01T00:00:00.000Z");
7
+ const capabilityDef = options.capabilityDef ?? {
8
+ name: capability,
9
+ description: `Test capability ${capability}`,
10
+ input: { type: "object" },
11
+ output: { type: "object" },
12
+ };
13
+ const grant = {
14
+ id: "grant_test",
15
+ agentId,
16
+ capability,
17
+ constraints: options.constraints ?? null,
18
+ grantedBy: userId,
19
+ deniedBy: null,
20
+ reason: null,
21
+ expiresAt: null,
22
+ status: "active",
23
+ createdAt: now,
24
+ updatedAt: now,
25
+ ...options.grant,
26
+ };
27
+ const agentSession = {
28
+ type: "delegated",
29
+ agentId,
30
+ userId,
31
+ agent: {
32
+ id: agentId,
33
+ name: "Test agent",
34
+ mode: "delegated",
35
+ capabilityGrants: [grant],
36
+ hostId: "host_test",
37
+ createdAt: now,
38
+ activatedAt: now,
39
+ metadata: null,
40
+ },
41
+ host: null,
42
+ user: {
43
+ id: userId ?? `agent-user:${agentId}`,
44
+ name: "Test user",
45
+ email: "agent-test@example.test",
46
+ },
47
+ ...options.agentSession,
48
+ };
49
+ return {
50
+ ctx: options.ctx ?? {},
51
+ capability,
52
+ capabilityDef,
53
+ arguments: options.arguments,
54
+ agentSession,
55
+ grant,
56
+ revokeGrant: options.revokeGrant ?? (async () => { }),
57
+ };
58
+ }
59
+ //# sourceMappingURL=testing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AA+BA,+DAA+D;AAC/D,MAAM,UAAU,0CAA0C,CACxD,UAA6D,EAAE;IAE/D,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,iBAAiB,CAAC;IAC3D,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,YAAY,CAAC;IAChD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IAC3E,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,0BAA0B,CAAC,CAAC;IACjD,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI;QAC7C,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE,mBAAmB,UAAU,EAAE;QAC5C,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACzB,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;KAC3B,CAAC;IACF,MAAM,KAAK,GAAG;QACZ,EAAE,EAAE,YAAY;QAChB,OAAO;QACP,UAAU;QACV,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,IAAI;QACxC,SAAS,EAAE,MAAM;QACjB,QAAQ,EAAE,IAAI;QACd,MAAM,EAAE,IAAI;QACZ,SAAS,EAAE,IAAI;QACf,MAAM,EAAE,QAAiB;QACzB,SAAS,EAAE,GAAG;QACd,SAAS,EAAE,GAAG;QACd,GAAG,OAAO,CAAC,KAAK;KACjB,CAAC;IACF,MAAM,YAAY,GAAG;QACnB,IAAI,EAAE,WAAoB;QAC1B,OAAO;QACP,MAAM;QACN,KAAK,EAAE;YACL,EAAE,EAAE,OAAO;YACX,IAAI,EAAE,YAAY;YAClB,IAAI,EAAE,WAAoB;YAC1B,gBAAgB,EAAE,CAAC,KAAK,CAAC;YACzB,MAAM,EAAE,WAAW;YACnB,SAAS,EAAE,GAAG;YACd,WAAW,EAAE,GAAG;YAChB,QAAQ,EAAE,IAAI;SACf;QACD,IAAI,EAAE,IAAI;QACV,IAAI,EAAE;YACJ,EAAE,EAAE,MAAM,IAAI,cAAc,OAAO,EAAE;YACrC,IAAI,EAAE,WAAW;YACjB,KAAK,EAAE,yBAAyB;SACjC;QACD,GAAG,OAAO,CAAC,YAAY;KACxB,CAAC;IAEF,OAAO;QACL,GAAG,EAAE,OAAO,CAAC,GAAG,IAAK,EAAkD;QACvE,UAAU;QACV,aAAa;QACb,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,YAAY;QACZ,KAAK;QACL,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,CAAC,KAAK,IAAI,EAAE,GAAE,CAAC,CAAC;KACrD,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beignet/agent-auth-better-auth",
3
- "version": "0.0.35",
3
+ "version": "0.0.36",
4
4
  "type": "module",
5
5
  "description": "Better Auth Agent Auth adapter for Beignet agent capabilities",
6
6
  "main": "./dist/index.js",
@@ -9,6 +9,10 @@
9
9
  ".": {
10
10
  "types": "./dist/index.d.ts",
11
11
  "default": "./dist/index.js"
12
+ },
13
+ "./testing": {
14
+ "types": "./dist/testing.d.ts",
15
+ "default": "./dist/testing.js"
12
16
  }
13
17
  },
14
18
  "files": [
@@ -29,11 +29,21 @@ approval strength, required constraints, and grant TTL in the adapter's typed
29
29
  bypass the bridge and must implement Agent Auth verification, grant enforcement,
30
30
  Beignet execution, and output validation independently.
31
31
 
32
+ Pass an executor factory when auth and server modules depend on each other.
33
+ Keep the registry in an import-safe module that does not import server
34
+ composition, then dynamically import only the executor.
35
+ The adapter resolves it on first execution, shares concurrent initialization,
36
+ memoizes success per warm module instance, and retries after initialization
37
+ failure.
38
+
32
39
  Grant constraints are checked by Agent Auth against raw arguments. Do not
33
40
  transform constrained fields such as tenant IDs, resource IDs, or amounts in
34
41
  the capability input schema. The adapter snapshots active constrained values
35
42
  before its single validation pass and rejects executions where validation
36
- changes one; normalization is fine for unconstrained fields.
43
+ changes one; normalization is fine for unconstrained fields. The adapter also
44
+ rejects active grants missing any currently required constraint. Revoke or
45
+ migrate stale grants after tightening capability metadata so agents can request
46
+ replacement scoped grants.
37
47
 
38
48
  Better Auth owns registration, JWT verification, grants, constraints,
39
49
  approval, and protocol persistence. Beignet owns validation, context, use-case
@@ -45,5 +55,9 @@ to return to the agent. AppError codes are preserved by individual and batch
45
55
  execution; only individual execution carries the AppError HTTP status.
46
56
 
47
57
  Test malformed inputs, missing tenant membership, authorization denial,
48
- output validation, and successful query/command execution. Do not record raw
49
- principal data, arguments, or results in instrumentation.
58
+ output validation, stale broad grants, and successful query/command execution.
59
+ Use `createBetterAuthAgentCapabilityTestContext(...)` from
60
+ `@beignet/agent-auth-better-auth/testing` instead of casting Better Auth
61
+ execution contexts. Completion hooks receive validated input/output and error
62
+ hooks receive validated input only when available. Do not record raw principal
63
+ data, arguments, or results in instrumentation.
package/src/index.ts CHANGED
@@ -47,14 +47,24 @@ export interface CreateBetterAuthAgentCapabilityAdapterOptions<
47
47
  Definitions extends readonly AnyAgentCapabilityDef[],
48
48
  > {
49
49
  registry: AgentCapabilityRegistry<Definitions>;
50
- executor: AgentCapabilityExecutor<
51
- AgentCapabilityPrincipal<Definitions[number]>,
52
- Definitions
53
- >;
50
+ /** Direct executor or lazy factory memoized after its first successful load. */
51
+ executor:
52
+ | AgentCapabilityExecutor<
53
+ AgentCapabilityPrincipal<Definitions[number]>,
54
+ Definitions
55
+ >
56
+ | (() => MaybePromise<
57
+ AgentCapabilityExecutor<
58
+ AgentCapabilityPrincipal<Definitions[number]>,
59
+ Definitions
60
+ >
61
+ >);
54
62
  principal(
55
63
  context: Parameters<NonNullable<AgentAuthOptions["onExecute"]>>[0],
56
64
  ): MaybePromise<AgentCapabilityPrincipal<Definitions[number]>>;
65
+ /** Converter used to expose Standard Schema inputs and outputs as JSON Schema. */
57
66
  schemaConverter?: SchemaConverter;
67
+ /** Transport metadata keyed by names in the Beignet capability registry. */
58
68
  metadata?: Partial<
59
69
  Record<Definitions[number]["name"], BetterAuthAgentCapabilityMetadata>
60
70
  >;
@@ -195,6 +205,60 @@ function snapshotConstrainedInput(args: {
195
205
  );
196
206
  }
197
207
 
208
+ function assertGrantHasRequiredConstraints(args: {
209
+ capability: Capability | undefined;
210
+ constraints: Record<string, unknown> | null | undefined;
211
+ }): void {
212
+ const requiredConstraints = args.capability?.requiredConstraints ?? [];
213
+ if (requiredConstraints.length === 0) return;
214
+
215
+ const missing = requiredConstraints.filter(
216
+ (field) => !args.constraints || !Object.hasOwn(args.constraints, field),
217
+ );
218
+ if (missing.length === 0) return;
219
+
220
+ throw agentError(
221
+ "FORBIDDEN",
222
+ AGENT_AUTH_ERROR_CODES.CONSTRAINT_VIOLATED,
223
+ `The active grant for capability "${args.capability?.name}" is missing required constraints: ${missing.join(", ")}. Request a new constrained grant.`,
224
+ );
225
+ }
226
+
227
+ function createExecutorResolver<
228
+ Definitions extends readonly AnyAgentCapabilityDef[],
229
+ >(
230
+ source: CreateBetterAuthAgentCapabilityAdapterOptions<Definitions>["executor"],
231
+ ): () => Promise<
232
+ AgentCapabilityExecutor<
233
+ AgentCapabilityPrincipal<Definitions[number]>,
234
+ Definitions
235
+ >
236
+ > {
237
+ if (typeof source !== "function") {
238
+ return async () => source;
239
+ }
240
+
241
+ let pending:
242
+ | Promise<
243
+ AgentCapabilityExecutor<
244
+ AgentCapabilityPrincipal<Definitions[number]>,
245
+ Definitions
246
+ >
247
+ >
248
+ | undefined;
249
+
250
+ return () => {
251
+ if (pending) return pending;
252
+ const resolution = Promise.resolve().then(source);
253
+ const guarded = resolution.catch((error) => {
254
+ if (pending === guarded) pending = undefined;
255
+ throw error;
256
+ });
257
+ pending = guarded;
258
+ return pending;
259
+ };
260
+ }
261
+
198
262
  /**
199
263
  * Convert a Beignet capability registry and executor into options accepted by
200
264
  * Better Auth's `agentAuth(...)` plugin.
@@ -224,19 +288,29 @@ export function createBetterAuthAgentCapabilityAdapter<
224
288
  ...options.metadata?.[capability.name as Definitions[number]["name"]],
225
289
  }),
226
290
  );
291
+ const capabilitiesByName = new Map(
292
+ capabilities.map((capability) => [capability.name, capability]),
293
+ );
294
+ const resolveExecutor = createExecutorResolver(options.executor);
227
295
 
228
296
  return {
229
297
  capabilities,
230
298
  async onExecute(context) {
231
299
  try {
300
+ assertGrantHasRequiredConstraints({
301
+ capability: capabilitiesByName.get(context.capability),
302
+ constraints: context.grant.constraints,
303
+ });
232
304
  const rawInput = context.arguments ?? {};
233
305
  const constrainedInput = snapshotConstrainedInput({
234
306
  constraints: context.grant.constraints,
235
307
  rawInput,
236
308
  });
237
- return await options.executor.executeDynamic({
309
+ const principal = await options.principal(context);
310
+ const executor = await resolveExecutor();
311
+ return await executor.executeDynamic({
238
312
  name: context.capability,
239
- principal: await options.principal(context),
313
+ principal,
240
314
  input: rawInput,
241
315
  authorize({ input }) {
242
316
  assertConstrainedFieldsAreStable({
package/src/testing.ts ADDED
@@ -0,0 +1,92 @@
1
+ import type { AgentAuthOptions } from "@better-auth/agent-auth";
2
+
3
+ /** Better Auth execution context accepted by an Agent Auth adapter. */
4
+ export type BetterAuthAgentCapabilityTestContext = Parameters<
5
+ NonNullable<AgentAuthOptions["onExecute"]>
6
+ >[0];
7
+
8
+ /** Options for a minimal Better Auth Agent Auth execution context. */
9
+ export interface CreateBetterAuthAgentCapabilityTestContextOptions {
10
+ /** Capability name presented to the adapter. */
11
+ capability?: string;
12
+ /** Raw capability arguments presented by Agent Auth. */
13
+ arguments?: Record<string, unknown>;
14
+ /** Constraints attached to the active grant. */
15
+ constraints?: BetterAuthAgentCapabilityTestContext["grant"]["constraints"];
16
+ /** Verified agent identifier. */
17
+ agentId?: string;
18
+ /** Represented user identifier, or null for an autonomous agent. */
19
+ userId?: string | null;
20
+ /** Complete capability definition override for advanced adapter tests. */
21
+ capabilityDef?: BetterAuthAgentCapabilityTestContext["capabilityDef"];
22
+ /** Agent session fields merged over the generated session. */
23
+ agentSession?: Partial<BetterAuthAgentCapabilityTestContext["agentSession"]>;
24
+ /** Grant fields merged over the generated active grant. */
25
+ grant?: Partial<BetterAuthAgentCapabilityTestContext["grant"]>;
26
+ /** Better Auth endpoint context override. */
27
+ ctx?: BetterAuthAgentCapabilityTestContext["ctx"];
28
+ /** Grant revocation callback override. */
29
+ revokeGrant?: BetterAuthAgentCapabilityTestContext["revokeGrant"];
30
+ }
31
+
32
+ /** Create a typed execution context for adapter unit tests. */
33
+ export function createBetterAuthAgentCapabilityTestContext(
34
+ options: CreateBetterAuthAgentCapabilityTestContextOptions = {},
35
+ ): BetterAuthAgentCapabilityTestContext {
36
+ const capability = options.capability ?? "capability.test";
37
+ const agentId = options.agentId ?? "agent_test";
38
+ const userId = options.userId === undefined ? "user_test" : options.userId;
39
+ const now = new Date("2026-01-01T00:00:00.000Z");
40
+ const capabilityDef = options.capabilityDef ?? {
41
+ name: capability,
42
+ description: `Test capability ${capability}`,
43
+ input: { type: "object" },
44
+ output: { type: "object" },
45
+ };
46
+ const grant = {
47
+ id: "grant_test",
48
+ agentId,
49
+ capability,
50
+ constraints: options.constraints ?? null,
51
+ grantedBy: userId,
52
+ deniedBy: null,
53
+ reason: null,
54
+ expiresAt: null,
55
+ status: "active" as const,
56
+ createdAt: now,
57
+ updatedAt: now,
58
+ ...options.grant,
59
+ };
60
+ const agentSession = {
61
+ type: "delegated" as const,
62
+ agentId,
63
+ userId,
64
+ agent: {
65
+ id: agentId,
66
+ name: "Test agent",
67
+ mode: "delegated" as const,
68
+ capabilityGrants: [grant],
69
+ hostId: "host_test",
70
+ createdAt: now,
71
+ activatedAt: now,
72
+ metadata: null,
73
+ },
74
+ host: null,
75
+ user: {
76
+ id: userId ?? `agent-user:${agentId}`,
77
+ name: "Test user",
78
+ email: "agent-test@example.test",
79
+ },
80
+ ...options.agentSession,
81
+ };
82
+
83
+ return {
84
+ ctx: options.ctx ?? ({} as BetterAuthAgentCapabilityTestContext["ctx"]),
85
+ capability,
86
+ capabilityDef,
87
+ arguments: options.arguments,
88
+ agentSession,
89
+ grant,
90
+ revokeGrant: options.revokeGrant ?? (async () => {}),
91
+ };
92
+ }