@mantyx/sdk 0.10.0 → 0.10.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/CHANGELOG.md CHANGED
@@ -3,7 +3,7 @@
3
3
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
4
4
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
5
5
 
6
- ## [Unreleased]
6
+ ## [0.10.0] — 2026-05-13
7
7
 
8
8
  ### Added
9
9
 
@@ -80,7 +80,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
80
80
 
81
81
  ## [0.1.0] — 2026-05-02
82
82
 
83
- [unreleased]: https://github.com/mantyx-io/mantyx-sdk/compare/v0.9.1..HEAD
83
+ [0.10.0]: https://github.com/mantyx-io/mantyx-sdk/compare/v0.9.1..v0.10.0
84
84
  [0.9.1]: https://github.com/mantyx-io/mantyx-sdk/compare/v0.9.0..v0.9.1
85
85
  [0.9.0]: https://github.com/mantyx-io/mantyx-sdk/compare/v0.8.0..v0.9.0
86
86
  [0.8.0]: https://github.com/mantyx-io/mantyx-sdk/compare/v0.7.0..v0.8.0
package/README.md CHANGED
@@ -555,58 +555,64 @@ All thrown errors extend `MantyxError`. Common subclasses:
555
555
 
556
556
  ### OAuth 2.0 refresh
557
557
 
558
- For long-running services, hand the SDK a `TokenSource` instead of a
559
- static `accessToken` the client refreshes proactively before
560
- expiry and again on 401, retrying the original request exactly once.
561
- Refresh tokens are **persistent and non-rotating** per
562
- [`docs/oauth.md`](./docs/oauth.md): the caller persists the
563
- `refreshToken` once at first sign-in (treat it as long-lived,
564
- encrypted at rest) and the SDK re-mints access tokens from it
565
- transparently.
558
+ The SDK ships a **refresh-only** OAuth client. It assumes the calling
559
+ app already obtained a refresh token through its own sign-in flow
560
+ (browser PKCE redirect, native auth, server-side exchange whatever
561
+ fits the host). The library does not drive consent and does not
562
+ initiate authorization-code or client-credentials grants. Once you
563
+ have the refresh token, hand it to the SDK and the rest is
564
+ transparent:
565
+
566
+ - Refresh tokens are **persistent and non-rotating** per
567
+ [`docs/oauth.md`](./docs/oauth.md): store them once at first
568
+ sign-in (treat them as long-lived, encrypted at rest) and the SDK
569
+ re-mints access tokens from the same value on demand.
570
+ - A `TokenSource` is called before every request and again on `401`,
571
+ with single-flight collapse on concurrent refreshes.
572
+ - `400 invalid_grant` from the token endpoint is surfaced as
573
+ `MantyxOAuthError` — that means the refresh has been revoked and
574
+ the caller has to drive a fresh sign-in.
566
575
 
567
576
  ```ts
568
577
  import { MantyxClient, MantyxOAuthClient } from "@mantyx/sdk";
569
578
 
570
579
  const oauth = new MantyxOAuthClient({
571
- clientId: process.env.MANTYX_OAUTH_CLIENT_ID!, // mantyx_oa_…
580
+ clientId: process.env.MANTYX_OAUTH_CLIENT_ID!, // mantyx_oa_…
572
581
  clientSecret: process.env.MANTYX_OAUTH_CLIENT_SECRET!, // mantyx_oas_…
573
582
  });
574
583
 
575
- // (1) Authorization-code: swap a `code` for the initial token pair, persist
576
- // the refresh token against the user record. See docs/oauth.md for the
577
- // full PKCE redirect dance the calling app is responsible for.
578
- const initial = await oauth.exchangeAuthorizationCode({
579
- code: authCode,
580
- redirectUri: "https://app.example.com/cb",
581
- codeVerifier: storedVerifier,
582
- });
583
- await db.users.update(userId, { mantyxRefreshToken: initial.refreshToken });
584
-
585
- // (2) End-user clients: build a refresh-driven TokenSource from the
586
- // persisted refresh token. The SDK calls it before every request and on
587
- // 401s; concurrent requests collapse onto one refresh.
584
+ // (1) Hand the SDK a stored refresh token — it caches the access token in
585
+ // memory, refreshes proactively before expiry, and retries the original
586
+ // request once on a 401.
588
587
  const client = new MantyxClient({
589
588
  tokenSource: oauth.refreshTokenSource({
590
- refreshToken: initial.refreshToken!,
591
- initialToken: initial,
589
+ refreshToken: storedRefreshToken, // mantyx_rt_…
592
590
  }),
593
591
  workspaceSlug: "acme",
594
592
  });
595
593
 
596
- // (3) Service-to-service: client_credentials sources never hold a refresh
597
- // token; they re-mint access tokens on demand.
598
- const svcClient = new MantyxClient({
599
- tokenSource: oauth.clientCredentialsTokenSource({ scope: ["agents:invoke"] }),
594
+ // (2) If the calling app already has a non-expired access token in hand
595
+ // (e.g. straight out of its sign-in flow), pass it as `initialToken` to
596
+ // skip the first /token round-trip.
597
+ const seeded = new MantyxClient({
598
+ tokenSource: oauth.refreshTokenSource({
599
+ refreshToken: storedRefreshToken,
600
+ initialToken: tokenFromSignIn,
601
+ }),
600
602
  workspaceSlug: "acme",
601
603
  });
602
604
 
603
- // (4) Manual override is still supported for short-lived access tokens that
604
- // the caller already manages.
605
+ // (3) Manual override for short-lived access tokens the caller manages
606
+ // itself no refresh, no retry, no OAuth client needed.
605
607
  const oneShot = new MantyxClient({ accessToken: "mantyx_at_…", workspaceSlug: "acme" });
608
+
609
+ // Optional: revoke a refresh token at sign-out — this kills the refresh and
610
+ // every live access token tied to its grant.
611
+ await oauth.revoke({ token: storedRefreshToken });
606
612
  ```
