zidane 6.2.34 → 6.2.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.
Files changed (80) hide show
  1. package/dist/{acp-DxXRKWib.js → acp-DZNCQaTQ.js} +2 -2
  2. package/dist/{acp-DxXRKWib.js.map → acp-DZNCQaTQ.js.map} +1 -1
  3. package/dist/acp-cli.js +5 -5
  4. package/dist/acp.d.ts +1 -1
  5. package/dist/acp.js +1 -1
  6. package/dist/{agent-BMVp4byv.js → agent-CrPwqpLI.js} +37 -33
  7. package/dist/agent-CrPwqpLI.js.map +1 -0
  8. package/dist/agent.d.ts +1 -1
  9. package/dist/agent.js +1 -1
  10. package/dist/{anthropic-BI-Ukg2w.js → anthropic-asnZVFS_.js} +98 -27
  11. package/dist/anthropic-asnZVFS_.js.map +1 -0
  12. package/dist/{auth-Wb2AlCCp.js → auth-C5YTniaq.js} +4 -4
  13. package/dist/{auth-Wb2AlCCp.js.map → auth-C5YTniaq.js.map} +1 -1
  14. package/dist/chat/pure.d.ts +3 -3
  15. package/dist/chat.d.ts +4 -4
  16. package/dist/chat.js +3 -3
  17. package/dist/contexts/daytona.d.ts +1 -1
  18. package/dist/contexts/e2b.d.ts +1 -1
  19. package/dist/eval.d.ts +1 -1
  20. package/dist/extensions.d.ts +1 -1
  21. package/dist/extensions.js +1 -1
  22. package/dist/headless.d.ts +1 -1
  23. package/dist/headless.js +1 -1
  24. package/dist/{index-LLXx0VRf.d.ts → index-CohO0oaX.d.ts} +199 -2
  25. package/dist/index-CohO0oaX.d.ts.map +1 -0
  26. package/dist/index.d.ts +2 -2
  27. package/dist/index.js +5 -4
  28. package/dist/index.js.map +1 -1
  29. package/dist/mcp.d.ts +1 -1
  30. package/dist/{oauth-8LqbeI_Q.js → oauth-CBi9eymX.js} +83 -6
  31. package/dist/oauth-CBi9eymX.js.map +1 -0
  32. package/dist/output/stream-json.d.ts +1 -1
  33. package/dist/output/terminal.d.ts +1 -1
  34. package/dist/presets.d.ts +1 -1
  35. package/dist/presets.js +1 -1
  36. package/dist/providers/anthropic.d.ts +2 -2
  37. package/dist/providers/anthropic.js +2 -2
  38. package/dist/providers/arcee.d.ts +1 -1
  39. package/dist/providers/baseten.d.ts +1 -1
  40. package/dist/providers/cerebras.d.ts +1 -1
  41. package/dist/providers/local.d.ts +1 -1
  42. package/dist/providers/openai-compat.d.ts +1 -1
  43. package/dist/providers/openai.d.ts +1 -1
  44. package/dist/providers/openai.js +1 -1
  45. package/dist/providers/openrouter.d.ts +1 -1
  46. package/dist/providers/xai.d.ts +1 -1
  47. package/dist/providers/xai.js +1 -1
  48. package/dist/{providers-BWsicxOG.js → providers-DnHPW-dL.js} +3 -3
  49. package/dist/{providers-BWsicxOG.js.map → providers-DnHPW-dL.js.map} +1 -1
  50. package/dist/providers.d.ts +2 -2
  51. package/dist/providers.js +5 -4
  52. package/dist/restate.d.ts +1 -1
  53. package/dist/session/sqlite.d.ts +1 -1
  54. package/dist/session.d.ts +1 -1
  55. package/dist/skills.d.ts +1 -1
  56. package/dist/{tool-formatters-DtUL8zcF.d.ts → tool-formatters-bZYz74qU.d.ts} +2 -2
  57. package/dist/{tool-formatters-DtUL8zcF.d.ts.map → tool-formatters-bZYz74qU.d.ts.map} +1 -1
  58. package/dist/tools/fetch-url.d.ts +1 -1
  59. package/dist/tools/web-search.d.ts +1 -1
  60. package/dist/tools.d.ts +1 -1
  61. package/dist/tools.js +1 -1
  62. package/dist/{transcript-anchors-Cmn6Apac.d.ts → transcript-anchors-EBchHUMo.d.ts} +2 -2
  63. package/dist/{transcript-anchors-Cmn6Apac.d.ts.map → transcript-anchors-EBchHUMo.d.ts.map} +1 -1
  64. package/dist/{transcript-anchors-A9qh0UUo.js → transcript-anchors-ZZYwCTjo.js} +7 -3
  65. package/dist/{transcript-anchors-A9qh0UUo.js.map → transcript-anchors-ZZYwCTjo.js.map} +1 -1
  66. package/dist/tui.d.ts +3 -3
  67. package/dist/tui.d.ts.map +1 -1
  68. package/dist/tui.js +135 -7
  69. package/dist/tui.js.map +1 -1
  70. package/dist/{turn-operations-PPSEo4C3.d.ts → turn-operations-DygcPreU.d.ts} +3 -3
  71. package/dist/{turn-operations-PPSEo4C3.d.ts.map → turn-operations-DygcPreU.d.ts.map} +1 -1
  72. package/dist/types.d.ts +1 -1
  73. package/dist/{xai-CPZBj_WJ.js → xai-B2hIs5We.js} +2 -2
  74. package/dist/{xai-CPZBj_WJ.js.map → xai-B2hIs5We.js.map} +1 -1
  75. package/docs/EXTENSIONS.md +8 -2
  76. package/package.json +1 -1
  77. package/dist/agent-BMVp4byv.js.map +0 -1
  78. package/dist/anthropic-BI-Ukg2w.js.map +0 -1
  79. package/dist/index-LLXx0VRf.d.ts.map +0 -1
  80. package/dist/oauth-8LqbeI_Q.js.map +0 -1
@@ -46,6 +46,20 @@ const CREDENTIALS_FILE_MODE = 384;
46
46
  */
47
47
  const refreshLocks = /* @__PURE__ */ new Map();
