@caplets/core 0.20.0 → 0.20.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/auth.d.ts CHANGED
@@ -30,8 +30,8 @@ export type GenericAuthTarget = {
30
30
  requestTimeoutMs?: number | undefined;
31
31
  };
32
32
  export declare function staticRemoteHeaders(server: CapletServerConfig): Record<string, string>;
33
- export declare function oauthHeaders(server: CapletServerConfig, authDir?: string): Record<string, string>;
34
- export declare function genericOAuthHeaders(target: GenericAuthTarget, authDir?: string): Record<string, string>;
33
+ export declare function oauthHeaders(server: CapletServerConfig, authDir?: string): Promise<Record<string, string>>;
34
+ export declare function genericOAuthHeaders(target: GenericAuthTarget, authDir?: string): Promise<Record<string, string>>;
35
35
  export declare class FileOAuthProvider implements OAuthClientProvider {
36
36
  readonly server: CapletServerConfig;
37
37
  readonly redirectUrl: string;
@@ -1,4 +1,4 @@
1
- import { St as resolveProjectConfigPath, Y as loadConfigWithSources, bt as resolveConfigPath, mt as DEFAULT_COMPLETION_CACHE_DIR, pt as DEFAULT_AUTH_DIR, vn as __exportAll, yt as resolveCapletsRoot } from "./service-D0MwLNyb.js";
1
+ import { St as resolveProjectConfigPath, Y as loadConfigWithSources, bt as resolveConfigPath, mt as DEFAULT_COMPLETION_CACHE_DIR, pt as DEFAULT_AUTH_DIR, vn as __exportAll, yt as resolveCapletsRoot } from "./service-D3W-LuOx.js";
2
2
  import { u as CapletsError } from "./validation-CdqbI2zN.js";
3
3
  import { mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
4
4
  import { dirname, join } from "node:path";
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
- import { $ as parseConfig, $t as ReadResourceRequestSchema, A as QuickJsCodeModeSandbox, At as toJsonSchemaCompat, B as CapletsEngine, Bt as ErrorCode, C as nativeCapletToolName, Ct as ReadBuffer, D as codeModeRunInputSchema, Dt as AjvJsonSchemaValidator, Et as assertToolsCallTaskCapability, F as redactCodeModeLogText, Ft as CreateMessageResultWithToolsSchema, G as handleServerTool, Gt as LATEST_PROTOCOL_VERSION, H as decodeDirectResourceUri, Ht as InitializeRequestSchema, I as codeModeDeclarationHash, It as CreateTaskResultSchema, J as loadConfig, Jt as ListResourcesRequestSchema, K as ServerRegistry, Kt as ListPromptsRequestSchema, L as generateCodeModeDeclarations, M as createCodeModeCapletsApi, Mt as CallToolResultSchema, N as listCodeModeCallableCaplets, Nt as CompleteRequestSchema, O as codeModeRunParamsSchema, Ot as Protocol, P as CodeModeLogStore, Pt as CreateMessageResultSchema, Q as loadProjectConfig, Qt as McpError, R as generateCodeModeRunToolDescription, Rt as ElicitResultSchema, S as nativeCapletToolDescription, St as resolveProjectConfigPath, T as nativeCodeModeToolId, Tt as assertClientRequestTaskCapability, U as findProjectRoot, Ut as InitializedNotificationSchema, V as resolveExposure, Vt as GetPromptRequestSchema, W as fingerprintProjectRoot, Wt as JSONRPCMessageSchema, X as loadGlobalConfig, Xt as ListToolsRequestSchema, Y as loadConfigWithSources, Yt as ListRootsResultSchema, Z as loadLocalOverlayConfigWithSources, Zt as LoggingLevelSchema, _ as controlUrlForBase, _n as safeParseAsync, _t as defaultConfigBaseDir, a as projectBindingError, an as isJSONRPCErrorResponse, at as markdownStructuredContent, b as resolveCapletsServer, bt as resolveConfigPath, c as cloudAuthPath, cn as getLiteralValue, ct as startGenericOAuthFlow, d as CloudAuthClient, dn as getSchemaDescription, dt as isTokenBundleExpired, en as SUPPORTED_PROTOCOL_VERSIONS, et as discoverCapletFiles, fn as isSchemaOptional, ft as readTokenBundle, g as resolveCapletsRemote, gn as safeParse, gt as defaultCacheBaseDir, hn as objectFromShape, ht as DEFAULT_OBSERVED_OUTPUT_SHAPE_CACHE_DIR, i as ProjectBindingError, in as isInitializeRequest, it as markdownCallToolResultContent, j as diagnoseCodeModeTypeScript, jt as CallToolRequestSchema, k as runCodeMode, kt as mergeCapabilities, l as migrateCredentials, ln as getObjectShape, lt as startOAuthFlow, m as buildProjectSyncManifest, mn as normalizeObjectSchema, n as resolveRemoteSelection, nn as assertCompleteRequestPrompt, nt as loadCapletFilesFromMap, o as projectBindingRecovery, on as isJSONRPCRequest, ot as runGenericOAuthFlow, p as createSdkRemoteCapletsClient, pn as isZ4Schema, q as capabilityDescription, qt as ListResourceTemplatesRequestSchema, r as PROJECT_BINDING_ERROR_CODES, rn as assertCompleteRequestResourceTemplate, rt as hasRenderableStructuredContent, s as CloudAuthStore, sn as isJSONRPCResultResponse, st as runOAuthFlow, t as createNativeCapletsService, tn as SetLevelRequestSchema, tt as validateCapletFile, u as redactedCloudAuthStatus, un as getParseErrorMessage, ut as deleteTokenBundle, v as parseServerBaseUrl, vt as defaultStateBaseDir, wt as serializeMessage, x as nativeCapletPromptGuidance, xt as resolveProjectCapletsRoot, y as resolveCapletsMode, yt as resolveCapletsRoot, z as minifyCodeModeDeclarationText, zt as EmptyResultSchema } from "./service-D0MwLNyb.js";
1
+ import { $ as parseConfig, $t as ReadResourceRequestSchema, A as QuickJsCodeModeSandbox, At as toJsonSchemaCompat, B as CapletsEngine, Bt as ErrorCode, C as nativeCapletToolName, Ct as ReadBuffer, D as codeModeRunInputSchema, Dt as AjvJsonSchemaValidator, Et as assertToolsCallTaskCapability, F as redactCodeModeLogText, Ft as CreateMessageResultWithToolsSchema, G as handleServerTool, Gt as LATEST_PROTOCOL_VERSION, H as decodeDirectResourceUri, Ht as InitializeRequestSchema, I as codeModeDeclarationHash, It as CreateTaskResultSchema, J as loadConfig, Jt as ListResourcesRequestSchema, K as ServerRegistry, Kt as ListPromptsRequestSchema, L as generateCodeModeDeclarations, M as createCodeModeCapletsApi, Mt as CallToolResultSchema, N as listCodeModeCallableCaplets, Nt as CompleteRequestSchema, O as codeModeRunParamsSchema, Ot as Protocol, P as CodeModeLogStore, Pt as CreateMessageResultSchema, Q as loadProjectConfig, Qt as McpError, R as generateCodeModeRunToolDescription, Rt as ElicitResultSchema, S as nativeCapletToolDescription, St as resolveProjectConfigPath, T as nativeCodeModeToolId, Tt as assertClientRequestTaskCapability, U as findProjectRoot, Ut as InitializedNotificationSchema, V as resolveExposure, Vt as GetPromptRequestSchema, W as fingerprintProjectRoot, Wt as JSONRPCMessageSchema, X as loadGlobalConfig, Xt as ListToolsRequestSchema, Y as loadConfigWithSources, Yt as ListRootsResultSchema, Z as loadLocalOverlayConfigWithSources, Zt as LoggingLevelSchema, _ as controlUrlForBase, _n as safeParseAsync, _t as defaultConfigBaseDir, a as projectBindingError, an as isJSONRPCErrorResponse, at as markdownStructuredContent, b as resolveCapletsServer, bt as resolveConfigPath, c as cloudAuthPath, cn as getLiteralValue, ct as startGenericOAuthFlow, d as CloudAuthClient, dn as getSchemaDescription, dt as isTokenBundleExpired, en as SUPPORTED_PROTOCOL_VERSIONS, et as discoverCapletFiles, fn as isSchemaOptional, ft as readTokenBundle, g as resolveCapletsRemote, gn as safeParse, gt as defaultCacheBaseDir, hn as objectFromShape, ht as DEFAULT_OBSERVED_OUTPUT_SHAPE_CACHE_DIR, i as ProjectBindingError, in as isInitializeRequest, it as markdownCallToolResultContent, j as diagnoseCodeModeTypeScript, jt as CallToolRequestSchema, k as runCodeMode, kt as mergeCapabilities, l as migrateCredentials, ln as getObjectShape, lt as startOAuthFlow, m as buildProjectSyncManifest, mn as normalizeObjectSchema, n as resolveRemoteSelection, nn as assertCompleteRequestPrompt, nt as loadCapletFilesFromMap, o as projectBindingRecovery, on as isJSONRPCRequest, ot as runGenericOAuthFlow, p as createSdkRemoteCapletsClient, pn as isZ4Schema, q as capabilityDescription, qt as ListResourceTemplatesRequestSchema, r as PROJECT_BINDING_ERROR_CODES, rn as assertCompleteRequestResourceTemplate, rt as hasRenderableStructuredContent, s as CloudAuthStore, sn as isJSONRPCResultResponse, st as runOAuthFlow, t as createNativeCapletsService, tn as SetLevelRequestSchema, tt as validateCapletFile, u as redactedCloudAuthStatus, un as getParseErrorMessage, ut as deleteTokenBundle, v as parseServerBaseUrl, vt as defaultStateBaseDir, wt as serializeMessage, x as nativeCapletPromptGuidance, xt as resolveProjectCapletsRoot, y as resolveCapletsMode, yt as resolveCapletsRoot, z as minifyCodeModeDeclarationText, zt as EmptyResultSchema } from "./service-D3W-LuOx.js";
2
2
  import { _ as record, b as unknown, d as literal, m as object, n as ZodOptional, o as array, p as number, r as _enum, s as boolean, v as string, x as url } from "./schemas-BZ6BBrh7.js";
3
3
  import { f as redactSecrets, i as SERVER_ID_PATTERN, l as CAPLETS_ERROR_CODES, p as toSafeError, u as CapletsError } from "./validation-CdqbI2zN.js";
4
4
  import { generatedToolInputSchema, generatedToolInputSchemaForCaplet } from "./generated-tool-input-schema.js";
5
5
  import { f as observedOutputShapeKey, i as observeOutputShape, u as FileObservedOutputShapeStore } from "./observed-output-shapes-uzAMQPhg.js";
6
- import { a as formatCapletList, c as resolveCliConfigPaths, l as cliCommands$1, n as completionScript, o as formatConfigPaths, s as listCaplets, t as completeCliWords, u as completionShells } from "./completion-CbazRAiL.js";
6
+ import { a as formatCapletList, c as resolveCliConfigPaths, l as cliCommands$1, n as completionScript, o as formatConfigPaths, s as listCaplets, t as completeCliWords, u as completionShells } from "./completion-DZg_TWiX.js";
7
7
  import { n as normalizeCapletSourcePath, t as FilesystemCapletSource } from "./filesystem-Kkg32TOJ.js";
8
8
  import { parseConfig as parseConfig$1 } from "./config-runtime.js";
9
9
  import fs, { accessSync, chmodSync, closeSync, constants, copyFileSync, cpSync, existsSync, lstatSync, mkdirSync, mkdtempSync, openSync, readFileSync, readdirSync, readlinkSync, realpathSync, rmSync, statSync, writeFileSync, writeSync } from "node:fs";
@@ -1553,7 +1553,7 @@ const EMPTY_COMPLETION_RESULT = { completion: {
1553
1553
  } };
1554
1554
  //#endregion
1555
1555
  //#region package.json
1556
- var version = "0.20.0";
1556
+ var version = "0.20.2";
1557
1557
  //#endregion
1558
1558
  //#region src/serve/session.ts
1559
1559
  var CapletsMcpSession = class {
@@ -7110,6 +7110,7 @@ function resolveServeOptions(raw, env = process.env) {
7110
7110
  path,
7111
7111
  ...serverUrl ? { publicOrigin: serverUrl.origin } : {},
7112
7112
  auth,
7113
+ allowUnauthenticatedHttp: raw.allowUnauthenticatedHttp === true,
7113
7114
  warnUnauthenticatedNetwork: !loopback && !auth.enabled,
7114
7115
  loopback,
7115
7116
  trustProxy: raw.trustProxy === true
@@ -11135,13 +11136,16 @@ function safeEqual(left, right) {
11135
11136
  }
11136
11137
  function dnsRebindingOptions(options) {
11137
11138
  const hostForHeader = options.host === "::1" ? "[::1]" : options.host;
11139
+ const publicUrl = options.publicOrigin ? new URL(options.publicOrigin) : void 0;
11140
+ const publicHosts = publicUrl && (options.auth.enabled || options.allowUnauthenticatedHttp) ? [publicUrl.hostname, publicUrl.host] : [];
11138
11141
  return {
11139
11142
  enableDnsRebindingProtection: true,
11140
11143
  allowedHosts: [
11141
11144
  options.host,
11142
11145
  hostForHeader,
11143
11146
  `${hostForHeader}:${options.port}`,
11144
- `localhost:${options.port}`
11147
+ `localhost:${options.port}`,
11148
+ ...publicHosts
11145
11149
  ]
11146
11150
  };
11147
11151
  }
package/dist/native.js CHANGED
@@ -1,4 +1,4 @@
1
- import { C as nativeCapletToolName, E as nativeCodeModeToolName, S as nativeCapletToolDescription, T as nativeCodeModeToolId, f as RemoteNativeCapletsService, h as resolveNativeCapletsServiceOptions, p as createSdkRemoteCapletsClient, t as createNativeCapletsService, w as nativeCapletsSystemGuidance, x as nativeCapletPromptGuidance } from "./service-D0MwLNyb.js";
1
+ import { C as nativeCapletToolName, E as nativeCodeModeToolName, S as nativeCapletToolDescription, T as nativeCodeModeToolId, f as RemoteNativeCapletsService, h as resolveNativeCapletsServiceOptions, p as createSdkRemoteCapletsClient, t as createNativeCapletsService, w as nativeCapletsSystemGuidance, x as nativeCapletPromptGuidance } from "./service-D3W-LuOx.js";
2
2
  import { generatedToolInputJsonSchema, generatedToolInputSchema } from "./generated-tool-input-schema.js";
3
3
  //#region src/native/process-cleanup.ts
4
4
  function registerNativeCapletsProcessCleanup(service, options = {}) {
@@ -19,6 +19,7 @@ export type HttpServeOptions = {
19
19
  path: string;
20
20
  publicOrigin?: string | undefined;
21
21
  auth: HttpBasicAuthOptions;
22
+ allowUnauthenticatedHttp: boolean;
22
23
  warnUnauthenticatedNetwork: boolean;
23
24
  loopback: boolean;
24
25
  trustProxy: boolean;
@@ -17317,23 +17317,24 @@ function staticRemoteHeaders(server) {
17317
17317
  if (server.auth?.type === "headers") return server.auth.headers;
17318
17318
  return {};
17319
17319
  }
17320
- function genericOAuthHeaders(target, authDir) {
17320
+ async function genericOAuthHeaders(target, authDir) {
17321
17321
  if (target.auth?.type !== "oauth2" && target.auth?.type !== "oidc") return {};
17322
17322
  const authConfig = target.auth;
17323
- const bundle = readTokenBundle(target.server, authDir);
17324
- if (!bundle?.accessToken) throw new CapletsError("AUTH_REQUIRED", `OAuth credentials required for ${target.server}`, {
17323
+ let bundle = readTokenBundle(target.server, authDir);
17324
+ if (!bundle?.accessToken && !bundle?.refreshToken) throw new CapletsError("AUTH_REQUIRED", `OAuth credentials required for ${target.server}`, {
17325
17325
  server: target.server,
17326
17326
  backend: target.backend,
17327
17327
  authType: authConfig.type,
17328
17328
  nextAction: "run_caplets_auth_login"
17329
17329
  });
17330
- if (isTokenBundleExpired(bundle)) throw new CapletsError("AUTH_REFRESH_FAILED", `OAuth token for ${target.server} is expired`, {
17330
+ assertTokenBundleMatchesTarget(bundle, target, authConfig);
17331
+ if (!bundle.accessToken || isTokenBundleExpired(bundle)) bundle = await refreshGenericOAuthBundle(target, authConfig, bundle, authDir);
17332
+ if (!bundle.accessToken || isTokenBundleExpired(bundle)) throw new CapletsError("AUTH_REFRESH_FAILED", `OAuth token for ${target.server} is expired`, {
17331
17333
  server: target.server,
17332
17334
  backend: target.backend,
17333
17335
  authType: authConfig.type,
17334
17336
  nextAction: "run_caplets_auth_login"
17335
17337
  });
17336
- assertTokenBundleMatchesTarget(bundle, target, authConfig);
17337
17338
  return { authorization: `${bundle.tokenType ?? "Bearer"} ${bundle.accessToken}` };
17338
17339
  }
17339
17340
  var FileOAuthProvider = class {
@@ -17441,7 +17442,7 @@ async function startOAuthFlow(server, options) {
17441
17442
  complete: async (callbackUrl) => {
17442
17443
  assertNoOAuthCallbackError(server, callbackUrl);
17443
17444
  const completion = extractCompletion(callbackUrl);
17444
- if (completion.state !== provider.state()) throw new CapletsError("AUTH_FAILED", "OAuth callback state did not match");
17445
+ if (completion.state !== provider.state()) throw oauthStateMismatchError(server.server);
17445
17446
  try {
17446
17447
  await auth(provider, {
17447
17448
  serverUrl: server.url,
@@ -17535,7 +17536,7 @@ async function startGenericOAuthFlow(target, options) {
17535
17536
  complete: async (callbackUrl) => {
17536
17537
  assertNoOAuthCallbackError(target, callbackUrl);
17537
17538
  const completion = extractCompletion(callbackUrl);
17538
- if (completion.state !== state) throw new CapletsError("AUTH_FAILED", "OAuth callback state did not match");
17539
+ if (completion.state !== state) throw oauthStateMismatchError(target.server);
17539
17540
  const params = new URLSearchParams({
17540
17541
  grant_type: "authorization_code",
17541
17542
  code: completion.code,
@@ -17613,7 +17614,7 @@ async function runGenericOAuthFlow(target, options = {}) {
17613
17614
  code: callbackCode,
17614
17615
  ...callbackState ? { state: callbackState } : {}
17615
17616
  } : void 0);
17616
- if (completion.state !== state) throw new CapletsError("AUTH_FAILED", "OAuth callback state did not match");
17617
+ if (completion.state !== state) throw oauthStateMismatchError(target.server);
17617
17618
  const params = new URLSearchParams({
17618
17619
  grant_type: "authorization_code",
17619
17620
  code: completion.code,
@@ -17658,9 +17659,9 @@ async function runGenericOAuthFlow(target, options = {}) {
17658
17659
  }
17659
17660
  function extractCompletion(input) {
17660
17661
  try {
17661
- const url = new URL(input);
17662
- const code = url.searchParams.get("code");
17663
- const state = url.searchParams.get("state") ?? void 0;
17662
+ const url = new URL(stripOAuthCallbackUrlWrapping(input));
17663
+ const code = extractOAuthCallbackParam(url, "code");
17664
+ const state = extractOAuthCallbackParam(url, "state");
17664
17665
  if (!code) throw new Error("missing code");
17665
17666
  return state ? {
17666
17667
  code,
@@ -17670,6 +17671,27 @@ function extractCompletion(input) {
17670
17671
  return { code: input.trim() };
17671
17672
  }
17672
17673
  }
17674
+ function stripOAuthCallbackUrlWrapping(input) {
17675
+ return input.replace(/\s+/g, "");
17676
+ }
17677
+ function extractOAuthCallbackParam(url, name) {
17678
+ const query = url.search.startsWith("?") ? url.search.slice(1) : url.search;
17679
+ for (const part of query.split("&")) {
17680
+ const separator = part.indexOf("=");
17681
+ const rawName = separator < 0 ? part : part.slice(0, separator);
17682
+ const rawValue = separator < 0 ? "" : part.slice(separator + 1);
17683
+ if (decodeOAuthCallbackQueryValue(rawName) === name) return decodeOAuthCallbackQueryValue(rawValue) || void 0;
17684
+ }
17685
+ }
17686
+ function decodeOAuthCallbackQueryValue(value) {
17687
+ return decodeURIComponent(value);
17688
+ }
17689
+ function oauthStateMismatchError(server) {
17690
+ return new CapletsError("AUTH_FAILED", "OAuth callback state did not match. Re-run auth login and use the authorization URL and callback URL from the same attempt.", {
17691
+ server,
17692
+ nextAction: "rerun_caplets_auth_login"
17693
+ });
17694
+ }
17673
17695
  function classifyRemoteAuthError(server, response) {
17674
17696
  if (response.status !== 401 && response.status !== 403) return;
17675
17697
  const challenge = extractWWWAuthenticateParams(response);
@@ -17768,6 +17790,87 @@ async function resolveGenericClient(target, authConfig, metadata, redirectUri, a
17768
17790
  dynamic: true
17769
17791
  };
17770
17792
  }
17793
+ async function refreshGenericOAuthBundle(target, authConfig, bundle, authDir) {
17794
+ if (!bundle.refreshToken) throw new CapletsError("AUTH_REFRESH_FAILED", `OAuth token for ${target.server} is expired`, {
17795
+ server: target.server,
17796
+ backend: target.backend,
17797
+ authType: authConfig.type,
17798
+ nextAction: "run_caplets_auth_login"
17799
+ });
17800
+ const allowLoopbackHttp = isLoopbackDevelopmentTarget(target, authConfig);
17801
+ let metadata = {};
17802
+ let tokenEndpoint = authConfig.tokenUrl;
17803
+ if (!tokenEndpoint) {
17804
+ metadata = await discoverAuthorizationServer(target, authConfig, allowLoopbackHttp);
17805
+ tokenEndpoint = metadata.token_endpoint;
17806
+ }
17807
+ if (!tokenEndpoint) throw new CapletsError("AUTH_REFRESH_FAILED", "OAuth metadata is missing token endpoint", {
17808
+ server: target.server,
17809
+ backend: target.backend,
17810
+ authType: authConfig.type,
17811
+ nextAction: "run_caplets_auth_login"
17812
+ });
17813
+ assertAllowedAuthUrl(tokenEndpoint, "token endpoint", allowLoopbackHttp);
17814
+ const clientId = authConfig.clientId ?? authConfig.clientMetadataUrl ?? bundle.clientId;
17815
+ if (!clientId) throw new CapletsError("AUTH_REFRESH_FAILED", "OAuth clientId is required to refresh tokens", {
17816
+ server: target.server,
17817
+ backend: target.backend,
17818
+ authType: authConfig.type,
17819
+ nextAction: "run_caplets_auth_login"
17820
+ });
17821
+ const clientSecret = authConfig.clientSecret ?? bundle.clientSecret;
17822
+ const params = new URLSearchParams({
17823
+ grant_type: "refresh_token",
17824
+ refresh_token: bundle.refreshToken,
17825
+ client_id: clientId
17826
+ });
17827
+ if (clientSecret) params.set("client_secret", clientSecret);
17828
+ let tokenResponse;
17829
+ try {
17830
+ tokenResponse = await fetchJson(tokenEndpoint, target.requestTimeoutMs, {
17831
+ method: "POST",
17832
+ headers: { "content-type": "application/x-www-form-urlencoded" },
17833
+ body: params.toString()
17834
+ }, allowLoopbackHttp);
17835
+ } catch (error) {
17836
+ if (error instanceof CapletsError) throw new CapletsError("AUTH_REFRESH_FAILED", `OAuth token refresh failed`, {
17837
+ server: target.server,
17838
+ backend: target.backend,
17839
+ authType: authConfig.type,
17840
+ nextAction: "run_caplets_auth_login",
17841
+ cause: error.details
17842
+ });
17843
+ throw error;
17844
+ }
17845
+ const idToken = asString(tokenResponse.id_token);
17846
+ const idClaims = parseJwtPayload(idToken);
17847
+ if (idToken) {
17848
+ if (!metadata.issuer && !authConfig.issuer) metadata = await discoverAuthorizationServer(target, authConfig, allowLoopbackHttp);
17849
+ validateOidcToken(authConfig, metadata, idToken, idClaims, clientId);
17850
+ }
17851
+ const refreshed = stripUndefined$1({
17852
+ ...bundle,
17853
+ server: target.server,
17854
+ authType: authConfig.type,
17855
+ accessToken: requireString(tokenResponse.access_token, "access_token"),
17856
+ refreshToken: asString(tokenResponse.refresh_token) ?? bundle.refreshToken,
17857
+ tokenType: asString(tokenResponse.token_type) ?? bundle.tokenType,
17858
+ expiresAt: refreshedExpiresAt(tokenResponse.expires_in, bundle.expiresAt),
17859
+ scope: asString(tokenResponse.scope) ?? bundle.scope ?? scopesFor(authConfig),
17860
+ idToken: idToken ?? bundle.idToken,
17861
+ issuer: asString(idClaims?.iss) ?? bundle.issuer ?? metadata.issuer ?? authConfig.issuer,
17862
+ subject: asString(idClaims?.sub) ?? bundle.subject,
17863
+ clientId,
17864
+ clientSecret,
17865
+ protectedResourceOrigin: protectedResourceOrigin(target, authConfig)
17866
+ });
17867
+ writeTokenBundle(refreshed, authDir);
17868
+ return refreshed;
17869
+ }
17870
+ function refreshedExpiresAt(expiresIn, fallback) {
17871
+ if (typeof expiresIn === "number") return new Date(Date.now() + expiresIn * 1e3).toISOString();
17872
+ if (fallback && Date.parse(fallback) > Date.now()) return fallback;
17873
+ }
17771
17874
  async function fetchOptionalJson(url, timeoutMs, allowLoopbackHttp = false) {
17772
17875
  try {
17773
17876
  return await fetchJson(url, timeoutMs, {}, allowLoopbackHttp);
@@ -49327,7 +49430,7 @@ var GraphQLManager = class {
49327
49430
  const headers = new Headers({
49328
49431
  "content-type": "application/json",
49329
49432
  ...staticHeaders(endpoint),
49330
- ...genericOAuthHeaders({
49433
+ ...await genericOAuthHeaders({
49331
49434
  server: endpoint.server,
49332
49435
  backend: "graphql",
49333
49436
  url: endpoint.endpointUrl,
@@ -49630,7 +49733,7 @@ async function postGraphQl(endpoint, url, payload, authDir) {
49630
49733
  headers: {
49631
49734
  "content-type": "application/json",
49632
49735
  ...staticHeaders(endpoint),
49633
- ...genericOAuthHeaders({
49736
+ ...await genericOAuthHeaders({
49634
49737
  server: endpoint.server,
49635
49738
  backend: "graphql",
49636
49739
  url: endpoint.endpointUrl,
@@ -49655,7 +49758,7 @@ async function fetchGraphQlText(endpoint, url, authDir, sendAuth = true) {
49655
49758
  response = await fetch(url, {
49656
49759
  redirect: "manual",
49657
49760
  signal: controller.signal,
49658
- headers: { ...sendAuth ? schemaAuthHeaders(endpoint, authDir) : {} }
49761
+ headers: { ...sendAuth ? await schemaAuthHeaders(endpoint, authDir) : {} }
49659
49762
  });
49660
49763
  } catch (error) {
49661
49764
  if (isAbortError(error)) throw new CapletsError("TOOL_CALL_TIMEOUT", "GraphQL schema request timed out");
@@ -49667,10 +49770,10 @@ async function fetchGraphQlText(endpoint, url, authDir, sendAuth = true) {
49667
49770
  if (!response.ok) throw new CapletsError("DOWNSTREAM_PROTOCOL_ERROR", "GraphQL schema request failed", { status: response.status });
49668
49771
  return readGraphQlText(response);
49669
49772
  }
49670
- function schemaAuthHeaders(endpoint, authDir) {
49773
+ async function schemaAuthHeaders(endpoint, authDir) {
49671
49774
  return {
49672
49775
  ...staticHeaders(endpoint),
49673
- ...genericOAuthHeaders({
49776
+ ...await genericOAuthHeaders({
49674
49777
  server: endpoint.server,
49675
49778
  backend: "graphql",
49676
49779
  url: endpoint.endpointUrl,
@@ -49726,7 +49829,7 @@ var HttpActionManager = class {
49726
49829
  try {
49727
49830
  const operations = operationsFor(api);
49728
49831
  validateBaseUrl(api);
49729
- authHeaders$1(api, this.options.authDir);
49832
+ await authHeaders$1(api, this.options.authDir);
49730
49833
  for (const operation of operations) validateAction(api, operation);
49731
49834
  this.registry.setStatus(api.server, "available");
49732
49835
  return {
@@ -49755,7 +49858,7 @@ var HttpActionManager = class {
49755
49858
  async callTool(api, toolName, args) {
49756
49859
  const operation = getOperation(api, toolName);
49757
49860
  const startedAt = Date.now();
49758
- const request = buildRequest$1(api, operation, args, this.options.authDir);
49861
+ const request = await buildRequest$1(api, operation, args, this.options.authDir);
49759
49862
  const controller = new AbortController();
49760
49863
  const timeout = setTimeout(() => controller.abort(), api.requestTimeoutMs);
49761
49864
  try {
@@ -49836,14 +49939,14 @@ function getOperation(api, toolName) {
49836
49939
  });
49837
49940
  return operation;
49838
49941
  }
49839
- function buildRequest$1(api, operation, args, authDir) {
49942
+ async function buildRequest$1(api, operation, args, authDir) {
49840
49943
  validateBaseUrl(api);
49841
49944
  validateAction(api, operation);
49842
49945
  const url = buildActionUrl(api.baseUrl, substitutePath$1(operation.path, args, operation), { allowEncodedSlash: true });
49843
49946
  const query = resolveMappingToRecord(operation.query, args, "query");
49844
49947
  for (const [key, value] of Object.entries(query)) if (value !== void 0 && value !== null) url.searchParams.append(key, serializeHttpValue$1("query", key, value));
49845
49948
  const headers = new Headers();
49846
- applyAuth$1(headers, api, authDir);
49949
+ await applyAuth$1(headers, api, authDir);
49847
49950
  const resolvedHeaders = resolveMappingToRecord(operation.headers, args, "headers");
49848
49951
  for (const [key, value] of Object.entries(resolvedHeaders)) if (value !== void 0 && value !== null) {
49849
49952
  validateResolvedHeader(api, operation, key);
@@ -49919,16 +50022,16 @@ function serializeHttpValue$1(location, name, value) {
49919
50022
  default: throw new CapletsError("REQUEST_INVALID", `HTTP action ${location} parameter ${name} must be a string, number, or boolean`);
49920
50023
  }
49921
50024
  }
49922
- function applyAuth$1(headers, api, authDir) {
49923
- for (const [key, value] of Object.entries(authHeaders$1(api, authDir))) headers.set(key, value);
50025
+ async function applyAuth$1(headers, api, authDir) {
50026
+ for (const [key, value] of Object.entries(await authHeaders$1(api, authDir))) headers.set(key, value);
49924
50027
  }
49925
- function authHeaders$1(api, authDir) {
50028
+ async function authHeaders$1(api, authDir) {
49926
50029
  switch (api.auth.type) {
49927
50030
  case "none": return {};
49928
50031
  case "bearer": return { authorization: `Bearer ${api.auth.token}` };
49929
50032
  case "headers": return api.auth.headers;
49930
50033
  case "oauth2":
49931
- case "oidc": return genericOAuthHeaders({
50034
+ case "oidc": return await genericOAuthHeaders({
49932
50035
  server: api.server,
49933
50036
  backend: "http",
49934
50037
  baseUrl: api.baseUrl,
@@ -59754,7 +59857,7 @@ var OpenApiManager = class {
59754
59857
  }
59755
59858
  async callTool(endpoint, toolName, args) {
59756
59859
  const operation = await this.getOperation(endpoint, toolName);
59757
- const request = buildRequest(endpoint, operation, args, this.options.authDir);
59860
+ const request = await buildRequest(endpoint, operation, args, this.options.authDir);
59758
59861
  const controller = new AbortController();
59759
59862
  const timeout = setTimeout(() => controller.abort(), endpoint.requestTimeoutMs);
59760
59863
  try {
@@ -59868,7 +59971,7 @@ async function loadOpenApiSource(endpoint, authDir) {
59868
59971
  if (endpoint.specPath) return endpoint.specPath;
59869
59972
  if (!endpoint.specUrl) throw new CapletsError("CONFIG_INVALID", `${endpoint.server} is missing OpenAPI spec source`);
59870
59973
  if (!endpoint.baseUrl) throw new CapletsError("CONFIG_INVALID", `${endpoint.server} must configure baseUrl when using remote specUrl`);
59871
- return parseOpenApiSourceText(await fetchWithLimit(endpoint.specUrl, endpoint.requestTimeoutMs, shouldSendSpecAuth(endpoint) ? authHeaders(endpoint, authDir) : {}));
59974
+ return parseOpenApiSourceText(await fetchWithLimit(endpoint.specUrl, endpoint.requestTimeoutMs, shouldSendSpecAuth(endpoint) ? await authHeaders(endpoint, authDir) : {}));
59872
59975
  }
59873
59976
  function parseOpenApiSourceText(source) {
59874
59977
  let parsed;
@@ -60039,13 +60142,13 @@ function rejectExternalRefs(value) {
60039
60142
  if (typeof object.$ref === "string" && !object.$ref.startsWith("#/")) throw new CapletsError("CONFIG_INVALID", "External OpenAPI $ref values are not supported");
60040
60143
  for (const nested of Object.values(object)) rejectExternalRefs(nested);
60041
60144
  }
60042
- function buildRequest(endpoint, operation, args, authDir) {
60145
+ async function buildRequest(endpoint, operation, args, authDir) {
60043
60146
  const base = endpoint.baseUrl ?? operation.baseUrl;
60044
60147
  validateOperationBaseUrl(endpoint, base);
60045
60148
  const url = buildOperationUrl(base, substitutePath(operation.path, asRecord(args.path), operation));
60046
60149
  for (const [key, value] of Object.entries(asRecord(args.query))) if (value !== void 0 && value !== null) url.searchParams.append(key, serializeHttpValue("query", key, value));
60047
60150
  const headers = new Headers();
60048
- applyAuth(headers, endpoint, authDir);
60151
+ await applyAuth(headers, endpoint, authDir);
60049
60152
  const configuredHeaderNames = configuredAuthHeaderNames(endpoint);
60050
60153
  for (const [key, value] of Object.entries(operation.staticHeaders ?? {})) if (!headers.has(key) && !configuredHeaderNames.has(key.toLowerCase())) headers.set(key, value);
60051
60154
  for (const [key, value] of Object.entries(asRecord(args.header))) if (value !== void 0 && value !== null) {
@@ -60090,19 +60193,19 @@ function serializeHttpValue(location, name, value) {
60090
60193
  function asRecord(value) {
60091
60194
  return value && typeof value === "object" && !Array.isArray(value) ? value : {};
60092
60195
  }
60093
- function applyAuth(headers, endpoint, authDir) {
60094
- for (const [key, value] of Object.entries(authHeaders(endpoint, authDir))) headers.set(key, value);
60196
+ async function applyAuth(headers, endpoint, authDir) {
60197
+ for (const [key, value] of Object.entries(await authHeaders(endpoint, authDir))) headers.set(key, value);
60095
60198
  }
60096
60199
  function configuredAuthHeaderNames(endpoint) {
60097
60200
  return endpoint.auth.type === "headers" ? new Set(Object.keys(endpoint.auth.headers).map((key) => key.toLowerCase())) : /* @__PURE__ */ new Set();
60098
60201
  }
60099
- function authHeaders(endpoint, authDir) {
60202
+ async function authHeaders(endpoint, authDir) {
60100
60203
  switch (endpoint.auth.type) {
60101
60204
  case "none": return {};
60102
60205
  case "bearer": return { authorization: `Bearer ${endpoint.auth.token}` };
60103
60206
  case "headers": return endpoint.auth.headers;
60104
60207
  case "oauth2":
60105
- case "oidc": return genericOAuthHeaders(endpoint, authDir);
60208
+ case "oidc": return await genericOAuthHeaders(endpoint, authDir);
60106
60209
  }
60107
60210
  }
60108
60211
  function shouldSendSpecAuth(endpoint) {
@@ -61697,7 +61800,7 @@ var CapletsEngine = class {
61697
61800
  }
61698
61801
  }
61699
61802
  async completeCliWords(words) {
61700
- const { completeCliWords } = await import("./completion-CbazRAiL.js").then((n) => n.r);
61803
+ const { completeCliWords } = await import("./completion-DZg_TWiX.js").then((n) => n.r);
61701
61804
  return await completeCliWords(words, {
61702
61805
  config: this.registry.config,
61703
61806
  managers: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@caplets/core",
3
- "version": "0.20.0",
3
+ "version": "0.20.2",
4
4
  "description": "Core runtime library for Caplets Code Mode and progressive disclosure gateways.",
5
5
  "keywords": [
6
6
  "caplets",