607
613
 
608
614
  See [`docs/oauth.md`](./docs/oauth.md) for grant types, token formats,
609
- and revocation.
615
+ scope catalog, and revocation semantics.
610
616
 
611
617
  ## Examples
612
618
 
@@ -2,7 +2,7 @@ import { AgentCard } from '@a2a-js/sdk';
2
2
  export { AgentCard, Message, MessageSendParams, Task, TaskArtifactUpdateEvent, TaskStatusUpdateEvent } from '@a2a-js/sdk';
3
3
  import { AgentExecutor, RequestContext, ExecutionEventBus } from '@a2a-js/sdk/server';
4
4
  export { AgentExecutor, ExecutionEventBus, RequestContext } from '@a2a-js/sdk/server';
5
- import { M as MantyxClient, T as ToolRef, R as ReasoningLevel } from './client-DHwh8MPj.cjs';
5
+ import { M as MantyxClient, T as ToolRef, R as ReasoningLevel } from './client-CZUVldDx.cjs';
6
6
  import 'zod';
7
7
 
8
8
  /**
@@ -2,7 +2,7 @@ import { AgentCard } from '@a2a-js/sdk';
2
2
  export { AgentCard, Message, MessageSendParams, Task, TaskArtifactUpdateEvent, TaskStatusUpdateEvent } from '@a2a-js/sdk';
3
3
  import { AgentExecutor, RequestContext, ExecutionEventBus } from '@a2a-js/sdk/server';
4
4
  export { AgentExecutor, ExecutionEventBus, RequestContext } from '@a2a-js/sdk/server';
5
- import { M as MantyxClient, T as ToolRef, R as ReasoningLevel } from './client-DHwh8MPj.js';
5
+ import { M as MantyxClient, T as ToolRef, R as ReasoningLevel } from './client-CZUVldDx.js';
6
6
  import 'zod';
7
7
 
8
8
  /**
@@ -113,26 +113,28 @@ declare class MantyxParseError extends MantyxError {
113
113
  }
114
114
 
115
115
  /**
116
- * MANTYX OAuth 2.0 client: authorization-code exchange, refresh-token
117
- * minting, client-credentials grant, and token revocation, plus typed
118
- * {@link TokenSource}s that {@link MantyxClient} can consume to refresh
119
- * access tokens transparently before they expire (and again on 401).
116
+ * MANTYX OAuth 2.0 refresh client: trade a stored refresh token for
117
+ * short-lived access tokens, revoke tokens at sign-out, and expose
118
+ * a {@link TokenSource} the {@link MantyxClient} HTTP layer calls
119
+ * before every request (and again on 401).
120
120
  *
121
- * The wire contract this implements is `docs/oauth.md` in the SDK monorepo:
121
+ * The library is intentionally **refresh-only**. It assumes the caller
122
+ * already obtained the refresh token through their own sign-in flow
123
+ * (Authorization Code + PKCE in a browser, native redirect, server-
124
+ * side exchange — whatever fits the host application). The SDK does
125
+ * not drive consent, does not initiate auth-code exchanges, and does
126
+ * not bundle PKCE helpers.
122
127
  *
123
- * - Token endpoint: `POST <baseUrl>/api/oauth/token`, form-encoded.
128
+ * Wire contract (`docs/oauth.md`):
129
+ *
130
+ * - Token endpoint: `POST <baseUrl>/api/oauth/token`, form-encoded,
131
+ * `grant_type=refresh_token`. Echoes back the same `refresh_token`
132
+ * the client sent (refresh tokens are persistent and non-rotating).
124
133
  * - Revoke endpoint: `POST <baseUrl>/api/oauth/revoke`, form-encoded.
125
134
  * - Access tokens (`mantyx_at_…`) live 1 hour (`expires_in: 3600`).
126
- * - Refresh tokens (`mantyx_rt_…`) are **persistent and non-rotating**:
127
- * `grant_type=refresh_token` echoes back the same value the client
128
- * sent. The caller persists the refresh token once at first sign-in
129
- * (encrypted at rest) and the SDK re-mints access tokens from it on
130
- * demand.
131
- *
132
- * See also `docs/oauth.md` for the authorization-code + PKCE consent
133
- * flow (which the SDK does **not** drive — the calling app owns the
134
- * redirect dance; once it has the auth code, `exchangeAuthorizationCode`
135
- * swaps it for the initial `{access_token, refresh_token}` pair).
135
+ * - Refresh tokens (`mantyx_rt_…`) are long-lived; the caller persists
136
+ * them once at first sign-in (encrypted at rest) and the SDK re-mints
137
+ * access tokens from the same value on demand.
136
138
  */
