@caplets/core 0.12.2 → 0.13.0
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.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { generatedToolInputDescriptions, operations } from "./generated-tool-input-schema.js";
|
|
1
|
+
import { generatedToolInputDescriptions, generatedToolInputJsonSchema, operations } from "./generated-tool-input-schema.js";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { accessSync, chmodSync, constants, existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, statSync, watch, writeFileSync } from "node:fs";
|
|
4
4
|
import minpath, { basename, delimiter, dirname, extname, isAbsolute, join, parse, posix, relative, resolve, win32 } from "node:path";
|
|
@@ -26433,6 +26433,24 @@ const capletCliToolsSchema = object({
|
|
|
26433
26433
|
maxOutputBytes: number$1().int().positive().optional(),
|
|
26434
26434
|
disabled: boolean().optional().describe("When true, omit this Caplet from discovery.")
|
|
26435
26435
|
}).strict();
|
|
26436
|
+
const capletSetSchema = object({
|
|
26437
|
+
configPath: string().min(1).optional().describe("Child Caplets config.json path."),
|
|
26438
|
+
capletsRoot: string().min(1).optional().describe("Child Markdown Caplets root directory."),
|
|
26439
|
+
defaultSearchLimit: number$1().int().positive().optional(),
|
|
26440
|
+
maxSearchLimit: number$1().int().positive().max(50).optional(),
|
|
26441
|
+
toolCacheTtlMs: number$1().int().nonnegative().optional(),
|
|
26442
|
+
disabled: boolean().optional().describe("When true, omit this Caplet from discovery.")
|
|
26443
|
+
}).strict().superRefine((set, ctx) => {
|
|
26444
|
+
if (!set.configPath && !set.capletsRoot) ctx.addIssue({
|
|
26445
|
+
code: "custom",
|
|
26446
|
+
message: "capletSet must define at least one source: configPath or capletsRoot"
|
|
26447
|
+
});
|
|
26448
|
+
if (set.defaultSearchLimit !== void 0 && set.maxSearchLimit !== void 0 && set.defaultSearchLimit > set.maxSearchLimit) ctx.addIssue({
|
|
26449
|
+
code: "custom",
|
|
26450
|
+
path: ["defaultSearchLimit"],
|
|
26451
|
+
message: "defaultSearchLimit must be <= maxSearchLimit"
|
|
26452
|
+
});
|
|
26453
|
+
});
|
|
26436
26454
|
const capletFileSchema = object({
|
|
26437
26455
|
$schema: string().url().optional().describe("Optional JSON Schema URL for editor validation."),
|
|
26438
26456
|
name: string().trim().min(1).max(80).describe("Human-readable Caplet display name."),
|
|
@@ -26442,13 +26460,17 @@ const capletFileSchema = object({
|
|
|
26442
26460
|
openapiEndpoint: capletOpenApiEndpointSchema.describe("OpenAPI endpoint backend configuration for this Caplet.").optional(),
|
|
26443
26461
|
graphqlEndpoint: capletGraphQlEndpointSchema.describe("GraphQL endpoint backend configuration for this Caplet.").optional(),
|
|
26444
26462
|
httpApi: capletHttpApiSchema.describe("HTTP API backend configuration for this Caplet.").optional(),
|
|
26445
|
-
cliTools: capletCliToolsSchema.describe("CLI tools backend configuration for this Caplet.").optional()
|
|
26463
|
+
cliTools: capletCliToolsSchema.describe("CLI tools backend configuration for this Caplet.").optional(),
|
|
26464
|
+
capletSet: capletSetSchema.describe("Nested Caplet collection backend configuration for this Caplet.").optional()
|
|
26446
26465
|
}).strict().superRefine((frontmatter, ctx) => {
|
|
26447
|
-
if (Number(Boolean(frontmatter.mcpServer)) + Number(Boolean(frontmatter.openapiEndpoint)) + Number(Boolean(frontmatter.graphqlEndpoint)) + Number(Boolean(frontmatter.httpApi)) + Number(Boolean(frontmatter.cliTools)) !== 1) ctx.addIssue({
|
|
26466
|
+
if (Number(Boolean(frontmatter.mcpServer)) + Number(Boolean(frontmatter.openapiEndpoint)) + Number(Boolean(frontmatter.graphqlEndpoint)) + Number(Boolean(frontmatter.httpApi)) + Number(Boolean(frontmatter.cliTools)) + Number(Boolean(frontmatter.capletSet)) !== 1) ctx.addIssue({
|
|
26448
26467
|
code: "custom",
|
|
26449
|
-
message: "Caplet file must define exactly one backend: mcpServer, openapiEndpoint, graphqlEndpoint, httpApi, or
|
|
26468
|
+
message: "Caplet file must define exactly one backend: mcpServer, openapiEndpoint, graphqlEndpoint, httpApi, cliTools, or capletSet"
|
|
26450
26469
|
});
|
|
26451
26470
|
});
|
|
26471
|
+
function loadCapletFiles(root) {
|
|
26472
|
+
return loadCapletFilesWithPaths(root)?.config;
|
|
26473
|
+
}
|
|
26452
26474
|
function loadCapletFilesWithPaths(root) {
|
|
26453
26475
|
if (!existsSync(root)) return;
|
|
26454
26476
|
const servers = {};
|
|
@@ -26456,9 +26478,10 @@ function loadCapletFilesWithPaths(root) {
|
|
|
26456
26478
|
const graphqlEndpoints = {};
|
|
26457
26479
|
const httpApis = {};
|
|
26458
26480
|
const cliTools = {};
|
|
26481
|
+
const capletSets = {};
|
|
26459
26482
|
const paths = {};
|
|
26460
26483
|
for (const candidate of discoverCapletFiles(root)) {
|
|
26461
|
-
if (servers[candidate.id] || openapiEndpoints[candidate.id] || graphqlEndpoints[candidate.id] || httpApis[candidate.id] || cliTools[candidate.id]) throw new CapletsError("CONFIG_INVALID", `Duplicate Caplet ID ${candidate.id} under ${root}`);
|
|
26484
|
+
if (servers[candidate.id] || openapiEndpoints[candidate.id] || graphqlEndpoints[candidate.id] || httpApis[candidate.id] || cliTools[candidate.id] || capletSets[candidate.id]) throw new CapletsError("CONFIG_INVALID", `Duplicate Caplet ID ${candidate.id} under ${root}`);
|
|
26462
26485
|
paths[candidate.id] = candidate.path;
|
|
26463
26486
|
const config = readCapletFile(candidate.path);
|
|
26464
26487
|
if (isPlainObject$5(config) && config.backend === "openapi") {
|
|
@@ -26473,6 +26496,9 @@ function loadCapletFilesWithPaths(root) {
|
|
|
26473
26496
|
} else if (isPlainObject$5(config) && config.backend === "cli") {
|
|
26474
26497
|
const { backend: _backend, ...endpoint } = config;
|
|
26475
26498
|
cliTools[candidate.id] = endpoint;
|
|
26499
|
+
} else if (isPlainObject$5(config) && config.backend === "caplets") {
|
|
26500
|
+
const { backend: _backend, ...endpoint } = config;
|
|
26501
|
+
capletSets[candidate.id] = endpoint;
|
|
26476
26502
|
} else servers[candidate.id] = config;
|
|
26477
26503
|
}
|
|
26478
26504
|
const hasServers = Object.keys(servers).length > 0;
|
|
@@ -26480,13 +26506,15 @@ function loadCapletFilesWithPaths(root) {
|
|
|
26480
26506
|
const hasGraphQl = Object.keys(graphqlEndpoints).length > 0;
|
|
26481
26507
|
const hasHttpApis = Object.keys(httpApis).length > 0;
|
|
26482
26508
|
const hasCliTools = Object.keys(cliTools).length > 0;
|
|
26483
|
-
|
|
26509
|
+
const hasCapletSets = Object.keys(capletSets).length > 0;
|
|
26510
|
+
return hasServers || hasOpenApi || hasGraphQl || hasHttpApis || hasCliTools || hasCapletSets ? {
|
|
26484
26511
|
config: {
|
|
26485
26512
|
...hasServers ? { mcpServers: servers } : {},
|
|
26486
26513
|
...hasOpenApi ? { openapiEndpoints } : {},
|
|
26487
26514
|
...hasGraphQl ? { graphqlEndpoints } : {},
|
|
26488
26515
|
...hasHttpApis ? { httpApis } : {},
|
|
26489
|
-
...hasCliTools ? { cliTools } : {}
|
|
26516
|
+
...hasCliTools ? { cliTools } : {},
|
|
26517
|
+
...hasCapletSets ? { capletSets } : {}
|
|
26490
26518
|
},
|
|
26491
26519
|
paths
|
|
26492
26520
|
} : void 0;
|
|
@@ -26564,6 +26592,16 @@ function capletToServerConfig(frontmatter, body, baseDir) {
|
|
|
26564
26592
|
...frontmatter.tags ? { tags: frontmatter.tags } : {},
|
|
26565
26593
|
body
|
|
26566
26594
|
};
|
|
26595
|
+
if (frontmatter.capletSet) return {
|
|
26596
|
+
...frontmatter.capletSet,
|
|
26597
|
+
configPath: normalizeLocalPath$1(frontmatter.capletSet.configPath, baseDir),
|
|
26598
|
+
capletsRoot: normalizeLocalPath$1(frontmatter.capletSet.capletsRoot, baseDir),
|
|
26599
|
+
backend: "caplets",
|
|
26600
|
+
name: frontmatter.name,
|
|
26601
|
+
description: frontmatter.description,
|
|
26602
|
+
...frontmatter.tags ? { tags: frontmatter.tags } : {},
|
|
26603
|
+
body
|
|
26604
|
+
};
|
|
26567
26605
|
return {
|
|
26568
26606
|
...frontmatter.mcpServer,
|
|
26569
26607
|
name: frontmatter.name,
|
|
@@ -26884,7 +26922,29 @@ const publicCliToolsSchema = object({
|
|
|
26884
26922
|
disabled: boolean().default(false).describe("When true, omit this CLI tools Caplet.")
|
|
26885
26923
|
}).strict();
|
|
26886
26924
|
const normalizedCliToolsSchema = publicCliToolsSchema.extend({ body: string().optional() });
|
|
26887
|
-
|
|
26925
|
+
const publicCapletSetSchema = object({
|
|
26926
|
+
name: string().trim().min(1).max(80).describe("Human-readable Caplet set display name."),
|
|
26927
|
+
description: string().describe("Capability description shown before child Caplets are disclosed.").refine((value) => value.trim().length >= 10, "description must contain at least 10 non-whitespace characters").refine((value) => value.length <= 1500, "description must be at most 1500 characters"),
|
|
26928
|
+
configPath: string().min(1).optional().describe("Child Caplets config.json path."),
|
|
26929
|
+
capletsRoot: string().min(1).optional().describe("Child Markdown Caplets root directory."),
|
|
26930
|
+
defaultSearchLimit: number$1().int().positive().default(20).describe("Default maximum number of child Caplet search results."),
|
|
26931
|
+
maxSearchLimit: number$1().int().positive().max(50).default(50).describe("Maximum accepted child Caplet search result limit."),
|
|
26932
|
+
toolCacheTtlMs: number$1().int().nonnegative().default(3e4).describe("Milliseconds child Caplet metadata stays fresh. Set 0 to refresh every time."),
|
|
26933
|
+
tags: array(string().trim().min(1).max(80)).optional(),
|
|
26934
|
+
disabled: boolean().default(false).describe("When true, omit this Caplet set.")
|
|
26935
|
+
}).strict().superRefine((set, ctx) => {
|
|
26936
|
+
if (!set.configPath && !set.capletsRoot) ctx.addIssue({
|
|
26937
|
+
code: "custom",
|
|
26938
|
+
message: "Caplet set must define at least one source: configPath or capletsRoot"
|
|
26939
|
+
});
|
|
26940
|
+
if (set.defaultSearchLimit > set.maxSearchLimit) ctx.addIssue({
|
|
26941
|
+
code: "custom",
|
|
26942
|
+
path: ["defaultSearchLimit"],
|
|
26943
|
+
message: "defaultSearchLimit must be <= maxSearchLimit"
|
|
26944
|
+
});
|
|
26945
|
+
});
|
|
26946
|
+
const normalizedCapletSetSchema = publicCapletSetSchema.extend({ body: string().optional() });
|
|
26947
|
+
function configSchemaFor(serverValueSchema, openApiEndpointValueSchema, graphQlEndpointValueSchema, httpApiValueSchema, cliToolsValueSchema, capletSetValueSchema) {
|
|
26888
26948
|
return object({
|
|
26889
26949
|
$schema: string().url().optional().describe("Optional JSON Schema URL for editor validation."),
|
|
26890
26950
|
version: literal(1).default(1).describe("Caplets config schema version."),
|
|
@@ -26894,7 +26954,8 @@ function configSchemaFor(serverValueSchema, openApiEndpointValueSchema, graphQlE
|
|
|
26894
26954
|
openapiEndpoints: record(string().regex(SERVER_ID_PATTERN), openApiEndpointValueSchema).default({}).describe("OpenAPI endpoints keyed by stable Caplet ID."),
|
|
26895
26955
|
graphqlEndpoints: record(string().regex(SERVER_ID_PATTERN), graphQlEndpointValueSchema).default({}).describe("GraphQL endpoints keyed by stable Caplet ID."),
|
|
26896
26956
|
httpApis: record(string().regex(SERVER_ID_PATTERN), httpApiValueSchema).default({}).describe("HTTP APIs keyed by stable Caplet ID."),
|
|
26897
|
-
cliTools: record(string().regex(SERVER_ID_PATTERN), cliToolsValueSchema).default({}).describe("CLI tools keyed by stable Caplet ID.")
|
|
26957
|
+
cliTools: record(string().regex(SERVER_ID_PATTERN), cliToolsValueSchema).default({}).describe("CLI tools keyed by stable Caplet ID."),
|
|
26958
|
+
capletSets: record(string().regex(SERVER_ID_PATTERN), capletSetValueSchema).default({}).describe("Nested Caplet collections keyed by stable Caplet ID.")
|
|
26898
26959
|
}).strict().superRefine((config, ctx) => {
|
|
26899
26960
|
if (config.defaultSearchLimit > config.maxSearchLimit) ctx.addIssue({
|
|
26900
26961
|
code: "custom",
|
|
@@ -27107,10 +27168,29 @@ function configSchemaFor(serverValueSchema, openApiEndpointValueSchema, graphQlE
|
|
|
27107
27168
|
message: "CLI action ID must match ^[a-zA-Z0-9_-]{1,64}$"
|
|
27108
27169
|
});
|
|
27109
27170
|
}
|
|
27171
|
+
for (const [server, rawValue] of Object.entries(config.capletSets)) {
|
|
27172
|
+
const raw = rawValue;
|
|
27173
|
+
const duplicateBackend = config.mcpServers[server] ? "mcpServers" : config.openapiEndpoints[server] ? "openapiEndpoints" : config.graphqlEndpoints[server] ? "graphqlEndpoints" : config.httpApis[server] ? "httpApis" : config.cliTools[server] ? "cliTools" : void 0;
|
|
27174
|
+
if (duplicateBackend) ctx.addIssue({
|
|
27175
|
+
code: "custom",
|
|
27176
|
+
path: ["capletSets", server],
|
|
27177
|
+
message: `Caplet ID ${server} is already used by ${duplicateBackend}`
|
|
27178
|
+
});
|
|
27179
|
+
if (!SERVER_ID_PATTERN.test(server)) ctx.addIssue({
|
|
27180
|
+
code: "custom",
|
|
27181
|
+
path: ["capletSets", server],
|
|
27182
|
+
message: "Caplet set ID must match ^[a-zA-Z0-9_-]{1,64}$"
|
|
27183
|
+
});
|
|
27184
|
+
if (!raw.configPath && !raw.capletsRoot) ctx.addIssue({
|
|
27185
|
+
code: "custom",
|
|
27186
|
+
path: ["capletSets", server],
|
|
27187
|
+
message: "Caplet set must define at least one source: configPath or capletsRoot"
|
|
27188
|
+
});
|
|
27189
|
+
}
|
|
27110
27190
|
});
|
|
27111
27191
|
}
|
|
27112
|
-
const configFileSchema = configSchemaFor(publicServerSchema, publicOpenApiEndpointSchema, publicGraphQlEndpointSchema, publicHttpApiSchema, publicCliToolsSchema);
|
|
27113
|
-
const normalizedConfigFileSchema = configSchemaFor(normalizedServerSchema, normalizedOpenApiEndpointSchema, normalizedGraphQlEndpointSchema, normalizedHttpApiSchema, normalizedCliToolsSchema);
|
|
27192
|
+
const configFileSchema = configSchemaFor(publicServerSchema, publicOpenApiEndpointSchema, publicGraphQlEndpointSchema, publicHttpApiSchema, publicCliToolsSchema, publicCapletSetSchema);
|
|
27193
|
+
const normalizedConfigFileSchema = configSchemaFor(normalizedServerSchema, normalizedOpenApiEndpointSchema, normalizedGraphQlEndpointSchema, normalizedHttpApiSchema, normalizedCliToolsSchema, normalizedCapletSetSchema);
|
|
27114
27194
|
function loadConfig(path = resolveConfigPath(), projectPath = resolveProjectConfigPath()) {
|
|
27115
27195
|
return loadConfigWithSources(path, projectPath).config;
|
|
27116
27196
|
}
|
|
@@ -27150,7 +27230,7 @@ function loadConfigWithSources(path = resolveConfigPath(), projectPath = resolve
|
|
|
27150
27230
|
}
|
|
27151
27231
|
} : void 0);
|
|
27152
27232
|
const config = parseConfig(input);
|
|
27153
|
-
if (Object.keys(config.mcpServers).length === 0 && Object.keys(config.openapiEndpoints).length === 0 && Object.keys(config.graphqlEndpoints).length === 0 && Object.keys(config.httpApis).length === 0 && Object.keys(config.cliTools).length === 0) throw new CapletsError("CONFIG_INVALID", "Caplets config must define at least one MCP server, OpenAPI endpoint, GraphQL endpoint, HTTP API,
|
|
27233
|
+
if (Object.keys(config.mcpServers).length === 0 && Object.keys(config.openapiEndpoints).length === 0 && Object.keys(config.graphqlEndpoints).length === 0 && Object.keys(config.httpApis).length === 0 && Object.keys(config.cliTools).length === 0 && Object.keys(config.capletSets).length === 0) throw new CapletsError("CONFIG_INVALID", "Caplets config must define at least one MCP server, OpenAPI endpoint, GraphQL endpoint, HTTP API, CLI tools backend, or Caplet set");
|
|
27154
27234
|
return {
|
|
27155
27235
|
config,
|
|
27156
27236
|
sources,
|
|
@@ -27161,6 +27241,19 @@ function loadConfigWithSources(path = resolveConfigPath(), projectPath = resolve
|
|
|
27161
27241
|
throw new CapletsError("CONFIG_INVALID", "Caplets config is not valid JSON", redactSecrets(error));
|
|
27162
27242
|
}
|
|
27163
27243
|
}
|
|
27244
|
+
function loadIsolatedConfig(options) {
|
|
27245
|
+
if (!options.configPath && !options.capletsRoot) throw new CapletsError("CONFIG_INVALID", "Nested Caplet set must define at least one source: configPath or capletsRoot");
|
|
27246
|
+
const configInput = options.configPath ? readPublicConfigInput(options.configPath) : void 0;
|
|
27247
|
+
const capletInput = options.capletsRoot ? loadCapletFiles(options.capletsRoot) : void 0;
|
|
27248
|
+
if (!configInput && !capletInput) throw new CapletsError("CONFIG_NOT_FOUND", `Nested Caplet set sources not found: ${[options.configPath, options.capletsRoot].filter(Boolean).join(", ")}`);
|
|
27249
|
+
const config = parseConfig(mergeConfigInputs(configInput, capletInput, {
|
|
27250
|
+
version: 1,
|
|
27251
|
+
defaultSearchLimit: options.defaultSearchLimit,
|
|
27252
|
+
maxSearchLimit: options.maxSearchLimit
|
|
27253
|
+
}));
|
|
27254
|
+
if (Object.keys(config.mcpServers).length === 0 && Object.keys(config.openapiEndpoints).length === 0 && Object.keys(config.graphqlEndpoints).length === 0 && Object.keys(config.httpApis).length === 0 && Object.keys(config.cliTools).length === 0 && Object.keys(config.capletSets).length === 0) throw new CapletsError("CONFIG_INVALID", "Nested Caplet set must define at least one Caplet");
|
|
27255
|
+
return config;
|
|
27256
|
+
}
|
|
27164
27257
|
function resolveProjectCapletsRootForConfigPath(projectPath) {
|
|
27165
27258
|
const root = dirname(projectPath);
|
|
27166
27259
|
return basename(root) === ".caplets" && basename(projectPath) === "config.json" ? root : void 0;
|
|
@@ -27181,7 +27274,8 @@ function normalizeLocalPaths(input, baseDir) {
|
|
|
27181
27274
|
...input,
|
|
27182
27275
|
openapiEndpoints: normalizeEndpointPaths(input.openapiEndpoints, baseDir, normalizeOpenApiPath),
|
|
27183
27276
|
graphqlEndpoints: normalizeEndpointPaths(input.graphqlEndpoints, baseDir, normalizeGraphQlPath),
|
|
27184
|
-
cliTools: normalizeEndpointPaths(input.cliTools, baseDir, normalizeCliToolsPaths)
|
|
27277
|
+
cliTools: normalizeEndpointPaths(input.cliTools, baseDir, normalizeCliToolsPaths),
|
|
27278
|
+
capletSets: normalizeEndpointPaths(input.capletSets, baseDir, normalizeCapletSetPaths)
|
|
27185
27279
|
});
|
|
27186
27280
|
}
|
|
27187
27281
|
function normalizeEndpointPaths(endpoints, baseDir, normalize) {
|
|
@@ -27216,6 +27310,13 @@ function normalizeCliToolsPaths(endpoint, baseDir) {
|
|
|
27216
27310
|
actions
|
|
27217
27311
|
};
|
|
27218
27312
|
}
|
|
27313
|
+
function normalizeCapletSetPaths(endpoint, baseDir) {
|
|
27314
|
+
return {
|
|
27315
|
+
...endpoint,
|
|
27316
|
+
configPath: normalizeLocalPath(endpoint.configPath, baseDir),
|
|
27317
|
+
capletsRoot: normalizeLocalPath(endpoint.capletsRoot, baseDir)
|
|
27318
|
+
};
|
|
27319
|
+
}
|
|
27219
27320
|
function normalizeLocalPath(value, baseDir) {
|
|
27220
27321
|
if (typeof value !== "string" || !value || isAbsolute(value) || hasEnvReference(value)) return value;
|
|
27221
27322
|
return join(baseDir, value);
|
|
@@ -27225,6 +27326,7 @@ function rejectProjectConfigExecutableBackendMaps(input, path) {
|
|
|
27225
27326
|
if (input.graphqlEndpoints && Object.keys(input.graphqlEndpoints).length > 0) throw new CapletsError("CONFIG_INVALID", `Project config at ${path} cannot define executable backend map graphqlEndpoints; use project Markdown Caplet files or user config instead`);
|
|
27226
27327
|
if (input.httpApis && Object.keys(input.httpApis).length > 0) throw new CapletsError("CONFIG_INVALID", `Project config at ${path} cannot define executable backend map httpApis; use project Markdown Caplet files or user config instead`);
|
|
27227
27328
|
if (input.cliTools && Object.keys(input.cliTools).length > 0) throw new CapletsError("CONFIG_INVALID", `Project config at ${path} cannot define executable backend map cliTools; use project Markdown Caplet files or user config instead`);
|
|
27329
|
+
if (input.capletSets && Object.keys(input.capletSets).length > 0) throw new CapletsError("CONFIG_INVALID", `Project config at ${path} cannot define executable backend map capletSets; use project Markdown Caplet files or user config instead`);
|
|
27228
27330
|
return input;
|
|
27229
27331
|
}
|
|
27230
27332
|
function mergeConfigInputs(...inputs) {
|
|
@@ -27253,6 +27355,10 @@ function mergeConfigInputs(...inputs) {
|
|
|
27253
27355
|
cliTools: {
|
|
27254
27356
|
...merged?.cliTools,
|
|
27255
27357
|
...input.cliTools
|
|
27358
|
+
},
|
|
27359
|
+
capletSets: {
|
|
27360
|
+
...merged?.capletSets,
|
|
27361
|
+
...input.capletSets
|
|
27256
27362
|
}
|
|
27257
27363
|
};
|
|
27258
27364
|
}
|
|
@@ -27284,13 +27390,15 @@ function removeCapletId(input, id) {
|
|
|
27284
27390
|
const { [id]: _graphqlEndpoint, ...graphqlEndpoints } = input.graphqlEndpoints ?? {};
|
|
27285
27391
|
const { [id]: _httpApi, ...httpApis } = input.httpApis ?? {};
|
|
27286
27392
|
const { [id]: _cliTools, ...cliTools } = input.cliTools ?? {};
|
|
27393
|
+
const { [id]: _capletSet, ...capletSets } = input.capletSets ?? {};
|
|
27287
27394
|
return {
|
|
27288
27395
|
...input,
|
|
27289
27396
|
mcpServers,
|
|
27290
27397
|
openapiEndpoints,
|
|
27291
27398
|
graphqlEndpoints,
|
|
27292
27399
|
httpApis,
|
|
27293
|
-
cliTools
|
|
27400
|
+
cliTools,
|
|
27401
|
+
capletSets
|
|
27294
27402
|
};
|
|
27295
27403
|
}
|
|
27296
27404
|
function capletIds(input) {
|
|
@@ -27299,7 +27407,8 @@ function capletIds(input) {
|
|
|
27299
27407
|
...Object.keys(input.openapiEndpoints ?? {}),
|
|
27300
27408
|
...Object.keys(input.graphqlEndpoints ?? {}),
|
|
27301
27409
|
...Object.keys(input.httpApis ?? {}),
|
|
27302
|
-
...Object.keys(input.cliTools ?? {})
|
|
27410
|
+
...Object.keys(input.cliTools ?? {}),
|
|
27411
|
+
...Object.keys(input.capletSets ?? {})
|
|
27303
27412
|
];
|
|
27304
27413
|
}
|
|
27305
27414
|
function sourceForId(source, id) {
|
|
@@ -27345,6 +27454,12 @@ function parseConfig(input) {
|
|
|
27345
27454
|
server,
|
|
27346
27455
|
backend: "cli"
|
|
27347
27456
|
});
|
|
27457
|
+
const capletSets = {};
|
|
27458
|
+
for (const [server, raw] of Object.entries(parsed.data.capletSets)) capletSets[server] = stripUndefined$1({
|
|
27459
|
+
...raw,
|
|
27460
|
+
server,
|
|
27461
|
+
backend: "caplets"
|
|
27462
|
+
});
|
|
27348
27463
|
return {
|
|
27349
27464
|
version: parsed.data.version,
|
|
27350
27465
|
options: {
|
|
@@ -27355,7 +27470,8 @@ function parseConfig(input) {
|
|
|
27355
27470
|
openapiEndpoints,
|
|
27356
27471
|
graphqlEndpoints,
|
|
27357
27472
|
httpApis,
|
|
27358
|
-
cliTools
|
|
27473
|
+
cliTools,
|
|
27474
|
+
capletSets
|
|
27359
27475
|
};
|
|
27360
27476
|
}
|
|
27361
27477
|
function validateEndpointAuthHeaders(auth, ctx, path) {
|
|
@@ -27384,7 +27500,7 @@ function interpolateConfig(value, path = []) {
|
|
|
27384
27500
|
return value;
|
|
27385
27501
|
}
|
|
27386
27502
|
function isPublicMetadataPath(path) {
|
|
27387
|
-
if (path.length < 3 || path[0] !== "mcpServers" && path[0] !== "openapiEndpoints" && path[0] !== "graphqlEndpoints" && path[0] !== "httpApis" && path[0] !== "cliTools") return false;
|
|
27503
|
+
if (path.length < 3 || path[0] !== "mcpServers" && path[0] !== "openapiEndpoints" && path[0] !== "graphqlEndpoints" && path[0] !== "httpApis" && path[0] !== "cliTools" && path[0] !== "capletSets") return false;
|
|
27388
27504
|
return NON_INTERPOLATED_SERVER_FIELDS.has(path[2] ?? "");
|
|
27389
27505
|
}
|
|
27390
27506
|
function isPlainObject$4(value) {
|
|
@@ -56973,7 +57089,7 @@ function openApiCacheKey(endpoint) {
|
|
|
56973
57089
|
//#endregion
|
|
56974
57090
|
//#region src/capability-description.mjs
|
|
56975
57091
|
function capabilityDescription(server) {
|
|
56976
|
-
const backendName = server.backend === "mcp" ? "MCP server" : server.backend === "openapi" ? "OpenAPI endpoint" : server.backend === "graphql" ? "GraphQL endpoint" : server.backend === "http" ? "HTTP API" : "CLI tools";
|
|
57092
|
+
const backendName = server.backend === "mcp" ? "MCP server" : server.backend === "openapi" ? "OpenAPI endpoint" : server.backend === "graphql" ? "GraphQL endpoint" : server.backend === "http" ? "HTTP API" : server.backend === "cli" ? "CLI tools" : server.backend === "caplets" ? "nested Caplets" : "backend";
|
|
56977
57093
|
const checkOperation = server.backend === "mcp" ? "check_mcp_server" : "check_backend";
|
|
56978
57094
|
const hint = [
|
|
56979
57095
|
`Use this Caplet to inspect and call tools from its ${backendName} backend.`,
|
|
@@ -57003,7 +57119,7 @@ var ServerRegistry = class {
|
|
|
57003
57119
|
return this.allCaplets().filter((server) => !server.disabled);
|
|
57004
57120
|
}
|
|
57005
57121
|
get(serverId) {
|
|
57006
|
-
const server = this.config.mcpServers[serverId] ?? this.config.openapiEndpoints[serverId] ?? this.config.graphqlEndpoints[serverId] ?? this.config.httpApis[serverId] ?? this.config.cliTools[serverId];
|
|
57122
|
+
const server = this.config.mcpServers[serverId] ?? this.config.openapiEndpoints[serverId] ?? this.config.graphqlEndpoints[serverId] ?? this.config.httpApis[serverId] ?? this.config.cliTools[serverId] ?? this.config.capletSets[serverId];
|
|
57007
57123
|
return server?.disabled ? void 0 : server;
|
|
57008
57124
|
}
|
|
57009
57125
|
require(serverId) {
|
|
@@ -57055,7 +57171,8 @@ var ServerRegistry = class {
|
|
|
57055
57171
|
...Object.values(this.config.openapiEndpoints),
|
|
57056
57172
|
...Object.values(this.config.graphqlEndpoints),
|
|
57057
57173
|
...Object.values(this.config.httpApis),
|
|
57058
|
-
...Object.values(this.config.cliTools)
|
|
57174
|
+
...Object.values(this.config.cliTools),
|
|
57175
|
+
...Object.values(this.config.capletSets)
|
|
57059
57176
|
];
|
|
57060
57177
|
}
|
|
57061
57178
|
};
|
|
@@ -57088,6 +57205,12 @@ function backendDetail(server) {
|
|
|
57088
57205
|
maxOutputBytes: server.maxOutputBytes,
|
|
57089
57206
|
configuredActions: Object.keys(server.actions).length
|
|
57090
57207
|
};
|
|
57208
|
+
if (server.backend === "caplets") return {
|
|
57209
|
+
type: "caplets",
|
|
57210
|
+
disabled: server.disabled,
|
|
57211
|
+
source: capletSetSource(server),
|
|
57212
|
+
toolCacheTtlMs: server.toolCacheTtlMs
|
|
57213
|
+
};
|
|
57091
57214
|
return {
|
|
57092
57215
|
type: "mcp",
|
|
57093
57216
|
transport: server.transport,
|
|
@@ -57097,6 +57220,9 @@ function backendDetail(server) {
|
|
|
57097
57220
|
toolCacheTtlMs: server.toolCacheTtlMs
|
|
57098
57221
|
};
|
|
57099
57222
|
}
|
|
57223
|
+
function capletSetSource(server) {
|
|
57224
|
+
return server.configPath && server.capletsRoot ? "both" : server.configPath ? "configPath" : "capletsRoot";
|
|
57225
|
+
}
|
|
57100
57226
|
function graphQlSource(server) {
|
|
57101
57227
|
if (server.schemaPath) return "schemaPath";
|
|
57102
57228
|
if (server.schemaUrl) return "schemaUrl";
|
|
@@ -57213,16 +57339,16 @@ const generatedToolInputSchema = object({
|
|
|
57213
57339
|
arguments: record(string(), unknown()).optional().describe(generatedToolInputDescriptions.arguments),
|
|
57214
57340
|
fields: array(string().min(1)).min(1).optional().describe(generatedToolInputDescriptions.fields)
|
|
57215
57341
|
}).strict();
|
|
57216
|
-
async function handleServerTool(server, request, registry, downstream, openapi, graphql, http, cli) {
|
|
57342
|
+
async function handleServerTool(server, request, registry, downstream, openapi, graphql, http, cli, caplets) {
|
|
57217
57343
|
const parsed = validateOperationRequest(request, registry.config.options.maxSearchLimit);
|
|
57218
57344
|
switch (parsed.operation) {
|
|
57219
57345
|
case "get_caplet": return jsonResult(registry.detail(server));
|
|
57220
|
-
case "check_backend": return jsonResult(await backendFor(server, downstream, openapi, graphql, http, cli).check(server));
|
|
57346
|
+
case "check_backend": return jsonResult(await backendFor(server, downstream, openapi, graphql, http, cli, caplets).check(server));
|
|
57221
57347
|
case "check_mcp_server":
|
|
57222
57348
|
if (server.backend !== "mcp") throw new CapletsError("REQUEST_INVALID", "check_mcp_server is only valid for MCP-backed Caplets; use check_backend");
|
|
57223
57349
|
return jsonResult(await downstream.checkServer(server));
|
|
57224
57350
|
case "list_tools": {
|
|
57225
|
-
const backend = backendFor(server, downstream, openapi, graphql, http, cli);
|
|
57351
|
+
const backend = backendFor(server, downstream, openapi, graphql, http, cli, caplets);
|
|
57226
57352
|
const tools = await backend.listTools(server);
|
|
57227
57353
|
return jsonResult({
|
|
57228
57354
|
server: server.server,
|
|
@@ -57230,7 +57356,7 @@ async function handleServerTool(server, request, registry, downstream, openapi,
|
|
|
57230
57356
|
});
|
|
57231
57357
|
}
|
|
57232
57358
|
case "search_tools": {
|
|
57233
|
-
const backend = backendFor(server, downstream, openapi, graphql, http, cli);
|
|
57359
|
+
const backend = backendFor(server, downstream, openapi, graphql, http, cli, caplets);
|
|
57234
57360
|
const tools = await backend.listTools(server);
|
|
57235
57361
|
const limit = parsed.limit ?? registry.config.options.defaultSearchLimit;
|
|
57236
57362
|
return jsonResult({
|
|
@@ -57240,14 +57366,14 @@ async function handleServerTool(server, request, registry, downstream, openapi,
|
|
|
57240
57366
|
});
|
|
57241
57367
|
}
|
|
57242
57368
|
case "get_tool": {
|
|
57243
|
-
const tool = await backendFor(server, downstream, openapi, graphql, http, cli).getTool(server, parsed.tool);
|
|
57369
|
+
const tool = await backendFor(server, downstream, openapi, graphql, http, cli, caplets).getTool(server, parsed.tool);
|
|
57244
57370
|
return jsonResult({
|
|
57245
57371
|
server: server.server,
|
|
57246
57372
|
tool
|
|
57247
57373
|
});
|
|
57248
57374
|
}
|
|
57249
57375
|
case "call_tool": {
|
|
57250
|
-
const backend = backendFor(server, downstream, openapi, graphql, http, cli);
|
|
57376
|
+
const backend = backendFor(server, downstream, openapi, graphql, http, cli, caplets);
|
|
57251
57377
|
if (parsed.fields === void 0) return backend.callTool(server, parsed.tool, parsed.arguments);
|
|
57252
57378
|
if (server.backend === "graphql") throw new CapletsError("REQUEST_INVALID", "call_tool.fields is not supported for GraphQL-backed Caplets; select fields in the GraphQL operation document instead");
|
|
57253
57379
|
const tool = await backend.getTool(server, parsed.tool);
|
|
@@ -57340,7 +57466,7 @@ function projectCallToolResult(result, outputSchema, fields) {
|
|
|
57340
57466
|
function isPlainObject(value) {
|
|
57341
57467
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
57342
57468
|
}
|
|
57343
|
-
function backendFor(server, downstream, openapi, graphql, http, cli) {
|
|
57469
|
+
function backendFor(server, downstream, openapi, graphql, http, cli, caplets) {
|
|
57344
57470
|
if (server.backend === "mcp") return {
|
|
57345
57471
|
check: (...args) => downstream.checkServer(...args),
|
|
57346
57472
|
listTools: (...args) => downstream.listTools(...args),
|
|
@@ -57382,6 +57508,17 @@ function backendFor(server, downstream, openapi, graphql, http, cli) {
|
|
|
57382
57508
|
search: (...args) => cli.search(...args)
|
|
57383
57509
|
};
|
|
57384
57510
|
}
|
|
57511
|
+
if (server.backend === "caplets") {
|
|
57512
|
+
if (!caplets) throw new CapletsError("INTERNAL_ERROR", "Caplet set manager is not configured");
|
|
57513
|
+
return {
|
|
57514
|
+
check: (...args) => caplets.checkSet(...args),
|
|
57515
|
+
listTools: (...args) => caplets.listTools(...args),
|
|
57516
|
+
getTool: (...args) => caplets.getTool(...args),
|
|
57517
|
+
callTool: (...args) => caplets.callTool(...args),
|
|
57518
|
+
compact: (...args) => caplets.compact(...args),
|
|
57519
|
+
search: (...args) => caplets.search(...args)
|
|
57520
|
+
};
|
|
57521
|
+
}
|
|
57385
57522
|
if (!openapi) throw new CapletsError("INTERNAL_ERROR", "OpenAPI manager is not configured");
|
|
57386
57523
|
return {
|
|
57387
57524
|
check: (...args) => openapi.checkEndpoint(...args),
|
|
@@ -57393,6 +57530,174 @@ function backendFor(server, downstream, openapi, graphql, http, cli) {
|
|
|
57393
57530
|
};
|
|
57394
57531
|
}
|
|
57395
57532
|
//#endregion
|
|
57533
|
+
//#region src/caplet-sets.ts
|
|
57534
|
+
var CapletSetManager = class CapletSetManager {
|
|
57535
|
+
registry;
|
|
57536
|
+
options;
|
|
57537
|
+
children = /* @__PURE__ */ new Map();
|
|
57538
|
+
childRefreshLocks = /* @__PURE__ */ new Map();
|
|
57539
|
+
constructor(registry, options = {}) {
|
|
57540
|
+
this.registry = registry;
|
|
57541
|
+
this.options = options;
|
|
57542
|
+
}
|
|
57543
|
+
updateRegistry(registry) {
|
|
57544
|
+
this.registry = registry;
|
|
57545
|
+
}
|
|
57546
|
+
invalidate(serverId) {
|
|
57547
|
+
const pending = this.childRefreshLocks.get(serverId);
|
|
57548
|
+
if (pending) {
|
|
57549
|
+
pending.then(() => this.closeChild(serverId), () => this.closeChild(serverId));
|
|
57550
|
+
return;
|
|
57551
|
+
}
|
|
57552
|
+
this.closeChild(serverId);
|
|
57553
|
+
}
|
|
57554
|
+
async close() {
|
|
57555
|
+
await Promise.allSettled(this.childRefreshLocks.values());
|
|
57556
|
+
await Promise.allSettled([...this.children.keys()].map((serverId) => this.closeChild(serverId)));
|
|
57557
|
+
}
|
|
57558
|
+
async checkSet(config) {
|
|
57559
|
+
const startedAt = Date.now();
|
|
57560
|
+
try {
|
|
57561
|
+
const childCaplets = (await this.childRuntime(config, true)).registry.enabledServers();
|
|
57562
|
+
this.registry.setStatus(config.server, "available");
|
|
57563
|
+
return {
|
|
57564
|
+
server: config.server,
|
|
57565
|
+
status: "available",
|
|
57566
|
+
toolCount: childCaplets.length,
|
|
57567
|
+
elapsedMs: Date.now() - startedAt
|
|
57568
|
+
};
|
|
57569
|
+
} catch (error) {
|
|
57570
|
+
const safe = toSafeError(error, "SERVER_UNAVAILABLE");
|
|
57571
|
+
this.registry.setStatus(config.server, "unavailable", safe);
|
|
57572
|
+
return {
|
|
57573
|
+
server: config.server,
|
|
57574
|
+
status: "unavailable",
|
|
57575
|
+
elapsedMs: Date.now() - startedAt,
|
|
57576
|
+
error: safe
|
|
57577
|
+
};
|
|
57578
|
+
}
|
|
57579
|
+
}
|
|
57580
|
+
async listTools(config) {
|
|
57581
|
+
return (await this.childRuntime(config, false)).registry.enabledServers().map((caplet) => this.toTool(caplet));
|
|
57582
|
+
}
|
|
57583
|
+
async getTool(config, toolName) {
|
|
57584
|
+
const child = await this.childRuntime(config, false);
|
|
57585
|
+
const caplet = child.registry.get(toolName);
|
|
57586
|
+
if (!caplet) throw new CapletsError("TOOL_NOT_FOUND", `Tool ${toolName} was not found on ${config.server}`, {
|
|
57587
|
+
server: config.server,
|
|
57588
|
+
tool: toolName,
|
|
57589
|
+
suggestions: nearbyCapletNames(child.registry.enabledServers(), toolName)
|
|
57590
|
+
});
|
|
57591
|
+
return this.toTool(caplet);
|
|
57592
|
+
}
|
|
57593
|
+
async callTool(config, toolName, args) {
|
|
57594
|
+
const child = await this.childRuntime(config, false);
|
|
57595
|
+
const caplet = child.registry.get(toolName);
|
|
57596
|
+
if (!caplet) throw new CapletsError("TOOL_NOT_FOUND", `Tool ${toolName} was not found on ${config.server}`, {
|
|
57597
|
+
server: config.server,
|
|
57598
|
+
tool: toolName,
|
|
57599
|
+
suggestions: nearbyCapletNames(child.registry.enabledServers(), toolName)
|
|
57600
|
+
});
|
|
57601
|
+
try {
|
|
57602
|
+
return await handleServerTool(caplet, args, child.registry, child.downstream, child.openapi, child.graphql, child.http, child.cli, child.capletSets);
|
|
57603
|
+
} catch (error) {
|
|
57604
|
+
return errorResult(error);
|
|
57605
|
+
}
|
|
57606
|
+
}
|
|
57607
|
+
compact(config, tool) {
|
|
57608
|
+
return {
|
|
57609
|
+
server: config.server,
|
|
57610
|
+
tool: tool.name,
|
|
57611
|
+
...tool.description ? { description: tool.description } : {},
|
|
57612
|
+
...tool.annotations ? { annotations: tool.annotations } : {},
|
|
57613
|
+
hasInputSchema: Boolean(tool.inputSchema),
|
|
57614
|
+
hasOutputSchema: Boolean(tool.outputSchema)
|
|
57615
|
+
};
|
|
57616
|
+
}
|
|
57617
|
+
search(config, tools, query, limit) {
|
|
57618
|
+
const needle = query.toLocaleLowerCase();
|
|
57619
|
+
return tools.filter((tool) => `${tool.name}\n${tool.description ?? ""}`.toLocaleLowerCase().includes(needle)).sort((left, right) => left.name.localeCompare(right.name)).slice(0, limit).map((tool) => this.compact(config, tool));
|
|
57620
|
+
}
|
|
57621
|
+
async childRuntime(config, force) {
|
|
57622
|
+
const pending = this.childRefreshLocks.get(config.server);
|
|
57623
|
+
if (pending) return pending;
|
|
57624
|
+
const refresh = this.loadChildRuntime(config, force).finally(() => {
|
|
57625
|
+
this.childRefreshLocks.delete(config.server);
|
|
57626
|
+
});
|
|
57627
|
+
this.childRefreshLocks.set(config.server, refresh);
|
|
57628
|
+
return await refresh;
|
|
57629
|
+
}
|
|
57630
|
+
async loadChildRuntime(config, force) {
|
|
57631
|
+
const cacheKey = sourceKey(config);
|
|
57632
|
+
const existing = this.children.get(config.server);
|
|
57633
|
+
const now = Date.now();
|
|
57634
|
+
const isFresh = existing && existing.cacheKey === cacheKey && existing.configFingerprint === JSON.stringify(config) && config.toolCacheTtlMs > 0 && now - existing.loadedAt <= config.toolCacheTtlMs;
|
|
57635
|
+
if (existing && !force && isFresh) return existing;
|
|
57636
|
+
const ancestry = this.options.ancestry ?? /* @__PURE__ */ new Set();
|
|
57637
|
+
if (ancestry.has(cacheKey)) throw new CapletsError("CONFIG_INVALID", "Nested Caplet set cycle detected", {
|
|
57638
|
+
server: config.server,
|
|
57639
|
+
source: cacheKey,
|
|
57640
|
+
ancestry: [...ancestry]
|
|
57641
|
+
});
|
|
57642
|
+
let child;
|
|
57643
|
+
try {
|
|
57644
|
+
const registry = new ServerRegistry(loadIsolatedConfig({
|
|
57645
|
+
...config.configPath ? { configPath: config.configPath } : {},
|
|
57646
|
+
...config.capletsRoot ? { capletsRoot: config.capletsRoot } : {},
|
|
57647
|
+
defaultSearchLimit: config.defaultSearchLimit,
|
|
57648
|
+
maxSearchLimit: config.maxSearchLimit
|
|
57649
|
+
}));
|
|
57650
|
+
const authOptions = this.options.authDir ? { authDir: this.options.authDir } : {};
|
|
57651
|
+
const childAncestry = new Set([...ancestry, cacheKey]);
|
|
57652
|
+
child = {
|
|
57653
|
+
registry,
|
|
57654
|
+
downstream: new DownstreamManager(registry, authOptions),
|
|
57655
|
+
openapi: new OpenApiManager(registry, authOptions),
|
|
57656
|
+
graphql: new GraphQLManager(registry, authOptions),
|
|
57657
|
+
http: new HttpActionManager(registry, authOptions),
|
|
57658
|
+
cli: new CliToolsManager(registry),
|
|
57659
|
+
capletSets: new CapletSetManager(registry, {
|
|
57660
|
+
...authOptions,
|
|
57661
|
+
ancestry: childAncestry
|
|
57662
|
+
}),
|
|
57663
|
+
cacheKey,
|
|
57664
|
+
configFingerprint: JSON.stringify(config),
|
|
57665
|
+
loadedAt: now
|
|
57666
|
+
};
|
|
57667
|
+
} catch (error) {
|
|
57668
|
+
if (existing) return existing;
|
|
57669
|
+
throw error;
|
|
57670
|
+
}
|
|
57671
|
+
if (existing) await this.closeChild(config.server);
|
|
57672
|
+
this.children.set(config.server, child);
|
|
57673
|
+
this.registry.setStatus(config.server, "available");
|
|
57674
|
+
return child;
|
|
57675
|
+
}
|
|
57676
|
+
async closeChild(serverId) {
|
|
57677
|
+
const child = this.children.get(serverId);
|
|
57678
|
+
this.children.delete(serverId);
|
|
57679
|
+
if (!child) return;
|
|
57680
|
+
await Promise.allSettled([child.downstream.close(), child.capletSets.close()]);
|
|
57681
|
+
}
|
|
57682
|
+
toTool(caplet) {
|
|
57683
|
+
return {
|
|
57684
|
+
name: caplet.server,
|
|
57685
|
+
description: capabilityDescription(caplet),
|
|
57686
|
+
inputSchema: generatedToolInputJsonSchema()
|
|
57687
|
+
};
|
|
57688
|
+
}
|
|
57689
|
+
};
|
|
57690
|
+
function sourceKey(config) {
|
|
57691
|
+
return JSON.stringify({
|
|
57692
|
+
configPath: config.configPath ? resolve(config.configPath) : void 0,
|
|
57693
|
+
capletsRoot: config.capletsRoot ? resolve(config.capletsRoot) : void 0
|
|
57694
|
+
});
|
|
57695
|
+
}
|
|
57696
|
+
function nearbyCapletNames(caplets, needle) {
|
|
57697
|
+
const lower = needle.toLocaleLowerCase();
|
|
57698
|
+
return caplets.map((caplet) => caplet.server).filter((name) => name.toLocaleLowerCase().includes(lower[0] ?? "")).sort().slice(0, 5);
|
|
57699
|
+
}
|
|
57700
|
+
//#endregion
|
|
57396
57701
|
//#region src/engine.ts
|
|
57397
57702
|
var CapletsEngine = class {
|
|
57398
57703
|
registry;
|
|
@@ -57401,6 +57706,7 @@ var CapletsEngine = class {
|
|
|
57401
57706
|
graphql;
|
|
57402
57707
|
http;
|
|
57403
57708
|
cli;
|
|
57709
|
+
capletSets;
|
|
57404
57710
|
paths;
|
|
57405
57711
|
watchDebounceMs;
|
|
57406
57712
|
watchEnabled;
|
|
@@ -57424,6 +57730,7 @@ var CapletsEngine = class {
|
|
|
57424
57730
|
this.graphql = new GraphQLManager(this.registry, selectAuthOptions(options.authDir));
|
|
57425
57731
|
this.http = new HttpActionManager(this.registry, selectAuthOptions(options.authDir));
|
|
57426
57732
|
this.cli = new CliToolsManager(this.registry);
|
|
57733
|
+
this.capletSets = new CapletSetManager(this.registry, selectAuthOptions(options.authDir));
|
|
57427
57734
|
this.watchDebounceMs = options.watchDebounceMs ?? 250;
|
|
57428
57735
|
this.watchEnabled = options.watch ?? true;
|
|
57429
57736
|
this.writeErr = options.writeErr ?? ((value) => process.stderr.write(value));
|
|
@@ -57465,7 +57772,7 @@ var CapletsEngine = class {
|
|
|
57465
57772
|
}
|
|
57466
57773
|
async execute(serverId, request) {
|
|
57467
57774
|
try {
|
|
57468
|
-
return await handleServerTool(this.registry.require(serverId), request, this.registry, this.downstream, this.openapi, this.graphql, this.http, this.cli);
|
|
57775
|
+
return await handleServerTool(this.registry.require(serverId), request, this.registry, this.downstream, this.openapi, this.graphql, this.http, this.cli, this.capletSets);
|
|
57469
57776
|
} catch (error) {
|
|
57470
57777
|
return errorResult(error);
|
|
57471
57778
|
}
|
|
@@ -57485,6 +57792,7 @@ var CapletsEngine = class {
|
|
|
57485
57792
|
} finally {
|
|
57486
57793
|
this.closeWatchers();
|
|
57487
57794
|
await this.downstream.close();
|
|
57795
|
+
await this.capletSets.close();
|
|
57488
57796
|
this.reloadListeners.clear();
|
|
57489
57797
|
}
|
|
57490
57798
|
}
|
|
@@ -57507,6 +57815,7 @@ var CapletsEngine = class {
|
|
|
57507
57815
|
this.graphql.updateRegistry(nextRegistry);
|
|
57508
57816
|
this.http.updateRegistry(nextRegistry);
|
|
57509
57817
|
this.cli.updateRegistry(nextRegistry);
|
|
57818
|
+
this.capletSets.updateRegistry(nextRegistry);
|
|
57510
57819
|
let invalidated = true;
|
|
57511
57820
|
try {
|
|
57512
57821
|
await this.invalidateChangedBackends(previousConfig, nextConfig);
|
|
@@ -57559,6 +57868,7 @@ var CapletsEngine = class {
|
|
|
57559
57868
|
if (before?.backend === "graphql" || after?.backend === "graphql" || !after) this.graphql.invalidate(serverId);
|
|
57560
57869
|
if (before?.backend === "http" || after?.backend === "http" || !after) this.http.invalidate(serverId);
|
|
57561
57870
|
if (before?.backend === "cli" || after?.backend === "cli" || !after) this.cli.invalidate(serverId);
|
|
57871
|
+
if (before?.backend === "caplets" || after?.backend === "caplets" || !after) this.capletSets.invalidate(serverId);
|
|
57562
57872
|
}
|
|
57563
57873
|
}
|
|
57564
57874
|
resetWatchers() {
|
|
@@ -57651,7 +57961,8 @@ function allCaplets(config) {
|
|
|
57651
57961
|
...Object.values(config.openapiEndpoints),
|
|
57652
57962
|
...Object.values(config.graphqlEndpoints),
|
|
57653
57963
|
...Object.values(config.httpApis),
|
|
57654
|
-
...Object.values(config.cliTools)
|
|
57964
|
+
...Object.values(config.cliTools),
|
|
57965
|
+
...Object.values(config.capletSets)
|
|
57655
57966
|
];
|
|
57656
57967
|
}
|
|
57657
57968
|
function nextEnabledServers(config) {
|
|
@@ -11,7 +11,7 @@ const operations = [
|
|
|
11
11
|
const generatedToolInputDescriptions = {
|
|
12
12
|
operation: [
|
|
13
13
|
"Caplets wrapper operation to perform for this configured Caplet backend.",
|
|
14
|
-
"Use get_caplet to read the full Caplet card, check_backend to check any backend, check_mcp_server to check an MCP backend, list_tools or search_tools to discover downstream tools, get_tool to read a downstream input schema, and call_tool to run one downstream tool, operation, action, or
|
|
14
|
+
"Use get_caplet to read the full Caplet card, check_backend to check any backend, check_mcp_server to check an MCP backend, list_tools or search_tools to discover downstream tools, get_tool to read a downstream input schema, and call_tool to run one downstream tool, operation, action, CLI command, or child Caplet.",
|
|
15
15
|
"For call_tool, pass downstream inputs only inside the top-level \"arguments\" object."
|
|
16
16
|
].join(" "),
|
|
17
17
|
query: "Required only for search_tools. Example: {\"operation\":\"search_tools\",\"query\":\"web search\",\"limit\":5}. Do not use query for call_tool; put downstream query values under arguments.query.",
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as assertCompleteRequestPrompt, A as CallToolRequestSchema, B as InitializeRequestSchema, C as SERVER_ID_PATTERN, D as Protocol, E as AjvJsonSchemaValidator, F as CreateTaskResultSchema, G as ListResourcesRequestSchema, H as LATEST_PROTOCOL_VERSION, I as ElicitResultSchema, J as LoggingLevelSchema, K as ListRootsResultSchema, L as EmptyResultSchema, M as CompleteRequestSchema, N as CreateMessageResultSchema, O as mergeCapabilities, P as CreateMessageResultWithToolsSchema, Q as SetLevelRequestSchema, R as ErrorCode, S as toSafeError, T as assertToolsCallTaskCapability, U as ListPromptsRequestSchema, V as InitializedNotificationSchema, W as ListResourceTemplatesRequestSchema, X as ReadResourceRequestSchema, Y as McpError, Z as SUPPORTED_PROTOCOL_VERSIONS, _ as resolveProjectCapletsRoot, a as capabilityDescription, at as getSchemaDescription, b as validateCapletFile, c as deleteTokenBundle, ct as normalizeObjectSchema, d as loadConfig, dt as safeParseAsync, et as assertCompleteRequestResourceTemplate, f as loadConfigWithSources, ft as __commonJSMin, g as resolveConfigPath, h as resolveCapletsRoot, i as ServerRegistry, it as getParseErrorMessage, j as CallToolResultSchema, k as toJsonSchemaCompat, l as isTokenBundleExpired, lt as objectFromShape, m as DEFAULT_AUTH_DIR, mt as __toESM, n as generatedToolInputSchema, nt as getLiteralValue, o as runGenericOAuthFlow, ot as isSchemaOptional, p as parseConfig, pt as __require, q as ListToolsRequestSchema, r as handleServerTool, rt as getObjectShape, s as runOAuthFlow, st as isZ4Schema, t as CapletsEngine, tt as ZodOptional, u as readTokenBundle, ut as safeParse, v as resolveProjectConfigPath, w as assertClientRequestTaskCapability, x as CapletsError, y as discoverCapletFiles, z as GetPromptRequestSchema } from "./engine-
|
|
1
|
+
import { $ as assertCompleteRequestPrompt, A as CallToolRequestSchema, B as InitializeRequestSchema, C as SERVER_ID_PATTERN, D as Protocol, E as AjvJsonSchemaValidator, F as CreateTaskResultSchema, G as ListResourcesRequestSchema, H as LATEST_PROTOCOL_VERSION, I as ElicitResultSchema, J as LoggingLevelSchema, K as ListRootsResultSchema, L as EmptyResultSchema, M as CompleteRequestSchema, N as CreateMessageResultSchema, O as mergeCapabilities, P as CreateMessageResultWithToolsSchema, Q as SetLevelRequestSchema, R as ErrorCode, S as toSafeError, T as assertToolsCallTaskCapability, U as ListPromptsRequestSchema, V as InitializedNotificationSchema, W as ListResourceTemplatesRequestSchema, X as ReadResourceRequestSchema, Y as McpError, Z as SUPPORTED_PROTOCOL_VERSIONS, _ as resolveProjectCapletsRoot, a as capabilityDescription, at as getSchemaDescription, b as validateCapletFile, c as deleteTokenBundle, ct as normalizeObjectSchema, d as loadConfig, dt as safeParseAsync, et as assertCompleteRequestResourceTemplate, f as loadConfigWithSources, ft as __commonJSMin, g as resolveConfigPath, h as resolveCapletsRoot, i as ServerRegistry, it as getParseErrorMessage, j as CallToolResultSchema, k as toJsonSchemaCompat, l as isTokenBundleExpired, lt as objectFromShape, m as DEFAULT_AUTH_DIR, mt as __toESM, n as generatedToolInputSchema, nt as getLiteralValue, o as runGenericOAuthFlow, ot as isSchemaOptional, p as parseConfig, pt as __require, q as ListToolsRequestSchema, r as handleServerTool, rt as getObjectShape, s as runOAuthFlow, st as isZ4Schema, t as CapletsEngine, tt as ZodOptional, u as readTokenBundle, ut as safeParse, v as resolveProjectConfigPath, w as assertClientRequestTaskCapability, x as CapletsError, y as discoverCapletFiles, z as GetPromptRequestSchema } from "./engine-D_zyCvXx.js";
|
|
2
2
|
import { accessSync, chmodSync, closeSync, constants, cpSync, existsSync, lstatSync, mkdirSync, mkdtempSync, openSync, readFileSync, rmSync, statSync, writeFileSync, writeSync } from "node:fs";
|
|
3
3
|
import { basename, dirname, join, parse, relative, resolve } from "node:path";
|
|
4
4
|
import { stdin, stdout } from "node:process";
|
|
@@ -1314,7 +1314,7 @@ const EMPTY_COMPLETION_RESULT = { completion: {
|
|
|
1314
1314
|
} };
|
|
1315
1315
|
//#endregion
|
|
1316
1316
|
//#region package.json
|
|
1317
|
-
var version = "0.
|
|
1317
|
+
var version = "0.13.0";
|
|
1318
1318
|
//#endregion
|
|
1319
1319
|
//#region src/runtime.ts
|
|
1320
1320
|
var CapletsRuntime = class {
|
|
@@ -1396,11 +1396,12 @@ function nextEnabledServers(config) {
|
|
|
1396
1396
|
...Object.values(config.openapiEndpoints),
|
|
1397
1397
|
...Object.values(config.graphqlEndpoints),
|
|
1398
1398
|
...Object.values(config.httpApis),
|
|
1399
|
-
...Object.values(config.cliTools)
|
|
1399
|
+
...Object.values(config.cliTools),
|
|
1400
|
+
...Object.values(config.capletSets)
|
|
1400
1401
|
].filter((server) => !server.disabled);
|
|
1401
1402
|
}
|
|
1402
1403
|
function capletById(config, serverId) {
|
|
1403
|
-
return config.mcpServers[serverId] ?? config.openapiEndpoints[serverId] ?? config.graphqlEndpoints[serverId] ?? config.httpApis[serverId] ?? config.cliTools[serverId];
|
|
1404
|
+
return config.mcpServers[serverId] ?? config.openapiEndpoints[serverId] ?? config.graphqlEndpoints[serverId] ?? config.httpApis[serverId] ?? config.cliTools[serverId] ?? config.capletSets[serverId];
|
|
1404
1405
|
}
|
|
1405
1406
|
function serializeCaplet(caplet) {
|
|
1406
1407
|
return JSON.stringify(caplet ?? null);
|
package/dist/native.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as capabilityDescription, n as generatedToolInputSchema, t as CapletsEngine } from "./engine-
|
|
1
|
+
import { a as capabilityDescription, n as generatedToolInputSchema, t as CapletsEngine } from "./engine-D_zyCvXx.js";
|
|
2
2
|
import { generatedToolInputJsonSchema } from "./generated-tool-input-schema.js";
|
|
3
3
|
//#region src/native/tools.ts
|
|
4
4
|
function nativeCapletToolName(capletId) {
|