@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-
|
|
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-
|
|
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-
|
|
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.
|
|
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-
|
|
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 = {}) {
|
package/dist/serve/options.d.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
17663
|
-
const state = url
|
|
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-
|
|
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: {
|