137
139
 
138
140
  declare const DEFAULT_OAUTH_BASE_URL = "https://app.mantyx.io";
@@ -157,12 +159,12 @@ declare class MantyxOAuthError extends MantyxError {
157
159
  }
158
160
  /**
159
161
  * Decoded `POST /api/oauth/token` response, augmented with an absolute
160
- * `expiresAt` timestamp the SDK can use to decide when to refresh.
162
+ * `expiresAt` timestamp the SDK uses to decide when to refresh.
161
163
  *
162
- * `refreshToken` is present on the initial `authorization_code` exchange
163
- * and on subsequent `refresh_token` calls (where it is identical to the
164
- * value the client just sent refresh tokens never rotate). The
165
- * `client_credentials` grant never returns one.
164
+ * On the refresh grant the response's `refreshToken` is identical to
165
+ * the value the client just sent (refresh tokens never rotate). The
166
+ * field is surfaced for symmetry with whatever the calling app's
167
+ * sign-in flow already does.
166
168
  */
167
169
  interface OAuthToken {
168
170
  readonly accessToken: string;
@@ -209,11 +211,6 @@ interface MantyxOAuthClientOptions {
209
211
  /** Default per-request timeout in milliseconds. Default: 30s. */
210
212
  timeoutMs?: number;
211
213
  }
212
- interface ExchangeAuthorizationCodeOptions {
213
- code: string;
214
- redirectUri: string;
215
- codeVerifier: string;
216
- }
217
214
  interface RefreshOptions {
218
215
  refreshToken: string;
219
216
  /**
@@ -224,9 +221,6 @@ interface RefreshOptions {
224
221
  */
225
222
  scope?: string | readonly string[];
226
223
  }
227
- interface ClientCredentialsOptions {
228
- scope?: string | readonly string[];
229
- }
230
224
  interface RevokeOptions {
231
225
  token: string;
232
226
  }
@@ -241,21 +235,24 @@ interface RefreshTokenSourceOptions {
241
235
  refreshSkewMs?: number;
242
236
  /**
243
237
  * Optional initial access token + expiry to seed the source's cache
244
- * with (e.g. the token already in hand from the authorization-code
245
- * exchange). When omitted, the source mints one on the first call.
238
+ * with (e.g. the token already in hand from the host application's
239
+ * sign-in flow). When omitted, the source mints one on the first
240
+ * call.
246
241
  */
247
242
  initialToken?: OAuthToken;
248
243
  }
249
- interface ClientCredentialsTokenSourceOptions {
250
- scope?: string | readonly string[];
251
- refreshSkewMs?: number;
252
- }
253
244
  /**
254
- * Wraps the MANTYX OAuth 2.0 authorization-server endpoints. App-scoped
255
- * (one per `{clientId, clientSecret}` pair); construct independently of
256
- * {@link MantyxClient}, then either call its grant helpers directly or
257
- * hand a `TokenSource` it produces to `MantyxClient` for fully
258
- * transparent refresh.
245
+ * Refresh-only wrapper around the MANTYX OAuth 2.0 authorization-server
246
+ * endpoints. App-scoped (one per `{clientId, clientSecret}` pair);
247
+ * construct independently of {@link MantyxClient}, then either call
248
+ * {@link refresh} / {@link revoke} directly or hand a `TokenSource`
249
+ * produced by {@link refreshTokenSource} to `MantyxClient` for fully
250
+ * transparent refresh on every request.
251
+ *
252
+ * The client deliberately does **not** drive the authorization-code
253
+ * exchange or any other "initiate sign-in" grant. The caller is
254
+ * expected to obtain the refresh token through their own consent flow
255
+ * and persist it before constructing this client.
259
256
  */
260
257
  declare class MantyxOAuthClient {
261
258
  readonly clientId: string;
@@ -264,33 +261,17 @@ declare class MantyxOAuthClient {
264
261
  private readonly fetchImpl;
265
262
  private readonly timeoutMs;
266
263
  constructor(opts: MantyxOAuthClientOptions);
267
- /**
268
- * Swap an authorization-code + PKCE verifier for the initial
269
- * `{access_token, refresh_token}` pair. Call this exactly once per
270
- * sign-in after the browser/native redirect lands back on your
271
- * `redirectUri` with a `code` parameter. Persist the returned
272
- * `refreshToken` against the user record — it is long-lived and
273
- * non-rotating per `docs/oauth.md` §"Token lifetimes & lifecycle".
274
- */
275
- exchangeAuthorizationCode(opts: ExchangeAuthorizationCodeOptions): Promise<OAuthToken>;
276
264
  /**
277
265
  * Mint a fresh access token from a stored refresh token. The
278
- * returned `refreshToken` is identical to the input — the field is
279
- * surfaced for symmetry with {@link exchangeAuthorizationCode} only.
266
+ * returned `refreshToken` is identical to the input — refresh
267
+ * tokens are persistent and non-rotating, so the field is
268
+ * surfaced only for symmetry with the response shape.
280
269
  *
281
270
  * On `400 invalid_grant` the refresh token has been revoked (or its
282
271
  * grant / app was deleted); the SDK surfaces a
283
272
  * {@link MantyxOAuthError} and callers must drive a fresh sign-in.
284
273
  */
285
274
  refresh(opts: RefreshOptions): Promise<OAuthToken>;
286
- /**
287
- * Request a workspace-scoped access token without a user via the
288
- * `client_credentials` grant. Available only on private OAuth apps
289
- * that were registered with `allowsClientCredentials: true`. No
290
- * refresh token is issued; re-call this method whenever a new
291
- * access token is needed.
292
- */
293
- clientCredentials(opts?: ClientCredentialsOptions): Promise<OAuthToken>;
294
275
  /**
295
276
  * Revoke an access or refresh token (RFC 7009). The server always
296
277
  * returns 200, even for unknown tokens. Revoking a **refresh**
@@ -305,16 +286,12 @@ declare class MantyxOAuthClient {
305
286
  * source caches the access token in-memory and refreshes
306
287
  * proactively when the cached value is within `refreshSkewMs` of
307
288
  * `expiresAt`, or eagerly when `MantyxClient` reports a 401.
289
+ *
290
+ * Pass `initialToken` if the calling app already has a non-expired
291
+ * access token in hand (e.g. straight out of the sign-in flow) to
292
+ * avoid an extra round-trip on the first request.
308
293
  */
309
294
  refreshTokenSource(opts: RefreshTokenSourceOptions): TokenSource;
310
- /**
311
- * Build a long-lived {@link TokenSource} backed by the
312
- * `client_credentials` grant. On every refresh the source re-mints
313
- * a workspace-scoped access token by calling the token endpoint
314
- * with `grant_type=client_credentials`. Available only on private
315
- * apps with `allowsClientCredentials: true`.
316
- */
317
- clientCredentialsTokenSource(opts?: ClientCredentialsTokenSourceOptions): TokenSource;
318
295
  /**
319
296
  * POST `application/x-www-form-urlencoded` to `/api/oauth/token` and
320
297
  * decode the {@link OAuthToken} response. Always injects `client_id`
@@ -323,22 +300,6 @@ declare class MantyxOAuthClient {
323
300
  private token;
324
301
  private formPost;
325
302
  }
326
- /**
327
- * Generate a high-entropy PKCE `code_verifier` (RFC 7636 §4.1). The
328
- * verifier is the raw secret you keep across the redirect; the
329
- * `code_challenge` you send on `/api/oauth/authorize` is derived from
330
- * it via {@link pkceChallenge}.
331
- *
332
- * Default length is 64 characters (≈ 384 bits of entropy after
333
- * base64url-encoding the 32 random bytes). Pass `length` to clamp to
334
- * the RFC's 43..128 inclusive range.
335
- */
336
- declare function generatePkceVerifier(length?: number): string;
337
- /**
338
- * Compute the PKCE `S256` `code_challenge` for a given verifier:
339
- * `base64url(sha256(verifier))` with no padding (RFC 7636 §4.2).
340
- */
341
- declare function pkceChallenge(verifier: string): string;
342
303
 
343
304
  /**
344
305
  * Public tool helpers for the MANTYX SDK.
@@ -1319,4 +1280,4 @@ interface LocalHandlers {
1319
1280
  */
1320
1281
  declare function parseRunOutput<T = unknown>(result: RunResult, validator?: (value: unknown) => T): T;
1321
1282
 
1322
- export { type RevokeOptions as $, type A2AToolRef as A, MantyxNetworkError as B, type CancelledEvent as C, DEFAULT_BASE_URL as D, type ErrorEvent as E, MantyxOAuthClient as F, type MantyxOAuthClientOptions as G, MantyxOAuthError as H, MantyxParseError as I, type MantyxPluginToolRef as J, MantyxRunError as K, type LocalA2ATool as L, MantyxClient as M, type MantyxRunErrorInit as N, MantyxScopeError as O, MantyxToolError as P, type MantyxToolRef as Q, type ReasoningLevel as R, type McpToolRef as S, type ToolRef as T, type ModelCatalog as U, type ModelInfo as V, type OAuthToken as W, type OutputSchema as X, type RefreshOptions as Y, type RefreshTokenSourceOptions as Z, type ResultEvent as _, AgentSession as a, type RunEvent as a0, type RunEventBase as a1, type RunResult as a2, type RunSpec as a3, type ServerToolResultEvent as a4, type SessionInfo as a5, type SessionSpec as a6, type ThinkingDeltaEvent as a7, type TokenRequestReason as a8, type TokenSource as a9, type ToolBudget as aa, type ToolBudgetExceededEvent as ab, type ToolBudgets as ac, type ZodLikeObject as ad, defineLocalA2A as ae, defineLocalMcp as af, defineLocalTool as ag, generatePkceVerifier as ah, isLocalA2ATool as ai, isLocalMcpServer as aj, isLocalTool as ak, mantyxA2A as al, mantyxMcp as am, mantyxPluginTool as an, mantyxTool as ao, parseRunOutput as ap, pkceChallenge as aq, type AgentSpecBase as b, type AssistantDeltaEvent as c, type AssistantMessageEvent as d, type ClientCredentialsOptions as e, type ClientCredentialsTokenSourceOptions as f, DEFAULT_OAUTH_BASE_URL as g, DEFAULT_REFRESH_SKEW_MS as h, type DefineLocalA2AOptions as i, type DefineLocalMcpOptions as j, type DefineLocalToolOptions as k, type ExchangeAuthorizationCodeOptions as l, type LocalHandlers as m, type LocalMcpHttpTransport as n, type LocalMcpServer as o, type LocalMcpStdioTransport as p, type LocalTool as q, type LocalToolCallEvent as r, type LocalToolResultInEvent as s, type LoopDetectedEvent as t, type LoopDetection as u, type MantyxA2AOptions as v, MantyxAuthError as w, type MantyxClientOptions as x, MantyxError as y, type MantyxMcpOptions as z };
1283
+ export { type RunResult as $, type A2AToolRef as A, MantyxOAuthError as B, type CancelledEvent as C, DEFAULT_BASE_URL as D, type ErrorEvent as E, MantyxParseError as F, type MantyxPluginToolRef as G, MantyxRunError as H, type MantyxRunErrorInit as I, MantyxScopeError as J, MantyxToolError as K, type LocalA2ATool as L, MantyxClient as M, type MantyxToolRef as N, type McpToolRef as O, type ModelCatalog as P, type ModelInfo as Q, type ReasoningLevel as R, type OAuthToken as S, type ToolRef as T, type OutputSchema as U, type RefreshOptions as V, type RefreshTokenSourceOptions as W, type ResultEvent as X, type RevokeOptions as Y, type RunEvent as Z, type RunEventBase as _, AgentSession as a, type RunSpec as a0, type ServerToolResultEvent as a1, type SessionInfo as a2, type SessionSpec as a3, type ThinkingDeltaEvent as a4, type TokenRequestReason as a5, type TokenSource as a6, type ToolBudget as a7, type ToolBudgetExceededEvent as a8, type ToolBudgets as a9, type ZodLikeObject as aa, defineLocalA2A as ab, defineLocalMcp as ac, defineLocalTool as ad, isLocalA2ATool as ae, isLocalMcpServer as af, isLocalTool as ag, mantyxA2A as ah, mantyxMcp as ai, mantyxPluginTool as aj, mantyxTool as ak, parseRunOutput as al, type AgentSpecBase as b, type AssistantDeltaEvent as c, type AssistantMessageEvent as d, DEFAULT_OAUTH_BASE_URL as e, DEFAULT_REFRESH_SKEW_MS as f, type DefineLocalA2AOptions as g, type DefineLocalMcpOptions as h, type DefineLocalToolOptions as i, type LocalHandlers as j, type LocalMcpHttpTransport as k, type LocalMcpServer as l, type LocalMcpStdioTransport as m, type LocalTool as n, type LocalToolCallEvent as o, type LocalToolResultInEvent as p, type LoopDetectedEvent as q, type LoopDetection as r, type MantyxA2AOptions as s, MantyxAuthError as t, type MantyxClientOptions as u, MantyxError as v, type MantyxMcpOptions as w, MantyxNetworkError as x, MantyxOAuthClient as y, type MantyxOAuthClientOptions as z };
@@ -113,26 +113,28 @@ declare class MantyxParseError extends MantyxError {
113
113
  }
114
114
 
115
115
  /**
116
- * MANTYX OAuth 2.0 client: authorization-code exchange, refresh-token
117
- * minting, client-credentials grant, and token revocation, plus typed
118
- * {@link TokenSource}s that {@link MantyxClient} can consume to refresh
119
- * access tokens transparently before they expire (and again on 401).
116
+ * MANTYX OAuth 2.0 refresh client: trade a stored refresh token for
117
+ * short-lived access tokens, revoke tokens at sign-out, and expose
118
+ * a {@link TokenSource} the {@link MantyxClient} HTTP layer calls
119
+ * before every request (and again on 401).
120
120
  *
121
- * The wire contract this implements is `docs/oauth.md` in the SDK monorepo:
121
+ * The library is intentionally **refresh-only**. It assumes the caller
122
+ * already obtained the refresh token through their own sign-in flow
123
+ * (Authorization Code + PKCE in a browser, native redirect, server-
124
+ * side exchange — whatever fits the host application). The SDK does
125
+ * not drive consent, does not initiate auth-code exchanges, and does
126
+ * not bundle PKCE helpers.
122
127
  *
123
- * - Token endpoint: `POST <baseUrl>/api/oauth/token`, form-encoded.
128
+ * Wire contract (`docs/oauth.md`):
129
+ *
130
+ * - Token endpoint: `POST <baseUrl>/api/oauth/token`, form-encoded,
131
+ * `grant_type=refresh_token`. Echoes back the same `refresh_token`
132
+ * the client sent (refresh tokens are persistent and non-rotating).
124
133
  * - Revoke endpoint: `POST <baseUrl>/api/oauth/revoke`, form-encoded.
125
134
  * - Access tokens (`mantyx_at_…`) live 1 hour (`expires_in: 3600`).
126
- * - Refresh tokens (`mantyx_rt_…`) are **persistent and non-rotating**:
127
- * `grant_type=refresh_token` echoes back the same value the client
128
- * sent. The caller persists the refresh token once at first sign-in
129
- * (encrypted at rest) and the SDK re-mints access tokens from it on
130
- * demand.
131
- *
132
- * See also `docs/oauth.md` for the authorization-code + PKCE consent
133
- * flow (which the SDK does **not** drive — the calling app owns the
134
- * redirect dance; once it has the auth code, `exchangeAuthorizationCode`
135
- * swaps it for the initial `{access_token, refresh_token}` pair).
135
+ * - Refresh tokens (`mantyx_rt_…`) are long-lived; the caller persists
136
+ * them once at first sign-in (encrypted at rest) and the SDK re-mints
137
+ * access tokens from the same value on demand.
136
138
  */
137
139
 
138
140
  declare const DEFAULT_OAUTH_BASE_URL = "https://app.mantyx.io";
@@ -157,12 +159,12 @@ declare class MantyxOAuthError extends MantyxError {
157
159
  }
158
160
  /**
159
161
  * Decoded `POST /api/oauth/token` response, augmented with an absolute
160
- * `expiresAt` timestamp the SDK can use to decide when to refresh.
162
+ * `expiresAt` timestamp the SDK uses to decide when to refresh.
161
163
  *
162
- * `refreshToken` is present on the initial `authorization_code` exchange
163
- * and on subsequent `refresh_token` calls (where it is identical to the
164
- * value the client just sent refresh tokens never rotate). The
165
- * `client_credentials` grant never returns one.
164
+ * On the refresh grant the response's `refreshToken` is identical to
165
+ * the value the client just sent (refresh tokens never rotate). The
166
+ * field is surfaced for symmetry with whatever the calling app's
167
+ * sign-in flow already does.
166
168
  */
167
169
  interface OAuthToken {
168
170
  readonly accessToken: string;
@@ -209,11 +211,6 @@ interface MantyxOAuthClientOptions {
209
211
  /** Default per-request timeout in milliseconds. Default: 30s. */
210
212
  timeoutMs?: number;
211
213
  }
212
- interface ExchangeAuthorizationCodeOptions {
213
- code: string;
214
- redirectUri: string;
215
- codeVerifier: string;
216
- }
217
214
  interface RefreshOptions {
218
215
  refreshToken: string;
219
216
  /**
@@ -224,9 +221,6 @@ interface RefreshOptions {
224
221
  */
225
222
  scope?: string | readonly string[];
226
223
  }
227
- interface ClientCredentialsOptions {
228
- scope?: string | readonly string[];
229
- }
230
224
  interface RevokeOptions {
231
225
  token: string;
232
226
  }
@@ -241,21 +235,24 @@ interface RefreshTokenSourceOptions {
241
235
  refreshSkewMs?: number;
242
236
  /**
243
237
  * Optional initial access token + expiry to seed the source's cache
244
- * with (e.g. the token already in hand from the authorization-code
245
- * exchange). When omitted, the source mints one on the first call.
238
+ * with (e.g. the token already in hand from the host application's
239
+ * sign-in flow). When omitted, the source mints one on the first
240
+ * call.
246
241
  */
247
242
  initialToken?: OAuthToken;
248
243
  }
249
- interface ClientCredentialsTokenSourceOptions {
250
- scope?: string | readonly string[];
251
- refreshSkewMs?: number;
252
- }
253
244
  /**
254
- * Wraps the MANTYX OAuth 2.0 authorization-server endpoints. App-scoped
255
- * (one per `{clientId, clientSecret}` pair); construct independently of
256
- * {@link MantyxClient}, then either call its grant helpers directly or
257
- * hand a `TokenSource` it produces to `MantyxClient` for fully
258
- * transparent refresh.
245
+ * Refresh-only wrapper around the MANTYX OAuth 2.0 authorization-server
246
+ * endpoints. App-scoped (one per `{clientId, clientSecret}` pair);
247
+ * construct independently of {@link MantyxClient}, then either call
248
+ * {@link refresh} / {@link revoke} directly or hand a `TokenSource`
249
+ * produced by {@link refreshTokenSource} to `MantyxClient` for fully
250
+ * transparent refresh on every request.
251
+ *
252
+ * The client deliberately does **not** drive the authorization-code
253
+ * exchange or any other "initiate sign-in" grant. The caller is
254
+ * expected to obtain the refresh token through their own consent flow
255
+ * and persist it before constructing this client.
259
256
  */
260
257
  declare class MantyxOAuthClient {
261
258
  readonly clientId: string;
@@ -264,33 +261,17 @@ declare class MantyxOAuthClient {
264
261
  private readonly fetchImpl;
265
262
  private readonly timeoutMs;
266
263
  constructor(opts: MantyxOAuthClientOptions);
267
- /**
268
- * Swap an authorization-code + PKCE verifier for the initial
269
- * `{access_token, refresh_token}` pair. Call this exactly once per
270
- * sign-in after the browser/native redirect lands back on your
271
- * `redirectUri` with a `code` parameter. Persist the returned
272
- * `refreshToken` against the user record — it is long-lived and
273
- * non-rotating per `docs/oauth.md` §"Token lifetimes & lifecycle".
274
- */
275
- exchangeAuthorizationCode(opts: ExchangeAuthorizationCodeOptions): Promise<OAuthToken>;
276
264
  /**
277
265
  * Mint a fresh access token from a stored refresh token. The
278
- * returned `refreshToken` is identical to the input — the field is
279
- * surfaced for symmetry with {@link exchangeAuthorizationCode} only.
266
+ * returned `refreshToken` is identical to the input — refresh
267
+ * tokens are persistent and non-rotating, so the field is
268
+ * surfaced only for symmetry with the response shape.
280
269
  *
281
270
  * On `400 invalid_grant` the refresh token has been revoked (or its
282
271
  * grant / app was deleted); the SDK surfaces a
283
272
  * {@link MantyxOAuthError} and callers must drive a fresh sign-in.
284
273
  */
285
274
  refresh(opts: RefreshOptions): Promise<OAuthToken>;
286
- /**
287
- * Request a workspace-scoped access token without a user via the
288
- * `client_credentials` grant. Available only on private OAuth apps
289
- * that were registered with `allowsClientCredentials: true`. No
290
- * refresh token is issued; re-call this method whenever a new
291
- * access token is needed.
292
- */
293
- clientCredentials(opts?: ClientCredentialsOptions): Promise<OAuthToken>;
294
275
  /**
295
276
  * Revoke an access or refresh token (RFC 7009). The server always
296
277
  * returns 200, even for unknown tokens. Revoking a **refresh**
@@ -305,16 +286,12 @@ declare class MantyxOAuthClient {
305
286
  * source caches the access token in-memory and refreshes
306
287
  * proactively when the cached value is within `refreshSkewMs` of
307
288
  * `expiresAt`, or eagerly when `MantyxClient` reports a 401.
289
+ *
290
+ * Pass `initialToken` if the calling app already has a non-expired
291
+ * access token in hand (e.g. straight out of the sign-in flow) to
292
+ * avoid an extra round-trip on the first request.
308
293
  */
309
294
  refreshTokenSource(opts: RefreshTokenSourceOptions): TokenSource;
310
- /**
311
- * Build a long-lived {@link TokenSource} backed by the
312
- * `client_credentials` grant. On every refresh the source re-mints
313
- * a workspace-scoped access token by calling the token endpoint
314
- * with `grant_type=client_credentials`. Available only on private
315
- * apps with `allowsClientCredentials: true`.
316
- */
317
- clientCredentialsTokenSource(opts?: ClientCredentialsTokenSourceOptions): TokenSource;
318
295
  /**
319
296
  * POST `application/x-www-form-urlencoded` to `/api/oauth/token` and
320
297
  * decode the {@link OAuthToken} response. Always injects `client_id`
@@ -323,22 +300,6 @@ declare class MantyxOAuthClient {
323
300
  private token;
324
301
  private formPost;
325
302
  }
326
- /**
327
- * Generate a high-entropy PKCE `code_verifier` (RFC 7636 §4.1). The
328
- * verifier is the raw secret you keep across the redirect; the
329
- * `code_challenge` you send on `/api/oauth/authorize` is derived from
330
- * it via {@link pkceChallenge}.
331
- *
332
- * Default length is 64 characters (≈ 384 bits of entropy after
333
- * base64url-encoding the 32 random bytes). Pass `length` to clamp to
334
- * the RFC's 43..128 inclusive range.
335
- */
336
- declare function generatePkceVerifier(length?: number): string;
337
- /**
338
- * Compute the PKCE `S256` `code_challenge` for a given verifier:
339
- * `base64url(sha256(verifier))` with no padding (RFC 7636 §4.2).
340
- */
341
- declare function pkceChallenge(verifier: string): string;
342
303
 
343
304
  /**
344
305
  * Public tool helpers for the MANTYX SDK.
@@ -1319,4 +1280,4 @@ interface LocalHandlers {
1319
1280
  */
1320
1281
  declare function parseRunOutput<T = unknown>(result: RunResult, validator?: (value: unknown) => T): T;
1321
1282
 
1322
- export { type RevokeOptions as $, type A2AToolRef as A, MantyxNetworkError as B, type CancelledEvent as C, DEFAULT_BASE_URL as D, type ErrorEvent as E, MantyxOAuthClient as F, type MantyxOAuthClientOptions as G, MantyxOAuthError as H, MantyxParseError as I, type MantyxPluginToolRef as J, MantyxRunError as K, type LocalA2ATool as L, MantyxClient as M, type MantyxRunErrorInit as N, MantyxScopeError as O, MantyxToolError as P, type MantyxToolRef as Q, type ReasoningLevel as R, type McpToolRef as S, type ToolRef as T, type ModelCatalog as U, type ModelInfo as V, type OAuthToken as W, type OutputSchema as X, type RefreshOptions as Y, type RefreshTokenSourceOptions as Z, type ResultEvent as _, AgentSession as a, type RunEvent as a0, type RunEventBase as a1, type RunResult as a2, type RunSpec as a3, type ServerToolResultEvent as a4, type SessionInfo as a5, type SessionSpec as a6, type ThinkingDeltaEvent as a7, type TokenRequestReason as a8, type TokenSource as a9, type ToolBudget as aa, type ToolBudgetExceededEvent as ab, type ToolBudgets as ac, type ZodLikeObject as ad, defineLocalA2A as ae, defineLocalMcp as af, defineLocalTool as ag, generatePkceVerifier as ah, isLocalA2ATool as ai, isLocalMcpServer as aj, isLocalTool as ak, mantyxA2A as al, mantyxMcp as am, mantyxPluginTool as an, mantyxTool as ao, parseRunOutput as ap, pkceChallenge as aq, type AgentSpecBase as b, type AssistantDeltaEvent as c, type AssistantMessageEvent as d, type ClientCredentialsOptions as e, type ClientCredentialsTokenSourceOptions as f, DEFAULT_OAUTH_BASE_URL as g, DEFAULT_REFRESH_SKEW_MS as h, type DefineLocalA2AOptions as i, type DefineLocalMcpOptions as j, type DefineLocalToolOptions as k, type ExchangeAuthorizationCodeOptions as l, type LocalHandlers as m, type LocalMcpHttpTransport as n, type LocalMcpServer as o, type LocalMcpStdioTransport as p, type LocalTool as q, type LocalToolCallEvent as r, type LocalToolResultInEvent as s, type LoopDetectedEvent as t, type LoopDetection as u, type MantyxA2AOptions as v, MantyxAuthError as w, type MantyxClientOptions as x, MantyxError as y, type MantyxMcpOptions as z };
1283
+ export { type RunResult as $, type A2AToolRef as A, MantyxOAuthError as B, type CancelledEvent as C, DEFAULT_BASE_URL as D, type ErrorEvent as E, MantyxParseError as F, type MantyxPluginToolRef as G, MantyxRunError as H, type MantyxRunErrorInit as I, MantyxScopeError as J, MantyxToolError as K, type LocalA2ATool as L, MantyxClient as M, type MantyxToolRef as N, type McpToolRef as O, type ModelCatalog as P, type ModelInfo as Q, type ReasoningLevel as R, type OAuthToken as S, type ToolRef as T, type OutputSchema as U, type RefreshOptions as V, type RefreshTokenSourceOptions as W, type ResultEvent as X, type RevokeOptions as Y, type RunEvent as Z, type RunEventBase as _, AgentSession as a, type RunSpec as a0, type ServerToolResultEvent as a1, type SessionInfo as a2, type SessionSpec as a3, type ThinkingDeltaEvent as a4, type TokenRequestReason as a5, type TokenSource as a6, type ToolBudget as a7, type ToolBudgetExceededEvent as a8, type ToolBudgets as a9, type ZodLikeObject as aa, defineLocalA2A as ab, defineLocalMcp as ac, defineLocalTool as ad, isLocalA2ATool as ae, isLocalMcpServer as af, isLocalTool as ag, mantyxA2A as ah, mantyxMcp as ai, mantyxPluginTool as aj, mantyxTool as ak, parseRunOutput as al, type AgentSpecBase as b, type AssistantDeltaEvent as c, type AssistantMessageEvent as d, DEFAULT_OAUTH_BASE_URL as e, DEFAULT_REFRESH_SKEW_MS as f, type DefineLocalA2AOptions as g, type DefineLocalMcpOptions as h, type DefineLocalToolOptions as i, type LocalHandlers as j, type LocalMcpHttpTransport as k, type LocalMcpServer as l, type LocalMcpStdioTransport as m, type LocalTool as n, type LocalToolCallEvent as o, type LocalToolResultInEvent as p, type LoopDetectedEvent as q, type LoopDetection as r, type MantyxA2AOptions as s, MantyxAuthError as t, type MantyxClientOptions as u, MantyxError as v, type MantyxMcpOptions as w, MantyxNetworkError as x, MantyxOAuthClient as y, type MantyxOAuthClientOptions as z };