48
48
  /**
49
+ * Register a custom OAuth flow with pi-ai's registry so lazy refresh through
50
+ * {@link resolveOAuthApiKey} can resolve `providerId`.
51
+ *
52
+ * Public because provider extensions need it: without registration,
53
+ * `getOAuthApiKey('<id>', …)` throws `Unknown OAuth provider` the first time a
54
+ * stored token expires. Idempotent per id (the registry is a keyed map), and
55
+ * lazily imported so importing this module never pulls pi-ai's OAuth surface
56
+ * into processes that don't authenticate.
57
+ */
58
+ async function registerCustomOAuthProvider(provider) {
59
+ const { registerOAuthProvider } = await import("@earendil-works/pi-ai/oauth");
60
+ registerOAuthProvider(provider);
61
+ }
62
+ /**
49
63
  * Pull a complete `{ access, refresh, expires }` triple out of provider params
50
64
  * when (and only when) all three OAuth fields are present and well-typed.
51
65
  * Returns `undefined` for the static-api-key path. Shared by the OAuth-capable
@@ -164,6 +178,51 @@ function releaseCredentialsLock(lockPath) {
164
178
  } catch {}
165
179
  }
166
180
  /**
181
+ * Cross-process lock parameters for the REFRESH critical section (read →
182
+ * check expiry → refresh → persist), held per provider around file-backed
183
+ * resolves in {@link resolveOAuthApiKey}.
184
+ *
185
+ * This is a different beast from the write lock above: the holder performs a
186
+ * network call, so it can legitimately hold the lock for seconds. Hence its
187
+ * own generous thresholds — and async waiting, because blocking the event
188
+ * loop for a peer's refresh round-trip is not acceptable. The stakes are
189
+ * higher too: providers with single-use rotating refresh tokens (Bolt) treat
190
+ * a replayed token as theft and revoke the WHOLE grant, so two processes
191
+ * refreshing the same provider concurrently don't just race a write — they
192
+ * self-revoke. A process that loses the race re-reads under the lock, finds
193
+ * the winner's fresh token, and skips its own refresh entirely.
194
+ *
195
+ * On timeout we proceed without the lock (degrades to the pre-lock racy
196
+ * behavior) rather than fail a resolve that would probably have succeeded.
197
+ */
198
+ const REFRESH_LOCK_STALE_MS = 6e4;
199
+ const REFRESH_LOCK_RETRY_MS = 50;
200
+ const REFRESH_LOCK_MAX_WAIT_MS = 3e4;
201
+ function refreshLockPath(providerId) {
202
+ return `${credentialsFilePath()}.refresh-${providerId.replace(/[^\w.-]/g, "_")}.lock`;
203
+ }
204
+ /** Async sibling of {@link acquireCredentialsLock} with refresh-scale thresholds. */
205
+ async function acquireRefreshLock(lockPath) {
206
+ const deadline = Date.now() + REFRESH_LOCK_MAX_WAIT_MS;
207
+ while (true) try {
208
+ writeFileSync(lockPath, String(process.pid), {
209
+ flag: "wx",
210
+ mode: CREDENTIALS_FILE_MODE
211
+ });
212
+ return true;
213
+ } catch (err) {
214
+ if (err.code !== "EEXIST") return false;
215
+ try {
216
+ if (Date.now() - statSync(lockPath).mtimeMs > REFRESH_LOCK_STALE_MS) {
217
+ unlinkSync(lockPath);
218
+ continue;
219
+ }
220
+ } catch {}
221
+ if (Date.now() >= deadline) return false;
222
+ await new Promise((resolve) => setTimeout(resolve, REFRESH_LOCK_RETRY_MS));
223
+ }
224
+ }
225
+ /**
167
226
  * Atomically write `.credentials.json` with mode 0o600.
168
227
  *
169
228
  * Writes to a sibling temp file first, then renames. `rename(2)` is atomic on
@@ -223,23 +282,41 @@ async function resolveOAuthApiKey(options, callbacks) {
223
282
  if (typeof options.params?.access === "string") return options.params.access;
224
283
  const readCredentials = options.readCredentials ?? readOAuthCredentials;
225
284
  const writeCredentials = options.writeCredentials ?? writeOAuthCredentials;
285
+ const usingDefaultStore = !options.readCredentials && !options.writeCredentials;
226
286
  const envValue = options.envKey ? process.env[options.envKey] : void 0;
227
287
  if (envValue) {
228
288
  if (!isOAuthAccessToken(envValue)) return envValue;
229
289
  if (!readCredentials()[options.providerId]) return envValue;
230
- return await withRefreshLock(`file:${options.providerId}`, async () => {
290
+ return await withRefreshLock(`file:${options.providerId}`, () => withCrossProcessRefreshLock(async () => {
231
291
  const allCredentials = readCredentials();
232
292
  const stored = allCredentials[options.providerId];
233
293
  if (!stored) return envValue;
234
294
  return await resolveCredentialSource("file", stored, allCredentials, writeCredentials);
235
- });
295
+ }));
236
296
  }
237
- return await withRefreshLock(`file:${options.providerId}`, async () => {
297
+ return await withRefreshLock(`file:${options.providerId}`, () => withCrossProcessRefreshLock(async () => {
238
298
  const allCredentials = readCredentials();
239
299
  const storedCredentials = allCredentials[options.providerId];
240
300
  if (!storedCredentials) throw new Error(options.missingError);
241
301
  return await resolveCredentialSource("file", storedCredentials, allCredentials, writeCredentials);
242
- });
302
+ }));
303
+ /**
304
+ * Hold the per-provider cross-process lockfile across the WHOLE file-backed
305
+ * critical section, not just the persist. Guarding only the write (as
306
+ * `writeOAuthCredentials` does) still lets two processes both spend a
307
+ * single-use rotating refresh token — which self-revokes providers with
308
+ * replay-detecting rotation. See the {@link REFRESH_LOCK_STALE_MS} note.
309
+ */
310
+ async function withCrossProcessRefreshLock(fn) {
311
+ if (!usingDefaultStore) return fn();
312
+ const lockPath = refreshLockPath(options.providerId);
313
+ const locked = await acquireRefreshLock(lockPath);
314
+ try {
315
+ return await fn();
316
+ } finally {
317
+ if (locked) releaseCredentialsLock(lockPath);
318
+ }
319
+ }
243
320
  async function resolveCredentialSource(source, current, allCredentials, persistCredentials) {
244
321
  let result;
245
322
  try {
@@ -287,6 +364,6 @@ async function withRefreshLock(key, fn) {
287
364
  return task;
288
365
  }
289
366
  //#endregion
290
- export { resolveOAuthApiKey as i, isOAuthAccessToken as n, readOAuthCredentials as r, extractRuntimeCredentials as t };
367
+ export { readOAuthCredentials as a, writeOAuthCredentials as c, isOAuthAccessToken as i, credentialsFromParams as n, registerCustomOAuthProvider as o, extractRuntimeCredentials as r, resolveOAuthApiKey as s, credentialsFilePath as t };
291
368
 
292
- //# sourceMappingURL=oauth-8LqbeI_Q.js.map
369
+ //# sourceMappingURL=oauth-CBi9eymX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-CBi9eymX.js","names":[],"sources":["../src/providers/oauth.ts"],"sourcesContent":["import type { OAuthCredentials } from '@earendil-works/pi-ai/oauth'\nimport type { StreamCallbacks } from '.'\nimport type { OAuthRefreshHookContext } from '../types'\nimport { Buffer } from 'node:buffer'\nimport { existsSync, readFileSync, statSync, unlinkSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { resolve } from 'node:path'\nimport { writeFileAtomic } from '../atomic-write'\nimport { errorMessage } from '../errors'\nimport { lazyAsync } from '../lazy'\n\ntype GetOAuthApiKey = typeof import('@earendil-works/pi-ai/oauth').getOAuthApiKey\n\nconst loadGetOAuthApiKey = lazyAsync(async () => (await import('@earendil-works/pi-ai/oauth')).getOAuthApiKey)\n\n/**\n * Resolve the creds-file path at call time rather than module-load time, so\n * env changes between import and first OAuth use (test suites, multi-project\n * CLIs) are honored.\n *\n * Order:\n * 1. `ZIDANE_CREDENTIALS_PATH` — explicit override. The TUI sets this at\n * launch to point at `<storageDir>/credentials.json` so the harness\n * providers find the same file the TUI manages.\n * 2. `~/.credentials.json` — home-anchored default.\n *\n * The historic `cwd/.credentials.json` fallback was deliberately dropped:\n * launching zidane inside an untrusted checkout would let that repo plant a\n * `.credentials.json` and become the credential source (and receive rotated\n * refresh tokens on the next refresh persist). Same trust model as the TUI's\n * legacy-file migration in `chat/credentials.ts`, which only honors the\n * home-anchored location. The only \"trusted\" cwd under that model is `$HOME`\n * itself — where the cwd-relative path resolves to `~/.credentials.json`\n * anyway, so anchoring at home preserves the legitimate legacy case.\n */\nexport function credentialsFilePath(): string {\n return process.env.ZIDANE_CREDENTIALS_PATH ?? resolve(homedir(), '.credentials.json')\n}\n\n/**\n * POSIX mode for credentials on disk. Read+write for the owner only — refresh\n * tokens and API keys leak if the file is world-readable on a shared box.\n * Ignored on Windows.\n */\nconst CREDENTIALS_FILE_MODE = 0o600\n\n/**\n * In-process mutex table keyed by provider id. Concurrent `resolveOAuthApiKey`\n * calls for the same provider (typical when a host fans out multiple streams\n * at once) coalesce onto a single refresh. Without this, N concurrent calls\n * each hit `getOAuthApiKey`, producing N writes to `.credentials.json` with\n * last-write-wins semantics — and, in worst-case interleaving, a corrupted\n * file.\n */\nconst refreshLocks = new Map<string, Promise<string>>()\n\n/**\n * Register a custom OAuth flow with pi-ai's registry so lazy refresh through\n * {@link resolveOAuthApiKey} can resolve `providerId`.\n *\n * Public because provider extensions need it: without registration,\n * `getOAuthApiKey('<id>', …)` throws `Unknown OAuth provider` the first time a\n * stored token expires. Idempotent per id (the registry is a keyed map), and\n * lazily imported so importing this module never pulls pi-ai's OAuth surface\n * into processes that don't authenticate.\n */\nexport async function registerCustomOAuthProvider(\n provider: import('@earendil-works/pi-ai/oauth').OAuthProviderInterface,\n): Promise<void> {\n const { registerOAuthProvider } = await import('@earendil-works/pi-ai/oauth')\n registerOAuthProvider(provider)\n}\n\nexport interface OAuthParams {\n apiKey?: string\n access?: string\n refresh?: string\n expires?: number\n}\n\n/**\n * Pull a complete `{ access, refresh, expires }` triple out of provider params\n * when (and only when) all three OAuth fields are present and well-typed.\n * Returns `undefined` for the static-api-key path. Shared by the OAuth-capable\n * providers so the runtime-credential guard can't drift between them.\n */\n/**\n * Whether a credential string is an OAuth *access token* rather than a real,\n * static API key. Anthropic OAuth tokens are prefixed `sk-ant-oat`; OpenAI\n * Codex OAuth access tokens are JWTs (`eyJ...`). Used to decide whether an\n * env-provided value can be refreshed (OAuth) or must be sent verbatim (API key).\n */\nexport function isOAuthAccessToken(value: string): boolean {\n return value.startsWith('sk-ant-oat') || isJwtLikeAccessToken(value)\n}\n\nfunction isJwtLikeAccessToken(value: string): boolean {\n const parts = value.split('.')\n if (parts.length !== 3 || !parts[0]?.startsWith('eyJ'))\n return false\n try {\n const header = JSON.parse(Buffer.from(parts[0], 'base64url').toString('utf8')) as unknown\n return Boolean(header && typeof header === 'object' && 'alg' in header)\n }\n catch {\n return false\n }\n}\n\nexport function extractRuntimeCredentials(\n params?: OAuthParams,\n): { access: string, refresh: string, expires: number } | undefined {\n if (\n typeof params?.access === 'string'\n && typeof params.refresh === 'string'\n && typeof params.expires === 'number'\n ) {\n return { access: params.access, refresh: params.refresh, expires: params.expires }\n }\n return undefined\n}\n\nexport interface ResolveOAuthApiKeyOptions<TParams extends OAuthParams = OAuthParams> {\n provider: string\n providerId: string\n params?: TParams\n envKey?: string\n extraCredentialKeys?: (keyof TParams & string)[]\n missingError: string\n refreshError: (reason: string) => string\n readCredentials?: () => Record<string, OAuthCredentials | undefined>\n writeCredentials?: (credentials: Record<string, OAuthCredentials | undefined>) => void\n getOAuthApiKey?: GetOAuthApiKey\n}\n\n/**\n * Read the shared credentials file.\n *\n * Returns `{}` when the file is missing OR when the file exists but is corrupted\n * / not valid JSON. Corrupt-file tolerance is important: the refresh-then-persist\n * path below writes atomically, but older builds wrote in place and could have\n * truncated the file on a crash. Treating corruption as \"no stored creds\" lets\n * users re-auth without manually deleting the file.\n *\n * Supports two on-disk shapes:\n * 1. **Legacy** (untagged): `{ \"anthropic\": { access, refresh, expires, ... } }`\n * — written by older `bun run auth`.\n * 2. **New** (kind-tagged): `{ \"anthropic\": { kind: 'oauth', access, refresh, expires, ... } }`\n * — written by the TUI. Entries with `kind: 'apikey'` are skipped — those\n * reach providers via env vars set at TUI launch (see `applyApiKeyEnv`).\n */\nexport function readOAuthCredentials(): Record<string, OAuthCredentials | undefined> {\n const path = credentialsFilePath()\n if (!existsSync(path))\n return {}\n\n try {\n const raw = readFileSync(path, 'utf-8')\n const parsed = JSON.parse(raw)\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))\n return {}\n const result: Record<string, OAuthCredentials | undefined> = {}\n for (const [key, value] of Object.entries(parsed)) {\n if (!value || typeof value !== 'object' || Array.isArray(value))\n continue\n const v = value as Record<string, unknown>\n // New schema: explicit `kind` tag.\n if (v.kind === 'apikey')\n continue\n // Both new (`kind: 'oauth'`) and legacy (untagged) entries have `access`;\n // the harmless `kind` field is allowed by `OAuthCredentials`'s\n // `[key: string]: unknown` index signature. Validate the required\n // fields explicitly so the assignment doesn't need a double-cast.\n if (\n typeof v.access === 'string'\n && typeof v.refresh === 'string'\n && typeof v.expires === 'number'\n ) {\n result[key] = { ...v, access: v.access, refresh: v.refresh, expires: v.expires }\n }\n }\n return result\n }\n catch {\n return {}\n }\n}\n\n/**\n * Cross-process lockfile parameters for the credentials read-merge-write.\n * A holder normally completes in well under a millisecond (read + JSON merge\n * + atomic write of a tiny file), so the stale threshold is generous and the\n * total wait short — on timeout we proceed without the lock rather than fail\n * the refresh (degrades to the historic last-write-wins behavior).\n */\nconst CREDENTIALS_LOCK_STALE_MS = 5000\nconst CREDENTIALS_LOCK_RETRY_MS = 20\nconst CREDENTIALS_LOCK_MAX_WAIT_MS = 2000\n\n/** Synchronous sleep without spinning — works on Bun and Node main threads. */\nfunction sleepSync(ms: number): void {\n Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms)\n}\n\n/**\n * Best-effort exclusive lock via `O_EXCL` create of `<file>.lock`. Returns\n * `true` when the lock was acquired (caller must release), `false` on\n * timeout (caller proceeds unlocked — see threshold rationale above). Locks\n * older than {@link CREDENTIALS_LOCK_STALE_MS} are treated as leftovers from\n * a crashed process and broken.\n */\nfunction acquireCredentialsLock(lockPath: string): boolean {\n const deadline = Date.now() + CREDENTIALS_LOCK_MAX_WAIT_MS\n while (true) {\n try {\n writeFileSync(lockPath, String(process.pid), { flag: 'wx', mode: CREDENTIALS_FILE_MODE })\n return true\n }\n catch (err) {\n // Only EEXIST means \"lock held\" — anything else (EPERM, ENOENT for a\n // missing parent dir, read-only fs) won't resolve by waiting, so bail\n // immediately and let the subsequent write surface the real error.\n if ((err as NodeJS.ErrnoException).code !== 'EEXIST')\n return false\n try {\n const age = Date.now() - statSync(lockPath).mtimeMs\n if (age > CREDENTIALS_LOCK_STALE_MS) {\n unlinkSync(lockPath)\n continue\n }\n }\n catch { /* lock vanished between create-fail and stat — retry */ }\n if (Date.now() >= deadline)\n return false\n sleepSync(CREDENTIALS_LOCK_RETRY_MS)\n }\n }\n}\n\nfunction releaseCredentialsLock(lockPath: string): void {\n try {\n unlinkSync(lockPath)\n }\n catch { /* already gone */ }\n}\n\n/**\n * Cross-process lock parameters for the REFRESH critical section (read →\n * check expiry → refresh → persist), held per provider around file-backed\n * resolves in {@link resolveOAuthApiKey}.\n *\n * This is a different beast from the write lock above: the holder performs a\n * network call, so it can legitimately hold the lock for seconds. Hence its\n * own generous thresholds — and async waiting, because blocking the event\n * loop for a peer's refresh round-trip is not acceptable. The stakes are\n * higher too: providers with single-use rotating refresh tokens (Bolt) treat\n * a replayed token as theft and revoke the WHOLE grant, so two processes\n * refreshing the same provider concurrently don't just race a write — they\n * self-revoke. A process that loses the race re-reads under the lock, finds\n * the winner's fresh token, and skips its own refresh entirely.\n *\n * On timeout we proceed without the lock (degrades to the pre-lock racy\n * behavior) rather than fail a resolve that would probably have succeeded.\n */\nconst REFRESH_LOCK_STALE_MS = 60_000\nconst REFRESH_LOCK_RETRY_MS = 50\nconst REFRESH_LOCK_MAX_WAIT_MS = 30_000\n\nfunction refreshLockPath(providerId: string): string {\n return `${credentialsFilePath()}.refresh-${providerId.replace(/[^\\w.-]/g, '_')}.lock`\n}\n\n/** Async sibling of {@link acquireCredentialsLock} with refresh-scale thresholds. */\nasync function acquireRefreshLock(lockPath: string): Promise<boolean> {\n const deadline = Date.now() + REFRESH_LOCK_MAX_WAIT_MS\n while (true) {\n try {\n writeFileSync(lockPath, String(process.pid), { flag: 'wx', mode: CREDENTIALS_FILE_MODE })\n return true\n }\n catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'EEXIST')\n return false\n try {\n const age = Date.now() - statSync(lockPath).mtimeMs\n if (age > REFRESH_LOCK_STALE_MS) {\n unlinkSync(lockPath)\n continue\n }\n }\n catch { /* lock vanished between create-fail and stat — retry */ }\n if (Date.now() >= deadline)\n return false\n await new Promise(resolve => setTimeout(resolve, REFRESH_LOCK_RETRY_MS))\n }\n }\n}\n\n/**\n * Atomically write `.credentials.json` with mode 0o600.\n *\n * Writes to a sibling temp file first, then renames. `rename(2)` is atomic on\n * the same filesystem, so readers either see the old file or the new one —\n * never a half-written one. This matters when a host has multiple processes\n * pointed at the same creds file.\n *\n * Merges the incoming OAuth entries on top of the raw file contents so that\n * entries this layer doesn't manage (e.g. `kind: 'apikey'` from the TUI\n * wizard) survive an OAuth refresh cycle. Without this merge,\n * `readOAuthCredentials` filters those entries out, and a naive overwrite\n * would delete them.\n *\n * The read-merge-write runs under a best-effort cross-process lockfile\n * (`<file>.lock`) so two processes refreshing different providers at the\n * same moment can't drop each other's rotated refresh tokens. On lock\n * timeout the write proceeds unlocked (last-write-wins, the pre-lock\n * behavior) rather than failing the refresh.\n */\nexport function writeOAuthCredentials(credentials: Record<string, OAuthCredentials | undefined>) {\n const path = credentialsFilePath()\n const lockPath = `${path}.lock`\n const locked = acquireCredentialsLock(lockPath)\n\n try {\n let existing: Record<string, unknown> = {}\n try {\n if (existsSync(path)) {\n const raw = readFileSync(path, 'utf-8')\n const parsed = JSON.parse(raw)\n if (parsed && typeof parsed === 'object' && !Array.isArray(parsed))\n existing = parsed as Record<string, unknown>\n }\n }\n catch { /* corrupt file — start fresh */ }\n\n const merged = { ...existing, ...credentials }\n // Remove keys explicitly set to undefined (provider was deleted).\n for (const [key, value] of Object.entries(merged)) {\n if (value === undefined)\n delete merged[key]\n }\n\n writeFileAtomic(path, JSON.stringify(merged, null, 2), { mode: CREDENTIALS_FILE_MODE })\n }\n finally {\n if (locked)\n releaseCredentialsLock(lockPath)\n }\n}\n\nexport function credentialsFromParams<TParams extends OAuthParams>(params?: TParams, extraKeys: (keyof TParams & string)[] = []): OAuthCredentials | undefined {\n if (typeof params?.access !== 'string' || typeof params.refresh !== 'string' || typeof params.expires !== 'number')\n return undefined\n\n const extras = Object.fromEntries(\n extraKeys\n .map(key => [key, params[key]])\n .filter(([, value]) => value !== undefined),\n )\n\n return {\n access: params.access,\n refresh: params.refresh,\n expires: params.expires,\n ...extras,\n }\n}\n\nexport async function resolveOAuthApiKey<TParams extends OAuthParams>(\n options: ResolveOAuthApiKeyOptions<TParams>,\n callbacks?: Pick<StreamCallbacks, 'onOAuthRefresh'>,\n): Promise<string> {\n if (typeof options.params?.apiKey === 'string')\n return options.params.apiKey\n\n const paramsCredentials = credentialsFromParams(options.params, options.extraCredentialKeys)\n if (paramsCredentials) {\n return await withRefreshLock(\n `params:${options.providerId}`,\n () => resolveCredentialSource('params', paramsCredentials),\n )\n }\n\n if (typeof options.params?.access === 'string')\n return options.params.access\n\n const readCredentials = options.readCredentials ?? readOAuthCredentials\n const writeCredentials = options.writeCredentials ?? writeOAuthCredentials\n // The cross-process refresh lock only means something when we're actually\n // backed by the shared credentials file; injected stores (tests, embedders)\n // have no cross-process story to protect and must not touch real lock files.\n const usingDefaultStore = !options.readCredentials && !options.writeCredentials\n\n // Env key handling. A real API key (e.g. `sk-ant-api…`) is used as-is. But an\n // OAuth *access token* (`sk-ant-oat…`) pasted into the API-key env var can't\n // be refreshed and will 401 once expired — so if refreshable OAuth creds for\n // this provider exist on disk, prefer those (they self-heal via refresh).\n const envValue = options.envKey ? process.env[options.envKey] : undefined\n if (envValue) {\n if (!isOAuthAccessToken(envValue))\n return envValue\n if (!readCredentials()[options.providerId])\n return envValue // no refreshable creds — fall back to the raw token\n return await withRefreshLock(`file:${options.providerId}`, () => withCrossProcessRefreshLock(async () => {\n // Re-read under the locks — a concurrent resolve (in this process or\n // another) may have rotated the refresh token between the pre-check\n // above and lock acquisition, and refreshing with the stale token would\n // invalidate the new one.\n const allCredentials = readCredentials()\n const stored = allCredentials[options.providerId]\n if (!stored)\n return envValue\n return await resolveCredentialSource('file', stored, allCredentials, writeCredentials)\n }))\n }\n\n return await withRefreshLock(`file:${options.providerId}`, () => withCrossProcessRefreshLock(async () => {\n // Read under the locks so we're always operating on the latest file state\n // and never interleave read/refresh/write against another concurrent\n // resolve — in-process (withRefreshLock) or cross-process (the lockfile).\n const allCredentials = readCredentials()\n const storedCredentials = allCredentials[options.providerId]\n if (!storedCredentials)\n throw new Error(options.missingError)\n\n return await resolveCredentialSource('file', storedCredentials, allCredentials, writeCredentials)\n }))\n\n /**\n * Hold the per-provider cross-process lockfile across the WHOLE file-backed\n * critical section, not just the persist. Guarding only the write (as\n * `writeOAuthCredentials` does) still lets two processes both spend a\n * single-use rotating refresh token — which self-revokes providers with\n * replay-detecting rotation. See the {@link REFRESH_LOCK_STALE_MS} note.\n */\n async function withCrossProcessRefreshLock(fn: () => Promise<string>): Promise<string> {\n if (!usingDefaultStore)\n return fn()\n const lockPath = refreshLockPath(options.providerId)\n const locked = await acquireRefreshLock(lockPath)\n try {\n return await fn()\n }\n finally {\n if (locked)\n releaseCredentialsLock(lockPath)\n }\n }\n\n async function resolveCredentialSource(\n source: OAuthRefreshHookContext['source'],\n current: OAuthCredentials,\n allCredentials?: Record<string, OAuthCredentials | undefined>,\n persistCredentials?: (credentials: Record<string, OAuthCredentials | undefined>) => void,\n ): Promise<string> {\n // Only the refresh call itself maps to `refreshError` — a throwing\n // persist or onOAuthRefresh hook after a SUCCESSFUL refresh must not be\n // misreported as a refresh failure, so those run outside the try.\n let result: Awaited<ReturnType<GetOAuthApiKey>>\n try {\n const refreshOAuthApiKey = options.getOAuthApiKey ?? await loadGetOAuthApiKey()\n result = await refreshOAuthApiKey(options.providerId, { [options.providerId]: current } as Record<string, OAuthCredentials>)\n }\n catch (err) {\n throw new Error(options.refreshError(errorMessage(err)))\n }\n if (!result)\n throw new Error(options.refreshError(options.missingError))\n\n if (result.newCredentials !== current) {\n // pi-ai's refresh returns only `{ access, refresh, expires }`. Merge it\n // onto the current credential so the persisted entry keeps its on-disk\n // `kind: 'oauth'` tag and any provider extras (e.g. openai-codex\n // `accountId`). A bare overwrite strips `kind`, and the TUI's auth-state\n // detection keys on `kind === 'oauth'` — so without this the provider\n // reads as signed out after every token refresh, forcing a daily re-login.\n const refreshed = { ...current, ...result.newCredentials }\n if (source === 'file' && allCredentials && persistCredentials) {\n allCredentials[options.providerId] = refreshed\n persistCredentials(allCredentials)\n }\n\n await callbacks?.onOAuthRefresh?.({\n provider: options.provider,\n providerId: options.providerId,\n source,\n previousCredentials: { ...current },\n credentials: { ...refreshed },\n })\n }\n\n return result.apiKey\n }\n}\n\n/**\n * Coalesce concurrent refresh calls onto a single in-flight promise per key.\n * The key combines the source (`params` vs `file`) and provider id, so a\n * per-agent param-only refresh does not starve a separate file-backed one.\n */\nasync function withRefreshLock(key: string, fn: () => Promise<string>): Promise<string> {\n const existing = refreshLocks.get(key)\n if (existing)\n return existing\n\n const task = (async () => {\n try {\n return await fn()\n }\n finally {\n refreshLocks.delete(key)\n }\n })()\n refreshLocks.set(key, task)\n return task\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { Bn as FormattedHeadlessTurnEvent, Gn as HeadlessResult, Hn as HeadlessEvent, Wi as Agent, Wn as HeadlessOutputFormat, zn as FormattedHeadlessResult } from "../index-LLXx0VRf.js";
1
+ import { Bn as FormattedHeadlessTurnEvent, Gn as HeadlessResult, Hn as HeadlessEvent, Wi as Agent, Wn as HeadlessOutputFormat, zn as FormattedHeadlessResult } from "../index-CohO0oaX.js";
2
2
 
3
3
  //#region src/output/stream-json.d.ts
4
4
  type StreamJsonOutputFormat = HeadlessOutputFormat;
@@ -1,4 +1,4 @@
1
- import { Ki as AgentHooks, Wi as Agent, t as Preset } from "../index-LLXx0VRf.js";
1
+ import { Ki as AgentHooks, Wi as Agent, t as Preset } from "../index-CohO0oaX.js";
2
2
 
3
3
  //#region src/output/terminal.d.ts
4
4
  interface TerminalOutputOptions {
package/dist/presets.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { Gi as AgentHookMap, a as basicTools, i as _default, n as composePresets, r as definePreset, t as Preset } from "./index-LLXx0VRf.js";
1
+ import { Gi as AgentHookMap, a as basicTools, i as _default, n as composePresets, r as definePreset, t as Preset } from "./index-CohO0oaX.js";
2
2
  export { type AgentHookMap, Preset, _default as basic, basicTools, composePresets, definePreset };
package/dist/presets.js CHANGED
@@ -1,2 +1,2 @@
1
- import { ct as definePreset, lt as basicTools, st as composePresets, ut as basic_default } from "./agent-BMVp4byv.js";
1
+ import { ct as basicTools, lt as basic_default, ot as composePresets, st as definePreset } from "./agent-CrPwqpLI.js";
2
2
  export { basic_default as basic, basicTools, composePresets, definePreset };
@@ -1,2 +1,2 @@
1
- import { Ah as defaultAnthropicMaxTokens, Dh as anthropic, Eh as AnthropicThinkingPlan, Mh as resolveAnthropicBetas, Nh as resolveAnthropicMaxOutput, Oh as applyAnthropicCacheBreakpoints, Th as AnthropicParams, jh as planAnthropicThinking, kh as classifyAnthropicError, wh as AnthropicContextManagement } from "../index-LLXx0VRf.js";
2
- export { AnthropicContextManagement, AnthropicParams, AnthropicThinkingPlan, anthropic, applyAnthropicCacheBreakpoints, classifyAnthropicError, defaultAnthropicMaxTokens, planAnthropicThinking, resolveAnthropicBetas, resolveAnthropicMaxOutput };
1
+ import { Ah as classifyAnthropicError, Dh as anthropic, Eh as AnthropicThinkingPlan, Fh as resolveAnthropicBetas, Ih as resolveAnthropicMaxOutput, Mh as defaultAnthropicMaxTokens, Nh as planAnthropicThinking, Oh as applyAnthropicCacheBreakpoints, Ph as resolveAnthropicAuthShape, Th as AnthropicParams, jh as credentialIdentity, kh as buildAnthropicClientOptions, wh as AnthropicContextManagement } from "../index-CohO0oaX.js";
2
+ export { AnthropicContextManagement, AnthropicParams, AnthropicThinkingPlan, anthropic, applyAnthropicCacheBreakpoints, buildAnthropicClientOptions, classifyAnthropicError, credentialIdentity, defaultAnthropicMaxTokens, planAnthropicThinking, resolveAnthropicAuthShape, resolveAnthropicBetas, resolveAnthropicMaxOutput };
@@ -1,2 +1,2 @@
1
- import { a as planAnthropicThinking, i as defaultAnthropicMaxTokens, n as applyAnthropicCacheBreakpoints, o as resolveAnthropicBetas, r as classifyAnthropicError, s as resolveAnthropicMaxOutput, t as anthropic } from "../anthropic-BI-Ukg2w.js";
2
- export { anthropic, applyAnthropicCacheBreakpoints, classifyAnthropicError, defaultAnthropicMaxTokens, planAnthropicThinking, resolveAnthropicBetas, resolveAnthropicMaxOutput };
1
+ import { a as credentialIdentity, c as resolveAnthropicAuthShape, i as classifyAnthropicError, l as resolveAnthropicBetas, n as applyAnthropicCacheBreakpoints, o as defaultAnthropicMaxTokens, r as buildAnthropicClientOptions, s as planAnthropicThinking, t as anthropic, u as resolveAnthropicMaxOutput } from "../anthropic-asnZVFS_.js";
2
+ export { anthropic, applyAnthropicCacheBreakpoints, buildAnthropicClientOptions, classifyAnthropicError, credentialIdentity, defaultAnthropicMaxTokens, planAnthropicThinking, resolveAnthropicAuthShape, resolveAnthropicBetas, resolveAnthropicMaxOutput };
@@ -1,2 +1,2 @@
1
- import { Ch as arcee, Sh as ArceeParams } from "../index-LLXx0VRf.js";
1
+ import { Ch as arcee, Sh as ArceeParams } from "../index-CohO0oaX.js";
2
2
  export { ArceeParams, arcee };
@@ -1,2 +1,2 @@
1
- import { bh as baseten, xh as planBasetenReasoning, yh as BasetenParams } from "../index-LLXx0VRf.js";
1
+ import { bh as baseten, xh as planBasetenReasoning, yh as BasetenParams } from "../index-CohO0oaX.js";
2
2
  export { BasetenParams, baseten, planBasetenReasoning };
@@ -1,2 +1,2 @@
1
- import { _h as CerebrasParams, vh as cerebras } from "../index-LLXx0VRf.js";
1
+ import { _h as CerebrasParams, vh as cerebras } from "../index-CohO0oaX.js";
2
2
  export { CerebrasParams, cerebras };
@@ -1,2 +1,2 @@
1
- import { mh as local, ph as LocalParams } from "../index-LLXx0VRf.js";
1
+ import { mh as local, ph as LocalParams } from "../index-CohO0oaX.js";
2
2
  export { LocalParams, local };
@@ -1,2 +1,2 @@
1
- import { $m as classifyOpenAICompatError, Gm as OpenAICompatHttpError, Hm as OAIMessage, Jm as TOOL_RESULTS_TAG, Km as OpenAICompatParams, Qm as buildAssistantContent, Um as OAITool, Vm as ASSISTANT_TOOL_CALLS_TAG, Wm as OpenAICompatAuthHeader, Xm as applyOAIToolCacheBreakpoint, Ym as applyOAICacheBreakpoints, Zm as assistantMessage, ah as toOAIMessages, eh as consumeSSE, ih as openaiCompat, nh as mapOAIFinishReason, oh as toolResultsMessage, qm as OpenAICompatStreamError, rh as openAICompatPromptMessage, sh as userMessage, th as formatTools } from "../index-LLXx0VRf.js";
1
+ import { $m as classifyOpenAICompatError, Gm as OpenAICompatHttpError, Hm as OAIMessage, Jm as TOOL_RESULTS_TAG, Km as OpenAICompatParams, Qm as buildAssistantContent, Um as OAITool, Vm as ASSISTANT_TOOL_CALLS_TAG, Wm as OpenAICompatAuthHeader, Xm as applyOAIToolCacheBreakpoint, Ym as applyOAICacheBreakpoints, Zm as assistantMessage, ah as toOAIMessages, eh as consumeSSE, ih as openaiCompat, nh as mapOAIFinishReason, oh as toolResultsMessage, qm as OpenAICompatStreamError, rh as openAICompatPromptMessage, sh as userMessage, th as formatTools } from "../index-CohO0oaX.js";
2
2
  export { ASSISTANT_TOOL_CALLS_TAG, OAIMessage, OAITool, OpenAICompatAuthHeader, OpenAICompatHttpError, OpenAICompatParams, OpenAICompatStreamError, TOOL_RESULTS_TAG, applyOAICacheBreakpoints, applyOAIToolCacheBreakpoint, assistantMessage, buildAssistantContent, classifyOpenAICompatError, consumeSSE, formatTools, mapOAIFinishReason, openAICompatPromptMessage, openaiCompat, toOAIMessages, toolResultsMessage, userMessage };
@@ -1,2 +1,2 @@
1
- import { ch as OpenAIParams, dh as openai, fh as toPiMessages, lh as classifyOpenAIError, uh as mapCodexStopReason } from "../index-LLXx0VRf.js";
1
+ import { ch as OpenAIParams, dh as openai, fh as toPiMessages, lh as classifyOpenAIError, uh as mapCodexStopReason } from "../index-CohO0oaX.js";
2
2
  export { OpenAIParams, classifyOpenAIError, mapCodexStopReason, openai, toPiMessages };
@@ -3,7 +3,7 @@ import { c as classifyErrorPrelude, d as isRetryableHttpStatus, f as matchesCont
3
3
  import { T as unsupportedMediaError, _ as userMessage, b as createOpenAIToolNameBoundary, g as toolResultsMessage, s as assistantMessage, x as fillEstimatedCost, y as sanitizeToolSpecs } from "../openai-compat-C77gOaHh.js";
4
4
  import { renderSystemForWire } from "../prompt.js";
5
5
  import { f as reasoningWireAction, n as SYNTHETIC_TOOL_RESULT_PLACEHOLDER } from "../messages-Cpb4g_KV.js";
6
- import { i as resolveOAuthApiKey, t as extractRuntimeCredentials } from "../oauth-8LqbeI_Q.js";
6
+ import { r as extractRuntimeCredentials, s as resolveOAuthApiKey } from "../oauth-CBi9eymX.js";
7
7
  import { stream } from "@earendil-works/pi-ai/api/openai-codex-responses";
8
8
  import { stream as stream$1 } from "@earendil-works/pi-ai/api/openai-responses";
9
9
  import { getBuiltinModel } from "@earendil-works/pi-ai/providers/all";
@@ -1,2 +1,2 @@
1
- import { Bm as openrouter, Rm as OpenRouterParams, zm as normalizeOpenRouterModelId } from "../index-LLXx0VRf.js";
1
+ import { Bm as openrouter, Rm as OpenRouterParams, zm as normalizeOpenRouterModelId } from "../index-CohO0oaX.js";
2
2
  export { OpenRouterParams, normalizeOpenRouterModelId, openrouter };
@@ -1,2 +1,2 @@
1
- import { Mm as xai, jm as XaiParams } from "../index-LLXx0VRf.js";
1
+ import { Mm as xai, jm as XaiParams } from "../index-CohO0oaX.js";
2
2
  export { XaiParams, xai };
@@ -1,2 +1,2 @@
1
- import { t as xai } from "../xai-CPZBj_WJ.js";
1
+ import { t as xai } from "../xai-B2hIs5We.js";
2
2
  export { xai };
@@ -1,6 +1,6 @@
1
1
  import { m as openaiCompat } from "./openai-compat-C77gOaHh.js";
2
- import { i as resolveOAuthApiKey } from "./oauth-8LqbeI_Q.js";
3
- import { r as generatePkce } from "./xai-CPZBj_WJ.js";
2
+ import { s as resolveOAuthApiKey } from "./oauth-CBi9eymX.js";
3
+ import { r as generatePkce } from "./xai-B2hIs5We.js";
4
4
  //#region src/chat/oauth-page/cursor.ts
5
5
  /** pi-ai / zidane OAuth provider id. Also the credentials-file key. */
6
6
  const CURSOR_OAUTH_PROVIDER_ID = "cursor";
@@ -165,4 +165,4 @@ function cursor(params) {
165
165
  //#endregion
166
166
  export { createCursorOAuthProvider as n, cursor as t };
167
167
 
168
- //# sourceMappingURL=providers-BWsicxOG.js.map
168
+ //# sourceMappingURL=providers-DnHPW-dL.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"providers-BWsicxOG.js","names":[],"sources":["../src/chat/oauth-page/cursor.ts","../src/providers/cursor.ts"],"sourcesContent":["/**\n * Cursor OAuth flow.\n *\n * Unlike Anthropic / OpenAI Codex (loopback-redirect PKCE), Cursor uses a\n * **poll-based** PKCE flow with no local callback server:\n *\n * 1. Generate a PKCE verifier + challenge and a random UUID.\n * 2. Open the browser to `cursor.com/loginDeepControl?challenge&uuid&mode&redirectTarget`.\n * 3. Poll `api2.cursor.sh/auth/poll?uuid&verifier` until tokens come back\n * (HTTP 404 = \"not ready yet\", keep polling with backoff).\n * 4. Refresh via `POST api2.cursor.sh/auth/exchange_user_api_key` with\n * `Authorization: Bearer <refresh>`.\n *\n * Token expiry is derived from the access token's JWT `exp` claim (minus a\n * 5-minute safety margin), falling back to +1h when the claim is missing.\n *\n * Flow adapted from https://github.com/ndraiman/pi-cursor-provider, itself\n * derived from https://github.com/ephraimduncan/opencode-cursor.\n *\n * Cursor's auth + inference protocol is unofficial and undocumented — re-verify\n * the endpoints/params below if login starts failing.\n */\n\nimport type {\n OAuthCredentials,\n OAuthLoginCallbacks,\n OAuthProviderInterface,\n} from '@earendil-works/pi-ai/oauth'\nimport { generatePkce } from './pkce'\n\n/** pi-ai / zidane OAuth provider id. Also the credentials-file key. */\nexport const CURSOR_OAUTH_PROVIDER_ID = 'cursor'\n\nconst CURSOR_LOGIN_URL = 'https://cursor.com/loginDeepControl'\nconst CURSOR_POLL_URL = 'https://api2.cursor.sh/auth/poll'\nconst CURSOR_REFRESH_URL = 'https://api2.cursor.sh/auth/exchange_user_api_key'\n\nconst POLL_MAX_ATTEMPTS = 150\nconst POLL_BASE_DELAY_MS = 1000\nconst POLL_MAX_DELAY_MS = 10_000\nconst POLL_BACKOFF_MULTIPLIER = 1.2\nconst POLL_MAX_CONSECUTIVE_ERRORS = 3\n\n/** Fallback lifetime when the JWT carries no `exp`. */\nconst DEFAULT_TOKEN_TTL_MS = 3600 * 1000\n/** Refresh slightly early so requests don't race expiry. */\nconst TOKEN_EXPIRY_SKEW_MS = 5 * 60 * 1000\n\ninterface CursorTokenResponse {\n accessToken: string\n refreshToken: string\n}\n\n/**\n * Derive expiry (epoch ms) from a JWT's `exp` claim, minus a safety skew.\n * Returns `now + 1h` for malformed tokens so a missing claim never wedges\n * refresh into an immediate-expire loop.\n */\nexport function cursorTokenExpiry(token: string): number {\n try {\n const parts = token.split('.')\n const payload = parts[1]\n if (parts.length !== 3 || !payload)\n return Date.now() + DEFAULT_TOKEN_TTL_MS\n\n const json = JSON.parse(atob(payload.replace(/-/g, '+').replace(/_/g, '/'))) as { exp?: unknown }\n if (typeof json.exp === 'number')\n return json.exp * 1000 - TOKEN_EXPIRY_SKEW_MS\n }\n catch {\n // fall through to default\n }\n return Date.now() + DEFAULT_TOKEN_TTL_MS\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise(r => setTimeout(r, ms))\n}\n\n/**\n * Poll Cursor's auth endpoint until login completes. `404` means the user\n * hasn't finished the browser flow yet; anything else non-2xx is a hard error.\n */\nasync function pollForTokens(\n uuid: string,\n verifier: string,\n callbacks: OAuthLoginCallbacks,\n): Promise<CursorTokenResponse> {\n let wait = POLL_BASE_DELAY_MS\n let consecutiveErrors = 0\n\n for (let attempt = 0; attempt < POLL_MAX_ATTEMPTS; attempt++) {\n if (callbacks.signal?.aborted)\n throw new Error('Cursor login aborted')\n\n await delay(wait)\n\n try {\n const url = `${CURSOR_POLL_URL}?uuid=${encodeURIComponent(uuid)}&verifier=${encodeURIComponent(verifier)}`\n const response = await fetch(url, { signal: callbacks.signal })\n\n if (response.status === 404) {\n consecutiveErrors = 0\n wait = Math.min(wait * POLL_BACKOFF_MULTIPLIER, POLL_MAX_DELAY_MS)\n continue\n }\n\n if (response.ok) {\n const data = await response.json() as Partial<CursorTokenResponse>\n if (!data.accessToken || !data.refreshToken)\n throw new Error(`Cursor poll response missing tokens: ${JSON.stringify(data)}`)\n return { accessToken: data.accessToken, refreshToken: data.refreshToken }\n }\n\n throw new Error(`Cursor poll failed (${response.status})`)\n }\n catch (err) {\n if (callbacks.signal?.aborted)\n throw new Error('Cursor login aborted')\n consecutiveErrors++\n if (consecutiveErrors >= POLL_MAX_CONSECUTIVE_ERRORS)\n throw err instanceof Error ? err : new Error(String(err))\n callbacks.onProgress?.('Waiting for Cursor login to complete…')\n }\n }\n\n throw new Error('Cursor authentication timed out')\n}\n\nexport async function loginCursor(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials> {\n const { verifier, challenge } = await generatePkce()\n const uuid = crypto.randomUUID()\n\n const authUrl = new URL(CURSOR_LOGIN_URL)\n authUrl.searchParams.set('challenge', challenge)\n authUrl.searchParams.set('uuid', uuid)\n authUrl.searchParams.set('mode', 'login')\n authUrl.searchParams.set('redirectTarget', 'cli')\n\n callbacks.onAuth({\n url: authUrl.toString(),\n instructions: 'A browser window should open. Complete login in Cursor to finish.',\n })\n\n const tokens = await pollForTokens(uuid, verifier, callbacks)\n\n return {\n access: tokens.accessToken,\n refresh: tokens.refreshToken,\n expires: cursorTokenExpiry(tokens.accessToken),\n }\n}\n\nexport async function refreshCursorToken(credentials: OAuthCredentials): Promise<OAuthCredentials> {\n const response = await fetch(CURSOR_REFRESH_URL, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${credentials.refresh}`,\n 'Content-Type': 'application/json',\n },\n body: '{}',\n })\n\n if (!response.ok) {\n const text = await response.text().catch(() => '')\n throw new Error(`Cursor token refresh failed (${response.status}): ${text || response.statusText}`)\n }\n\n const data = await response.json() as Partial<CursorTokenResponse>\n if (!data.accessToken)\n throw new Error(`Cursor token refresh response missing access token: ${JSON.stringify(data)}`)\n\n return {\n access: data.accessToken,\n // Cursor may omit a rotated refresh token — keep the existing one.\n refresh: data.refreshToken || credentials.refresh,\n expires: cursorTokenExpiry(data.accessToken),\n }\n}\n\n/**\n * Build a Cursor `OAuthProviderInterface`. Shape matches Anthropic / Codex so\n * it drops into `BUILTIN_PROVIDERS` and `src/auth.ts` unchanged.\n *\n * No `renderPage` parameter: Cursor's poll flow has no local callback server,\n * so there is no post-redirect page to theme.\n */\nexport function createCursorOAuthProvider(): OAuthProviderInterface {\n return {\n id: CURSOR_OAUTH_PROVIDER_ID,\n name: 'Cursor',\n usesCallbackServer: false,\n login: loginCursor,\n refreshToken: refreshCursorToken,\n getApiKey: credentials => credentials.access,\n }\n}\n","import type { Provider, StreamCallbacks } from '.'\nimport { CURSOR_OAUTH_PROVIDER_ID } from '../chat/oauth-page/cursor'\nimport { resolveOAuthApiKey } from './oauth'\nimport { openaiCompat } from './openai-compat'\n\n/**\n * Cursor provider (OAuth).\n *\n * Auth is fully wired: `bun run auth --cursor` (or the TUI wizard) logs in via\n * Cursor's poll-based PKCE flow and persists credentials; this provider resolves\n * + refreshes the OAuth token on every turn via {@link resolveOAuthApiKey}.\n *\n * Inference is **not** wired yet. Cursor does not expose an OpenAI-compatible\n * HTTP endpoint — it speaks a protobuf/Connect agent protocol over HTTP/2 to\n * `api2.cursor.sh`. Implementing `stream()` requires porting that transport\n * (generated protobuf schemas + an HTTP/2 streaming client) in-process, which\n * is intentionally left as a follow-up. Until then `stream()` resolves the\n * token (proving auth works) and then throws a clear, actionable error.\n *\n * The `openaiCompat` base supplies the message-format helpers (`formatTools`,\n * `userMessage`, `toolResultsMessage`, …) so the provider satisfies the full\n * `Provider` contract and slots into the registry; only `stream` is overridden.\n */\nexport interface CursorParams {\n /** Bypass OAuth resolution with an explicit token (mainly for tests). */\n apiKey?: string\n defaultModel?: string\n /**\n * Extra HTTP headers for the eventual Cursor transport. Accepted for API\n * parity with the other providers and forwarded to the openai-compat base,\n * but inert until Cursor inference is implemented (the `stream` override\n * currently throws before any request is made).\n */\n extraHeaders?: Record<string, string>\n}\n\nconst DEFAULT_MODEL = 'claude-4.6-sonnet'\n\nconst NOT_IMPLEMENTED_MESSAGE\n = 'Cursor OAuth login works, but inference over Cursor is not implemented yet. '\n + 'Cursor uses a protobuf/HTTP-2 agent protocol (not an OpenAI-compatible API), '\n + 'so the streaming transport still needs to be ported. Use another provider for now.'\n\nexport function cursor(params?: CursorParams): Provider {\n const defaultModel = params?.defaultModel || DEFAULT_MODEL\n\n // Base only provides the format/serialization methods; `baseURL` is never\n // hit because we override `stream` below.\n const base = openaiCompat({\n name: 'cursor',\n apiKey: params?.apiKey ?? 'oauth',\n baseURL: 'https://api2.cursor.sh',\n defaultModel,\n capabilities: { vision: true, imageInToolResult: false },\n extraHeaders: params?.extraHeaders,\n })\n\n return {\n ...base,\n meta: { ...base.meta, defaultModel },\n async stream(options, callbacks: StreamCallbacks) {\n // Resolve (and lazily refresh) the OAuth token so auth failures surface\n // here with the right remediation, distinct from the not-implemented path.\n await resolveOAuthApiKey(\n {\n provider: 'cursor',\n providerId: CURSOR_OAUTH_PROVIDER_ID,\n params,\n missingError: 'No Cursor credentials found. Run `bun run auth --cursor` first.',\n refreshError: reason => `Cursor OAuth token refresh failed. Run \\`bun run auth --cursor\\` again. ${reason}`,\n },\n callbacks,\n )\n void options\n throw new Error(NOT_IMPLEMENTED_MESSAGE)\n },\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"providers-DnHPW-dL.js","names":[],"sources":["../src/chat/oauth-page/cursor.ts","../src/providers/cursor.ts"],"sourcesContent":["/**\n * Cursor OAuth flow.\n *\n * Unlike Anthropic / OpenAI Codex (loopback-redirect PKCE), Cursor uses a\n * **poll-based** PKCE flow with no local callback server:\n *\n * 1. Generate a PKCE verifier + challenge and a random UUID.\n * 2. Open the browser to `cursor.com/loginDeepControl?challenge&uuid&mode&redirectTarget`.\n * 3. Poll `api2.cursor.sh/auth/poll?uuid&verifier` until tokens come back\n * (HTTP 404 = \"not ready yet\", keep polling with backoff).\n * 4. Refresh via `POST api2.cursor.sh/auth/exchange_user_api_key` with\n * `Authorization: Bearer <refresh>`.\n *\n * Token expiry is derived from the access token's JWT `exp` claim (minus a\n * 5-minute safety margin), falling back to +1h when the claim is missing.\n *\n * Flow adapted from https://github.com/ndraiman/pi-cursor-provider, itself\n * derived from https://github.com/ephraimduncan/opencode-cursor.\n *\n * Cursor's auth + inference protocol is unofficial and undocumented — re-verify\n * the endpoints/params below if login starts failing.\n */\n\nimport type {\n OAuthCredentials,\n OAuthLoginCallbacks,\n OAuthProviderInterface,\n} from '@earendil-works/pi-ai/oauth'\nimport { generatePkce } from './pkce'\n\n/** pi-ai / zidane OAuth provider id. Also the credentials-file key. */\nexport const CURSOR_OAUTH_PROVIDER_ID = 'cursor'\n\nconst CURSOR_LOGIN_URL = 'https://cursor.com/loginDeepControl'\nconst CURSOR_POLL_URL = 'https://api2.cursor.sh/auth/poll'\nconst CURSOR_REFRESH_URL = 'https://api2.cursor.sh/auth/exchange_user_api_key'\n\nconst POLL_MAX_ATTEMPTS = 150\nconst POLL_BASE_DELAY_MS = 1000\nconst POLL_MAX_DELAY_MS = 10_000\nconst POLL_BACKOFF_MULTIPLIER = 1.2\nconst POLL_MAX_CONSECUTIVE_ERRORS = 3\n\n/** Fallback lifetime when the JWT carries no `exp`. */\nconst DEFAULT_TOKEN_TTL_MS = 3600 * 1000\n/** Refresh slightly early so requests don't race expiry. */\nconst TOKEN_EXPIRY_SKEW_MS = 5 * 60 * 1000\n\ninterface CursorTokenResponse {\n accessToken: string\n refreshToken: string\n}\n\n/**\n * Derive expiry (epoch ms) from a JWT's `exp` claim, minus a safety skew.\n * Returns `now + 1h` for malformed tokens so a missing claim never wedges\n * refresh into an immediate-expire loop.\n */\nexport function cursorTokenExpiry(token: string): number {\n try {\n const parts = token.split('.')\n const payload = parts[1]\n if (parts.length !== 3 || !payload)\n return Date.now() + DEFAULT_TOKEN_TTL_MS\n\n const json = JSON.parse(atob(payload.replace(/-/g, '+').replace(/_/g, '/'))) as { exp?: unknown }\n if (typeof json.exp === 'number')\n return json.exp * 1000 - TOKEN_EXPIRY_SKEW_MS\n }\n catch {\n // fall through to default\n }\n return Date.now() + DEFAULT_TOKEN_TTL_MS\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise(r => setTimeout(r, ms))\n}\n\n/**\n * Poll Cursor's auth endpoint until login completes. `404` means the user\n * hasn't finished the browser flow yet; anything else non-2xx is a hard error.\n */\nasync function pollForTokens(\n uuid: string,\n verifier: string,\n callbacks: OAuthLoginCallbacks,\n): Promise<CursorTokenResponse> {\n let wait = POLL_BASE_DELAY_MS\n let consecutiveErrors = 0\n\n for (let attempt = 0; attempt < POLL_MAX_ATTEMPTS; attempt++) {\n if (callbacks.signal?.aborted)\n throw new Error('Cursor login aborted')\n\n await delay(wait)\n\n try {\n const url = `${CURSOR_POLL_URL}?uuid=${encodeURIComponent(uuid)}&verifier=${encodeURIComponent(verifier)}`\n const response = await fetch(url, { signal: callbacks.signal })\n\n if (response.status === 404) {\n consecutiveErrors = 0\n wait = Math.min(wait * POLL_BACKOFF_MULTIPLIER, POLL_MAX_DELAY_MS)\n continue\n }\n\n if (response.ok) {\n const data = await response.json() as Partial<CursorTokenResponse>\n if (!data.accessToken || !data.refreshToken)\n throw new Error(`Cursor poll response missing tokens: ${JSON.stringify(data)}`)\n return { accessToken: data.accessToken, refreshToken: data.refreshToken }\n }\n\n throw new Error(`Cursor poll failed (${response.status})`)\n }\n catch (err) {\n if (callbacks.signal?.aborted)\n throw new Error('Cursor login aborted')\n consecutiveErrors++\n if (consecutiveErrors >= POLL_MAX_CONSECUTIVE_ERRORS)\n throw err instanceof Error ? err : new Error(String(err))\n callbacks.onProgress?.('Waiting for Cursor login to complete…')\n }\n }\n\n throw new Error('Cursor authentication timed out')\n}\n\nexport async function loginCursor(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials> {\n const { verifier, challenge } = await generatePkce()\n const uuid = crypto.randomUUID()\n\n const authUrl = new URL(CURSOR_LOGIN_URL)\n authUrl.searchParams.set('challenge', challenge)\n authUrl.searchParams.set('uuid', uuid)\n authUrl.searchParams.set('mode', 'login')\n authUrl.searchParams.set('redirectTarget', 'cli')\n\n callbacks.onAuth({\n url: authUrl.toString(),\n instructions: 'A browser window should open. Complete login in Cursor to finish.',\n })\n\n const tokens = await pollForTokens(uuid, verifier, callbacks)\n\n return {\n access: tokens.accessToken,\n refresh: tokens.refreshToken,\n expires: cursorTokenExpiry(tokens.accessToken),\n }\n}\n\nexport async function refreshCursorToken(credentials: OAuthCredentials): Promise<OAuthCredentials> {\n const response = await fetch(CURSOR_REFRESH_URL, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${credentials.refresh}`,\n 'Content-Type': 'application/json',\n },\n body: '{}',\n })\n\n if (!response.ok) {\n const text = await response.text().catch(() => '')\n throw new Error(`Cursor token refresh failed (${response.status}): ${text || response.statusText}`)\n }\n\n const data = await response.json() as Partial<CursorTokenResponse>\n if (!data.accessToken)\n throw new Error(`Cursor token refresh response missing access token: ${JSON.stringify(data)}`)\n\n return {\n access: data.accessToken,\n // Cursor may omit a rotated refresh token — keep the existing one.\n refresh: data.refreshToken || credentials.refresh,\n expires: cursorTokenExpiry(data.accessToken),\n }\n}\n\n/**\n * Build a Cursor `OAuthProviderInterface`. Shape matches Anthropic / Codex so\n * it drops into `BUILTIN_PROVIDERS` and `src/auth.ts` unchanged.\n *\n * No `renderPage` parameter: Cursor's poll flow has no local callback server,\n * so there is no post-redirect page to theme.\n */\nexport function createCursorOAuthProvider(): OAuthProviderInterface {\n return {\n id: CURSOR_OAUTH_PROVIDER_ID,\n name: 'Cursor',\n usesCallbackServer: false,\n login: loginCursor,\n refreshToken: refreshCursorToken,\n getApiKey: credentials => credentials.access,\n }\n}\n","import type { Provider, StreamCallbacks } from '.'\nimport { CURSOR_OAUTH_PROVIDER_ID } from '../chat/oauth-page/cursor'\nimport { resolveOAuthApiKey } from './oauth'\nimport { openaiCompat } from './openai-compat'\n\n/**\n * Cursor provider (OAuth).\n *\n * Auth is fully wired: `bun run auth --cursor` (or the TUI wizard) logs in via\n * Cursor's poll-based PKCE flow and persists credentials; this provider resolves\n * + refreshes the OAuth token on every turn via {@link resolveOAuthApiKey}.\n *\n * Inference is **not** wired yet. Cursor does not expose an OpenAI-compatible\n * HTTP endpoint — it speaks a protobuf/Connect agent protocol over HTTP/2 to\n * `api2.cursor.sh`. Implementing `stream()` requires porting that transport\n * (generated protobuf schemas + an HTTP/2 streaming client) in-process, which\n * is intentionally left as a follow-up. Until then `stream()` resolves the\n * token (proving auth works) and then throws a clear, actionable error.\n *\n * The `openaiCompat` base supplies the message-format helpers (`formatTools`,\n * `userMessage`, `toolResultsMessage`, …) so the provider satisfies the full\n * `Provider` contract and slots into the registry; only `stream` is overridden.\n */\nexport interface CursorParams {\n /** Bypass OAuth resolution with an explicit token (mainly for tests). */\n apiKey?: string\n defaultModel?: string\n /**\n * Extra HTTP headers for the eventual Cursor transport. Accepted for API\n * parity with the other providers and forwarded to the openai-compat base,\n * but inert until Cursor inference is implemented (the `stream` override\n * currently throws before any request is made).\n */\n extraHeaders?: Record<string, string>\n}\n\nconst DEFAULT_MODEL = 'claude-4.6-sonnet'\n\nconst NOT_IMPLEMENTED_MESSAGE\n = 'Cursor OAuth login works, but inference over Cursor is not implemented yet. '\n + 'Cursor uses a protobuf/HTTP-2 agent protocol (not an OpenAI-compatible API), '\n + 'so the streaming transport still needs to be ported. Use another provider for now.'\n\nexport function cursor(params?: CursorParams): Provider {\n const defaultModel = params?.defaultModel || DEFAULT_MODEL\n\n // Base only provides the format/serialization methods; `baseURL` is never\n // hit because we override `stream` below.\n const base = openaiCompat({\n name: 'cursor',\n apiKey: params?.apiKey ?? 'oauth',\n baseURL: 'https://api2.cursor.sh',\n defaultModel,\n capabilities: { vision: true, imageInToolResult: false },\n extraHeaders: params?.extraHeaders,\n })\n\n return {\n ...base,\n meta: { ...base.meta, defaultModel },\n async stream(options, callbacks: StreamCallbacks) {\n // Resolve (and lazily refresh) the OAuth token so auth failures surface\n // here with the right remediation, distinct from the not-implemented path.\n await resolveOAuthApiKey(\n {\n provider: 'cursor',\n providerId: CURSOR_OAUTH_PROVIDER_ID,\n params,\n missingError: 'No Cursor credentials found. Run `bun run auth --cursor` first.',\n refreshError: reason => `Cursor OAuth token refresh failed. Run \\`bun run auth --cursor\\` again. ${reason}`,\n },\n callbacks,\n )\n void options\n throw new Error(NOT_IMPLEMENTED_MESSAGE)\n },\n }\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { $m as classifyOpenAICompatError, Am as TurnResult, Bm as openrouter, Ch as arcee, Cm as ProviderCapabilities, Dh as anthropic, Dm as ToolCall, Em as TokenCountPayload, Fm as SchemaSanitizeResult, Gm as OpenAICompatHttpError, Im as sanitizeToolSchema, Km as OpenAICompatParams, Lm as sanitizeToolSpecs, Mm as xai, Nm as SchemaSanitizeOptions, Oh as applyAnthropicCacheBreakpoints, Om as ToolResult, Pm as SchemaSanitizeProfile, Rm as OpenRouterParams, Sh as ArceeParams, Sm as Provider, Th as AnthropicParams, Tm as StreamOptions, Wm as OpenAICompatAuthHeader, _h as CerebrasParams, bh as baseten, ch as OpenAIParams, dh as openai, gh as cursor, hh as CursorParams, ih as openaiCompat, jm as XaiParams, km as ToolSpec, mh as local, nh as mapOAIFinishReason, ph as LocalParams, vh as cerebras, wm as StreamCallbacks, xh as planBasetenReasoning, xm as HistoryRepair, yh as BasetenParams } from "./index-LLXx0VRf.js";
2
- export { type AnthropicParams, type ArceeParams, type BasetenParams, type CerebrasParams, type CursorParams, HistoryRepair, type LocalParams, type OpenAICompatAuthHeader, OpenAICompatHttpError, type OpenAICompatParams, type OpenAIParams, type OpenRouterParams, Provider, ProviderCapabilities, type SchemaSanitizeOptions, type SchemaSanitizeProfile, type SchemaSanitizeResult, StreamCallbacks, StreamOptions, TokenCountPayload, ToolCall, ToolResult, ToolSpec, TurnResult, type XaiParams, anthropic, applyAnthropicCacheBreakpoints, arcee, baseten, cerebras, classifyOpenAICompatError, cursor, local, mapOAIFinishReason, openai, openaiCompat, openrouter, planBasetenReasoning, sanitizeToolSchema, sanitizeToolSpecs, xai };
1
+ import { $m as classifyOpenAICompatError, Am as TurnResult, Bh as credentialsFromParams, Bm as openrouter, Ch as arcee, Cm as ProviderCapabilities, Dh as anthropic, Dm as ToolCall, Em as TokenCountPayload, Fm as SchemaSanitizeResult, Gh as resolveOAuthApiKey, Gm as OpenAICompatHttpError, Hh as isOAuthAccessToken, Im as sanitizeToolSchema, Kh as writeOAuthCredentials, Km as OpenAICompatParams, Lh as OAuthParams, Lm as sanitizeToolSpecs, Mm as xai, Nm as SchemaSanitizeOptions, Oh as applyAnthropicCacheBreakpoints, Om as ToolResult, Pm as SchemaSanitizeProfile, Rh as ResolveOAuthApiKeyOptions, Rm as OpenRouterParams, Sh as ArceeParams, Sm as Provider, Th as AnthropicParams, Tm as StreamOptions, Uh as readOAuthCredentials, Vh as extractRuntimeCredentials, Wh as registerCustomOAuthProvider, Wm as OpenAICompatAuthHeader, _h as CerebrasParams, bh as baseten, ch as OpenAIParams, dh as openai, gh as cursor, hh as CursorParams, ih as openaiCompat, jm as XaiParams, km as ToolSpec, mh as local, nh as mapOAIFinishReason, ph as LocalParams, vh as cerebras, wm as StreamCallbacks, xh as planBasetenReasoning, xm as HistoryRepair, yh as BasetenParams, zh as credentialsFilePath } from "./index-CohO0oaX.js";
2
+ export { type AnthropicParams, type ArceeParams, type BasetenParams, type CerebrasParams, type CursorParams, HistoryRepair, type LocalParams, type OAuthParams, type OpenAICompatAuthHeader, OpenAICompatHttpError, type OpenAICompatParams, type OpenAIParams, type OpenRouterParams, Provider, ProviderCapabilities, type ResolveOAuthApiKeyOptions, type SchemaSanitizeOptions, type SchemaSanitizeProfile, type SchemaSanitizeResult, StreamCallbacks, StreamOptions, TokenCountPayload, ToolCall, ToolResult, ToolSpec, TurnResult, type XaiParams, anthropic, applyAnthropicCacheBreakpoints, arcee, baseten, cerebras, classifyOpenAICompatError, credentialsFilePath, credentialsFromParams, cursor, extractRuntimeCredentials, isOAuthAccessToken, local, mapOAIFinishReason, openai, openaiCompat, openrouter, planBasetenReasoning, readOAuthCredentials, registerCustomOAuthProvider, resolveOAuthApiKey, sanitizeToolSchema, sanitizeToolSpecs, writeOAuthCredentials, xai };
package/dist/providers.js CHANGED
@@ -1,11 +1,12 @@
1
1
  import { f as mapOAIFinishReason, l as classifyOpenAICompatError, m as openaiCompat, n as OpenAICompatHttpError, v as sanitizeToolSchema, y as sanitizeToolSpecs } from "./openai-compat-C77gOaHh.js";
2
- import { n as applyAnthropicCacheBreakpoints, t as anthropic } from "./anthropic-BI-Ukg2w.js";
2
+ import { n as applyAnthropicCacheBreakpoints, t as anthropic } from "./anthropic-asnZVFS_.js";
3
+ import { a as readOAuthCredentials, c as writeOAuthCredentials, i as isOAuthAccessToken, n as credentialsFromParams, o as registerCustomOAuthProvider, r as extractRuntimeCredentials, s as resolveOAuthApiKey, t as credentialsFilePath } from "./oauth-CBi9eymX.js";
3
4
  import { arcee } from "./providers/arcee.js";
4
5
  import { baseten, planBasetenReasoning } from "./providers/baseten.js";
5
6
  import { cerebras } from "./providers/cerebras.js";
6
- import { t as xai } from "./xai-CPZBj_WJ.js";
7
- import { t as cursor } from "./providers-BWsicxOG.js";
7
+ import { t as xai } from "./xai-B2hIs5We.js";
8
+ import { t as cursor } from "./providers-DnHPW-dL.js";
8
9
  import { local } from "./providers/local.js";
9
10
  import { openai } from "./providers/openai.js";
10
11
  import { openrouter } from "./providers/openrouter.js";
11
- export { OpenAICompatHttpError, anthropic, applyAnthropicCacheBreakpoints, arcee, baseten, cerebras, classifyOpenAICompatError, cursor, local, mapOAIFinishReason, openai, openaiCompat, openrouter, planBasetenReasoning, sanitizeToolSchema, sanitizeToolSpecs, xai };
12
+ export { OpenAICompatHttpError, anthropic, applyAnthropicCacheBreakpoints, arcee, baseten, cerebras, classifyOpenAICompatError, credentialsFilePath, credentialsFromParams, cursor, extractRuntimeCredentials, isOAuthAccessToken, local, mapOAIFinishReason, openai, openaiCompat, openrouter, planBasetenReasoning, readOAuthCredentials, registerCustomOAuthProvider, resolveOAuthApiKey, sanitizeToolSchema, sanitizeToolSpecs, writeOAuthCredentials, xai };
package/dist/restate.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Gd as AgentBehavior, Kd as AgentClock, Pf as ToolBatchExecutor, Qf as ToolDef, Rf as ToolResultContent, Sm as Provider, Tm as StreamOptions, Xi as McpToolWrap, Yi as McpToolMeta, Zf as ToolContext, xp as SessionStore } from "./index-LLXx0VRf.js";
1
+ import { Gd as AgentBehavior, Kd as AgentClock, Pf as ToolBatchExecutor, Qf as ToolDef, Rf as ToolResultContent, Sm as Provider, Tm as StreamOptions, Xi as McpToolWrap, Yi as McpToolMeta, Zf as ToolContext, xp as SessionStore } from "./index-CohO0oaX.js";
2
2
  import { h as TaskExitInfo, l as ExecutionHandle, m as TaskEntry, o as DetachedTasksCapability } from "./types-BDccavwj.js";
3
3
 
4
4
  //#region src/restate/types.d.ts
@@ -1,4 +1,4 @@
1
- import { xp as SessionStore } from "../index-LLXx0VRf.js";
1
+ import { xp as SessionStore } from "../index-CohO0oaX.js";
2
2
 
3
3
  //#region src/session/sqlite.d.ts
4
4
  interface SqliteStoreOptions {
package/dist/session.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { Af as SessionTurn, Ap as withExtensionSession, Bp as PairingDropKind, Cp as currentExtensionSession, Dp as loadSession, Ef as SessionContentBlock, Ep as getExtensionSessionState, Fp as FileMapStoreOptions, Ip as createFileMapStore, Mp as createRemoteStore, Np as createMemoryStore, Op as resumeChainRunIds, Pp as FileMapAdapter, Sp as createSession, Tp as demoteStaleRunningStatus, Yp as autoDetectAndConvert, Zp as dropInvalidToolPairings, _p as Session, bp as SessionRun, cm as toWireMessages, gp as LoadSessionOptions, hp as CreateSessionOptions, jp as RemoteStoreOptions, kf as SessionMessage, kp as setExtensionSessionState, nm as fromOpenAI, om as toAnthropic, qp as ToWireMessagesOptions, sm as toOpenAI, tm as fromAnthropic, vp as SessionData, wp as deleteExtensionSessionState, xp as SessionStore, yp as SessionMetaRow, zp as PairingDrop } from "./index-LLXx0VRf.js";
1
+ import { Af as SessionTurn, Ap as withExtensionSession, Bp as PairingDropKind, Cp as currentExtensionSession, Dp as loadSession, Ef as SessionContentBlock, Ep as getExtensionSessionState, Fp as FileMapStoreOptions, Ip as createFileMapStore, Mp as createRemoteStore, Np as createMemoryStore, Op as resumeChainRunIds, Pp as FileMapAdapter, Sp as createSession, Tp as demoteStaleRunningStatus, Yp as autoDetectAndConvert, Zp as dropInvalidToolPairings, _p as Session, bp as SessionRun, cm as toWireMessages, gp as LoadSessionOptions, hp as CreateSessionOptions, jp as RemoteStoreOptions, kf as SessionMessage, kp as setExtensionSessionState, nm as fromOpenAI, om as toAnthropic, qp as ToWireMessagesOptions, sm as toOpenAI, tm as fromAnthropic, vp as SessionData, wp as deleteExtensionSessionState, xp as SessionStore, yp as SessionMetaRow, zp as PairingDrop } from "./index-CohO0oaX.js";
2
2
  export { CreateSessionOptions, type FileMapAdapter, type FileMapStoreOptions, LoadSessionOptions, type PairingDrop, type PairingDropKind, type RemoteStoreOptions, Session, type SessionContentBlock, SessionData, type SessionMessage, SessionMetaRow, SessionRun, SessionStore, type SessionTurn, type ToWireMessagesOptions, autoDetectAndConvert, createFileMapStore, createMemoryStore, createRemoteStore, createSession, currentExtensionSession, deleteExtensionSessionState, demoteStaleRunningStatus, dropInvalidToolPairings, fromAnthropic, fromOpenAI, getExtensionSessionState, loadSession, resumeChainRunIds, setExtensionSessionState, toAnthropic, toOpenAI, toWireMessages, withExtensionSession };
package/dist/skills.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { $s as resolveSkills, Cc as installAllowedToolsGate, Dc as SkillActivationState, Ec as DeactivationReason, Gs as SkillValidationResult, Hs as writeSkillToDisk, Js as parseAllowedToolPattern, Ks as isToolAllowedByUnion, Oc as SkillActivationStateOptions, Qs as validateSkillName, Sc as IMPLICITLY_ALLOWED_SKILL_TOOLS, Tc as ActiveSkill, Us as writeSkillsToDisk, Vs as defineSkill, Ws as SkillValidationIssue, Xs as validateResourcePathReal, Ys as validateResourcePath, Zs as validateSkillForWrite, _c as getDefaultScanPaths, ac as SkillInstallCandidate, bc as parseSkillFile, cc as SkillInstallOptions, dc as installSkillFromSpec, dp as SkillDiagnostic, ec as InterpolateShellCommandsOptions, fc as listSkillCandidates, fp as SkillResource, gc as discoverSkills, hc as SourcedScanPath, ic as SkillCandidateDetail, kc as createSkillActivationState, lc as SkillInstallResult, lp as ShellInterpolationApproval, mc as readSkillProvenance, mp as SkillsConfig, nc as stripShellInterpolations, oc as SkillInstallError, pc as parseSkillInstallSpec, pp as SkillSource, qs as matchesAllowedTool, rc as SKILL_PROVENANCE_FILE, sc as SkillInstallErrorCode, tc as interpolateShellCommands, uc as SkillInstallSpec, up as SkillConfig, vc as inferSource, wc as ActivationVia, xc as buildCatalog, yc as parseFrontmatter } from "./index-LLXx0VRf.js";
1
+ import { $s as resolveSkills, Cc as installAllowedToolsGate, Dc as SkillActivationState, Ec as DeactivationReason, Gs as SkillValidationResult, Hs as writeSkillToDisk, Js as parseAllowedToolPattern, Ks as isToolAllowedByUnion, Oc as SkillActivationStateOptions, Qs as validateSkillName, Sc as IMPLICITLY_ALLOWED_SKILL_TOOLS, Tc as ActiveSkill, Us as writeSkillsToDisk, Vs as defineSkill, Ws as SkillValidationIssue, Xs as validateResourcePathReal, Ys as validateResourcePath, Zs as validateSkillForWrite, _c as getDefaultScanPaths, ac as SkillInstallCandidate, bc as parseSkillFile, cc as SkillInstallOptions, dc as installSkillFromSpec, dp as SkillDiagnostic, ec as InterpolateShellCommandsOptions, fc as listSkillCandidates, fp as SkillResource, gc as discoverSkills, hc as SourcedScanPath, ic as SkillCandidateDetail, kc as createSkillActivationState, lc as SkillInstallResult, lp as ShellInterpolationApproval, mc as readSkillProvenance, mp as SkillsConfig, nc as stripShellInterpolations, oc as SkillInstallError, pc as parseSkillInstallSpec, pp as SkillSource, qs as matchesAllowedTool, rc as SKILL_PROVENANCE_FILE, sc as SkillInstallErrorCode, tc as interpolateShellCommands, uc as SkillInstallSpec, up as SkillConfig, vc as inferSource, wc as ActivationVia, xc as buildCatalog, yc as parseFrontmatter } from "./index-CohO0oaX.js";
2
2
  export { type ActivationVia, type ActiveSkill, type DeactivationReason, IMPLICITLY_ALLOWED_SKILL_TOOLS, type InterpolateShellCommandsOptions, SKILL_PROVENANCE_FILE, type ShellInterpolationApproval, type SkillActivationState, type SkillActivationStateOptions, type SkillCandidateDetail, type SkillConfig, type SkillDiagnostic, type SkillInstallCandidate, SkillInstallError, type SkillInstallErrorCode, type SkillInstallOptions, type SkillInstallResult, type SkillInstallSpec, type SkillResource, type SkillSource, type SkillValidationIssue, type SkillValidationResult, type SkillsConfig, type SourcedScanPath, buildCatalog, createSkillActivationState, defineSkill, discoverSkills, getDefaultScanPaths, inferSource, installAllowedToolsGate, installSkillFromSpec, interpolateShellCommands, isToolAllowedByUnion, listSkillCandidates, matchesAllowedTool, parseAllowedToolPattern, parseFrontmatter, parseSkillFile, parseSkillInstallSpec, readSkillProvenance, resolveSkills, stripShellInterpolations, validateResourcePath, validateResourcePathReal, validateSkillForWrite, validateSkillName, writeSkillToDisk, writeSkillsToDisk };
@@ -1,4 +1,4 @@
1
- import { Af as SessionTurn, Gu as StreamEvent, Uu as SessionMeta, Wu as Settings, cd as ModelInfo, id as ProviderKey, rd as ProviderAuth } from "./index-LLXx0VRf.js";
1
+ import { Af as SessionTurn, Gu as StreamEvent, Uu as SessionMeta, Wu as Settings, cd as ModelInfo, id as ProviderKey, rd as ProviderAuth } from "./index-CohO0oaX.js";
2
2
  import { ReactNode } from "react";
3
3
 
4
4
  //#region src/chat/turn-selection.d.ts
@@ -529,4 +529,4 @@ declare function displayNameFor(name: string, input?: Record<string, unknown>):
529
529
  declare function formatToolCall(name: string, input: Record<string, unknown>): ToolFormatLine | null;
530
530
  //#endregion
531
531
  export { selectableTurnIds as $, highlightSegments as A, ApprovalDecision as B, SearchTurnResult as C, buildSessionSearchIndex as D, SessionSearchIndex as E, searchSessionIndex as F, useSafeModeActions as G, RequestApproval as H, searchSessionIndexAsync as I, EDIT_TOOL_NAMES as J, useSafeModeQueue as K, searchSessionTurns as L, searchSessionHistory as M, searchSessionHistoryIndex as N, buildSessionSearchIndexAsync as O, searchSessionHistoryIndexAsync as P, isVisible as Q, searchTurns as R, SearchSessionResult as S, SessionSearchExcerpt as T, SafeModeActions as U, ApprovalRequest as V, SafeModeProvider as W, isTurnHighlighted as X, isEditErrorResult as Y, isUserBashEvent as Z, splitMarkdownCodeBlocks as _, formatToolCall as a, IndexedSearchTurn as b, splitPromptSegments as c, filterModelCatalog as d, selectionAfterTurnRemoval as et, indexOfEntry as f, normalizeMarkdownCodeFences as g, chunkMarkdownForRender as h, displayNameFor as i, searchHighlightRanges as j, filterSessionSearchCatalog as k, CatalogEntry as l, MarkdownSegment as m, ToolDisplayMeta as n, PromptSegment as o, MARKDOWN_RENDER_CHUNK_TARGET_BYTES as p, BASH_CALL_ID_PREFIX as q, ToolFormatLine as r, PromptSegmentRef as s, TOOL_DISPLAY as t, turnSelectionOwnership as tt, buildModelCatalog as u, HighlightRange as v, SessionHistoryMatch as w, SearchExcerpt as x, HighlightSegment as y, searchableTurnText as z };
532
- //# sourceMappingURL=tool-formatters-DtUL8zcF.d.ts.map
532
+ //# sourceMappingURL=tool-formatters-bZYz74qU.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tool-formatters-DtUL8zcF.d.ts","names":[],"sources":["../src/chat/turn-selection.ts","../src/chat/safe-mode-context.tsx","../src/chat/history-search.ts","../src/chat/markdown-segments.ts","../src/chat/model-catalog.ts","../src/chat/prompt-segments.ts","../src/chat/tool-formatters.ts"],"mappings":"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"}
1
+ {"version":3,"file":"tool-formatters-bZYz74qU.d.ts","names":[],"sources":["../src/chat/turn-selection.ts","../src/chat/safe-mode-context.tsx","../src/chat/history-search.ts","../src/chat/markdown-segments.ts","../src/chat/model-catalog.ts","../src/chat/prompt-segments.ts","../src/chat/tool-formatters.ts"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { Qf as ToolDef } from "../index-LLXx0VRf.js";
1
+ import { Qf as ToolDef } from "../index-CohO0oaX.js";
2
2
 
3
3
  //#region src/tools/fetch-url.d.ts
4
4
  declare function isBlockedAddress(ip: string): boolean;
@@ -1,4 +1,4 @@
1
- import { Qf as ToolDef } from "../index-LLXx0VRf.js";
1
+ import { Qf as ToolDef } from "../index-CohO0oaX.js";
2
2
 
3
3
  //#region src/tools/web-search.d.ts
4
4
  declare const webSearch: ToolDef;
package/dist/tools.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { $f as ToolMap, Ar as InteractionToolOptions, As as SpawnToolOptions, Bs as matchModelEntries, Cr as shellKill, Dr as readFile, Ds as SpawnTaskInput, Er as shell, Es as ExtensionSubagentDef, Fs as createSpawnTool, Is as isSpawnTool, Ls as SpawnModelEntry, Mr as grep, Ms as SubagentDef, Nr as glob, Ns as SubagentOverride, Or as multiEdit, Os as SpawnTaskOutcome, Pr as edit, Ps as SubagentRegistry, Qf as ToolDef, Rs as createModelSearchTool, Sr as createSkillsReadTool, Tr as createShellTool, Ts as ChildAgent, Zf as ToolContext, _r as SkillsUseToolOptions, ap as hydrateReadStateFromSession, br as createSkillsRunScriptTool, cp as resolveReadStateMap, cr as WAIT_TASK_TIMED_OUT_PREFIX, dr as validateToolArgs, ep as HydrateReadStateOptions, fr as TailTruncateOptions, gr as createToolSearchTool, hr as ToolSearchToolOptions, ip as hashContent, jr as createInteractionTool, js as SpawnToolState, kr as listFiles, ks as SpawnTool, lr as waitTask, mr as LazyToolEntry, np as ReadStateMap, op as hydrateReadStateFromSessionAsync, pr as tailTruncate, rp as getReadState, sp as readStateKey, sr as writeFile, tp as ReadStateEntry, ur as ValidationResult, vr as createSkillsUseTool, wr as CreateShellToolOptions, xr as SkillsReadToolOptions, yr as SkillsRunScriptToolOptions, zs as formatModelLine } from "./index-LLXx0VRf.js";
1
+ import { $f as ToolMap, Ar as InteractionToolOptions, As as SpawnToolOptions, Bs as matchModelEntries, Cr as shellKill, Dr as readFile, Ds as SpawnTaskInput, Er as shell, Es as ExtensionSubagentDef, Fs as createSpawnTool, Is as isSpawnTool, Ls as SpawnModelEntry, Mr as grep, Ms as SubagentDef, Nr as glob, Ns as SubagentOverride, Or as multiEdit, Os as SpawnTaskOutcome, Pr as edit, Ps as SubagentRegistry, Qf as ToolDef, Rs as createModelSearchTool, Sr as createSkillsReadTool, Tr as createShellTool, Ts as ChildAgent, Zf as ToolContext, _r as SkillsUseToolOptions, ap as hydrateReadStateFromSession, br as createSkillsRunScriptTool, cp as resolveReadStateMap, cr as WAIT_TASK_TIMED_OUT_PREFIX, dr as validateToolArgs, ep as HydrateReadStateOptions, fr as TailTruncateOptions, gr as createToolSearchTool, hr as ToolSearchToolOptions, ip as hashContent, jr as createInteractionTool, js as SpawnToolState, kr as listFiles, ks as SpawnTool, lr as waitTask, mr as LazyToolEntry, np as ReadStateMap, op as hydrateReadStateFromSessionAsync, pr as tailTruncate, rp as getReadState, sp as readStateKey, sr as writeFile, tp as ReadStateEntry, ur as ValidationResult, vr as createSkillsUseTool, wr as CreateShellToolOptions, xr as SkillsReadToolOptions, yr as SkillsRunScriptToolOptions, zs as formatModelLine } from "./index-CohO0oaX.js";
2
2
  export { type ChildAgent, type CreateShellToolOptions, type ExtensionSubagentDef, type HydrateReadStateOptions, type InteractionToolOptions, type LazyToolEntry, type ReadStateEntry, type ReadStateMap, type SkillsReadToolOptions, type SkillsRunScriptToolOptions, type SkillsUseToolOptions, type SpawnModelEntry, type SpawnTaskInput, type SpawnTaskOutcome, type SpawnTool, type SpawnToolOptions, type SpawnToolState, type SubagentDef, type SubagentOverride, type SubagentRegistry, type TailTruncateOptions, type ToolContext, type ToolDef, type ToolMap, type ToolSearchToolOptions, type ValidationResult, WAIT_TASK_TIMED_OUT_PREFIX, createInteractionTool, createModelSearchTool, createShellTool, createSkillsReadTool, createSkillsRunScriptTool, createSkillsUseTool, createSpawnTool, createToolSearchTool, edit, formatModelLine, getReadState, glob, grep, hashContent, hydrateReadStateFromSession, hydrateReadStateFromSessionAsync, isSpawnTool, listFiles, matchModelEntries, multiEdit, readFile, readStateKey, resolveReadStateMap, shell, shellKill, tailTruncate, validateToolArgs, waitTask, writeFile };
package/dist/tools.js CHANGED
@@ -1,3 +1,3 @@
1
1
  import { a as hydrateReadStateFromSessionAsync, c as resolveReadStateMap, i as hydrateReadStateFromSession, r as hashContent, s as readStateKey, t as getReadState } from "./read-state-rDmfeLmz.js";
2
- import { At as listFiles, Ct as tailTruncate, Dt as createModelSearchTool, Et as multiEdit, Ft as validateToolArgs, Mt as grep, Nt as glob, Ot as formatModelLine, Pt as edit, St as shell, _t as createSkillsUseTool, bt as shellKill, dt as writeFile, ft as WAIT_TASK_TIMED_OUT_PREFIX, gt as isSpawnTool, ht as createSpawnTool, jt as createInteractionTool, kt as matchModelEntries, mt as createToolSearchTool, pt as waitTask, vt as createSkillsRunScriptTool, wt as readFile, xt as createShellTool, yt as createSkillsReadTool } from "./agent-BMVp4byv.js";
2
+ import { At as createInteractionTool, Ct as readFile, Dt as formatModelLine, Et as createModelSearchTool, Mt as glob, Nt as edit, Ot as matchModelEntries, Pt as validateToolArgs, St as tailTruncate, Tt as multiEdit, _t as createSkillsRunScriptTool, bt as createShellTool, dt as WAIT_TASK_TIMED_OUT_PREFIX, ft as waitTask, gt as createSkillsUseTool, ht as isSpawnTool, jt as grep, kt as listFiles, mt as createSpawnTool, pt as createToolSearchTool, ut as writeFile, vt as createSkillsReadTool, xt as shell, yt as shellKill } from "./agent-CrPwqpLI.js";
3
3
  export { WAIT_TASK_TIMED_OUT_PREFIX, createInteractionTool, createModelSearchTool, createShellTool, createSkillsReadTool, createSkillsRunScriptTool, createSkillsUseTool, createSpawnTool, createToolSearchTool, edit, formatModelLine, getReadState, glob, grep, hashContent, hydrateReadStateFromSession, hydrateReadStateFromSessionAsync, isSpawnTool, listFiles, matchModelEntries, multiEdit, readFile, readStateKey, resolveReadStateMap, shell, shellKill, tailTruncate, validateToolArgs, waitTask, writeFile };
@@ -1,4 +1,4 @@
1
- import { Af as SessionTurn, Ef as SessionContentBlock, Gu as StreamEvent, Lo as ExtensionRegistry, Lu as EditOutcome, Nf as ThinkingLevel, Ns as SubagentOverride, Ps as SubagentRegistry, Rf as ToolResultContent, Tu as AgentRegistry, Uu as SessionMeta, Vu as Picked, Wa as ExtensionConfigCategory, Wu as Settings, bp as SessionRun, cd as ModelInfo, id as ProviderKey, no as StoredExtensionConfigItem, of as McpServerConfig, qu as ModelChainEntry, rd as ProviderAuth, t as Preset, ud as ProviderDescriptor, vp as SessionData, xp as SessionStore } from "./index-LLXx0VRf.js";
1
+ import { Af as SessionTurn, Ef as SessionContentBlock, Gu as StreamEvent, Lo as ExtensionRegistry, Lu as EditOutcome, Nf as ThinkingLevel, Ns as SubagentOverride, Ps as SubagentRegistry, Rf as ToolResultContent, Tu as AgentRegistry, Uu as SessionMeta, Vu as Picked, Wa as ExtensionConfigCategory, Wu as Settings, bp as SessionRun, cd as ModelInfo, id as ProviderKey, no as StoredExtensionConfigItem, of as McpServerConfig, qu as ModelChainEntry, rd as ProviderAuth, t as Preset, ud as ProviderDescriptor, vp as SessionData, xp as SessionStore } from "./index-CohO0oaX.js";
2
2
  //#region src/chat/hints.d.ts
3
3
  /**
4
4
  * Single hint entry — `<key> <label>`, optionally followed by an inline
@@ -1476,4 +1476,4 @@ declare function computeTurnAnchors(items: readonly TranscriptItem[]): {
1476
1476
  };
1477
1477
  //#endregion
1478
1478
  export { KEYBINDING_KEY_COL_WIDTH as $, resolveStorageDirs as A, loadState as B, ResolvedPaths as C, StorageDirs as D, ResolveStorageDirsOptions as E, createStateStore as F, titleFromTurns as G, saveState as H, deriveSessionTitle as I, updateToolEventOutcomes as J, toolCallPreview as K, eventsFromTurns as L, StateStoreApi as M, TuiState as N, StorageMode as O, compactSummaryEvent as P, KEYBINDING_DEF_BY_ACTION as Q, lastContextSizeFromTurns as R, ResolvedConfig as S, resolveStoragePaths as T, stripSpawnTokensLine as U, marginTopFor as V, sumRunCosts as W, DEFAULT_KEYBINDINGS as X, usageByModel as Y, KEYBINDING_DEFS as Z, discoverProjectMcps as _, EMPTY_HINTS as _t, SessionExportTarget as a, ResolvedExtensionKeybinding as at, ChatOptions as b, hintsLength as bt, writeSessionExport as c, groupBindings as ct, useEnabledToggleSet as d, mergeKeybindings as dt, KeyAction as et, DiscoveredMcp as f, parseBindingSpec as ft, defaultMcpsConfigPaths as g, stripJsonComments as gt, buildMcpServers as h, resolveExtensionKeybindings as ht, SessionExportFormat as i, ParsedBinding as it, ModelUsageSummary as j, StorageSlot as k, EnabledAllowlistKey as l, keybindingsPath as lt, DiscoveryResult as m, readKeybindingsRaw as mt, computeTurnAnchors as n, KeyBindingSection as nt, renderSession as o, ensureKeybindingsFile as ot, DiscoveryError as p, readKeybindings as pt, toolResultText as q, SessionExportAnchor as r, KeyBindings as rt, resolveSessionExportTarget as s, formatBindingForDisplay as st, TranscriptItem as t, KeyBindingDef as tt, EnabledToggleSet as u, matchesBinding as ut, parseMcpsFile as v, Hint as vt, resolveConfig as w, ProviderRegistry as x, truncateTrailing as xt, AutoUpdateConfig as y, clipHintsToWidth as yt, listSessionMeta as z };
1479
- //# sourceMappingURL=transcript-anchors-Cmn6Apac.d.ts.map
1479
+ //# sourceMappingURL=transcript-anchors-EBchHUMo.d.ts.map